/** * Open the given url in a popup * @param {string} url - * @param {number} width - * @param {number} height - * @return {void} - */ function openInPopup(url, width, height) { browser.windows.create({ url, type: 'popup', allowScriptsToClose: true, width, height, }) } var last_tab; /** * Share Current Tab * @return {void} - */ function shareCurrentTab(tab) { const url = tab.url; const title = tab.title || url; browser.storage.local.get("url").then((storage) => { if(!storage.url){ browser.runtime.openOptionsPage(); return; } const shareUrl = `${storage.url}?post=${encodeURIComponent(url)}&title=${encodeURIComponent(title)}&source=bookmarklet`; openInPopup(shareUrl, storage.popupWidth, storage.popupHeight); }); } /** * Show Page Action on current page if activated * @param {string} tabId - Current tab id * @return {void} - */ function showPageAction(tabId){ browser.storage.local.get("pageAction").then((storage) => { storage.pageAction ? browser.pageAction.show(tabId) : browser.pageAction.hide(tabId); }); } /** * Show page action with given active information * @param {object} activeInfo - * @return {void} - */ function tabActivation(activeInfo){ showPageAction(activeInfo.tabId); } /* Initialize */ browser.tabs.query({active: true, currentWindow: true}).then((tabs) => { showPageAction(tabs[0].id); }); async function getCurrentTab() { // Get active tabs in current window var tabs = await browser.tabs.query({ currentWindow: true, active: true, }); if (tabs.length < 1) { throw new Error("no tab available"); } // Make sure URL protocol supported var supportedProtocols = ["https:", "http:", "ftp:", "file:"], activeTab = tabs[0], url = document.createElement('a'); if (activeTab.url !== "") { url.href = activeTab.url; if (supportedProtocols.indexOf(url.protocol) === -1) { throw new Error(`protocol "${url.protocol}" is not supported`); } } last_tab = activeTab return activeTab; } async function findLocalBookmark(url){ let data = await browser.storage.local.get("links"); let result = data.links.hasOwnProperty(url); return result } async function updateIcon() { // Set initial icon var runtimeUrl = await browser.runtime.getURL("/"), icon = {path: { 16: "../resources/icons/leaf_off.svg", 32: "../resources/icons/leaf_off.svg", 64: "../resources/icons/leaf_off.svg" }}; // Firefox allows using empty object as default icon. // This way, Firefox will use default_icon that defined in manifest.json // if (runtimeUrl.startsWith("moz")) { // icon = {}; // } // Get current active tab try { var tab = await getCurrentTab() var local = await findLocalBookmark(tab.url); if (local) icon.path = { 16: "../resources/icons/leaf_on.svg", 32: "../resources/icons/leaf_on.svg", 64: "../resources/icons/leaf_on.svg" } // console.log("tab:", tab); // icon.tabId = tab.id; // browser.pageAction.setIcon(icon); } catch {} return browser.browserAction.setIcon(icon); } function updateActiveTab() { updateIcon().catch(err => console.error(err.message)); } /* Listeners */ browser.tabs.onActivated.addListener(tabActivation); browser.browserAction.onClicked.addListener(shareCurrentTab); browser.pageAction.onClicked.addListener(shareCurrentTab); browser.tabs.onUpdated.addListener(updateActiveTab); browser.tabs.onActivated.addListener(updateActiveTab); browser.windows.onFocusChanged.addListener(updateActiveTab); updateActiveTab(); let onCreated = console.log; browser.contextMenus.create({ id: "log-selection", title: "Sync bookmarks", contexts: ["all"] }, onCreated); async function sync_links(){ // get server url from storage var storage_server_url = await browser.storage.local.get("url") if(!storage_server_url.url){ return } let server_url = storage_server_url.url; // get token from storage var storage_token = await browser.storage.local.get("token") if(!storage_token.token){ return } let token = storage_token.token; // construct api url let api_url = new URL(server_url); api_url.pathname = "/api/v1/links"; api_url.searchParams.append("limit", "all"); // get links var result = await getLinks(token, api_url.href); // generate link dictionary let links = {} result.forEach((value)=>{ links[value.url] = true; }) // save link dictionary browser.storage.local.set({"links":links}); } browser.contextMenus.onClicked.addListener(async function(info, tab) { await sync_links(); }) browser.runtime.onMessage.addListener(async (message) => { if (message === "sync") { await new Promise(r => setTimeout(r, 1000)); await sync_links(); await new Promise(r => setTimeout(r, 100)); updateIcon(); } }); console.log("addon loaded"); sync_links(); browser.storage.local.set({"attempt":0});