tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 04a772b0419369510f76dd39a8a4a1a1e8b9a11c
parent 0af60e3c664ea39b269fb29653472ef77550f7c8
Author: Alexandru Marc <amarc@mozilla.com>
Date:   Tue, 30 Sep 2025 20:58:30 +0300

Revert (Bug 1979902, Bug 1978284) for causing dt failures @ webconsole/index.html

This reverts commit 6d6b71f2b65384bf812007b9dee9b2a9c899efc2.

Revert "Bug 1978284 - [devtools] Migrate Source preview to Cm6 r=devtools-reviewers,nchevobbe,perftest-reviewers,tschuster,afinder"

This reverts commit e835bebd765921bb897870f6c5f861761f4e3289.

Diffstat:
Mdevtools/client/debugger/src/components/Editor/Editor.css | 20++++++++++++++++++++
Mdevtools/client/debugger/src/utils/editor/create-editor.js | 2--
Mdevtools/client/netmonitor/index.html | 2+-
Mdevtools/client/netmonitor/src/components/TabboxPanel.js | 5-----
Mdevtools/client/netmonitor/src/components/Toolbar.js | 2+-
Mdevtools/client/netmonitor/src/components/previews/SourcePreview.js | 125+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Mdevtools/client/netmonitor/src/components/request-details/RequestPanel.js | 5+----
Mdevtools/client/netmonitor/src/components/request-details/ResponsePanel.js | 3---
Mdevtools/client/netmonitor/test/browser_net_brotli.js | 2+-
Mdevtools/client/netmonitor/test/browser_net_chunked-response.js | 2+-
Mdevtools/client/netmonitor/test/browser_net_complex-params.js | 15+++++++++------
Mdevtools/client/netmonitor/test/browser_net_content-type.js | 2+-
Mdevtools/client/netmonitor/test/browser_net_cyrillic-01.js | 2+-
Mdevtools/client/netmonitor/test/browser_net_cyrillic-02.js | 4++--
Mdevtools/client/netmonitor/test/browser_net_delayed-response.js | 5++++-
Mdevtools/client/netmonitor/test/browser_net_json-b64.js | 4++--
Mdevtools/client/netmonitor/test/browser_net_json-empty.js | 7+++++--
Mdevtools/client/netmonitor/test/browser_net_json-long.js | 4++--
Mdevtools/client/netmonitor/test/browser_net_json-malformed.js | 4++--
Mdevtools/client/netmonitor/test/browser_net_json-null.js | 14++++++++++----
Mdevtools/client/netmonitor/test/browser_net_json-numbers.js | 7+++++--
Mdevtools/client/netmonitor/test/browser_net_json-xssi-protection.js | 22++++++++++++----------
Mdevtools/client/netmonitor/test/browser_net_json_custom_mime.js | 4++--
Mdevtools/client/netmonitor/test/browser_net_json_text_mime.js | 4++--
Mdevtools/client/netmonitor/test/browser_net_jsonp.js | 6+++---
Mdevtools/client/netmonitor/test/browser_net_large-response.js | 6+++---
Mdevtools/client/netmonitor/test/browser_net_post-data-json-payloads.js | 6+++---
Mdevtools/client/netmonitor/test/browser_net_post-data-raw-payloads-with-upload-stream-headers.js | 4++--
Mdevtools/client/netmonitor/test/browser_net_post-data.js | 4++--
Mdevtools/client/netmonitor/test/browser_net_raw_response.js | 2+-
Mdevtools/client/netmonitor/test/browser_net_search-results.js | 8++++----
Mdevtools/client/netmonitor/test/browser_net_truncate-post-data.js | 8+++++---
Mdevtools/client/netmonitor/test/browser_net_zstd.js | 2+-
Mdevtools/client/netmonitor/test/head.js | 13+++++--------
Mdevtools/client/shared/sourceeditor/codemirror/mozilla.css | 59++++-------------------------------------------------------
Mdevtools/client/shared/sourceeditor/editor.js | 16++--------------
Mdevtools/client/webconsole/test/browser/browser_webconsole_network_messages_expand.js | 6+++---
Mdevtools/client/webconsole/test/browser/browser_webconsole_network_messages_expand_before_updates.js | 6+++---
Mdevtools/client/webconsole/test/browser/browser_webconsole_network_messages_html_preview.js | 2+-
Mdom/security/nsContentSecurityUtils.cpp | 2--
Mtesting/talos/talos/tests/devtools/addon/content/tests/netmonitor/netmonitor-helpers.js | 2+-
41 files changed, 199 insertions(+), 219 deletions(-)

diff --git a/devtools/client/debugger/src/components/Editor/Editor.css b/devtools/client/debugger/src/components/Editor/Editor.css @@ -7,6 +7,7 @@ --debug-line-error-border: rgb(255, 0, 0); --debug-expression-error-background: rgba(231, 116, 113, 0.3); --line-exception-background: hsl(344, 73%, 97%); + --highlight-line-duration: 5000ms; } .theme-dark .editor-wrapper { @@ -177,6 +178,25 @@ html[dir="rtl"] .editor-mount { .new-debug-line-error .CodeMirror-activeline-background { display: none; } +.highlight-line .CodeMirror-line, +/* For CM6 */ +.cm-editor .cm-line.highlight-line { + animation-name: fade-highlight-out; + animation-duration: var(--highlight-line-duration); + animation-timing-function: ease-out; + animation-fill-mode: forwards; +} + +@keyframes fade-highlight-out { + 0%, + 30% { + /* We want to use a color with some transparency so text selection is visible through it */ + background-color: var(--theme-contrast-background-alpha); + } + 100% { + background-color: transparent; + } +} .visible { visibility: visible; diff --git a/devtools/client/debugger/src/utils/editor/create-editor.js b/devtools/client/debugger/src/utils/editor/create-editor.js @@ -21,8 +21,6 @@ export function createEditor(config = { cm6: false }) { return new SourceEditor({ mode: SourceEditor.modes.javascript, foldGutter: features.codeFolding, - disableSearchAddon: false, - useSearchAddonPanel: false, enableCodeFolding: features.codeFolding, readOnly: true, lineNumbers: true, diff --git a/devtools/client/netmonitor/index.html b/devtools/client/netmonitor/index.html @@ -6,7 +6,7 @@ <head> <meta http-equiv="Content-Security-Policy" - content="default-src chrome: resource:; img-src chrome: resource: data:; style-src chrome: 'unsafe-inline';" + content="default-src chrome: resource:; img-src chrome: resource: data:;" /> <link rel="stylesheet" diff --git a/devtools/client/netmonitor/src/components/TabboxPanel.js b/devtools/client/netmonitor/src/components/TabboxPanel.js @@ -109,11 +109,6 @@ class TabboxPanel extends Component { closeOnEsc(event) { if (event.key == "Escape") { event.preventDefault(); - // Don't take focus when the keyboard shortcut is triggered in a CodeMirror instance, - // so the CodeMirror search UI is closed. - if (event.target.closest(".cm-search")) { - return; - } this.props.openNetworkDetails(false); } } diff --git a/devtools/client/netmonitor/src/components/Toolbar.js b/devtools/client/netmonitor/src/components/Toolbar.js @@ -294,7 +294,7 @@ class Toolbar extends Component { onSearchBoxFocusKeyboardShortcut(event) { // Don't take focus when the keyboard shortcut is triggered in a CodeMirror instance, // so the CodeMirror search UI is displayed. - return !!event.target.closest(".cm-editor"); + return !!event.target.closest(".CodeMirror"); } onSearchBoxFocus() { diff --git a/devtools/client/netmonitor/src/components/previews/SourcePreview.js b/devtools/client/netmonitor/src/components/previews/SourcePreview.js @@ -31,13 +31,12 @@ class SourcePreview extends Component { // Reset target search result that has been used for navigation in this panel. // This is done to avoid second navigation the next time. resetTargetSearchResult: PropTypes.func, - url: PropTypes.string, }; } componentDidMount() { - this.loadEditor(); - this.updateEditor(); + const { mimeType, text } = this.props; + this.loadEditor(mimeType, text); } shouldComponentUpdate(nextProps) { @@ -49,10 +48,11 @@ class SourcePreview extends Component { } componentDidUpdate(prevProps) { - const { targetSearchResult, text } = this.props; + const { mimeType, targetSearchResult, text } = this.props; + if (prevProps.text !== text) { // When updating from editor to editor - this.updateEditor(); + this.updateEditor(mimeType, text); } else if (prevProps.targetSearchResult !== targetSearchResult) { this.findSearchResult(); } @@ -67,90 +67,102 @@ class SourcePreview extends Component { return Editor.modes[lang]; } - loadEditor() { + loadEditor(mimeType, text) { this.editor = new Editor({ - cm6: true, lineNumbers: true, lineWrapping: false, - disableSearchAddon: false, - useSearchAddonPanel: true, - mode: null, // Disable auto syntax detection, but then we set the mode later + mode: null, // Disable auto syntax detection, but then we set mode asynchronously readOnly: true, theme: "mozilla", - value: "", + value: text, }); - this.editor.appendToLocalElement(this.refs.editorElement); - // Used for netmonitor tests - window.codeMirrorSourceEditorTestInstance = this.editor; + // Delay to CodeMirror initialization content to prevent UI freezing + this.editorTimeout = setTimeout(() => { + this.editorTimeout = null; + this.editor.appendToLocalElement(this.refs.editorElement); + + // CodeMirror's setMode() (syntax highlight) is the performance bottleneck when + // processing large content, so we enable it asynchronously within the setTimeout + // to avoid UI blocking. (rendering source code -> drawing syntax highlight) + this.editorSetModeTimeout = setTimeout(() => { + this.editorSetModeTimeout = null; + const mode = this.getSourceEditorModeForMimetype(mimeType); + this.editor.setMode(mode); + this.findSearchResult(); + }); + }); } - async updateEditor() { - const { mimeType, text, url } = this.props; + updateEditor(mimeType, text) { + // Reset the existed 'mode' attribute in order to make setText() process faster + // to prevent drawing unnecessary syntax highlight. if (this?.editor?.hasCodeMirror) { - const mode = this.getSourceEditorModeForMimetype(mimeType); - await this.editor.setMode(mode); - await this.editor.setText(text, url); - // When navigating from the netmonitor search, find and highlight the - // the current search result. - await this.findSearchResult(); + this.editor.setMode(null); + this.editor.setText(text); } + + if (this.editorSetModeTimeout) { + clearTimeout(this.editorSetModeTimeout); + } + + // CodeMirror's setMode() (syntax highlight) is the performance bottleneck when + // processing large content, so we enable it asynchronously within the setTimeout + // to avoid UI blocking. (rendering source code -> drawing syntax highlight) + this.editorSetModeTimeout = setTimeout(() => { + this.editorSetModeTimeout = null; + const mode = this.getSourceEditorModeForMimetype(mimeType); + this.editor.setMode(mode); + this.findSearchResult(); + }); } unloadEditor() { + clearTimeout(this.editorTimeout); + clearTimeout(this.editorSetModeTimeout); if (this.editor) { this.editor.destroy(); this.editor = null; } } - async findSearchResult() { + findSearchResult() { const { targetSearchResult, resetTargetSearchResult } = this.props; + if (targetSearchResult?.line) { const { line } = targetSearchResult; // scroll the editor to center the line // with the target search result if (this.editor) { - await this.editor.scrollTo(line, 0); - await this.editor.setCursorAt(line - 1, 0); - - // Highlight line - this.editor.setLineContentMarker({ - id: this.editor.markerTypes.HIGHLIGHT_LINE_MARKER, - lineClassName: "highlight-line", - lines: [{ line }], - }); - this.clearHighlightLineAfterDuration(); + this.editor.setCursor({ line: line - 1 }, "center"); } } resetTargetSearchResult(); } - clearHighlightLineAfterDuration() { - const editorContainer = document.querySelector(".editor-row-container"); - - if (editorContainer === null) { - return; - } - - const duration = parseInt( - getComputedStyle(editorContainer).getPropertyValue( - "--highlight-line-duration" - ), - 10 - ); + // Scroll to specified line if the user clicks on search results. + scrollToLine(element) { + const { targetSearchResult, resetTargetSearchResult } = this.props; - const highlightTimeout = setTimeout(() => { - if (!this.editor) { - return; + // The following code is responsible for scrolling given line + // to visible view-port. + // It gets the <div> child element representing the target + // line (by index) and uses `scrollIntoView` API to make sure + // it's visible to the user. + if (element && targetSearchResult && targetSearchResult.line) { + const child = element.children[targetSearchResult.line - 1]; + if (child) { + const range = document.createRange(); + range.selectNode(child); + document.getSelection().addRange(range); + child.scrollIntoView({ block: "center" }); } - clearTimeout(highlightTimeout); - this.editor.removeLineContentMarker("highlight-line-marker"); - }, duration); + resetTargetSearchResult(); + } } - render() { + renderEditor() { return div( { className: "editor-row-container" }, div({ @@ -159,6 +171,13 @@ class SourcePreview extends Component { }) ); } + + render() { + return div( + { key: "EDITOR_CONFIG", className: "editor-row-container" }, + this.renderEditor() + ); + } } module.exports = connect(null, dispatch => ({ diff --git a/devtools/client/netmonitor/src/components/request-details/RequestPanel.js b/devtools/client/netmonitor/src/components/request-details/RequestPanel.js @@ -189,7 +189,7 @@ class RequestPanel extends Component { render() { const { request, targetSearchResult } = this.props; const { filterText, rawRequestPayloadDisplayed } = this.state; - const { formDataSections, mimeType, requestPostData, url } = request; + const { formDataSections, mimeType, requestPostData } = request; const postData = requestPostData ? requestPostData.postData?.text : null; if ((!formDataSections || formDataSections.length === 0) && !postData) { @@ -212,7 +212,6 @@ class RequestPanel extends Component { filterText, targetSearchResult, defaultSelectFirstNode: false, - url, }; requestPayloadLabel = REQUEST_FORM_DATA; hasFormattedDisplay = true; @@ -243,7 +242,6 @@ class RequestPanel extends Component { filterText, targetSearchResult, defaultSelectFirstNode: false, - url, }; requestPayloadLabel = JSON_SCOPE_NAME; hasFormattedDisplay = true; @@ -260,7 +258,6 @@ class RequestPanel extends Component { text: postData, mimeType: mimeType?.replace(/;.+/, ""), targetSearchResult, - url, }; requestPayloadLabel = REQUEST_POST_PAYLOAD; } diff --git a/devtools/client/netmonitor/src/components/request-details/ResponsePanel.js b/devtools/client/netmonitor/src/components/request-details/ResponsePanel.js @@ -319,7 +319,6 @@ class ResponsePanel extends Component { defaultSelectFirstNode: false, mode: MODE.LONG, useBaseTreeViewExpand: true, - url, }; hasFormattedDisplay = true; } else if (Filters.html(this.props.request)) { @@ -335,7 +334,6 @@ class ResponsePanel extends Component { text, mimeType: json ? "application/json" : mimeType.replace(/;.+/, ""), targetSearchResult, - url, }; } return { @@ -346,7 +344,6 @@ class ResponsePanel extends Component { json, responsePayloadLabel, xssiStrippedCharsInfoBox, - url, }; } diff --git a/devtools/client/netmonitor/test/browser_net_brotli.js b/devtools/client/netmonitor/test/browser_net_brotli.js @@ -55,7 +55,7 @@ add_task(async function () { } ); - const wait = waitForDOM(document, ".cm-content"); + const wait = waitForDOM(document, ".CodeMirror-code"); const onResponseContent = monitor.panelWin.api.once( TEST_EVENTS.RECEIVED_RESPONSE_CONTENT ); diff --git a/devtools/client/netmonitor/test/browser_net_chunked-response.js b/devtools/client/netmonitor/test/browser_net_chunked-response.js @@ -85,7 +85,7 @@ add_task(async function () { info("Open the response panel and wait for initial chunk of the data"); const waitForResponsePanel = waitForDOM( document, - "#response-panel .cm-content" + "#response-panel .CodeMirror-code" ); store.dispatch(Actions.toggleNetworkDetails()); clickOnSidebarTab(document, "response"); diff --git a/devtools/client/netmonitor/test/browser_net_complex-params.js b/devtools/client/netmonitor/test/browser_net_complex-params.js @@ -146,7 +146,7 @@ async function testRequestWithFormattedView( "The request params box should be displayed." ); Assert.strictEqual( - tabpanel.querySelector(".cm-content"), + tabpanel.querySelector(".CodeMirror-code"), null, "The request post data editor should not be displayed." ); @@ -172,7 +172,7 @@ async function testRequestWithFormattedView( ); // Toggle the raw data display. This should hide the formatted display. - waitForContent = waitForDOM(document, "#request-panel .cm-content"); + waitForContent = waitForDOM(document, "#request-panel .CodeMirror-code"); let rawDataToggle = document.querySelector( "#request-panel .raw-data-toggle-input .devtools-checkbox-toggle" ); @@ -197,7 +197,7 @@ async function testRequestWithFormattedView( "The formatted display should be hidden." ); is( - tabpanel.querySelector(".cm-content") !== null, + tabpanel.querySelector(".CodeMirror-code") !== null, true, "The raw payload data display is shown." ); @@ -236,7 +236,10 @@ async function testRequestWithOnlyRawDataView( // Wait for header and CodeMirror editor to be displayed const wait = waitForDOM(document, "#request-panel .data-header"); - const waitForContent = waitForDOM(document, "#request-panel .cm-content"); + const waitForContent = waitForDOM( + document, + "#request-panel .CodeMirror-code" + ); EventUtils.sendMouseEvent({ type: "mousedown" }, requestListItem); await Promise.all([wait, waitForContent]); @@ -259,7 +262,7 @@ async function testRequestWithOnlyRawDataView( "The formatted display should be hidden." ); is( - tabpanel.querySelector(".cm-content") !== null, + tabpanel.querySelector(".CodeMirror-code") !== null, true, "The raw payload data display is shown." ); @@ -298,7 +301,7 @@ async function testRequestWithoutRequestData(monitor, requestListItem) { "The formatted display should be hidden." ); is( - tabpanel.querySelector(".cm-content") === null, + tabpanel.querySelector(".CodeMirror-code") === null, true, "The raw payload data display should be hidden." ); diff --git a/devtools/client/netmonitor/test/browser_net_content-type.js b/devtools/client/netmonitor/test/browser_net_content-type.js @@ -181,7 +181,7 @@ add_task(async function () { "The response json view doesn't display" ); is( - tabpanel.querySelector(".cm-content") === null, + tabpanel.querySelector(".CodeMirror-code") === null, box !== "textarea", "The response editor doesn't display" ); diff --git a/devtools/client/netmonitor/test/browser_net_cyrillic-01.js b/devtools/client/netmonitor/test/browser_net_cyrillic-01.js @@ -49,7 +49,7 @@ add_task(async function () { document.querySelectorAll(".request-list-item")[0] ); await wait; - wait = waitForDOM(document, "#response-panel .cm-content"); + wait = waitForDOM(document, "#response-panel .CodeMirror-code"); clickOnSidebarTab(document, "response"); await wait; diff --git a/devtools/client/netmonitor/test/browser_net_cyrillic-02.js b/devtools/client/netmonitor/test/browser_net_cyrillic-02.js @@ -56,7 +56,7 @@ add_task(async function () { clickOnSidebarTab(document, "response"); await wait; - wait = waitForDOM(document, "#response-panel .cm-content"); + wait = waitForDOM(document, "#response-panel .CodeMirror-code"); const header = document.querySelector( "#response-panel .raw-data-toggle-input .devtools-checkbox-toggle" ); @@ -65,7 +65,7 @@ add_task(async function () { // CodeMirror will only load lines currently in view to the DOM. getValue() // retrieves all lines pending render after a user begins scrolling. - const text = getCodeMirrorValue(monitor); + const text = document.querySelector(".CodeMirror").CodeMirror.getValue(); ok( text.includes("\u0411\u0440\u0430\u0442\u0430\u043d"), diff --git a/devtools/client/netmonitor/test/browser_net_delayed-response.js b/devtools/client/netmonitor/test/browser_net_delayed-response.js @@ -155,7 +155,10 @@ add_task(async function () { ); info("Open the response panel and wait for the response content"); - waitForResponsePanel = waitForDOM(document, "#response-panel .cm-content"); + waitForResponsePanel = waitForDOM( + document, + "#response-panel .CodeMirror-code" + ); clickOnSidebarTab(document, "response"); await waitForResponsePanel; diff --git a/devtools/client/netmonitor/test/browser_net_json-b64.js b/devtools/client/netmonitor/test/browser_net_json-b64.js @@ -59,7 +59,7 @@ add_task(async function () { ); // Open the response payload section, it should hide the json section - wait = waitForDOM(document, "#response-panel .cm-content"); + wait = waitForDOM(document, "#response-panel .CodeMirror-code"); const header = document.querySelector( "#response-panel .raw-data-toggle-input .devtools-checkbox-toggle" ); @@ -84,7 +84,7 @@ add_task(async function () { "The raw response toggle should be on." ); is( - tabpanel.querySelector(".cm-content") === null, + tabpanel.querySelector(".CodeMirror-code") === null, false, "The response editor has the intended visibility." ); diff --git a/devtools/client/netmonitor/test/browser_net_json-empty.js b/devtools/client/netmonitor/test/browser_net_json-empty.js @@ -33,7 +33,10 @@ add_task(async function () { await onResponsePanelReady; - const codeMirrorReady = waitForDOM(document, "#response-panel .cm-content"); + const codeMirrorReady = waitForDOM( + document, + "#response-panel .CodeMirror-code" + ); const header = document.querySelector( "#response-panel .raw-data-toggle-input .devtools-checkbox-toggle" @@ -55,7 +58,7 @@ add_task(async function () { "The response error header doesn't have the intended visibility." ); is( - tabpanel.querySelector(".cm-content") === null, + tabpanel.querySelector(".CodeMirror-code") === null, false, "The response editor has the intended visibility." ); diff --git a/devtools/client/netmonitor/test/browser_net_json-long.js b/devtools/client/netmonitor/test/browser_net_json-long.js @@ -78,7 +78,7 @@ add_task(async function () { testJsonInResposeTab(); - wait = waitForDOM(document, "#response-panel .cm-content"); + wait = waitForDOM(document, "#response-panel .CodeMirror-code"); const rawResponseToggle = document.querySelector( "#response-panel .raw-data-toggle-input .devtools-checkbox-toggle" ); @@ -146,7 +146,7 @@ add_task(async function () { "The source editor container has visible height." ); is( - tabpanel.querySelector(".cm-content") === null, + tabpanel.querySelector(".CodeMirror-code") === null, false, "The response editor has the intended visibility." ); diff --git a/devtools/client/netmonitor/test/browser_net_json-malformed.js b/devtools/client/netmonitor/test/browser_net_json-malformed.js @@ -47,7 +47,7 @@ add_task(async function () { } ); - const wait = waitForDOM(document, "#response-panel .cm-content"); + const wait = waitForDOM(document, "#response-panel .CodeMirror-code"); store.dispatch(Actions.toggleNetworkDetails()); clickOnSidebarTab(document, "response"); await wait; @@ -77,7 +77,7 @@ add_task(async function () { "The response json view doesn't have the intended visibility." ); is( - tabpanel.querySelector(".cm-content") === null, + tabpanel.querySelector(".CodeMirror-code") === null, false, "The response editor has the intended visibility." ); diff --git a/devtools/client/netmonitor/test/browser_net_json-null.js b/devtools/client/netmonitor/test/browser_net_json-null.js @@ -66,7 +66,10 @@ add_task(async function () { "The first json property value was incorrect." ); - const onCodeMirrorReady = waitForDOM(document, "#response-panel .cm-content"); + const onCodeMirrorReady = waitForDOM( + document, + "#response-panel .CodeMirror-code" + ); const rawResponseToggle = document.querySelector( "#response-panel .raw-data-toggle-input .devtools-checkbox-toggle" @@ -97,7 +100,7 @@ add_task(async function () { "The response json view has the intended visibility." ); is( - panel.querySelector(".cm-content") === null, + panel.querySelector(".CodeMirror-code") === null, false, "The response editor has the intended visibility." ); @@ -126,13 +129,16 @@ add_task(async function () { // Execute requests. await performRequests(monitor, tab, 1); - const onCodeMirrorReady = waitForDOM(document, "#response-panel .cm-content"); + const onCodeMirrorReady = waitForDOM( + document, + "#response-panel .CodeMirror-code" + ); store.dispatch(Actions.toggleNetworkDetails()); clickOnSidebarTab(document, "response"); const [codeMirrorCodeEl] = await onCodeMirrorReady; is( - codeMirrorCodeEl.querySelector(".cm-line").textContent, + codeMirrorCodeEl.querySelector("pre.CodeMirror-line span").textContent, "null", "root null JSON object is displayed in a CodeMirror editor" ); diff --git a/devtools/client/netmonitor/test/browser_net_json-numbers.js b/devtools/client/netmonitor/test/browser_net_json-numbers.js @@ -144,13 +144,16 @@ add_task(async function testLargeRootInteger() { await performRequests(monitor, tab, 1); - const onCodeMirrorReady = waitForDOM(document, "#response-panel .cm-content"); + const onCodeMirrorReady = waitForDOM( + document, + "#response-panel .CodeMirror-code" + ); store.dispatch(Actions.toggleNetworkDetails()); clickOnSidebarTab(document, "response"); const [codeMirrorCodeEl] = await onCodeMirrorReady; is( - codeMirrorCodeEl.querySelector(".cm-line").textContent, + codeMirrorCodeEl.querySelector("pre.CodeMirror-line span").textContent, "1516340399466235648", "Large number is displayed in a CodeMirror editor" ); diff --git a/devtools/client/netmonitor/test/browser_net_json-xssi-protection.js b/devtools/client/netmonitor/test/browser_net_json-xssi-protection.js @@ -23,43 +23,45 @@ add_task(async function () { await performRequests(monitor, tab, 1); const wait = waitForDOM(document, "#response-panel .data-header"); - const waitForRawView = waitForDOM(document, "#response-panel .cm-content", 1); - const waitForRawToggleOn = waitUntil( - () => - document.querySelector("#response-panel #raw-response-checkbox")?.checked + const waitForRawView = waitForDOM( + document, + "#response-panel .CodeMirror-code", + 1 ); store.dispatch(Actions.toggleNetworkDetails()); info("Opening response panel"); clickOnSidebarTab(document, "response"); - await Promise.all([wait, waitForRawView, waitForRawToggleOn]); + await Promise.all([wait, waitForRawView]); info( "making sure response panel defaults to raw view and correctly displays payload" ); - const codeLines = document.querySelector("#response-panel .cm-content"); + const codeLines = document.querySelector("#response-panel .CodeMirror-code"); const firstLine = codeLines.firstChild; + const firstLineText = firstLine.querySelector("pre.CodeMirror-line span"); is( - firstLine.textContent, + firstLineText.textContent, ")]}'", "XSSI protection sequence should be visibly in raw view" ); - info("making sure XSSI notification box is not present in raw view"); let notification = document.querySelector( '.network-monitor #response-panel .notification[data-key="xssi-string-removed-info-box"]' ); ok(!notification, "notification should not be present in raw view"); - info("switching to props view"); const waitForPropsView = waitForDOM( document, "#response-panel .properties-view", 1 ); + + info("switching to props view"); const tabpanel = document.querySelector("#response-panel"); - clickElement(tabpanel.querySelector("#raw-response-checkbox"), monitor); + const rawResponseToggle = tabpanel.querySelector("#raw-response-checkbox"); + clickElement(rawResponseToggle, monitor); await waitForPropsView; is( diff --git a/devtools/client/netmonitor/test/browser_net_json_custom_mime.js b/devtools/client/netmonitor/test/browser_net_json_custom_mime.js @@ -60,7 +60,7 @@ add_task(async function () { testJsonSectionInResponseTab(); - wait = waitForDOM(document, "#response-panel .cm-content"); + wait = waitForDOM(document, "#response-panel .CodeMirror-code"); const rawResponseToggle = document.querySelector( "#response-panel .raw-data-toggle-input .devtools-checkbox-toggle" ); @@ -115,7 +115,7 @@ add_task(async function () { "The raw response toggle should be on." ); is( - tabpanel.querySelector(".cm-content") === null, + tabpanel.querySelector(".CodeMirror-code") === null, false, "The response editor has the intended visibility." ); diff --git a/devtools/client/netmonitor/test/browser_net_json_text_mime.js b/devtools/client/netmonitor/test/browser_net_json_text_mime.js @@ -63,7 +63,7 @@ add_task(async function () { testJsonSectionInResponseTab(); - wait = waitForDOM(document, "#response-panel .cm-content"); + wait = waitForDOM(document, "#response-panel .CodeMirror-code"); const rawResponseToggle = document.querySelector( "#response-panel .raw-data-toggle-input .devtools-checkbox-toggle" ); @@ -120,7 +120,7 @@ add_task(async function () { "The response json view has the intended visibility." ); is( - tabpanel.querySelector(".cm-content") === null, + tabpanel.querySelector(".CodeMirror-code") === null, false, "The response editor has the intended visibility." ); diff --git a/devtools/client/netmonitor/test/browser_net_jsonp.js b/devtools/client/netmonitor/test/browser_net_jsonp.js @@ -80,7 +80,7 @@ add_task(async function () { testJsonSectionInResponseTab(`"Hello JSONP!"`); - wait = waitForDOM(document, "#response-panel .cm-content"); + wait = waitForDOM(document, "#response-panel .CodeMirror-code"); let rawResponseToggle = document.querySelector( "#response-panel .raw-data-toggle-input .devtools-checkbox-toggle" ); @@ -113,7 +113,7 @@ add_task(async function () { testJsonSectionInResponseTab(`"Hello weird JSONP!"`); - wait = waitForDOM(document, "#response-panel .cm-content"); + wait = waitForDOM(document, "#response-panel .CodeMirror-code"); rawResponseToggle = document.querySelector( "#response-panel .raw-data-toggle-input .devtools-checkbox-toggle" ); @@ -161,7 +161,7 @@ add_task(async function () { "The response json view has the intened visibility and correct title." ); is( - tabpanel.querySelector(".cm-content") === null, + tabpanel.querySelector(".CodeMirror-code") === null, false, "The response editor has the intended visibility." ); diff --git a/devtools/client/netmonitor/test/browser_net_large-response.js b/devtools/client/netmonitor/test/browser_net_large-response.js @@ -61,7 +61,7 @@ add_task(async function () { clickOnSidebarTab(document, "response"); await wait; - wait = waitForDOM(document, "#response-panel .cm-content"); + wait = waitForDOM(document, "#response-panel .CodeMirror-code"); const payloadHeader = document.querySelector( "#response-panel .raw-data-toggle-input .devtools-checkbox-toggle" ); @@ -74,10 +74,10 @@ add_task(async function () { ); info("Check that search input can be displayed"); - getCMEditor(monitor).focus(); + document.querySelector(".CodeMirror").CodeMirror.focus(); synthesizeKeyShortcut("CmdOrCtrl+F"); const searchInput = await waitFor(() => - document.querySelector(".cm-editor .cm-search input.cm-textfield") + document.querySelector(".CodeMirror input[type=search]") ); Assert.equal( searchInput.ownerDocument.activeElement, diff --git a/devtools/client/netmonitor/test/browser_net_post-data-json-payloads.js b/devtools/client/netmonitor/test/browser_net_post-data-json-payloads.js @@ -40,7 +40,7 @@ add_task(async function () { "The request params doesn't have the indended visibility." ); is( - tabpanel.querySelector(".cm-content") === null, + tabpanel.querySelector(".CodeMirror-code") === null, true, "The request post data doesn't have the indended visibility." ); @@ -68,7 +68,7 @@ add_task(async function () { is(values[0].textContent, "1", "The JSON var value was incorrect."); // Toggle the raw data display. This should hide the formatted display. - waitForContent = waitForDOM(document, "#request-panel .cm-content"); + waitForContent = waitForDOM(document, "#request-panel .CodeMirror-code"); const rawDataToggle = document.querySelector( "#request-panel .raw-data-toggle-input .devtools-checkbox-toggle" ); @@ -93,7 +93,7 @@ add_task(async function () { ); // Bug 1514750 - Show JSON request in plain text view also ok( - tabpanel.querySelector(".cm-content"), + tabpanel.querySelector(".CodeMirror-code"), "The request post data doesn't have the indended visibility." ); ok( diff --git a/devtools/client/netmonitor/test/browser_net_post-data-raw-payloads-with-upload-stream-headers.js b/devtools/client/netmonitor/test/browser_net_post-data-raw-payloads-with-upload-stream-headers.js @@ -185,14 +185,14 @@ add_task(async function () { tabpanel.querySelector(".data-label").textContent == L10N.getStr("paramsPostPayload") && tabpanel.querySelector( - ".panel-container .editor-row-container .cm-content" + ".panel-container .editor-row-container .CodeMirror-code" ) ); // Check that the expected header lines are included in the codemirror // text. const actualText = tabpanel.querySelector( - ".panel-container .editor-row-container .cm-content" + ".panel-container .editor-row-container .CodeMirror-code" ).textContent; const requestPayloadIsCorrect = expected.requestPanelPayload.every( content => actualText.includes(content) diff --git a/devtools/client/netmonitor/test/browser_net_post-data.js b/devtools/client/netmonitor/test/browser_net_post-data.js @@ -88,7 +88,7 @@ add_task(async function () { const waitForHeader = waitForDOM(document, "#request-panel .data-header"); const waitForSourceEditor = waitForDOM( document, - "#request-panel .cm-content" + "#request-panel .CodeMirror-code" ); EventUtils.sendMouseEvent( { type: "mousedown" }, @@ -104,7 +104,7 @@ add_task(async function () { function checkVisibility(box) { is( - tabpanel.querySelector(".cm-content") === null, + tabpanel.querySelector(".CodeMirror-code") === null, !box.includes("editor"), "The request post data doesn't have the intended visibility." ); diff --git a/devtools/client/netmonitor/test/browser_net_raw_response.js b/devtools/client/netmonitor/test/browser_net_raw_response.js @@ -143,7 +143,7 @@ function getRawResponseToggle(doc) { } function getRawResponseCodeMirrorElement(doc) { - return doc.querySelector("#response-panel .cm-editor"); + return doc.querySelector("#response-panel .CodeMirror"); } function getHtmlPreviewElement(doc) { diff --git a/devtools/client/netmonitor/test/browser_net_search-results.js b/devtools/client/netmonitor/test/browser_net_search-results.js @@ -104,8 +104,8 @@ add_task(async function () { monitor, matches[4], "#response-panel", - ".cm-content", - ".cm-line", + ".CodeMirror-code", + ".CodeMirror-activeline", [SEARCH_STRING] ); await checkSearchResult( @@ -160,8 +160,8 @@ add_task(async function () { monitor, matches[11], "#response-panel", - ".cm-content", - ".cm-line", + ".CodeMirror-code", + ".CodeMirror-activeline", [SEARCH_STRING] ); diff --git a/devtools/client/netmonitor/test/browser_net_truncate-post-data.js b/devtools/client/netmonitor/test/browser_net_truncate-post-data.js @@ -70,7 +70,10 @@ async function checkPostDataRequest(expectErrorDisplay) { // Make sure the header and editor are loaded const waitHeader = waitForDOM(document, "#request-panel .data-header"); - const waitSourceEditor = waitForDOM(document, "#request-panel .cm-editor"); + const waitSourceEditor = waitForDOM( + document, + "#request-panel .CodeMirror.cm-s-mozilla" + ); store.dispatch(Actions.toggleNetworkDetails()); clickOnSidebarTab(document, "request"); @@ -96,9 +99,8 @@ async function checkPostDataRequest(expectErrorDisplay) { false, "The params json view doesn't have the intended visibility." ); - is( - tabpanel.querySelector(".cm-editor") === null, + tabpanel.querySelector("PRE") === null, false, "The Request Payload has the intended visibility." ); diff --git a/devtools/client/netmonitor/test/browser_net_zstd.js b/devtools/client/netmonitor/test/browser_net_zstd.js @@ -55,7 +55,7 @@ add_task(async function () { } ); - const wait = waitForDOM(document, ".cm-content"); + const wait = waitForDOM(document, ".CodeMirror-code"); const onResponseContent = monitor.panelWin.api.once( TEST_EVENTS.RECEIVED_RESPONSE_CONTENT ); diff --git a/devtools/client/netmonitor/test/head.js b/devtools/client/netmonitor/test/head.js @@ -1157,9 +1157,9 @@ async function selectIndexAndWaitForSourceEditor(monitor, index) { document.querySelectorAll(".request-list-item")[index] ); // We may already be on the ResponseTab, so only select it if needed. - const editor = document.querySelector("#response-panel .cm-content"); + const editor = document.querySelector("#response-panel .CodeMirror-code"); if (!editor) { - const waitDOM = waitForDOM(document, "#response-panel .cm-content"); + const waitDOM = waitForDOM(document, "#response-panel .CodeMirror-code"); document.querySelector("#response-tab").click(); await waitDOM; } @@ -1181,15 +1181,12 @@ async function performRequests(monitor, tab, count) { await wait; } -function getCMEditor(monitor) { - return monitor.panelWin.codeMirrorSourceEditorTestInstance; -} - /** - * Helper function for retrieving the editor content + * Helper function for retrieving `.CodeMirror` content */ function getCodeMirrorValue(monitor) { - return getCMEditor(monitor).getText(); + const { document } = monitor.panelWin; + return document.querySelector(".CodeMirror")?.CodeMirror.getValue(); } /** diff --git a/devtools/client/shared/sourceeditor/codemirror/mozilla.css b/devtools/client/shared/sourceeditor/codemirror/mozilla.css @@ -8,7 +8,7 @@ --breakpoint-active-color-hover: light-dark(rgba(44,187,15,.5), rgba(0,255,175,.7);); --gutter-background-color: var(--theme-sidebar-background); --gutter-border-color: light-dark(var(--theme-splitter-color), var(--theme-toolbar-background)); - --highlight-line-duration: 5000ms; + &[forced-colors-active] { /* overriding variable in HCM so the border is actually visible (see Bug 1953376) */ --gutter-border-color: var(--theme-splitter-color); @@ -112,9 +112,9 @@ } /* Search highlight style - * cm-searching is used in Style Editor, cm-highlight in Debugger and searchMatch in Netmonitor */ + * cm-searching is used in Style Editor, and cm-highlight in Debugger */ .cm-searching, -.cm-highlight, .cm-editor .cm-searchMatch { +.cm-highlight { border-bottom: 1px solid var(--theme-contrast-border); /* Use the translucent yellow background, because we want the text selection background (CodeMirror-selected) to show through this. */ @@ -377,7 +377,7 @@ } /* CodeMirror matchhighlight styling */ -.cm-matchhighlight, .cm-searchMatch-selected { +.cm-matchhighlight, .cm-selectionMatch { outline: 1px solid var(--theme-contrast-border); border-radius: 2px; /* Override cm6 inline */ @@ -453,12 +453,6 @@ font-family: unset; } -/* Remove the default selection match background, as search results might have the -.cm-selectionMatch class after the current search term has been removed, these should not be styled`` */ -.cm-editor .cm-selectionMatch { - background-color: transparent; -} - .cm-editor .cm-selectionBackground { background: var(--theme-text-selection-background) !important; } @@ -467,7 +461,6 @@ /* We don't want forced colors on selection so we can adjust the colors as we want. This especially helps for the unfocused selected text */ forced-color-adjust: none; - color: inherit; } .cm-editor .cm-line ::selection { @@ -534,47 +527,3 @@ color: currentColor; } } - -.highlight-line .CodeMirror-line, -/* For CM6 */ -.cm-editor .cm-line.highlight-line { - animation-name: fade-highlight-out; - animation-duration: var(--highlight-line-duration); - animation-timing-function: ease-out; - animation-fill-mode: forwards; -} - -@keyframes fade-highlight-out { - - 0%, - 30% { - /* We want to use a color with some transparency so text selection is visible through it */ - background-color: var(--theme-contrast-background-alpha); - } - 100% { - background-color: transparent; - } -} - -.cm-editor .cm-panels { - background-color: var(--theme-toolbar-background); - color: var(--theme-body-color); -} - -.cm-editor .cm-panels-top { - border-color: var(--theme-splitter-color); -} - -/* Default search panel */ -.cm-search .cm-textfield { - width: 100%; - font-size: inherit; - background-color: transparent; - border-color: var(--theme-splitter-color); - margin: 0 !important; -} - -/* Hide all other elements of the search except the text input */ -.cm-search .cm-button, .cm-search label, .cm-search button[name="close"] { - display: none; -} diff --git a/devtools/client/shared/sourceeditor/editor.js b/devtools/client/shared/sourceeditor/editor.js @@ -273,13 +273,8 @@ class Editor extends EventEmitter { autocompleteOpts: {}, // Expect a CssProperties object (see devtools/client/fronts/css-properties.js) cssProperties: null, - // Set to `true` to prevent the search addon to be activated. + // Set to true to prevent the search addon to be activated. disableSearchAddon: false, - // When the search addon is activated (i.e disableSearchAddon == false), - // `useSearchAddonPanel` determines if the default search panel for the search addon should be used. - // Set to `false` when a custom search panel is used. - // Note: This can probably be removed when Bug 1941575 is fixed, and custom search panel is used everywhere - useSearchAddonPanel: true, maxHighlightLength: 1000, // Disable codeMirror setTimeout-based cursor blinking (will be replaced by a CSS animation) cursorBlinkRate: 0, @@ -744,7 +739,7 @@ class Editor extends EventEmitter { placeholder, }, codemirrorState: { EditorState, Compartment, Prec }, - codemirrorSearch: { search, searchKeymap, highlightSelectionMatches }, + codemirrorSearch: { highlightSelectionMatches }, codemirrorLanguage: { syntaxTreeAvailable, indentUnit, @@ -850,13 +845,6 @@ class Editor extends EventEmitter { codemirror.minimalSetup, ]; - if (!this.config.disableSearchAddon && this.config.useSearchAddonPanel) { - this.config.keyMap = this.config.keyMap - ? [...this.config.keyMap, ...searchKeymap] - : [...searchKeymap]; - extensions.push(search({ top: true })); - } - if (this.config.placeholder) { extensions.push(placeholder(this.config.placeholder)); } diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_network_messages_expand.js b/devtools/client/webconsole/test/browser/browser_webconsole_network_messages_expand.js @@ -164,7 +164,7 @@ async function testRequest(messageNode) { const requestPanel = messageNode.querySelector("#request-panel"); await waitForSourceEditor(requestPanel); const requestContent = requestPanel.querySelector( - ".panel-container .cm-editor" + ".panel-container .CodeMirror" ); ok(requestContent, "Request content is available"); ok( @@ -184,7 +184,7 @@ async function testResponse(messageNode) { const responsePanel = messageNode.querySelector("#response-panel"); await waitForSourceEditor(responsePanel); const responseContent = messageNode.querySelector( - "#response-panel .editor-row-container .cm-editor" + "#response-panel .editor-row-container .CodeMirror" ); ok(responseContent, "Response content is available"); ok(responseContent.textContent, "Response text is available"); @@ -241,7 +241,7 @@ async function waitForPayloadReady(hud) { async function waitForSourceEditor(panel) { return waitUntil(() => { - return !!panel.querySelector(".cm-editor"); + return !!panel.querySelector(".CodeMirror"); }); } diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_network_messages_expand_before_updates.js b/devtools/client/webconsole/test/browser/browser_webconsole_network_messages_expand_before_updates.js @@ -196,7 +196,7 @@ async function testRequest(messageNode) { const requestPanel = messageNode.querySelector("#request-panel"); await waitForSourceEditor(requestPanel); const requestContent = requestPanel.querySelector( - ".panel-container .cm-content" + ".panel-container .CodeMirror" ); ok(requestContent, "Request content is available"); ok( @@ -232,7 +232,7 @@ async function testResponse(messageNode) { } await waitForSourceEditor(responsePanel); const responseContent = messageNode.querySelector( - "#response-panel .editor-row-container .cm-content" + "#response-panel .editor-row-container .CodeMirror" ); ok(responseContent, "Response content is available"); ok(responseContent.textContent, "Response text is available"); @@ -300,7 +300,7 @@ async function testSecurity(messageNode) { async function waitForSourceEditor(panel) { return waitUntil(() => { - return !!panel.querySelector(".cm-content"); + return !!panel.querySelector(".CodeMirror"); }); } diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_network_messages_html_preview.js b/devtools/client/webconsole/test/browser/browser_webconsole_network_messages_html_preview.js @@ -162,7 +162,7 @@ async function expandNetworkRequestAndWaitForHtmlView({ const rawToggleEl = node.querySelector(".devtools-checkbox-toggle"); ok(!rawToggleEl.checked, "Raw toggle isn't checked by default"); rawToggleEl.click(); - await waitFor(() => node.querySelector(".cm-editor")); + await waitFor(() => node.querySelector(".CodeMirror")); ok(true, "The CodeMirror instance is rendered"); } diff --git a/dom/security/nsContentSecurityUtils.cpp b/dom/security/nsContentSecurityUtils.cpp @@ -1288,10 +1288,8 @@ static nsLiteralCString sStyleSrcUnsafeInlineAllowList[] = { "chrome://devtools/content/framework/toolbox-window.xhtml"_ns, "chrome://devtools/content/inspector/index.xhtml"_ns, "chrome://devtools/content/inspector/markup/markup.xhtml"_ns, - "chrome://devtools/content/netmonitor/index.html"_ns, "chrome://devtools/content/memory/index.xhtml"_ns, "chrome://devtools/content/shared/sourceeditor/codemirror/cmiframe.html"_ns, - "chrome://devtools/content/webconsole/index.html"_ns, "chrome://formautofill/content/manageAddresses.xhtml"_ns, "chrome://formautofill/content/manageCreditCards.xhtml"_ns, "chrome://gfxsanity/content/sanityparent.html"_ns, diff --git a/testing/talos/talos/tests/devtools/addon/content/tests/netmonitor/netmonitor-helpers.js b/testing/talos/talos/tests/devtools/addon/content/tests/netmonitor/netmonitor-helpers.js @@ -218,7 +218,7 @@ exports.openResponseDetailsPanel = async function (label, toolbox) { const request = document.querySelectorAll(".request-list-item")[0]; const waitForEditor = waitForDOMElement( monitor, - "#response-panel .cm-editor" + "#response-panel .CodeMirror.cm-s-mozilla" ); mouseDownElement(request, win); await waitForEditor;