first commit

This commit is contained in:
Jesse
2026-04-19 19:58:17 +08:00
commit 40ade69297
14 changed files with 1122 additions and 0 deletions

585
js/popup.js Normal file
View File

@@ -0,0 +1,585 @@
$(function () {
const isFirefox = typeof window.browser !== "undefined";
const browserAPI = window.browser || window.chrome;
const storageAPI = {
get: function (keys, cb) {
if (isFirefox) {
browserAPI.storage.local.get(keys).then(cb);
} else {
browserAPI.storage.local.get(keys, cb);
}
},
set: function (obj, cb) {
if (isFirefox) {
browserAPI.storage.local.set(obj).then(function () {
cb && cb();
});
} else {
browserAPI.storage.local.set(obj, cb);
}
},
clear: function (cb) {
if (isFirefox) {
browserAPI.storage.local.clear().then(function () {
cb && cb();
});
} else {
browserAPI.storage.local.clear(cb);
}
}
};
const bookmarksAPI = {
getTree: function (cb) {
if (isFirefox) {
browserAPI.bookmarks.getTree().then(cb);
} else {
browserAPI.bookmarks.getTree(cb);
}
},
getSubTree: function (id, cb) {
if (isFirefox) {
browserAPI.bookmarks.getSubTree(id).then(cb);
} else {
browserAPI.bookmarks.getSubTree(id, cb);
}
},
getChildren: function (id, cb) {
if (isFirefox) {
browserAPI.bookmarks.getChildren(id).then(cb);
} else {
browserAPI.bookmarks.getChildren(id, cb);
}
},
removeTree: function (id, cb) {
if (isFirefox) {
browserAPI.bookmarks.removeTree(id).then(cb);
} else {
browserAPI.bookmarks.removeTree(id, cb);
}
},
create: function (options, cb) {
if (isFirefox) {
browserAPI.bookmarks.create(options).then(cb);
} else {
browserAPI.bookmarks.create(options, cb);
}
}
};
sync = {
/**
* 初始化函数
*/
init: function () {
let that = this;
that.base64 = new Base64();
// 码云的API根地址现在从表单读取
that.baseUrl = $("#tbServer").val().endsWith('/') ? $("#tbServer").val() : $("#tbServer").val() + '/';
that.getCacheUserInfo();
that.bindEvent();
},
/**
* 表单收集
*/
createFormObj: function () {
let formObj = {};
formObj.server = $("#tbServer").val();
formObj.access_token = $("#tbAccessToken").val();
formObj.owner = $("#tbOwner").val();
formObj.repo = $("#tbRepo").val();
formObj.path = $("#tbPath").val();
formObj.branch = $("#tbBranch").val();
return formObj;
},
/**
* 弹出窗开始时从缓存读取已经存储的数据
*/
getCacheUserInfo: function () {
let that = this;
// 从缓存中读取数据并设置到表单中
storageAPI.get(["server", "access_token", "owner", "repo", "path", "branch", "remember"], function (obj) {
// 插件最开始的状态是记住开关打开了但是chrome本地缓存中还没有设置值
if (!obj.remember) {
if ($("#rememberDot").hasClass("green")) {
that.saveRememberState("on");
} else {
that.saveRememberState("off");
}
} else if (obj.remember == "on") {
$("#rememberDot").addClass("green");
} else {
$("#rememberDot").removeClass("green");
}
if ($("#rememberDot").hasClass("green")) {
if (obj.server || obj.access_token || obj.owner || obj.repo || obj.path || obj.branch) {
$("#tbServer").val(obj.server || "https://gitee.com/api/v5/");
that.baseUrl = ($("#tbServer").val().endsWith('/') ? $("#tbServer").val() : $("#tbServer").val() + '/');
$("#tbAccessToken").val(obj.access_token);
$("#tbOwner").val(obj.owner);
$("#tbRepo").val(obj.repo);
$("#tbPath").val(obj.path);
$("#tbBranch").val(obj.branch);
that.rememberOn();
}
}
});
},
rememberOn: function () {
let that = this;
$("#rememberText").addClass("grey");
$("#rememberDot").addClass("green");
that.saveRememberState("on");
},
rememberOff: function () {
let that = this;
$("#rememberText").removeClass("grey");
$("#rememberDot").removeClass("green");
that.saveRememberState("off");
},
/**
* 清除用户信息
*/
clearUserInfo: function () {
storageAPI.clear(function () {
console.log('clear user info success');
});
},
/**
* 保存用户信息
*/
saveUserInfo: function () {
let that = this;
let formObj = that.createFormObj();
storageAPI.set(formObj, function () {
console.log('save user info success');
});
},
/**
* 保存记住按钮的状态
* stateon记住off不记住
*/
saveRememberState: function (state) {
let rememberObj = {};
rememberObj.remember = state;
storageAPI.set(rememberObj, function () {
console.log('save remember state success');
});
},
/**
* 获取书签栏根节点 ID
*/
getBookmarkBarId: function (fn) {
let that = this;
if (!isFirefox) {
fn("1");
return;
}
bookmarksAPI.getTree(function (tree) {
let root = Array.isArray(tree) ? tree[0] : tree;
if (!root || !root.children) {
fn("toolbar_____");
return;
}
let toolbar = root.children.find(function (node) {
return node.id === "toolbar_____" || node.title === "Bookmarks Toolbar" || (node.title && node.title.toLowerCase().indexOf("toolbar") !== -1);
});
fn(toolbar ? toolbar.id : "toolbar_____");
});
},
/**
* 获取浏览器的书签数据
*/
getBookmarks: function (fn) {
let that = this;
that.getBookmarkBarId(function (rootId) {
bookmarksAPI.getSubTree(rootId, function (bookmarks) {
console.log('Retrieved bookmarks:', bookmarks);
fn(bookmarks);
});
});
},
/**
* 清空书签栏文件夹(不能直接清除根书签栏,只能遍历一个一个文件夹清除)
*/
emptyBookmarks: function (fn) {
let that = this;
that.getBookmarkBarId(function (rootId) {
bookmarksAPI.getChildren(rootId, function (children) {
// 需要判断书签栏是否原来就是空的
if (!children || children.length <= 0) {
fn();
return;
}
for (let i = 0; i < children.length; i++) {
let item = children[i];
bookmarksAPI.removeTree(item.id, function () {
// 判断是不是已经删除到最后一个了,是的话就调用回调函数
if (i == (children.length - 1)) {
fn();
}
});
}
});
});
},
bindEvent: function () {
let that = this;
// 记住按钮点击事件
$("#rememberDot").on("click", function () {
// 先判断当前记住按钮的状态,假如已经记住则不再记住,清空缓存
if ($("#rememberDot").hasClass("green")) {
that.clearUserInfo();
that.rememberOff();
} else {
// 获取表单数据,有则保存到缓存中
let formObj = that.createFormObj();
let existRes = that.checkFormExist(formObj);
if (existRes) {
that.saveUserInfo();
}
that.rememberOn();
}
});
// 输入框的输入事件,用来记忆表单数据
$(".input").on("input", function () {
if ($("#rememberDot").hasClass("green")) {
that.saveUserInfo();
that.rememberOn();
}
});
// 点击上传按钮
$("#btnUpload").on("click", function () {
console.log('Upload button clicked');
let formObj = that.createFormObj();
console.log('Form object:', formObj);
let formRes = that.checkForm(formObj);
if (formRes != "ok") {
$("#toast").text(formRes).show();
return;
}
// 更新baseUrl
that.baseUrl = formObj.server.endsWith('/') ? formObj.server : formObj.server + '/';
console.log('Base URL set to:', that.baseUrl);
// 假如记住按钮已经点击了
if ($("#rememberDot").hasClass("green")) {
that.saveUserInfo();
that.rememberOn();
} else {
that.clearUserInfo();
that.rememberOff();
}
$("#loaderWrap").show();
// 从码云上获取书签内容
console.log('Calling getGit');
that.getGit(formObj, function (getState, getRes) {
console.log('getGit callback:', getState, getRes);
// 获取浏览器的书签
that.getBookmarks(function (bookmarks) {
console.log('getBookmarks callback');
// 获取码云的内容存在则更新文件,否则更新文件
if (getState) {
let sha = getRes.sha;
that.updateGit(formObj, bookmarks, sha, function (updState, updRes) {
// 更新成功,则提示,否则提示错误
if (updState) {
$("#successWrap").show();
$(".successText").text("Upload Success");
} else {
$("#toast").text(updRes).show();
}
$("#loaderWrap").hide();
});
} else {
that.createGit(formObj, bookmarks, function (createState, createRes) {
// 创建成功,则提示,否则提示错误
if (createState) {
$("#successWrap").show();
$(".successText").text("Upload Success");
} else {
$("#toast").text(createRes).show();
}
$("#loaderWrap").hide();
});
}
});
});
});
// 点击下载按钮事件
$("#btnDownload").on("click", function () {
let formObj = that.createFormObj();
let formRes = that.checkForm(formObj);
if (formRes != "ok") {
$("#toast").text(formRes).show();
return;
}
// 更新baseUrl
that.baseUrl = formObj.server.endsWith('/') ? formObj.server : formObj.server + '/';
// 假如记住按钮已经点击了
if ($("#rememberDot").hasClass("green")) {
that.saveUserInfo();
that.rememberOn();
} else {
that.clearUserInfo();
that.rememberOff();
}
$("#loaderWrap").show();
// 从码云上获取书签内容
that.getGit(formObj, function (getState, getRes) {
// 获取码云的内容存在则创建文件,否则提示文件不存在
if (getState) {
let gitContent = that.base64.decode(getRes["content"]);
let bookmarksParent = JSON.parse(gitContent);
let bookmarks = bookmarksParent[0];
// 清空书签栏
that.emptyBookmarks(function () {
// 等所有书签都清空后开始设置书签
that.getBookmarkBarId(function (rootId) {
that.setBookmarks(rootId, bookmarks);
$("#successWrap").show();
$(".successText").text("Download Success");
});
});
} else {
$("#toast").text("Git文件不存在").show();
}
$("#loaderWrap").hide();
});
});
},
/**
* 将git获取的内容设置到浏览器书签上去
*/
setBookmarks: function (parentId, bookmarks) {
let that = this;
if (!bookmarks.children || bookmarks.children.length <= 0) {
return;
}
for (let i = 0; i < bookmarks.children.length; i++) {
let item = bookmarks.children[i];
bookmarksAPI.create({
parentId: parentId,
index: item.index,
title: item.title,
url: item.url
}, function (res) {
// 判断假如还有子元素则递归调用自身添加
if (item.children && item.children.length > 0) {
that.setBookmarks(res.id, item);
}
});
}
},
/**
* 校验表单
*/
checkForm: function (formObj) {
if (!formObj.server) {
$("#tbServer").addClass('error');
return 'server is required';
}
$("#tbServer").removeClass('error');
if (!formObj.access_token) {
$("#tbAccessToken").addClass('error');
return 'access_token is required';
}
$("#tbAccessToken").removeClass('error');
if (!formObj.owner) {
$("#tbOwner").addClass('error');
return 'owner is required';
}
$("#tbOwner").removeClass('error');
if (!formObj.repo) {
$("#tbRepo").addClass('error');
return 'repo is required';
}
$("#tbRepo").removeClass('error');
if (!formObj.path) {
$("#tbPath").addClass('error');
return 'path is required';
}
$("#tbPath").removeClass('error');
if (!formObj.branch) {
$("#tbBranch").addClass('error');
return 'branch is required';
}
$("#tbBranch").removeClass('error');
return "ok";
},
/**
* 查看表单是否至少有一个值
*/
checkFormExist: function (formObj) {
if (formObj.server != '') {
return true;
}
if (formObj.access_token != '') {
return true;
}
if (formObj.owner != '') {
return true;
}
if (formObj.repo != '') {
return true;
}
if (formObj.path != '') {
return true;
}
if (formObj.branch != '') {
return true;
}
return false;
},
/**
* 获取Gitee上的数据
* curl -X GET --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/xieyf00/chrome/contents/bookmark/bookmark-4.json?access_token=16c6176faea12d4b2dba667872d9b21c&ref=master'
*/
getGit: function (formObj, fn) {
let that = this;
let getUrl = that.baseUrl + "repos/" + formObj.owner + "/" + formObj.repo + "/contents/" + formObj.path + "?ref=" + formObj.branch;
$.ajax({
type: "GET",
url: getUrl,
headers: {
'Authorization': 'token ' + formObj.access_token
},
crossDomain: true,
success: function (res) {
fn && fn(true, res);
},
error: function (xhr, textStatus, error) {
fn && fn(false, error);
}
});
},
/**
* 创建Git文件
* curl -X POST --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/xieyf00/chrome/contents/bookmark/bookmark-copy.json' -d '{"access_token":"16c6176faea12d4b2dba667872d9b21c","content":"xxx","message":"xieyangfan commit","branch":"master"}'
* createContentRaw文件内容, 要用 base64 编码
*/
createGit: function (formObj, createContentRaw, fn) {
let that = this;
if (createContentRaw == null) {
console.error('createGit missing contentRaw');
fn && fn(false, 'No bookmark data to upload');
return;
}
console.log('createContentRaw:', createContentRaw);
let jsonStr = JSON.stringify(createContentRaw);
console.log('JSON string:', jsonStr);
let createContent = that.base64.encode(jsonStr);
console.log('Base64 encoded:', createContent);
// Git提交信息
let createMessage = "Chrome Browser Bookmark Created" + new Date();
// 构建
let createData = {};
createData.access_token = formObj.access_token;
createData.content = createContent;
createData.message = createMessage;
createData.branch = formObj.branch;
let createUrl = that.baseUrl + "repos/" + formObj.owner + "/" + formObj.repo + "/contents/" + formObj.path;
console.log('Create URL:', createUrl);
console.log('Create data:', createData);
$.ajax({
type: "POST",
url: createUrl,
contentType: 'application/json',
headers: {
'Authorization': 'token ' + formObj.access_token
},
data: JSON.stringify(createData),
crossDomain: true,
success: function (res) {
console.log('Create success:', res);
fn && fn(true, res);
},
error: function (xhr, textStatus, error) {
console.log('Create error:', xhr, textStatus, error);
fn && fn(false, error);
}
});
},
/**
* 更新Git文件
* curl -X PUT --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/xieyf00/chrome/contents/bookmark/bookmark-6.json' -d '{"access_token":"16c6176faea12d4b2dba667872d9b21c","content":"InhpZXlhbmdmYW4gMjAxOTA3MjQgMTU0OCI=","sha":"dce85293664c50792d2ebcfc4ede23bf3e1197c2","message":"xieyangfan 20190724 1736","branch":"master"}'
* updateContentRaw文件内容, 要用 base64 编码
* sha文件的 Blob SHA可通过 [获取仓库具体路径下的内容] API 获取
*/
updateGit: function (formObj, updateContentRaw, sha, fn) {
let that = this;
if (updateContentRaw == null) {
console.error('updateGit missing updateContentRaw');
fn && fn(false, 'No bookmark data to update');
return;
}
console.log('updateContentRaw:', updateContentRaw);
let jsonStr = JSON.stringify(updateContentRaw);
console.log('JSON string:', jsonStr);
let updateContent = that.base64.encode(jsonStr);
console.log('Base64 encoded:', updateContent);
// Git提交信息
let updateMessage = "Chrome Browser Bookmark Updated" + new Date();
// 构建
let updateData = {};
updateData.access_token = formObj.access_token;
updateData.content = updateContent;
updateData.message = updateMessage;
updateData.sha = sha;
updateData.branch = formObj.branch;
let updateUrl = that.baseUrl + "repos/" + formObj.owner + "/" + formObj.repo + "/contents/" + formObj.path;
console.log('Update URL:', updateUrl);
console.log('Update data:', updateData);
$.ajax({
type: "PUT",
url: updateUrl,
contentType: 'application/json',
headers: {
'Authorization': 'token ' + formObj.access_token
},
data: JSON.stringify(updateData),
crossDomain: true,
success: function (res) {
console.log('Update success:', res);
fn && fn(true, res);
},
error: function (xhr, textStatus, error) {
console.log('Update error:', xhr, textStatus, error);
fn && fn(false, error);
}
});
},
/**
* 删除Git文件
* curl -X DELETE --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/xieyf00/chrome/contents/bookmark/bookmark-6.json?access_token=16c6176faea12d4b2dba667872d9b21c&sha=dce85293664c50792d2ebcfc4ede23bf3e1197c2&message=Chrome%20Browser%20Bookmark%20Deleted&branch=master'
* sha文件的 Blob SHA可通过 [获取仓库具体路径下的内容] API 获取
*/
deleteGit: function (formObj, sha, fn) {
let that = this;
// Git提交信息
let deleteMessage = "Chrome Browser Bookmark Deleted" + new Date();
// 构建
let deleteData = {};
deleteData.access_token = formObj.access_token;
deleteData.message = deleteMessage;
deleteData.sha = sha;
deleteData.branch = formObj.branch;
let deleteUrl = that.baseUrl + "repos/" + formObj.owner + "/" + formObj.repo + "/contents/" + formObj.path;
$.ajax({
type: "DELETE",
url: deleteUrl,
data: deleteData,
crossDomain: true,
success: function (res) {
fn && fn(true, res);
},
error: function (xhr, textStatus, error) {
fn && fn(false, error);
}
});
}
}
sync.init();
});