diff --git a/.eslintrc.yml b/.eslintrc.yml index 8f75dacf6..79d68bc7f 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -6,7 +6,6 @@ es6: true browser: true jquery: true - webextensions: true extends: eslint:recommended rules: dot-notation: [error, allowPattern: "^[A-Z]"] @@ -72,3 +71,5 @@ GM_openInTab: writable GM_listValues: writable GM_xmlhttpRequest: writable + + bridge_call: writable diff --git a/Extensions/xkit_patches.js b/Extensions/xkit_patches.js index 97f736268..b8982e0b0 100644 --- a/Extensions/xkit_patches.js +++ b/Extensions/xkit_patches.js @@ -19,8 +19,7 @@ XKit.extensions.xkit_patches = new Object({ if (XKit.browser().firefox === true && XKit.storage.get("xkit_patches", "w_edition_warned") !== "true") { let version = XKit.tools.parse_version(XKit.version); if (version.major === 7 && version.minor >= 8) { - fetch(browser.runtime.getURL("manifest.json")) // eslint-disable-line no-undef - .then(response => response.json()) + bridge_call("browser.runtime.getManifest") .then(responseData => { if (responseData.applications && responseData.applications.gecko.id === "@new-xkit-w" || responseData.browser_specific_settings && responseData.browser_specific_settings.gecko.id === "@new-xkit-w") { diff --git a/background.js b/background.js new file mode 100644 index 000000000..50219bd60 --- /dev/null +++ b/background.js @@ -0,0 +1,91 @@ +/* globals browser, chrome */ + +if (typeof browser === "undefined") { + // eslint-disable-next-line no-global-assign + browser = chrome; +} + +function isUserScriptsAvailable() { + try { + browser.userScripts; + return true; + } catch { + return false; + } +} + +if (isUserScriptsAvailable) { + browser.userScripts.configureWorld({ + csp: "script-src 'self' 'unsafe-inline' 'unsafe-eval'", + messaging: true, + }); + + browser.runtime.onInstalled.addListener(async () => { + const existingScripts = await browser.userScripts.getScripts({ + ids: ["new-xkit"], + }); + browser.userScripts[existingScripts.length > 0 ? "update" : "register"]([ + { + id: "new-xkit", + // allFrames: true, + runAt: "document_start", + excludeMatches: [ + "*://*.tumblr.com/*/audio_player_iframe/*", + "*://*.tumblr.com/*/photoset_iframe/*", + "*://assets.tumblr.com/*", + "*://*.media.tumblr.com/*", + "*://www.tumblr.com/upload/image*", + "*://www.tumblr.com/video/*", + ], + matches: ["*://*.tumblr.com/*"], + js: [ + "bridge.js", + "vendor/lodash.min.js", + "vendor/jquery.js", + "vendor/tiptip.js", + "vendor/moment.js", + "vendor/nano.js", + "xkit.js", + ].map(file => ({file})), + world: "USER_SCRIPT", + }, + ]); + }); +} + +// must use synchronous callback form due to https://issues.chromium.org/issues/40753031 +browser.runtime.onUserScriptMessage.addListener((request, sender, sendResponse) => { + console.log("onUserScriptMessage", {request, sender, sendResponse}); + + if (request.func) { + (async () => { + const {func, args = []} = request; + + switch (func) { + case "browser.runtime.getManifest": + sendResponse(await browser.runtime.getManifest(...args)); + break; + case "browser.storage.local.get": + sendResponse(await browser.storage.local.get(...args)); + break; + case "browser.storage.local.getBytesInUse": + sendResponse(await browser.storage.local.getBytesInUse(...args)); + break; + case "browser.storage.local.remove": + sendResponse(await browser.storage.local.remove(...args)); + break; + case "browser.storage.local.clear": + sendResponse(await browser.storage.local.clear(...args)); + break; + case "browser.storage.local.set": + sendResponse(await browser.storage.local.set(...args)); + break; + case "browser.runtime.getURL": + sendResponse(await browser.runtime.getURL(...args)); + break; + } + })(); + } + + return true; +}); diff --git a/bridge.js b/bridge.js index 5596f1214..6a4b4cc18 100644 --- a/bridge.js +++ b/bridge.js @@ -8,7 +8,7 @@ */ -/* globals msBrowser */ +/* globals browser, chrome, msBrowser */ if (typeof(browser) === 'undefined') { if (typeof(chrome) !== 'undefined') { @@ -23,10 +23,12 @@ var bridge_error_object; var xkit_storage = {}; var bridge_ver = "2.2.1"; +async function bridge_call(func, args) { // eslint-disable-line no-redeclare + return browser.runtime.sendMessage({ func, args }); +} + try { - var storage = browser.storage.local; var storage_loaded = false; - var framework_version = getVersion(); // eslint-disable-line no-redeclare var storage_used = 0; // eslint-disable-line no-redeclare var storage_max = -1; // eslint-disable-line no-redeclare init_bridge(); @@ -49,17 +51,14 @@ function getBridgeError() { // eslint-disable-line no-redeclare return m_object; } -function getVersion() { - var xhr = new XMLHttpRequest(); - xhr.open('GET', browser.runtime.getURL('manifest.json'), false); - xhr.send(null); - var manifest = JSON.parse(xhr.responseText); +async function getVersion() { + const manifest = await bridge_call("browser.runtime.getManifest"); return manifest.version; } -function call_xkit() { +async function call_xkit() { if (typeof XKit !== "undefined") { - XKit.init(); + XKit.init(await getVersion()); } else { setTimeout(function() { call_xkit(); }, 1); } @@ -74,7 +73,7 @@ function init_bridge() { try { - storage.get(function(items) { + bridge_call("browser.storage.local.get").then(function(items) { if (browser.runtime.lastError) { last_error = browser.runtime.lastError.message; @@ -107,15 +106,12 @@ function init_bridge() { storage_loaded = true; console.log("[XKit Bridge] Storage loaded, calling XKit.. bye!"); - if (storage.getBytesInUse) { - storage.getBytesInUse(function(bytes) { - storage_used = bytes; - storage_max = -1; - call_xkit(); - }); - } else { + bridge_call("browser.storage.local.getBytesInUse").then(function(bytes) { + storage_used = bytes; + storage_max = -1; call_xkit(); - } + }); + }); @@ -134,8 +130,8 @@ function init_bridge() { function GM_flushStorage(callback) { // eslint-disable-line no-redeclare - storage.remove("xkit_something", function() { - storage.clear(function(items) { + bridge_call("browser.storage.local.remove", ["xkit_something"]).then(function() { + bridge_call("browser.storage.local.clear").then(function(items) { var last_error = 'unknown error'; if (browser.runtime.lastError) { last_error = browser.runtime.lastError.message; @@ -149,11 +145,11 @@ function GM_flushStorage(callback) { // eslint-disable-line no-redeclare function GM_deleteAllValues(callback) { // eslint-disable-line no-redeclare - storage.get(function(items) { + bridge_call("browser.storage.local.get").then(function(items) { for (var key in items) { GM_deleteValue(key); } - storage.clear(); + bridge_call("browser.storage.local.clear"); callback(); }); @@ -176,7 +172,7 @@ function GM_getValue(name, defaultValue) { // eslint-disable-line no-redeclare function GM_deleteValue(name) { // eslint-disable-line no-redeclare //console.log("Bridge : GM_deleteValue for " + name); - storage.remove(name); + bridge_call("browser.storage.local.remove", [name]); delete xkit_storage[name]; } @@ -187,7 +183,7 @@ function GM_setValue(name, value) { // eslint-disable-line no-redeclare var m_name = name; m_object[ m_name ] = value; xkit_storage[name] = value; - storage.set(m_object); + bridge_call("browser.storage.local.set", [m_object]); return true; } diff --git a/manifest.json b/manifest.json index 5fea89873..26b2b1f24 100644 --- a/manifest.json +++ b/manifest.json @@ -11,29 +11,29 @@ "*://www.tumblr.com/upload/image*", "*://www.tumblr.com/video/*" ], - "js": [ - "bridge.js", - "vendor/lodash.min.js", - "vendor/jquery.js", - "vendor/tiptip.js", - "vendor/moment.js", - "vendor/nano.js", - "xkit.js" - ], "matches": [ "*://*.tumblr.com/*" ] } ], + "background": { + "scripts": [ "background.js" ], + "service_worker": "background.js", + "persistent": false + }, "description": "A fork of XKit, the extension framework for Tumblr.", "homepage_url": "https://github.com/new-xkit/XKit", "icons": { "128": "icon.png" }, - "manifest_version": 2, - "minimum_chrome_version": "88.0", + "manifest_version": 3, + "minimum_chrome_version": "120.0", "name": "New XKit", "author": "New XKit Team", - "permissions": ["storage", "unlimitedStorage", "*://*.tumblr.com/*", "https://new-xkit.github.io/XKit/*", "https://cloud.new-xkit.com/*" ], + "permissions": ["storage", "unlimitedStorage", "userScripts" ], + "host_permissions": [ "*://*.tumblr.com/*", "https://new-xkit.github.io/XKit/*", "https://cloud.new-xkit.com/*" ], "version": "7.10.0", - "web_accessible_resources": [ "*.js", "*.json", "*.css" ], + "web_accessible_resources": [{ + "resources": [ "*.js", "*.json", "*.css" ], + "matches": [ "*://www.tumblr.com/*" ] + }], "browser_specific_settings": { "gecko": { "id": "@new-xkit", diff --git a/xkit.js b/xkit.js index 326f2fdd7..1d94334a7 100755 --- a/xkit.js +++ b/xkit.js @@ -6,7 +6,7 @@ var xkit_global_start = Date.now(); // log start timestamp if (typeof XKit !== "undefined") { return; } XKit = { - version: framework_version, + version: undefined, api_key: "kZSI0VnPBJom8cpIeTFw4huEh9gGbq4KfWKY7z5QECutAAki6D", page: { standard: @@ -23,7 +23,8 @@ var xkit_global_start = Date.now(); // log start timestamp xkit: document.location.href.indexOf('://www.tumblr.com/xkit_') !== -1 }, - init: function() { + init: function(version) { + XKit.version = version; if (!XKit.page.xkit) { XKit.init_flags(); } @@ -3328,13 +3329,13 @@ function show_message(title, msg, icon, buttons) { }); } -function xkit_init_special() { +async function xkit_init_special() { $("body").html(""); document.title = "XKit"; XKit.notifications.init(); - XKit.notifications.add("Welcome to XKit " + framework_version + "
© 2011-2013 STUDIOXENIX"); + XKit.notifications.add("Welcome to XKit " + XKit.version + "
© 2011-2013 STUDIOXENIX"); if (document.location.href.indexOf("/xkit_reset") !== -1) { XKit.special.reset(); @@ -3354,11 +3355,8 @@ function xkit_init_special() { if (document.location.href.indexOf("/xkit_editor") !== -1) { if (typeof(browser) !== 'undefined') { - var xhr = new XMLHttpRequest(); - xhr.open('GET', browser.extension.getURL('editor.js'), false); - xhr.send(null); try { - new Function(xhr.responseText + "\n//# sourceURL=xkit/editor.js")(); + await import(await bridge_call("browser.runtime.getURL", ["/editor.js"])); XKit.extensions.xkit_editor.run(); } catch (e) { XKit.window.show("Can't launch XKit Editor", "

" + e.message + "

", "error", "
OK
"); @@ -3536,7 +3534,7 @@ function install_extension(mdata, callback) { function xkit_install() { - XKit.window.show("Welcome to New XKit " + framework_version + "!", "Please wait while I initialize the setup. This might take a while.
Please do not navigate away from this page.
", "info"); + XKit.window.show("Welcome to New XKit " + XKit.version + "!", "Please wait while I initialize the setup. This might take a while.
Please do not navigate away from this page.
", "info"); console.log("Trying to retrieve XKit Installer."); XKit.install("xkit_installer", function(mdata) { @@ -3612,7 +3610,7 @@ function show_error_update(message) { * Functions used in place of gulp build server */ -const loadFile = path => fetch(browser.runtime.getURL(path)).then(response => response.text()); +const loadFile = async path => fetch(await bridge_call("browser.runtime.getURL", [path])).then(response => response.text()); const extensionDataCache = {};