summaryrefslogtreecommitdiffstats
path: root/devtools/client
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
commitd8bbc7858622b6d9c278469aab701ca0b609cddf (patch)
treeeff41dc61d9f714852212739e6b3738b82a2af87 /devtools/client
parentReleasing progress-linux version 125.0.3-1~progress7.99u1. (diff)
downloadfirefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.tar.xz
firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.zip
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client')
-rw-r--r--devtools/client/aboutdebugging/initializer.js4
-rw-r--r--devtools/client/aboutdebugging/src/modules/extensions-helper.js2
-rw-r--r--devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_manifest_url.js2
-rw-r--r--devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-linux.xpibin495578 -> 518006 bytes
-rw-r--r--devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-linux64.xpibin824421 -> 854419 bytes
-rw-r--r--devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-mac64.xpibin782572 -> 805405 bytes
-rw-r--r--devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-win32.xpibin713900 -> 742749 bytes
-rw-r--r--devtools/client/accessibility/main.js4
-rw-r--r--devtools/client/accessibility/test/chrome/head.js4
-rw-r--r--devtools/client/application/initializer.js4
-rw-r--r--devtools/client/debugger/index.html4
-rw-r--r--devtools/client/debugger/src/.eslintrc.js5
-rw-r--r--devtools/client/debugger/src/actions/context-menus/editor.js21
-rw-r--r--devtools/client/debugger/src/components/Editor/Breakpoint.js2
-rw-r--r--devtools/client/debugger/src/components/Editor/Breakpoints.css27
-rw-r--r--devtools/client/debugger/src/components/Editor/Breakpoints.js114
-rw-r--r--devtools/client/debugger/src/components/Editor/DebugLine.js63
-rw-r--r--devtools/client/debugger/src/components/Editor/Editor.css25
-rw-r--r--devtools/client/debugger/src/components/Editor/Exceptions.js49
-rw-r--r--devtools/client/debugger/src/components/Editor/index.js145
-rw-r--r--devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/index.js3
-rw-r--r--devtools/client/debugger/src/components/shared/Button/styles/CommandBarButton.css1
-rw-r--r--devtools/client/debugger/src/utils/editor/index.js17
-rw-r--r--devtools/client/debugger/src/utils/editor/source-documents.js10
-rw-r--r--devtools/client/debugger/src/utils/editor/tokens.js2
-rw-r--r--devtools/client/debugger/src/utils/ui.js6
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-popup.js8
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-call-stack.js2
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-console-async.js2
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-console-map-bindings.js2
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-console.js2
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-dom-mutation-breakpoints.js4
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-es-module-worker.js2
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-log-events.js2
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-log-point-mapping.js2
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-log-points-workers.js2
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-log-points.js2
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-paused-anonymous.js9
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-preview.js40
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-source-pragma.js3
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-state-based-panels.js3
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-step-in-navigate.js3
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-windowless-service-workers-reload.js3
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-windowless-service-workers.js9
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-windowless-workers.js7
-rw-r--r--devtools/client/debugger/test/mochitest/shared-head.js20
-rw-r--r--devtools/client/dom/main.js4
-rw-r--r--devtools/client/framework/components/MeatballMenu.js34
-rw-r--r--devtools/client/framework/components/ToolboxToolbar.js8
-rw-r--r--devtools/client/framework/test/browser_dynamic_tool_enabling.js2
-rw-r--r--devtools/client/framework/test/browser_toolbox_error_count.js32
-rw-r--r--devtools/client/framework/test/browser_toolbox_error_count_reset_on_navigation.js2
-rw-r--r--devtools/client/framework/test/browser_toolbox_remoteness_change.js2
-rw-r--r--devtools/client/framework/test/browser_toolbox_screenshot_tool.js2
-rw-r--r--devtools/client/framework/test/browser_toolbox_watchedByDevTools.js5
-rw-r--r--devtools/client/framework/toolbox-init.js4
-rw-r--r--devtools/client/framework/toolbox-options.html12
-rw-r--r--devtools/client/framework/toolbox-options.js10
-rw-r--r--devtools/client/framework/toolbox.js49
-rw-r--r--devtools/client/fronts/targets/target-mixin.js31
-rw-r--r--devtools/client/inspector/changes/test/browser_changes_nested_rules.js4
-rw-r--r--devtools/client/inspector/computed/test/browser_computed_search-filter_context-menu.js12
-rw-r--r--devtools/client/inspector/index.xhtml4
-rw-r--r--devtools/client/inspector/markup/test/browser_markup_screenshot_node_about_page.js8
-rw-r--r--devtools/client/inspector/rules/models/element-style.js122
-rw-r--r--devtools/client/inspector/rules/test/browser_rules_content_01.js2
-rw-r--r--devtools/client/inspector/rules/test/browser_rules_nested_rules.js6
-rw-r--r--devtools/client/inspector/rules/test/browser_rules_search-filter_context-menu.js12
-rw-r--r--devtools/client/inspector/rules/test/browser_rules_select-and-copy-styles.js4
-rw-r--r--devtools/client/inspector/rules/test/browser_rules_selector-highlighter-nested-rules.js4
-rw-r--r--devtools/client/inspector/rules/test/browser_rules_variables_02.js9
-rw-r--r--devtools/client/inspector/test/browser_inspector_highlighter-cssshape_offset-path.js1
-rw-r--r--devtools/client/inspector/test/browser_inspector_inspect_loading_document.js11
-rw-r--r--devtools/client/inspector/test/browser_inspector_menu-04-use-in-console.js20
-rw-r--r--devtools/client/inspector/test/browser_inspector_search-filter_context-menu.js12
-rw-r--r--devtools/client/jar.mn1
-rw-r--r--devtools/client/locales/en-US/toolbox-options.ftl10
-rw-r--r--devtools/client/locales/en-US/toolbox.properties6
-rw-r--r--devtools/client/memory/panel.js4
-rw-r--r--devtools/client/memory/test/chrome/head.js4
-rw-r--r--devtools/client/netmonitor/initializer.js4
-rw-r--r--devtools/client/netmonitor/src/har/test/browser_net_har_copy_all_as_har.js10
-rw-r--r--devtools/client/netmonitor/src/har/test/browser_net_har_import.js2
-rw-r--r--devtools/client/netmonitor/src/har/test/head.js2
-rw-r--r--devtools/client/netmonitor/test/browser_net_cached-status.js3
-rw-r--r--devtools/client/netmonitor/test/browser_net_copy_as_powershell.js8
-rw-r--r--devtools/client/netmonitor/test/browser_net_copy_headers.js1
-rw-r--r--devtools/client/netmonitor/test/browser_net_headers_sorted.js2
-rw-r--r--devtools/client/netmonitor/test/browser_net_http3_request_details.js4
-rw-r--r--devtools/client/netmonitor/test/browser_net_resend.js11
-rw-r--r--devtools/client/netmonitor/test/browser_net_simple-request-details.js4
-rw-r--r--devtools/client/performance-new/@types/gecko.d.ts2
-rw-r--r--devtools/client/performance-new/aboutprofiling/initializer.js4
-rw-r--r--devtools/client/performance-new/panel/initializer.js4
-rw-r--r--devtools/client/performance-new/shared/#typescript-lazy-load.jsm.js#55
-rw-r--r--devtools/client/performance-new/tsconfig.json7
-rw-r--r--devtools/client/responsive/index.js4
-rw-r--r--devtools/client/responsive/test/browser/browser_device_width.js3
-rw-r--r--devtools/client/responsive/test/browser/browser_toolbox_computed_view.js28
-rw-r--r--devtools/client/responsive/test/browser/browser_viewport_resizing_after_reload.js2
-rw-r--r--devtools/client/responsive/test/browser/browser_viewport_resizing_fixed_width.js4
-rw-r--r--devtools/client/responsive/test/browser/doc_toolbox_rule_view.html1
-rw-r--r--devtools/client/shared/components/NotificationBox.css2
-rw-r--r--devtools/client/shared/components/test/chrome/head.js4
-rw-r--r--devtools/client/shared/output-parser.js76
-rw-r--r--devtools/client/shared/remote-debugging/adb/xpcshell/test_prepare-tcp-connection.js4
-rw-r--r--devtools/client/shared/sourceeditor/editor.js251
-rw-r--r--devtools/client/shared/test/browser_browserloader_mocks.js4
-rw-r--r--devtools/client/shared/test/browser_outputparser.js31
-rw-r--r--devtools/client/shared/test/browser_require_raw.js4
-rw-r--r--devtools/client/shared/test/shared-head.js26
-rw-r--r--devtools/client/shared/thread-utils.js5
-rw-r--r--devtools/client/shared/vendor/WASMPARSER_UPGRADING4
-rw-r--r--devtools/client/shared/vendor/WasmDis.js54
-rw-r--r--devtools/client/shared/vendor/WasmParser.js81
-rw-r--r--devtools/client/shared/widgets/tooltip/css-compatibility-tooltip-helper.js4
-rw-r--r--devtools/client/storage/test/browser_storage_cache_navigation.js5
-rw-r--r--devtools/client/storage/test/browser_storage_cookies_navigation.js6
-rw-r--r--devtools/client/styleeditor/StyleEditorUI.sys.mjs5
-rw-r--r--devtools/client/styleeditor/panel.js1
-rw-r--r--devtools/client/styleeditor/test/browser_styleeditor_at_rules_sidebar.js30
-rw-r--r--devtools/client/styleeditor/test/media-rules.html7
-rw-r--r--devtools/client/themes/dark-theme.css8
-rw-r--r--devtools/client/themes/images/whatsnew.svg10
-rw-r--r--devtools/client/themes/light-theme.css8
-rw-r--r--devtools/client/themes/rules.css4
-rw-r--r--devtools/client/webconsole/components/Output/message-types/JSTracerTrace.js2
-rw-r--r--devtools/client/webconsole/test/browser/_jsterm.toml2
-rw-r--r--devtools/client/webconsole/test/browser/browser_console_webconsole_private_browsing.js2
-rw-r--r--devtools/client/webconsole/test/browser/browser_jsterm_await_paused.js2
-rw-r--r--devtools/client/webconsole/test/browser/browser_jsterm_eager_evaluation.js2
-rw-r--r--devtools/client/webconsole/test/browser/browser_jsterm_editor_reverse_search_keyboard_navigation.js6
-rw-r--r--devtools/client/webconsole/test/browser/browser_webconsole_console_api_iframe.js2
-rw-r--r--devtools/client/webconsole/test/browser/browser_webconsole_cors_errors.js15
-rw-r--r--devtools/client/webconsole/test/browser/browser_webconsole_split_escape_key.js23
-rw-r--r--devtools/client/webconsole/test/browser/browser_webconsole_split_persist.js2
-rw-r--r--devtools/client/webconsole/test/browser/browser_webconsole_stubs_console_api.js5
-rw-r--r--devtools/client/webconsole/test/browser/browser_webconsole_stubs_page_error.js5
-rw-r--r--devtools/client/webconsole/test/chrome/head.js4
-rw-r--r--devtools/client/webconsole/webconsole-ui.js4
140 files changed, 1475 insertions, 494 deletions
diff --git a/devtools/client/aboutdebugging/initializer.js b/devtools/client/aboutdebugging/initializer.js
index a541df46b9..46c9b63893 100644
--- a/devtools/client/aboutdebugging/initializer.js
+++ b/devtools/client/aboutdebugging/initializer.js
@@ -4,8 +4,8 @@
"use strict";
-const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
const { require } = BrowserLoader({
baseURI: "resource://devtools/client/aboutdebugging/",
diff --git a/devtools/client/aboutdebugging/src/modules/extensions-helper.js b/devtools/client/aboutdebugging/src/modules/extensions-helper.js
index cf6c7641e9..03831939d0 100644
--- a/devtools/client/aboutdebugging/src/modules/extensions-helper.js
+++ b/devtools/client/aboutdebugging/src/modules/extensions-helper.js
@@ -42,7 +42,7 @@ exports.getExtensionUuid = function (extension) {
* The window object where the filepicker should be opened.
* Note: We cannot use the global window object here because it is undefined if
* this module is loaded from a file outside of devtools/client/aboutdebugging/.
- * See browser-loader.js `uri.startsWith(baseURI)` for more details.
+ * See browser-loader.sys.mjs `uri.startsWith(baseURI)` for more details.
* @param {String} message
* The help message that should be displayed to the user in the filepicker.
* @return {Promise} returns a promise that resolves a File object corresponding to the
diff --git a/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_manifest_url.js b/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_manifest_url.js
index 6420a076b0..a4da406a6b 100644
--- a/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_manifest_url.js
+++ b/devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_manifest_url.js
@@ -7,7 +7,7 @@ const {
adbAddon,
} = require("resource://devtools/client/shared/remote-debugging/adb/adb-addon.js");
-const ABD_ADDON_NAME = "ADB binary provider";
+const ABD_ADDON_NAME = "Firefox DevTools ADB Extension";
/* import-globals-from helper-adb.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-adb.js", this);
diff --git a/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-linux.xpi b/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-linux.xpi
index 56054c341c..2e0b115665 100644
--- a/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-linux.xpi
+++ b/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-linux.xpi
Binary files differ
diff --git a/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-linux64.xpi b/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-linux64.xpi
index 9cd737b017..8065f96de4 100644
--- a/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-linux64.xpi
+++ b/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-linux64.xpi
Binary files differ
diff --git a/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-mac64.xpi b/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-mac64.xpi
index 5af9bc963d..d6ecd43957 100644
--- a/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-mac64.xpi
+++ b/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-mac64.xpi
Binary files differ
diff --git a/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-win32.xpi b/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-win32.xpi
index 0c10c8502c..95d5c6485f 100644
--- a/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-win32.xpi
+++ b/devtools/client/aboutdebugging/test/browser/resources/test-adb-extension/adb-extension-win32.xpi
Binary files differ
diff --git a/devtools/client/accessibility/main.js b/devtools/client/accessibility/main.js
index c658d05825..bbfae3462a 100644
--- a/devtools/client/accessibility/main.js
+++ b/devtools/client/accessibility/main.js
@@ -3,8 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
-const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
// Module Loader
diff --git a/devtools/client/accessibility/test/chrome/head.js b/devtools/client/accessibility/test/chrome/head.js
index a1a02df8a8..2bd03d53c6 100644
--- a/devtools/client/accessibility/test/chrome/head.js
+++ b/devtools/client/accessibility/test/chrome/head.js
@@ -8,8 +8,8 @@
var { require } = ChromeUtils.importESModule(
"resource://devtools/shared/loader/Loader.sys.mjs"
);
-var { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+var { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
var DevToolsUtils = require("resource://devtools/shared/DevToolsUtils.js");
diff --git a/devtools/client/application/initializer.js b/devtools/client/application/initializer.js
index c431945bf0..06caa9d169 100644
--- a/devtools/client/application/initializer.js
+++ b/devtools/client/application/initializer.js
@@ -4,8 +4,8 @@
"use strict";
-const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
const require = BrowserLoader({
baseURI: "resource://devtools/client/application/",
diff --git a/devtools/client/debugger/index.html b/devtools/client/debugger/index.html
index 0a7ef58d8e..108fe5a653 100644
--- a/devtools/client/debugger/index.html
+++ b/devtools/client/debugger/index.html
@@ -55,8 +55,8 @@
></script>
<script>
try {
- const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+ const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
const { require } = BrowserLoader({
baseURI: "resource://devtools/client/debugger",
diff --git a/devtools/client/debugger/src/.eslintrc.js b/devtools/client/debugger/src/.eslintrc.js
index ec6d77b504..67f317ea28 100644
--- a/devtools/client/debugger/src/.eslintrc.js
+++ b/devtools/client/debugger/src/.eslintrc.js
@@ -251,8 +251,9 @@ module.exports = {
// Disallow unreachable statements after a return, throw, continue, or break
// statement.
"no-unreachable": 2,
- // Disallow global and local variables that arent used, but allow unused function arguments.
- "no-unused-vars": [2, { vars: "all", args: "none" }],
+ // Disallow global and local variables that arent used. Allow unused function arguments
+ // that are prefixed with `_`.
+ "no-unused-vars": [2, { vars: "all", argsIgnorePattern: "^_" }],
// Allow using variables before they are defined.
"no-use-before-define": 0,
// We use var-only-at-top-level instead of no-var as we allow top level
diff --git a/devtools/client/debugger/src/actions/context-menus/editor.js b/devtools/client/debugger/src/actions/context-menus/editor.js
index 1cad1e2131..4785c963cb 100644
--- a/devtools/client/debugger/src/actions/context-menus/editor.js
+++ b/devtools/client/debugger/src/actions/context-menus/editor.js
@@ -73,7 +73,7 @@ export function showEditorContextMenu(event, editor, location) {
};
}
-export function showEditorGutterContextMenu(event, editor, location, lineText) {
+export function showEditorGutterContextMenu(event, line, location, lineText) {
return async ({ dispatch, getState }) => {
const { source } = location;
const state = getState();
@@ -90,7 +90,7 @@ export function showEditorGutterContextMenu(event, editor, location, lineText) {
{ type: "separator" },
blackBoxLineMenuItem(
source,
- editor,
+ line,
blackboxedRanges,
isSourceOnIgnoreList,
location.line,
@@ -178,7 +178,7 @@ const blackBoxMenuItem = (
const blackBoxLineMenuItem = (
selectedSource,
- editor,
+ { from, to },
blackboxedRanges,
isSourceOnIgnoreList,
// the clickedLine is passed when the context menu
@@ -187,10 +187,6 @@ const blackBoxLineMenuItem = (
clickedLine = null,
dispatch
) => {
- const { codeMirror } = editor;
- const from = codeMirror.getCursor("from");
- const to = codeMirror.getCursor("to");
-
const startLine = clickedLine ?? toSourceLine(selectedSource.id, from.line);
const endLine = clickedLine ?? toSourceLine(selectedSource.id, to.line);
@@ -251,16 +247,12 @@ const blackBoxLineMenuItem = (
const blackBoxLinesMenuItem = (
selectedSource,
- editor,
+ { from, to },
blackboxedRanges,
isSourceOnIgnoreList,
clickedLine,
dispatch
) => {
- const { codeMirror } = editor;
- const from = codeMirror.getCursor("from");
- const to = codeMirror.getCursor("to");
-
const startLine = toSourceLine(selectedSource.id, from.line);
const endLine = toSourceLine(selectedSource.id, to.line);
@@ -408,7 +400,10 @@ function editorMenuItems({
items.push(
blackBoxSourceLinesMenuItem(
source,
- editor,
+ {
+ from: editor.codeMirror.getCursor("from"),
+ to: editor.codeMirror.getCursor("to"),
+ },
blackboxedRanges,
isSourceOnIgnoreList,
null,
diff --git a/devtools/client/debugger/src/components/Editor/Breakpoint.js b/devtools/client/debugger/src/components/Editor/Breakpoint.js
index 4559a20289..40de6d47c7 100644
--- a/devtools/client/debugger/src/components/Editor/Breakpoint.js
+++ b/devtools/client/debugger/src/components/Editor/Breakpoint.js
@@ -59,7 +59,7 @@ class Breakpoint extends PureComponent {
selectedSource,
} = this.props;
- // ignore right clicks
+ // ignore ctrl + click and right clicks when clicking on the breakpoint
if ((event.ctrlKey && event.button === 0) || event.button === 2) {
return;
}
diff --git a/devtools/client/debugger/src/components/Editor/Breakpoints.css b/devtools/client/debugger/src/components/Editor/Breakpoints.css
index 1269f73f82..92121e0f46 100644
--- a/devtools/client/debugger/src/components/Editor/Breakpoints.css
+++ b/devtools/client/debugger/src/components/Editor/Breakpoints.css
@@ -36,7 +36,7 @@
pointer-events: none;
}
-.editor-wrapper :not(.empty-line, .new-breakpoint)
+.editor-wrapper :not(.empty-line, .new-breakpoint .cm6-gutter-breakpoint)
> .CodeMirror-gutter-wrapper
> .CodeMirror-linenumber:hover::after {
content: "";
@@ -55,6 +55,27 @@
mask-position: right;
}
+/* Codemirror 6*/
+.cm6-gutter-breakpoint .breakpoint-marker svg {
+ fill: var(--breakpoint-fill);
+ stroke: var(--breakpoint-stroke);
+ height: 14px;
+ position: absolute;
+ right: -8px;
+ z-index: -99;
+}
+
+/* set the linenumber white when there is a breakpoint */
+.editor-wrapper:not(.skip-pausing) .new-breakpoint .CodeMirror-gutter-wrapper .CodeMirror-linenumber,
+ .editor-wrapper:not(.skip-pausing) .cm6-gutter-breakpoint {
+ color: white;
+}
+
+/* move the breakpoint below the other gutter elements */
+.new-breakpoint .CodeMirror-gutter-elt:nth-child(2) {
+ z-index: 0;
+}
+
.editor.new-breakpoint svg {
fill: var(--breakpoint-fill);
stroke: var(--breakpoint-stroke);
@@ -85,7 +106,9 @@
}
.editor.new-breakpoint.breakpoint-disabled svg,
-.blackboxed-line .editor.new-breakpoint svg {
+.blackboxed-line .editor.new-breakpoint svg,
+.cm6-gutter-breakpoint .breakpoint-marker.breakpoint-disabled svg,
+.cm6-gutter-breakpoint.blackboxed-line .breakpoint-marker svg {
fill-opacity: var(--breakpoint-disabled-opacity);
stroke-opacity: var(--breakpoint-disabled-opacity);
}
diff --git a/devtools/client/debugger/src/components/Editor/Breakpoints.js b/devtools/client/debugger/src/components/Editor/Breakpoints.js
index 6d1d088f11..ac3fe0890c 100644
--- a/devtools/client/debugger/src/components/Editor/Breakpoints.js
+++ b/devtools/client/debugger/src/components/Editor/Breakpoints.js
@@ -11,9 +11,31 @@ import {
getSelectedSource,
getFirstVisibleBreakpoints,
} from "../../selectors/index";
+import { getSelectedLocation } from "../../utils/selected-location";
import { makeBreakpointId } from "../../utils/breakpoint/index";
import { connect } from "devtools/client/shared/vendor/react-redux";
+import { fromEditorLine } from "../../utils/editor/index";
import actions from "../../actions/index";
+import { features } from "../../utils/prefs";
+const classnames = require("resource://devtools/client/shared/classnames.js");
+
+const isMacOS = Services.appinfo.OS === "Darwin";
+
+const breakpointSvg = document.createElement("div");
+const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+svg.setAttribute("viewBox", "0 0 60 15");
+svg.setAttribute("width", 60);
+svg.setAttribute("height", 15);
+
+const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
+path.setAttributeNS(
+ null,
+ "d",
+ "M53.07.5H1.5c-.54 0-1 .46-1 1v12c0 .54.46 1 1 1h51.57c.58 0 1.15-.26 1.53-.7l4.7-6.3-4.7-6.3c-.38-.44-.95-.7-1.53-.7z"
+);
+
+svg.appendChild(path);
+breakpointSvg.appendChild(svg);
class Breakpoints extends Component {
static get propTypes() {
@@ -27,6 +49,93 @@ class Breakpoints extends Component {
showEditorEditBreakpointContextMenu: PropTypes.func,
};
}
+
+ constructor(props) {
+ super(props);
+ }
+
+ componentDidUpdate() {
+ const { selectedSource, breakpoints, editor } = this.props;
+
+ // Only for codemirror 6
+ if (!features.codemirrorNext) {
+ return;
+ }
+
+ if (!selectedSource || !breakpoints || !editor) {
+ return;
+ }
+
+ const markers = [
+ {
+ id: "gutter-breakpoint-marker",
+ lineClassName: "cm6-gutter-breakpoint",
+ condition: line => {
+ const lineNumber = fromEditorLine(selectedSource.id, line);
+ return breakpoints.some(bp => bp.location.line === lineNumber);
+ },
+ createLineElementNode: line => {
+ const lineNumber = fromEditorLine(selectedSource.id, line);
+ const breakpoint = breakpoints.find(
+ bp => bp.location.line === lineNumber
+ );
+
+ const breakpointNode = breakpointSvg.cloneNode(true);
+ breakpointNode.appendChild(document.createTextNode(lineNumber));
+ breakpointNode.className = classnames("breakpoint-marker", {
+ "breakpoint-disabled": breakpoint.disabled,
+ "has-condition": breakpoint?.options.condition,
+ "has-log": breakpoint?.options.logValue,
+ });
+ breakpointNode.onclick = event => this.onClick(event, breakpoint);
+ breakpointNode.oncontextmenu = event =>
+ this.onContextMenu(event, breakpoint);
+ return breakpointNode;
+ },
+ },
+ ];
+ editor.setLineGutterMarkers(markers);
+ }
+
+ onClick = (event, breakpoint) => {
+ const {
+ continueToHere,
+ toggleBreakpointsAtLine,
+ removeBreakpointsAtLine,
+ selectedSource,
+ } = this.props;
+
+ event.stopPropagation();
+ event.preventDefault();
+
+ // ignore right clicks when clicking on the breakpoint
+ if (event.button === 2) {
+ return;
+ }
+
+ const selectedLocation = getSelectedLocation(breakpoint, selectedSource);
+ const ctrlOrCmd = isMacOS ? event.metaKey : event.ctrlKey;
+
+ if (ctrlOrCmd) {
+ continueToHere(selectedLocation);
+ return;
+ }
+
+ if (event.shiftKey) {
+ toggleBreakpointsAtLine(!breakpoint.disabled, selectedLocation.line);
+ return;
+ }
+
+ removeBreakpointsAtLine(selectedLocation.source, selectedLocation.line);
+ };
+
+ onContextMenu = (event, breakpoint) => {
+ event.stopPropagation();
+ event.preventDefault();
+
+ this.props.showEditorEditBreakpointContextMenu(event, breakpoint);
+ };
+
render() {
const {
breakpoints,
@@ -41,6 +150,11 @@ class Breakpoints extends Component {
if (!selectedSource || !breakpoints) {
return null;
}
+
+ if (features.codemirrorNext) {
+ return null;
+ }
+
return div(
null,
breakpoints.map(breakpoint => {
diff --git a/devtools/client/debugger/src/components/Editor/DebugLine.js b/devtools/client/debugger/src/components/Editor/DebugLine.js
index 1b8e59ba64..61caae69a5 100644
--- a/devtools/client/debugger/src/components/Editor/DebugLine.js
+++ b/devtools/client/debugger/src/components/Editor/DebugLine.js
@@ -6,6 +6,7 @@ import { PureComponent } from "devtools/client/shared/vendor/react";
import PropTypes from "devtools/client/shared/vendor/react-prop-types";
import {
toEditorPosition,
+ fromEditorLine,
getDocument,
hasDocument,
startOperation,
@@ -21,12 +22,16 @@ import {
getSourceTextContent,
getCurrentThread,
} from "../../selectors/index";
+import { isWasm } from "../../utils/wasm";
+import { features } from "../../utils/prefs";
export class DebugLine extends PureComponent {
debugExpression;
static get propTypes() {
return {
+ editor: PropTypes.object,
+ selectedSource: PropTypes.object,
location: PropTypes.object,
why: PropTypes.object,
};
@@ -34,21 +39,62 @@ export class DebugLine extends PureComponent {
componentDidMount() {
const { why, location } = this.props;
+ if (features.codemirrorNext) {
+ return;
+ }
this.setDebugLine(why, location);
}
componentWillUnmount() {
const { why, location } = this.props;
+ if (features.codemirrorNext) {
+ return;
+ }
this.clearDebugLine(why, location);
}
componentDidUpdate(prevProps) {
- const { why, location } = this.props;
-
- startOperation();
- this.clearDebugLine(prevProps.why, prevProps.location);
- this.setDebugLine(why, location);
- endOperation();
+ const { why, location, editor, selectedSource } = this.props;
+
+ if (features.codemirrorNext) {
+ if (!selectedSource) {
+ return;
+ }
+
+ if (
+ prevProps.location == this.props.location &&
+ prevProps.selectedSource?.id == selectedSource?.id
+ ) {
+ return;
+ }
+
+ const { lineClass } = this.getTextClasses(why);
+ // Remove the debug line marker when no longer paused, or the selected source
+ // is no longer the source where the pause occured.
+ if (!location || location.source.id !== selectedSource.id) {
+ editor.removeLineContentMarker("debug-line-marker");
+ } else {
+ const isSourceWasm = isWasm(selectedSource.id);
+ editor.setLineContentMarker({
+ id: "debug-line-marker",
+ lineClassName: lineClass,
+ condition(line) {
+ const lineNumber = fromEditorLine(
+ selectedSource.id,
+ line,
+ isSourceWasm
+ );
+ const editorLocation = toEditorPosition(location);
+ return editorLocation.line == lineNumber;
+ },
+ });
+ }
+ } else {
+ startOperation();
+ this.clearDebugLine(prevProps.why, prevProps.location);
+ this.setDebugLine(why, location);
+ endOperation();
+ }
}
setDebugLine(why, location) {
@@ -125,7 +171,10 @@ const mapStateToProps = state => {
return {};
}
const sourceTextContent = getSourceTextContent(state, location);
- if (!isDocumentReady(location, sourceTextContent)) {
+ if (
+ !features.codemirrorNext &&
+ !isDocumentReady(location, sourceTextContent)
+ ) {
return {};
}
return {
diff --git a/devtools/client/debugger/src/components/Editor/Editor.css b/devtools/client/debugger/src/components/Editor/Editor.css
index 0c48da019e..f28833747d 100644
--- a/devtools/client/debugger/src/components/Editor/Editor.css
+++ b/devtools/client/debugger/src/components/Editor/Editor.css
@@ -80,19 +80,6 @@ html[dir="rtl"] .editor-mount {
line-height: var(--theme-code-line-height);
}
-/* set the linenumber white when there is a breakpoint */
-.editor-wrapper:not(.skip-pausing)
- .new-breakpoint
- .CodeMirror-gutter-wrapper
- .CodeMirror-linenumber {
- color: white;
-}
-
-/* move the breakpoint below the other gutter elements */
-.new-breakpoint .CodeMirror-gutter-elt:nth-child(2) {
- z-index: 0;
-}
-
.theme-dark .editor-wrapper .CodeMirror-line .cm-comment {
color: var(--theme-comment);
}
@@ -134,7 +121,9 @@ html[dir="rtl"] .editor-mount {
background-color: var(--debug-expression-error-background);
}
-.new-debug-line > .CodeMirror-line {
+.new-debug-line > .CodeMirror-line,
+/* For CM6 */
+.cm-editor .cm-line.new-debug-line {
background-color: transparent !important;
outline: var(--debug-line-border) solid 1px;
}
@@ -145,7 +134,9 @@ html[dir="rtl"] .editor-mount {
display: none;
}
-.new-debug-line-error > .CodeMirror-line {
+.new-debug-line-error > .CodeMirror-line,
+/* For CM6 */
+.cm-editor .cm-line.new-debug-line-error {
background-color: var(--debug-expression-error-background) !important;
outline: var(--debug-line-error-border) solid 1px;
}
@@ -196,10 +187,6 @@ html[dir="rtl"] .editor-mount {
border-left: none;
}
-.editor-wrapper .CodeMirror-foldgutter .CodeMirror-guttermarker-subtle {
- visibility: visible;
-}
-
.editor-wrapper .CodeMirror-foldgutter .CodeMirror-linenumber {
text-align: left;
padding: 0 0 0 2px;
diff --git a/devtools/client/debugger/src/components/Editor/Exceptions.js b/devtools/client/debugger/src/components/Editor/Exceptions.js
index 2fb183f135..217ec40be6 100644
--- a/devtools/client/debugger/src/components/Editor/Exceptions.js
+++ b/devtools/client/debugger/src/components/Editor/Exceptions.js
@@ -6,25 +6,72 @@ import React, { Component } from "devtools/client/shared/vendor/react";
import PropTypes from "devtools/client/shared/vendor/react-prop-types";
import { connect } from "devtools/client/shared/vendor/react-redux";
+import {
+ toEditorPosition,
+ fromEditorLine,
+ getDocument,
+} from "../../utils/editor/index";
+import { createLocation } from "../../utils/location";
+
+import { features } from "../../utils/prefs";
+
import Exception from "./Exception";
import {
getSelectedSource,
getSelectedSourceExceptions,
} from "../../selectors/index";
-import { getDocument } from "../../utils/editor/index";
class Exceptions extends Component {
static get propTypes() {
return {
exceptions: PropTypes.array,
selectedSource: PropTypes.object,
+ editor: PropTypes.object,
};
}
+ componentDidUpdate() {
+ const { exceptions, selectedSource, editor } = this.props;
+
+ if (!features.codemirrorNext) {
+ return;
+ }
+
+ if (!selectedSource || !editor || !exceptions.length) {
+ return;
+ }
+
+ editor.setLineContentMarker({
+ id: "line-exception-marker",
+ lineClassName: "line-exception",
+ condition: line => {
+ const lineNumber = fromEditorLine(selectedSource.id, line);
+
+ const exception = exceptions.find(e => e.lineNumber == lineNumber);
+ if (!exception) {
+ return false;
+ }
+ const exceptionLocation = createLocation({
+ source: selectedSource,
+ line: exception.lineNumber,
+ // Exceptions are reported with column being 1-based
+ // while the frontend uses 0-based column.
+ column: exception.columnNumber - 1,
+ });
+ const editorLocation = toEditorPosition(exceptionLocation);
+ return editorLocation.line == lineNumber;
+ },
+ });
+ }
+
render() {
const { exceptions, selectedSource } = this.props;
+ if (features.codemirrorNext) {
+ return null;
+ }
+
if (!selectedSource || !exceptions.length) {
return null;
}
diff --git a/devtools/client/debugger/src/components/Editor/index.js b/devtools/client/debugger/src/components/Editor/index.js
index ae9bde7657..e21e05c11a 100644
--- a/devtools/client/debugger/src/components/Editor/index.js
+++ b/devtools/client/debugger/src/components/Editor/index.js
@@ -12,6 +12,7 @@ import { connect } from "devtools/client/shared/vendor/react-redux";
import { getLineText, isLineBlackboxed } from "./../../utils/source";
import { createLocation } from "./../../utils/location";
import { getIndentation } from "../../utils/indentation";
+import { isWasm } from "../../utils/wasm";
import { features } from "../../utils/prefs";
import {
@@ -50,6 +51,7 @@ import Exceptions from "./Exceptions";
import BlackboxLines from "./BlackboxLines";
import {
+ fromEditorLine,
showSourceText,
setDocument,
resetLineNumberFormat,
@@ -68,7 +70,11 @@ import {
endOperation,
} from "../../utils/editor/index";
-import { resizeToggleButton, resizeBreakpointGutter } from "../../utils/ui";
+import {
+ resizeToggleButton,
+ getLineNumberWidth,
+ resizeBreakpointGutter,
+} from "../../utils/ui";
const { debounce } = require("resource://devtools/shared/debounce.js");
const classnames = require("resource://devtools/client/shared/classnames.js");
@@ -169,7 +175,7 @@ class Editor extends PureComponent {
if (this.props.selectedSource != nextProps.selectedSource) {
this.props.updateViewport();
resizeBreakpointGutter(editor.codeMirror);
- resizeToggleButton(editor.codeMirror);
+ resizeToggleButton(getLineNumberWidth(editor.codeMirror));
}
} else {
// For codemirror 6
@@ -180,6 +186,12 @@ class Editor extends PureComponent {
}
}
+ onEditorUpdated(v) {
+ if (v.docChanged || v.geometryChanged) {
+ resizeToggleButton(v.view.dom.querySelector(".cm-gutters").clientWidth);
+ }
+ }
+
setupEditor() {
const editor = getEditor(features.codemirrorNext);
@@ -216,32 +228,18 @@ class Editor extends PureComponent {
codeMirrorWrapper.addEventListener("keydown", e => this.onKeyDown(e));
codeMirrorWrapper.addEventListener("click", e => this.onClick(e));
codeMirrorWrapper.addEventListener("mouseover", onMouseOver(codeMirror));
-
- const toggleFoldMarkerVisibility = () => {
- if (node instanceof HTMLElement) {
- node
- .querySelectorAll(".CodeMirror-guttermarker-subtle")
- .forEach(elem => {
- elem.classList.toggle("visible");
- });
- }
- };
-
- const codeMirrorGutter = codeMirror.getGutterElement();
- codeMirrorGutter.addEventListener(
- "mouseleave",
- toggleFoldMarkerVisibility
- );
- codeMirrorGutter.addEventListener(
- "mouseenter",
- toggleFoldMarkerVisibility
- );
codeMirrorWrapper.addEventListener("contextmenu", event =>
this.openMenu(event)
);
codeMirror.on("scroll", this.onEditorScroll);
this.onEditorScroll();
+ } else {
+ editor.setUpdateListener(this.onEditorUpdated);
+ editor.setGutterEventListeners({
+ click: (event, cm, line) => this.onGutterClick(cm, line, null, event),
+ contextmenu: (event, cm, line) => this.openMenu(event, line, true),
+ });
}
this.setState({ editor });
return editor;
@@ -280,6 +278,69 @@ class Editor extends PureComponent {
}
};
+ componentDidUpdate(prevProps) {
+ const {
+ selectedSource,
+ blackboxedRanges,
+ isSourceOnIgnoreList,
+ breakableLines,
+ } = this.props;
+ const { editor } = this.state;
+
+ if (!selectedSource || !editor) {
+ return;
+ }
+
+ // Sets the breakables lines for codemirror 6
+ if (features.codemirrorNext) {
+ const shouldUpdateBreakableLines =
+ prevProps.breakableLines.size !== this.props.breakableLines.size ||
+ prevProps.selectedSource?.id !== selectedSource.id;
+
+ const isSourceWasm = isWasm(selectedSource.id);
+
+ if (shouldUpdateBreakableLines) {
+ editor.setLineGutterMarkers([
+ {
+ id: "empty-line-marker",
+ lineClassName: "empty-line",
+ condition: line => {
+ const lineNumber = fromEditorLine(
+ selectedSource.id,
+ line,
+ isSourceWasm
+ );
+ return !breakableLines.has(lineNumber);
+ },
+ },
+ ]);
+ }
+
+ function condition(line) {
+ const lineNumber = fromEditorLine(selectedSource.id, line);
+
+ return isLineBlackboxed(
+ blackboxedRanges[selectedSource.url],
+ lineNumber,
+ isSourceOnIgnoreList
+ );
+ }
+
+ editor.setLineGutterMarkers([
+ {
+ id: "blackboxed-line-gutter-marker",
+ lineClassName: "blackboxed-line",
+ condition,
+ },
+ ]);
+ editor.setLineContentMarker({
+ id: "blackboxed-line-marker",
+ lineClassName: "blackboxed-line",
+ condition,
+ });
+ }
+ }
+
componentWillUnmount() {
if (!features.codemirrorNext) {
const { editor } = this.state;
@@ -396,8 +457,9 @@ class Editor extends PureComponent {
e.preventDefault();
}
};
-
- openMenu(event) {
+ // Note: The line is optional, if not passed (as is likely for codemirror 6)
+ // it fallsback to lineAtHeight.
+ openMenu(event, line) {
event.stopPropagation();
event.preventDefault();
@@ -421,13 +483,19 @@ class Editor extends PureComponent {
const target = event.target;
const { id: sourceId } = selectedSource;
- const line = lineAtHeight(editor, sourceId, event);
+ line = line ?? lineAtHeight(editor, sourceId, event);
if (typeof line != "number") {
return;
}
- if (target.classList.contains("CodeMirror-linenumber")) {
+ if (
+ // handles codemirror 6
+ (target.classList.contains("cm-gutterElement") &&
+ target.closest(".cm-gutter.cm-lineNumbers")) ||
+ // handles codemirror 5
+ target.classList.contains("CodeMirror-linenumber")
+ ) {
const location = createLocation({
line,
column: undefined,
@@ -440,7 +508,14 @@ class Editor extends PureComponent {
line
).trim();
- this.props.showEditorGutterContextMenu(event, editor, location, lineText);
+ const lineObject = { from: { line }, to: { line } };
+
+ this.props.showEditorGutterContextMenu(
+ event,
+ lineObject,
+ location,
+ lineText
+ );
return;
}
@@ -542,10 +617,6 @@ class Editor extends PureComponent {
);
};
- onGutterContextMenu = event => {
- this.openMenu(event);
- };
-
onClick(e) {
const { selectedSource, updateCursorPosition, jumpToMappedLocation } =
this.props;
@@ -717,6 +788,18 @@ class Editor extends PureComponent {
} = this.props;
const { editor } = this.state;
+ if (features.codemirrorNext) {
+ return React.createElement(
+ React.Fragment,
+ null,
+ React.createElement(Breakpoints, {
+ editor,
+ }),
+ React.createElement(DebugLine, { editor, selectedSource }),
+ React.createElement(Exceptions, { editor })
+ );
+ }
+
if (!selectedSource || !editor || !getDocument(selectedSource.id)) {
return null;
}
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/index.js b/devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/index.js
index 1f5e08cd7e..767df21bf6 100644
--- a/devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/index.js
+++ b/devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/index.js
@@ -17,7 +17,6 @@ import { getSelectedLocation } from "../../../utils/selected-location";
import { createHeadlessEditor } from "../../../utils/editor/create-editor";
import { makeBreakpointId } from "../../../utils/breakpoint/index";
-import { features } from "../../../utils/prefs";
import {
getSelectedSource,
@@ -154,7 +153,7 @@ class Breakpoints extends Component {
className: "pane",
},
this.renderExceptionsOptions(),
- !features.codemirrorNext ? this.renderBreakpoints() : null
+ this.renderBreakpoints()
);
}
}
diff --git a/devtools/client/debugger/src/components/shared/Button/styles/CommandBarButton.css b/devtools/client/debugger/src/components/shared/Button/styles/CommandBarButton.css
index 12e53e6fc5..a04f080291 100644
--- a/devtools/client/debugger/src/components/shared/Button/styles/CommandBarButton.css
+++ b/devtools/client/debugger/src/components/shared/Button/styles/CommandBarButton.css
@@ -14,6 +14,7 @@
min-width: 30px;
/* Adjust outline so it's not clipped */
outline-offset: -3px;
+ flex-shrink: 0;
}
.command-bar-button:disabled {
diff --git a/devtools/client/debugger/src/utils/editor/index.js b/devtools/client/debugger/src/utils/editor/index.js
index d12e2f29f1..e729388acf 100644
--- a/devtools/client/debugger/src/utils/editor/index.js
+++ b/devtools/client/debugger/src/utils/editor/index.js
@@ -11,6 +11,7 @@ import { createEditor } from "./create-editor";
import { isWasm, lineToWasmOffset, wasmOffsetToLine } from "../wasm";
import { createLocation } from "../location";
+import { features } from "../prefs";
let editor;
@@ -65,6 +66,10 @@ export function toEditorLine(sourceId, lineOrOffset) {
return wasmOffsetToLine(sourceId, lineOrOffset) || 0;
}
+ if (features.codemirrorNext) {
+ return lineOrOffset;
+ }
+
return lineOrOffset ? lineOrOffset - 1 : 1;
}
@@ -73,6 +78,10 @@ export function fromEditorLine(sourceId, line, sourceIsWasm) {
return lineToWasmOffset(sourceId, line) || 0;
}
+ if (features.codemirrorNext) {
+ return line;
+ }
+
return line + 1;
}
@@ -88,7 +97,13 @@ export function toEditorPosition(location) {
}
export function toSourceLine(sourceId, line) {
- return isWasm(sourceId) ? lineToWasmOffset(sourceId, line) : line + 1;
+ if (isWasm(sourceId)) {
+ return lineToWasmOffset(sourceId, line);
+ }
+ if (features.codemirrorNext) {
+ return line;
+ }
+ return line + 1;
}
export function scrollToPosition(codeMirror, line, column) {
diff --git a/devtools/client/debugger/src/utils/editor/source-documents.js b/devtools/client/debugger/src/utils/editor/source-documents.js
index 53ee4f2f35..cc9f44d82a 100644
--- a/devtools/client/debugger/src/utils/editor/source-documents.js
+++ b/devtools/client/debugger/src/utils/editor/source-documents.js
@@ -4,7 +4,11 @@
import { isWasm, getWasmLineNumberFormatter, renderWasmText } from "../wasm";
import { isMinified } from "../isMinified";
-import { resizeBreakpointGutter, resizeToggleButton } from "../ui";
+import {
+ resizeBreakpointGutter,
+ resizeToggleButton,
+ getLineNumberWidth,
+} from "../ui";
import { javascriptLikeExtensions } from "../source";
const sourceDocs = new Map();
@@ -39,7 +43,7 @@ export function resetLineNumberFormat(editor) {
const cm = editor.codeMirror;
cm.setOption("lineNumberFormatter", number => number);
resizeBreakpointGutter(cm);
- resizeToggleButton(cm);
+ resizeToggleButton(getLineNumberWidth(cm));
}
function updateLineNumberFormat(editor, sourceId) {
@@ -51,7 +55,7 @@ function updateLineNumberFormat(editor, sourceId) {
const lineNumberFormatter = getWasmLineNumberFormatter(sourceId);
cm.setOption("lineNumberFormatter", lineNumberFormatter);
resizeBreakpointGutter(cm);
- resizeToggleButton(cm);
+ resizeToggleButton(getLineNumberWidth(cm));
}
const contentTypeModeMap = new Map([
diff --git a/devtools/client/debugger/src/utils/editor/tokens.js b/devtools/client/debugger/src/utils/editor/tokens.js
index f8783c02fe..3c6875f9cd 100644
--- a/devtools/client/debugger/src/utils/editor/tokens.js
+++ b/devtools/client/debugger/src/utils/editor/tokens.js
@@ -50,6 +50,8 @@ function _isInvalidTarget(target) {
target.closest(".CodeMirror-widget") ||
// exclude in-line "empty" space, as well as the gutter
target.matches(".CodeMirror-line, .CodeMirror-gutter-elt") ||
+ // exclude items that are not in a line
+ !target.closest(".CodeMirror-line") ||
target.getBoundingClientRect().top == 0
) {
return true;
diff --git a/devtools/client/debugger/src/utils/ui.js b/devtools/client/debugger/src/utils/ui.js
index eab5bb1e07..3ad221f465 100644
--- a/devtools/client/debugger/src/utils/ui.js
+++ b/devtools/client/debugger/src/utils/ui.js
@@ -38,11 +38,11 @@ export function resizeBreakpointGutter(editor) {
* Forces the left toggle button in source header to be the same size
* as the line numbers gutter.
*/
-export function resizeToggleButton(editor) {
+export function resizeToggleButton(newSize) {
const toggleButton = document.querySelector(
- ".source-header .toggle-button-start"
+ ".source-header .toggle-button.start"
);
if (toggleButton) {
- toggleButton.style.width = `${getLineNumberWidth(editor)}px`;
+ toggleButton.style.width = `${newSize}px`;
}
}
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-popup.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-popup.js
index eba02919d3..8a7ac18df4 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-popup.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-popup.js
@@ -70,8 +70,7 @@ add_task(async function testPausedByBreakpoint() {
info("Open the popup in order to be able to set a breakpoint");
const firstPopupBrowsingContext = await openPopup(POPUP_URL);
- await waitForSource(dbg, POPUP_URL);
- const source = findSource(dbg, POPUP_URL);
+ let source = await waitForSource(dbg, POPUP_URL);
await selectSource(dbg, source);
await addBreakpoint(dbg, source, 4);
@@ -88,7 +87,7 @@ add_task(async function testPausedByBreakpoint() {
"The popup is really paused"
);
- await waitForSource(dbg, POPUP_URL);
+ source = await waitForSource(dbg, POPUP_URL);
assertPausedAtSourceAndLine(dbg, source.id, 4);
await resume(dbg);
@@ -131,8 +130,7 @@ add_task(async function testPausedInTwoPopups() {
const browser = gBrowser.selectedBrowser;
const popupBrowsingContext = await openPopup(POPUP_URL);
- await waitForSource(dbg, POPUP_URL);
- const source = findSource(dbg, POPUP_URL);
+ const source = await waitForSource(dbg, POPUP_URL);
await selectSource(dbg, source);
await addBreakpoint(dbg, source, 4);
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-call-stack.js b/devtools/client/debugger/test/mochitest/browser_dbg-call-stack.js
index d461918d7a..4d8720d395 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-call-stack.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-call-stack.js
@@ -19,6 +19,8 @@ add_task(async function () {
const button = toggleButton(dbg);
ok(!button, "toggle button shouldn't be there");
+
+ await resume(dbg);
});
add_task(async function () {
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-console-async.js b/devtools/client/debugger/test/mochitest/browser_dbg-console-async.js
index 4c669766b0..caa122eb24 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-console-async.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-console-async.js
@@ -9,7 +9,7 @@
"use strict";
add_task(async function () {
- Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true);
+ Services.prefs.setBoolPref("devtools.toolbox.splitconsole.open", true);
Services.prefs.setBoolPref(
"devtools.debugger.features.map-await-expression",
true
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-console-map-bindings.js b/devtools/client/debugger/test/mochitest/browser_dbg-console-map-bindings.js
index 26529a75cd..085b048fb6 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-console-map-bindings.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-console-map-bindings.js
@@ -5,7 +5,7 @@
"use strict";
add_task(async function () {
- Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true);
+ Services.prefs.setBoolPref("devtools.toolbox.splitconsole.open", true);
const dbg = await initDebugger("doc-strict.html");
await getSplitConsole(dbg);
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-console.js b/devtools/client/debugger/test/mochitest/browser_dbg-console.js
index a725f7de43..73a5780cc6 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-console.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-console.js
@@ -5,7 +5,7 @@
"use strict";
add_task(async function () {
- Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true);
+ Services.prefs.setBoolPref("devtools.toolbox.splitconsole.open", true);
const dbg = await initDebugger(
"doc-script-switching.html",
"script-switching-01.js"
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-dom-mutation-breakpoints.js b/devtools/client/debugger/test/mochitest/browser_dbg-dom-mutation-breakpoints.js
index e26ca0493b..de10014069 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-dom-mutation-breakpoints.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-dom-mutation-breakpoints.js
@@ -146,9 +146,7 @@ add_task(async function () {
await resume(dbg);
info("Blackboxing the source prevents debugger pause");
- await waitForSource(dbg, "dom-mutation.original.js");
-
- const source = findSource(dbg, "dom-mutation.original.js");
+ const source = await waitForSource(dbg, "dom-mutation.original.js");
await selectSource(dbg, source);
await clickElement(dbg, "blackbox");
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-es-module-worker.js b/devtools/client/debugger/test/mochitest/browser_dbg-es-module-worker.js
index 93123187e1..f9b299991f 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-es-module-worker.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-es-module-worker.js
@@ -40,7 +40,7 @@ add_task(async function () {
is(threads.length, 1, "Got the page and the worker threads");
is(threads[0].name, WORKER_URL, "Thread name is correct");
- const source = findSource(dbg, "worker.js");
+ const source = await waitForSource(dbg, "worker.js");
await selectSource(dbg, source);
await addBreakpoint(dbg, source, 3);
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-log-events.js b/devtools/client/debugger/test/mochitest/browser_dbg-log-events.js
index 6ce0acbc77..e857a38654 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-log-events.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-log-events.js
@@ -9,7 +9,7 @@
"use strict";
add_task(async function () {
- Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true);
+ Services.prefs.setBoolPref("devtools.toolbox.splitconsole.open", true);
const dbg = await initDebugger(
"doc-event-breakpoints.html",
"event-breakpoints.js"
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-log-point-mapping.js b/devtools/client/debugger/test/mochitest/browser_dbg-log-point-mapping.js
index 67886672b6..521e59b270 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-log-point-mapping.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-log-point-mapping.js
@@ -9,7 +9,7 @@
"use strict";
add_task(async function () {
- Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true);
+ Services.prefs.setBoolPref("devtools.toolbox.splitconsole.open", true);
await pushPref("devtools.debugger.map-scopes-enabled", true);
const dbg = await initDebugger("doc-sourcemaps3.html", "test.js");
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-log-points-workers.js b/devtools/client/debugger/test/mochitest/browser_dbg-log-points-workers.js
index aa52904d31..3475d3f41d 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-log-points-workers.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-log-points-workers.js
@@ -9,7 +9,7 @@
"use strict";
add_task(async function () {
- Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true);
+ Services.prefs.setBoolPref("devtools.toolbox.splitconsole.open", true);
const dbg = await initDebugger("doc-windowless-workers.html");
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-log-points.js b/devtools/client/debugger/test/mochitest/browser_dbg-log-points.js
index d265caa0ad..ea3fecf1ec 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-log-points.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-log-points.js
@@ -9,7 +9,7 @@
"use strict";
add_task(async function () {
- Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true);
+ Services.prefs.setBoolPref("devtools.toolbox.splitconsole.open", true);
const dbg = await initDebugger(
"doc-script-switching.html",
"script-switching-01.js"
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-paused-anonymous.js b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-paused-anonymous.js
index 8d3771cae9..223f401c73 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-paused-anonymous.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-paused-anonymous.js
@@ -22,8 +22,7 @@ add_task(async function () {
const prettyEvaluatedSourceFilename =
evaluatedSourceId.split("/").at(-1) + ":formatted";
- await waitForSource(dbg, prettyEvaluatedSourceFilename);
- const prettySource = findSource(dbg, prettyEvaluatedSourceFilename);
+ const prettySource = await waitForSource(dbg, prettyEvaluatedSourceFilename);
info("Check that the script was pretty-printed as expected");
const { value: prettySourceValue } = findSourceContent(dbg, prettySource);
@@ -67,8 +66,7 @@ document.addEventListener('click', e => {
const prettyEvalSourceFilename =
evalSourceId.split("/").at(-1) + ":formatted";
- await waitForSource(dbg, prettyEvalSourceFilename);
- const prettyEvalSource = findSource(dbg, prettyEvalSourceFilename);
+ const prettyEvalSource = await waitForSource(dbg, prettyEvalSourceFilename);
info("Check that the script was pretty-printed as expected");
const { value: prettyEvalSourceValue } = findSourceContent(
@@ -113,8 +111,7 @@ setTimeout(
const prettyNewFunctionSourceFilename =
newFunctionSourceId.split("/").at(-1) + ":formatted";
- await waitForSource(dbg, prettyNewFunctionSourceFilename);
- const prettyNewFunctionSource = findSource(
+ const prettyNewFunctionSource = await waitForSource(
dbg,
prettyNewFunctionSourceFilename
);
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-preview.js b/devtools/client/debugger/test/mochitest/browser_dbg-preview.js
index 532854548c..b7bb67c7d8 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-preview.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-preview.js
@@ -158,6 +158,46 @@ async function testHoveringInvalidTargetTokens(dbg) {
is(raceResult, "TIMEOUT", "No popup was displayed over the inline preview");
await resume(dbg);
+
+ info("Test hovering element not in a line");
+ await getDebuggerSplitConsole(dbg);
+ const { hud } = dbg.toolbox.getPanel("webconsole");
+ evaluateExpressionInConsole(
+ hud,
+ `
+ a = 1;
+ debugger;
+ b = 2;`
+ );
+ await waitForPaused(dbg);
+ await dbg.toolbox.toggleSplitConsole();
+
+ resetCursorPositionToTopLeftCorner(dbg);
+
+ const racePromiseLines = Promise.any([
+ waitForElement(dbg, "previewPopup"),
+ wait(500).then(() => "TIMEOUT_LINES"),
+ ]);
+ // We don't want to use hoverToken, as it synthesize the event at the center of the element,
+ // which wouldn't reproduce the original issue we want to check
+ EventUtils.synthesizeMouse(
+ findElementWithSelector(dbg, ".CodeMirror-lines"),
+ 0,
+ 0,
+ {
+ type: "mousemove",
+ },
+ dbg.win
+ );
+ is(
+ await racePromiseLines,
+ "TIMEOUT_LINES",
+ "No popup was displayed over the .CodeMirror-lines element"
+ );
+
+ // Resume and select back the main JS file that is used by the other assertions
+ await resume(dbg);
+ await selectSource(dbg, "preview.js");
}
async function assertNoPreviews(dbg, expression, line, column) {
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-source-pragma.js b/devtools/client/debugger/test/mochitest/browser_dbg-source-pragma.js
index edca4e2b80..82fbd911ac 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-source-pragma.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-source-pragma.js
@@ -13,8 +13,7 @@ add_task(async function () {
const dbg = await initDebugger("doc-source-pragma.html");
// The sourceURL pragma didn't rename the source
- await waitForSource(dbg, "source-pragma.js");
- const source = findSource(dbg, "source-pragma.js");
+ const source = await waitForSource(dbg, "source-pragma.js");
const actors = dbg.selectors.getSourceActorsForSource(source.id);
is(actors.length, 1, "have a single actor");
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-state-based-panels.js b/devtools/client/debugger/test/mochitest/browser_dbg-state-based-panels.js
index 0dc81605c9..2f07390c48 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-state-based-panels.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-state-based-panels.js
@@ -149,8 +149,9 @@ add_task(async function testBreakpointsPanePersistOnPauseToggle() {
is(getPaneElements(dbg).length, 1, "Breakpoint pane is closed");
info("Check event listener breakpoints log box");
-
+ const wait = waitForDispatch(dbg.store, "TOGGLE_EVENT_LISTENERS");
await clickElement(dbg, "logEventsCheckbox");
+ await wait;
is(getPaneElements(dbg).length, 1, "Breakpoint pane is still closed");
});
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-step-in-navigate.js b/devtools/client/debugger/test/mochitest/browser_dbg-step-in-navigate.js
index 53d66c6f12..85dff42104 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-step-in-navigate.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-step-in-navigate.js
@@ -24,11 +24,10 @@ add_task(async function () {
await addBreakpoint(dbg, "long.js", 1);
// Navigation should clear the stepping state
- const reloaded = reload(dbg);
+ const reloaded = reload(dbg, "simple2.js");
await waitForPaused(dbg);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "long.js").id, 1);
await resume(dbg);
await reloaded;
- await waitForSource(dbg, "simple3.js");
});
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-windowless-service-workers-reload.js b/devtools/client/debugger/test/mochitest/browser_dbg-windowless-service-workers-reload.js
index 1638cb9722..9256f91c2f 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-windowless-service-workers-reload.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-windowless-service-workers-reload.js
@@ -17,8 +17,7 @@ add_task(async function () {
const dbg = await initDebugger("doc-service-workers.html");
invokeInTab("registerWorker");
- await waitForSource(dbg, "service-worker.sjs");
- const workerSource = findSource(dbg, "service-worker.sjs");
+ const workerSource = await waitForSource(dbg, "service-worker.sjs");
await reload(dbg, "service-worker.sjs");
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-windowless-service-workers.js b/devtools/client/debugger/test/mochitest/browser_dbg-windowless-service-workers.js
index f2e20f4541..c89541871b 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-windowless-service-workers.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-windowless-service-workers.js
@@ -22,8 +22,7 @@ add_task(async function () {
);
invokeInTab("registerWorker");
- await waitForSource(dbg, "service-worker.sjs");
- const workerSource = findSource(dbg, "service-worker.sjs");
+ const workerSource = await waitForSource(dbg, "service-worker.sjs");
await addBreakpoint(dbg, "service-worker.sjs", 13);
@@ -52,8 +51,7 @@ add_task(async function () {
// The test page will immediately fetch from the service worker if registered.
const onReloaded = reload(dbg);
- await waitForSource(dbg, "service-worker.sjs");
- const workerSource = findSource(dbg, "service-worker.sjs");
+ const workerSource = await waitForSource(dbg, "service-worker.sjs");
await waitForPaused(dbg);
assertPausedAtSourceAndLine(dbg, workerSource.id, 13);
@@ -140,8 +138,7 @@ add_task(async function () {
invokeInTab("registerWorker");
await checkAdditionalThreadCount(dbg, 1);
- await waitForSource(dbg, "service-worker.sjs");
- const workerSource = findSource(dbg, "service-worker.sjs");
+ const workerSource = await waitForSource(dbg, "service-worker.sjs");
await waitForBreakpointCount(dbg, 1);
await waitForPaused(dbg);
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-windowless-workers.js b/devtools/client/debugger/test/mochitest/browser_dbg-windowless-workers.js
index ffe362b44f..49decefd1c 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-windowless-workers.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-windowless-workers.js
@@ -10,7 +10,10 @@
add_task(async function () {
await pushPref("devtools.debugger.threads-visible", true);
- const dbg = await initDebugger("doc-windowless-workers.html");
+ const dbg = await initDebugger(
+ "doc-windowless-workers.html",
+ "simple-worker.js"
+ );
const mainThread = dbg.toolbox.threadFront.actor;
await waitForThreadCount(dbg, 2);
@@ -21,8 +24,6 @@ add_task(async function () {
const mainThreadSource = findSource(dbg, "doc-windowless-workers.html");
- await waitForSource(dbg, "simple-worker.js");
-
info("Pause in the main thread");
assertNotPaused(dbg);
await dbg.actions.breakOnNext();
diff --git a/devtools/client/debugger/test/mochitest/shared-head.js b/devtools/client/debugger/test/mochitest/shared-head.js
index b2a1c7c3d7..fe3ab0171c 100644
--- a/devtools/client/debugger/test/mochitest/shared-head.js
+++ b/devtools/client/debugger/test/mochitest/shared-head.js
@@ -68,25 +68,27 @@ const DEBUGGER_L10N = new LocalizationHelper(
/**
* Waits for `predicate()` to be true. `state` is the redux app state.
*
- * @memberof mochitest/waits
* @param {Object} dbg
* @param {Function} predicate
+ * @param {String} msg
* @return {Promise}
- * @static
*/
-function waitForState(dbg, predicate, msg) {
+function waitForState(dbg, predicate, msg = "") {
return new Promise(resolve => {
- info(`Waiting for state change: ${msg || ""}`);
- if (predicate(dbg.store.getState())) {
- info(`Finished waiting for state change: ${msg || ""}`);
- resolve();
+ info(`Waiting for state change: ${msg}`);
+ let result = predicate(dbg.store.getState());
+ if (result) {
+ info(
+ `--> The state was immediately correct (should rather do an immediate assertion?)`
+ );
+ resolve(result);
return;
}
const unsubscribe = dbg.store.subscribe(() => {
- const result = predicate(dbg.store.getState());
+ result = predicate(dbg.store.getState());
if (result) {
- info(`Finished waiting for state change: ${msg || ""}`);
+ info(`Finished waiting for state change: ${msg}`);
unsubscribe();
resolve(result);
}
diff --git a/devtools/client/dom/main.js b/devtools/client/dom/main.js
index d7fbd5dc5f..b48d7e2739 100644
--- a/devtools/client/dom/main.js
+++ b/devtools/client/dom/main.js
@@ -6,8 +6,8 @@
const { XPCOMUtils } = ChromeUtils.importESModule(
"resource://gre/modules/XPCOMUtils.sys.mjs"
);
-const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
// Module Loader
diff --git a/devtools/client/framework/components/MeatballMenu.js b/devtools/client/framework/components/MeatballMenu.js
index fc694171c8..74d8592723 100644
--- a/devtools/client/framework/components/MeatballMenu.js
+++ b/devtools/client/framework/components/MeatballMenu.js
@@ -3,6 +3,8 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
+const SPLITCONSOLE_ENABLED_PREF = "devtools.toolbox.splitconsole.enabled";
+
const {
PureComponent,
createFactory,
@@ -180,19 +182,27 @@ class MeatballMenu extends PureComponent {
// Split console
if (this.props.currentToolId !== "webconsole") {
- const l10nID = this.props.isSplitConsoleActive
- ? "toolbox-meatball-menu-hideconsole-label"
- : "toolbox-meatball-menu-splitconsole-label";
- items.push(
- MenuItem({
- id: "toolbox-meatball-menu-splitconsole",
- key: "splitconsole",
- l10nID,
- accelerator: "Esc",
- onClick: this.props.toggleSplitConsole,
- className: "iconic",
- })
+ const isSplitConsoleEnabled = Services.prefs.getBoolPref(
+ SPLITCONSOLE_ENABLED_PREF,
+ true
);
+
+ if (isSplitConsoleEnabled) {
+ const l10nID = this.props.isSplitConsoleActive
+ ? "toolbox-meatball-menu-hideconsole-label"
+ : "toolbox-meatball-menu-splitconsole-label";
+
+ items.push(
+ MenuItem({
+ id: "toolbox-meatball-menu-splitconsole",
+ key: "splitconsole",
+ l10nID,
+ accelerator: "Esc",
+ onClick: this.props.toggleSplitConsole,
+ className: "iconic",
+ })
+ );
+ }
}
// Settings
diff --git a/devtools/client/framework/components/ToolboxToolbar.js b/devtools/client/framework/components/ToolboxToolbar.js
index f9998db0ab..bd9e3d5071 100644
--- a/devtools/client/framework/components/ToolboxToolbar.js
+++ b/devtools/client/framework/components/ToolboxToolbar.js
@@ -320,6 +320,10 @@ class ToolboxToolbar extends Component {
errorCount = "99+";
}
+ const errorIconTooltip = this.props.toolbox.isSplitConsoleEnabled()
+ ? this.props.L10N.getStr("toolbox.errorCountButton.tooltip")
+ : this.props.L10N.getStr("toolbox.errorCountButtonConsoleTab.tooltip");
+
return button(
{
id,
@@ -330,9 +334,7 @@ class ToolboxToolbar extends Component {
}
},
title:
- this.props.currentToolId !== "webconsole"
- ? this.props.L10N.getStr("toolbox.errorCountButton.tooltip")
- : null,
+ this.props.currentToolId !== "webconsole" ? errorIconTooltip : null,
},
errorCount
);
diff --git a/devtools/client/framework/test/browser_dynamic_tool_enabling.js b/devtools/client/framework/test/browser_dynamic_tool_enabling.js
index 56313607cf..0caf32b134 100644
--- a/devtools/client/framework/test/browser_dynamic_tool_enabling.js
+++ b/devtools/client/framework/test/browser_dynamic_tool_enabling.js
@@ -11,7 +11,7 @@ var gItemsToTest = {
};
function expectedAttributeValueFromPrefs(prefs) {
- return prefs.every(pref => Services.prefs.getBoolPref(pref)) ? "" : "true";
+ return prefs.every(pref => Services.prefs.getBoolPref(pref)) ? null : "true";
}
function checkItem(el, prefs) {
diff --git a/devtools/client/framework/test/browser_toolbox_error_count.js b/devtools/client/framework/test/browser_toolbox_error_count.js
index e4dcf0214f..858615f18b 100644
--- a/devtools/client/framework/test/browser_toolbox_error_count.js
+++ b/devtools/client/framework/test/browser_toolbox_error_count.js
@@ -22,8 +22,14 @@ const TEST_URI = `https://example.com/document-builder.sjs?html=<meta charset=ut
const { Toolbox } = require("resource://devtools/client/framework/toolbox.js");
add_task(async function () {
- // Make sure we start the test with the split console disabled.
- await pushPref("devtools.toolbox.splitconsoleEnabled", false);
+ // Make sure we start the test with the split console closed, and the split console setting enabled
+ await pushPref("devtools.toolbox.splitconsole.open", false);
+ await pushPref("devtools.toolbox.splitconsole.enabled", true);
+
+ registerCleanupFunction(() => {
+ Services.prefs.clearUserPref("devtools.toolbox.splitconsole.enabled");
+ });
+
const tab = await addTab(TEST_URI);
const toolbox = await openToolboxForTab(
@@ -175,6 +181,28 @@ add_task(async function () {
"The error is displayed again, with the correct error count, after enabling it from the settings panel"
);
+ info("Disable the split console from the options panel");
+ const splitConsoleButtonToggleEl =
+ optionsPanel.panelWin.document.querySelector(
+ "input#devtools-enable-split-console"
+ );
+ splitConsoleButtonToggleEl.click();
+ await waitFor(
+ () => getErrorIcon(toolbox).getAttribute("title") === "Show Console"
+ );
+ ok(
+ true,
+ "The error count icon title changed to reflect split console being disabled"
+ );
+
+ info(
+ "Check if with split console being disabled click leads to the console tab"
+ );
+ const onWebConsole = toolbox.once("webconsole-selected");
+ getErrorIcon(toolbox).click();
+ await onWebConsole;
+ ok(!toolbox.splitConsole, "Web Console opened instead of split console");
+
toolbox.destroy();
});
diff --git a/devtools/client/framework/test/browser_toolbox_error_count_reset_on_navigation.js b/devtools/client/framework/test/browser_toolbox_error_count_reset_on_navigation.js
index 53f5068655..ebf862be88 100644
--- a/devtools/client/framework/test/browser_toolbox_error_count_reset_on_navigation.js
+++ b/devtools/client/framework/test/browser_toolbox_error_count_reset_on_navigation.js
@@ -23,7 +23,7 @@ add_task(async function () {
// Make sure we start the test with the split console disabled.
// ⚠️ In this test it's important to _not_ enable the console.
- await pushPref("devtools.toolbox.splitconsoleEnabled", false);
+ await pushPref("devtools.toolbox.splitconsole.open", false);
const tab = await addTab(TEST_URI);
const toolbox = await openToolboxForTab(
diff --git a/devtools/client/framework/test/browser_toolbox_remoteness_change.js b/devtools/client/framework/test/browser_toolbox_remoteness_change.js
index af5f105214..ff019d1826 100644
--- a/devtools/client/framework/test/browser_toolbox_remoteness_change.js
+++ b/devtools/client/framework/test/browser_toolbox_remoteness_change.js
@@ -19,7 +19,7 @@ add_task(async function () {
);
is(
tab.linkedBrowser.getAttribute("remote"),
- "",
+ null,
"And running in parent process"
);
diff --git a/devtools/client/framework/test/browser_toolbox_screenshot_tool.js b/devtools/client/framework/test/browser_toolbox_screenshot_tool.js
index 63c8b9fd58..e87830a940 100644
--- a/devtools/client/framework/test/browser_toolbox_screenshot_tool.js
+++ b/devtools/client/framework/test/browser_toolbox_screenshot_tool.js
@@ -121,6 +121,6 @@ add_task(async function () {
await resetDownloads();
const closePromise = BrowserTestUtils.windowClosed(privateWindow);
- privateWindow.BrowserTryToCloseWindow();
+ privateWindow.BrowserCommands.tryToCloseWindow();
await closePromise;
});
diff --git a/devtools/client/framework/test/browser_toolbox_watchedByDevTools.js b/devtools/client/framework/test/browser_toolbox_watchedByDevTools.js
index a58b57885d..7365c43313 100644
--- a/devtools/client/framework/test/browser_toolbox_watchedByDevTools.js
+++ b/devtools/client/framework/test/browser_toolbox_watchedByDevTools.js
@@ -64,6 +64,11 @@ add_task(async function () {
info("Check that the flag is reset when the toolbox is closed");
await gDevTools.closeToolboxForTab(tab);
+
+ // As the destroy sequence of DevTools server is synchronous and we aren't waiting
+ // for full completion of server cleanups, we have to wait for its full processing.
+ await waitFor(() => !tab.linkedBrowser.browsingContext.watchedByDevTools);
+
is(
tab.linkedBrowser.browsingContext.watchedByDevTools,
false,
diff --git a/devtools/client/framework/toolbox-init.js b/devtools/client/framework/toolbox-init.js
index de2bce080a..130f94dc0e 100644
--- a/devtools/client/framework/toolbox-init.js
+++ b/devtools/client/framework/toolbox-init.js
@@ -40,8 +40,8 @@ const onLoad = new Promise(r => {
async function showErrorPage(doc, errorMessage) {
const win = doc.defaultView;
- const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+ const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
const browserRequire = BrowserLoader({
window: win,
diff --git a/devtools/client/framework/toolbox-options.html b/devtools/client/framework/toolbox-options.html
index 2ff33a581f..08c63265f0 100644
--- a/devtools/client/framework/toolbox-options.html
+++ b/devtools/client/framework/toolbox-options.html
@@ -126,6 +126,18 @@
</label>
</fieldset>
+ <fieldset id="webconsole-options" class="options-groupbox">
+ <legend data-l10n-id="options-webconsole-label"></legend>
+ <label data-l10n-id="options-webconsole-split-console-tooltip">
+ <input
+ type="checkbox"
+ id="devtools-enable-split-console"
+ data-pref="devtools.toolbox.splitconsole.enabled"
+ />
+ <span data-l10n-id="options-webconsole-split-console-label"></span>
+ </label>
+ </fieldset>
+
<fieldset id="styleeditor-options" class="options-groupbox">
<legend data-l10n-id="options-styleeditor-label"></legend>
<label data-l10n-id="options-stylesheet-autocompletion-tooltip">
diff --git a/devtools/client/framework/toolbox-options.js b/devtools/client/framework/toolbox-options.js
index 98b263ad44..809804e2f1 100644
--- a/devtools/client/framework/toolbox-options.js
+++ b/devtools/client/framework/toolbox-options.js
@@ -106,6 +106,10 @@ OptionsPanel.prototype = {
"devtools.source-map.client-service.enabled",
this._prefChanged
);
+ Services.prefs.addObserver(
+ "devtools.toolbox.splitconsole.enabled",
+ this._prefChanged
+ );
gDevTools.on("theme-registered", this._themeRegistered);
gDevTools.on("theme-unregistered", this._themeUnregistered);
@@ -126,6 +130,10 @@ OptionsPanel.prototype = {
"devtools.source-map.client-service.enabled",
this._prefChanged
);
+ Services.prefs.removeObserver(
+ "devtools.toolbox.splitconsole.enabled",
+ this._prefChanged
+ );
this.toolbox.off("tool-registered", this.setupToolsList);
this.toolbox.off("tool-unregistered", this.setupToolsList);
@@ -145,6 +153,8 @@ OptionsPanel.prototype = {
this.updateCurrentTheme();
} else if (prefName === "devtools.source-map.client-service.enabled") {
this.updateSourceMapPref();
+ } else if (prefName === "devtools.toolbox.splitconsole.enabled") {
+ this.toolbox.updateIsSplitConsoleEnabled();
}
},
diff --git a/devtools/client/framework/toolbox.js b/devtools/client/framework/toolbox.js
index a03360aa26..222f928ecf 100644
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -5,7 +5,8 @@
"use strict";
const MAX_ORDINAL = 99;
-const SPLITCONSOLE_ENABLED_PREF = "devtools.toolbox.splitconsoleEnabled";
+const SPLITCONSOLE_OPEN_PREF = "devtools.toolbox.splitconsole.open";
+const SPLITCONSOLE_ENABLED_PREF = "devtools.toolbox.splitconsole.enabled";
const SPLITCONSOLE_HEIGHT_PREF = "devtools.toolbox.splitconsoleHeight";
const DEVTOOLS_ALWAYS_ON_TOP = "devtools.toolbox.alwaysOnTop";
const DISABLE_AUTOHIDE_PREF = "ui.popup.disable_autohide";
@@ -41,8 +42,8 @@ var Startup = Cc["@mozilla.org/devtools/startup-clh;1"].getService(
Ci.nsISupports
).wrappedJSObject;
-const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
const {
@@ -608,6 +609,18 @@ Toolbox.prototype = {
);
},
+ /**
+ * Get the enabled split console setting, and if it's not set, set it with updateIsSplitConsoleEnabled
+ * @returns {boolean} devtools.toolbox.splitconsole.enabled option
+ */
+ isSplitConsoleEnabled() {
+ if (typeof this._splitConsoleEnabled !== "boolean") {
+ this.updateIsSplitConsoleEnabled();
+ }
+
+ return this._splitConsoleEnabled;
+ },
+
get isBrowserToolbox() {
return this.hostType === Toolbox.HostType.BROWSERTOOLBOX;
},
@@ -1038,7 +1051,7 @@ Toolbox.prototype = {
// Wait until the original tool is selected so that the split
// console input will receive focus.
let splitConsolePromise = Promise.resolve();
- if (Services.prefs.getBoolPref(SPLITCONSOLE_ENABLED_PREF)) {
+ if (Services.prefs.getBoolPref(SPLITCONSOLE_OPEN_PREF)) {
splitConsolePromise = this.openSplitConsole();
this.telemetry.addEventProperty(
this.topWindow,
@@ -1617,7 +1630,7 @@ Toolbox.prototype = {
},
_splitConsoleOnKeypress(e) {
- if (e.keyCode !== KeyCodes.DOM_VK_ESCAPE) {
+ if (e.keyCode !== KeyCodes.DOM_VK_ESCAPE || !this.isSplitConsoleEnabled()) {
return;
}
@@ -2351,6 +2364,21 @@ Toolbox.prototype = {
},
/**
+ * Setup the _splitConsoleEnabled, reflecting the enabled/disabled state of the Enable Split
+ * Console setting, and close the split console if it's open and the setting is turned off
+ */
+ updateIsSplitConsoleEnabled() {
+ this._splitConsoleEnabled = Services.prefs.getBoolPref(
+ SPLITCONSOLE_ENABLED_PREF,
+ true
+ );
+
+ if (!this._splitConsoleEnabled && this.splitConsole) {
+ this.closeSplitConsole();
+ }
+ },
+
+ /**
* Ensure the visibility of each toolbox button matches the preference value.
*/
_commandIsVisible(button) {
@@ -3013,8 +3041,15 @@ Toolbox.prototype = {
* loaded and focused.
*/
openSplitConsole({ focusConsoleInput = true } = {}) {
+ if (!this.isSplitConsoleEnabled()) {
+ return this.selectTool(
+ "webconsole",
+ "use_in_console_with_disabled_split_console"
+ );
+ }
+
this._splitConsole = true;
- Services.prefs.setBoolPref(SPLITCONSOLE_ENABLED_PREF, true);
+ Services.prefs.setBoolPref(SPLITCONSOLE_OPEN_PREF, true);
this._refreshConsoleDisplay();
// Ensure split console is visible if console was already loaded in background
@@ -3044,7 +3079,7 @@ Toolbox.prototype = {
*/
closeSplitConsole() {
this._splitConsole = false;
- Services.prefs.setBoolPref(SPLITCONSOLE_ENABLED_PREF, false);
+ Services.prefs.setBoolPref(SPLITCONSOLE_OPEN_PREF, false);
this._refreshConsoleDisplay();
this.component.setIsSplitConsoleActive(false);
diff --git a/devtools/client/fronts/targets/target-mixin.js b/devtools/client/fronts/targets/target-mixin.js
index 157e83e73a..bef1f5f975 100644
--- a/devtools/client/fronts/targets/target-mixin.js
+++ b/devtools/client/fronts/targets/target-mixin.js
@@ -10,12 +10,6 @@ loader.lazyRequireGetter(
"resource://devtools/shared/protocol.js",
true
);
-loader.lazyRequireGetter(
- this,
- "getThreadOptions",
- "resource://devtools/client/shared/thread-utils.js",
- true
-);
/**
* A Target represents a debuggable context. It can be a browser tab, a tab on
@@ -420,39 +414,16 @@ function TargetMixin(parentClass) {
return;
}
- const options = await getThreadOptions();
// If the target is destroyed or soon will be, don't go further
if (this.isDestroyedOrBeingDestroyed()) {
return;
}
- await this.attachThread(options);
- }
-
- async attachThread(options = {}) {
if (!this.targetForm || !this.targetForm.threadActor) {
throw new Error(
- "TargetMixin sub class should set targetForm.threadActor before calling " +
- "attachThread"
+ "TargetMixin sub class should set targetForm.threadActor before calling attachAndInitThread"
);
}
this.threadFront = await this.getFront("thread");
-
- // Avoid attaching if the thread actor was already attached on target creation from the server side.
- // This doesn't include:
- // * targets that aren't yet supported by the Watcher (like web extensions),
- // * workers, which still use a unique codepath for thread actor attach
- // * all targets when connecting to an older server
- // If all targets are supported by watcher actor, and workers no longer use
- // its unique attach sequence, we can assume the thread front is always attached.
- const isAttached = await this.threadFront.isAttached();
-
- const isDestroyed =
- this.isDestroyedOrBeingDestroyed() || this.threadFront.isDestroyed();
- if (!isAttached && !isDestroyed) {
- await this.threadFront.attach(options);
- }
-
- return this.threadFront;
}
isDestroyedOrBeingDestroyed() {
diff --git a/devtools/client/inspector/changes/test/browser_changes_nested_rules.js b/devtools/client/inspector/changes/test/browser_changes_nested_rules.js
index 789d88fdda..d6da1af72d 100644
--- a/devtools/client/inspector/changes/test/browser_changes_nested_rules.js
+++ b/devtools/client/inspector/changes/test/browser_changes_nested_rules.js
@@ -12,7 +12,7 @@
// --- @container myContainer (width > 10px) {
// ----- div {
// ------- & > span { … }
-// ------- .mySpan {
+// ------- & .mySpan {
// --------- &:not(:focus) {
const spanNotFocusedRule = `&:not(:focus) {
@@ -94,7 +94,7 @@ const EXPECTED_AFTER_SPAN_PROP_CHANGES = EXPECTED_AFTER_DIV_PROP_CHANGE.map(
})
).concat([
{
- text: ".mySpan {",
+ text: "& .mySpan {",
copyRuleClipboard:
applyModificationAfterSpanPropertiesChange(spanClassRule),
},
diff --git a/devtools/client/inspector/computed/test/browser_computed_search-filter_context-menu.js b/devtools/client/inspector/computed/test/browser_computed_search-filter_context-menu.js
index 0069d644c7..bea344e5f5 100644
--- a/devtools/client/inspector/computed/test/browser_computed_search-filter_context-menu.js
+++ b/devtools/client/inspector/computed/test/browser_computed_search-filter_context-menu.js
@@ -88,12 +88,12 @@ add_task(async function () {
cmdCopy = searchContextMenu.querySelector("#editmenu-copy");
cmdPaste = searchContextMenu.querySelector("#editmenu-paste");
- is(cmdUndo.getAttribute("disabled"), "", "cmdUndo is enabled");
- is(cmdDelete.getAttribute("disabled"), "", "cmdDelete is enabled");
- is(cmdSelectAll.getAttribute("disabled"), "", "cmdSelectAll is enabled");
- is(cmdCut.getAttribute("disabled"), "", "cmdCut is enabled");
- is(cmdCopy.getAttribute("disabled"), "", "cmdCopy is enabled");
- is(cmdPaste.getAttribute("disabled"), "", "cmdPaste is enabled");
+ is(cmdUndo.getAttribute("disabled"), null, "cmdUndo is enabled");
+ is(cmdDelete.getAttribute("disabled"), null, "cmdDelete is enabled");
+ is(cmdSelectAll.getAttribute("disabled"), null, "cmdSelectAll is enabled");
+ is(cmdCut.getAttribute("disabled"), null, "cmdCut is enabled");
+ is(cmdCopy.getAttribute("disabled"), null, "cmdCopy is enabled");
+ is(cmdPaste.getAttribute("disabled"), null, "cmdPaste is enabled");
onContextMenuClose = toolbox.once("menu-close");
searchContextMenu.hidePopup();
diff --git a/devtools/client/inspector/index.xhtml b/devtools/client/inspector/index.xhtml
index 75d0a792c3..4cdbea4bee 100644
--- a/devtools/client/inspector/index.xhtml
+++ b/devtools/client/inspector/index.xhtml
@@ -66,8 +66,8 @@
var { require, loader } = ChromeUtils.importESModule(
"resource://devtools/shared/loader/Loader.sys.mjs"
);
- var { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+ var { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
}
</script>
diff --git a/devtools/client/inspector/markup/test/browser_markup_screenshot_node_about_page.js b/devtools/client/inspector/markup/test/browser_markup_screenshot_node_about_page.js
index 4d8f4ff6a6..21dcf844b7 100644
--- a/devtools/client/inspector/markup/test/browser_markup_screenshot_node_about_page.js
+++ b/devtools/client/inspector/markup/test/browser_markup_screenshot_node_about_page.js
@@ -23,12 +23,12 @@ add_task(async function () {
info("Select the main content node");
await selectNode(".main-content", inspector);
- let inContentPageBackgroundColor = await getComputedStyleProperty(
+ let pageBackgroundColor = await getComputedStyleProperty(
":root",
null,
- "--in-content-page-background"
+ "background-color"
);
- inContentPageBackgroundColor = inContentPageBackgroundColor.trim();
+ pageBackgroundColor = pageBackgroundColor.trim();
info("Take a screenshot of the element and verify it looks as expected");
const image = await takeNodeScreenshot(inspector);
@@ -38,7 +38,7 @@ add_task(async function () {
image,
x: 0,
y: 0,
- expectedColor: hexToCSS(inContentPageBackgroundColor),
+ expectedColor: hexToCSS(pageBackgroundColor),
label: "The screenshot was taken",
});
diff --git a/devtools/client/inspector/rules/models/element-style.js b/devtools/client/inspector/rules/models/element-style.js
index e280a5e4a0..368a8ae953 100644
--- a/devtools/client/inspector/rules/models/element-style.js
+++ b/devtools/client/inspector/rules/models/element-style.js
@@ -57,7 +57,7 @@ class ElementStyle {
this.ruleView = ruleView;
this.store = store || {};
this.pageStyle = pageStyle;
- this.pseudoElements = [];
+ this.pseudoElementTypes = new Set();
this.showUserAgentStyles = showUserAgentStyles;
this.rules = [];
this.cssProperties = this.ruleView.cssProperties;
@@ -90,7 +90,7 @@ class ElementStyle {
}
this.destroyed = true;
- this.pseudoElements = [];
+ this.pseudoElementTypes.clear();
for (const rule of this.rules) {
if (rule.editor) {
@@ -141,9 +141,12 @@ class ElementStyle {
}
// Store a list of all pseudo-element types found in the matching rules.
- this.pseudoElements = this.rules
- .filter(r => r.pseudoElement)
- .map(r => r.pseudoElement);
+ this.pseudoElementTypes = new Set();
+ for (const rule of this.rules) {
+ if (rule.pseudoElement) {
+ this.pseudoElementTypes.add(rule.pseudoElement);
+ }
+ }
// Mark overridden computed styles.
this.onRuleUpdated();
@@ -275,7 +278,7 @@ class ElementStyle {
this.updateDeclarations();
// Update declarations for matching rules for pseudo-elements.
- for (const pseudo of this.pseudoElements) {
+ for (const pseudo of this.pseudoElementTypes) {
this.updateDeclarations(pseudo);
}
}
@@ -299,11 +302,6 @@ class ElementStyle {
updateDeclarations(pseudo = "") {
// Gather all text properties applicable to the selected element or pseudo-element.
const textProps = this._getDeclarations(pseudo);
- // Gather all the computed properties applied by those text properties.
- let computedProps = [];
- for (const textProp of textProps) {
- computedProps = computedProps.concat(textProp.computed);
- }
// CSS Variables inherits from the normal element in case of pseudo element.
const variables = new Map(pseudo ? this.variablesMap.get("") : null);
@@ -332,58 +330,62 @@ class ElementStyle {
// _overriddenDirty will be set on each prop, indicating whether its
// dirty status changed during this pass.
const taken = new Map();
- for (const computedProp of computedProps) {
- const earlier = taken.get(computedProp.name);
-
- // Prevent -webkit-gradient from being selected after unchecking
- // linear-gradient in this case:
- // -moz-linear-gradient: ...;
- // -webkit-linear-gradient: ...;
- // linear-gradient: ...;
- if (!computedProp.textProp.isValid()) {
- computedProp.overridden = true;
- continue;
- }
-
- let overridden;
- if (
- earlier &&
- computedProp.priority === "important" &&
- (earlier.priority !== "important" ||
- // Even if the earlier property was important, if the current rule is in a layer
- // it will take precedence, unless the earlier property rule was in the same layer.
- (computedProp.textProp.rule?.isInLayer() &&
- computedProp.textProp.rule.isInDifferentLayer(
- earlier.textProp.rule
- ))) &&
- // For !important only consider rules applying to the same parent node.
- computedProp.textProp.rule.inherited == earlier.textProp.rule.inherited
- ) {
- // New property is higher priority. Mark the earlier property
- // overridden (which will reverse its dirty state).
- earlier._overriddenDirty = !earlier._overriddenDirty;
- earlier.overridden = true;
- overridden = false;
- } else {
- overridden = !!earlier;
- }
-
- computedProp._overriddenDirty = !!computedProp.overridden !== overridden;
- computedProp.overridden = overridden;
-
- if (!computedProp.overridden && computedProp.textProp.enabled) {
- taken.set(computedProp.name, computedProp);
+ for (const textProp of textProps) {
+ for (const computedProp of textProp.computed) {
+ const earlier = taken.get(computedProp.name);
+
+ // Prevent -webkit-gradient from being selected after unchecking
+ // linear-gradient in this case:
+ // -moz-linear-gradient: ...;
+ // -webkit-linear-gradient: ...;
+ // linear-gradient: ...;
+ if (!computedProp.textProp.isValid()) {
+ computedProp.overridden = true;
+ continue;
+ }
- // At this point, we can get CSS variable from "inherited" rules.
- // When this is a registered custom property with `inherits` set to false,
- // the text prop is "invisible" (i.e. not shown in the rule view).
- // In such case, we don't want to get the value in the Map, and we'll rather
- // get the initial value from the registered property definition.
+ let overridden;
if (
- isCssVariable(computedProp.name) &&
- !computedProp.textProp.invisible
+ earlier &&
+ computedProp.priority === "important" &&
+ (earlier.priority !== "important" ||
+ // Even if the earlier property was important, if the current rule is in a layer
+ // it will take precedence, unless the earlier property rule was in the same layer.
+ (computedProp.textProp.rule?.isInLayer() &&
+ computedProp.textProp.rule.isInDifferentLayer(
+ earlier.textProp.rule
+ ))) &&
+ // For !important only consider rules applying to the same parent node.
+ computedProp.textProp.rule.inherited ==
+ earlier.textProp.rule.inherited
) {
- variables.set(computedProp.name, computedProp.value);
+ // New property is higher priority. Mark the earlier property
+ // overridden (which will reverse its dirty state).
+ earlier._overriddenDirty = !earlier._overriddenDirty;
+ earlier.overridden = true;
+ overridden = false;
+ } else {
+ overridden = !!earlier;
+ }
+
+ computedProp._overriddenDirty =
+ !!computedProp.overridden !== overridden;
+ computedProp.overridden = overridden;
+
+ if (!computedProp.overridden && computedProp.textProp.enabled) {
+ taken.set(computedProp.name, computedProp);
+
+ // At this point, we can get CSS variable from "inherited" rules.
+ // When this is a registered custom property with `inherits` set to false,
+ // the text prop is "invisible" (i.e. not shown in the rule view).
+ // In such case, we don't want to get the value in the Map, and we'll rather
+ // get the initial value from the registered property definition.
+ if (
+ isCssVariable(computedProp.name) &&
+ !computedProp.textProp.invisible
+ ) {
+ variables.set(computedProp.name, computedProp.value);
+ }
}
}
}
diff --git a/devtools/client/inspector/rules/test/browser_rules_content_01.js b/devtools/client/inspector/rules/test/browser_rules_content_01.js
index b92ec47db0..1985f07f5f 100644
--- a/devtools/client/inspector/rules/test/browser_rules_content_01.js
+++ b/devtools/client/inspector/rules/test/browser_rules_content_01.js
@@ -103,7 +103,7 @@ add_task(async function () {
matches: true,
},
{
- selector: ".unmatched",
+ selector: "& .unmatched",
matches: false,
},
]);
diff --git a/devtools/client/inspector/rules/test/browser_rules_nested_rules.js b/devtools/client/inspector/rules/test/browser_rules_nested_rules.js
index 925f36a0e6..0dc068232b 100644
--- a/devtools/client/inspector/rules/test/browser_rules_nested_rules.js
+++ b/devtools/client/inspector/rules/test/browser_rules_nested_rules.js
@@ -93,7 +93,7 @@ add_task(async function () {
checkRuleViewContent(view, [
{ selector: "element", ancestorRulesData: null, declarations: [] },
{
- selector: `.foo`,
+ selector: `& .foo`,
// prettier-ignore
ancestorRulesData: [
`body {`,
@@ -108,7 +108,7 @@ add_task(async function () {
checkRuleViewContent(view, [
{ selector: "element", ancestorRulesData: null, declarations: [] },
{
- selector: `#bar`,
+ selector: `& #bar`,
// prettier-ignore
ancestorRulesData: [
`body {`,
@@ -138,7 +138,7 @@ add_task(async function () {
checkRuleViewContent(view, [
{ selector: "element", ancestorRulesData: null, declarations: [] },
{
- selector: `[href]`,
+ selector: `& [href]`,
ancestorRulesData: [
`body {`,
` @media screen {`,
diff --git a/devtools/client/inspector/rules/test/browser_rules_search-filter_context-menu.js b/devtools/client/inspector/rules/test/browser_rules_search-filter_context-menu.js
index 881b5274ee..009c67cd70 100644
--- a/devtools/client/inspector/rules/test/browser_rules_search-filter_context-menu.js
+++ b/devtools/client/inspector/rules/test/browser_rules_search-filter_context-menu.js
@@ -86,12 +86,12 @@ add_task(async function () {
cmdCopy = searchContextMenu.querySelector("#editmenu-copy");
cmdPaste = searchContextMenu.querySelector("#editmenu-paste");
- is(cmdUndo.getAttribute("disabled"), "", "cmdUndo is enabled");
- is(cmdDelete.getAttribute("disabled"), "", "cmdDelete is enabled");
- is(cmdSelectAll.getAttribute("disabled"), "", "cmdSelectAll is enabled");
- is(cmdCut.getAttribute("disabled"), "", "cmdCut is enabled");
- is(cmdCopy.getAttribute("disabled"), "", "cmdCopy is enabled");
- is(cmdPaste.getAttribute("disabled"), "", "cmdPaste is enabled");
+ is(cmdUndo.getAttribute("disabled"), null, "cmdUndo is enabled");
+ is(cmdDelete.getAttribute("disabled"), null, "cmdDelete is enabled");
+ is(cmdSelectAll.getAttribute("disabled"), null, "cmdSelectAll is enabled");
+ is(cmdCut.getAttribute("disabled"), null, "cmdCut is enabled");
+ is(cmdCopy.getAttribute("disabled"), null, "cmdCopy is enabled");
+ is(cmdPaste.getAttribute("disabled"), null, "cmdPaste is enabled");
const onContextMenuHidden = toolbox.once("menu-close");
searchContextMenu.hidePopup();
diff --git a/devtools/client/inspector/rules/test/browser_rules_select-and-copy-styles.js b/devtools/client/inspector/rules/test/browser_rules_select-and-copy-styles.js
index f9d245828e..c6d4f29a4d 100644
--- a/devtools/client/inspector/rules/test/browser_rules_select-and-copy-styles.js
+++ b/devtools/client/inspector/rules/test/browser_rules_select-and-copy-styles.js
@@ -209,9 +209,9 @@ async function checkCopyNestedRule(view) {
const copyEvent = new win.Event("copy", { bubbles: true });
const expectedNested = `html {
- body {
+ & body {
@container (1px < width) {
- #nested {
+ & #nested {
background: tomato;
color: gold;
}
diff --git a/devtools/client/inspector/rules/test/browser_rules_selector-highlighter-nested-rules.js b/devtools/client/inspector/rules/test/browser_rules_selector-highlighter-nested-rules.js
index 4a5e8bcd0c..ecf41fb920 100644
--- a/devtools/client/inspector/rules/test/browser_rules_selector-highlighter-nested-rules.js
+++ b/devtools/client/inspector/rules/test/browser_rules_selector-highlighter-nested-rules.js
@@ -88,8 +88,8 @@ add_task(async function () {
);
ok(highlighterData.isShown, "The selector highlighter was shown");
- info(`Clicking on ".title" selector icon`);
- highlighterData = await clickSelectorIcon(view, ".title");
+ info(`Clicking on "& .title" selector icon`);
+ highlighterData = await clickSelectorIcon(view, "& .title");
is(
highlighterData.nodeFront.nodeName.toLowerCase(),
"h1",
diff --git a/devtools/client/inspector/rules/test/browser_rules_variables_02.js b/devtools/client/inspector/rules/test/browser_rules_variables_02.js
index 4100859fb9..ee37a7b07a 100644
--- a/devtools/client/inspector/rules/test/browser_rules_variables_02.js
+++ b/devtools/client/inspector/rules/test/browser_rules_variables_02.js
@@ -119,9 +119,14 @@ async function testBorderShorthandAndInheritance(inspector, view) {
// var(x) is the next sibling of the parent of M
const setVarXParent = setVarMParent.parentNode.nextElementSibling;
- // var(r) is the next sibling of var(x), and var(g) is the next sibling of var(r), etc.
- const setVarRParent = setVarXParent.nextElementSibling;
+ // var(x) next sibling is the element that wraps the color
+ const colorParent =
+ setVarXParent.nextElementSibling.querySelector(".ruleview-color");
+ // var(r) is the first childElement of the ruleview-color element
+ const setVarRParent = colorParent.firstElementChild;
+ // var(g) is the next sibling of var(r),
const setVarGParent = setVarRParent.nextElementSibling;
+ // and var(b) is the next sibling of var(g),
const setVarBParent = setVarGParent.nextElementSibling;
const setVarM = getVarFromParent(setVarMParent);
diff --git a/devtools/client/inspector/test/browser_inspector_highlighter-cssshape_offset-path.js b/devtools/client/inspector/test/browser_inspector_highlighter-cssshape_offset-path.js
index 004d7e945f..bb187db4f5 100644
--- a/devtools/client/inspector/test/browser_inspector_highlighter-cssshape_offset-path.js
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-cssshape_offset-path.js
@@ -38,7 +38,6 @@ const TEST_URL = `data:text/html,<meta charset=utf8>${encodeURIComponent(`
const HIGHLIGHTER_TYPE = "ShapesHighlighter";
add_task(async function () {
- await pushPref("layout.css.motion-path-basic-shapes.enabled", true);
const env = await openInspectorForURL(TEST_URL);
const { highlighterTestFront, inspector } = env;
const view = selectRuleView(inspector);
diff --git a/devtools/client/inspector/test/browser_inspector_inspect_loading_document.js b/devtools/client/inspector/test/browser_inspector_inspect_loading_document.js
index 6798c85394..11e67ff4cd 100644
--- a/devtools/client/inspector/test/browser_inspector_inspect_loading_document.js
+++ b/devtools/client/inspector/test/browser_inspector_inspect_loading_document.js
@@ -131,6 +131,10 @@ add_task(async function testSlowLoadingDocument() {
// Navigate to about:blank to clean the state.
await navigateTo("about:blank");
+ const markuploaded = inspector.once("markuploaded");
+ const onNewRoot = inspector.once("new-root");
+ const onUpdated = inspector.once("inspector-updated");
+
await navigateTo(TEST_URL_2, { waitForLoad: false });
info("Wait for the #start div to be available as a markupview container");
await TestUtils.waitForCondition(async () => {
@@ -165,4 +169,11 @@ add_task(async function testSlowLoadingDocument() {
"body",
inspector
);
+
+ info(
+ "Waiting for inspector to update after having released the document load"
+ );
+ await markuploaded;
+ await onNewRoot;
+ await onUpdated;
});
diff --git a/devtools/client/inspector/test/browser_inspector_menu-04-use-in-console.js b/devtools/client/inspector/test/browser_inspector_menu-04-use-in-console.js
index ac6ae35ad1..bd655a9a96 100644
--- a/devtools/client/inspector/test/browser_inspector_menu-04-use-in-console.js
+++ b/devtools/client/inspector/test/browser_inspector_menu-04-use-in-console.js
@@ -11,9 +11,17 @@ add_task(async function () {
// requests to evaluateJSAsync.
await pushPref("devtools.webconsole.input.eagerEvaluation", false);
- const { inspector, toolbox } = await openInspectorForURL(TEST_URL);
+ info("Testing 'Use in Console' menu item with enabled split console.");
+ await pushPref("devtools.toolbox.splitconsole.enabled", true);
+ await testConsoleFunctionality({ isSplitConsoleEnabled: true });
+
+ info("Testing 'Use in Console' menu item with disabled split console.");
+ await pushPref("devtools.toolbox.splitconsole.enabled", false);
+ await testConsoleFunctionality({ isSplitConsoleEnabled: false });
+});
- info("Testing 'Use in Console' menu item.");
+async function testConsoleFunctionality({ isSplitConsoleEnabled }) {
+ const { inspector, toolbox } = await openInspectorForURL(TEST_URL);
await selectNode("#console-var", inspector);
const container = await getContainerForSelector("#console-var", inspector);
@@ -27,6 +35,12 @@ add_task(async function () {
const hud = toolbox.getPanel("webconsole").hud;
+ if (isSplitConsoleEnabled) {
+ ok(toolbox.splitConsole, "The console is split console.");
+ } else {
+ ok(!toolbox.splitConsole, "The console is Web Console tab.");
+ }
+
const getConsoleResults = () => hud.ui.outputNode.querySelectorAll(".result");
is(hud.getInputValue(), "temp0", "first console variable is named temp0");
@@ -54,4 +68,4 @@ add_task(async function () {
);
hud.ui.wrapper.dispatchClearHistory();
-});
+}
diff --git a/devtools/client/inspector/test/browser_inspector_search-filter_context-menu.js b/devtools/client/inspector/test/browser_inspector_search-filter_context-menu.js
index dad2ffa0b8..e8392b1425 100644
--- a/devtools/client/inspector/test/browser_inspector_search-filter_context-menu.js
+++ b/devtools/client/inspector/test/browser_inspector_search-filter_context-menu.js
@@ -96,12 +96,12 @@ add_task(async function () {
cmdCopy = searchContextMenu.querySelector("#editmenu-copy");
cmdPaste = searchContextMenu.querySelector("#editmenu-paste");
- is(cmdUndo.getAttribute("disabled"), "", "cmdUndo is enabled");
- is(cmdDelete.getAttribute("disabled"), "", "cmdDelete is enabled");
- is(cmdSelectAll.getAttribute("disabled"), "", "cmdSelectAll is enabled");
- is(cmdCut.getAttribute("disabled"), "", "cmdCut is enabled");
- is(cmdCopy.getAttribute("disabled"), "", "cmdCopy is enabled");
- is(cmdPaste.getAttribute("disabled"), "", "cmdPaste is enabled");
+ is(cmdUndo.getAttribute("disabled"), null, "cmdUndo is enabled");
+ is(cmdDelete.getAttribute("disabled"), null, "cmdDelete is enabled");
+ is(cmdSelectAll.getAttribute("disabled"), null, "cmdSelectAll is enabled");
+ is(cmdCut.getAttribute("disabled"), null, "cmdCut is enabled");
+ is(cmdCopy.getAttribute("disabled"), null, "cmdCopy is enabled");
+ is(cmdPaste.getAttribute("disabled"), null, "cmdPaste is enabled");
const onContextMenuHidden = toolbox.once("menu-close");
searchContextMenu.hidePopup();
diff --git a/devtools/client/jar.mn b/devtools/client/jar.mn
index a2b1b7bfb7..4975514395 100644
--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -116,6 +116,7 @@ devtools.jar:
skin/images/import.svg (themes/images/import.svg)
skin/images/pane-collapse.svg (themes/images/pane-collapse.svg)
skin/images/pane-expand.svg (themes/images/pane-expand.svg)
+ skin/images/whatsnew.svg (themes/images/whatsnew.svg)
skin/images/help.svg (themes/images/help.svg)
skin/images/report.svg (themes/images/report.svg)
skin/images/reveal.svg (themes/images/reveal.svg)
diff --git a/devtools/client/locales/en-US/toolbox-options.ftl b/devtools/client/locales/en-US/toolbox-options.ftl
index 28b1d86705..0e711d1a41 100644
--- a/devtools/client/locales/en-US/toolbox-options.ftl
+++ b/devtools/client/locales/en-US/toolbox-options.ftl
@@ -66,6 +66,16 @@ options-default-color-unit-rgb = RGB(A)
options-default-color-unit-hwb = HWB
options-default-color-unit-name = Color Names
+## Web Console section
+
+# The heading
+options-webconsole-label = Web Console
+
+# The label for the checkbox that toggle whether the Split console is enabled
+options-webconsole-split-console-label = Enable Split Console
+options-webconsole-split-console-tooltip =
+ .title = Open Split Console with the Escape Key
+
## Style Editor section
# The heading
diff --git a/devtools/client/locales/en-US/toolbox.properties b/devtools/client/locales/en-US/toolbox.properties
index fc8dd99241..51c5d33658 100644
--- a/devtools/client/locales/en-US/toolbox.properties
+++ b/devtools/client/locales/en-US/toolbox.properties
@@ -160,9 +160,13 @@ toolbox.meatballMenu.button.tooltip=Customize Developer Tools and Get Help
toolbox.closebutton.tooltip=Close Developer Tools
# LOCALIZATION NOTE (toolbox.errorCountButton.tooltip): This is the tooltip for
-# the error count button displayed in the developer tools toolbox.
+# the error count button displayed in the developer tools toolbox if the "Enable Split Console" setting is checked.
toolbox.errorCountButton.tooltip=Show Split Console
+# LOCALIZATION NOTE (toolbox.errorCountButtonConsoleTab.tooltip): This is the tooltip for
+# the error count button displayed in the developer tools toolbox if the "Enable Split Console" setting is unchecked.
+toolbox.errorCountButtonConsoleTab.tooltip=Show Console
+
# LOCALIZATION NOTE (toolbox.errorCountButton.description): This is the description that
# will be used for the error count button in the devTools settings panel.
toolbox.errorCountButton.description=Show the number of errors on the page
diff --git a/devtools/client/memory/panel.js b/devtools/client/memory/panel.js
index e6143aafa4..c9d4f82f80 100644
--- a/devtools/client/memory/panel.js
+++ b/devtools/client/memory/panel.js
@@ -12,8 +12,8 @@ function MemoryPanel(iframeWindow, toolbox, commands) {
this._toolbox = toolbox;
this._commands = commands;
- const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+ const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
const browserRequire = BrowserLoader({
baseURI: "resource://devtools/client/memory/",
diff --git a/devtools/client/memory/test/chrome/head.js b/devtools/client/memory/test/chrome/head.js
index 685fa62928..4061ffa264 100644
--- a/devtools/client/memory/test/chrome/head.js
+++ b/devtools/client/memory/test/chrome/head.js
@@ -3,8 +3,8 @@
"use strict";
-var { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+var { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
var { require } = BrowserLoader({
baseURI: "resource://devtools/client/memory/",
diff --git a/devtools/client/netmonitor/initializer.js b/devtools/client/netmonitor/initializer.js
index c6a8a246f5..24afadf434 100644
--- a/devtools/client/netmonitor/initializer.js
+++ b/devtools/client/netmonitor/initializer.js
@@ -9,8 +9,8 @@
* This script is the entry point of Network monitor panel.
* See README.md for more information.
*/
-const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
const require = (window.windowRequire = BrowserLoader({
diff --git a/devtools/client/netmonitor/src/har/test/browser_net_har_copy_all_as_har.js b/devtools/client/netmonitor/src/har/test/browser_net_har_copy_all_as_har.js
index 2faaf01b73..08dbfbf068 100644
--- a/devtools/client/netmonitor/src/har/test/browser_net_har_copy_all_as_har.js
+++ b/devtools/client/netmonitor/src/har/test/browser_net_har_copy_all_as_har.js
@@ -7,7 +7,7 @@
* Basic tests for exporting Network panel content into HAR format.
*/
-const EXPECTED_REQUEST_HEADER_COUNT = 9;
+const EXPECTED_REQUEST_HEADER_COUNT = 13;
const EXPECTED_RESPONSE_HEADER_COUNT = 6;
add_task(async function () {
@@ -15,7 +15,7 @@ add_task(async function () {
// (bug 1352274). TCP Fast Open is not present on all platforms therefore the
// number of response headers will vary depending on the platform.
await pushPref("network.tcp.tcp_fastopen_enable", false);
- const { tab, monitor, toolbox } = await initNetMonitor(SIMPLE_URL, {
+ const { tab, monitor, toolbox } = await initNetMonitor(HTTPS_SIMPLE_URL, {
requestCount: 1,
});
@@ -45,7 +45,7 @@ async function testSimpleReload({ tab, monitor, toolbox }) {
const page = har.log.pages[0];
- is(page.title, SIMPLE_URL, "There must be some page title");
+ is(page.title, HTTPS_SIMPLE_URL, "There must be some page title");
ok("onContentLoad" in page.pageTimings, "There must be onContentLoad time");
ok("onLoad" in page.pageTimings, "There must be onLoad time");
@@ -98,7 +98,7 @@ async function testManyReloads({ tab, monitor, toolbox }) {
if (entry) {
ok(entry, "Found the cancelled request");
is(entry.request.method, "GET", "Method is set");
- is(entry.request.url, SIMPLE_URL, "URL is set");
+ is(entry.request.url, HTTPS_SIMPLE_URL, "URL is set");
// We always get the following headers:
// "Host", "User-agent", "Accept", "Accept-Language", "Accept-Encoding", "Connection"
// but are missing the three last headers:
@@ -173,7 +173,7 @@ function assertNavigationRequestEntry(entry) {
info("Assert that the entry relates to the navigation request");
Assert.greater(entry.time, 0, "Check the total time");
is(entry.request.method, "GET", "Check the method");
- is(entry.request.url, SIMPLE_URL, "Check the URL");
+ is(entry.request.url, HTTPS_SIMPLE_URL, "Check the URL");
is(
entry.request.headers.length,
EXPECTED_REQUEST_HEADER_COUNT,
diff --git a/devtools/client/netmonitor/src/har/test/browser_net_har_import.js b/devtools/client/netmonitor/src/har/test/browser_net_har_import.js
index 44ae3a8e16..9d66674bd3 100644
--- a/devtools/client/netmonitor/src/har/test/browser_net_har_import.js
+++ b/devtools/client/netmonitor/src/har/test/browser_net_har_import.js
@@ -65,7 +65,7 @@ add_task(async () => {
);
is(
har2.log.entries[1]._securityState,
- "insecure",
+ "secure",
"There must be expected security state"
);
is(har2.log.entries[2].response.status, 304, "There must be expected status");
diff --git a/devtools/client/netmonitor/src/har/test/head.js b/devtools/client/netmonitor/src/har/test/head.js
index b41ea580fd..abf34c1ffb 100644
--- a/devtools/client/netmonitor/src/har/test/head.js
+++ b/devtools/client/netmonitor/src/har/test/head.js
@@ -13,7 +13,7 @@ Services.scriptloader.loadSubScript(netMonitorHead, this);
// Directory with HAR related test files.
const HAR_EXAMPLE_URL =
- "http://example.com/browser/devtools/client/netmonitor/src/har/test/";
+ "https://example.com/browser/devtools/client/netmonitor/src/har/test/";
/**
* Trigger a "copy all as har" from the context menu of the requests list.
diff --git a/devtools/client/netmonitor/test/browser_net_cached-status.js b/devtools/client/netmonitor/test/browser_net_cached-status.js
index b41362b398..d6dd5519c5 100644
--- a/devtools/client/netmonitor/test/browser_net_cached-status.js
+++ b/devtools/client/netmonitor/test/browser_net_cached-status.js
@@ -10,6 +10,9 @@
add_task(async function () {
// Disable rcwn to make cache behavior deterministic.
await pushPref("network.http.rcwn.enabled", false);
+ // performing http to https redirects, hence we do not
+ // want https-first to interfere with that test
+ await pushPref("dom.security.https_first", false);
const { tab, monitor } = await initNetMonitor(STATUS_CODES_URL, {
enableCache: true,
diff --git a/devtools/client/netmonitor/test/browser_net_copy_as_powershell.js b/devtools/client/netmonitor/test/browser_net_copy_as_powershell.js
index 5785b89929..8160b10cfa 100644
--- a/devtools/client/netmonitor/test/browser_net_copy_as_powershell.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_as_powershell.js
@@ -19,7 +19,7 @@ add_task(async function () {
-Headers @{
"Accept" = "*/*"
"Accept-Language" = "en-US"
- "Accept-Encoding" = "gzip, deflate, br"
+ "Accept-Encoding" = "gzip, deflate, br, zstd"
"X-Custom-Header-1" = "Custom value"
"X-Custom-Header-2" = "8.8.8.8"
"X-Custom-Header-3" = "Mon, 3 Mar 2014 11:11:11 GMT"
@@ -42,7 +42,7 @@ Invoke-WebRequest -UseBasicParsing -Uri "https://example.com/browser/devtools/cl
-Headers @{
"Accept" = "*/*"
"Accept-Language" = "en-US"
- "Accept-Encoding" = "gzip, deflate, br"
+ "Accept-Encoding" = "gzip, deflate, br, zstd"
"X-Custom-Header-1" = "Custom value"
"X-Custom-Header-2" = "8.8.8.8"
"X-Custom-Header-3" = "Mon, 3 Mar 2014 11:11:11 GMT"
@@ -66,7 +66,7 @@ Invoke-WebRequest -UseBasicParsing -Uri "https://example.com/browser/devtools/cl
-Headers @{
"Accept" = "*/*"
"Accept-Language" = "en-US"
- "Accept-Encoding" = "gzip, deflate, br"
+ "Accept-Encoding" = "gzip, deflate, br, zstd"
"X-Custom-Header-1" = "Custom value"
"X-Custom-Header-2" = "8.8.8.8"
"X-Custom-Header-3" = "Mon, 3 Mar 2014 11:11:11 GMT"
@@ -95,7 +95,7 @@ Invoke-WebRequest -UseBasicParsing -Uri "https://example.com/browser/devtools/cl
-Headers @{
"Accept" = "*/*"
"Accept-Language" = "en-US"
- "Accept-Encoding" = "gzip, deflate, br"
+ "Accept-Encoding" = "gzip, deflate, br, zstd"
"X-Custom-Header-1" = "Custom value"
"X-Custom-Header-2" = "8.8.8.8"
"X-Custom-Header-3" = "Mon, 3 Mar 2014 11:11:11 GMT"
diff --git a/devtools/client/netmonitor/test/browser_net_copy_headers.js b/devtools/client/netmonitor/test/browser_net_copy_headers.js
index cd6499d93b..458a19af97 100644
--- a/devtools/client/netmonitor/test/browser_net_copy_headers.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_headers.js
@@ -47,6 +47,7 @@ add_task(async function () {
"Accept-Encoding: gzip, deflate",
"Connection: keep-alive",
"Upgrade-Insecure-Requests: 1",
+ "Priority: u=1",
"Pragma: no-cache",
"Cache-Control: no-cache",
].join("\n");
diff --git a/devtools/client/netmonitor/test/browser_net_headers_sorted.js b/devtools/client/netmonitor/test/browser_net_headers_sorted.js
index 2965ea8d3c..ea12b1c67e 100644
--- a/devtools/client/netmonitor/test/browser_net_headers_sorted.js
+++ b/devtools/client/netmonitor/test/browser_net_headers_sorted.js
@@ -71,6 +71,7 @@ async function verifyHeaders(monitor) {
"Cookie",
"Host",
"Pragma",
+ "Priority",
"Sec-Fetch-Dest",
"Sec-Fetch-Mode",
"Sec-Fetch-Site",
@@ -144,6 +145,7 @@ async function verifyRawHeaders(monitor) {
"Sec-Fetch-Dest",
"Sec-Fetch-Mode",
"Sec-Fetch-Site",
+ "Priority",
"Pragma",
"Cache-Control",
];
diff --git a/devtools/client/netmonitor/test/browser_net_http3_request_details.js b/devtools/client/netmonitor/test/browser_net_http3_request_details.js
index 9ceb9dba88..6a6c5973c9 100644
--- a/devtools/client/netmonitor/test/browser_net_http3_request_details.js
+++ b/devtools/client/netmonitor/test/browser_net_http3_request_details.js
@@ -74,8 +74,8 @@ add_task(async function () {
// The Text-Encoding header is not consistently displayed, exclude it from
// the assertion. See Bug 1830053.
headers.filter(cell => cell.textContent != "TE").length,
- 25,
- "There should be 25 header values displayed in this tabpanel."
+ 26,
+ "There should be 26 header values displayed in this tabpanel."
);
const headersTable = tabpanel.querySelector(".accordion");
diff --git a/devtools/client/netmonitor/test/browser_net_resend.js b/devtools/client/netmonitor/test/browser_net_resend.js
index cc3c212988..9150bfe3ba 100644
--- a/devtools/client/netmonitor/test/browser_net_resend.js
+++ b/devtools/client/netmonitor/test/browser_net_resend.js
@@ -60,14 +60,23 @@ async function testResendRequest() {
"The resent request has the same url and query parameters and the first request"
);
+ // The priority header only appears when the urgency and incremental values
+ // are not both default values (u=3 and i=false). In this case the original
+ // request has no priority header and the resent request does, hence we subtract one.
is(
firstResend.originalResource.requestHeaders.headers.length,
- firstResend.newResource.requestHeaders.headers.length,
+ firstResend.newResource.requestHeaders.headers.length - 1,
"The no of headers are the same"
);
+ // Because a resent request has a different purpose and principal it will
+ // also have a different CoS flag (meaning a different priority header).
+ // So we can't compare the original and resent request's priority and skip it.
firstResend.originalResource.requestHeaders.headers.forEach(
({ name, value }) => {
+ if (name === "Priority") {
+ return;
+ }
const foundHeader = firstResend.newResource.requestHeaders.headers.find(
header => header.name == name
);
diff --git a/devtools/client/netmonitor/test/browser_net_simple-request-details.js b/devtools/client/netmonitor/test/browser_net_simple-request-details.js
index e52a0b101a..e7d07f392c 100644
--- a/devtools/client/netmonitor/test/browser_net_simple-request-details.js
+++ b/devtools/client/netmonitor/test/browser_net_simple-request-details.js
@@ -137,8 +137,8 @@ add_task(async function () {
is(
tabpanel.querySelectorAll(".accordion .treeLabelCell").length,
- 23,
- "There should be 23 header values displayed in this tabpanel."
+ 24,
+ "There should be 24 header values displayed in this tabpanel."
);
const headersTable = tabpanel.querySelector(".accordion");
diff --git a/devtools/client/performance-new/@types/gecko.d.ts b/devtools/client/performance-new/@types/gecko.d.ts
index f5da78697e..682db32c13 100644
--- a/devtools/client/performance-new/@types/gecko.d.ts
+++ b/devtools/client/performance-new/@types/gecko.d.ts
@@ -28,7 +28,7 @@ declare namespace MockedExports {
"resource://devtools/shared/loader/Loader.sys.mjs": typeof import("resource://devtools/shared/loader/Loader.sys.mjs");
"resource://devtools/client/performance-new/shared/background.sys.mjs": typeof import("resource://devtools/client/performance-new/shared/background.sys.mjs");
"resource://devtools/client/performance-new/shared/symbolication.sys.mjs": typeof import("resource://devtools/client/performance-new/shared/symbolication.sys.mjs");
- "resource://devtools/shared/loader/browser-loader.js": any;
+ "resource://devtools/shared/loader/browser-loader.sys.mjs": any;
"resource://devtools/client/performance-new/popup/menu-button.sys.mjs": typeof import("resource://devtools/client/performance-new/popup/menu-button.sys.mjs");
"resource://devtools/client/performance-new/shared/typescript-lazy-load.sys.mjs": typeof import("resource://devtools/client/performance-new/shared/typescript-lazy-load.sys.mjs");
"resource://devtools/client/performance-new/popup/logic.sys.mjs": typeof import("resource://devtools/client/performance-new/popup/logic.sys.mjs");
diff --git a/devtools/client/performance-new/aboutprofiling/initializer.js b/devtools/client/performance-new/aboutprofiling/initializer.js
index 8dd854007c..2e99ca0a3a 100644
--- a/devtools/client/performance-new/aboutprofiling/initializer.js
+++ b/devtools/client/performance-new/aboutprofiling/initializer.js
@@ -19,8 +19,8 @@
// TypeScript. See devtools/client/performance-new/typescript.md and
// the section on "Do not overload require" for more information.
- const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+ const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
const browserLoader = BrowserLoader({
baseURI: "resource://devtools/client/performance-new/aboutprofiling",
diff --git a/devtools/client/performance-new/panel/initializer.js b/devtools/client/performance-new/panel/initializer.js
index 2264e4764f..25a2176a36 100644
--- a/devtools/client/performance-new/panel/initializer.js
+++ b/devtools/client/performance-new/panel/initializer.js
@@ -23,8 +23,8 @@
// TypeScript. See devtools/client/performance-new/typescript.md and
// the section on "Do not overload require" for more information.
- const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+ const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
const browserLoader = BrowserLoader({
baseURI: "resource://devtools/client/performance-new/",
diff --git a/devtools/client/performance-new/shared/#typescript-lazy-load.jsm.js# b/devtools/client/performance-new/shared/#typescript-lazy-load.jsm.js#
deleted file mode 100644
index de982cc3ff..0000000000
--- a/devtools/client/performance-new/shared/#typescript-lazy-load.jsm.js#
+++ /dev/null
@@ -1,55 +0,0 @@
-/* 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/. */
-// @ts-check
-"use strict";
-
-/**
- * TypeScript can't understand the lazyRequireGetter mechanism, due to how it defines
- * properties as a getter. This function, instead provides lazy loading in a
- * TypeScript-friendly manner. It applies the lazy load memoization to each property
- * of the provided object.
- *
- * Example usage:
- *
- * const lazy = createLazyLoaders({
- * moduleA: () => require("module/a"),
- * moduleB: () => require("module/b"),
- * });
- *
- * Later:
- *
- * const moduleA = lazy.moduleA();
- * const { objectInModuleB } = lazy.moduleB();
- *
- * @template {{ [key: string]: () => any }} T
- * @param {T} definition - An object where each property has a function that loads a module.
- * @returns {T} - The load memoized version of T.
- */
-function createLazyLoaders(definition) {
- /** @type {any} */
- const result = {};
- for (const [key, callback] of Object.entries(definition)) {
- /** @type {any} */
- let cache;
- result[key] = () => {
- if (cache === undefined) {
- cache = callback();
- }
- return cache;
- };
- }
- return result;
-}
-
-// Provide an exports object for the JSM to be properly read by TypeScript.
-/** @type {any} */
-var module = {};
-
-module.exports = {
- createLazyLoaders,
-};
-
-// Object.keys() confuses the linting which expects a static array expression.
-// eslint-disable-next-line
-var EXPORTED_SYMBOLS = Object.keys(module.exports);
diff --git a/devtools/client/performance-new/tsconfig.json b/devtools/client/performance-new/tsconfig.json
index f98b4b33d4..80bababd37 100644
--- a/devtools/client/performance-new/tsconfig.json
+++ b/devtools/client/performance-new/tsconfig.json
@@ -14,7 +14,12 @@
"noEmit": true,
// Allow esnext syntax. Otherwise the default is ES5 only.
"target": "esnext",
- "lib": ["esnext", "dom"]
+ "lib": ["esnext", "dom"],
+ // Make sure that only this project is taken into account when checking types.
+ // In the future we'll want to use the same types as in the rest of Gecko, but
+ // that's not ready yet.
+ // See Bug 1891209
+ "typeRoots": ["./@types", "./node_modules/@types"]
},
"files": ["./@types/gecko.d.ts"],
// Add a @ts-check comment to a JS file to start type checking it.
diff --git a/devtools/client/responsive/index.js b/devtools/client/responsive/index.js
index 84bdf16e12..5ee25ab95e 100644
--- a/devtools/client/responsive/index.js
+++ b/devtools/client/responsive/index.js
@@ -6,8 +6,8 @@
"use strict";
-const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
const { require } = BrowserLoader({
baseURI: "resource://devtools/client/responsive/",
diff --git a/devtools/client/responsive/test/browser/browser_device_width.js b/devtools/client/responsive/test/browser/browser_device_width.js
index 11dc8fd31c..a7d1dfde30 100644
--- a/devtools/client/responsive/test/browser/browser_device_width.js
+++ b/devtools/client/responsive/test/browser/browser_device_width.js
@@ -11,9 +11,6 @@ addRDMTask(TEST_URL, async function ({ ui, manager }) {
ok(ui, "An instance of the RDM should be attached to the tab.");
await setViewportSizeAndAwaitReflow(ui, manager, 110, 500);
- info("Checking initial width/height properties.");
- await doInitialChecks(ui, 110);
-
info("Checking initial width/height with meta viewport on");
await setTouchAndMetaViewportSupport(ui, true);
await doInitialChecks(ui, 980);
diff --git a/devtools/client/responsive/test/browser/browser_toolbox_computed_view.js b/devtools/client/responsive/test/browser/browser_toolbox_computed_view.js
index f22ee8d246..d4d9c94c79 100644
--- a/devtools/client/responsive/test/browser/browser_toolbox_computed_view.js
+++ b/devtools/client/responsive/test/browser/browser_toolbox_computed_view.js
@@ -6,18 +6,22 @@
// Check that when the viewport is resized, the computed-view refreshes.
const TEST_URI =
- "data:text/html;charset=utf-8,<html><style>" +
- "div {" +
- " width: 500px;" +
- " height: 10px;" +
- " background: purple;" +
- "} " +
- "@media screen and (max-width: 200px) {" +
- " div { " +
- " width: 100px;" +
- " }" +
- "};" +
- "</style><div></div></html>";
+ "data:text/html;charset=utf-8," +
+ `
+ <meta name="viewport" content="width=device-width">
+ <style>
+ div {
+ width: 500px;
+ height: 10px;
+ background: purple;
+ }
+ @media screen and (max-width: 200px) {
+ div {
+ width: 100px;
+ }
+ };
+ </style><div></div></html>
+`;
addRDMTask(TEST_URI, async function ({ ui, manager }) {
info("Open the responsive design mode and set its size to 500x500 to start");
diff --git a/devtools/client/responsive/test/browser/browser_viewport_resizing_after_reload.js b/devtools/client/responsive/test/browser/browser_viewport_resizing_after_reload.js
index ad750326ae..22dbdff527 100644
--- a/devtools/client/responsive/test/browser/browser_viewport_resizing_after_reload.js
+++ b/devtools/client/responsive/test/browser/browser_viewport_resizing_after_reload.js
@@ -23,7 +23,7 @@ addRDMTask(TEST_URL, async function ({ ui, manager }) {
const expected = [
{
metaSupport: false,
- before: [1.0, 300, 600],
+ before: [0.5, 300, 600],
after: [1.0, 600, 300],
},
{
diff --git a/devtools/client/responsive/test/browser/browser_viewport_resizing_fixed_width.js b/devtools/client/responsive/test/browser/browser_viewport_resizing_fixed_width.js
index 46a2529b12..5fd38565be 100644
--- a/devtools/client/responsive/test/browser/browser_viewport_resizing_fixed_width.js
+++ b/devtools/client/responsive/test/browser/browser_viewport_resizing_fixed_width.js
@@ -19,8 +19,8 @@ addRDMTask(TEST_URL, async function ({ ui, manager }) {
const expected = [
{
metaSupport: false,
- before: [1.0, 600, 300],
- after: [1.0, 50, 50], // Zoom is unaffected.
+ before: [2.0, 300, 150],
+ after: [0.25, 300, 300], // This checks that min-zoom is active.
},
{
metaSupport: true,
diff --git a/devtools/client/responsive/test/browser/doc_toolbox_rule_view.html b/devtools/client/responsive/test/browser/doc_toolbox_rule_view.html
index e4a311b7ec..f0cc88ef97 100644
--- a/devtools/client/responsive/test/browser/doc_toolbox_rule_view.html
+++ b/devtools/client/responsive/test/browser/doc_toolbox_rule_view.html
@@ -1,4 +1,5 @@
<html>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" charset="UTF-8" type="text/css" media="screen" href="doc_toolbox_rule_view.css"/>
<div></div>
</html>
diff --git a/devtools/client/shared/components/NotificationBox.css b/devtools/client/shared/components/NotificationBox.css
index f2ff550f46..b051c96a2f 100644
--- a/devtools/client/shared/components/NotificationBox.css
+++ b/devtools/client/shared/components/NotificationBox.css
@@ -87,7 +87,7 @@
}
.notificationbox .messageImage[data-type="new"] {
- background-image: url("chrome://global/skin/icons/whatsnew.svg");
+ background-image: url("chrome://devtools/skin/images/whatsnew.svg");
fill: var(--theme-highlight-blue);
}
diff --git a/devtools/client/shared/components/test/chrome/head.js b/devtools/client/shared/components/test/chrome/head.js
index 7abe54942f..e8260cb774 100644
--- a/devtools/client/shared/components/test/chrome/head.js
+++ b/devtools/client/shared/components/test/chrome/head.js
@@ -14,8 +14,8 @@ var { Assert } = ChromeUtils.importESModule(
"resource://testing-common/Assert.sys.mjs"
);
var { gDevTools } = require("resource://devtools/client/framework/devtools.js");
-var { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+var { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
var {
DevToolsServer,
diff --git a/devtools/client/shared/output-parser.js b/devtools/client/shared/output-parser.js
index fc1afca5a0..bd514096b3 100644
--- a/devtools/client/shared/output-parser.js
+++ b/devtools/client/shared/output-parser.js
@@ -217,8 +217,13 @@ class OutputParser {
options.getVariableValue
) {
sawVariable = true;
- const { node } = this.#parseVariable(token, text, tokenStream, options);
- functionData.push(node);
+ const { node, value, fallbackValue } = this.#parseVariable(
+ token,
+ text,
+ tokenStream,
+ options
+ );
+ functionData.push({ node, value, fallbackValue });
} else if (token.tokenType === "function") {
++depth;
}
@@ -278,6 +283,7 @@ class OutputParser {
const secondOpts = {};
let varValue;
+ let varFallbackValue;
// Get the variable value if it is in use.
if (tokens && tokens.length === 1) {
@@ -324,11 +330,16 @@ class OutputParser {
const span = this.#createNode("span", secondOpts);
span.appendChild(rest);
+ varFallbackValue = span.textContent;
variableNode.appendChild(span);
}
variableNode.appendChild(this.#doc.createTextNode(")"));
- return { node: variableNode, value: varValue };
+ return {
+ node: variableNode,
+ value: varValue,
+ fallbackValue: varFallbackValue,
+ };
}
/**
@@ -435,17 +446,43 @@ class OutputParser {
);
if (sawVariable) {
- // If function contains variable, we need to add both strings
- // and nodes.
- this.#appendTextNode(functionName);
- for (const data of functionData) {
- if (typeof data === "string") {
- this.#appendTextNode(data);
- } else if (data) {
- this.#parsed.push(data);
+ const computedFunctionText =
+ functionName +
+ functionData
+ .map(data => {
+ if (typeof data === "string") {
+ return data;
+ }
+ return data.value ?? data.fallbackValue;
+ })
+ .join("") +
+ ")";
+ if (
+ colorOK() &&
+ InspectorUtils.isValidCSSColor(computedFunctionText)
+ ) {
+ this.#appendColor(computedFunctionText, {
+ ...options,
+ colorFunction: colorFunctions.at(-1)?.functionName,
+ valueParts: [
+ functionName,
+ ...functionData.map(data => data.node || data),
+ ")",
+ ],
+ });
+ } else {
+ // If function contains variable, we need to add both strings
+ // and nodes.
+ this.#appendTextNode(functionName);
+ for (const data of functionData) {
+ if (typeof data === "string") {
+ this.#appendTextNode(data);
+ } else if (data) {
+ this.#parsed.push(data.node);
+ }
}
+ this.#appendTextNode(")");
}
- this.#appendTextNode(")");
} else {
// If no variable in function, join the text together and add
// to DOM accordingly.
@@ -1598,13 +1635,14 @@ class OutputParser {
container.appendChild(options.variableContainer);
} else {
// Otherwise we create a new element with the `color` as textContent.
- const value = this.#createNode(
- "span",
- {
- class: options.colorClass,
- },
- color
- );
+ const value = this.#createNode("span", {
+ class: options.colorClass,
+ });
+ if (options.valueParts) {
+ value.append(...options.valueParts);
+ } else {
+ value.append(this.#doc.createTextNode(color));
+ }
container.appendChild(value);
}
diff --git a/devtools/client/shared/remote-debugging/adb/xpcshell/test_prepare-tcp-connection.js b/devtools/client/shared/remote-debugging/adb/xpcshell/test_prepare-tcp-connection.js
index 09dad165f2..11df5663f8 100644
--- a/devtools/client/shared/remote-debugging/adb/xpcshell/test_prepare-tcp-connection.js
+++ b/devtools/client/shared/remote-debugging/adb/xpcshell/test_prepare-tcp-connection.js
@@ -15,8 +15,8 @@ add_task(async function testParseFileUri() {
// Mocks are not supported for the regular DevTools loader.
info("Create a BrowserLoader to enable mocks in the test");
- const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+ const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
const mockedRequire = BrowserLoader({
baseURI: "resource://devtools/client/shared/remote-debugging/adb",
diff --git a/devtools/client/shared/sourceeditor/editor.js b/devtools/client/shared/sourceeditor/editor.js
index 056914b931..3487acffa4 100644
--- a/devtools/client/shared/sourceeditor/editor.js
+++ b/devtools/client/shared/sourceeditor/editor.js
@@ -166,6 +166,10 @@ class Editor extends EventEmitter {
#ownerDoc;
#prefObserver;
#win;
+ #lineGutterMarkers = new Map();
+ #lineContentMarkers = new Map();
+
+ #updateListener = null;
constructor(config) {
super();
@@ -412,6 +416,12 @@ class Editor extends EventEmitter {
}
}
+ // This update listener allows listening to the changes
+ // to the codemiror editor.
+ setUpdateListener(listener = null) {
+ this.#updateListener = listener;
+ }
+
/**
* Do the actual appending and configuring of the CodeMirror instance. This is
* used by both append functions above, and does all the hard work to
@@ -614,11 +624,17 @@ class Editor extends EventEmitter {
const tabSizeCompartment = new Compartment();
const indentCompartment = new Compartment();
const lineWrapCompartment = new Compartment();
+ const lineNumberCompartment = new Compartment();
+ const lineNumberMarkersCompartment = new Compartment();
+ const lineContentMarkerCompartment = new Compartment();
this.#compartments = {
tabSizeCompartment,
indentCompartment,
lineWrapCompartment,
+ lineNumberCompartment,
+ lineNumberMarkersCompartment,
+ lineContentMarkerCompartment,
};
const indentStr = (this.config.indentWithTabs ? "\t" : " ").repeat(
@@ -632,6 +648,7 @@ class Editor extends EventEmitter {
this.config.lineWrapping ? EditorView.lineWrapping : []
),
EditorState.readOnly.of(this.config.readOnly),
+ lineNumberCompartment.of(this.config.lineNumbers ? lineNumbers() : []),
codemirrorLanguage.codeFolding({
placeholderText: "↔",
}),
@@ -645,6 +662,21 @@ class Editor extends EventEmitter {
},
}),
codemirrorLanguage.syntaxHighlighting(lezerHighlight.classHighlighter),
+ EditorView.updateListener.of(v => {
+ if (v.viewportChanged || v.docChanged) {
+ // reset line gutter markers for the new visible ranges
+ // when the viewport changes(e.g when the page is scrolled).
+ if (this.#lineGutterMarkers.size > 0) {
+ this.setLineGutterMarkers();
+ }
+ }
+ // Any custom defined update listener should be called
+ if (typeof this.#updateListener == "function") {
+ this.#updateListener(v);
+ }
+ }),
+ lineNumberMarkersCompartment.of([]),
+ lineContentMarkerCompartment.of(this.#lineContentMarkersExtension([])),
// keep last so other extension take precedence
codemirror.minimalSetup,
];
@@ -653,10 +685,6 @@ class Editor extends EventEmitter {
extensions.push(codemirrorLangJavascript.javascript());
}
- if (this.config.lineNumbers) {
- extensions.push(lineNumbers());
- }
-
const cm = new EditorView({
parent: el,
extensions,
@@ -666,6 +694,219 @@ class Editor extends EventEmitter {
}
/**
+ * This creates the extension used to manage the rendering of markers
+ * for in editor line content.
+ * @param {Array} markers - The current list of markers
+ * @returns {Array<ViewPlugin>} showLineContentDecorations - An extension which is an array containing the view
+ * which manages the rendering of the line content markers.
+ */
+ #lineContentMarkersExtension(markers) {
+ const {
+ codemirrorView: { Decoration, ViewPlugin },
+ codemirrorState: { RangeSetBuilder },
+ } = this.#CodeMirror6;
+
+ // Build and return the decoration set
+ function buildDecorations(view) {
+ const builder = new RangeSetBuilder();
+ for (const { from, to } of view.visibleRanges) {
+ for (let pos = from; pos <= to; ) {
+ const line = view.state.doc.lineAt(pos);
+ for (const { lineClassName, condition } of markers) {
+ if (condition(line.number)) {
+ builder.add(
+ line.from,
+ line.from,
+ Decoration.line({ class: lineClassName })
+ );
+ }
+ }
+ pos = line.to + 1;
+ }
+ }
+ return builder.finish();
+ }
+
+ // The view which handles rendering and updating the
+ // markers decorations
+ const showLineContentDecorations = ViewPlugin.fromClass(
+ class {
+ decorations;
+ constructor(view) {
+ this.decorations = buildDecorations(view);
+ }
+ update(update) {
+ if (update.docChanged || update.viewportChanged) {
+ this.decorations = buildDecorations(update.view);
+ }
+ }
+ },
+ { decorations: v => v.decorations }
+ );
+
+ return [showLineContentDecorations];
+ }
+
+ /**
+ * This adds a marker used to add classes to editor line based on a condition.
+ * @property {object} marker - The rule rendering a marker or class.
+ * @property {object} marker.id - The unique identifier for this marker
+ * @property {string} marker.lineClassName - The css class to add to the line
+ * @property {function} marker.condition - The condition that decides if the marker/class gets added or removed.
+ * The line is passed as an argument.
+ */
+ setLineContentMarker(marker) {
+ const cm = editors.get(this);
+ this.#lineContentMarkers.set(marker.id, marker);
+
+ cm.dispatch({
+ effects: this.#compartments.lineContentMarkerCompartment.reconfigure(
+ this.#lineContentMarkersExtension(
+ Array.from(this.#lineContentMarkers.values())
+ )
+ ),
+ });
+ }
+
+ /**
+ * This removes the marker which has the specified className
+ * @param {string} markerId - The unique identifier for this marker
+ */
+ removeLineContentMarker(markerId) {
+ const cm = editors.get(this);
+ this.#lineContentMarkers.delete(markerId);
+
+ cm.dispatch({
+ effects: this.#compartments.lineContentMarkerCompartment.reconfigure(
+ this.#lineContentMarkersExtension(
+ Array.from(this.#lineContentMarkers.values())
+ )
+ ),
+ });
+ }
+
+ /**
+ * Set event listeners for the line gutter
+ * @param {Object} domEventHandlers
+ *
+ * example usage:
+ * const domEventHandlers = { click(event) { console.log(event);} }
+ */
+ setGutterEventListeners(domEventHandlers) {
+ const cm = editors.get(this);
+ const {
+ codemirrorView: { lineNumbers },
+ } = this.#CodeMirror6;
+
+ for (const eventName in domEventHandlers) {
+ const handler = domEventHandlers[eventName];
+ domEventHandlers[eventName] = (view, line, event) => {
+ line = view.state.doc.lineAt(line.from);
+ handler(event, view, line.number);
+ };
+ }
+
+ cm.dispatch({
+ effects: this.#compartments.lineWrapCompartment.reconfigure(
+ lineNumbers({ domEventHandlers })
+ ),
+ });
+ }
+
+ /**
+ * This supports adding/removing of line classes or markers on the
+ * line number gutter based on the defined conditions. This only supports codemirror 6.
+ *
+ * @param {Array<Marker>} markers - The list of marker objects which defines the rules
+ * for rendering each marker.
+ * @property {object} marker - The rule rendering a marker or class. This is required.
+ * @property {string} marker.id - The unique identifier for this marker.
+ * @property {string} marker.lineClassName - The css class to add to the line. This is required.
+ * @property {function} marker.condition - The condition that decides if the marker/class gets added or removed.
+ * @property {function=} marker.createLineElementNode - This gets the line as an argument and should return the DOM element which
+ * is used for the marker. This is optional.
+ */
+ setLineGutterMarkers(markers) {
+ const cm = editors.get(this);
+
+ if (markers) {
+ // Cache the markers for use later. See next comment
+ for (const marker of markers) {
+ if (!marker.id) {
+ throw new Error("Marker has no unique identifier");
+ }
+ this.#lineGutterMarkers.set(marker.id, marker);
+ }
+ }
+ // When no markers are passed, the cached markers are used to update the line gutters.
+ // This is useful for re-rendering the line gutters when the viewport changes
+ // (note: the visible ranges will be different) in this case, mainly when the editor is scrolled.
+ else if (!this.#lineGutterMarkers.size) {
+ return;
+ }
+ markers = Array.from(this.#lineGutterMarkers.values());
+
+ const {
+ codemirrorView: { lineNumberMarkers, GutterMarker },
+ codemirrorState: { RangeSetBuilder },
+ } = this.#CodeMirror6;
+
+ // This creates a new GutterMarker https://codemirror.net/docs/ref/#view.GutterMarker
+ // to represents how each line gutter is rendered in the view.
+ // This is set as the value for the Range https://codemirror.net/docs/ref/#state.Range
+ // which represents the line.
+ class LineGutterMarker extends GutterMarker {
+ constructor(className, lineNumber, createElementNode) {
+ super();
+ this.elementClass = className || null;
+ this.toDOM = createElementNode
+ ? () => createElementNode(lineNumber)
+ : null;
+ }
+ }
+
+ // Loop through the visible ranges https://codemirror.net/docs/ref/#view.EditorView.visibleRanges
+ // (representing the lines in the current viewport) and generate a new rangeset for updating the line gutter
+ // based on the conditions defined in the markers(for each line) provided.
+ const builder = new RangeSetBuilder();
+ for (const { from, to } of cm.visibleRanges) {
+ for (let pos = from; pos <= to; ) {
+ const line = cm.state.doc.lineAt(pos);
+ for (const {
+ lineClassName,
+ condition,
+ createLineElementNode,
+ } of markers) {
+ if (typeof condition !== "function") {
+ throw new Error("The `condition` is not a valid function");
+ }
+ if (condition(line.number)) {
+ builder.add(
+ line.from,
+ line.to,
+ new LineGutterMarker(
+ lineClassName,
+ line.number,
+ createLineElementNode
+ )
+ );
+ }
+ }
+ pos = line.to + 1;
+ }
+ }
+
+ // To update the state with the newly generated marker range set, a dispatch is called on the view
+ // with an transaction effect created by the lineNumberMarkersCompartment, which is used to update the
+ // lineNumberMarkers extension configuration.
+ cm.dispatch({
+ effects: this.#compartments.lineNumberMarkersCompartment.reconfigure(
+ lineNumberMarkers.of(builder.finish())
+ ),
+ });
+ }
+
+ /**
* Returns a boolean indicating whether the editor is ready to
* use. Use appendTo(el).then(() => {}) for most cases
*/
@@ -1658,6 +1899,8 @@ class Editor extends EventEmitter {
this.config = null;
this.version = null;
this.#ownerDoc = null;
+ this.#updateListener = null;
+ this.#lineGutterMarkers.clear();
if (this.#prefObserver) {
this.#prefObserver.off(KEYMAP_PREF, this.setKeyMap);
diff --git a/devtools/client/shared/test/browser_browserloader_mocks.js b/devtools/client/shared/test/browser_browserloader_mocks.js
index 6cc38259f3..5a67b6fcd2 100644
--- a/devtools/client/shared/test/browser_browserloader_mocks.js
+++ b/devtools/client/shared/test/browser_browserloader_mocks.js
@@ -3,8 +3,8 @@
"use strict";
-const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
const {
diff --git a/devtools/client/shared/test/browser_outputparser.js b/devtools/client/shared/test/browser_outputparser.js
index 226e0bb685..7e0c1b7e00 100644
--- a/devtools/client/shared/test/browser_outputparser.js
+++ b/devtools/client/shared/test/browser_outputparser.js
@@ -6,7 +6,6 @@
add_task(async function () {
await pushPref("layout.css.backdrop-filter.enabled", true);
await pushPref("layout.css.individual-transform.enabled", true);
- await pushPref("layout.css.motion-path-basic-shapes.enabled", true);
await addTab("about:blank");
await performTest();
gBrowser.removeCurrentTab();
@@ -671,6 +670,36 @@ function testParseVariable(doc, parser) {
`</span>)` +
`</span>`,
},
+ {
+ text: "rgba(var(--r), 0, 0, var(--a))",
+ variables: { "--r": "255", "--a": "0.5" },
+ expected:
+ // prettier-ignore
+ '<span data-color="rgba(255, 0, 0, 0.5)">' +
+ "<span>rgba("+
+ "<span>" +
+ 'var(<span data-variable="--r = 255">--r</span>)' +
+ "</span>, 0, 0, " +
+ "<span>" +
+ 'var(<span data-variable="--a = 0.5">--a</span>)' +
+ "</span>" +
+ ")</span>" +
+ "</span>",
+ },
+ {
+ text: "rgb(var(--not-seen, 255), 0, 0)",
+ variables: {},
+ expected:
+ // prettier-ignore
+ '<span data-color="rgb( 255, 0, 0)">' +
+ "<span>rgb("+
+ "<span>var(" +
+ `<span class="unmatched-class" data-variable="--not-seen is not set">--not-seen</span>,` +
+ `<span> 255</span>` +
+ ")</span>, 0, 0" +
+ ")</span>" +
+ "</span>",
+ },
];
for (const test of TESTS) {
diff --git a/devtools/client/shared/test/browser_require_raw.js b/devtools/client/shared/test/browser_require_raw.js
index bcf4afe98f..64d48f2eb1 100644
--- a/devtools/client/shared/test/browser_require_raw.js
+++ b/devtools/client/shared/test/browser_require_raw.js
@@ -3,8 +3,8 @@
"use strict";
-const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
const { require: browserRequire } = BrowserLoader({
diff --git a/devtools/client/shared/test/shared-head.js b/devtools/client/shared/test/shared-head.js
index aa47b35edd..0657ede75e 100644
--- a/devtools/client/shared/test/shared-head.js
+++ b/devtools/client/shared/test/shared-head.js
@@ -93,6 +93,30 @@ if (DEBUG_STEP) {
});
}
+const DEBUG_TRACE_LINE = Services.env.get("DEBUG_TRACE_LINE");
+if (DEBUG_TRACE_LINE) {
+ // Use a custom loader with `invisibleToDebugger` flag for the allocation tracker
+ // as it instantiates custom Debugger API instances and has to be running in a distinct
+ // compartments from DevTools and system scopes (ESMs, XPCOM,...)
+ const {
+ useDistinctSystemPrincipalLoader,
+ releaseDistinctSystemPrincipalLoader,
+ } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/DistinctSystemPrincipalLoader.sys.mjs"
+ );
+ const requester = {};
+ const loader = useDistinctSystemPrincipalLoader(requester);
+
+ const lineTracer = loader.require(
+ "resource://devtools/shared/test-helpers/test-line-tracer.js"
+ );
+ lineTracer.start(globalThis, gTestPath, DEBUG_TRACE_LINE);
+ registerCleanupFunction(() => {
+ lineTracer.stop();
+ releaseDistinctSystemPrincipalLoader(requester);
+ });
+}
+
const { loader, require } = ChromeUtils.importESModule(
"resource://devtools/shared/loader/Loader.sys.mjs"
);
@@ -276,7 +300,7 @@ registerCleanupFunction(() => {
Services.prefs.clearUserPref("dom.ipc.processPrelaunch.enabled");
Services.prefs.clearUserPref("devtools.toolbox.host");
Services.prefs.clearUserPref("devtools.toolbox.previousHost");
- Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled");
+ Services.prefs.clearUserPref("devtools.toolbox.splitconsole.open");
Services.prefs.clearUserPref("devtools.toolbox.splitconsoleHeight");
Services.prefs.clearUserPref(
"javascript.options.asyncstack_capture_debuggee_only"
diff --git a/devtools/client/shared/thread-utils.js b/devtools/client/shared/thread-utils.js
index 9c29681b91..7f3aa4a8ac 100644
--- a/devtools/client/shared/thread-utils.js
+++ b/devtools/client/shared/thread-utils.js
@@ -4,8 +4,9 @@
"use strict";
const asyncStoreHelper = require("resource://devtools/client/shared/async-store-helper.js");
-const { validateBreakpointLocation } = ChromeUtils.import(
- "resource://devtools/shared/validate-breakpoint.jsm"
+const { validateBreakpointLocation } = ChromeUtils.importESModule(
+ "resource://devtools/shared/validate-breakpoint.sys.mjs",
+ { global: "contextual" }
);
const asyncStore = asyncStoreHelper("debugger", {
diff --git a/devtools/client/shared/vendor/WASMPARSER_UPGRADING b/devtools/client/shared/vendor/WASMPARSER_UPGRADING
index 05a9e8abd3..f756c45dd2 100644
--- a/devtools/client/shared/vendor/WASMPARSER_UPGRADING
+++ b/devtools/client/shared/vendor/WASMPARSER_UPGRADING
@@ -1,13 +1,13 @@
# wasmparser version
-Current version is: 5.9.0
+Current version is: 5.11.0
# Upgrade process
1. Pull latest release from npm and extract WasmDis.js and WasmParser.js, e.g.
```
-curl https://registry.npmjs.org/wasmparser/-/wasmparser-5.9.0.tgz | tar -zx --strip-components 3 package/dist/cjs/{WasmDis,WasmParser}.js
+curl https://registry.npmjs.org/wasmparser/-/wasmparser-5.11.0.tgz | tar -zx --strip-components 3 package/dist/cjs/{WasmDis,WasmParser}.js
```
2. Remove reference to source maps (last line)
diff --git a/devtools/client/shared/vendor/WasmDis.js b/devtools/client/shared/vendor/WasmDis.js
index a412de6b39..be6849d1c8 100644
--- a/devtools/client/shared/vendor/WasmDis.js
+++ b/devtools/client/shared/vendor/WasmDis.js
@@ -256,7 +256,7 @@ var DefaultNameResolver = /** @class */ (function () {
return "$elem".concat(index);
};
DefaultNameResolver.prototype.getTagName = function (index, isRef) {
- return "$event".concat(index);
+ return "$tag".concat(index);
};
DefaultNameResolver.prototype.getFunctionName = function (index, isImport, isRef) {
return (isImport ? "$import" : "$func") + index;
@@ -476,6 +476,8 @@ var WasmDisassembler = /** @class */ (function () {
return "eq";
case -20 /* TypeKind.i31ref */:
return "i31";
+ case -23 /* TypeKind.exnref */:
+ return "exnref";
case -21 /* TypeKind.structref */:
return "struct";
case -22 /* TypeKind.arrayref */:
@@ -486,8 +488,13 @@ var WasmDisassembler = /** @class */ (function () {
return "noextern";
case -15 /* TypeKind.nullref */:
return "none";
+ case -12 /* TypeKind.nullexnref */:
+ return "noexnref";
}
};
+ WasmDisassembler.prototype.refTypeToString = function (typeIndex, nullable) {
+ return this.typeToString(new WasmParser_js_1.RefType(nullable ? -29 /* TypeKind.ref_null */ : -28 /* TypeKind.ref */, typeIndex));
+ };
WasmDisassembler.prototype.typeToString = function (type) {
switch (type.kind) {
case -1 /* TypeKind.i32 */:
@@ -508,6 +515,8 @@ var WasmDisassembler = /** @class */ (function () {
return "funcref";
case -17 /* TypeKind.externref */:
return "externref";
+ case -23 /* TypeKind.exnref */:
+ return "exnref";
case -18 /* TypeKind.anyref */:
return "anyref";
case -19 /* TypeKind.eqref */:
@@ -522,6 +531,8 @@ var WasmDisassembler = /** @class */ (function () {
return "nullfuncref";
case -14 /* TypeKind.nullexternref */:
return "nullexternref";
+ case -12 /* TypeKind.nullexnref */:
+ return "nullexnref";
case -15 /* TypeKind.nullref */:
return "nullref";
case -28 /* TypeKind.ref */:
@@ -647,6 +658,7 @@ var WasmDisassembler = /** @class */ (function () {
case 3 /* OperatorCode.loop */:
case 4 /* OperatorCode.if */:
case 6 /* OperatorCode.try */:
+ case 31 /* OperatorCode.try_table */:
if (this._labelMode !== LabelMode.Depth) {
var backrefLabel_1 = {
line: this._lines.length,
@@ -665,6 +677,31 @@ var WasmDisassembler = /** @class */ (function () {
this._backrefLabels.push(backrefLabel_1);
}
this.printBlockType(operator.blockType);
+ if (operator.tryTable) {
+ for (var i = 0; i < operator.tryTable.length; i++) {
+ this.appendBuffer(" (");
+ switch (operator.tryTable[i].kind) {
+ case WasmParser_js_1.CatchHandlerKind.Catch:
+ this.appendBuffer("catch ");
+ break;
+ case WasmParser_js_1.CatchHandlerKind.CatchRef:
+ this.appendBuffer("catch_ref ");
+ break;
+ case WasmParser_js_1.CatchHandlerKind.CatchAll:
+ this.appendBuffer("catch_all ");
+ break;
+ case WasmParser_js_1.CatchHandlerKind.CatchAllRef:
+ this.appendBuffer("catch_all_ref ");
+ break;
+ }
+ if (operator.tryTable[i].tagIndex != null) {
+ var tagName = this._nameResolver.getTagName(operator.tryTable[i].tagIndex, true);
+ this.appendBuffer("".concat(tagName, " "));
+ }
+ this.appendBuffer(this.useLabel(operator.tryTable[i].depth + 1));
+ this.appendBuffer(")");
+ }
+ }
break;
case 11 /* OperatorCode.end */:
if (this._labelMode === LabelMode.Depth) {
@@ -947,9 +984,17 @@ var WasmDisassembler = /** @class */ (function () {
break;
}
case 64278 /* OperatorCode.ref_cast */:
+ case 64276 /* OperatorCode.ref_test */: {
+ var refType = this.refTypeToString(operator.refType, false);
+ this.appendBuffer(" ".concat(refType));
+ break;
+ }
case 64279 /* OperatorCode.ref_cast_null */:
- case 64276 /* OperatorCode.ref_test */:
- case 64277 /* OperatorCode.ref_test_null */:
+ case 64277 /* OperatorCode.ref_test_null */: {
+ var refType = this.refTypeToString(operator.refType, true);
+ this.appendBuffer(" ".concat(refType));
+ break;
+ }
case 64257 /* OperatorCode.struct_new_default */:
case 64256 /* OperatorCode.struct_new */:
case 64263 /* OperatorCode.array_new_default */:
@@ -1496,7 +1541,6 @@ var WasmDisassembler = /** @class */ (function () {
case 5 /* OperatorCode.else */:
case 7 /* OperatorCode.catch */:
case 25 /* OperatorCode.catch_all */:
- case 10 /* OperatorCode.unwind */:
case 24 /* OperatorCode.delegate */:
this.decreaseIndent();
break;
@@ -1510,9 +1554,9 @@ var WasmDisassembler = /** @class */ (function () {
case 3 /* OperatorCode.loop */:
case 5 /* OperatorCode.else */:
case 6 /* OperatorCode.try */:
+ case 31 /* OperatorCode.try_table */:
case 7 /* OperatorCode.catch */:
case 25 /* OperatorCode.catch_all */:
- case 10 /* OperatorCode.unwind */:
this.increaseIndent();
break;
}
diff --git a/devtools/client/shared/vendor/WasmParser.js b/devtools/client/shared/vendor/WasmParser.js
index 68397b8eeb..efa5b9a4e6 100644
--- a/devtools/client/shared/vendor/WasmParser.js
+++ b/devtools/client/shared/vendor/WasmParser.js
@@ -29,7 +29,7 @@ var __extends = (this && this.__extends) || (function () {
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
-exports.bytesToString = exports.BinaryReader = exports.Int64 = exports.TagAttribute = exports.ElementMode = exports.DataMode = exports.BinaryReaderState = exports.NameType = exports.LinkingType = exports.RelocType = exports.RefType = exports.Type = exports.FuncDef = exports.FieldDef = exports.TypeKind = exports.ExternalKind = exports.OperatorCodeNames = exports.OperatorCode = exports.SectionCode = void 0;
+exports.bytesToString = exports.BinaryReader = exports.Int64 = exports.TagAttribute = exports.ElementMode = exports.DataMode = exports.BinaryReaderState = exports.NameType = exports.LinkingType = exports.RelocType = exports.CatchHandler = exports.CatchHandlerKind = exports.RefType = exports.Type = exports.FuncDef = exports.FieldDef = exports.TypeKind = exports.ExternalKind = exports.OperatorCodeNames = exports.OperatorCode = exports.SectionCode = void 0;
// See https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md
var WASM_MAGIC_NUMBER = 0x6d736100;
var WASM_SUPPORTED_EXPERIMENTAL_VERSION = 0xd;
@@ -64,7 +64,7 @@ var OperatorCode;
OperatorCode[OperatorCode["catch"] = 7] = "catch";
OperatorCode[OperatorCode["throw"] = 8] = "throw";
OperatorCode[OperatorCode["rethrow"] = 9] = "rethrow";
- OperatorCode[OperatorCode["unwind"] = 10] = "unwind";
+ OperatorCode[OperatorCode["throw_ref"] = 10] = "throw_ref";
OperatorCode[OperatorCode["end"] = 11] = "end";
OperatorCode[OperatorCode["br"] = 12] = "br";
OperatorCode[OperatorCode["br_if"] = 13] = "br_if";
@@ -82,6 +82,7 @@ var OperatorCode;
OperatorCode[OperatorCode["drop"] = 26] = "drop";
OperatorCode[OperatorCode["select"] = 27] = "select";
OperatorCode[OperatorCode["select_with_type"] = 28] = "select_with_type";
+ OperatorCode[OperatorCode["try_table"] = 31] = "try_table";
OperatorCode[OperatorCode["local_get"] = 32] = "local_get";
OperatorCode[OperatorCode["local_set"] = 33] = "local_set";
OperatorCode[OperatorCode["local_tee"] = 34] = "local_tee";
@@ -597,8 +598,8 @@ var OperatorCode;
OperatorCode[OperatorCode["f64x2_relaxed_min"] = 1036559] = "f64x2_relaxed_min";
OperatorCode[OperatorCode["f64x2_relaxed_max"] = 1036560] = "f64x2_relaxed_max";
OperatorCode[OperatorCode["i16x8_relaxed_q15mulr_s"] = 1036561] = "i16x8_relaxed_q15mulr_s";
- OperatorCode[OperatorCode["i16x8_dot_i8x16_i7x16_s"] = 1036562] = "i16x8_dot_i8x16_i7x16_s";
- OperatorCode[OperatorCode["i32x4_dot_i8x16_i7x16_add_s"] = 1036563] = "i32x4_dot_i8x16_i7x16_add_s";
+ OperatorCode[OperatorCode["i16x8_relaxed_dot_i8x16_i7x16_s"] = 1036562] = "i16x8_relaxed_dot_i8x16_i7x16_s";
+ OperatorCode[OperatorCode["i32x4_relaxed_dot_i8x16_i7x16_add_s"] = 1036563] = "i32x4_relaxed_dot_i8x16_i7x16_add_s";
// GC proposal.
OperatorCode[OperatorCode["struct_new"] = 64256] = "struct_new";
OperatorCode[OperatorCode["struct_new_default"] = 64257] = "struct_new_default";
@@ -643,7 +644,7 @@ exports.OperatorCodeNames = [
"catch",
"throw",
"rethrow",
- "unwind",
+ "throw_ref",
"end",
"br",
"br_if",
@@ -664,7 +665,7 @@ exports.OperatorCodeNames = [
"select",
undefined,
undefined,
- undefined,
+ "try_table",
"local.get",
"local.set",
"local.tee",
@@ -1187,8 +1188,8 @@ exports.OperatorCodeNames = [
"f64x2.relaxed_min",
"f64x2.relaxed_max",
"i16x8.relaxed_q15mulr_s",
- "i16x8.dot_i8x16_i7x16_s",
- "i32x4.dot_i8x16_i7x16_add_s",
+ "i16x8.relaxed_dot_i8x16_i7x16_s",
+ "i32x4.relaxed_dot_i8x16_i7x16_add_s",
].forEach(function (s, i) {
exports.OperatorCodeNames[0xfd000 | i] = s;
});
@@ -1297,9 +1298,9 @@ exports.OperatorCodeNames = [
"array.init_data",
"array.init_elem",
"ref.test",
- "ref.test null",
+ "ref.test",
+ "ref.cast",
"ref.cast",
- "ref.cast null",
"br_on_cast",
"br_on_cast_fail",
"any.convert_extern",
@@ -1328,6 +1329,7 @@ var TypeKind;
TypeKind[TypeKind["v128"] = -5] = "v128";
TypeKind[TypeKind["i8"] = -8] = "i8";
TypeKind[TypeKind["i16"] = -9] = "i16";
+ TypeKind[TypeKind["nullexnref"] = -12] = "nullexnref";
TypeKind[TypeKind["nullfuncref"] = -13] = "nullfuncref";
TypeKind[TypeKind["nullref"] = -15] = "nullref";
TypeKind[TypeKind["nullexternref"] = -14] = "nullexternref";
@@ -1338,6 +1340,7 @@ var TypeKind;
TypeKind[TypeKind["i31ref"] = -20] = "i31ref";
TypeKind[TypeKind["structref"] = -21] = "structref";
TypeKind[TypeKind["arrayref"] = -22] = "arrayref";
+ TypeKind[TypeKind["exnref"] = -23] = "exnref";
TypeKind[TypeKind["ref"] = -28] = "ref";
TypeKind[TypeKind["ref_null"] = -29] = "ref_null";
TypeKind[TypeKind["func"] = -32] = "func";
@@ -1388,6 +1391,7 @@ var Type = exports.Type = /** @class */ (function () {
// Convenience singletons.
Type.funcref = new Type(-16 /* TypeKind.funcref */);
Type.externref = new Type(-17 /* TypeKind.externref */);
+ Type.exnref = new Type(-23 /* TypeKind.exnref */);
return Type;
}());
var RefType = /** @class */ (function (_super) {
@@ -1411,6 +1415,19 @@ var RefType = /** @class */ (function (_super) {
return RefType;
}(Type));
exports.RefType = RefType;
+var CatchHandlerKind;
+(function (CatchHandlerKind) {
+ CatchHandlerKind[CatchHandlerKind["Catch"] = 0] = "Catch";
+ CatchHandlerKind[CatchHandlerKind["CatchRef"] = 1] = "CatchRef";
+ CatchHandlerKind[CatchHandlerKind["CatchAll"] = 2] = "CatchAll";
+ CatchHandlerKind[CatchHandlerKind["CatchAllRef"] = 3] = "CatchAllRef";
+})(CatchHandlerKind = exports.CatchHandlerKind || (exports.CatchHandlerKind = {}));
+var CatchHandler = /** @class */ (function () {
+ function CatchHandler() {
+ }
+ return CatchHandler;
+}());
+exports.CatchHandler = CatchHandler;
var RelocType;
(function (RelocType) {
RelocType[RelocType["FunctionIndex_LEB"] = 0] = "FunctionIndex_LEB";
@@ -1814,11 +1831,13 @@ var BinaryReader = /** @class */ (function () {
case -9 /* TypeKind.i16 */:
case -16 /* TypeKind.funcref */:
case -17 /* TypeKind.externref */:
+ case -23 /* TypeKind.exnref */:
case -18 /* TypeKind.anyref */:
case -19 /* TypeKind.eqref */:
case -20 /* TypeKind.i31ref */:
case -14 /* TypeKind.nullexternref */:
case -13 /* TypeKind.nullfuncref */:
+ case -12 /* TypeKind.nullexnref */:
case -21 /* TypeKind.structref */:
case -22 /* TypeKind.arrayref */:
case -15 /* TypeKind.nullref */:
@@ -1989,6 +2008,7 @@ var BinaryReader = /** @class */ (function () {
case -9 /* TypeKind.i16 */:
case -16 /* TypeKind.funcref */:
case -17 /* TypeKind.externref */:
+ case -23 /* TypeKind.exnref */:
case -18 /* TypeKind.anyref */:
case -19 /* TypeKind.eqref */:
this.result = {
@@ -2936,8 +2956,8 @@ var BinaryReader = /** @class */ (function () {
case 1036559 /* OperatorCode.f64x2_relaxed_min */:
case 1036560 /* OperatorCode.f64x2_relaxed_max */:
case 1036561 /* OperatorCode.i16x8_relaxed_q15mulr_s */:
- case 1036562 /* OperatorCode.i16x8_dot_i8x16_i7x16_s */:
- case 1036563 /* OperatorCode.i32x4_dot_i8x16_i7x16_add_s */:
+ case 1036562 /* OperatorCode.i16x8_relaxed_dot_i8x16_i7x16_s */:
+ case 1036563 /* OperatorCode.i32x4_relaxed_dot_i8x16_i7x16_add_s */:
break;
default:
this.error = new Error("Unknown operator: 0x".concat(code.toString(16).padStart(4, "0")));
@@ -3109,7 +3129,7 @@ var BinaryReader = /** @class */ (function () {
}
break;
}
- var code, blockType, selectType, refType, brDepth, brTable, relativeDepth, funcIndex, typeIndex, tableIndex, localIndex, globalIndex, tagIndex, memoryAddress, literal, reserved;
+ var code, blockType, selectType, refType, brDepth, brTable, tryTable, relativeDepth, funcIndex, typeIndex, tableIndex, localIndex, globalIndex, tagIndex, memoryAddress, literal, reserved;
if (this.state === 26 /* BinaryReaderState.INIT_EXPRESSION_OPERATOR */ &&
this._sectionId === 9 /* SectionCode.Element */ &&
isExternvalElementSegmentType(this._segmentType)) {
@@ -3171,6 +3191,38 @@ var BinaryReader = /** @class */ (function () {
case 8 /* OperatorCode.throw */:
tagIndex = this.readVarInt32();
break;
+ case 31 /* OperatorCode.try_table */:
+ blockType = this.readType();
+ var tableCount = this.readVarUint32();
+ if (!this.hasBytes(2 * tableCount)) {
+ // We need at least (2 * tableCount) bytes
+ this._pos = pos;
+ return false;
+ }
+ tryTable = [];
+ for (var i = 0; i < tableCount; i++) {
+ if (!this.hasVarIntBytes()) {
+ this._pos = pos;
+ return false;
+ }
+ var kind = this.readVarUint32();
+ var tagIndex;
+ if (kind == CatchHandlerKind.Catch ||
+ kind == CatchHandlerKind.CatchRef) {
+ if (!this.hasVarIntBytes()) {
+ this._pos = pos;
+ return false;
+ }
+ tagIndex = this.readVarUint32();
+ }
+ if (!this.hasVarIntBytes()) {
+ this._pos = pos;
+ return false;
+ }
+ var depth = this.readVarUint32();
+ tryTable.push({ kind: kind, depth: depth, tagIndex: tagIndex });
+ }
+ break;
case 208 /* OperatorCode.ref_null */:
refType = this.readHeapType();
break;
@@ -3278,7 +3330,6 @@ var BinaryReader = /** @class */ (function () {
case 0 /* OperatorCode.unreachable */:
case 1 /* OperatorCode.nop */:
case 5 /* OperatorCode.else */:
- case 10 /* OperatorCode.unwind */:
case 11 /* OperatorCode.end */:
case 15 /* OperatorCode.return */:
case 25 /* OperatorCode.catch_all */:
@@ -3415,6 +3466,7 @@ var BinaryReader = /** @class */ (function () {
case 209 /* OperatorCode.ref_is_null */:
case 212 /* OperatorCode.ref_as_non_null */:
case 211 /* OperatorCode.ref_eq */:
+ case 10 /* OperatorCode.throw_ref */:
break;
default:
this.error = new Error("Unknown operator: ".concat(code));
@@ -3430,6 +3482,7 @@ var BinaryReader = /** @class */ (function () {
srcType: undefined,
brDepth: brDepth,
brTable: brTable,
+ tryTable: tryTable,
relativeDepth: relativeDepth,
tableIndex: tableIndex,
funcIndex: funcIndex,
diff --git a/devtools/client/shared/widgets/tooltip/css-compatibility-tooltip-helper.js b/devtools/client/shared/widgets/tooltip/css-compatibility-tooltip-helper.js
index 40755a212b..ee6a62d4e2 100644
--- a/devtools/client/shared/widgets/tooltip/css-compatibility-tooltip-helper.js
+++ b/devtools/client/shared/widgets/tooltip/css-compatibility-tooltip-helper.js
@@ -4,8 +4,8 @@
"use strict";
-const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
loader.lazyRequireGetter(
diff --git a/devtools/client/storage/test/browser_storage_cache_navigation.js b/devtools/client/storage/test/browser_storage_cache_navigation.js
index 5421b85028..0a7ed68484 100644
--- a/devtools/client/storage/test/browser_storage_cache_navigation.js
+++ b/devtools/client/storage/test/browser_storage_cache_navigation.js
@@ -51,7 +51,10 @@ add_task(async function () {
// Check second domain
await navigateTo(URL2);
- // Select the Cache view in order to force updating it
+ info("Waiting until Cache > example.net is available in the UI");
+ await waitUntil(() => gUI.tree.exists(["Cache", "https://example.net"]));
+
+ info("Select the Cache view in order to force updating it");
await selectTreeItem(["Cache", "https://example.net"]);
// wait for storage tree refresh, and check host
diff --git a/devtools/client/storage/test/browser_storage_cookies_navigation.js b/devtools/client/storage/test/browser_storage_cookies_navigation.js
index 3dc1406451..cd4a562a33 100644
--- a/devtools/client/storage/test/browser_storage_cookies_navigation.js
+++ b/devtools/client/storage/test/browser_storage_cookies_navigation.js
@@ -115,6 +115,12 @@ add_task(async function () {
"host of iframe in previous document (example.org) is not in the tree anymore"
);
+ // indexedDB is slightly more asynchronously fetched than the others
+ // and is emitted as a Resource to the frontend late. navigateTo isn't waiting for
+ // the full initialization of the storage panel on reload.
+ // To avoid exception when navigating back wait for indexed DB to be updated.
+ await waitUntil(() => isInTree(doc, ["indexedDB", "https://example.com"]));
+
info("Navigate backward to test bfcache navigation");
gBrowser.goBack();
await waitUntil(
diff --git a/devtools/client/styleeditor/StyleEditorUI.sys.mjs b/devtools/client/styleeditor/StyleEditorUI.sys.mjs
index e00a88c3ad..e31bd4bcc1 100644
--- a/devtools/client/styleeditor/StyleEditorUI.sys.mjs
+++ b/devtools/client/styleeditor/StyleEditorUI.sys.mjs
@@ -1400,6 +1400,10 @@ export class StyleEditorUI extends EventEmitter {
type.append(this.#panelDoc.createTextNode(`@${rule.type}\u00A0`));
if (rule.type == "layer" && rule.layerName) {
type.append(this.#panelDoc.createTextNode(`${rule.layerName}\u00A0`));
+ } else if (rule.type === "property") {
+ type.append(
+ this.#panelDoc.createTextNode(`${rule.propertyName}\u00A0`)
+ );
}
const cond = this.#panelDoc.createElementNS(HTML_NS, "span");
@@ -1549,6 +1553,7 @@ export class StyleEditorUI extends EventEmitter {
this.#loadingStyleSheets = null;
this.#root.classList.remove("loading");
+ this.emit("reloaded");
}
async #handleStyleSheetResource(resource) {
diff --git a/devtools/client/styleeditor/panel.js b/devtools/client/styleeditor/panel.js
index 5a2772d095..a7f8cf77c7 100644
--- a/devtools/client/styleeditor/panel.js
+++ b/devtools/client/styleeditor/panel.js
@@ -48,6 +48,7 @@ StyleEditorPanel.prototype = {
cssProperties
);
this.UI.on("error", this._showError);
+ this.UI.on("reloaded", () => this.emit("reloaded"));
await this.UI.initialize(options);
return this;
diff --git a/devtools/client/styleeditor/test/browser_styleeditor_at_rules_sidebar.js b/devtools/client/styleeditor/test/browser_styleeditor_at_rules_sidebar.js
index a0a9bc93fd..d106d6780e 100644
--- a/devtools/client/styleeditor/test/browser_styleeditor_at_rules_sidebar.js
+++ b/devtools/client/styleeditor/test/browser_styleeditor_at_rules_sidebar.js
@@ -39,6 +39,8 @@ waitForExplicitFinish();
add_task(async function () {
await pushPref("layout.css.container-queries.enabled", true);
+ // Enable @property rules
+ await pushPref("layout.css.properties-and-values.enabled", true);
const { ui } = await openStyleEditorForURL(TESTCASE_URI);
@@ -88,7 +90,7 @@ async function testInlineMediaEditor(ui, editor) {
is(sidebar.hidden, false, "sidebar is showing on editor with @media");
const entries = sidebar.querySelectorAll(".at-rule-label");
- is(entries.length, 6, "6 @media rules displayed in sidebar");
+ is(entries.length, 7, "7 at-rules displayed in sidebar");
await testRule({
ui,
@@ -123,7 +125,6 @@ async function testInlineMediaEditor(ui, editor) {
ui,
editor,
rule: entries[3],
- conditionText: "",
line: 16,
type: "layer",
layerName: "myLayer",
@@ -146,6 +147,15 @@ async function testInlineMediaEditor(ui, editor) {
line: 21,
type: "support",
});
+
+ await testRule({
+ ui,
+ editor,
+ rule: entries[6],
+ line: 30,
+ type: "property",
+ propertyName: "--my-property",
+ });
}
async function testMediaEditor(ui, editor) {
@@ -273,27 +283,35 @@ async function testMediaRuleAdded(ui, editor) {
* @param {StyleEditorUI} options.ui
* @param {StyleSheetEditor} options.editor: The editor the rule is displayed in
* @param {Element} options.rule: The rule element in the media sidebar
- * @param {String} options.conditionText: media query condition text
+ * @param {String} options.conditionText: at-rule condition text (for @media, @container, @support)
* @param {Boolean} options.matches: Whether or not the document matches the rule
* @param {String} options.layerName: Optional name of the @layer
+ * @param {String} options.propertyName: Name of the @property if type is "property"
* @param {Number} options.line: Line of the rule
- * @param {String} options.type: The type of the rule (container, layer, media, support ).
+ * @param {String} options.type: The type of the rule (container, layer, media, support, property ).
* Defaults to "media".
*/
async function testRule({
ui,
editor,
rule,
- conditionText,
+ conditionText = "",
matches,
layerName,
+ propertyName,
line,
type = "media",
}) {
const atTypeEl = rule.querySelector(".at-rule-type");
+ let name;
+ if (type === "layer") {
+ name = layerName;
+ } else if (type === "property") {
+ name = propertyName;
+ }
is(
atTypeEl.textContent,
- `@${type}\u00A0${layerName ? `${layerName}\u00A0` : ""}`,
+ `@${type}\u00A0${name ? `${name}\u00A0` : ""}`,
"label for at-rule type is correct"
);
diff --git a/devtools/client/styleeditor/test/media-rules.html b/devtools/client/styleeditor/test/media-rules.html
index 76725bfb54..b74d97f6b2 100644
--- a/devtools/client/styleeditor/test/media-rules.html
+++ b/devtools/client/styleeditor/test/media-rules.html
@@ -2,6 +2,7 @@
<html>
<head>
<meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="simple.css"/>
<link rel="stylesheet" href="media-rules.css"/>
<!-- This stylesheet is needed to ensure we cover the fix for Bug 1779043 -->
@@ -38,6 +39,12 @@
}
}
}
+
+ @property --my-property {
+ syntax: "<color>";
+ inherits: true;
+ initial-value: #f06;
+ }
</style>
</head>
<body>
diff --git a/devtools/client/themes/dark-theme.css b/devtools/client/themes/dark-theme.css
index 8433bc75c4..cd1b58e36e 100644
--- a/devtools/client/themes/dark-theme.css
+++ b/devtools/client/themes/dark-theme.css
@@ -261,12 +261,16 @@ div.CodeMirror span.marked-text {
}
-.cm-s-mozilla .empty-line .CodeMirror-linenumber {
+.cm-s-mozilla .empty-line .CodeMirror-linenumber,
+/* Codemirror 6 */
+.cm-editor .cm-gutterElement.empty-line {
color: var(--grey-50);
}
/* Blackboxing lines */
-.CodeMirror-lines .blackboxed-line :is(span, .cm-comment, .CodeMirror-gutter-elt) {
+.CodeMirror-lines .blackboxed-line :is(span, .cm-comment, .CodeMirror-gutter-elt),
+/* Codemirror 6 */
+.cm-gutterElement.blackboxed-line, .cm-line.blackboxed-line span[class^="tok-"] {
color: #806414cc;
}
diff --git a/devtools/client/themes/images/whatsnew.svg b/devtools/client/themes/images/whatsnew.svg
new file mode 100644
index 0000000000..b77d0165a6
--- /dev/null
+++ b/devtools/client/themes/images/whatsnew.svg
@@ -0,0 +1,10 @@
+<!-- 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/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M2 13.76A1.23 1.23 0 0 0 3.24 15H7V9H2z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M9 9v6h3.76A1.23 1.23 0 0 0 14 13.76V9H9z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M1 5v3h6V4H2a1 1 0 0 0-1 1z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M14 4H9v4h6V5a1 1 0 0 0-1-1z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M10.05.41A1.34 1.34 0 0 0 8 1a1.35 1.35 0 0 0-2-.59C5.2 1.08 4.91 2.48 8 4c3.09-1.52 2.8-2.92 2.05-3.59z"/>
+</svg>
diff --git a/devtools/client/themes/light-theme.css b/devtools/client/themes/light-theme.css
index d54bfffef3..979999bd31 100644
--- a/devtools/client/themes/light-theme.css
+++ b/devtools/client/themes/light-theme.css
@@ -248,12 +248,16 @@ div.CodeMirror span.marked-text {
margin-inline-end: -1px;
}
-.cm-s-mozilla .empty-line .CodeMirror-linenumber {
+.cm-s-mozilla .empty-line .CodeMirror-linenumber,
+/* Codemirror 6 */
+.cm-editor .cm-gutterElement.empty-line {
color: var(--grey-40);
}
/* Blackboxing lines */
-.CodeMirror-lines .blackboxed-line :is(span, .cm-comment, .CodeMirror-gutter-elt) {
+.CodeMirror-lines .blackboxed-line :is(span, .cm-comment, .CodeMirror-gutter-elt),
+/* Codemirror 6 */
+.cm-gutterElement.blackboxed-line, .cm-line.blackboxed-line span[class^="tok-"] {
color: #806414cc;
}
diff --git a/devtools/client/themes/rules.css b/devtools/client/themes/rules.css
index 72ca35fff7..c3079e3d62 100644
--- a/devtools/client/themes/rules.css
+++ b/devtools/client/themes/rules.css
@@ -825,6 +825,10 @@
cursor: text;
}
+.ruleview-variable {
+ color: var(--theme-highlight-blue);
+}
+
.ruleview-selector-separator,
.ruleview-selector.unmatched,
.ruleview-unmatched-variable,
diff --git a/devtools/client/webconsole/components/Output/message-types/JSTracerTrace.js b/devtools/client/webconsole/components/Output/message-types/JSTracerTrace.js
index 241fa15bd1..ed74728777 100644
--- a/devtools/client/webconsole/components/Output/message-types/JSTracerTrace.js
+++ b/devtools/client/webconsole/components/Output/message-types/JSTracerTrace.js
@@ -60,7 +60,7 @@ function JSTracerTrace(props) {
// Attributes specific to function call returns
returnedValue,
relatedTraceId,
- // See tracer.jsm FRAME_EXIT_REASONS
+ // See tracer.sys.mjs FRAME_EXIT_REASONS
why,
// Attributes specific to DOM Mutations
diff --git a/devtools/client/webconsole/test/browser/_jsterm.toml b/devtools/client/webconsole/test/browser/_jsterm.toml
index c9be46216a..fd23edd9c6 100644
--- a/devtools/client/webconsole/test/browser/_jsterm.toml
+++ b/devtools/client/webconsole/test/browser/_jsterm.toml
@@ -28,7 +28,7 @@ support-files = [
"!/devtools/client/framework/browser-toolbox/test/helpers-browser-toolbox.js",
"!/devtools/client/shared/test/telemetry-test-helpers.js",
"!/devtools/client/shared/test/highlighter-test-actor.js",
- "../../../../../toolkit/components/reader/test/readerModeArticle.html",
+ "../../../../../toolkit/components/reader/tests/browser/readerModeArticle.html",
]
["browser_jsterm_add_edited_input_to_history.js"]
diff --git a/devtools/client/webconsole/test/browser/browser_console_webconsole_private_browsing.js b/devtools/client/webconsole/test/browser/browser_console_webconsole_private_browsing.js
index 0fed8c03c5..96033f84d8 100644
--- a/devtools/client/webconsole/test/browser/browser_console_webconsole_private_browsing.js
+++ b/devtools/client/webconsole/test/browser/browser_console_webconsole_private_browsing.js
@@ -141,7 +141,7 @@ add_task(async function () {
info("close the private window and check if private messages are removed");
const onPrivateMessagesCleared = hud.ui.once("private-messages-cleared");
- privateWindow.BrowserTryToCloseWindow();
+ privateWindow.BrowserCommands.tryToCloseWindow();
await onPrivateMessagesCleared;
ok(
diff --git a/devtools/client/webconsole/test/browser/browser_jsterm_await_paused.js b/devtools/client/webconsole/test/browser/browser_jsterm_await_paused.js
index 421837e9eb..f0dbca4dd8 100644
--- a/devtools/client/webconsole/test/browser/browser_jsterm_await_paused.js
+++ b/devtools/client/webconsole/test/browser/browser_jsterm_await_paused.js
@@ -12,7 +12,7 @@ add_task(async function () {
await pushPref("devtools.debugger.features.map-await-expression", true);
// Force the split console to be closed.
- await pushPref("devtools.toolbox.splitconsoleEnabled", false);
+ await pushPref("devtools.toolbox.splitconsole.open", false);
const hud = await openNewTabAndConsole(TEST_URI);
const pauseExpression = `(() => {
diff --git a/devtools/client/webconsole/test/browser/browser_jsterm_eager_evaluation.js b/devtools/client/webconsole/test/browser/browser_jsterm_eager_evaluation.js
index 194cc64531..dae99c1961 100644
--- a/devtools/client/webconsole/test/browser/browser_jsterm_eager_evaluation.js
+++ b/devtools/client/webconsole/test/browser/browser_jsterm_eager_evaluation.js
@@ -310,7 +310,7 @@ add_task(async function () {
EventUtils.synthesizeKey("KEY_ArrowDown");
// Navigates to the XMLDocument item in the popup
- await waitForEagerEvaluationResult(hud, `function ()`);
+ await waitForEagerEvaluationResult(hud, `function XMLDocument()`);
onPopupClose = popup.once("popup-closed");
EventUtils.sendString(" ");
diff --git a/devtools/client/webconsole/test/browser/browser_jsterm_editor_reverse_search_keyboard_navigation.js b/devtools/client/webconsole/test/browser/browser_jsterm_editor_reverse_search_keyboard_navigation.js
index 0b9b828ce3..bbdc251107 100644
--- a/devtools/client/webconsole/test/browser/browser_jsterm_editor_reverse_search_keyboard_navigation.js
+++ b/devtools/client/webconsole/test/browser/browser_jsterm_editor_reverse_search_keyboard_navigation.js
@@ -6,7 +6,7 @@
// Ensure keyboard navigation works in editor mode and does
// not trigger reader mode (See 1682340).
-const TEST_URI = `http://example.com/browser/toolkit/components/reader/test/readerModeArticle.html`;
+const TEST_URI = `http://example.com/browser/toolkit/components/reader/tests/browser/readerModeArticle.html`;
const isMacOS = AppConstants.platform === "macosx";
add_task(async function () {
@@ -42,7 +42,7 @@ add_task(async function () {
await wait(1000);
is(
readerModeButtonEl.getAttribute("readeractive"),
- "",
+ null,
"reader mode wasn't activated"
);
@@ -72,7 +72,7 @@ add_task(async function () {
await wait(1000);
is(
readerModeButtonEl.getAttribute("readeractive"),
- "",
+ null,
"reader mode still wasn't activated"
);
diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_console_api_iframe.js b/devtools/client/webconsole/test/browser/browser_webconsole_console_api_iframe.js
index 9670312e85..977710b78e 100644
--- a/devtools/client/webconsole/test/browser/browser_webconsole_console_api_iframe.js
+++ b/devtools/client/webconsole/test/browser/browser_webconsole_console_api_iframe.js
@@ -17,7 +17,7 @@ add_task(async function () {
ok(true, "The initial message is displayed in the console");
// Create a promise for the message logged after the reload.
const onMessage = waitForMessageByType(hud, loggedString, ".console-api");
- BrowserReload();
+ BrowserCommands.reload();
await onMessage;
ok(true, "The message is also displayed after a page reload");
});
diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_cors_errors.js b/devtools/client/webconsole/test/browser/browser_webconsole_cors_errors.js
index b29da33bab..c20991c1bf 100644
--- a/devtools/client/webconsole/test/browser/browser_webconsole_cors_errors.js
+++ b/devtools/client/webconsole/test/browser/browser_webconsole_cors_errors.js
@@ -6,6 +6,9 @@
"use strict";
+// The test can take a bit long on slow machines.
+requestLongerTimeout(2);
+
const TEST_URI =
"http://example.com/browser/devtools/client/webconsole/test/browser/test-network-request.html";
const BASE_CORS_ERROR_URL =
@@ -40,6 +43,7 @@ add_task(async function () {
await checkCorsMessage(hud, message, "CORSDisabled");
await pushPref("content.cors.disable", false);
+ await clearOutput(hud);
info("Test CORSPreflightDidNotSucceed");
onCorsMessage = waitForMessageByType(
hud,
@@ -50,6 +54,7 @@ add_task(async function () {
message = await onCorsMessage;
await checkCorsMessage(hud, message, "CORSPreflightDidNotSucceed");
+ await clearOutput(hud);
info("Test CORS did not succeed");
onCorsMessage = waitForMessageByType(
hud,
@@ -60,6 +65,7 @@ add_task(async function () {
message = await onCorsMessage;
await checkCorsMessage(hud, message, "CORSDidNotSucceed");
+ await clearOutput(hud);
info("Test CORSExternalRedirectNotAllowed");
onCorsMessage = waitForMessageByType(
hud,
@@ -70,6 +76,7 @@ add_task(async function () {
message = await onCorsMessage;
await checkCorsMessage(hud, message, "CORSExternalRedirectNotAllowed");
+ await clearOutput(hud);
info("Test CORSMissingAllowOrigin");
onCorsMessage = waitForMessageByType(
hud,
@@ -82,6 +89,7 @@ add_task(async function () {
message = await onCorsMessage;
await checkCorsMessage(hud, message, "CORSMissingAllowOrigin");
+ await clearOutput(hud);
info("Test CORSMultipleAllowOriginNotAllowed");
onCorsMessage = waitForMessageByType(
hud,
@@ -94,6 +102,7 @@ add_task(async function () {
message = await onCorsMessage;
await checkCorsMessage(hud, message, "CORSMultipleAllowOriginNotAllowed");
+ await clearOutput(hud);
info("Test CORSAllowOriginNotMatchingOrigin");
onCorsMessage = waitForMessageByType(
hud,
@@ -107,6 +116,7 @@ add_task(async function () {
message = await onCorsMessage;
await checkCorsMessage(hud, message, "CORSAllowOriginNotMatchingOrigin");
+ await clearOutput(hud);
info("Test CORSNotSupportingCredentials");
onCorsMessage = waitForMessageByType(
hud,
@@ -118,6 +128,7 @@ add_task(async function () {
message = await onCorsMessage;
await checkCorsMessage(hud, message, "CORSNotSupportingCredentials");
+ await clearOutput(hud);
info("Test CORSMethodNotFound");
onCorsMessage = waitForMessageByType(
hud,
@@ -129,6 +140,7 @@ add_task(async function () {
message = await onCorsMessage;
await checkCorsMessage(hud, message, "CORSMethodNotFound");
+ await clearOutput(hud);
info("Test CORSMissingAllowCredentials");
onCorsMessage = waitForMessageByType(
hud,
@@ -140,6 +152,7 @@ add_task(async function () {
message = await onCorsMessage;
await checkCorsMessage(hud, message, "CORSMissingAllowCredentials");
+ await clearOutput(hud);
info("Test CORSInvalidAllowMethod");
onCorsMessage = waitForMessageByType(
hud,
@@ -151,6 +164,7 @@ add_task(async function () {
message = await onCorsMessage;
await checkCorsMessage(hud, message, "CORSInvalidAllowMethod");
+ await clearOutput(hud);
info("Test CORSInvalidAllowHeader");
onCorsMessage = waitForMessageByType(
hud,
@@ -162,6 +176,7 @@ add_task(async function () {
message = await onCorsMessage;
await checkCorsMessage(hud, message, "CORSInvalidAllowHeader");
+ await clearOutput(hud);
info("Test CORSMissingAllowHeaderFromPreflight");
onCorsMessage = waitForMessageByType(
hud,
diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_split_escape_key.js b/devtools/client/webconsole/test/browser/browser_webconsole_split_escape_key.js
index 84c6935510..8127ae1709 100644
--- a/devtools/client/webconsole/test/browser/browser_webconsole_split_escape_key.js
+++ b/devtools/client/webconsole/test/browser/browser_webconsole_split_escape_key.js
@@ -53,4 +53,27 @@ add_task(async function () {
await onSplitConsoleEvent;
ok(!toolbox.splitConsole, "Split console is hidden.");
+
+ info("Test if Split console Shortcut stops working when it's disabled.");
+
+ info("Setting the Pref to false and sending ESCAPE key.");
+ await pushPref("devtools.toolbox.splitconsole.enabled", false);
+ // pushPref doesn't trigger _prefChanged of toolbox-options.js, so we invoke the toolbox setting update manually
+ toolbox.updateIsSplitConsoleEnabled();
+ const onSplitConsole = toolbox.once("split-console");
+ const onTimeout = wait(1000).then(() => "TIMEOUT");
+ EventUtils.sendKey("ESCAPE", toolbox.win);
+ const raceResult = await Promise.race([onSplitConsole, onTimeout]);
+ is(raceResult, "TIMEOUT", "split-console wasn't emitted");
+
+ ok(!toolbox.splitConsole, "Split console didn't get Triggered.");
+
+ info("Setting the Pref to true and sending ESCAPE key again.");
+ await pushPref("devtools.toolbox.splitconsole.enabled", true);
+ toolbox.updateIsSplitConsoleEnabled();
+ const onSplitConsoleReadyAgain = toolbox.once("split-console");
+ EventUtils.sendKey("ESCAPE", toolbox.win);
+ await onSplitConsoleReadyAgain;
+
+ ok(toolbox.splitConsole, "Split console Shortcut is working again.");
});
diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_split_persist.js b/devtools/client/webconsole/test/browser/browser_webconsole_split_persist.js
index 2442b64b5b..2f037c6ee0 100644
--- a/devtools/client/webconsole/test/browser/browser_webconsole_split_persist.js
+++ b/devtools/client/webconsole/test/browser/browser_webconsole_split_persist.js
@@ -99,7 +99,7 @@ add_task(async function () {
});
function getVisiblePrefValue() {
- return Services.prefs.getBoolPref("devtools.toolbox.splitconsoleEnabled");
+ return Services.prefs.getBoolPref("devtools.toolbox.splitconsole.open");
}
function getHeightPrefValue() {
diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_console_api.js b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_console_api.js
index 9718a8efd1..86e62b173d 100644
--- a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_console_api.js
+++ b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_console_api.js
@@ -68,6 +68,11 @@ async function generateConsoleApiStubs() {
await commands.targetCommand.startListening();
const resourceCommand = commands.resourceCommand;
+ // Ensure waiting for sources in order to populate message.sourceId correctly.
+ await resourceCommand.watchResources([resourceCommand.TYPES.SOURCE], {
+ onAvailable() {},
+ });
+
// The resource-watcher only supports a single call to watch/unwatch per
// instance, so we attach a unique watch callback, which will forward the
// resource to `handleConsoleMessage`, dynamically updated for each command.
diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_page_error.js b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_page_error.js
index d6610b7309..50029a3139 100644
--- a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_page_error.js
+++ b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_page_error.js
@@ -70,6 +70,11 @@ async function generatePageErrorStubs() {
await commands.targetCommand.startListening();
const resourceCommand = commands.resourceCommand;
+ // Ensure waiting for sources in order to populate message.sourceId correctly.
+ await resourceCommand.watchResources([resourceCommand.TYPES.SOURCE], {
+ onAvailable() {},
+ });
+
// The resource-watcher only supports a single call to watch/unwatch per
// instance, so we attach a unique watch callback, which will forward the
// resource to `handleErrorMessage`, dynamically updated for each command.
diff --git a/devtools/client/webconsole/test/chrome/head.js b/devtools/client/webconsole/test/chrome/head.js
index 2f984d564d..3f4988c2d0 100644
--- a/devtools/client/webconsole/test/chrome/head.js
+++ b/devtools/client/webconsole/test/chrome/head.js
@@ -4,8 +4,8 @@
"use strict";
-var { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+var { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
var { require: browserRequire } = BrowserLoader({
diff --git a/devtools/client/webconsole/webconsole-ui.js b/devtools/client/webconsole/webconsole-ui.js
index a12f1f3983..b562752ccb 100644
--- a/devtools/client/webconsole/webconsole-ui.js
+++ b/devtools/client/webconsole/webconsole-ui.js
@@ -10,8 +10,8 @@ const {
l10n,
} = require("resource://devtools/client/webconsole/utils/messages.js");
-const { BrowserLoader } = ChromeUtils.import(
- "resource://devtools/shared/loader/browser-loader.js"
+const { BrowserLoader } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/browser-loader.sys.mjs"
);
const {
getAdHocFrontOrPrimitiveGrip,