diff --git a/extension/include/compat-common.js b/extension/include/compat-common.js deleted file mode 100644 index ead71dda..00000000 --- a/extension/include/compat-common.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - GNOME Shell integration for Chrome - Copyright (C) 2016 Yuri Konotopov - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - */ - -/* global chrome, COMPAT */ - -COMPAT.ON_INSTALLED = true; -COMPAT.ON_STARTUP = true; -COMPAT.PERMISSIONS_CONTAINS = true; -COMPAT.SYNC_STORAGE = (!COMPAT.IS_OPERA || false); -COMPAT.NOTIFICATIONS_BUTTONS = (!COMPAT.IS_OPERA && !COMPAT.IS_FIREFOX || false); - -if (typeof (chrome.runtime.onStartup) === 'undefined') -{ - chrome.runtime.onStartup = { - addListener: function() { } - }; - COMPAT.ON_STARTUP = false; -} - -if(typeof(chrome.runtime.onInstalled) === 'undefined') -{ - chrome.runtime.onInstalled = { - addListener: function() { } - }; - COMPAT.ON_INSTALLED = false; -} - -if(typeof(chrome.runtime.onMessageExternal) === 'undefined') -{ - 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.storage.sync) === 'undefined' || COMPAT.IS_FIREFOX) -{ - chrome.storage.sync = chrome.storage.local; - COMPAT.SYNC_STORAGE = false; -} diff --git a/extension/include/gsc.js b/extension/include/gsc.js deleted file mode 100644 index fc3945e8..00000000 --- a/extension/include/gsc.js +++ /dev/null @@ -1,143 +0,0 @@ -/* - GNOME Shell integration for Chrome - Copyright (C) 2016 Yuri Konotopov - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - */ - -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 - ) - { - // 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); - } - }; -})(); diff --git a/extension/include/sync.js b/extension/include/sync.js deleted file mode 100644 index fb38b07e..00000000 --- a/extension/include/sync.js +++ /dev/null @@ -1,374 +0,0 @@ -/* - GNOME Shell integration for Chrome - Copyright (C) 2016 Yuri Konotopov - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - */ - -/* - * Main object that handles extensions synchronization with remote storage. - */ -GSC.sync = (function($) { - /* - * Initialization rutines. - */ - function init() { - if(!COMPAT.SYNC_STORAGE) - { - return; - } - - 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(deferred, remoteExtensions) { - GSC.sendNativeRequest({ - execute: 'listExtensions' - }, function(response) { - if(response && response.success) - { - if(remoteExtensions) - { - deferred.resolve(mergeExtensions(remoteExtensions, response.extensions)); - } - else - { - chrome.storage.sync.get({ - extensions: {} - }, function(options) { - if(chrome.runtime.lastError) - { - deferred.reject(chrome.runtime.lastError.message); - } - else - { - var extensions = mergeExtensions(options.extensions, response.extensions); - deferred.resolve(extensions); - } - }); - } - } - else - { - var message = response && response.message ? response.message : m('error_extension_response'); - deferred.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 = {}; - - $.each(remoteExtensions, function(key, extension) { - if(extension.uuid && extension.name && extension.state) - { - extensions[extension.uuid] = { - uuid: extension.uuid, - name: extension.name, - remoteState: extension.state, - remote: true, - local: false - }; - } - }); - - $.each(localExtensions, function(key, extension) { - 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. - * - * @param extension - extension object: - * { - * uuid: extension uuid, - * name: extension name, - * state: extension state - * } - */ - function localExtensionChanged(extension) { - if($.inArray(extension.state, [EXTENSION_STATE.ENABLED, EXTENSION_STATE.DISABLED, EXTENSION_STATE.UNINSTALLED]) !== -1) - { - chrome.storage.sync.get({ - extensions: {} - }, function (options) { - GSC.sendNativeRequest({ - execute: 'getExtensionInfo', - uuid: extension.uuid - }, function(response) { - // Extension can be uninstalled already - if(response && response.extensionInfo && !$.isEmptyObject(response.extensionInfo)) - { - extension = response.extensionInfo; - } - - 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 - }); - }); - }); - } - } - - /* - * Synchronize remote changes with local GNOME Shell. - * - * @param remoteExtensions - (optional) remote extensions list - */ - function remoteExtensionsChanged(remoteExtensions) { - getExtensions($.Deferred().done(function(extensions) { - var enableExtensions = []; - $.each(extensions, function(uuid, extension) { - 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 - }); - } - }).fail(function(message) { - createSyncFailedNotification(message); - }), remoteExtensions); - } - - /* - * 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) - { - return; - } - - runIfSyncEnabled(function() { - localExtensionChanged({ - uuid: request.parameters[EXTENSION_CHANGED_UUID], - state: request.parameters[EXTENSION_CHANGED_STATE], - error: request.parameters[EXTENSION_CHANGED_ERROR] - }); - }); - } - - /* - * 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) - { - 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 - }; -})(jQuery); diff --git a/extension/include/update.js b/extension/include/update.js deleted file mode 100644 index 1e6792e4..00000000 --- a/extension/include/update.js +++ /dev/null @@ -1,300 +0,0 @@ -/* - GNOME Shell integration for Chrome - Copyright (C) 2016 Yuri Konotopov - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - */ - -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) - { - var shellVersion = response.properties.shellVersion; - - // TODO: remove deprecated in version 9 - if(GSC.nativeUpdateCheckSupported(response)) - { - GSC.sendNativeRequest({execute: 'checkUpdate', url: UPDATE_URL}, function (response) { - if (response.success) - { - onSweetToothResponse(response.upgrade, response.extensions); - } - else - { - createUpdateFailedNotification(response.message ? response.message : m('native_request_failed', 'checkUpdate')); - } - }); - } - else - { - _frontendCheck(shellVersion); - } - } - else - { - createUpdateFailedNotification(response.message ? response.message : m('native_request_failed', 'initialize')); - } - }); - } - - /* - * TODO: remove in version 9 - * @Deprecated - */ - function _frontendCheck(shellVersion) - { - GSC.sendNativeRequest({execute: 'listExtensions'}, function (extensionsResponse) { - if (extensionsResponse.success) - { - if ($.isEmptyObject(extensionsResponse.extensions)) - return; - - var request = { - shell_version: shellVersion, - installed: {} - }; - - for (uuid in extensionsResponse.extensions) - { - if (GSC.isUUID(uuid) && extensionsResponse.extensions[uuid].type == EXTENSION_TYPE.PER_USER) - { - request.installed[uuid] = {version: parseInt(extensionsResponse.extensions[uuid].version) || 1}; - } - } - - request.installed = JSON.stringify(request.installed); - - chrome.permissions.contains({ - permissions: ["webRequest"] - }, function (webRequestEnabled) { - if (webRequestEnabled) - { - chrome.webRequest.onErrorOccurred.addListener( - onNetworkError, - { - urls: [UPDATE_URL + "*"], - types: ['xmlhttprequest'] - } - ); - } - - $.ajax({ - url: UPDATE_URL, - data: request, - dataType: 'json', - method: 'GET', - cache: false - }) - .done(function(data) { - onSweetToothResponse(data, extensionsResponse.extensions) - }) - .fail(function (jqXHR, textStatus, errorThrown) { - if (textStatus === 'error' && !errorThrown) - { - if (webRequestEnabled) - { - return; - } - - textStatus = m('network_error'); - } - - createUpdateFailedNotification(textStatus); - }).always(function () { - if (webRequestEnabled) - { - chrome.webRequest.onErrorOccurred.removeListener(onNetworkError); - } - }); - }); - } else - { - createUpdateFailedNotification(response.message ? response.message : m('native_request_failed', 'listExtensions')); - } - }); - } - - function onSweetToothResponse(data, installedExtensions) { - GSC.notifications.remove(NOTIFICATION_UPDATE_CHECK_FAILED); - - var toUpgrade = []; - for (uuid in data) - { - if (installedExtensions[uuid] && $.inArray(data[uuid], ['upgrade', 'downgrade']) !== -1) - { - 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 createUpdateFailedNotification(cause) { - GSC.notifications.create(NOTIFICATION_UPDATE_CHECK_FAILED, { - message: m('update_check_failed', cause), - buttons: [ - {title: m('retry')}, - {title: m('close')} - ] - }); - } - - function onNetworkError(details) { - createUpdateFailedNotification(details.error); - } - - function init() { - function onNotificationAction(notificationId, buttonIndex) { - if ($.inArray(notificationId, [NOTIFICATION_UPDATE_AVAILABLE, NOTIFICATION_UPDATE_CHECK_FAILED]) === -1) - return; - - if (notificationId === NOTIFICATION_UPDATE_CHECK_FAILED && buttonIndex == 0) - { - check(); - } - - 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 - { - 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); - } - else if(request.signal == SIGNAL_NOTIFICATION_CLICKED) - { - onNotificationClicked(request.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 - }; -})(jQuery);