From f466d60db322f9531332bb3ce91d5a1d09017682 Mon Sep 17 00:00:00 2001 From: Daisuke Akatsuka Date: Tue, 19 Feb 2019 01:10:54 +0000 Subject: [PATCH] Bug 1500350: Add a checkbox to enable addon debugging on this-firefox. r=jdescottes,ladybenko Differential Revision: https://phabricator.services.mozilla.com/D18196 --HG-- extra : moz-landing-system : lando --- .../src/actions/runtimes.js | 39 ++++++++++ .../client/aboutdebugging-new/src/base.css | 12 +++ .../src/components/ExtensionDebugSetting.js | 74 +++++++++++++++++++ .../src/components/RuntimePage.js | 16 +++- .../src/components/moz.build | 1 + .../aboutdebugging-new/src/constants.js | 5 ++ .../src/modules/client-wrapper.js | 2 + .../src/modules/debug-target-support.js | 13 ++++ .../src/reducers/runtimes-state.js | 10 +++ .../aboutdebugging-new/src/types/runtime.js | 4 + .../tmp-locale/en-US/aboutdebugging.notftl | 6 ++ 11 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 devtools/client/aboutdebugging-new/src/components/ExtensionDebugSetting.js diff --git a/devtools/client/aboutdebugging-new/src/actions/runtimes.js b/devtools/client/aboutdebugging-new/src/actions/runtimes.js index 4ebe93b03562..86c92ca1f231 100644 --- a/devtools/client/aboutdebugging-new/src/actions/runtimes.js +++ b/devtools/client/aboutdebugging-new/src/actions/runtimes.js @@ -14,6 +14,7 @@ const { const { l10n } = require("../modules/l10n"); const { createClientForRuntime } = require("../modules/runtime-client-factory"); +const { isExtensionDebugSettingNeeded } = require("../modules/debug-target-support"); const { remoteClientManager } = require("devtools/client/shared/remote-debugging/remote-client-manager"); @@ -36,6 +37,9 @@ const { UPDATE_CONNECTION_PROMPT_SETTING_FAILURE, UPDATE_CONNECTION_PROMPT_SETTING_START, UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS, + UPDATE_EXTENSION_DEBUG_SETTING_FAILURE, + UPDATE_EXTENSION_DEBUG_SETTING_START, + UPDATE_EXTENSION_DEBUG_SETTING_SUCCESS, UPDATE_RUNTIME_MULTIE10S_FAILURE, UPDATE_RUNTIME_MULTIE10S_START, UPDATE_RUNTIME_MULTIE10S_SUCCESS, @@ -71,12 +75,19 @@ function connectRuntime(id) { const icon = await getRuntimeIcon(deviceDescription.channel); const { + CHROME_DEBUG_ENABLED, CONNECTION_PROMPT, PERMANENT_PRIVATE_BROWSING, + REMOTE_DEBUG_ENABLED, SERVICE_WORKERS_ENABLED, } = RUNTIME_PREFERENCE; const connectionPromptEnabled = await clientWrapper.getPreference(CONNECTION_PROMPT, false); + const extensionDebugEnabled = + isExtensionDebugSettingNeeded(runtime.type) + ? await clientWrapper.getPreference(CHROME_DEBUG_ENABLED, true) && + await clientWrapper.getPreference(REMOTE_DEBUG_ENABLED, true) + : true; const privateBrowsing = await clientWrapper.getPreference(PERMANENT_PRIVATE_BROWSING, false); const serviceWorkersEnabled = @@ -87,6 +98,7 @@ function connectRuntime(id) { clientWrapper, compatibilityReport, connectionPromptEnabled, + extensionDebugEnabled, info: { deviceName: deviceDescription.deviceName, icon, @@ -186,6 +198,32 @@ function updateConnectionPromptSetting(connectionPromptEnabled) { }; } +function updateExtensionDebugSetting(extensionDebugEnabled) { + return async (dispatch, getState) => { + dispatch({ type: UPDATE_EXTENSION_DEBUG_SETTING_START }); + try { + const runtime = getCurrentRuntime(getState().runtimes); + const { clientWrapper } = runtime.runtimeDetails; + + const { CHROME_DEBUG_ENABLED, REMOTE_DEBUG_ENABLED } = RUNTIME_PREFERENCE; + await clientWrapper.setPreference(CHROME_DEBUG_ENABLED, extensionDebugEnabled); + await clientWrapper.setPreference(REMOTE_DEBUG_ENABLED, extensionDebugEnabled); + + // Re-get actual value from the runtime. + const isChromeDebugEnabled = + await clientWrapper.getPreference(CHROME_DEBUG_ENABLED, extensionDebugEnabled); + const isRemoveDebugEnabled = + await clientWrapper.getPreference(REMOTE_DEBUG_ENABLED, extensionDebugEnabled); + extensionDebugEnabled = isChromeDebugEnabled && isRemoveDebugEnabled; + + dispatch({ type: UPDATE_EXTENSION_DEBUG_SETTING_SUCCESS, + runtime, extensionDebugEnabled }); + } catch (e) { + dispatch({ type: UPDATE_EXTENSION_DEBUG_SETTING_FAILURE, error: e }); + } + }; +} + function updateMultiE10s() { return async (dispatch, getState) => { dispatch({ type: UPDATE_RUNTIME_MULTIE10S_START }); @@ -375,6 +413,7 @@ module.exports = { removeRuntimeListeners, unwatchRuntime, updateConnectionPromptSetting, + updateExtensionDebugSetting, updateNetworkRuntimes, updateUSBRuntimes, watchRuntime, diff --git a/devtools/client/aboutdebugging-new/src/base.css b/devtools/client/aboutdebugging-new/src/base.css index b180d1a5c551..2d964e3c68d8 100644 --- a/devtools/client/aboutdebugging-new/src/base.css +++ b/devtools/client/aboutdebugging-new/src/base.css @@ -123,6 +123,11 @@ p { font-family: var(--monospace-font-family); } +/* Text that is not selectable */ +.unselectable-text { + -moz-user-select: none; +} + /* * Typography */ @@ -299,6 +304,13 @@ Form controls background-color: var(--box-background); } +.default-checkbox { + /* Note: this styles are from Photon, not common.css */ + height: calc(var(--base-unit) * 4); + margin-inline-end: var(--base-unit); + width: calc(var(--base-unit) * 4); +} + /* * Other UI components */ diff --git a/devtools/client/aboutdebugging-new/src/components/ExtensionDebugSetting.js b/devtools/client/aboutdebugging-new/src/components/ExtensionDebugSetting.js new file mode 100644 index 000000000000..c6081e4c4c99 --- /dev/null +++ b/devtools/client/aboutdebugging-new/src/components/ExtensionDebugSetting.js @@ -0,0 +1,74 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); +const dom = require("devtools/client/shared/vendor/react-dom-factories"); +const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); + +const FluentReact = require("devtools/client/shared/vendor/fluent-react"); +const Localized = createFactory(FluentReact.Localized); + +const Actions = require("../actions/index"); + +const DOC_URL = + "https://developer.mozilla.org/docs/Tools/about:debugging#Enabling_add-on_debugging"; + +class ExtensionDebugSetting extends PureComponent { + static get propTypes() { + return { + dispatch: PropTypes.func.isRequired, + extensionDebugEnabled: PropTypes.bool.isRequired, + }; + } + + onToggle() { + const { extensionDebugEnabled, dispatch } = this.props; + dispatch(Actions.updateExtensionDebugSetting(!extensionDebugEnabled)); + } + + renderCheckbox() { + const { extensionDebugEnabled } = this.props; + + return dom.input( + { + type: "checkbox", + id: "extension-debug-setting-input", + className: "default-checkbox", + checked: extensionDebugEnabled, + onChange: () => this.onToggle(), + } + ); + } + + renderLabel() { + return Localized( + { + id: "about-debugging-extension-debug-setting-label", + a: dom.a({ + href: DOC_URL, + target: "_blank", + }), + }, + dom.label( + { + className: "unselectable-text", + htmlFor: "extension-debug-setting-input", + }, + "Enable extension debugging [Learn more]" + ) + ); + } + + render() { + return dom.aside( + {}, + this.renderCheckbox(), + this.renderLabel(), + ); + } +} + +module.exports = ExtensionDebugSetting; diff --git a/devtools/client/aboutdebugging-new/src/components/RuntimePage.js b/devtools/client/aboutdebugging-new/src/components/RuntimePage.js index 87eda8acfe6f..0942c9cfa0f4 100644 --- a/devtools/client/aboutdebugging-new/src/components/RuntimePage.js +++ b/devtools/client/aboutdebugging-new/src/components/RuntimePage.js @@ -15,6 +15,7 @@ const Localized = createFactory(FluentReact.Localized); const CompatibilityWarning = createFactory(require("./CompatibilityWarning")); const ConnectionPromptSetting = createFactory(require("./ConnectionPromptSetting")); const DebugTargetPane = createFactory(require("./debugtarget/DebugTargetPane")); +const ExtensionDebugSetting = createFactory(require("./ExtensionDebugSetting")); const ExtensionDetail = createFactory(require("./debugtarget/ExtensionDetail")); const InspectAction = createFactory(require("./debugtarget/InspectAction")); const ProfilerDialog = createFactory(require("./ProfilerDialog")); @@ -33,7 +34,10 @@ const { DEBUG_TARGET_PANE, PAGE_TYPES, RUNTIMES } = require("../constants"); const Types = require("../types/index"); const { getCurrentRuntimeDetails } = require("../modules/runtimes-state-helper"); -const { isSupportedDebugTargetPane } = require("../modules/debug-target-support"); +const { + isExtensionDebugSettingNeeded, + isSupportedDebugTargetPane, +} = require("../modules/debug-target-support"); class RuntimePage extends PureComponent { static get propTypes() { @@ -125,6 +129,12 @@ class RuntimePage extends PureComponent { ); } + renderExtensionDebugSetting() { + const { runtimeDetails, dispatch } = this.props; + const { extensionDebugEnabled } = runtimeDetails; + return ExtensionDebugSetting({ extensionDebugEnabled, dispatch }); + } + render() { const { dispatch, @@ -155,6 +165,10 @@ class RuntimePage extends PureComponent { this.renderRemoteRuntimeActions(), runtimeDetails.serviceWorkersAvailable ? null : ServiceWorkersWarning(), CompatibilityWarning({ compatibilityReport }), + // show component to enable/disable extension debugging. + isExtensionDebugSettingNeeded(type) + ? this.renderExtensionDebugSetting() + : null, isSupportedDebugTargetPane(type, DEBUG_TARGET_PANE.TEMPORARY_EXTENSION) ? TemporaryExtensionInstaller({ dispatch, diff --git a/devtools/client/aboutdebugging-new/src/components/moz.build b/devtools/client/aboutdebugging-new/src/components/moz.build index b360406b7177..17de2ca9428f 100644 --- a/devtools/client/aboutdebugging-new/src/components/moz.build +++ b/devtools/client/aboutdebugging-new/src/components/moz.build @@ -14,6 +14,7 @@ DevToolsModules( 'App.js', 'CompatibilityWarning.js', 'ConnectionPromptSetting.js', + 'ExtensionDebugSetting.js', 'ProfilerDialog.css', 'ProfilerDialog.js', 'RuntimeInfo.js', diff --git a/devtools/client/aboutdebugging-new/src/constants.js b/devtools/client/aboutdebugging-new/src/constants.js index c383477d898a..9f5ccb8c59aa 100644 --- a/devtools/client/aboutdebugging-new/src/constants.js +++ b/devtools/client/aboutdebugging-new/src/constants.js @@ -50,6 +50,9 @@ const actionTypes = { UPDATE_CONNECTION_PROMPT_SETTING_FAILURE: "UPDATE_CONNECTION_PROMPT_SETTING_FAILURE", UPDATE_CONNECTION_PROMPT_SETTING_START: "UPDATE_CONNECTION_PROMPT_SETTING_START", UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS: "UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS", + UPDATE_EXTENSION_DEBUG_SETTING_FAILURE: "UPDATE_EXTENSION_DEBUG_SETTING_FAILURE", + UPDATE_EXTENSION_DEBUG_SETTING_START: "UPDATE_EXTENSION_DEBUG_SETTING_START", + UPDATE_EXTENSION_DEBUG_SETTING_SUCCESS: "UPDATE_EXTENSION_DEBUG_SETTING_SUCCESS", UPDATE_RUNTIME_MULTIE10S_FAILURE: "UPDATE_RUNTIME_MULTIE10S_FAILURE", UPDATE_RUNTIME_MULTIE10S_START: "UPDATE_RUNTIME_MULTIE10S_START", UPDATE_RUNTIME_MULTIE10S_SUCCESS: "UPDATE_RUNTIME_MULTIE10S_SUCCESS", @@ -95,8 +98,10 @@ const PREFERENCES = { }; const RUNTIME_PREFERENCE = { + CHROME_DEBUG_ENABLED: "devtools.chrome.enabled", CONNECTION_PROMPT: "devtools.debugger.prompt-connection", PERMANENT_PRIVATE_BROWSING: "browser.privatebrowsing.autostart", + REMOTE_DEBUG_ENABLED: "devtools.debugger.remote-enabled", SERVICE_WORKERS_ENABLED: "dom.serviceWorkers.enabled", }; diff --git a/devtools/client/aboutdebugging-new/src/modules/client-wrapper.js b/devtools/client/aboutdebugging-new/src/modules/client-wrapper.js index 566fb21987e8..8153a39bc56c 100644 --- a/devtools/client/aboutdebugging-new/src/modules/client-wrapper.js +++ b/devtools/client/aboutdebugging-new/src/modules/client-wrapper.js @@ -16,8 +16,10 @@ const PREF_TYPES = { // Map of preference to preference type. const PREF_TO_TYPE = { + [RUNTIME_PREFERENCE.CHROME_DEBUG_ENABLED]: PREF_TYPES.BOOL, [RUNTIME_PREFERENCE.CONNECTION_PROMPT]: PREF_TYPES.BOOL, [RUNTIME_PREFERENCE.PERMANENT_PRIVATE_BROWSING]: PREF_TYPES.BOOL, + [RUNTIME_PREFERENCE.REMOTE_DEBUG_ENABLED]: PREF_TYPES.BOOL, [RUNTIME_PREFERENCE.SERVICE_WORKERS_ENABLED]: PREF_TYPES.BOOL, }; diff --git a/devtools/client/aboutdebugging-new/src/modules/debug-target-support.js b/devtools/client/aboutdebugging-new/src/modules/debug-target-support.js index 41a07027fa1d..bcc08d23a315 100644 --- a/devtools/client/aboutdebugging-new/src/modules/debug-target-support.js +++ b/devtools/client/aboutdebugging-new/src/modules/debug-target-support.js @@ -25,6 +25,19 @@ const SUPPORTED_TARGET_PANE_BY_RUNTIME = { [RUNTIMES.NETWORK]: REMOTE_DEBUG_TARGET_PANES, }; +/** + * If extension debug setting is needed for given runtime type, return true. + * + * @param {String} runtimeType + * @return {bool} true: needed + */ +function isExtensionDebugSettingNeeded(runtimeType) { + // Debugging local addons for This Firefox reuses the Browser Toolbox, which requires + // some preferences to be enabled. + return runtimeType === RUNTIMES.THIS_FIREFOX; +} +exports.isExtensionDebugSettingNeeded = isExtensionDebugSettingNeeded; + /** * A debug target pane is more specialized than a debug target. For instance EXTENSION is * a DEBUG_TARGET but INSTALLED_EXTENSION and TEMPORARY_EXTENSION are DEBUG_TARGET_PANES. diff --git a/devtools/client/aboutdebugging-new/src/reducers/runtimes-state.js b/devtools/client/aboutdebugging-new/src/reducers/runtimes-state.js index a57c0ee79ff3..4edd479bae33 100644 --- a/devtools/client/aboutdebugging-new/src/reducers/runtimes-state.js +++ b/devtools/client/aboutdebugging-new/src/reducers/runtimes-state.js @@ -9,6 +9,7 @@ const { DISCONNECT_RUNTIME_SUCCESS, RUNTIMES, UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS, + UPDATE_EXTENSION_DEBUG_SETTING_SUCCESS, UPDATE_RUNTIME_MULTIE10S_SUCCESS, REMOTE_RUNTIMES_UPDATED, SELECTED_RUNTIME_ID_UPDATED, @@ -97,6 +98,15 @@ function runtimesReducer(state = RuntimesState(), action) { return _updateRuntimeById(runtimeId, { runtimeDetails }, state); } + case UPDATE_EXTENSION_DEBUG_SETTING_SUCCESS: { + const { extensionDebugEnabled } = action; + const { id: runtimeId } = action.runtime; + const runtime = findRuntimeById(runtimeId, state); + const runtimeDetails = + Object.assign({}, runtime.runtimeDetails, { extensionDebugEnabled }); + return _updateRuntimeById(runtimeId, { runtimeDetails }, state); + } + case UPDATE_RUNTIME_MULTIE10S_SUCCESS: { const { isMultiE10s } = action; const { id: runtimeId } = action.runtime; diff --git a/devtools/client/aboutdebugging-new/src/types/runtime.js b/devtools/client/aboutdebugging-new/src/types/runtime.js index d29d56c965b6..e2fc74708301 100644 --- a/devtools/client/aboutdebugging-new/src/types/runtime.js +++ b/devtools/client/aboutdebugging-new/src/types/runtime.js @@ -55,6 +55,10 @@ const runtimeDetails = { // reflect devtools.debugger.prompt-connection preference of this runtime connectionPromptEnabled: PropTypes.bool.isRequired, + // In case that runtime is this-firefox, reflects devtools.chrome.enabled and + // devtools.debugger.remote-enabled preference. Otherwise, this sould be true. + extensionDebugEnabled: PropTypes.bool.isRequired, + // runtime information info: PropTypes.shape(runtimeInfo).isRequired, diff --git a/devtools/client/aboutdebugging-new/tmp-locale/en-US/aboutdebugging.notftl b/devtools/client/aboutdebugging-new/tmp-locale/en-US/aboutdebugging.notftl index 66cc2a3a5766..7b759cac8838 100644 --- a/devtools/client/aboutdebugging-new/tmp-locale/en-US/aboutdebugging.notftl +++ b/devtools/client/aboutdebugging-new/tmp-locale/en-US/aboutdebugging.notftl @@ -300,3 +300,9 @@ about-debugging-page-title = { -application-title } - { about-debugging-page-tit # Title of a modal dialog displayed on remote runtime pages after clicking on the Profile Runtime button. about-debugging-profiler-dialog-title = Performance Profiler + +# Label of a checkbox displayed in the runtime page for "This Firefox". +# This checkbox will toggle preferences that enable local addon debugging. +# The "Learn more" link points to MDN. +# https://developer.mozilla.org/docs/Tools/about:debugging#Enabling_add-on_debugging +about-debugging-extension-debug-setting-label = Enable extension debugging Learn more