[gnome-browser-extension/wip/refactor: 7/7] Format code
- From: Yuri Konotopov <ykonotopov src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-browser-extension/wip/refactor: 7/7] Format code
- Date: Thu, 4 Aug 2022 18:59:51 +0000 (UTC)
commit 9ecca91282ca9ca0aa618d5b7181e03273ee7ecb
Author: Yuri Konotopov <ykonotopov gnome org>
Date: Thu Aug 4 22:40:52 2022 +0400
Format code
1. Use spaces instead of tabs
2. Use open curly bracket on same line
3. Use space after operator before parenthesis
extension/content-script-start.js | 53 +-
extension/css/options.css | 143 ++---
extension/extension.js | 320 ++++++-----
extension/include/compat-common.js | 160 +++---
extension/include/compat-content-script.js | 68 ++-
extension/include/constants.js | 96 ++--
extension/include/gsc.js | 260 +++++----
extension/include/i18n.js | 43 +-
extension/include/notifications.js | 396 +++++++-------
extension/include/sweettooth-api.js | 397 +++++++-------
extension/include/sync.js | 832 ++++++++++++++---------------
extension/include/toolbar.js | 90 ++--
extension/include/update.js | 360 ++++++-------
extension/options.html | 229 ++++----
extension/options.js | 703 +++++++++++-------------
15 files changed, 1981 insertions(+), 2169 deletions(-)
---
diff --git a/extension/content-script-start.js b/extension/content-script-start.js
index 2772662..dfa820d 100644
--- a/extension/content-script-start.js
+++ b/extension/content-script-start.js
@@ -6,51 +6,48 @@
*/
var gs_require_inject = function () {
- GS_CHROME_ID = "${GS_CHROME_ID}";
- GS_CHROME_VERSION = "${GS_CHROME_VERSION}";
+ GS_CHROME_ID = "${GS_CHROME_ID}";
+ GS_CHROME_VERSION = "${GS_CHROME_VERSION}";
};
var siteMessages = {};
-if(EXTERNAL_MESSAGES)
-{
- for(var key in EXTERNAL_MESSAGES)
- {
- siteMessages[EXTERNAL_MESSAGES[key]] = chrome.i18n.getMessage(EXTERNAL_MESSAGES[key]);
- }
+if (EXTERNAL_MESSAGES) {
+ for (var key in EXTERNAL_MESSAGES) {
+ siteMessages[EXTERNAL_MESSAGES[key]] = chrome.i18n.getMessage(EXTERNAL_MESSAGES[key]);
+ }
}
var s = document.createElement('script');
s.type = "text/javascript";
s.textContent = '(' +
- gs_require_inject.toString()
- .replace("${GS_CHROME_ID}", GS_CHROME_ID)
- .replace("${GS_CHROME_VERSION}", chrome.runtime.getManifest().version)
- + ")(); GSC = {i18n: JSON.parse('" + JSON.stringify(siteMessages).replace(/'/g, "\\'") + "')};";
-(document.head||document.documentElement).appendChild(s);
+ gs_require_inject.toString()
+ .replace("${GS_CHROME_ID}", GS_CHROME_ID)
+ .replace("${GS_CHROME_VERSION}", chrome.runtime.getManifest().version)
+ + ")(); GSC = {i18n: JSON.parse('" + JSON.stringify(siteMessages).replace(/'/g, "\\'") + "')};";
+(document.head || document.documentElement).appendChild(s);
s.parentNode.removeChild(s);
chrome.runtime.onMessage.addListener(
- function (request, sender, sendResponse) {
- if(
- sender.id && sender.id === GS_CHROME_ID &&
- request && request.signal &&
- [SIGNAL_EXTENSION_CHANGED, SIGNAL_SHELL_APPEARED,
SIGNAL_SHELL_SETTING_CHANGED].indexOf(request.signal) !== -1)
- {
- window.postMessage(
- {
- type: "gs-chrome",
- request: request
- }, "*"
- );
- }
- }
+ function (request, sender, sendResponse) {
+ if (
+ sender.id && sender.id === GS_CHROME_ID &&
+ request && request.signal &&
+ [SIGNAL_EXTENSION_CHANGED, SIGNAL_SHELL_APPEARED,
SIGNAL_SHELL_SETTING_CHANGED].indexOf(request.signal) !== -1) {
+ window.postMessage(
+ {
+ type: "gs-chrome",
+ request: request
+ }, "*"
+ );
+ }
+ }
);
s = document.createElement('script');
s.src = chrome.extension.getURL('include/sweettooth-api.js');
-s.onload = function() {
+s.onload = function () {
this.parentNode.removeChild(this);
};
(document.head || document.documentElement).appendChild(s);
diff --git a/extension/css/options.css b/extension/css/options.css
index 3c7ba6e..456bb04 100644
--- a/extension/css/options.css
+++ b/extension/css/options.css
@@ -1,125 +1,144 @@
body {
- font-family: Cantarell, Arial, sans-serif;
- padding: 10px;
- min-width: 550px;
+ font-family: Cantarell, Arial, sans-serif;
+ padding: 10px;
+ min-width: 550px;
+}
+
+#update_check_period {
+ width: 5em;
}
-#update_check_period { width: 5em; }
#status {
- visibility: hidden;
- opacity: 0;
- color: green;
- text-align: center;
+ visibility: hidden;
+ opacity: 0;
+ color: green;
+ text-align: center;
}
#error {
- visibility: hidden;
- opacity: 0;
- color: red;
- text-align: center;
+ visibility: hidden;
+ opacity: 0;
+ color: red;
+ text-align: center;
}
.show {
- visibility: visible !important;
- opacity: 1 !important;
- transition: visibility 0.25s, opacity 0.25s ease-in-out;
+ visibility: visible !important;
+ opacity: 1 !important;
+ transition: visibility 0.25s, opacity 0.25s ease-in-out;
}
.hide {
- display: none;
+ display: none;
}
-.buttons { text-align: center; margin-top: 1em; }
-.notice { font-size: 90%; font-weight: normal; margin-top: 0.5em; white-space: nowrap; }
-.update-notice { display: none; }
-.wrapped { white-space: normal; }
+.buttons {
+ text-align: center;
+ margin-top: 1em;
+}
+
+.notice {
+ font-size: 90%;
+ font-weight: normal;
+ margin-top: 0.5em;
+ white-space: nowrap;
+}
+
+.update-notice {
+ display: none;
+}
+
+.wrapped {
+ white-space: normal;
+}
fieldset {
- border: 0;
- margin: 0;
- padding: 0;
- width: 100%;
+ border: 0;
+ margin: 0;
+ padding: 0;
+ width: 100%;
}
dl {
- padding: 0.2em 0;
- clear: both;
+ padding: 0.2em 0;
+ clear: both;
}
dt {
- display: block;
- float: left;
- width: 50%;
- text-align: left;
- font-weight: bold;
+ display: block;
+ float: left;
+ width: 50%;
+ text-align: left;
+ font-weight: bold;
}
dd {
- margin-left: 51%;
- vertical-align: top;
- margin-bottom: 3px;
+ margin-left: 51%;
+ vertical-align: top;
+ margin-bottom: 3px;
}
ul.tabs {
- float: right;
+ float: right;
}
ul.tabs li {
- list-style: none;
+ list-style: none;
}
-ul.tabs li, ul.tabs li a {
- display: inline-block;
+ul.tabs li,
+ul.tabs li a {
+ display: inline-block;
}
ul.tabs li a.active {
- color: inherit;
- cursor: default;
- text-decoration: none;
+ color: inherit;
+ cursor: default;
+ text-decoration: none;
}
ul.tabs li:not(:last-child) {
- border-right: 1px solid #000;
- margin-right: 5px;
- padding-right: 5px;
+ border-right: 1px solid #000;
+ margin-right: 5px;
+ padding-right: 5px;
}
div.tabs-pane {
- clear: both;
+ clear: both;
}
#synchronization table {
- width: 100%;
- border-collapse: collapse;
- vertical-align: middle;
+ width: 100%;
+ border-collapse: collapse;
+ vertical-align: middle;
}
#synchronization table th {
- border-bottom: 1px solid #000;
+ border-bottom: 1px solid #000;
}
-#synchronization table tbody td.ok, #synchronization table td.fail {
- text-align: center;
- font-size: 150%;
+#synchronization table tbody td.ok,
+#synchronization table td.fail {
+ text-align: center;
+ font-size: 150%;
}
#synchronization table tbody td.ok:after {
- content: '\2713';
- color: green;
+ content: '\2713';
+ color: green;
}
#synchronization table td.fail:after {
- content: '\2717';
- color: red;
+ content: '\2717';
+ color: red;
}
dialog#syncChoice button {
- display: block;
- width: 90%;
- margin: 0.3em auto;
+ display: block;
+ width: 90%;
+ margin: 0.3em auto;
}
-div#translation_credits div
-{
- white-space: pre-line;
+div#translation_credits div {
+ white-space: pre-line;
}
diff --git a/extension/extension.js b/extension/extension.js
index 0b752db..f1032dd 100644
--- a/extension/extension.js
+++ b/extension/extension.js
@@ -1,196 +1,178 @@
// SPDX-License-Identifer: GPL-3.0-or-later
-chrome.runtime.onInstalled.addListener(function(details) {
- var version = chrome.runtime.getManifest().version;
-
- if(details.reason == chrome.runtime.OnInstalledReason.UPDATE && details.previousVersion != version)
- {
- chrome.storage.sync.get(DEFAULT_SYNC_OPTIONS, function (options) {
- if(options.showReleaseNotes)
- {
- chrome.tabs.create({
- url:
'https://wiki.gnome.org/Projects/GnomeShellIntegrationForChrome/ReleaseNotes/' + version,
- active: true
- });
- }
- });
- }
+chrome.runtime.onInstalled.addListener(function (details) {
+ var version = chrome.runtime.getManifest().version;
+
+ if (details.reason == chrome.runtime.OnInstalledReason.UPDATE && details.previousVersion != version) {
+ chrome.storage.sync.get(DEFAULT_SYNC_OPTIONS, function (options) {
+ if (options.showReleaseNotes) {
+ chrome.tabs.create({
+ url: 'https://wiki.gnome.org/Projects/GnomeShellIntegrationForChrome/ReleaseNotes/' +
version,
+ active: true
+ });
+ }
+ });
+ }
});
chrome.runtime.onMessageExternal.addListener(function (request, sender, sendResponse) {
- if (
- EXTENSIONS_WEBSITE.reduce(
- (accumulator, url) => accumulator + sender.url.startsWith(url),
- 0)
- )
- {
- if (request && request.execute)
- {
- if (request.uuid && !GSC.isUUID(request.uuid))
- {
- return;
- }
-
- switch (request.execute)
- {
- case 'initialize':
- case 'listExtensions':
- GSC.sendNativeRequest({execute: request.execute}, sendResponse);
- return true;
-
- case 'launchExtensionPrefs':
- GSC.sendNativeRequest({execute: request.execute, uuid: request.uuid});
- break;
-
- case 'getExtensionErrors':
- case 'getExtensionInfo':
- case 'installExtension':
- case 'uninstallExtension':
- GSC.sendNativeRequest({execute: request.execute, uuid: request.uuid},
sendResponse);
- return true;
-
- case 'enableExtension':
- GSC.sendNativeRequest({
- execute: request.execute,
- uuid: request.uuid,
- enable: request.enable
- },
- sendResponse
- );
- return true;
-
- case 'setUserExtensionsDisabled':
- case 'setVersionValidationDisabled':
- GSC.sendNativeRequest({execute: request.execute, disable:
request.disable ? true : false}, sendResponse);
- return true;
- }
- }
- }
+ if (
+ EXTENSIONS_WEBSITE.reduce(
+ (accumulator, url) => accumulator + sender.url.startsWith(url),
+ 0)
+ ) {
+ if (request && request.execute) {
+ if (request.uuid && !GSC.isUUID(request.uuid)) {
+ return;
+ }
+
+ switch (request.execute) {
+ case 'initialize':
+ case 'listExtensions':
+ GSC.sendNativeRequest({ execute: request.execute }, sendResponse);
+ return true;
+
+ case 'launchExtensionPrefs':
+ GSC.sendNativeRequest({ execute: request.execute, uuid: request.uuid });
+ break;
+
+ case 'getExtensionErrors':
+ case 'getExtensionInfo':
+ case 'installExtension':
+ case 'uninstallExtension':
+ GSC.sendNativeRequest({ execute: request.execute, uuid: request.uuid }, sendResponse);
+ return true;
+
+ case 'enableExtension':
+ GSC.sendNativeRequest({
+ execute: request.execute,
+ uuid: request.uuid,
+ enable: request.enable
+ },
+ sendResponse
+ );
+ return true;
+
+ case 'setUserExtensionsDisabled':
+ case 'setVersionValidationDisabled':
+ GSC.sendNativeRequest({ execute: request.execute, disable: request.disable ? true :
false }, sendResponse);
+ return true;
+ }
+ }
+ }
});
EXTENSIONS_WEBSITE.forEach(url => {
- chrome.browserAction.onClicked.addListener(function () {
- chrome.tabs.create({
- url: url,
- active: true
- });
- });
+ chrome.browserAction.onClicked.addListener(function () {
+ chrome.tabs.create({
+ url: url,
+ active: true
+ });
+ });
});
var disabledExtensionTimeout = null;
-var lastPortMessage = {message: null, date: 0};
+var lastPortMessage = { message: null, date: 0 };
var port = chrome.runtime.connectNative(NATIVE_HOST);
/*
* Native host messaging events handler.
*/
port.onMessage.addListener(function (message) {
- if (message && message.signal)
- {
- if([SIGNAL_EXTENSION_CHANGED, SIGNAL_SHELL_APPEARED,
SIGNAL_SHELL_SETTING_CHANGED].indexOf(message.signal) !== -1)
- {
- /*
- * Skip duplicate events. This is happens eg when extension is installed.
- */
- if (
- message.signal != SIGNAL_SHELL_SETTING_CHANGED &&
- (new Date().getTime()) - lastPortMessage.date < 1000 &&
GSC.isSignalsEqual(message, lastPortMessage.message)
- )
- {
- lastPortMessage.date = new Date().getTime();
- return;
- }
-
- /*
- * Send events to opened extensions.gnome.org tabs
- */
- EXTENSIONS_WEBSITE.forEach(url => {
- chrome.tabs.query({
- url: url + '*'
- },
- function (tabs) {
- for (k in tabs)
- {
- chrome.tabs.sendMessage(tabs[k].id, message);
- }
- });
- });
-
- /*
- * Route message to Options page.
- */
- chrome.runtime.sendMessage(GS_CHROME_ID, message);
- if (message.signal === SIGNAL_EXTENSION_CHANGED)
- {
- /*
- * GNOME Shell sends 2 events when extension is uninstalled:
- * "disabled" event and then "uninstalled" event.
- * Let's delay any "disabled" event and drop it if
- * "uninstalled" event received within 1,5 secs.
- */
- if (message.parameters[EXTENSION_CHANGED_STATE] === EXTENSION_STATE.DISABLED)
- {
- disabledExtensionTimeout = setTimeout(function () {
- disabledExtensionTimeout = null;
- GSC.sync.onExtensionChanged(message);
- }, 1500);
- }
- else if (
- disabledExtensionTimeout &&
- message.parameters[EXTENSION_CHANGED_STATE] ===
EXTENSION_STATE.UNINSTALLED &&
- lastPortMessage.message.signal === SIGNAL_EXTENSION_CHANGED &&
- lastPortMessage.message.parameters[EXTENSION_CHANGED_UUID] ===
message.parameters[EXTENSION_CHANGED_UUID] &&
- lastPortMessage.message.parameters[EXTENSION_CHANGED_STATE] ===
EXTENSION_STATE.DISABLED
- )
- {
- clearTimeout(disabledExtensionTimeout);
- disabledExtensionTimeout = null;
- GSC.sync.onExtensionChanged(message);
- }
- else
- {
- GSC.sync.onExtensionChanged(message);
- }
- }
-
- lastPortMessage = {
- message: message,
- date: new Date().getTime()
- };
- }
- else if([SIGNAL_NOTIFICATION_ACTION, SIGNAL_NOTIFICATION_CLICKED].indexOf(message.signal) !=
-1)
- {
- window.postMessage(message, "*");
- }
- }
+ if (message && message.signal) {
+ if ([SIGNAL_EXTENSION_CHANGED, SIGNAL_SHELL_APPEARED,
SIGNAL_SHELL_SETTING_CHANGED].indexOf(message.signal) !== -1) {
+ /*
+ * Skip duplicate events. This is happens eg when extension is installed.
+ */
+ if (
+ message.signal != SIGNAL_SHELL_SETTING_CHANGED &&
+ (new Date().getTime()) - lastPortMessage.date < 1000 && GSC.isSignalsEqual(message,
lastPortMessage.message)
+ ) {
+ lastPortMessage.date = new Date().getTime();
+ return;
+ }
+
+ /*
+ * Send events to opened extensions.gnome.org tabs
+ */
+ EXTENSIONS_WEBSITE.forEach(url => {
+ chrome.tabs.query({
+ url: url + '*'
+ },
+ function (tabs) {
+ for (k in tabs) {
+ chrome.tabs.sendMessage(tabs[k].id, message);
+ }
+ });
+ });
+
+ /*
+ * Route message to Options page.
+ */
+ chrome.runtime.sendMessage(GS_CHROME_ID, message);
+ if (message.signal === SIGNAL_EXTENSION_CHANGED) {
+ /*
+ * GNOME Shell sends 2 events when extension is uninstalled:
+ * "disabled" event and then "uninstalled" event.
+ * Let's delay any "disabled" event and drop it if
+ * "uninstalled" event received within 1,5 secs.
+ */
+ if (message.parameters[EXTENSION_CHANGED_STATE] === EXTENSION_STATE.DISABLED) {
+ disabledExtensionTimeout = setTimeout(function () {
+ disabledExtensionTimeout = null;
+ GSC.sync.onExtensionChanged(message);
+ }, 1500);
+ }
+ else if (
+ disabledExtensionTimeout &&
+ message.parameters[EXTENSION_CHANGED_STATE] === EXTENSION_STATE.UNINSTALLED &&
+ lastPortMessage.message.signal === SIGNAL_EXTENSION_CHANGED &&
+ lastPortMessage.message.parameters[EXTENSION_CHANGED_UUID] ===
message.parameters[EXTENSION_CHANGED_UUID] &&
+ lastPortMessage.message.parameters[EXTENSION_CHANGED_STATE] === EXTENSION_STATE.DISABLED
+ ) {
+ clearTimeout(disabledExtensionTimeout);
+ disabledExtensionTimeout = null;
+ GSC.sync.onExtensionChanged(message);
+ }
+ else {
+ GSC.sync.onExtensionChanged(message);
+ }
+ }
+
+ lastPortMessage = {
+ message: message,
+ date: new Date().getTime()
+ };
+ }
+ else if ([SIGNAL_NOTIFICATION_ACTION, SIGNAL_NOTIFICATION_CLICKED].indexOf(message.signal) != -1) {
+ window.postMessage(message, "*");
+ }
+ }
});
/*
* Subscribe to GNOME Shell signals
*/
-port.postMessage({execute: 'subscribeSignals'});
+port.postMessage({ execute: 'subscribeSignals' });
window.addEventListener("message", function (event) {
- // We only accept messages from ourselves
- if (event.source == window && event.data && event.data.execute)
- {
- switch (event.data.execute)
- {
- case 'createNotification':
- port.postMessage(event.data);
- break;
- case 'removeNotification':
- port.postMessage(event.data);
- break;
- }
- }
- }
+ // We only accept messages from ourselves
+ if (event.source == window && event.data && event.data.execute) {
+ switch (event.data.execute) {
+ case 'createNotification':
+ port.postMessage(event.data);
+ break;
+ case 'removeNotification':
+ port.postMessage(event.data);
+ break;
+ }
+ }
+}
);
-chrome.runtime.getPlatformInfo(function(info) {
- if (PLATFORMS_WHITELIST.indexOf(info.os) !== -1)
- {
- GSC.update.init();
- GSC.sync.init();
- }
+chrome.runtime.getPlatformInfo(function (info) {
+ if (PLATFORMS_WHITELIST.indexOf(info.os) !== -1) {
+ GSC.update.init();
+ GSC.sync.init();
+ }
});
GSC.toolbar.init();
diff --git a/extension/include/compat-common.js b/extension/include/compat-common.js
index a0d17a5..0ad3cd3 100644
--- a/extension/include/compat-common.js
+++ b/extension/include/compat-common.js
@@ -6,106 +6,98 @@ $ = (...args) => document.querySelector(...args);
$$ = (...args) => document.querySelectorAll(...args);
function empty(element) {
- while(element.firstChild) element.removeChild(element.firstChild);
+ while (element.firstChild) element.removeChild(element.firstChild);
}
function isEmptyObject(object) {
- for (const k in object) return false;
- return true;
+ for (const k in object) return false;
+ return true;
}
function showWithDelay(element, delay, message) {
- if (message) {
- element.innerHtml = message;
- }
+ if (message) {
+ element.innerHtml = message;
+ }
- element.classList.remove('hide');
- element.classList.add('show');
- setTimeout(() => {
- element.classList.remove('show');
- setTimeout(() => {
- element.classList.add('hide');
- }, 250);
- }, delay);
+ element.classList.remove('hide');
+ element.classList.add('show');
+ setTimeout(() => {
+ element.classList.remove('show');
+ setTimeout(() => {
+ element.classList.add('hide');
+ }, 250);
+ }, delay);
}
-COMPAT.PERMISSIONS_CONTAINS = true;
-COMPAT.PERMISSIONS_EVENTS = true;
-COMPAT.SYNC_STORAGE = true;
-COMPAT.NOTIFICATIONS_BUTTONS = (!COMPAT.IS_FIREFOX || false);
+COMPAT.PERMISSIONS_CONTAINS = true;
+COMPAT.PERMISSIONS_EVENTS = true;
+COMPAT.SYNC_STORAGE = true;
+COMPAT.NOTIFICATIONS_BUTTONS = (!COMPAT.IS_FIREFOX || false);
-if(COMPAT.IS_FIREFOX)
-{
- chrome.runtime.onMessageExternal = {
- addListener: chrome.runtime.onMessage.addListener
- };
+if (COMPAT.IS_FIREFOX) {
+ chrome.runtime.onMessageExternal = {
+ addListener: chrome.runtime.onMessage.addListener
+ };
}
-if(typeof(chrome.permissions) === 'undefined')
-{
- chrome.permissions = {
- contains: function(permissions, callback) {
- callback(false);
- }
- };
- COMPAT.PERMISSIONS_CONTAINS = false;
+if (typeof (chrome.permissions) === 'undefined') {
+ chrome.permissions = {
+ contains: function (permissions, callback) {
+ callback(false);
+ }
+ };
+ COMPAT.PERMISSIONS_CONTAINS = false;
}
-if(typeof(chrome.permissions.onAdded) === 'undefined' || typeof(chrome.permissions.onRemoved) ===
'undefined')
-{
- chrome.permissions.onAdded = {
- addListener: function(callback) {
- chrome.runtime.onMessage.addListener(
- function (request, sender, sendResponse) {
- if (sender.id && sender.id === GS_CHROME_ID && request)
- {
- if (request === MESSAGE_IDLE_PERMISSION_ADDED)
- {
- callback({
- permissions: ['idle']
- });
- }
- }
- }
- );
- },
- removeListener: function(callback) {
- chrome.runtime.onMessage.removeListener(callback);
- },
- hasListener: function(callback) {
- return chrome.runtime.onMessage.hasListener(callback);
- }
- }
+if (typeof (chrome.permissions.onAdded) === 'undefined' || typeof (chrome.permissions.onRemoved) ===
'undefined') {
+ chrome.permissions.onAdded = {
+ addListener: function (callback) {
+ chrome.runtime.onMessage.addListener(
+ function (request, sender, sendResponse) {
+ if (sender.id && sender.id === GS_CHROME_ID && request) {
+ if (request === MESSAGE_IDLE_PERMISSION_ADDED) {
+ callback({
+ permissions: ['idle']
+ });
+ }
+ }
+ }
+ );
+ },
+ removeListener: function (callback) {
+ chrome.runtime.onMessage.removeListener(callback);
+ },
+ hasListener: function (callback) {
+ return chrome.runtime.onMessage.hasListener(callback);
+ }
+ }
- chrome.permissions.onRemoved = {
- addListener: function(callback) {
- chrome.runtime.onMessage.addListener(
- function (request, sender, sendResponse) {
- if (sender.id && sender.id === GS_CHROME_ID && request)
- {
- if (request === MESSAGE_IDLE_PERMISSION_REMOVED)
- {
- callback({
- permissions: ['idle']
- });
- }
- }
- }
- );
- },
- removeListener: function(callback) {
- chrome.runtime.onMessage.removeListener(callback);
- },
- hasListener: function(callback) {
- return chrome.runtime.onMessage.hasListener(callback);
- }
- }
+ chrome.permissions.onRemoved = {
+ addListener: function (callback) {
+ chrome.runtime.onMessage.addListener(
+ function (request, sender, sendResponse) {
+ if (sender.id && sender.id === GS_CHROME_ID && request) {
+ if (request === MESSAGE_IDLE_PERMISSION_REMOVED) {
+ callback({
+ permissions: ['idle']
+ });
+ }
+ }
+ }
+ );
+ },
+ removeListener: function (callback) {
+ chrome.runtime.onMessage.removeListener(callback);
+ },
+ hasListener: function (callback) {
+ return chrome.runtime.onMessage.hasListener(callback);
+ }
+ }
- COMPAT.PERMISSIONS_EVENTS = false;
+ COMPAT.PERMISSIONS_EVENTS = false;
}
-if(typeof(chrome.storage.sync) === 'undefined')
-{
- chrome.storage.sync = chrome.storage.local;
- COMPAT.SYNC_STORAGE = false;
+if (typeof (chrome.storage.sync) === 'undefined') {
+ chrome.storage.sync = chrome.storage.local;
+ COMPAT.SYNC_STORAGE = false;
}
diff --git a/extension/include/compat-content-script.js b/extension/include/compat-content-script.js
index f6870d2..448f55f 100644
--- a/extension/include/compat-content-script.js
+++ b/extension/include/compat-content-script.js
@@ -1,42 +1,38 @@
// SPDX-License-Identifer: GPL-3.0-or-later
-if(!window.chrome)
-{
- (function() {
- // Define the API subset provided to the webpage
- var externalMessaging = {
- runtime: {
- sendMessage: function (extensionId, message, options, responseCallback) {
- if(extensionId !== chrome.runtime.id)
- {
- console.error('Wrong extension id provided.')
- return;
- }
+if (!window.chrome) {
+ (function () {
+ // Define the API subset provided to the webpage
+ var externalMessaging = {
+ runtime: {
+ sendMessage: function (extensionId, message, options, responseCallback) {
+ if (extensionId !== chrome.runtime.id) {
+ console.error('Wrong extension id provided.')
+ return;
+ }
- if(typeof(options) === 'function')
- {
- responseCallback = options;
- options = undefined;
- }
+ if (typeof (options) === 'function') {
+ responseCallback = options;
+ options = undefined;
+ }
- chrome.runtime.sendMessage(extensionId, message, options)
- .then(result => {
- if(typeof(responseCallback) == 'function')
- {
- responseCallback(cloneInto(result, window));
- }
- })
- .catch(err => {
- console.error("firefox-external-messaging:
runtime.sendMessage error", err);
- });
- }
- }
- };
+ chrome.runtime.sendMessage(extensionId, message, options)
+ .then(result => {
+ if (typeof (responseCallback) == 'function') {
+ responseCallback(cloneInto(result, window));
+ }
+ })
+ .catch(err => {
+ console.error("firefox-external-messaging: runtime.sendMessage error", err);
+ });
+ }
+ }
+ };
- // Inject the API in the webpage wrapped by this content script
- // (exposed as `chrome.runtime.sendMessage({anyProp: "anyValue"}).then(reply => ..., err =>
...)`)
- window.wrappedJSObject.chrome = cloneInto(externalMessaging, window, {
- cloneFunctions: true,
- });
- })();
+ // Inject the API in the webpage wrapped by this content script
+ // (exposed as `chrome.runtime.sendMessage({anyProp: "anyValue"}).then(reply => ..., err => ...)`)
+ window.wrappedJSObject.chrome = cloneInto(externalMessaging, window, {
+ cloneFunctions: true,
+ });
+ })();
}
diff --git a/extension/include/constants.js b/extension/include/constants.js
index 87adf55..976a63b 100644
--- a/extension/include/constants.js
+++ b/extension/include/constants.js
@@ -1,73 +1,73 @@
// SPDX-License-Identifer: GPL-3.0-or-later
-GS_CHROME_ID = chrome.runtime.id;
-PLATFORMS_WHITELIST = ["freebsd", "linux", "openbsd"];
+GS_CHROME_ID = chrome.runtime.id;
+PLATFORMS_WHITELIST = ["freebsd", "linux", "openbsd"];
COMPAT = {
- IS_FIREFOX: CSS.supports("-moz-appearance: none"),
+ IS_FIREFOX: CSS.supports("-moz-appearance: none"),
};
-NOTIFICATION_SYNC_FAILED = 'gs-chrome-sync-fail';
-NOTIFICATION_UPDATE_AVAILABLE = 'gs-chrome-update';
-ALARM_UPDATE_CHECK = 'gs-chrome-update-check';
+NOTIFICATION_SYNC_FAILED = 'gs-chrome-sync-fail';
+NOTIFICATION_UPDATE_AVAILABLE = 'gs-chrome-update';
+ALARM_UPDATE_CHECK = 'gs-chrome-update-check';
-MESSAGE_NEXT_UPDATE_CHANGED = 'gs-next-update-changed';
-MESSAGE_SYNC_FROM_REMOTE = 'gs-sync-from-remote';
-MESSAGE_IDLE_PERMISSION_ADDED = 'gs-idle-added';
-MESSAGE_IDLE_PERMISSION_REMOVED = 'gs-idle-removed';
+MESSAGE_NEXT_UPDATE_CHANGED = 'gs-next-update-changed';
+MESSAGE_SYNC_FROM_REMOTE = 'gs-sync-from-remote';
+MESSAGE_IDLE_PERMISSION_ADDED = 'gs-idle-added';
+MESSAGE_IDLE_PERMISSION_REMOVED = 'gs-idle-removed';
-SIGNAL_EXTENSION_CHANGED = 'ExtensionStatusChanged';
-SIGNAL_NOTIFICATION_ACTION = 'NotificationAction';
-SIGNAL_NOTIFICATION_CLICKED = 'NotificationClicked';
-SIGNAL_SHELL_SETTING_CHANGED = 'ShellSettingsChanged';
-SIGNAL_SHELL_APPEARED = 'org.gnome.Shell';
+SIGNAL_EXTENSION_CHANGED = 'ExtensionStatusChanged';
+SIGNAL_NOTIFICATION_ACTION = 'NotificationAction';
+SIGNAL_NOTIFICATION_CLICKED = 'NotificationClicked';
+SIGNAL_SHELL_SETTING_CHANGED = 'ShellSettingsChanged';
+SIGNAL_SHELL_APPEARED = 'org.gnome.Shell';
-EXTENSION_CHANGED_UUID = 0;
-EXTENSION_CHANGED_STATE = 1;
-EXTENSION_CHANGED_ERROR = 2;
+EXTENSION_CHANGED_UUID = 0;
+EXTENSION_CHANGED_STATE = 1;
+EXTENSION_CHANGED_ERROR = 2;
-NATIVE_HOST = 'org.gnome.chrome_gnome_shell';
+NATIVE_HOST = 'org.gnome.chrome_gnome_shell';
-EXTENSIONS_WEBSITE = [
- 'https://extensions.gnome.org/',
+EXTENSIONS_WEBSITE = [
+ 'https://extensions.gnome.org/',
];
-UPDATE_URL = EXTENSIONS_WEBSITE + 'update-info/';
+UPDATE_URL = EXTENSIONS_WEBSITE + 'update-info/';
-DEFAULT_SYNC_OPTIONS = {
- showReleaseNotes: true,
- updateCheck: true,
- updateCheckEnabledOnly: true,
- updateCheckPeriod: 6
+DEFAULT_SYNC_OPTIONS = {
+ showReleaseNotes: true,
+ updateCheck: true,
+ updateCheckEnabledOnly: true,
+ updateCheckPeriod: 6
};
-DEFAULT_LOCAL_OPTIONS = {
- syncExtensions: false,
- useLightIcon: false
+DEFAULT_LOCAL_OPTIONS = {
+ syncExtensions: false,
+ useLightIcon: false
};
-EXTERNAL_MESSAGES = [
- "error_connector_response",
- "no_gnome_shell",
- "no_host_connector",
- "warning_apis_missing"
+EXTERNAL_MESSAGES = [
+ "error_connector_response",
+ "no_gnome_shell",
+ "no_host_connector",
+ "warning_apis_missing"
];
// gnome-shell/js/ui/extensionSystem.js
-EXTENSION_STATE = {
- ENABLED: 1,
- DISABLED: 2,
- ERROR: 3,
- OUT_OF_DATE: 4,
- DOWNLOADING: 5,
- INITIALIZED: 6,
+EXTENSION_STATE = {
+ ENABLED: 1,
+ DISABLED: 2,
+ ERROR: 3,
+ OUT_OF_DATE: 4,
+ DOWNLOADING: 5,
+ INITIALIZED: 6,
- // Used as an error state for operations on unknown extensions,
- // should never be in a real extensionMeta object.
- UNINSTALLED: 99
+ // Used as an error state for operations on unknown extensions,
+ // should never be in a real extensionMeta object.
+ UNINSTALLED: 99
};
// gnome-shell/js/misc/extensionUtils.js
-EXTENSION_TYPE = {
- SYSTEM: 1,
- PER_USER: 2
+EXTENSION_TYPE = {
+ SYSTEM: 1,
+ PER_USER: 2
};
diff --git a/extension/include/gsc.js b/extension/include/gsc.js
index 7f52885..8e00907 100644
--- a/extension/include/gsc.js
+++ b/extension/include/gsc.js
@@ -1,140 +1,126 @@
// SPDX-License-Identifer: GPL-3.0-or-later
-GSC = (function() {
- var ready = new Promise(function(resolve, reject) {
- chrome.runtime.getPlatformInfo(function(info) {
- if (PLATFORMS_WHITELIST.indexOf(info.os) === -1)
- {
- reject();
- }
- else
- {
- resolve();
- }
- });
- });
- ready.catch(function() {});
-
- var onInitialize = new Promise((resolve, reject) => {
- sendNativeRequest({ execute: "initialize" }, (response) => {
- if(response && response.success)
- {
- resolve(response);
- }
- else
- {
- reject(response);
- }
- });
- });
-
- function sendNativeRequest(request, sendResponse) {
- ready.then(function () {
- if (sendResponse)
- {
- chrome.runtime.sendNativeMessage(
- NATIVE_HOST,
- request,
- function (response) {
- if (response)
- {
- sendResponse(response);
- }
- else
- {
- var message = m('no_host_connector');
- if (
- chrome.runtime.lastError &&
- chrome.runtime.lastError.message &&
-
chrome.runtime.lastError.message.indexOf("host not found") === -1 && // Chrome
-
chrome.runtime.lastError.message.indexOf("disconnected port") === -1 // Firefox
- )
- {
- // Some error occured. Show to user
- message = chrome.runtime.lastError.message;
- }
-
- sendResponse({
- success: false,
- message: message
- });
- }
- }
- );
- }
- else
- {
- chrome.runtime.sendNativeMessage(NATIVE_HOST, request);
- }
- }, function () {
- if (sendResponse)
- {
- sendResponse({
- success: false,
- message: m('platform_not_supported')
- });
- }
- });
- }
-
- function isSupported(feature, response) {
- return response.properties &&
- response.properties.supports && response.properties.supports.indexOf(feature)
!== -1;
- }
-
- return {
- // https://wiki.gnome.org/Projects/GnomeShell/Extensions/UUIDGuidelines
- isUUID: function(uuid) {
- return uuid && uuid.match('^[-a-zA-Z0-9@._]+$');
- },
-
- sendNativeRequest: sendNativeRequest,
-
- isSignalsEqual: function(newSignal, oldSignal) {
- if(!oldSignal || !newSignal)
- return false;
-
- if(!newSignal.signal || !oldSignal.signal || newSignal.signal !== oldSignal.signal)
- return false;
-
- if(newSignal.parameters)
- {
- if(!oldSignal.parameters)
- return false;
-
- if(newSignal.parameters.length !== oldSignal.parameters.length)
- return false;
-
- for(var i = 0; i < newSignal.parameters.length; i++)
- {
- if(newSignal.parameters[i] !== oldSignal.parameters[i])
- {
- return false;
- }
- }
- }
- else if (oldSignal.parameters)
- {
- return false;
- }
-
- return true;
- },
-
- onInitialize: function() {
- return onInitialize;
- },
-
- nativeNotificationsSupported: function (response) {
- return isSupported('notifications', response);
- },
-
- nativeUpdateCheckSupported: function (response) {
- return isSupported('update-check', response);
- },
-
- nativeUpdateCheckEnabledOnlySupported: function (response) {
- return isSupported('update-enabled', response);
- }
- };
+GSC = (function () {
+ var ready = new Promise(function (resolve, reject) {
+ chrome.runtime.getPlatformInfo(function (info) {
+ if (PLATFORMS_WHITELIST.indexOf(info.os) === -1) {
+ reject();
+ }
+ else {
+ resolve();
+ }
+ });
+ });
+ ready.catch(function () { });
+
+ var onInitialize = new Promise((resolve, reject) => {
+ sendNativeRequest({ execute: "initialize" }, (response) => {
+ if (response && response.success) {
+ resolve(response);
+ }
+ else {
+ reject(response);
+ }
+ });
+ });
+
+ function sendNativeRequest(request, sendResponse) {
+ ready.then(function () {
+ if (sendResponse) {
+ chrome.runtime.sendNativeMessage(
+ NATIVE_HOST,
+ request,
+ function (response) {
+ if (response) {
+ sendResponse(response);
+ }
+ else {
+ var message = m('no_host_connector');
+ if (
+ chrome.runtime.lastError &&
+ chrome.runtime.lastError.message &&
+ chrome.runtime.lastError.message.indexOf("host not found") === -1 && //
Chrome
+ chrome.runtime.lastError.message.indexOf("disconnected port") === -1 //
Firefox
+ ) {
+ // Some error occured. Show to user
+ message = chrome.runtime.lastError.message;
+ }
+
+ sendResponse({
+ success: false,
+ message: message
+ });
+ }
+ }
+ );
+ }
+ else {
+ chrome.runtime.sendNativeMessage(NATIVE_HOST, request);
+ }
+ }, function () {
+ if (sendResponse) {
+ sendResponse({
+ success: false,
+ message: m('platform_not_supported')
+ });
+ }
+ });
+ }
+
+ function isSupported(feature, response) {
+ return response.properties &&
+ response.properties.supports && response.properties.supports.indexOf(feature) !== -1;
+ }
+
+ return {
+ // https://wiki.gnome.org/Projects/GnomeShell/Extensions/UUIDGuidelines
+ isUUID: function (uuid) {
+ return uuid && uuid.match('^[-a-zA-Z0-9@._]+$');
+ },
+
+ sendNativeRequest: sendNativeRequest,
+
+ isSignalsEqual: function (newSignal, oldSignal) {
+ if (!oldSignal || !newSignal)
+ return false;
+
+ if (!newSignal.signal || !oldSignal.signal || newSignal.signal !== oldSignal.signal)
+ return false;
+
+ if (newSignal.parameters) {
+ if (!oldSignal.parameters)
+ return false;
+
+ if (newSignal.parameters.length !== oldSignal.parameters.length)
+ return false;
+
+ for (var i = 0; i < newSignal.parameters.length; i++) {
+ if (newSignal.parameters[i] !== oldSignal.parameters[i]) {
+ return false;
+ }
+ }
+ }
+ else if (oldSignal.parameters) {
+ return false;
+ }
+
+ return true;
+ },
+
+ onInitialize: function () {
+ return onInitialize;
+ },
+
+ nativeNotificationsSupported: function (response) {
+ return isSupported('notifications', response);
+ },
+
+ nativeUpdateCheckSupported: function (response) {
+ return isSupported('update-check', response);
+ },
+
+ nativeUpdateCheckEnabledOnlySupported: function (response) {
+ return isSupported('update-enabled', response);
+ }
+ };
})();
diff --git a/extension/include/i18n.js b/extension/include/i18n.js
index ba9ac4a..b32fbd3 100644
--- a/extension/include/i18n.js
+++ b/extension/include/i18n.js
@@ -2,31 +2,26 @@
m = chrome.i18n.getMessage;
i18n = (() => {
- $$('[data-i18n]').forEach((element) => {
- let data = element.dataset.i18n.split(',').map((value) => {
- value = value.trim();
+ $$('[data-i18n]').forEach((element) => {
+ let data = element.dataset.i18n.split(',').map((value) => {
+ value = value.trim();
- if(value.startsWith('__MSG_'))
- {
- return value.replace(/__MSG_(\w+)__/g, function(match, key)
- {
- return key ? m(key) : "";
- });
- }
+ if (value.startsWith('__MSG_')) {
+ return value.replace(/__MSG_(\w+)__/g, function (match, key) {
+ return key ? m(key) : "";
+ });
+ }
- return value;
- });
+ return value;
+ });
- if(data)
- {
- if(element.dataset.i18nHtml)
- {
- element.innerHtml = m(data[0], data.slice(1));
- }
- else
- {
- element.innerText = m(data[0], data.slice(1));
- }
- }
- });
+ if (data) {
+ if (element.dataset.i18nHtml) {
+ element.innerHtml = m(data[0], data.slice(1));
+ }
+ else {
+ element.innerText = m(data[0], data.slice(1));
+ }
+ }
+ });
});
diff --git a/extension/include/notifications.js b/extension/include/notifications.js
index d2631cc..05fb445 100644
--- a/extension/include/notifications.js
+++ b/extension/include/notifications.js
@@ -1,210 +1,192 @@
// SPDX-License-Identifer: GPL-3.0-or-later
-GSC.notifications = (function() {
- var DEFAULT_NOTIFICATION_OPTIONS = {
- type: chrome.notifications.TemplateType.BASIC,
- iconUrl: 'icons/GnomeLogo-128.png',
- title: m('gs_chrome'),
- buttons: [
- {title: m('close')}
- ],
- priority: 2,
- isClickable: true,
- requireInteraction: true
- };
-
- function remove_list(options) {
- if(options.items)
- {
- var items = [];
- for (k in options.items)
- {
- if (options.items.hasOwnProperty(k))
- {
- items.push(options.items[k].title + ' ' + options.items[k].message);
- }
- }
-
- if(options.message && items)
- {
- options.message += "\n";
- }
-
- options.message += items.join("\n");
-
- options.type = chrome.notifications.TemplateType.BASIC;
- delete options.items;
- }
-
- return options;
- }
-
- /*
- @Deprecated: remove browser notifications in version 9
- */
- var browser = (function() {
- function init() {
- chrome.runtime.onStartup.addListener(function() {
- // Do nothing. We just need this callback to restore notifications
- });
-
- chrome.notifications.onClosed.addListener(function (notificationId, byUser) {
- if (!byUser)
- {
- update(notificationId);
- }
- else
- {
- remove(notificationId);
- }
- });
-
- chrome.notifications.onClicked.addListener(function (notificationId) {
- GSC.notifications.remove(notificationId);
- });
-
- restore();
- }
-
- function create(name, options) {
- chrome.storage.local.get({
- notifications: {}
- }, function (items) {
- var notifications = items.notifications;
-
- notifications[name] = {...DEFAULT_NOTIFICATION_OPTIONS, ...options};
-
- _create(name, notifications[name], function (notificationId) {
- chrome.storage.local.set({
- notifications: notifications
- });
- });
- });
- }
-
- function _create(name, options, callback)
- {
- if(!COMPAT.NOTIFICATIONS_BUTTONS && options.buttons)
- {
- delete options.buttons;
- }
-
- if (callback)
- {
- chrome.notifications.create(name, options, callback);
- }
- else
- {
- chrome.notifications.create(name, options);
- }
- }
-
- function update(notificationId) {
- chrome.storage.local.get({
- notifications: {}
- }, function (items) {
- var notifications = items.notifications;
-
- if (notifications[notificationId])
- {
- _create(notificationId, notifications[notificationId]);
- }
- });
- }
-
- function remove(notificationId) {
- chrome.storage.local.get({
- notifications: {}
- }, function (items) {
- var notifications = items.notifications;
-
- if (notifications[notificationId])
- {
- delete notifications[notificationId];
- chrome.storage.local.set({
- notifications: notifications
- });
- }
-
- chrome.notifications.clear(notificationId);
- });
- }
-
- function restore() {
- chrome.storage.local.get({
- notifications: {}
- }, function (items) {
- var notifications = items.notifications;
-
- for (notificationId in notifications)
- {
- update(notificationId);
- }
- });
- }
-
- return {
- create: create,
- remove: remove,
- init: init
- };
- })();
-
- var native = (function() {
- function create(name, options) {
- options = remove_list(options);
-
- window.postMessage({
- execute: 'createNotification',
- name: name,
- options: {...DEFAULT_NOTIFICATION_OPTIONS, ...options}
- }, "*");
- }
-
- function remove(notificationId) {
- chrome.runtime.sendMessage({
- execute: 'removeNotification',
- name: notificationId
- });
- }
-
- return {
- create: create,
- remove: remove
- };
- })();
-
- GSC.onInitialize().then(response => {
- if (!GSC.nativeNotificationsSupported(response))
- {
- browser.init();
- }
- });
-
- return {
- create: function() {
- GSC.onInitialize().then(response => {
- if(GSC.nativeNotificationsSupported(response))
- {
- native.create.apply(this, arguments);
- }
- else
- {
- browser.create.apply(this, arguments);
- }
- });
- },
- remove: function() {
- GSC.onInitialize().then(response => {
- if(GSC.nativeNotificationsSupported(response))
- {
- native.remove.apply(this, arguments);
- }
- else
- {
- browser.remove.apply(this, arguments);
- }
- });
- }
- };
+GSC.notifications = (function () {
+ var DEFAULT_NOTIFICATION_OPTIONS = {
+ type: chrome.notifications.TemplateType.BASIC,
+ iconUrl: 'icons/GnomeLogo-128.png',
+ title: m('gs_chrome'),
+ buttons: [
+ { title: m('close') }
+ ],
+ priority: 2,
+ isClickable: true,
+ requireInteraction: true
+ };
+
+ function remove_list(options) {
+ if (options.items) {
+ var items = [];
+ for (k in options.items) {
+ if (options.items.hasOwnProperty(k)) {
+ items.push(options.items[k].title + ' ' + options.items[k].message);
+ }
+ }
+
+ if (options.message && items) {
+ options.message += "\n";
+ }
+
+ options.message += items.join("\n");
+
+ options.type = chrome.notifications.TemplateType.BASIC;
+ delete options.items;
+ }
+
+ return options;
+ }
+
+ /*
+ @Deprecated: remove browser notifications in version 9
+ */
+ var browser = (function () {
+ function init() {
+ chrome.runtime.onStartup.addListener(function () {
+ // Do nothing. We just need this callback to restore notifications
+ });
+
+ chrome.notifications.onClosed.addListener(function (notificationId, byUser) {
+ if (!byUser) {
+ update(notificationId);
+ }
+ else {
+ remove(notificationId);
+ }
+ });
+
+ chrome.notifications.onClicked.addListener(function (notificationId) {
+ GSC.notifications.remove(notificationId);
+ });
+
+ restore();
+ }
+
+ function create(name, options) {
+ chrome.storage.local.get({
+ notifications: {}
+ }, function (items) {
+ var notifications = items.notifications;
+
+ notifications[name] = { ...DEFAULT_NOTIFICATION_OPTIONS, ...options };
+
+ _create(name, notifications[name], function (notificationId) {
+ chrome.storage.local.set({
+ notifications: notifications
+ });
+ });
+ });
+ }
+
+ function _create(name, options, callback) {
+ if (!COMPAT.NOTIFICATIONS_BUTTONS && options.buttons) {
+ delete options.buttons;
+ }
+
+ if (callback) {
+ chrome.notifications.create(name, options, callback);
+ }
+ else {
+ chrome.notifications.create(name, options);
+ }
+ }
+
+ function update(notificationId) {
+ chrome.storage.local.get({
+ notifications: {}
+ }, function (items) {
+ var notifications = items.notifications;
+
+ if (notifications[notificationId]) {
+ _create(notificationId, notifications[notificationId]);
+ }
+ });
+ }
+
+ function remove(notificationId) {
+ chrome.storage.local.get({
+ notifications: {}
+ }, function (items) {
+ var notifications = items.notifications;
+
+ if (notifications[notificationId]) {
+ delete notifications[notificationId];
+ chrome.storage.local.set({
+ notifications: notifications
+ });
+ }
+
+ chrome.notifications.clear(notificationId);
+ });
+ }
+
+ function restore() {
+ chrome.storage.local.get({
+ notifications: {}
+ }, function (items) {
+ var notifications = items.notifications;
+
+ for (notificationId in notifications) {
+ update(notificationId);
+ }
+ });
+ }
+
+ return {
+ create: create,
+ remove: remove,
+ init: init
+ };
+ })();
+
+ var native = (function () {
+ function create(name, options) {
+ options = remove_list(options);
+
+ window.postMessage({
+ execute: 'createNotification',
+ name: name,
+ options: { ...DEFAULT_NOTIFICATION_OPTIONS, ...options }
+ }, "*");
+ }
+
+ function remove(notificationId) {
+ chrome.runtime.sendMessage({
+ execute: 'removeNotification',
+ name: notificationId
+ });
+ }
+
+ return {
+ create: create,
+ remove: remove
+ };
+ })();
+
+ GSC.onInitialize().then(response => {
+ if (!GSC.nativeNotificationsSupported(response)) {
+ browser.init();
+ }
+ });
+
+ return {
+ create: function () {
+ GSC.onInitialize().then(response => {
+ if (GSC.nativeNotificationsSupported(response)) {
+ native.create.apply(this, arguments);
+ }
+ else {
+ browser.create.apply(this, arguments);
+ }
+ });
+ },
+ remove: function () {
+ GSC.onInitialize().then(response => {
+ if (GSC.nativeNotificationsSupported(response)) {
+ native.remove.apply(this, arguments);
+ }
+ else {
+ browser.remove.apply(this, arguments);
+ }
+ });
+ }
+ };
})();
diff --git a/extension/include/sweettooth-api.js b/extension/include/sweettooth-api.js
index 1929d00..b7c197e 100644
--- a/extension/include/sweettooth-api.js
+++ b/extension/include/sweettooth-api.js
@@ -3,220 +3,197 @@
"use strict";
GSC.getMessage = function (key) {
- if (GSC && GSC.i18n && GSC.i18n[key])
- {
- var message = GSC.i18n[key];
+ if (GSC && GSC.i18n && GSC.i18n[key]) {
+ var message = GSC.i18n[key];
- for (var i = 1; i < arguments.length; i++)
- {
- message = message.replace('$' + i, arguments[i]);
- }
+ for (var i = 1; i < arguments.length; i++) {
+ message = message.replace('$' + i, arguments[i]);
+ }
- return message;
- }
+ return message;
+ }
- return key;
+ return key;
};
window.SweetTooth = function () {
- var apiObject = {
- apiVersion: 5,
- shellVersion: '-1',
- versionValidationEnabled: true,
- userExtensionsDisabled: false,
-
- getChromeExtensionId: function () {
- return GS_CHROME_ID;
- },
-
- getExtensionErrors: function (uuid) {
- return sendResolveExtensionMessage("getExtensionErrors", "extensionErrors", {uuid:
uuid});
- },
-
- getExtensionInfo: function (uuid) {
- return sendResolveExtensionMessage("getExtensionInfo", "extensionInfo", {uuid: uuid});
- },
-
- installExtension: function (uuid) {
- return sendResolveExtensionMessage("installExtension", "status", {uuid: uuid});
- },
-
- launchExtensionPrefs: function (uuid) {
- sendExtensionMessage("launchExtensionPrefs", null, {uuid: uuid});
- },
-
- listExtensions: function () {
- return sendResolveExtensionMessage("listExtensions", "extensions");
- },
-
- setExtensionEnabled: function (uuid, enable) {
- return sendResolveExtensionMessage("enableExtension", "success", {uuid: uuid, enable:
enable});
- },
-
- uninstallExtension: function (uuid) {
- return sendResolveExtensionMessage("uninstallExtension", "status", {uuid: uuid});
- },
-
- setUserExtensionsDisabled: function (disable) {
- return sendResolveExtensionMessage("setUserExtensionsDisabled", "success", {disable:
disable})
- .then(success => {
- if(success)
- {
- apiObject.userExtensionsDisabled = disable;
- }
-
- return success;
- });
- },
-
- setVersionValidationDisabled: function (disable) {
- return sendResolveExtensionMessage("setVersionValidationDisabled", "success",
{disable: disable})
- .then(success => {
- if(success)
- {
- apiObject.versionValidationEnabled = !disable;
- }
-
- return success;
- });
- },
-
- initialize: function () {
- if (SweetTooth.shellVersion !== '-1')
- {
- return Promise.resolve(apiObject);
- }
-
- var ready = new Promise(function(resolve, reject) {
- sendExtensionMessage("initialize", response => {
- if (response && response.success && response.properties &&
response.properties.shellVersion)
- {
- resolve(response.properties);
- }
- else
- {
- var message = response && response.message ?
GSC.getMessage(response.message) : GSC.getMessage('error_connector_response');
- reject(message);
- }
- });
- });
-
- ready.then(function (response) {
- apiObject.shellVersion = response.shellVersion;
- apiObject.versionValidationEnabled = response.versionValidationEnabled;
- apiObject.userExtensionsDisabled = response.userExtensionsDisabled;
-
- let REQUIRED_APIS = [
- "notifications",
- "v6"
- ];
-
- if(response.supports)
- {
- for(let api of response.supports)
- {
- let api_index;
- if((api_index = REQUIRED_APIS.indexOf(api)) != -1)
- {
- REQUIRED_APIS.splice(api_index, 1);
- }
-
- if(api === 'v6')
- {
- apiObject.apiVersion = 6;
- }
- }
- }
-
- if (REQUIRED_APIS.length > 0)
- {
- require(['messages'], function (messages) {
- messages.addWarning(GSC.getMessage('warning_apis_missing',
REQUIRED_APIS.join(", ")));
- });
- }
- }, function (message) {
- apiObject.apiVersion = null;
-
- require(['messages'], function (messages) {
- messages.addError(message ? message :
GSC.getMessage('no_host_connector'));
- })
- });
-
- return ready;
- }
- };
-
- window.addEventListener("message", function (event) {
- // We only accept messages from ourselves
- if (event.source != window)
- {
- return;
- }
-
- if (event.data.type)
- {
- if (event.data.type == "gs-chrome")
- {
- if (event.data.request.signal == 'ExtensionStatusChanged' &&
apiObject.onchange)
- {
- apiObject.onchange(
- event.data.request.parameters[0],
- event.data.request.parameters[1],
- event.data.request.parameters[2]
- );
- }
- else if (event.data.request.signal == 'org.gnome.Shell' &&
apiObject.onshellrestart)
- {
- apiObject.onshellrestart();
- }
- else if (event.data.request.signal == 'ShellSettingsChanged' &&
apiObject.onShellSettingChanged)
- {
- if(event.data.request.key === 'disable-user-extensions')
- {
- apiObject.userExtensionsDisabled = event.data.request.value;
- }
- else if(event.data.request.key ===
'disable-extension-version-validation')
- {
- apiObject.versionValidationEnabled =
!event.data.request.value;
- }
-
- apiObject.onShellSettingChanged(event.data.request.key,
event.data.request.value);
- }
- }
- }
- }, false);
-
- function sendResolveExtensionMessage(method, resolveProperty, parameters) {
- return new Promise(function (resolve, reject) {
- sendExtensionMessage(method, function (response) {
- if (response && response.success)
- {
- resolve(response[resolveProperty]);
- }
- else
- {
- var message = response && response.message ? response.message
: GSC.getMessage('error_connector_response');
- reject(message);
- }
- },
- parameters
- );
- });
- }
-
- function sendExtensionMessage(method, callback, parameters) {
- var request = {execute: method};
- if (parameters)
- {
- request = Object.assign(parameters, request);
- }
-
- chrome.runtime.sendMessage(
- apiObject.getChromeExtensionId(),
- request,
- callback
- );
- }
-
- return apiObject;
+ var apiObject = {
+ apiVersion: 5,
+ shellVersion: '-1',
+ versionValidationEnabled: true,
+ userExtensionsDisabled: false,
+
+ getChromeExtensionId: function () {
+ return GS_CHROME_ID;
+ },
+
+ getExtensionErrors: function (uuid) {
+ return sendResolveExtensionMessage("getExtensionErrors", "extensionErrors", { uuid: uuid });
+ },
+
+ getExtensionInfo: function (uuid) {
+ return sendResolveExtensionMessage("getExtensionInfo", "extensionInfo", { uuid: uuid });
+ },
+
+ installExtension: function (uuid) {
+ return sendResolveExtensionMessage("installExtension", "status", { uuid: uuid });
+ },
+
+ launchExtensionPrefs: function (uuid) {
+ sendExtensionMessage("launchExtensionPrefs", null, { uuid: uuid });
+ },
+
+ listExtensions: function () {
+ return sendResolveExtensionMessage("listExtensions", "extensions");
+ },
+
+ setExtensionEnabled: function (uuid, enable) {
+ return sendResolveExtensionMessage("enableExtension", "success", { uuid: uuid, enable: enable });
+ },
+
+ uninstallExtension: function (uuid) {
+ return sendResolveExtensionMessage("uninstallExtension", "status", { uuid: uuid });
+ },
+
+ setUserExtensionsDisabled: function (disable) {
+ return sendResolveExtensionMessage("setUserExtensionsDisabled", "success", { disable: disable })
+ .then(success => {
+ if (success) {
+ apiObject.userExtensionsDisabled = disable;
+ }
+
+ return success;
+ });
+ },
+
+ setVersionValidationDisabled: function (disable) {
+ return sendResolveExtensionMessage("setVersionValidationDisabled", "success", { disable: disable
})
+ .then(success => {
+ if (success) {
+ apiObject.versionValidationEnabled = !disable;
+ }
+
+ return success;
+ });
+ },
+
+ initialize: function () {
+ if (SweetTooth.shellVersion !== '-1') {
+ return Promise.resolve(apiObject);
+ }
+
+ var ready = new Promise(function (resolve, reject) {
+ sendExtensionMessage("initialize", response => {
+ if (response && response.success && response.properties &&
response.properties.shellVersion) {
+ resolve(response.properties);
+ }
+ else {
+ var message = response && response.message ? GSC.getMessage(response.message) :
GSC.getMessage('error_connector_response');
+ reject(message);
+ }
+ });
+ });
+
+ ready.then(function (response) {
+ apiObject.shellVersion = response.shellVersion;
+ apiObject.versionValidationEnabled = response.versionValidationEnabled;
+ apiObject.userExtensionsDisabled = response.userExtensionsDisabled;
+
+ let REQUIRED_APIS = [
+ "notifications",
+ "v6"
+ ];
+
+ if (response.supports) {
+ for (let api of response.supports) {
+ let api_index;
+ if ((api_index = REQUIRED_APIS.indexOf(api)) != -1) {
+ REQUIRED_APIS.splice(api_index, 1);
+ }
+
+ if (api === 'v6') {
+ apiObject.apiVersion = 6;
+ }
+ }
+ }
+
+ if (REQUIRED_APIS.length > 0) {
+ require(['messages'], function (messages) {
+ messages.addWarning(GSC.getMessage('warning_apis_missing', REQUIRED_APIS.join(",
")));
+ });
+ }
+ }, function (message) {
+ apiObject.apiVersion = null;
+
+ require(['messages'], function (messages) {
+ messages.addError(message ? message : GSC.getMessage('no_host_connector'));
+ })
+ });
+
+ return ready;
+ }
+ };
+
+ window.addEventListener("message", function (event) {
+ // We only accept messages from ourselves
+ if (event.source != window) {
+ return;
+ }
+
+ if (event.data.type) {
+ if (event.data.type == "gs-chrome") {
+ if (event.data.request.signal == 'ExtensionStatusChanged' && apiObject.onchange) {
+ apiObject.onchange(
+ event.data.request.parameters[0],
+ event.data.request.parameters[1],
+ event.data.request.parameters[2]
+ );
+ }
+ else if (event.data.request.signal == 'org.gnome.Shell' && apiObject.onshellrestart) {
+ apiObject.onshellrestart();
+ }
+ else if (event.data.request.signal == 'ShellSettingsChanged' &&
apiObject.onShellSettingChanged) {
+ if (event.data.request.key === 'disable-user-extensions') {
+ apiObject.userExtensionsDisabled = event.data.request.value;
+ }
+ else if (event.data.request.key === 'disable-extension-version-validation') {
+ apiObject.versionValidationEnabled = !event.data.request.value;
+ }
+
+ apiObject.onShellSettingChanged(event.data.request.key, event.data.request.value);
+ }
+ }
+ }
+ }, false);
+
+ function sendResolveExtensionMessage(method, resolveProperty, parameters) {
+ return new Promise(function (resolve, reject) {
+ sendExtensionMessage(method, function (response) {
+ if (response && response.success) {
+ resolve(response[resolveProperty]);
+ }
+ else {
+ var message = response && response.message ? response.message :
GSC.getMessage('error_connector_response');
+ reject(message);
+ }
+ },
+ parameters
+ );
+ });
+ }
+
+ function sendExtensionMessage(method, callback, parameters) {
+ var request = { execute: method };
+ if (parameters) {
+ request = Object.assign(parameters, request);
+ }
+
+ chrome.runtime.sendMessage(
+ apiObject.getChromeExtensionId(),
+ request,
+ callback
+ );
+ }
+
+ return apiObject;
}();
diff --git a/extension/include/sync.js b/extension/include/sync.js
index 37ff0f5..dc390f9 100644
--- a/extension/include/sync.js
+++ b/extension/include/sync.js
@@ -3,445 +3,395 @@
/*
* Main object that handles extensions synchronization with remote storage.
*/
-GSC.sync = (function($) {
- var enabled = true;
- var extensionChangedTimeout = false;
- var extensionChangedQueue = {};
-
- const SYNC_QUEUE_TIMEOUT = 7000;
-
- /*
- * Initialization rutines.
- */
- function init() {
- if(!COMPAT.SYNC_STORAGE)
- {
- enabled = false;
- return;
- }
-
- function onIdleStateChanged(state) {
- if (state === 'locked')
- {
- enabled = false;
-
- // Remove all disabled extensions from queue
- for (const [extensionId, extension] of Object.entries(extensionChangedQueue))
{
- if(extension.state == EXTENSION_STATE.DISABLED)
- {
- delete extensionChangedQueue[extensionId];
- }
- };
- }
- else if (state === 'active')
- {
- enabled = true;
- }
- }
-
- chrome.permissions.contains({
- permissions: ["idle"]
- }, function (result) {
- if(result)
- {
- chrome.idle.onStateChanged.addListener(onIdleStateChanged);
- }
- else
- {
- enabled = false;
- }
- });
-
- chrome.permissions.onAdded.addListener(function(permissions) {
- if(permissions.permissions && permissions.permissions.indexOf('idle') !== -1)
- {
- enabled = true;
- chrome.idle.onStateChanged.addListener(onIdleStateChanged);
- }
- });
-
- chrome.permissions.onRemoved.addListener(function(permissions) {
- if(permissions.permissions && permissions.permissions.indexOf('idle') !== -1)
- {
- enabled = false;
- chrome.idle.onStateChanged.removeListener(onIdleStateChanged);
- }
- });
-
- function onNotificationAction(notificationId, buttonIndex) {
- if (notificationId !== NOTIFICATION_SYNC_FAILED)
- {
- return;
- }
-
- GSC.notifications.remove(notificationId);
- }
-
- onSyncFromRemote();
- chrome.storage.onChanged.addListener(function(changes, areaName) {
- if(areaName === 'sync' && changes.extensions)
- {
- onSyncFromRemote(changes.extensions.newValue);
- }
- });
-
- chrome.runtime.onMessage.addListener(
- function (request, sender, sendResponse) {
- if (sender.id && sender.id === GS_CHROME_ID && request)
- {
- if (request === MESSAGE_SYNC_FROM_REMOTE)
- {
- onSyncFromRemote();
- }
- }
- }
- );
-
- GSC.onInitialize().then(response => {
- /*
- @Deprecated: remove browser notifications in version 9
- */
- if (!GSC.nativeNotificationsSupported(response))
- {
- chrome.notifications.onButtonClicked.addListener(onNotificationAction);
- }
- else
- {
- chrome.runtime.onMessage.addListener(
- function (request, sender, sendResponse) {
- if(
- sender.id && sender.id === GS_CHROME_ID &&
- request && request.signal)
- {
- if(request.signal == SIGNAL_NOTIFICATION_ACTION)
- {
- onNotificationAction(request.name,
request.button_id);
- }
- }
- }
- );
- }
- });
- }
-
- /*
- * Returns array of all local and remote extensions with structure:
- * [
- * $extension_uuid: {
- * uuid: extension uuid,
- * name: extension name,
- * remoteState: extension state in remote storage,
- * localState: extension state in current GNOME Shell,
- * remote: true if extensions is in remote storage,
- * local: true if extension installed localy
- * },
- * ...
- * ]
- */
- function getExtensions(remoteExtensions) {
- return new Promise((resolve, reject) => {
- GSC.sendNativeRequest({
- execute: 'listExtensions'
- }, function(response) {
- if(response && response.success)
- {
- if(remoteExtensions)
- {
- resolve(mergeExtensions(remoteExtensions,
response.extensions));
- }
- else
- {
- chrome.storage.sync.get({
- extensions: {}
- }, function(options) {
- if(chrome.runtime.lastError)
- {
- reject(chrome.runtime.lastError.message);
- }
- else
- {
- resolve(mergeExtensions(options.extensions,
response.extensions));
- }
- });
- }
- }
- else
- {
- var message = response && response.message ? response.message :
m('error_connector_response');
- reject(message);
- }
- });
- });
- }
-
- /*
- * Returns merged list of extensions list in remote storage and
- * locally installed extensions.
- *
- * Both parameters should be in form:
- * {
- * $extension_uuid: {
- * uuid: ,
- * name: ,
- * state:
- * },
- * ...
- * }
- */
- function mergeExtensions(remoteExtensions, localExtensions)
- {
- var extensions = {};
-
- for (const [key, extension] of Object.entries(remoteExtensions)) {
- if(extension.uuid && extension.name && extension.state)
- {
- extensions[extension.uuid] = {
- uuid: extension.uuid,
- name: extension.name,
- remoteState: extension.state,
- remote: true,
- local: false
- };
- }
- };
-
- for (const [key, extension] of Object.entries(localExtensions)) {
- if(extensions[extension.uuid])
- {
- extensions[extension.uuid].name = extension.name;
- extensions[extension.uuid].localState = extension.state;
- extensions[extension.uuid].local = true;
- }
- else
- {
- extensions[extension.uuid] = {
- uuid: extension.uuid,
- name: extension.name,
- remoteState: EXTENSION_STATE.UNINSTALLED,
- localState: extension.state,
- remote: false,
- local: true
- };
- }
- };
-
- return extensions;
- }
-
- /*
- * Synchronize local changed extensions to remote list.
- */
- function localExtensionsChanged() {
- extensionChangedTimeout = false;
-
- if (!isEmptyObject(extensionChangedQueue))
- {
- GSC.sendNativeRequest({
- execute: 'listExtensions'
- }, function (response) {
- if (response && response.success && response.extensions)
- {
- chrome.storage.sync.get({
- extensions: {}
- }, function (options) {
- for (const [extensionId, extension] of
Object.entries(extensionChangedQueue)) {
- if ([EXTENSION_STATE.ENABLED,
EXTENSION_STATE.DISABLED, EXTENSION_STATE.UNINSTALLED].includes(extension.state))
- {
- // Extension can be uninstalled already
- if (response.extensions[extensionId] &&
!isEmptyObject(response.extensions[extensionId]))
- {
- extension =
response.extensions[extensionId];
- }
-
- if (extension.state ===
EXTENSION_STATE.UNINSTALLED && options.extensions[extension.uuid])
- {
- delete
options.extensions[extension.uuid];
- }
- else
- {
- options.extensions[extension.uuid] = {
- uuid: extension.uuid,
- name: extension.name,
- state: extension.state
- };
- }
- }
- };
-
- chrome.storage.sync.set({
- extensions: options.extensions
- });
-
- extensionChangedQueue = {};
- });
- }
- else
- {
- createSyncFailedNotification();
- }
- });
- }
- }
-
- /*
- * Synchronize remote changes with local GNOME Shell.
- *
- * @param remoteExtensions - (optional) remote extensions list
- */
- function remoteExtensionsChanged(remoteExtensions) {
- getExtensions(remoteExtensions).then((extensions) => {
- var enableExtensions = [];
- for ([uuid, extension] of Object.entries(extensions)) {
- if(extension.remote)
- {
- if(!extension.local)
- {
- GSC.sendNativeRequest({
- execute: "installExtension",
- uuid: extension.uuid
- }, onInstallUninstall);
- }
- else if (extension.remoteState !== extension.localState)
- {
- if(extension.remoteState === EXTENSION_STATE.ENABLED)
- {
- enableExtensions.push({
- uuid: extension.uuid,
- enable: true
- });
- }
- else
- {
- enableExtensions.push({
- uuid: extension.uuid,
- enable: false
- });
- }
- }
- }
- else if(extension.local)
- {
- GSC.sendNativeRequest({
- execute: "uninstallExtension",
- uuid: extension.uuid
- }, onInstallUninstall);
- }
- };
-
- if(enableExtensions.length > 0)
- {
- GSC.sendNativeRequest({
- execute: "enableExtension",
- extensions: enableExtensions
- });
- }
- }).catch((message) => {
- createSyncFailedNotification(message);
- });
- }
-
- /*
- * Callback called when extension is installed or uninstalled as part
- * of synchronization process.
- */
- function onInstallUninstall(response) {
- if(response)
- {
- if(!response.success)
- {
- createSyncFailedNotification(response.message);
- }
- }
- else
- {
- createSyncFailedNotification();
- }
- }
-
- /*
- * Wrapper for localExtensionChanged that checks if synchronization is
- * enabled.
- */
- function onExtensionChanged(request)
- {
- if(!COMPAT.SYNC_STORAGE || !enabled)
- {
- return;
- }
-
- runIfSyncEnabled(() => {
- if (extensionChangedTimeout)
- {
- clearTimeout(extensionChangedTimeout);
- }
-
- extensionChangedQueue[request.parameters[EXTENSION_CHANGED_UUID]] = {
- uuid: request.parameters[EXTENSION_CHANGED_UUID],
- state: request.parameters[EXTENSION_CHANGED_STATE],
- error: request.parameters[EXTENSION_CHANGED_ERROR]
- };
-
- extensionChangedTimeout = setTimeout(function () {
- localExtensionsChanged();
- }, SYNC_QUEUE_TIMEOUT);
- });
- }
-
- /*
- * Wrapper for remoteExtensionsChanged that checks if synchronization is
- * enabled.
- */
- function onSyncFromRemote(remoteExtensions)
- {
- if(!COMPAT.SYNC_STORAGE)
- {
- return;
- }
-
- runIfSyncEnabled(function() {
- remoteExtensionsChanged(remoteExtensions);
- });
- }
-
- /*
- * Runs callback function if synchronyzation is enabled.
- *
- * @param callback - callback function
- */
- function runIfSyncEnabled(callback) {
- chrome.storage.local.get({
- syncExtensions: false
- }, function (options) {
- if (options.syncExtensions)
- {
- chrome.permissions.contains({
- permissions: ["idle"]
- }, function (result) {
- if (result)
- {
- callback();
- }
- });
-
- }
- });
- }
-
- /*
- * Create notification when synchronization failed.
- */
- function createSyncFailedNotification(cause) {
- GSC.notifications.create(NOTIFICATION_SYNC_FAILED, {
- message: m('synchronization_failed', cause ? cause : m('unknown_error'))
- });
- }
-
- /*
- * Public methods.
- */
- return {
- init: init,
- getExtensions: getExtensions,
- onExtensionChanged: onExtensionChanged
- };
+GSC.sync = (function ($) {
+ var enabled = true;
+ var extensionChangedTimeout = false;
+ var extensionChangedQueue = {};
+
+ const SYNC_QUEUE_TIMEOUT = 7000;
+
+ /*
+ * Initialization rutines.
+ */
+ function init() {
+ if (!COMPAT.SYNC_STORAGE) {
+ enabled = false;
+ return;
+ }
+
+ function onIdleStateChanged(state) {
+ if (state === 'locked') {
+ enabled = false;
+
+ // Remove all disabled extensions from queue
+ for (const [extensionId, extension] of Object.entries(extensionChangedQueue)) {
+ if (extension.state == EXTENSION_STATE.DISABLED) {
+ delete extensionChangedQueue[extensionId];
+ }
+ };
+ }
+ else if (state === 'active') {
+ enabled = true;
+ }
+ }
+
+ chrome.permissions.contains({
+ permissions: ["idle"]
+ }, function (result) {
+ if (result) {
+ chrome.idle.onStateChanged.addListener(onIdleStateChanged);
+ }
+ else {
+ enabled = false;
+ }
+ });
+
+ chrome.permissions.onAdded.addListener(function (permissions) {
+ if (permissions.permissions && permissions.permissions.indexOf('idle') !== -1) {
+ enabled = true;
+ chrome.idle.onStateChanged.addListener(onIdleStateChanged);
+ }
+ });
+
+ chrome.permissions.onRemoved.addListener(function (permissions) {
+ if (permissions.permissions && permissions.permissions.indexOf('idle') !== -1) {
+ enabled = false;
+ chrome.idle.onStateChanged.removeListener(onIdleStateChanged);
+ }
+ });
+
+ function onNotificationAction(notificationId, buttonIndex) {
+ if (notificationId !== NOTIFICATION_SYNC_FAILED) {
+ return;
+ }
+
+ GSC.notifications.remove(notificationId);
+ }
+
+ onSyncFromRemote();
+ chrome.storage.onChanged.addListener(function (changes, areaName) {
+ if (areaName === 'sync' && changes.extensions) {
+ onSyncFromRemote(changes.extensions.newValue);
+ }
+ });
+
+ chrome.runtime.onMessage.addListener(
+ function (request, sender, sendResponse) {
+ if (sender.id && sender.id === GS_CHROME_ID && request) {
+ if (request === MESSAGE_SYNC_FROM_REMOTE) {
+ onSyncFromRemote();
+ }
+ }
+ }
+ );
+
+ GSC.onInitialize().then(response => {
+ /*
+ @Deprecated: remove browser notifications in version 9
+ */
+ if (!GSC.nativeNotificationsSupported(response)) {
+ chrome.notifications.onButtonClicked.addListener(onNotificationAction);
+ }
+ else {
+ chrome.runtime.onMessage.addListener(
+ function (request, sender, sendResponse) {
+ if (
+ sender.id && sender.id === GS_CHROME_ID &&
+ request && request.signal) {
+ if (request.signal == SIGNAL_NOTIFICATION_ACTION) {
+ onNotificationAction(request.name, request.button_id);
+ }
+ }
+ }
+ );
+ }
+ });
+ }
+
+ /*
+ * Returns array of all local and remote extensions with structure:
+ * [
+ * $extension_uuid: {
+ * uuid: extension uuid,
+ * name: extension name,
+ * remoteState: extension state in remote storage,
+ * localState: extension state in current GNOME Shell,
+ * remote: true if extensions is in remote storage,
+ * local: true if extension installed localy
+ * },
+ * ...
+ * ]
+ */
+ function getExtensions(remoteExtensions) {
+ return new Promise((resolve, reject) => {
+ GSC.sendNativeRequest({
+ execute: 'listExtensions'
+ }, function (response) {
+ if (response && response.success) {
+ if (remoteExtensions) {
+ resolve(mergeExtensions(remoteExtensions, response.extensions));
+ }
+ else {
+ chrome.storage.sync.get({
+ extensions: {}
+ }, function (options) {
+ if (chrome.runtime.lastError) {
+ reject(chrome.runtime.lastError.message);
+ }
+ else {
+ resolve(mergeExtensions(options.extensions, response.extensions));
+ }
+ });
+ }
+ }
+ else {
+ var message = response && response.message ? response.message :
m('error_connector_response');
+ reject(message);
+ }
+ });
+ });
+ }
+
+ /*
+ * Returns merged list of extensions list in remote storage and
+ * locally installed extensions.
+ *
+ * Both parameters should be in form:
+ * {
+ * $extension_uuid: {
+ * uuid: ,
+ * name: ,
+ * state:
+ * },
+ * ...
+ * }
+ */
+ function mergeExtensions(remoteExtensions, localExtensions) {
+ var extensions = {};
+
+ for (const [key, extension] of Object.entries(remoteExtensions)) {
+ if (extension.uuid && extension.name && extension.state) {
+ extensions[extension.uuid] = {
+ uuid: extension.uuid,
+ name: extension.name,
+ remoteState: extension.state,
+ remote: true,
+ local: false
+ };
+ }
+ };
+
+ for (const [key, extension] of Object.entries(localExtensions)) {
+ if (extensions[extension.uuid]) {
+ extensions[extension.uuid].name = extension.name;
+ extensions[extension.uuid].localState = extension.state;
+ extensions[extension.uuid].local = true;
+ }
+ else {
+ extensions[extension.uuid] = {
+ uuid: extension.uuid,
+ name: extension.name,
+ remoteState: EXTENSION_STATE.UNINSTALLED,
+ localState: extension.state,
+ remote: false,
+ local: true
+ };
+ }
+ };
+
+ return extensions;
+ }
+
+ /*
+ * Synchronize local changed extensions to remote list.
+ */
+ function localExtensionsChanged() {
+ extensionChangedTimeout = false;
+
+ if (!isEmptyObject(extensionChangedQueue)) {
+ GSC.sendNativeRequest({
+ execute: 'listExtensions'
+ }, function (response) {
+ if (response && response.success && response.extensions) {
+ chrome.storage.sync.get({
+ extensions: {}
+ }, function (options) {
+ for (const [extensionId, extension] of Object.entries(extensionChangedQueue)) {
+ if ([EXTENSION_STATE.ENABLED, EXTENSION_STATE.DISABLED,
EXTENSION_STATE.UNINSTALLED].includes(extension.state)) {
+ // Extension can be uninstalled already
+ if (response.extensions[extensionId] &&
!isEmptyObject(response.extensions[extensionId])) {
+ extension = response.extensions[extensionId];
+ }
+
+ if (extension.state === EXTENSION_STATE.UNINSTALLED &&
options.extensions[extension.uuid]) {
+ delete options.extensions[extension.uuid];
+ }
+ else {
+ options.extensions[extension.uuid] = {
+ uuid: extension.uuid,
+ name: extension.name,
+ state: extension.state
+ };
+ }
+ }
+ };
+
+ chrome.storage.sync.set({
+ extensions: options.extensions
+ });
+
+ extensionChangedQueue = {};
+ });
+ }
+ else {
+ createSyncFailedNotification();
+ }
+ });
+ }
+ }
+
+ /*
+ * Synchronize remote changes with local GNOME Shell.
+ *
+ * @param remoteExtensions - (optional) remote extensions list
+ */
+ function remoteExtensionsChanged(remoteExtensions) {
+ getExtensions(remoteExtensions).then((extensions) => {
+ var enableExtensions = [];
+ for ([uuid, extension] of Object.entries(extensions)) {
+ if (extension.remote) {
+ if (!extension.local) {
+ GSC.sendNativeRequest({
+ execute: "installExtension",
+ uuid: extension.uuid
+ }, onInstallUninstall);
+ }
+ else if (extension.remoteState !== extension.localState) {
+ if (extension.remoteState === EXTENSION_STATE.ENABLED) {
+ enableExtensions.push({
+ uuid: extension.uuid,
+ enable: true
+ });
+ }
+ else {
+ enableExtensions.push({
+ uuid: extension.uuid,
+ enable: false
+ });
+ }
+ }
+ }
+ else if (extension.local) {
+ GSC.sendNativeRequest({
+ execute: "uninstallExtension",
+ uuid: extension.uuid
+ }, onInstallUninstall);
+ }
+ };
+
+ if (enableExtensions.length > 0) {
+ GSC.sendNativeRequest({
+ execute: "enableExtension",
+ extensions: enableExtensions
+ });
+ }
+ }).catch((message) => {
+ createSyncFailedNotification(message);
+ });
+ }
+
+ /*
+ * Callback called when extension is installed or uninstalled as part
+ * of synchronization process.
+ */
+ function onInstallUninstall(response) {
+ if (response) {
+ if (!response.success) {
+ createSyncFailedNotification(response.message);
+ }
+ }
+ else {
+ createSyncFailedNotification();
+ }
+ }
+
+ /*
+ * Wrapper for localExtensionChanged that checks if synchronization is
+ * enabled.
+ */
+ function onExtensionChanged(request) {
+ if (!COMPAT.SYNC_STORAGE || !enabled) {
+ return;
+ }
+
+ runIfSyncEnabled(() => {
+ if (extensionChangedTimeout) {
+ clearTimeout(extensionChangedTimeout);
+ }
+
+ extensionChangedQueue[request.parameters[EXTENSION_CHANGED_UUID]] = {
+ uuid: request.parameters[EXTENSION_CHANGED_UUID],
+ state: request.parameters[EXTENSION_CHANGED_STATE],
+ error: request.parameters[EXTENSION_CHANGED_ERROR]
+ };
+
+ extensionChangedTimeout = setTimeout(function () {
+ localExtensionsChanged();
+ }, SYNC_QUEUE_TIMEOUT);
+ });
+ }
+
+ /*
+ * Wrapper for remoteExtensionsChanged that checks if synchronization is
+ * enabled.
+ */
+ function onSyncFromRemote(remoteExtensions) {
+ if (!COMPAT.SYNC_STORAGE) {
+ return;
+ }
+
+ runIfSyncEnabled(function () {
+ remoteExtensionsChanged(remoteExtensions);
+ });
+ }
+
+ /*
+ * Runs callback function if synchronyzation is enabled.
+ *
+ * @param callback - callback function
+ */
+ function runIfSyncEnabled(callback) {
+ chrome.storage.local.get({
+ syncExtensions: false
+ }, function (options) {
+ if (options.syncExtensions) {
+ chrome.permissions.contains({
+ permissions: ["idle"]
+ }, function (result) {
+ if (result) {
+ callback();
+ }
+ });
+
+ }
+ });
+ }
+
+ /*
+ * Create notification when synchronization failed.
+ */
+ function createSyncFailedNotification(cause) {
+ GSC.notifications.create(NOTIFICATION_SYNC_FAILED, {
+ message: m('synchronization_failed', cause ? cause : m('unknown_error'))
+ });
+ }
+
+ /*
+ * Public methods.
+ */
+ return {
+ init: init,
+ getExtensions: getExtensions,
+ onExtensionChanged: onExtensionChanged
+ };
})();
diff --git a/extension/include/toolbar.js b/extension/include/toolbar.js
index d918b43..24a7fda 100644
--- a/extension/include/toolbar.js
+++ b/extension/include/toolbar.js
@@ -3,55 +3,51 @@
/*
* Main object that handles toolbar icon.
*/
-GSC.toolbar = (function() {
- /*
- * Initialization rutines.
- */
- function init() {
- chrome.storage.local.get(DEFAULT_LOCAL_OPTIONS, function (options) {
- if (options.useLightIcon)
- {
- setLightIcon();
- }
- });
+GSC.toolbar = (function () {
+ /*
+ * Initialization rutines.
+ */
+ function init() {
+ chrome.storage.local.get(DEFAULT_LOCAL_OPTIONS, function (options) {
+ if (options.useLightIcon) {
+ setLightIcon();
+ }
+ });
- chrome.storage.onChanged.addListener(function(changes, areaName) {
- if(areaName === 'local' && changes.useLightIcon)
- {
- if(changes.useLightIcon.newValue)
- {
- setLightIcon();
- }
- else
- {
- setDarkicon();
- }
- }
- });
- }
+ chrome.storage.onChanged.addListener(function (changes, areaName) {
+ if (areaName === 'local' && changes.useLightIcon) {
+ if (changes.useLightIcon.newValue) {
+ setLightIcon();
+ }
+ else {
+ setDarkicon();
+ }
+ }
+ });
+ }
- function setLightIcon() {
- chrome.browserAction.setIcon({
- path: {
- "16": "icons/GnomeLogo-light-16.png",
- "32": "icons/GnomeLogo-light-32.png"
- }
- });
- }
+ function setLightIcon() {
+ chrome.browserAction.setIcon({
+ path: {
+ "16": "icons/GnomeLogo-light-16.png",
+ "32": "icons/GnomeLogo-light-32.png"
+ }
+ });
+ }
- function setDarkicon() {
- chrome.browserAction.setIcon({
- path: {
- "16": "icons/GnomeLogo-16.png",
- "32": "icons/GnomeLogo-32.png"
- }
- });
- }
+ function setDarkicon() {
+ chrome.browserAction.setIcon({
+ path: {
+ "16": "icons/GnomeLogo-16.png",
+ "32": "icons/GnomeLogo-32.png"
+ }
+ });
+ }
- /*
- * Public methods.
- */
- return {
- init: init
- };
+ /*
+ * Public methods.
+ */
+ return {
+ init: init
+ };
})();
diff --git a/extension/include/update.js b/extension/include/update.js
index db1a948..53050ff 100644
--- a/extension/include/update.js
+++ b/extension/include/update.js
@@ -1,196 +1,170 @@
// SPDX-License-Identifer: GPL-3.0-or-later
-GSC.update = (function() {
- function schedule(updateCheckPeriod, skipCheck) {
- if(!skipCheck)
- {
- check();
- }
-
- chrome.alarms.create(
- ALARM_UPDATE_CHECK,
- {
- delayInMinutes: updateCheckPeriod * 60,
- periodInMinutes: updateCheckPeriod * 60
- }
- );
-
- chrome.runtime.sendMessage(GS_CHROME_ID, MESSAGE_NEXT_UPDATE_CHANGED);
- }
-
- function check() {
- GSC.onInitialize().then(response => {
- if (response.success)
- {
- if(GSC.nativeUpdateCheckSupported(response))
- {
- chrome.storage.sync.get(DEFAULT_SYNC_OPTIONS, function (options) {
- GSC.sendNativeRequest(
- {
- execute: 'checkUpdate',
- url: UPDATE_URL,
- enabledOnly: options.updateCheckEnabledOnly
- }, function (response) {
- if (response.success)
- {
- onSweetToothResponse(response.upgrade,
response.extensions);
- }
- else if(console)
- {
- console.error(response.message ?
response.message : m('native_request_failed', 'checkUpdate'));
- }
- });
- });
- }
- else
- {
- chrome.storage.sync.set({
- updateCheck: false
- });
- }
- }
- else if(console)
- {
- console.error(response.message ? response.message :
m('native_request_failed', 'initialize'));
- }
- });
- }
-
- function onSweetToothResponse(data, installedExtensions) {
- var toUpgrade = [];
- for (uuid in data)
- {
- if (installedExtensions[uuid] && ['upgrade', 'downgrade'].includes(data[uuid]))
- {
- toUpgrade.push({
- title: installedExtensions[uuid].name,
- message: m('extension_status_' + data[uuid])
- });
- }
- }
-
- if (toUpgrade.length > 0)
- {
- GSC.notifications.create(NOTIFICATION_UPDATE_AVAILABLE, {
- type: chrome.notifications.TemplateType.LIST,
- title: m('update_available'),
- message: '',
- items: toUpgrade
- });
- }
-
- chrome.storage.local.set({
- lastUpdateCheck: new Date().toLocaleString()
- });
- }
-
- function init() {
- function onNotificationAction(notificationId, buttonIndex) {
- if (NOTIFICATION_UPDATE_AVAILABLE == notificationId)
- return;
-
- GSC.notifications.remove(notificationId);
- }
-
- function onNotificationClicked(notificationId) {
- if (notificationId === NOTIFICATION_UPDATE_AVAILABLE)
- {
- chrome.tabs.create({
- url: EXTENSIONS_WEBSITE + 'local/',
- active: true
- });
- }
- }
-
- chrome.alarms.onAlarm.addListener(function (alarm) {
- if (alarm.name === ALARM_UPDATE_CHECK)
- {
- check();
-
- chrome.alarms.get(ALARM_UPDATE_CHECK, function (alarm) {
- if (alarm && alarm.periodInMinutes && ((alarm.scheduledTime -
Date.now()) / 1000 / 60 < alarm.periodInMinutes * 0.9))
- {
- schedule(alarm.periodInMinutes / 60, true);
- }
- else
- {
- chrome.runtime.sendMessage(GS_CHROME_ID,
MESSAGE_NEXT_UPDATE_CHANGED);
- }
- });
- }
- });
-
- GSC.onInitialize().then(response => {
- /*
- @Deprecated: remove browser notifications in version 9
- */
- if (!GSC.nativeNotificationsSupported(response))
- {
- chrome.notifications.onClicked.addListener(function (notificationId) {
- onNotificationClicked(notificationId);
- });
-
- chrome.notifications.onButtonClicked.addListener(onNotificationAction);
- }
- else
- {
- window.addEventListener("message", function (event) {
- if (event.source == window && event.data && event.data.signal)
- {
- if(event.data.signal == SIGNAL_NOTIFICATION_ACTION)
- {
- onNotificationAction(event.data.name,
event.data.button_id);
- }
- else if(event.data.signal == SIGNAL_NOTIFICATION_CLICKED)
- {
- onNotificationClicked(event.data.name);
- }
- }
- });
- }
- });
-
- chrome.storage.onChanged.addListener(function (changes, areaName) {
- if (changes.updateCheck)
- {
- if (!changes.updateCheck.newValue)
- {
- chrome.alarms.clear(ALARM_UPDATE_CHECK);
- }
- else
- {
- chrome.storage.sync.get(DEFAULT_SYNC_OPTIONS, function (options) {
- schedule(options.updateCheckPeriod);
- });
- }
- }
- else if (changes.updateCheckPeriod)
- {
- chrome.storage.sync.get(DEFAULT_SYNC_OPTIONS, function (options) {
- if (options.updateCheck)
- {
- schedule(options.updateCheckPeriod);
- }
- });
- }
- });
-
- chrome.storage.sync.get(DEFAULT_SYNC_OPTIONS, function (options) {
- if (options.updateCheck)
- {
- chrome.alarms.get(ALARM_UPDATE_CHECK, function (alarm) {
- if (!alarm || !alarm.periodInMinutes || alarm.periodInMinutes !==
options.updateCheckPeriod * 60)
- {
- schedule(options.updateCheckPeriod);
- }
- });
- }
- });
- }
-
- return {
- init: init,
- check: check,
- schedule: schedule
- };
+GSC.update = (function () {
+ function schedule(updateCheckPeriod, skipCheck) {
+ if (!skipCheck) {
+ check();
+ }
+
+ chrome.alarms.create(
+ ALARM_UPDATE_CHECK,
+ {
+ delayInMinutes: updateCheckPeriod * 60,
+ periodInMinutes: updateCheckPeriod * 60
+ }
+ );
+
+ chrome.runtime.sendMessage(GS_CHROME_ID, MESSAGE_NEXT_UPDATE_CHANGED);
+ }
+
+ function check() {
+ GSC.onInitialize().then(response => {
+ if (response.success) {
+ if (GSC.nativeUpdateCheckSupported(response)) {
+ chrome.storage.sync.get(DEFAULT_SYNC_OPTIONS, function (options) {
+ GSC.sendNativeRequest(
+ {
+ execute: 'checkUpdate',
+ url: UPDATE_URL,
+ enabledOnly: options.updateCheckEnabledOnly
+ }, function (response) {
+ if (response.success) {
+ onSweetToothResponse(response.upgrade, response.extensions);
+ }
+ else if (console) {
+ console.error(response.message ? response.message :
m('native_request_failed', 'checkUpdate'));
+ }
+ });
+ });
+ }
+ else {
+ chrome.storage.sync.set({
+ updateCheck: false
+ });
+ }
+ }
+ else if (console) {
+ console.error(response.message ? response.message : m('native_request_failed',
'initialize'));
+ }
+ });
+ }
+
+ function onSweetToothResponse(data, installedExtensions) {
+ var toUpgrade = [];
+ for (uuid in data) {
+ if (installedExtensions[uuid] && ['upgrade', 'downgrade'].includes(data[uuid])) {
+ toUpgrade.push({
+ title: installedExtensions[uuid].name,
+ message: m('extension_status_' + data[uuid])
+ });
+ }
+ }
+
+ if (toUpgrade.length > 0) {
+ GSC.notifications.create(NOTIFICATION_UPDATE_AVAILABLE, {
+ type: chrome.notifications.TemplateType.LIST,
+ title: m('update_available'),
+ message: '',
+ items: toUpgrade
+ });
+ }
+
+ chrome.storage.local.set({
+ lastUpdateCheck: new Date().toLocaleString()
+ });
+ }
+
+ function init() {
+ function onNotificationAction(notificationId, buttonIndex) {
+ if (NOTIFICATION_UPDATE_AVAILABLE == notificationId)
+ return;
+
+ GSC.notifications.remove(notificationId);
+ }
+
+ function onNotificationClicked(notificationId) {
+ if (notificationId === NOTIFICATION_UPDATE_AVAILABLE) {
+ chrome.tabs.create({
+ url: EXTENSIONS_WEBSITE + 'local/',
+ active: true
+ });
+ }
+ }
+
+ chrome.alarms.onAlarm.addListener(function (alarm) {
+ if (alarm.name === ALARM_UPDATE_CHECK) {
+ check();
+
+ chrome.alarms.get(ALARM_UPDATE_CHECK, function (alarm) {
+ if (alarm && alarm.periodInMinutes && ((alarm.scheduledTime - Date.now()) / 1000 / 60 <
alarm.periodInMinutes * 0.9)) {
+ schedule(alarm.periodInMinutes / 60, true);
+ }
+ else {
+ chrome.runtime.sendMessage(GS_CHROME_ID, MESSAGE_NEXT_UPDATE_CHANGED);
+ }
+ });
+ }
+ });
+
+ GSC.onInitialize().then(response => {
+ /*
+ @Deprecated: remove browser notifications in version 9
+ */
+ if (!GSC.nativeNotificationsSupported(response)) {
+ chrome.notifications.onClicked.addListener(function (notificationId) {
+ onNotificationClicked(notificationId);
+ });
+
+ chrome.notifications.onButtonClicked.addListener(onNotificationAction);
+ }
+ else {
+ window.addEventListener("message", function (event) {
+ if (event.source == window && event.data && event.data.signal) {
+ if (event.data.signal == SIGNAL_NOTIFICATION_ACTION) {
+ onNotificationAction(event.data.name, event.data.button_id);
+ }
+ else if (event.data.signal == SIGNAL_NOTIFICATION_CLICKED) {
+ onNotificationClicked(event.data.name);
+ }
+ }
+ });
+ }
+ });
+
+ chrome.storage.onChanged.addListener(function (changes, areaName) {
+ if (changes.updateCheck) {
+ if (!changes.updateCheck.newValue) {
+ chrome.alarms.clear(ALARM_UPDATE_CHECK);
+ }
+ else {
+ chrome.storage.sync.get(DEFAULT_SYNC_OPTIONS, function (options) {
+ schedule(options.updateCheckPeriod);
+ });
+ }
+ }
+ else if (changes.updateCheckPeriod) {
+ chrome.storage.sync.get(DEFAULT_SYNC_OPTIONS, function (options) {
+ if (options.updateCheck) {
+ schedule(options.updateCheckPeriod);
+ }
+ });
+ }
+ });
+
+ chrome.storage.sync.get(DEFAULT_SYNC_OPTIONS, function (options) {
+ if (options.updateCheck) {
+ chrome.alarms.get(ALARM_UPDATE_CHECK, function (alarm) {
+ if (!alarm || !alarm.periodInMinutes || alarm.periodInMinutes !==
options.updateCheckPeriod * 60) {
+ schedule(options.updateCheckPeriod);
+ }
+ });
+ }
+ });
+ }
+
+ return {
+ init: init,
+ check: check,
+ schedule: schedule
+ };
})();
diff --git a/extension/options.html b/extension/options.html
index c8f809a..61e3337 100644
--- a/extension/options.html
+++ b/extension/options.html
@@ -1,113 +1,132 @@
<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <title data-i18n="options_title, __MSG_gs_chrome__"></title>
- <link href="css/options.css" rel="stylesheet" type="text/css" />
- <script type="text/javascript" src="include/i18n.js"></script>
- <script type="text/javascript" src="include/constants.js"></script>
- <script type="text/javascript" src="include/compat-common.js"></script>
- <script type="text/javascript" src="include/gsc.js"></script>
- <script type="text/javascript" src="include/sync.js"></script>
- </head>
- <body>
- <ul data-tabs class="tabs">
- <li><a href="#options" data-tabs-active data-i18n='options_link'
data-tab='tab'></a></li>
- <li><a href="#synchronization" data-i18n='synchronization' data-tab='tab'></a></li>
- <li class='translation_credits_container'><a href="#translation_credits"
data-i18n='translation_credits_title' data-tab='tab'></a></li>
- </ul>
- <div>
- <div id="options" class="tabs-pane active" data-tabs-pane='tabs-pane'>
- <div id="status" class="hide" data-i18n="options_saved"></div>
- <div id="error" class="hide"></div>
- <fieldset>
- <dl>
- <dt>
- <span data-i18n="options_update_check"></span>:<br
class="update-notice"/>
- <span class="notice wrapped update-notice"
data-i18n="options_update_check_notice"></span>
- </dt>
- <dd>
- <label for='update_check_yes'
data-i18n="yes"></label> <input type='radio' id='update_check_yes' name='update_check' disabled='disabled' />
- <label for='update_check_no' data-i18n="no"></label>
<input type='radio' id='update_check_no' name='update_check' disabled='disabled' />
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title data-i18n="options_title, __MSG_gs_chrome__"></title>
+ <link href="css/options.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="include/i18n.js"></script>
+ <script type="text/javascript" src="include/constants.js"></script>
+ <script type="text/javascript" src="include/compat-common.js"></script>
+ <script type="text/javascript" src="include/gsc.js"></script>
+ <script type="text/javascript" src="include/sync.js"></script>
+</head>
- <div class='notice'><span
data-i18n="options_last_check"></span>: <span id="last_update_check" data-i18n="never"></span></div>
- </dd>
- </dl>
- <dl>
- <dt>
- <span
data-i18n="options_update_check_enabled"></span>:<br class="update-notice"/>
- <span class="notice wrapped update-notice"
data-i18n="options_update_check_enabled_notice"></span>
- </dt>
- <dd>
- <label for='update_check_enabled_yes'
data-i18n="yes"></label> <input type='radio' id='update_check_enabled_yes' name='update_check_enabled'
disabled='disabled' />
- <label for='update_check_enabled_no'
data-i18n="no"></label> <input type='radio' id='update_check_enabled_no' name='update_check_enabled'
disabled='disabled' />
- </dd>
- </dl>
- <dl>
- <dt><label for='update_check_period'
data-i18n="options_check_period"></label>:</dt>
- <dd>
- <input id='update_check_period' type='number' min="3"
disabled='disabled' /> <span data-i18n="hours"></span>
+<body>
+ <ul data-tabs class="tabs">
+ <li><a href="#options" data-tabs-active data-i18n='options_link' data-tab='tab'></a></li>
+ <li><a href="#synchronization" data-i18n='synchronization' data-tab='tab'></a></li>
+ <li class='translation_credits_container'><a href="#translation_credits"
data-i18n='translation_credits_title'
+ data-tab='tab'></a></li>
+ </ul>
+ <div>
+ <div id="options" class="tabs-pane active" data-tabs-pane='tabs-pane'>
+ <div id="status" class="hide" data-i18n="options_saved"></div>
+ <div id="error" class="hide"></div>
- <div class='notice'><span
data-i18n="options_next_check"></span>: <span id="next_update_check" data-i18n="never"></span></div>
- </dd>
- </dl>
- <dl>
- <dt>
- <label for='synchronize_extensions_yes'
data-i18n="options_synchronize_extensions"></label>:<br />
- <span class="notice wrapped"
data-i18n="options_synchronize_extensions_notice"></span>
- </dt>
- <dd>
- <label for='synchronize_extensions_yes'
data-i18n="yes"></label> <input type='radio' id='synchronize_extensions_yes' name='synchronize_extensions' />
- <label for='synchronize_extensions_no'
data-i18n="no"></label> <input type='radio' id='synchronize_extensions_no' name='synchronize_extensions' />
- </dd>
- </dl>
- <dl>
- <dt><span data-i18n="options_use_light_icon"></span>:</dt>
- <dd>
- <label for='use_light_icon_yes'
data-i18n="yes"></label> <input type='radio' id='use_light_icon_yes' name='use_light_icon' />
- <label for='use_light_icon_no'
data-i18n="no"></label> <input type='radio' id='use_light_icon_no' name='use_light_icon' />
- </dd>
- </dl>
- <dl>
- <dt><span data-i18n="options_show_release_notes"></span>:</dt>
- <dd>
- <label for='show_release_notes_yes'
data-i18n="yes"></label> <input type='radio' id='show_release_notes_yes' name='show_release_notes' />
- <label for='show_release_notes_no'
data-i18n="no"></label> <input type='radio' id='show_release_notes_no' name='show_release_notes' />
- </dd>
- </dl>
- </fieldset>
+ <fieldset>
+ <dl>
+ <dt>
+ <span data-i18n="options_update_check"></span>:<br class="update-notice" />
+ <span class="notice wrapped update-notice"
data-i18n="options_update_check_notice"></span>
+ </dt>
+ <dd>
+ <label for='update_check_yes' data-i18n="yes"></label> <input type='radio'
id='update_check_yes'
+ name='update_check' disabled='disabled' />
+ <label for='update_check_no' data-i18n="no"></label> <input type='radio'
id='update_check_no'
+ name='update_check' disabled='disabled' />
- <div class='buttons'>
- <button id="save" data-i18n="save"></button>
- </div>
- </div>
- <div id="synchronization" class="tabs-pane" data-tabs-pane='tabs-pane'>
- <table>
- <thead>
- <tr>
- <th data-i18n="extension_name"></th>
- <th data-i18n="extension_installed"></th>
- <th data-i18n="extension_enabled"></th>
- <th data-i18n="extension_synchronized"></th>
- </tr>
- </thead>
- <tbody></tbody>
- </table>
- </div>
- <div id="translation_credits" class="tabs-pane translation_credits_container"
data-tabs-pane='tabs-pane'>
- <div data-i18n='translation_credits' data-i18n-html='true'></div>
- </div>
- </div>
+ <div class='notice'><span data-i18n="options_last_check"></span>: <span
id="last_update_check"
+ data-i18n="never"></span></div>
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <span data-i18n="options_update_check_enabled"></span>:<br class="update-notice" />
+ <span class="notice wrapped update-notice"
+ data-i18n="options_update_check_enabled_notice"></span>
+ </dt>
+ <dd>
+ <label for='update_check_enabled_yes' data-i18n="yes"></label> <input type='radio'
+ id='update_check_enabled_yes' name='update_check_enabled' disabled='disabled' />
+ <label for='update_check_enabled_no' data-i18n="no"></label> <input type='radio'
+ id='update_check_enabled_no' name='update_check_enabled' disabled='disabled' />
+ </dd>
+ </dl>
+ <dl>
+ <dt><label for='update_check_period' data-i18n="options_check_period"></label>:</dt>
+ <dd>
+ <input id='update_check_period' type='number' min="3" disabled='disabled' /> <span
+ data-i18n="hours"></span>
+
+ <div class='notice'><span data-i18n="options_next_check"></span>: <span
id="next_update_check"
+ data-i18n="never"></span></div>
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <label for='synchronize_extensions_yes'
+ data-i18n="options_synchronize_extensions"></label>:<br />
+ <span class="notice wrapped"
data-i18n="options_synchronize_extensions_notice"></span>
+ </dt>
+ <dd>
+ <label for='synchronize_extensions_yes' data-i18n="yes"></label> <input type='radio'
+ id='synchronize_extensions_yes' name='synchronize_extensions' />
+ <label for='synchronize_extensions_no' data-i18n="no"></label> <input type='radio'
+ id='synchronize_extensions_no' name='synchronize_extensions' />
+ </dd>
+ </dl>
+ <dl>
+ <dt><span data-i18n="options_use_light_icon"></span>:</dt>
+ <dd>
+ <label for='use_light_icon_yes' data-i18n="yes"></label> <input type='radio'
+ id='use_light_icon_yes' name='use_light_icon' />
+ <label for='use_light_icon_no' data-i18n="no"></label> <input type='radio'
+ id='use_light_icon_no' name='use_light_icon' />
+ </dd>
+ </dl>
+ <dl>
+ <dt><span data-i18n="options_show_release_notes"></span>:</dt>
+ <dd>
+ <label for='show_release_notes_yes' data-i18n="yes"></label> <input type='radio'
+ id='show_release_notes_yes' name='show_release_notes' />
+ <label for='show_release_notes_no' data-i18n="no"></label> <input type='radio'
+ id='show_release_notes_no' name='show_release_notes' />
+ </dd>
+ </dl>
+ </fieldset>
+
+ <div class='buttons'>
+ <button id="save" data-i18n="save"></button>
+ </div>
+ </div>
+ <div id="synchronization" class="tabs-pane" data-tabs-pane='tabs-pane'>
+ <table>
+ <thead>
+ <tr>
+ <th data-i18n="extension_name"></th>
+ <th data-i18n="extension_installed"></th>
+ <th data-i18n="extension_enabled"></th>
+ <th data-i18n="extension_synchronized"></th>
+ </tr>
+ </thead>
+ <tbody></tbody>
+ </table>
+ </div>
+ <div id="translation_credits" class="tabs-pane translation_credits_container"
data-tabs-pane='tabs-pane'>
+ <div data-i18n='translation_credits' data-i18n-html='true'></div>
+ </div>
+ </div>
+
+ <dialog id='syncChoice'>
+ <h2 data-i18n='synchronization_storage_exists'></h2>
+ <form method="dialog">
+ <button type='submit' value='local' data-i18n='synchronization_use_local'></button>
+ <button type='submit' value='remote' data-i18n='synchronization_use_remote'></button>
+ <button type='submit' value='cancel' data-i18n='synchronization_cancel'></button>
+ </form>
+ </dialog>
+ <script type="text/javascript" src="options.js"></script>
+</body>
- <dialog id='syncChoice'>
- <h2 data-i18n='synchronization_storage_exists'></h2>
- <form method="dialog">
- <button type='submit' value='local'
data-i18n='synchronization_use_local'></button>
- <button type='submit' value='remote'
data-i18n='synchronization_use_remote'></button>
- <button type='submit' value='cancel'
data-i18n='synchronization_cancel'></button>
- </form>
- </dialog>
- <script type="text/javascript" src="options.js"></script>
- </body>
</html>
diff --git a/extension/options.js b/extension/options.js
index f0f67f2..5aa392e 100644
--- a/extension/options.js
+++ b/extension/options.js
@@ -1,369 +1,325 @@
// SPDX-License-Identifer: GPL-3.0-or-later
-function init_tabs()
-{
- let tabLinks = $("[data-tabs]").querySelectorAll('a');
- let updateTabs = (active = null) => {
- tabLinks.forEach((link) => {
- let tab = $(link.getAttribute("href"));
-
- if((!active && link.hasAttribute('data-tabs-active')) || link == active) {
- tab.classList.remove('hide');
- }
- else {
- tab.classList.add('hide');
- }
- });
- };
-
- tabLinks.forEach((link) => {
- link.addEventListener('click', (event) => {
- updateTabs(event.target);
- });
- });
-
- updateTabs();
+function init_tabs() {
+ let tabLinks = $("[data-tabs]").querySelectorAll('a');
+ let updateTabs = (active = null) => {
+ tabLinks.forEach((link) => {
+ let tab = $(link.getAttribute("href"));
+
+ if ((!active && link.hasAttribute('data-tabs-active')) || link == active) {
+ tab.classList.remove('hide');
+ }
+ else {
+ tab.classList.add('hide');
+ }
+ });
+ };
+
+ tabLinks.forEach((link) => {
+ link.addEventListener('click', (event) => {
+ updateTabs(event.target);
+ });
+ });
+
+ updateTabs();
}
-function save_options()
-{
- var showReleaseNotes = $('#show_release_notes_yes').checked;
- var syncExtensions = $('#synchronize_extensions_yes').checked;
- var updateCheck = $('#update_check_yes').checked;
- var updateCheckEnabledOnly = $('#update_check_enabled_yes').checked;
- var updateCheckPeriod = $('#update_check_period').value;
- var useLightIcon = $('#use_light_icon_yes').checked;
- updateCheckPeriod = Math.max(3, updateCheckPeriod);
-
- chrome.storage.sync.set({
- showReleaseNotes: showReleaseNotes,
- updateCheck: updateCheck,
- updateCheckEnabledOnly: updateCheckEnabledOnly,
- updateCheckPeriod: updateCheckPeriod
- }, function () {
- chrome.storage.local.set({
- syncExtensions: syncExtensions,
- useLightIcon: useLightIcon
- }, function() {
- if(syncExtensions)
- {
- syncType = document.getElementById('syncChoice').returnValue;
- if(!syncType || syncType === 'local')
- {
- GSC.sync.getExtensions().then((extensions) => {
- var localExtensions = {};
- for (const [uuid, extension] of Object.entries(extensions)) {
- if(extension.local && extension.localState !=
EXTENSION_STATE.UNINSTALLED)
- {
- localExtensions[extension.uuid] = {
- uuid: extension.uuid,
- name: extension.name,
- state: extension.localState
- };
- }
- };
-
- chrome.storage.sync.set({
- extensions: localExtensions
- }, function() {
- showSuccessStatus();
- });
- }).catch((message) => {
- showWithDelay($('#error'), 15000, message);
- });
- }
- else if(syncType === 'remote')
- {
- chrome.runtime.sendMessage(GS_CHROME_ID, MESSAGE_SYNC_FROM_REMOTE);
- showSuccessStatus();
- }
- }
- else
- {
- showSuccessStatus();
- }
- });
- });
+function save_options() {
+ var showReleaseNotes = $('#show_release_notes_yes').checked;
+ var syncExtensions = $('#synchronize_extensions_yes').checked;
+ var updateCheck = $('#update_check_yes').checked;
+ var updateCheckEnabledOnly = $('#update_check_enabled_yes').checked;
+ var updateCheckPeriod = $('#update_check_period').value;
+ var useLightIcon = $('#use_light_icon_yes').checked;
+ updateCheckPeriod = Math.max(3, updateCheckPeriod);
+
+ chrome.storage.sync.set({
+ showReleaseNotes: showReleaseNotes,
+ updateCheck: updateCheck,
+ updateCheckEnabledOnly: updateCheckEnabledOnly,
+ updateCheckPeriod: updateCheckPeriod
+ }, function () {
+ chrome.storage.local.set({
+ syncExtensions: syncExtensions,
+ useLightIcon: useLightIcon
+ }, function () {
+ if (syncExtensions) {
+ syncType = document.getElementById('syncChoice').returnValue;
+ if (!syncType || syncType === 'local') {
+ GSC.sync.getExtensions().then((extensions) => {
+ var localExtensions = {};
+ for (const [uuid, extension] of Object.entries(extensions)) {
+ if (extension.local && extension.localState != EXTENSION_STATE.UNINSTALLED) {
+ localExtensions[extension.uuid] = {
+ uuid: extension.uuid,
+ name: extension.name,
+ state: extension.localState
+ };
+ }
+ };
+
+ chrome.storage.sync.set({
+ extensions: localExtensions
+ }, function () {
+ showSuccessStatus();
+ });
+ }).catch((message) => {
+ showWithDelay($('#error'), 15000, message);
+ });
+ }
+ else if (syncType === 'remote') {
+ chrome.runtime.sendMessage(GS_CHROME_ID, MESSAGE_SYNC_FROM_REMOTE);
+ showSuccessStatus();
+ }
+ }
+ else {
+ showSuccessStatus();
+ }
+ });
+ });
}
-function showSuccessStatus()
-{
- // Update status to let user know options were saved.
- showWithDelay($('#status'), 750);
+function showSuccessStatus() {
+ // Update status to let user know options were saved.
+ showWithDelay($('#status'), 750);
}
-function restore_options()
-{
- init_tabs();
-
- chrome.storage.sync.get(DEFAULT_SYNC_OPTIONS, function (items) {
- function toggle_notice(show, id) {
- let notice = $('#' + id)
- .closest('dl')
- .querySelector('dt br, dt span.notice');
-
- if (show)
- {
- notice.style.display = 'block';
- }
- else
- {
- notice.style.display = 'none';
- }
- }
-
- function toggle_update_notice(show) {
- toggle_notice(show, "update_check_yes");
- }
-
- function toggle_update_enable_notice(show) {
- toggle_notice(show, "update_check_enabled_yes");
- }
-
- function disable_update_check() {
- if (items.updateCheck)
- {
- items.updateCheck = false;
-
- chrome.storage.sync.set({
- updateCheck: items.updateCheck
- });
- }
-
- toggle_update_notice(true);
- }
-
- function disable_update_enabled_only() {
- if (items.updateCheckEnabledOnly)
- {
- items.updateCheckEnabledOnly = false;
-
- chrome.storage.sync.set({
- updateCheckEnabledOnly: items.updateCheckEnabledOnly
- });
- }
-
- toggle_update_enable_notice(true);
- }
-
- GSC.onInitialize().then(function (response) {
- if (!GSC.nativeUpdateCheckSupported(response))
- {
- disable_update_check();
- }
- else
- {
- $$("input[name='update_check'], #update_check_period").forEach((input) =>
input.disabled = false);
- $('#update_check_period').value = items.updateCheckPeriod;
- toggle_update_notice(false);
- retrieveUpdateTimes();
- }
-
- if (!GSC.nativeUpdateCheckEnabledOnlySupported(response))
- {
- disable_update_enabled_only();
- }
- else
- {
- $("input[name='update_check_enabled']").disabled = false;
- toggle_update_enable_notice(false);
- }
-
- setCheckUpdate(items.updateCheck);
- setCheckUpdateEnabledOnly(items.updateCheckEnabledOnly);
- }, function(response) {
- disable_update_check();
- });
-
- setReleaseNotes(items.showReleaseNotes);
- });
-
- if(COMPAT.SYNC_STORAGE)
- {
- updateSynchronizationStatus();
- }
- else
- {
- $('a[data-i18n="synchronization"]').parentNode.remove();
- $('#synchronize_extensions_yes').closest('dl').style.display = 'none';
- }
-
- chrome.storage.local.get(DEFAULT_LOCAL_OPTIONS, function (items) {
- if(items.syncExtensions)
- {
- chrome.permissions.contains({
- permissions: ["idle"]
- }, function (result) {
- setSyncExtensions(result);
- });
- }
- else if(COMPAT.SYNC_STORAGE)
- {
- setSyncExtensions(false);
- }
-
- setLightIcon(items.useLightIcon);
- });
+function restore_options() {
+ init_tabs();
+
+ chrome.storage.sync.get(DEFAULT_SYNC_OPTIONS, function (items) {
+ function toggle_notice(show, id) {
+ let notice = $('#' + id)
+ .closest('dl')
+ .querySelector('dt br, dt span.notice');
+
+ if (show) {
+ notice.style.display = 'block';
+ }
+ else {
+ notice.style.display = 'none';
+ }
+ }
+
+ function toggle_update_notice(show) {
+ toggle_notice(show, "update_check_yes");
+ }
+
+ function toggle_update_enable_notice(show) {
+ toggle_notice(show, "update_check_enabled_yes");
+ }
+
+ function disable_update_check() {
+ if (items.updateCheck) {
+ items.updateCheck = false;
+
+ chrome.storage.sync.set({
+ updateCheck: items.updateCheck
+ });
+ }
+
+ toggle_update_notice(true);
+ }
+
+ function disable_update_enabled_only() {
+ if (items.updateCheckEnabledOnly) {
+ items.updateCheckEnabledOnly = false;
+
+ chrome.storage.sync.set({
+ updateCheckEnabledOnly: items.updateCheckEnabledOnly
+ });
+ }
+
+ toggle_update_enable_notice(true);
+ }
+
+ GSC.onInitialize().then(function (response) {
+ if (!GSC.nativeUpdateCheckSupported(response)) {
+ disable_update_check();
+ }
+ else {
+ $$("input[name='update_check'], #update_check_period").forEach((input) => input.disabled =
false);
+ $('#update_check_period').value = items.updateCheckPeriod;
+ toggle_update_notice(false);
+ retrieveUpdateTimes();
+ }
+
+ if (!GSC.nativeUpdateCheckEnabledOnlySupported(response)) {
+ disable_update_enabled_only();
+ }
+ else {
+ $("input[name='update_check_enabled']").disabled = false;
+ toggle_update_enable_notice(false);
+ }
+
+ setCheckUpdate(items.updateCheck);
+ setCheckUpdateEnabledOnly(items.updateCheckEnabledOnly);
+ }, function (response) {
+ disable_update_check();
+ });
+
+ setReleaseNotes(items.showReleaseNotes);
+ });
+
+ if (COMPAT.SYNC_STORAGE) {
+ updateSynchronizationStatus();
+ }
+ else {
+ $('a[data-i18n="synchronization"]').parentNode.remove();
+ $('#synchronize_extensions_yes').closest('dl').style.display = 'none';
+ }
+
+ chrome.storage.local.get(DEFAULT_LOCAL_OPTIONS, function (items) {
+ if (items.syncExtensions) {
+ chrome.permissions.contains({
+ permissions: ["idle"]
+ }, function (result) {
+ setSyncExtensions(result);
+ });
+ }
+ else if (COMPAT.SYNC_STORAGE) {
+ setSyncExtensions(false);
+ }
+
+ setLightIcon(items.useLightIcon);
+ });
}
-function retrieveUpdateTimes()
-{
- chrome.storage.local.get({
- lastUpdateCheck: null
- }, function (items) {
- if(items.lastUpdateCheck)
- {
- $('#last_update_check').innerText = items.lastUpdateCheck;
- }
- else
- {
- $('#last_update_check').innerText = m('never');
- }
- });
-
- retrieveNextUpdateTime();
+function retrieveUpdateTimes() {
+ chrome.storage.local.get({
+ lastUpdateCheck: null
+ }, function (items) {
+ if (items.lastUpdateCheck) {
+ $('#last_update_check').innerText = items.lastUpdateCheck;
+ }
+ else {
+ $('#last_update_check').innerText = m('never');
+ }
+ });
+
+ retrieveNextUpdateTime();
}
-function retrieveNextUpdateTime()
-{
- chrome.alarms.get(ALARM_UPDATE_CHECK, function (alarm) {
- if (alarm)
- {
- $('#next_update_check').innerText = new Date(alarm.scheduledTime).toLocaleString();
- }
- else
- {
- $('#next_update_check').innerText = m('never');
- }
- });
+function retrieveNextUpdateTime() {
+ chrome.alarms.get(ALARM_UPDATE_CHECK, function (alarm) {
+ if (alarm) {
+ $('#next_update_check').innerText = new Date(alarm.scheduledTime).toLocaleString();
+ }
+ else {
+ $('#next_update_check').innerText = m('never');
+ }
+ });
}
-function setCheckUpdate(result)
-{
- if(result)
- $('#update_check_yes').checked = true;
- else
- $('#update_check_no').checked = true;
+function setCheckUpdate(result) {
+ if (result)
+ $('#update_check_yes').checked = true;
+ else
+ $('#update_check_no').checked = true;
}
-function setCheckUpdateEnabledOnly(result)
-{
- if(result)
- $('#update_check_enabled_yes').checked = true;
- else
- $('#update_check_enabled_no').checked = true;
+function setCheckUpdateEnabledOnly(result) {
+ if (result)
+ $('#update_check_enabled_yes').checked = true;
+ else
+ $('#update_check_enabled_no').checked = true;
}
-function setLightIcon(result)
-{
- if(result)
- $('#use_light_icon_yes').checked = true;
- else
- $('#use_light_icon_no').checked = true;
+function setLightIcon(result) {
+ if (result)
+ $('#use_light_icon_yes').checked = true;
+ else
+ $('#use_light_icon_no').checked = true;
}
-function setReleaseNotes(result)
-{
- if(result)
- $('#show_release_notes_yes').checked = true;
- else
- $('#show_release_notes_no').checked = true;
+function setReleaseNotes(result) {
+ if (result)
+ $('#show_release_notes_yes').checked = true;
+ else
+ $('#show_release_notes_no').checked = true;
}
-function setSyncExtensions(result)
-{
- if(result)
- $('#synchronize_extensions_yes').checked = true;
- else
- $('#synchronize_extensions_no').checked = true;
+function setSyncExtensions(result) {
+ if (result)
+ $('#synchronize_extensions_yes').checked = true;
+ else
+ $('#synchronize_extensions_no').checked = true;
}
-function handleSynchronize()
-{
- if($('#synchronize_extensions_yes').checked)
- {
- chrome.permissions.request({
- permissions: ["idle"]
- }, function(granted) {
- if(granted)
- {
- if(!COMPAT.PERMISSIONS_EVENTS)
- {
- chrome.runtime.sendMessage(GS_CHROME_ID,
MESSAGE_IDLE_PERMISSION_ADDED);
- }
-
- chrome.storage.sync.get({
- extensions: {}
- }, function (options) {
- if(!isEmptyObject(options.extensions))
- {
- document.getElementById('syncChoice').showModal();
- }
- });
- }
- else
- {
- if(!COMPAT.PERMISSIONS_EVENTS)
- {
- chrome.runtime.sendMessage(GS_CHROME_ID,
MESSAGE_IDLE_PERMISSION_REMOVED);
- }
-
- setSyncExtensions(false);
- }
- });
- }
- else
- {
- chrome.permissions.remove({
- permissions: ["idle"]
- }, function(removed) {
- if(removed && !COMPAT.PERMISSIONS_EVENTS)
- {
- chrome.runtime.sendMessage(GS_CHROME_ID, MESSAGE_IDLE_PERMISSION_REMOVED);
- }
-
- setSyncExtensions(!removed);
- });
- }
+function handleSynchronize() {
+ if ($('#synchronize_extensions_yes').checked) {
+ chrome.permissions.request({
+ permissions: ["idle"]
+ }, function (granted) {
+ if (granted) {
+ if (!COMPAT.PERMISSIONS_EVENTS) {
+ chrome.runtime.sendMessage(GS_CHROME_ID, MESSAGE_IDLE_PERMISSION_ADDED);
+ }
+
+ chrome.storage.sync.get({
+ extensions: {}
+ }, function (options) {
+ if (!isEmptyObject(options.extensions)) {
+ document.getElementById('syncChoice').showModal();
+ }
+ });
+ }
+ else {
+ if (!COMPAT.PERMISSIONS_EVENTS) {
+ chrome.runtime.sendMessage(GS_CHROME_ID, MESSAGE_IDLE_PERMISSION_REMOVED);
+ }
+
+ setSyncExtensions(false);
+ }
+ });
+ }
+ else {
+ chrome.permissions.remove({
+ permissions: ["idle"]
+ }, function (removed) {
+ if (removed && !COMPAT.PERMISSIONS_EVENTS) {
+ chrome.runtime.sendMessage(GS_CHROME_ID, MESSAGE_IDLE_PERMISSION_REMOVED);
+ }
+
+ setSyncExtensions(!removed);
+ });
+ }
}
-function updateSynchronizationStatus()
-{
- GSC.sync.getExtensions().then((extensions) => {
- var keys = Object.keys(extensions).sort(function (a, b) {
- var nameA = extensions[a].name.toLowerCase();
- var nameB = extensions[b].name.toLowerCase();
-
- if (nameA < nameB)
- {
- return -1;
- }
-
- if (nameA > nameB)
- {
- return 1;
- }
-
- return 0;
- });
-
- empty($('#synchronization table tbody'));
- for (const [key, uuid] of Object.entries(keys)) {
- var extension = extensions[uuid];
-
- $('#synchronization table tbody').insertAdjacentHTML(
- 'beforeEnd',
- `<tr>
+function updateSynchronizationStatus() {
+ GSC.sync.getExtensions().then((extensions) => {
+ var keys = Object.keys(extensions).sort(function (a, b) {
+ var nameA = extensions[a].name.toLowerCase();
+ var nameB = extensions[b].name.toLowerCase();
+
+ if (nameA < nameB) {
+ return -1;
+ }
+
+ if (nameA > nameB) {
+ return 1;
+ }
+
+ return 0;
+ });
+
+ empty($('#synchronization table tbody'));
+ for (const [key, uuid] of Object.entries(keys)) {
+ var extension = extensions[uuid];
+
+ $('#synchronization table tbody').insertAdjacentHTML(
+ 'beforeEnd',
+ `<tr>
<td>${extension.name}</td>
<td class='${extension.local && 'ok' || 'fail'}'></td>
<td class='${extension.localState == EXTENSION_STATE.ENABLED && 'ok'
|| 'fail'}'></td>
<td class='${extension.remote && 'ok' || 'fail'}'></td>
</tr>`
- );
- };
- }).catch((message) => {
- showWithDelay($('#error'), 15000, message);
- });
+ );
+ };
+ }).catch((message) => {
+ showWithDelay($('#error'), 15000, message);
+ });
}
i18n();
@@ -372,58 +328,49 @@ document.addEventListener('DOMContentLoaded', restore_options);
document.getElementById('save').addEventListener('click', save_options);
document.getElementsByName('synchronize_extensions').forEach((control) => {
- control.addEventListener('change', handleSynchronize);
+ control.addEventListener('change', handleSynchronize);
});
-document.getElementById('syncChoice').addEventListener('close', function() {
- if(document.getElementById('syncChoice').returnValue === 'cancel')
- {
- chrome.permissions.remove({
- permissions: ["idle"]
- }, function(removed) {
- if(removed && !COMPAT.PERMISSIONS_EVENTS)
- {
- chrome.runtime.sendMessage(GS_CHROME_ID, MESSAGE_IDLE_PERMISSION_REMOVED);
- }
-
- setSyncExtensions(!removed);
- });
- }
+document.getElementById('syncChoice').addEventListener('close', function () {
+ if (document.getElementById('syncChoice').returnValue === 'cancel') {
+ chrome.permissions.remove({
+ permissions: ["idle"]
+ }, function (removed) {
+ if (removed && !COMPAT.PERMISSIONS_EVENTS) {
+ chrome.runtime.sendMessage(GS_CHROME_ID, MESSAGE_IDLE_PERMISSION_REMOVED);
+ }
+
+ setSyncExtensions(!removed);
+ });
+ }
});
-if(!$('#translation_credits div').firstChild)
-{
- $('.translation_credits_container').remove();
+if (!$('#translation_credits div').firstChild) {
+ $('.translation_credits_container').remove();
}
chrome.storage.onChanged.addListener(function (changes, areaName) {
- if (areaName === 'local')
- {
- if(changes.lastUpdateCheck && changes.lastUpdateCheck.newValue)
- {
- $('#last_update_check').innerText = changes.lastUpdateCheck.newValue;
- }
- }
-
- if (areaName === 'sync' && changes.extensions)
- {
- updateSynchronizationStatus();
- }
+ if (areaName === 'local') {
+ if (changes.lastUpdateCheck && changes.lastUpdateCheck.newValue) {
+ $('#last_update_check').innerText = changes.lastUpdateCheck.newValue;
+ }
+ }
+
+ if (areaName === 'sync' && changes.extensions) {
+ updateSynchronizationStatus();
+ }
});
chrome.runtime.onMessage.addListener(
- function (request, sender, sendResponse) {
- if(sender.id && sender.id === GS_CHROME_ID && request)
- {
- if(request === MESSAGE_NEXT_UPDATE_CHANGED)
- {
- retrieveNextUpdateTime();
- }
- else if(request.signal && request.signal === SIGNAL_EXTENSION_CHANGED)
- {
- updateSynchronizationStatus();
- }
- }
- }
+ function (request, sender, sendResponse) {
+ if (sender.id && sender.id === GS_CHROME_ID && request) {
+ if (request === MESSAGE_NEXT_UPDATE_CHANGED) {
+ retrieveNextUpdateTime();
+ }
+ else if (request.signal && request.signal === SIGNAL_EXTENSION_CHANGED) {
+ updateSynchronizationStatus();
+ }
+ }
+ }
);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]