diff --git a/browser_extensions/chrome/js/background.js b/browser_extensions/chrome/js/background.js deleted file mode 100644 index df1215a..0000000 --- a/browser_extensions/chrome/js/background.js +++ /dev/null @@ -1,119 +0,0 @@ -/* - Storage - */ - -var SYNC_STORAGE = chrome.storage.sync; -var LOCAL_STORAGE = chrome.storage.local; - -var DEFAULT_SETTINGS = { - 'spacing_mode': 'spacing_when_load', - 'spacing_rule': 'blacklists', - 'blacklists': [ // TODO: support regex - '//docs.google.com', - '//gist.github.com', - '/blob/', - '/commit/', - '/pull/' - ], - 'whitelists': [], - 'is_mute': false -}; -var CACHED_SETTINGS = Object.create(DEFAULT_SETTINGS); -var SETTING_KEYS = Object.keys(DEFAULT_SETTINGS); - -function refresh_cached_settings() { - SYNC_STORAGE.get(null, function(items) { - CACHED_SETTINGS = items; - }); -} - -function merge_settings() { - SYNC_STORAGE.get(null, function(items) { - var old_settings = items; - var new_settings = {}; - - SETTING_KEYS.forEach(function(key) { - if (old_settings[key] === undefined) { - new_settings[key] = DEFAULT_SETTINGS[key]; - } - else { - new_settings[key] = old_settings[key]; - } - }); - - // 如果 new_settings 跟 old_settings 一樣的話,並不會觸發 chrome.storage.onChanged - // 所以這裡強制 refresh,確保 CACHED_SETTINGS 一定有東西 - SYNC_STORAGE.set(new_settings, function() { - refresh_cached_settings(); - }); - }); -} - -chrome.storage.onChanged.addListener( - function(changes, areaName) { - if (areaName === 'sync') { - refresh_cached_settings(); - - // chrome.storage.sync 同步更新到 chrome.storage.local - var obj_to_save = {}; - for (var key in changes) { - obj_to_save[key] = changes[key].newValue; - } - LOCAL_STORAGE.set(obj_to_save); - } - } -); - -merge_settings(); - -/* - Message Passing - */ - -// 判斷能不能對這個頁面插入空格 -function can_spacing(tab) { - if (tab === undefined) { - return false; - } - - if (CACHED_SETTINGS['spacing_mode'] === 'spacing_when_load') { - var current_url = tab.url; - - if (CACHED_SETTINGS['spacing_rule'] === 'blacklists') { - for (var i in CACHED_SETTINGS['blacklists']) { - var blacklist_url = CACHED_SETTINGS['blacklists'][i]; - if (current_url.indexOf(blacklist_url) >= 0) { - return false; - } - } - - return true; - } - else if (CACHED_SETTINGS['spacing_rule'] === 'whitelists') { - for (var j in CACHED_SETTINGS['whitelists']) { - var whitelist_url = CACHED_SETTINGS['whitelists'][j]; - if (current_url.indexOf(whitelist_url) >= 0) { - return true; - } - } - - return false; - } - } - else if (CACHED_SETTINGS['spacing_mode'] === 'spacing_when_click') { - return false; - } - - return true; -} - -// 監聽來自 content_script.js 的訊息 -chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) { - switch (message.purpose) { - case 'can_spacing': - sendResponse({'result': can_spacing(sender.tab)}); - break; - default: - sendResponse({'result': false}); - } -}); diff --git a/browser_extensions/chrome/js/options.js b/browser_extensions/chrome/js/options.js index 6847209..0a3eb8b 100644 --- a/browser_extensions/chrome/js/options.js +++ b/browser_extensions/chrome/js/options.js @@ -36,7 +36,7 @@ var app = angular.module('app', ['xeditable']); app.controller('OptionsController', [ '$scope', - function OptionsController($scope) { + async function OptionsController($scope) { angular.element('#page_title').html(utils_chrome.get_i18n('extension_name')); angular.element('#header_title').html(utils_chrome.get_i18n('extension_name')); angular.element('#subtitle').html(utils_chrome.get_i18n('subtitle')); @@ -47,10 +47,10 @@ app.controller('OptionsController', [ /* 什麼時候作用? */ - $scope.spacing_mode = utils_chrome.CACHED_SETTINGS['spacing_mode']; + $scope.spacing_mode = await chrome.runtime.sendMessage({purpose: 'get_cache_setting', key: 'spacing_mode'}); $scope.spacing_mode_display = utils_chrome.get_i18n($scope.spacing_mode); $scope.spacing_when_click_msg = utils_chrome.get_i18n('spacing_when_click_msg'); - $scope.change_spacing_mode = function() { + $scope.change_spacing_mode = async function() { play_sound('Hadouken'); if ($scope.spacing_mode === 'spacing_when_load') { @@ -61,19 +61,16 @@ app.controller('OptionsController', [ } $scope.spacing_mode_display = utils_chrome.get_i18n($scope.spacing_mode); - - utils_chrome.SYNC_STORAGE.set({'spacing_mode': $scope.spacing_mode}, function() { - // utils_chrome.print_sync_storage(); - }); + chrome.runtime.sendMessage({purpose: 'set_cache_setting', key: 'spacing_mode', value: $scope.spacing_mode}); }; /* 然後,你是否希望: */ - $scope.spacing_rule = utils_chrome.CACHED_SETTINGS['spacing_rule']; + $scope.spacing_rule = await chrome.runtime.sendMessage({purpose: 'get_cache_setting', key: 'spacing_rule'}); $scope.spacing_rule_display = utils_chrome.get_i18n($scope.spacing_rule); - $scope.blacklists = utils_chrome.CACHED_SETTINGS['blacklists']; - $scope.whitelists = utils_chrome.CACHED_SETTINGS['whitelists']; + $scope.blacklists = await chrome.runtime.sendMessage({purpose: 'get_cache_setting', key: 'blacklists'}); + $scope.whitelists = await chrome.runtime.sendMessage({purpose: 'get_cache_setting', key: 'whitelists'}); $scope.change_spacing_rule = function() { play_sound('Shouryuuken'); @@ -86,10 +83,7 @@ app.controller('OptionsController', [ } $scope.spacing_rule_display = utils_chrome.get_i18n($scope.spacing_rule); - - utils_chrome.SYNC_STORAGE.set({'spacing_rule': $scope.spacing_rule}, function() { - // print_sync_storage(); - }); + chrome.runtime.sendMessage({purpose: 'set_cache_setting', key: 'spacing_rule', value: $scope.spacing_rule}); }; $scope.update_urls = function(url) { @@ -98,12 +92,8 @@ app.controller('OptionsController', [ var spacing_rule = $scope.spacing_rule; // 'blacklists' or 'whitelists' var urls = $scope[spacing_rule]; - var obj_to_save = {}; - obj_to_save[spacing_rule] = urls; + chrome.runtime.sendMessage({purpose: 'set_cache_setting', key: spacing_rule, value: urls}); - utils_chrome.SYNC_STORAGE.set(obj_to_save, function() { - // utils_chrome.print_sync_storage(); - }); } else { play_sound('WahWahWaaah'); @@ -120,11 +110,7 @@ app.controller('OptionsController', [ var urls = $scope[spacing_rule]; urls.splice(array_index, 1); - var obj_to_save = {}; - obj_to_save[spacing_rule] = urls; - utils_chrome.SYNC_STORAGE.set(obj_to_save, function() { - // utils_chrome.print_sync_storage(); - }); + chrome.runtime.sendMessage({purpose: 'set_cache_setting', key: spacing_rule, value: urls}); event.preventDefault(); }; @@ -139,12 +125,8 @@ app.controller('OptionsController', [ var spacing_rule = $scope.spacing_rule; var urls = $scope[spacing_rule]; urls.push(new_url); + chrome.runtime.sendMessage({purpose: 'set_cache_setting', key: spacing_rule, value: urls}); - var obj_to_save = {}; - obj_to_save[spacing_rule] = urls; - utils_chrome.SYNC_STORAGE.set(obj_to_save, function() { - // utils_chrome.print_sync_storage(); - }); } else { play_sound('WahWahWaaah'); @@ -166,17 +148,16 @@ app.controller('OptionsController', [ 在這個頁面靜音 */ $scope.label_is_mute = utils_chrome.get_i18n('label_is_mute'); - $scope.is_mute = utils_chrome.CACHED_SETTINGS['is_mute']; + $scope.is_mute = await chrome.runtime.sendMessage({purpose: 'get_cache_setting', key: 'is_mute'}); $scope.$watch('is_mute', function(new_val, old_val) { if (new_val !== old_val) { - utils_chrome.SYNC_STORAGE.set({'is_mute': new_val}, function() { - // utils_chrome.print_sync_storage(); - }); + chrome.runtime.sendMessage({purpose: 'set_cache_setting', key: 'is_mute', value: new_val}); } IS_MUTE = new_val; }); + $scope.$apply() } ]); diff --git a/browser_extensions/chrome/js/popup.js b/browser_extensions/chrome/js/popup.js index de06028..9756563 100644 --- a/browser_extensions/chrome/js/popup.js +++ b/browser_extensions/chrome/js/popup.js @@ -11,6 +11,10 @@ function is_valid_url_for_spacing(url) { } } +function spacing_page() { + pangu.spacingPage(); +} + /* Angular */ @@ -19,11 +23,11 @@ var app = angular.module('app', []); app.controller('PopupController', [ '$scope', - function PopupController($scope) { + async function PopupController($scope) { angular.element('#god_of_spacing').html(utils_chrome.get_i18n('god_of_spacing')); // 切換 spacing_mode - $scope.spacing_mode = utils_chrome.CACHED_SETTINGS['spacing_mode']; + $scope.spacing_mode = await chrome.runtime.sendMessage({purpose: 'get_cache_setting', key: 'spacing_mode'}); $scope.spacing_mode_display = utils_chrome.get_i18n($scope.spacing_mode); $scope.change_spacing_mode = function() { if ($scope.spacing_mode === 'spacing_when_load') { @@ -35,9 +39,7 @@ app.controller('PopupController', [ $scope.spacing_mode_display = utils_chrome.get_i18n($scope.spacing_mode); - utils_chrome.SYNC_STORAGE.set({'spacing_mode': $scope.spacing_mode}, function() { - // utils_chrome.print_sync_storage(); - }); + chrome.runtime.sendMessage({purpose: 'set_cache_setting', key: 'spacing_mode', value: $scope.spacing_mode}); }; // 招喚空格之神 @@ -53,7 +55,10 @@ app.controller('PopupController', [ // 略過 chrome:// 之類的 URL if (is_valid_url_for_spacing(tab.url)) { - chrome.tabs.executeScript(tab.id, {code: 'pangu.spacingPage();', allFrames: true}); + chrome.scripting.executeScript({ + target: {tabId: tab.id}, + func: spacing_page + }); } else { if (i === 0) { @@ -69,5 +74,6 @@ app.controller('PopupController', [ $scope.open_options_page = function() { chrome.tabs.create({url: 'pages/options.html'}); }; + $scope.$apply() } ]); diff --git a/browser_extensions/chrome/js/service_worker.js b/browser_extensions/chrome/js/service_worker.js new file mode 100644 index 0000000..7134ace --- /dev/null +++ b/browser_extensions/chrome/js/service_worker.js @@ -0,0 +1,131 @@ +/* + Storage + */ + +var SYNC_STORAGE = chrome.storage.sync; +var LOCAL_STORAGE = chrome.storage.local; + +var DEFAULT_SETTINGS = { + 'spacing_mode': 'spacing_when_load', + 'spacing_rule': 'blacklists', + 'blacklists': [ // TODO: support regex + '//docs.google.com', + '//gist.github.com', + '/blob/', + '/commit/', + '/pull/' + ], + 'whitelists': [], + 'is_mute': false +}; +var CACHED_SETTINGS = Object.create(DEFAULT_SETTINGS); +var SETTING_KEYS = Object.keys(DEFAULT_SETTINGS); + +function refresh_cached_settings() { + SYNC_STORAGE.get(null, function(items) { + CACHED_SETTINGS = items; + }); +} + +function merge_settings() { + SYNC_STORAGE.get(null, function(items) { + var old_settings = items; + var new_settings = {}; + + SETTING_KEYS.forEach(function(key) { + if (old_settings[key] === undefined) { + new_settings[key] = DEFAULT_SETTINGS[key]; + } + else { + new_settings[key] = old_settings[key]; + } + }); + + // 如果 new_settings 跟 old_settings 一樣的話,並不會觸發 chrome.storage.onChanged + // 所以這裡強制 refresh,確保 CACHED_SETTINGS 一定有東西 + SYNC_STORAGE.set(new_settings, function() { + refresh_cached_settings(); + }); + }); +} + +/* + Message Passing + */ + +// 判斷能不能對這個頁面插入空格 +function can_spacing(tab) { + if (tab === undefined) { + return false; + } + + if (CACHED_SETTINGS['spacing_mode'] === 'spacing_when_load') { + var current_url = tab.url; + + if (CACHED_SETTINGS['spacing_rule'] === 'blacklists') { + for (var i in CACHED_SETTINGS['blacklists']) { + var blacklist_url = CACHED_SETTINGS['blacklists'][i]; + if (current_url.indexOf(blacklist_url) >= 0) { + return false; + } + } + + return true; + } + else if (CACHED_SETTINGS['spacing_rule'] === 'whitelists') { + for (var j in CACHED_SETTINGS['whitelists']) { + var whitelist_url = CACHED_SETTINGS['whitelists'][j]; + if (current_url.indexOf(whitelist_url) >= 0) { + return true; + } + } + + return false; + } + } + else if (CACHED_SETTINGS['spacing_mode'] === 'spacing_when_click') { + return false; + } + return true; +} + +chrome.storage.onChanged.addListener( + function(changes, areaName) { + if (areaName === 'sync') { + refresh_cached_settings(); + + // chrome.storage.sync 同步更新到 chrome.storage.local + var obj_to_save = {}; + for (var key in changes) { + obj_to_save[key] = changes[key].newValue; + } + LOCAL_STORAGE.set(obj_to_save); + } + } +); + +chrome.runtime.onInstalled.addListener(function() { + merge_settings(); +}); + +// 監聽來自 content_script.js 的訊息 +chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) { + switch (message.purpose) { + case 'can_spacing': + sendResponse({'result': can_spacing(sender.tab)}); + break; + case 'get_cache_setting': + sendResponse(CACHED_SETTINGS[message.key]); + break; + case 'set_cache_setting': + let update_setting = {}; + update_setting[message.key] = message.value + SYNC_STORAGE.set(update_setting, function() { + refresh_cached_settings(); + }); + break; + default: + sendResponse({'result': false}); + } + return true; +}); diff --git a/browser_extensions/chrome/js/utils_chrome.js b/browser_extensions/chrome/js/utils_chrome.js index 26a5b54..db4b1b3 100644 --- a/browser_extensions/chrome/js/utils_chrome.js +++ b/browser_extensions/chrome/js/utils_chrome.js @@ -4,22 +4,15 @@ var utils_chrome = (function() { - var BG_PAGE = chrome.extension.getBackgroundPage(); - var SYNC_STORAGE = BG_PAGE.SYNC_STORAGE; - var CACHED_SETTINGS = BG_PAGE.CACHED_SETTINGS; - - return { - BG_PAGE: BG_PAGE, - SYNC_STORAGE: SYNC_STORAGE, - CACHED_SETTINGS: CACHED_SETTINGS, - get_i18n: function(message_name) { - return chrome.i18n.getMessage(message_name); - }, - print_sync_storage: function() { - SYNC_STORAGE.get(null, function(items) { - console.log('SYNC_STORAGE: %O', items); - }); - } - }; + return { + get_i18n: function(message_name) { + return chrome.i18n.getMessage(message_name); + }, + print_sync_storage: function() { + SYNC_STORAGE.get(null, function(items) { + console.log('SYNC_STORAGE: %O', items); + }); + } + }; }()); diff --git a/browser_extensions/chrome/manifest.json b/browser_extensions/chrome/manifest.json index 910ba20..497a2fd 100644 --- a/browser_extensions/chrome/manifest.json +++ b/browser_extensions/chrome/manifest.json @@ -1,7 +1,7 @@ { - "manifest_version": 2, + "manifest_version": 3, "name": "__MSG_extension_name__", - "version": "4.0.7", + "version": "5.0.0", "default_locale": "zh_TW", "description": "__MSG_extension_description__", "icons": { @@ -9,17 +9,19 @@ "48": "images/icon_48.png", "128": "images/icon_128.png" }, - "browser_action": { - "default_icon": "images/icon_19.png", + "action": { + "default_icon": { + "16": "images/icon_16.png", + "32": "images/icon_32.png", + "48": "images/icon_48.png" + }, "default_title": "__MSG_god_of_spacing__", "default_popup": "pages/popup.html" }, "author": "Vinta", "background": { - "scripts": [ - "js/background.js" - ], - "persistent": true + "service_worker": "js/service_worker.js", + "type": "module" }, "content_scripts": [ { @@ -39,10 +41,15 @@ "offline_enabled": true, "options_page": "pages/options.html", "permissions": [ + "scripting", "storage", - "tabs", + "tabs" + ], + "host_permissions": [ "http://*/*", - "https://*/*", + "https://*/*" + ], + "optional_host_permissions": [ "file:///*/*" ], "short_name": "__MSG_god_of_spacing__"