From 94db6c69fa4aa25231e213c6d0e185197bfe3418 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 11 Feb 2021 18:55:09 -0500 Subject: Permissions button in browser action popup (#1368) * Add key icon * Update context icon styles * Add permissions links * Show warning badge if permissions are insufficient for certain settings * Create PermissionsUtil * Use PermissionsUtil in Backend * Update SettingsController to use PermissionsUtil * Update AnkiController to use getRequiredPermissionsForAnkiFieldValue * Show the permissions buttons/links on the context page when necessary * Update MV3 compatibility --- ext/bg/js/backend.js | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) (limited to 'ext/bg/js/backend.js') diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index e5f8466e..3dd1955f 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -28,6 +28,7 @@ * MediaUtility * ObjectPropertyAccessor * OptionsUtil + * PermissionsUtil * ProfileConditions * RequestBuilder * Translator @@ -83,6 +84,8 @@ class Backend { this._defaultBrowserActionTitle = null; this._badgePrepareDelayTimer = null; this._logErrorLevel = null; + this._permissions = null; + this._permissionsUtil = new PermissionsUtil(); this._messageHandlers = new Map([ ['requestBackendReadySignal', {async: false, contentScript: true, handler: this._onApiRequestBackendReadySignal.bind(this)}], @@ -174,12 +177,17 @@ class Backend { const onMessage = this._onMessageWrapper.bind(this); chrome.runtime.onMessage.addListener(onMessage); + + const onPermissionsChanged = this._onWebExtensionEventWrapper(this._onPermissionsChanged.bind(this)); + chrome.permissions.onAdded.addListener(onPermissionsChanged); + chrome.permissions.onRemoved.addListener(onPermissionsChanged); } async _prepareInternal() { try { this._prepareInternalSync(); + this._permissions = await this._permissionsUtil.getAllPermissions(); this._defaultBrowserActionTitle = await this._getBrowserIconTitle(); this._badgePrepareDelayTimer = setTimeout(() => { this._badgePrepareDelayTimer = null; @@ -357,6 +365,10 @@ class Backend { this._sendMessageTabIgnoreResponse(tabId, {action: 'zoomChanged', params: {oldZoomFactor, newZoomFactor}}); } + _onPermissionsChanged() { + this._checkPermissions(); + } + // Message handlers _onApiRequestBackendReadySignal(_params, sender) { @@ -682,7 +694,7 @@ class Backend { let permissionsOkay = false; try { - permissionsOkay = await this._hasPermissions({permissions: ['nativeMessaging']}); + permissionsOkay = await this._permissionsUtil.hasPermissions({permissions: ['nativeMessaging']}); } catch (e) { // NOP } @@ -1263,6 +1275,10 @@ class Backend { text = 'off'; color = '#555555'; status = 'Disabled'; + } else if (!this._hasRequiredPermissionsForSettings(options)) { + text = '!'; + color = '#f0ad4e'; + status = 'Some settings require additional permissions'; } else if (!this._isAnyDictionaryEnabled(options)) { text = '!'; color = '#f0ad4e'; @@ -1941,17 +1957,6 @@ class Backend { }); } - _hasPermissions(permissions) { - return new Promise((resolve, reject) => chrome.permissions.contains(permissions, (result) => { - const e = chrome.runtime.lastError; - if (e) { - reject(new Error(e.message)); - } else { - resolve(result); - } - })); - } - _getTabById(tabId) { return new Promise((resolve, reject) => { chrome.tabs.get( @@ -1967,4 +1972,13 @@ class Backend { ); }); } + + async _checkPermissions() { + this._permissions = await this._permissionsUtil.getAllPermissions(); + this._updateBadge(); + } + + _hasRequiredPermissionsForSettings(options) { + return this._permissions === null || this._permissionsUtil.hasRequiredPermissionsForOptions(this._permissions, options); + } } -- cgit v1.2.3