From 15c84553386b36d5dda0abd07a5e48dbbaeb1fb0 Mon Sep 17 00:00:00 2001 From: Stanca Serban Date: Thu, 6 Jul 2023 02:11:59 +0300 Subject: [PATCH] Backed out changeset 1c835137f532 (bug 1824886) for causing multiple failures. CLOSED TREE --- .../test/static/browser_parsable_css.js | 12 +- .../ScreenshotsOverlayChild.sys.mjs | 133 ++++-- .../screenshots/overlay/overlay.css | 130 ++--- .../src/components/manifest/ManifestIssue.js | 2 +- ...plication_panel-ManifestIssue.test.js.snap | 2 +- .../src/components/shared/AccessibleImage.css | 4 +- .../browser_inspector_highlighter-zoom.js | 8 +- devtools/client/inspector/test/head.js | 5 - devtools/client/jar.mn | 1 + .../src/assets/styles/RequestList.css | 2 +- .../themes/accessibility-color-contrast.css | 2 +- devtools/client/themes/animation.css | 2 +- .../themes}/images/error-small.svg | 0 devtools/client/themes/toolbox.css | 6 +- devtools/client/themes/webconsole.css | 2 +- .../{highlighters/css => }/highlighters.css | 451 ++++++++++-------- .../server/actors/highlighters/css-grid.js | 5 +- .../server/actors/highlighters/css/moz.build | 9 - devtools/server/actors/highlighters/moz.build | 1 - .../highlighters/utils/accessibility.js | 3 +- .../actors/highlighters/utils/markup.js | 64 ++- devtools/server/actors/moz.build | 1 + .../actors/utils/stylesheets-manager.js | 25 +- .../chrome/test_css-logic-specificity.html | 23 +- .../test_highlighter_paused_debugger.html | 6 +- .../tests/browser_resources_stylesheets.js | 18 +- devtools/shared/images/moz.build | 13 - devtools/shared/jar.mn | 11 +- devtools/shared/moz.build | 1 - dom/base/AnonymousContent.cpp | 213 ++++++++- dom/base/AnonymousContent.h | 76 ++- dom/base/Document.cpp | 31 +- dom/base/Document.h | 6 +- dom/base/test/mochitest.ini | 1 + dom/base/test/test_anonymousContent_api.html | 44 +- ..._anonymousContent_append_after_reflow.html | 25 +- .../test/test_anonymousContent_canvas.html | 81 ++-- .../test/test_anonymousContent_insert.html | 31 +- ...t_anonymousContent_manipulate_content.html | 61 ++- .../test/test_anonymousContent_set_style.html | 35 ++ .../test/test_anonymousContent_style_csp.html | 27 +- dom/webidl/AnonymousContent.webidl | 89 +++- dom/webidl/Document.webidl | 8 +- layout/base/AccessibleCaret.cpp | 83 ++-- layout/base/AccessibleCaret.h | 19 +- layout/base/AccessibleCaretEventHub.cpp | 6 +- layout/base/AccessibleCaretManager.cpp | 5 + layout/base/AccessibleCaretManager.h | 4 + layout/base/PresShell.cpp | 3 +- layout/base/nsLayoutUtils.cpp | 2 +- layout/generic/nsCanvasFrame.cpp | 74 ++- layout/painting/nsDisplayList.cpp | 6 +- layout/style/Loader.cpp | 17 +- layout/style/StyleSheet.cpp | 26 +- layout/style/moz.build | 1 - layout/style/res/accessiblecaret.css | 108 ----- layout/style/res/ua.css | 103 +++- layout/style/test/chrome/test_bug1346623.html | 9 +- .../test/test_custom_content_inheritance.html | 26 +- 59 files changed, 1299 insertions(+), 863 deletions(-) rename devtools/{shared => client/themes}/images/error-small.svg (100%) rename devtools/server/actors/{highlighters/css => }/highlighters.css (56%) delete mode 100644 devtools/server/actors/highlighters/css/moz.build delete mode 100644 devtools/shared/images/moz.build create mode 100644 dom/base/test/test_anonymousContent_set_style.html delete mode 100644 layout/style/res/accessiblecaret.css diff --git a/browser/base/content/test/static/browser_parsable_css.js b/browser/base/content/test/static/browser_parsable_css.js index 81a296c5ad0b..0cfd066cdc82 100644 --- a/browser/base/content/test/static/browser_parsable_css.js +++ b/browser/base/content/test/static/browser_parsable_css.js @@ -16,6 +16,12 @@ let whitelist = [ sourceName: /devtools\/content\/debugger\/src\/components\/([A-z\/]+).css/i, isFromDevTools: true, }, + // Highlighter CSS uses a UA-only pseudo-class, see bug 985597. + { + sourceName: /highlighters\.css$/i, + errorMessage: /Unknown pseudo-class.*moz-native-anonymous/i, + isFromDevTools: true, + }, // UA-only media features. { sourceName: /\b(autocomplete-item)\.css$/, @@ -62,6 +68,11 @@ let whitelist = [ /Unknown property ‘text-size-adjust’\. {2}Declaration dropped\./i, isFromDevTools: false, }, + { + sourceName: /overlay\.css$/i, + errorMessage: /Unknown pseudo-class.*moz-native-anonymous/i, + isFromDevTools: false, + }, ]; if (!Services.prefs.getBoolPref("layout.css.color-mix.enabled")) { @@ -136,7 +147,6 @@ let propNameWhitelist = [ // These variables are used in a shorthand, but the CSS parser deletes the values // when expanding the shorthands. See https://github.com/w3c/csswg-drafts/issues/2515 { propName: "--bezier-diagonal-color", isFromDevTools: true }, - { propName: "--highlighter-font-family", isFromDevTools: true }, // This variable is used from CSS embedded in JS in adjustableTitle.js { propName: "--icon-url", isFromDevTools: false }, diff --git a/browser/components/screenshots/ScreenshotsOverlayChild.sys.mjs b/browser/components/screenshots/ScreenshotsOverlayChild.sys.mjs index 67fcdfe269c8..db2c24f3dc9d 100644 --- a/browser/components/screenshots/ScreenshotsOverlayChild.sys.mjs +++ b/browser/components/screenshots/ScreenshotsOverlayChild.sys.mjs @@ -110,7 +110,6 @@ class AnonymousContentOverlay { } return this._content; } - async initialize() { if (this._initialized) { return; @@ -119,12 +118,24 @@ class AnonymousContentOverlay { let document = this.contentDocument; let window = document.ownerGlobal; + // Inject stylesheet if (!this.overlayFragment) { + try { + window.windowUtils.loadSheetUsingURIString( + STYLESHEET_URL, + window.windowUtils.AGENT_SHEET + ); + } catch { + // The method fails if the url is already loaded. + } + // Inject markup for the overlay UI this.overlayFragment = this.buildOverlay(); } - this._content = document.insertAnonymousContent(); - this._content.root.appendChild(this.overlayFragment.cloneNode(true)); + this._content = document.insertAnonymousContent( + this.overlayFragment.children[0] + ); + this.addEventListeners(); const hoverElementBox = new HoverElementBox( @@ -293,7 +304,6 @@ class AnonymousContentOverlay { const htmlString = `
-
@@ -1037,22 +1047,18 @@ class AnonLayer { this.content = content; } - _element(id) { - return this.content.root.getElementById(id); - } - /** * Show element with id this.id */ show() { - this._element(this.id).style = ""; + this.content.removeAttributeForElement(this.id, "style"); } /** * Hide element with id this.id */ hide() { - this._element(this.id).style.display = "none"; + this.content.setAttributeForElement(this.id, "style", "display:none;"); } } @@ -1091,9 +1097,11 @@ class HoverElementBox extends AnonLayer { let width = rect.left + rect.width > maxWidth ? maxWidth - rect.left : rect.width; - this._element( - this.id - ).style = `top:${top}px;left:${left}px;height:${height}px;width:${width}px;`; + this.content.setAttributeForElement( + this.id, + "style", + `top:${top}px;left:${left}px;height:${height}px;width:${width}px;` + ); } } @@ -1296,17 +1304,38 @@ class HoverElementBox extends AnonLayer { * get the screenshots elements as the elements from a given point */ setPointerEventsNone() { - this._element("screenshots-component").style.pointerEvents = "none"; - this._element("screenshots-overlay-container").style.pointerEvents = "none"; + this.content.setAttributeForElement( + "screenshots-component", + "style", + "pointer-events:none;" + ); + + let temp = this.content.getAttributeForElement( + "screenshots-overlay-container", + "style" + ); + this.content.setAttributeForElement( + "screenshots-overlay-container", + "style", + temp + "pointer-events:none;" + ); } /** * Return the pointer events to the original state because we found the element */ resetPointerEvents() { - this._element("screenshots-component").style.pointerEvents = ""; + this.content.setAttributeForElement("screenshots-component", "style", ""); - this._element("screenshots-overlay-container").style.pointerEvents = ""; + let temp = this.content.getAttributeForElement( + "screenshots-overlay-container", + "style" + ); + this.content.setAttributeForElement( + "screenshots-overlay-container", + "style", + temp.replace("pointer-events:none;", "") + ); } } @@ -1570,21 +1599,35 @@ class SelectionBox extends AnonLayer { * Draw the selected region for screenshotting */ show() { - this._element( - "highlight" - ).style = `top:${this.top}px;left:${this.left}px;height:${this.height}px;width:${this.width}px;`; - this._element( - "bgTop" - ).style = `top:0px;height:${this.top}px;left:0px;width:100%;`; - this._element( - "bgBottom" - ).style = `top:${this.bottom}px;height:calc(100% - ${this.bottom}px);left:0px;width:100%;`; - this._element( - "bgLeft" - ).style = `top:${this.top}px;height:${this.height}px;left:0px;width:${this.left}px;`; - this._element( - "bgRight" - ).style = `top:${this.top}px;height:${this.height}px;left:${this.right}px;width:calc(100% - ${this.right}px);`; + this.content.setAttributeForElement( + "highlight", + "style", + `top:${this.top}px;left:${this.left}px;height:${this.height}px;width:${this.width}px;` + ); + + this.content.setAttributeForElement( + "bgTop", + "style", + `top:0px;height:${this.top}px;left:0px;width:100%;` + ); + + this.content.setAttributeForElement( + "bgBottom", + "style", + `top:${this.bottom}px;height:calc(100% - ${this.bottom}px);left:0px;width:100%;` + ); + + this.content.setAttributeForElement( + "bgLeft", + "style", + `top:${this.top}px;height:${this.height}px;left:0px;width:${this.left}px;` + ); + + this.content.setAttributeForElement( + "bgRight", + "style", + `top:${this.top}px;height:${this.height}px;left:${this.right}px;width:calc(100% - ${this.right}px);` + ); } /** @@ -1604,9 +1647,11 @@ class SelectionBox extends AnonLayer { * Hide the selected region */ hide() { - for (let id of ["highlight", "bgTop", "bgBottom", "bgLeft", "bgRight"]) { - this._element(id).style = `display:none;`; - } + this.content.setAttributeForElement("highlight", "style", "display:none;"); + this.content.setAttributeForElement("bgTop", "style", "display:none;"); + this.content.setAttributeForElement("bgBottom", "style", "display:none;"); + this.content.setAttributeForElement("bgLeft", "style", "display:none;"); + this.content.setAttributeForElement("bgRight", "style", "display:none;"); } /** @@ -1781,7 +1826,11 @@ class ButtonsLayer extends AnonLayer { leftOrRight = `left:${boxLeft}px;`; } - this._element("buttons").style = `top:${top}px;${leftOrRight}`; + this.content.setAttributeForElement( + "buttons", + "style", + `top:${top}px;${leftOrRight}` + ); } } @@ -1801,8 +1850,8 @@ class PreviewLayer extends AnonLayer { const xpos = Math.floor((10 * (clientX - width / 2)) / width); const ypos = Math.floor((10 * (clientY - height / 2)) / height); const move = `transform:translate(${xpos}px, ${ypos}px);`; - this._element("left-eye").style = move; - this._element("right-eye").style = move; + this.content.setAttributeForElement("left-eye", "style", move); + this.content.setAttributeForElement("right-eye", "style", move); } } @@ -2086,9 +2135,11 @@ class ScreenshotsContainerLayer extends AnonLayer { * Draw the screenshots container */ drawScreenshotsContainer() { - this._element(this.id).style = `top:0;left:0;width:${ - this.#width - }px;height:${this.#height}px;`; + this.content.setAttributeForElement( + this.id, + "style", + `top:0;left:0;width:${this.#width}px;height:${this.#height}px;` + ); } get hoverElementBoxRect() { diff --git a/browser/components/screenshots/overlay/overlay.css b/browser/components/screenshots/overlay/overlay.css index 12c3e761f8a9..7b008fb8aa21 100644 --- a/browser/components/screenshots/overlay/overlay.css +++ b/browser/components/screenshots/overlay/overlay.css @@ -2,7 +2,7 @@ * 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/. */ -#screenshots-component { +:-moz-native-anonymous #screenshots-component { --in-content-page-background: #fff; --in-content-button-text-color: rgb(21, 20, 26); @@ -29,7 +29,7 @@ } @media (prefers-color-scheme: dark) { - #screenshots-component { + :-moz-native-anonymous #screenshots-component { --in-content-page-background: #42414d; --in-content-button-text-color: rgb(251,251,254); @@ -45,7 +45,7 @@ } @media (forced-colors: active), (prefers-contrast) { - #screenshots-component { + :-moz-native-anonymous #screenshots-component { --in-content-page-background: Canvas; --in-content-button-text-color: ButtonText; @@ -72,7 +72,7 @@ } } -#screenshots-component { +:-moz-native-anonymous #screenshots-component { width: 100%; height: 100%; overflow: clip; @@ -85,7 +85,7 @@ * Overlay content is position: fixed as we need to allow for the possiblily * of the document scrolling or changing size while the overlay is visible */ -#screenshots-overlay-container { +:-moz-native-anonymous #screenshots-overlay-container { /* Content CSS applying to the html element can impact the overlay. To avoid that, possible cases have been set to initial. @@ -103,7 +103,7 @@ cursor: crosshair; } -#preview-container { +:-moz-native-anonymous #preview-container { background-color: rgba(0, 0, 0, 0.7); position: fixed; top: 0; @@ -112,7 +112,7 @@ height: 100%; } -#selection-container { +:-moz-native-anonymous #selection-container { overflow: clip; position: absolute; top: 0; @@ -121,15 +121,15 @@ height: 100%; } -#screenshots-overlay-container[hidden] { +:-moz-native-anonymous #screenshots-overlay-container[hidden] { display: none; } -#screenshots-overlay-container[dragging] { +:-moz-native-anonymous #screenshots-overlay-container[dragging] { cursor: grabbing; } -#buttons { +:-moz-native-anonymous #buttons { position: absolute; margin: 10px 0; display: flex; @@ -140,7 +140,7 @@ padding: 4px; } -.screenshots-button { +:-moz-native-anonymous .screenshots-button { display: flex; align-items: center; justify-content: center; @@ -167,43 +167,43 @@ background-color: var(--in-content-button-background); } -.screenshots-button:focus-visible, -#screenshots-cancel-button:focus-visible { +:-moz-native-anonymous .screenshots-button:focus-visible, +:-moz-native-anonymous #screenshots-cancel-button:focus-visible { outline: 2px solid var(--in-content-focus-outline-color); outline-offset: 2px; } -.screenshots-button:hover { +:-moz-native-anonymous .screenshots-button:hover { background-color: var(--in-content-button-background-hover); border-color: var(--in-content-button-border-color-hover); color: var(--in-content-button-text-color-hover); } -.screenshots-button:active { +:-moz-native-anonymous .screenshots-button:active { background-color: var(--in-content-button-background-active); border-color: var(--in-content-button-border-color-active); color: var(--in-content-button-text-color-active); } -.primary { +:-moz-native-anonymous .primary { background-color: var(--in-content-primary-button-background); border-color: var(--in-content-primary-button-border-color); color: var(--in-content-primary-button-text-color); } -.primary:hover { +:-moz-native-anonymous .primary:hover { background-color: var(--in-content-primary-button-background-hover); border-color: var(--in-content-primary-button-border-color-hover); color: var(--in-content-primary-button-text-color-hover); } -.primary:active { +:-moz-native-anonymous .primary:active { background-color: var(--in-content-primary-button-background-active); border-color: var(--in-content-primary-button-border-color-active); color: var(--in-content-primary-button-text-color-active); } -#screenshots-cancel-button { +:-moz-native-anonymous #screenshots-cancel-button { background-color: transparent; margin-top: 40px; width: fit-content; @@ -211,43 +211,43 @@ color: #fff; } -#screenshots-cancel-button:hover { +:-moz-native-anonymous #screenshots-cancel-button:hover { background-color: #fff; color: #000; } @media (forced-colors: active), (prefers-contrast) { - #screenshots-cancel-button { + :-moz-native-anonymous #screenshots-cancel-button { border-color: ButtonBorder; color: CanvasText; } } -.screenshots-button > img { +:-moz-native-anonymous .screenshots-button > img { -moz-context-properties: fill; fill: currentColor; width: 16px; height: 16px; } -#cancel > img { +:-moz-native-anonymous #cancel > img { content: url("chrome://global/skin/icons/close.svg"); } -#copy > img { +:-moz-native-anonymous #copy > img { content: url("chrome://global/skin/icons/edit-copy.svg"); } -#download > img { +:-moz-native-anonymous #download > img { content: url("chrome://browser/skin/downloads/downloads.svg"); } -#download > img, -#copy > img { +:-moz-native-anonymous #download > img, +:-moz-native-anonymous #copy > img { margin-inline-end: 5px; } -.fixed-container { +:-moz-native-anonymous .fixed-container { align-items: center; display: flex; flex-direction: column; @@ -261,20 +261,20 @@ width: 100%; } -.face-container { +:-moz-native-anonymous .face-container { position: relative; width: 64px; height: 64px; } -.face { +:-moz-native-anonymous .face { width: 62px; height: 62px; display: block; background-image: url("chrome://browser/content/screenshots/icon-welcome-face-without-eyes.svg"); } -.eye { +:-moz-native-anonymous .eye { background-color: #fff; width: 10px; height: 14px; @@ -285,7 +285,7 @@ top: 19px; } -.eyeball { +:-moz-native-anonymous .eyeball { position: absolute; width: 6px; height: 6px; @@ -296,19 +296,19 @@ z-index: 10; } -.left { +:-moz-native-anonymous .left { margin-inline-start: 0; } -.right { +:-moz-native-anonymous .right { margin-inline-start: 20px; } -.preview-instructions { +:-moz-native-anonymous .preview-instructions { display: flex; align-items: center; justify-content: center; - animation: pulse 125ms cubic-bezier(0.07, 0.95, 0, 1); + animation: pulse 125mm cubic-bezier(0.07, 0.95, 0, 1); color: #fff; font-family: -apple-system, BlinkMacSystemFont, "segoe ui", "helvetica neue", helvetica, ubuntu, roboto, noto, arial, sans-serif; font-size: 24px; @@ -319,12 +319,12 @@ } @media (forced-colors: active), (prefers-contrast) { - .preview-instructions { + :-moz-native-anonymous .preview-instructions { color: CanvasText; } } -#hover-highlight { +:-moz-native-anonymous #hover-highlight { animation: fade-in 125ms forwards cubic-bezier(0.07, 0.95, 0, 1); background: rgba(255, 255, 255, 0.2); border-radius: 1px; @@ -333,7 +333,7 @@ z-index: 11; } -#hover-highlight::before { +:-moz-native-anonymous #hover-highlight::before { border: 2px dashed rgba(255, 255, 255, 0.4); bottom: 0; content: ""; @@ -343,13 +343,13 @@ top: 0; } -.bghighlight { +:-moz-native-anonymous .bghighlight { background-color: rgba(0, 0, 0, 0.7); position: absolute; overflow: clip; } -.highlight { +:-moz-native-anonymous .highlight { border-radius: 1px; border: 2px dashed rgba(255, 255, 255, 0.8); box-sizing: border-box; @@ -359,7 +359,7 @@ z-index: 2; } -.mover-target { +:-moz-native-anonymous .mover-target { display: flex; align-items: center; justify-content: center; @@ -368,7 +368,7 @@ pointer-events: auto; } -.mover-target.direction-topLeft { +:-moz-native-anonymous .mover-target.direction-topLeft { cursor: nwse-resize; height: 60px; left: -30px; @@ -376,7 +376,7 @@ width: 60px; } -.mover-target.direction-top { +:-moz-native-anonymous .mover-target.direction-top { cursor: ns-resize; height: 60px; inset-inline-start: 0; @@ -385,7 +385,7 @@ z-index: 4; } -.mover-target.direction-topRight { +:-moz-native-anonymous .mover-target.direction-topRight { cursor: nesw-resize; height: 60px; right: -30px; @@ -393,7 +393,7 @@ width: 60px; } -.mover-target.direction-left { +:-moz-native-anonymous .mover-target.direction-left { cursor: ew-resize; height: 100%; left: -30px; @@ -402,7 +402,7 @@ z-index: 4; } -.mover-target.direction-right { +:-moz-native-anonymous .mover-target.direction-right { cursor: ew-resize; height: 100%; right: -30px; @@ -411,7 +411,7 @@ z-index: 4; } -.mover-target.direction-bottomLeft { +:-moz-native-anonymous .mover-target.direction-bottomLeft { bottom: -30px; cursor: nesw-resize; height: 60px; @@ -419,7 +419,7 @@ width: 60px; } -.mover-target.direction-bottom { +:-moz-native-anonymous .mover-target.direction-bottom { bottom: -30px; cursor: ns-resize; height: 60px; @@ -428,7 +428,7 @@ z-index: 4; } -.mover-target.direction-bottomRight { +:-moz-native-anonymous .mover-target.direction-bottomRight { bottom: -30px; cursor: nwse-resize; height: 60px; @@ -436,11 +436,11 @@ width: 60px; } -.mover-target:hover .mover { +:-moz-native-anonymous .mover-target:hover .mover { transform: scale(1.05); } -.mover { +:-moz-native-anonymous .mover { background-color: #fff; border-radius: 50%; box-shadow: 0 0 4px rgba(0, 0, 0, 0.5); @@ -451,31 +451,31 @@ width: 16px; } -.small-selection .mover { +:-moz-native-anonymous .small-selection .mover { height: 10px; width: 10px; } -.direction-topLeft .mover, -.direction-left .mover, -.direction-bottomLeft .mover { +:-moz-native-anonymous .direction-topLeft .mover, +:-moz-native-anonymous .direction-left .mover, +:-moz-native-anonymous .direction-bottomLeft .mover { left: -1px; } -.direction-topLeft .mover, -.direction-top .mover, -.direction-topRight .mover { +:-moz-native-anonymous .direction-topLeft .mover, +:-moz-native-anonymous .direction-top .mover, +:-moz-native-anonymous .direction-topRight .mover { top: -1px; } -.direction-topRight .mover, -.direction-right .mover, -.direction-bottomRight .mover { +:-moz-native-anonymous .direction-topRight .mover, +:-moz-native-anonymous .direction-right .mover, +:-moz-native-anonymous .direction-bottomRight .mover { right: -1px; } -.direction-bottomRight .mover, -.direction-bottom .mover, -.direction-bottomLeft .mover { +:-moz-native-anonymous .direction-bottomRight .mover, +:-moz-native-anonymous .direction-bottom .mover, +:-moz-native-anonymous .direction-bottomLeft .mover { bottom: -1px; } diff --git a/devtools/client/application/src/components/manifest/ManifestIssue.js b/devtools/client/application/src/components/manifest/ManifestIssue.js index 6a9680d6048e..1cdf62ff8fa2 100644 --- a/devtools/client/application/src/components/manifest/ManifestIssue.js +++ b/devtools/client/application/src/components/manifest/ManifestIssue.js @@ -44,7 +44,7 @@ class ManifestIssue extends PureComponent { case MANIFEST_ISSUE_LEVELS.ERROR: default: return { - src: "resource://devtools-shared-images/error-small.svg", + src: "chrome://devtools/skin/images/error-small.svg", localizationId: "icon-error", }; } diff --git a/devtools/client/application/test/node/components/manifest/__snapshots__/components_application_panel-ManifestIssue.test.js.snap b/devtools/client/application/test/node/components/manifest/__snapshots__/components_application_panel-ManifestIssue.test.js.snap index 99e83af1f22c..3cf46f07b11e 100644 --- a/devtools/client/application/test/node/components/manifest/__snapshots__/components_application_panel-ManifestIssue.test.js.snap +++ b/devtools/client/application/test/node/components/manifest/__snapshots__/components_application_panel-ManifestIssue.test.js.snap @@ -39,7 +39,7 @@ exports[`ManifestIssue renders the expected snapshot for an error 1`] = ` > diff --git a/devtools/client/debugger/src/components/shared/AccessibleImage.css b/devtools/client/debugger/src/components/shared/AccessibleImage.css index e69ec68a6f9d..06b81493250c 100644 --- a/devtools/client/debugger/src/components/shared/AccessibleImage.css +++ b/devtools/client/debugger/src/components/shared/AccessibleImage.css @@ -158,7 +158,7 @@ html[dir="rtl"] .img.more-tabs { } .img.resume { - mask-image: url(resource://devtools-shared-images/resume.svg); + mask-image: url(chrome://devtools/content/shared/images/resume.svg); } .img.search { @@ -182,7 +182,7 @@ html[dir="rtl"] .img.more-tabs { } .img.stepOver { - mask-image: url(resource://devtools-shared-images/stepOver.svg); + mask-image: url(chrome://devtools/content/shared/images/stepOver.svg); } .img.tab { diff --git a/devtools/client/inspector/test/browser_inspector_highlighter-zoom.js b/devtools/client/inspector/test/browser_inspector_highlighter-zoom.js index ba81fde1b8df..f0e3e6a7f168 100644 --- a/devtools/client/inspector/test/browser_inspector_highlighter-zoom.js +++ b/devtools/client/inspector/test/browser_inspector_highlighter-zoom.js @@ -15,11 +15,9 @@ const TEST_LEVELS = [2, 1, 0.5]; // Returns the expected style attribute value to check for on the highlighter's elements // node, for the values given. const expectedStyle = (w, h, z) => - (z !== 1 - ? `transform-origin: left top 0px; transform: scale(${1 / z}); ` - : "") + - `position: absolute; width: ${w * z}px; height: ${h * z}px; ` + - "overflow: hidden;"; + (z !== 1 ? `transform-origin:top left; transform:scale(${1 / z}); ` : "") + + `position:absolute; width:${w * z}px;height:${h * z}px; ` + + "overflow:hidden"; add_task(async function () { const { inspector, highlighterTestFront } = await openInspectorForURL( diff --git a/devtools/client/inspector/test/head.js b/devtools/client/inspector/test/head.js index 7e3de8222cb3..7054d8ec1f39 100644 --- a/devtools/client/inspector/test/head.js +++ b/devtools/client/inspector/test/head.js @@ -814,11 +814,6 @@ function waitForStyleEditor(toolbox, href) { // A helper that resolves the promise once it receives an editor that // matches the expected href. Returns false if the editor was not correct. const gotEditor = editor => { - if (!editor) { - info("Editor went away after selected?"); - return false; - } - const currentHref = editor.styleSheet.href; if (!href || (href && currentHref.endsWith(href))) { info("Stylesheet editor selected"); diff --git a/devtools/client/jar.mn b/devtools/client/jar.mn index fbeafccad115..4bfc7708e3c4 100644 --- a/devtools/client/jar.mn +++ b/devtools/client/jar.mn @@ -147,6 +147,7 @@ devtools.jar: skin/images/alert-tiny.svg (themes/images/alert-tiny.svg) skin/images/arrow-dropdown-12.svg (themes/images/arrow-dropdown-12.svg) skin/images/error.svg (themes/images/error.svg) + skin/images/error-small.svg (themes/images/error-small.svg) skin/images/error-tiny.svg (themes/images/error-tiny.svg) skin/images/info.svg (themes/images/info.svg) skin/images/info-small.svg (themes/images/info-small.svg) diff --git a/devtools/client/netmonitor/src/assets/styles/RequestList.css b/devtools/client/netmonitor/src/assets/styles/RequestList.css index edb4a0e5e6f0..3d1b77fdef43 100644 --- a/devtools/client/netmonitor/src/assets/styles/RequestList.css +++ b/devtools/client/netmonitor/src/assets/styles/RequestList.css @@ -336,7 +336,7 @@ } .security-state-broken { - background-image: url(resource://devtools-shared-images/error-small.svg); + background-image: url(chrome://devtools/skin/images/error-small.svg); width: 16px; fill: var(--theme-icon-error-color); } diff --git a/devtools/client/themes/accessibility-color-contrast.css b/devtools/client/themes/accessibility-color-contrast.css index dcf2a38614d6..a612b0832e78 100644 --- a/devtools/client/themes/accessibility-color-contrast.css +++ b/devtools/client/themes/accessibility-color-contrast.css @@ -42,7 +42,7 @@ height: 12px; content: ""; vertical-align: -2px; - background-image: url(resource://devtools-shared-images/error-small.svg); + background-image: url(chrome://devtools/skin/images/error-small.svg); background-position: center; background-repeat: no-repeat; -moz-context-properties: fill; diff --git a/devtools/client/themes/animation.css b/devtools/client/themes/animation.css index f244d5dad5f1..b6b581bc3e38 100644 --- a/devtools/client/themes/animation.css +++ b/devtools/client/themes/animation.css @@ -750,5 +750,5 @@ select.playback-rate-selector.devtools-button:not(:empty, :disabled, .checked):h } .animation-element-picker::before { - background-image: url("resource://devtools-shared-images/command-pick.svg"); + background-image: url("chrome://devtools/content/shared/images/command-pick.svg"); } diff --git a/devtools/shared/images/error-small.svg b/devtools/client/themes/images/error-small.svg similarity index 100% rename from devtools/shared/images/error-small.svg rename to devtools/client/themes/images/error-small.svg diff --git a/devtools/client/themes/toolbox.css b/devtools/client/themes/toolbox.css index 86f78d28097e..b7ddb98b87e9 100644 --- a/devtools/client/themes/toolbox.css +++ b/devtools/client/themes/toolbox.css @@ -473,7 +473,7 @@ } .toolbox-error::before { - background-image: url("resource://devtools-shared-images/error-small.svg"); + background-image: url("chrome://devtools/skin/images/error-small.svg"); fill: var(--theme-icon-error-color) !important; } @@ -488,7 +488,7 @@ } #command-button-pick::before { - background-image: url("resource://devtools-shared-images/command-pick.svg"); + background-image: url("chrome://devtools/content/shared/images/command-pick.svg"); } #command-button-pick.accessibility::before { @@ -496,7 +496,7 @@ } #command-button-pick.remote-fenix::before { - background-image: url("resource://devtools-shared-images/command-pick-remote-touch.svg"); + background-image: url("chrome://devtools/content/shared/images/command-pick-remote-touch.svg"); } /* Command button images */ diff --git a/devtools/client/themes/webconsole.css b/devtools/client/themes/webconsole.css index 2ab1c1d02747..87a40226e553 100644 --- a/devtools/client/themes/webconsole.css +++ b/devtools/client/themes/webconsole.css @@ -296,7 +296,7 @@ .message.error > .icon { color: var(--theme-icon-error-color); - background-image: url(resource://devtools-shared-images/error-small.svg); + background-image: url(chrome://devtools/skin/images/error-small.svg); } .message.warn > .icon { diff --git a/devtools/server/actors/highlighters/css/highlighters.css b/devtools/server/actors/highlighters.css similarity index 56% rename from devtools/server/actors/highlighters/css/highlighters.css rename to devtools/server/actors/highlighters.css index 1551778e7349..c0b51ac6dc75 100644 --- a/devtools/server/actors/highlighters/css/highlighters.css +++ b/devtools/server/actors/highlighters.css @@ -2,9 +2,31 @@ * 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/. */ -:host { display: contents; } +/* + The :-moz-native-anonymous selector prefix prevents the styles defined here + from impacting web content. Indeed, this pseudo-class is only available to chrome code. + This stylesheet is loaded as a ua stylesheet via the addon sdk, so having this + pseudo-class is important. -.highlighter-container { + A specific selector should still be specified to avoid impacting non-devtools + chrome content. +*/ + +:-moz-native-anonymous .highlighter-container { + /* + Content CSS applying to the html element impact the highlighters. + To avoid that, possible cases have been set to initial. + */ + text-transform: initial; + text-indent: initial; + letter-spacing: initial; + word-spacing: initial; + color: initial; + direction: initial; + writing-mode: initial; +} + +:-moz-native-anonymous .highlighter-container { --highlighter-accessibility-bounds-color: #6a5acd; --highlighter-accessibility-bounds-opacity: 0.6; --highlighter-box-border-color: #444444; @@ -19,6 +41,7 @@ --highlighter-font-size: 11px; --highlighter-guide-color: hsl(200, 100%, 40%); --highlighter-infobar-color: hsl(210, 30%, 85%); + --highlighter-marker-color: #000; --grey-40: #b1b1b3; --red-40: #ff3b6b; @@ -27,14 +50,14 @@ } /** - * Highlighters are absolute positioned in the page by default. + * Highlighters are asbolute positioned in the page by default. * A single highlighter can have fixed position in its css class if needed (see below the * eye dropper or rulers highlighter, for example); but if it has to handle the * document's scrolling (as rulers does), it would lag a bit behind due the APZ (Async * Pan/Zoom module), that performs asynchronously panning and zooming on the compositor * thread rather than the main thread. */ -.highlighter-container { +:-moz-native-anonymous .highlighter-container { position: absolute; width: 100%; height: 100%; @@ -46,66 +69,66 @@ pointer-events: none; } -.highlighter-container.box-model { +:-moz-native-anonymous .highlighter-container.box-model { /* Make the box-model container have a z-index other than auto so it always sits above other highlighters. */ z-index: 1; } -.highlighter-container [hidden] { - display: none !important; +:-moz-native-anonymous .highlighter-container [hidden] { + display: none; } -.highlighter-container [dragging] { +:-moz-native-anonymous .highlighter-container [dragging] { cursor: grabbing; } /* Box Model Highlighter */ -.box-model-regions { +:-moz-native-anonymous .box-model-regions { opacity: 0.6; } /* Box model regions can be faded (see the onlyRegionArea option in highlighters.js) in order to only display certain regions. */ -.box-model-regions [faded] { +:-moz-native-anonymous .box-model-regions [faded] { display: none; } -.box-model-content { +:-moz-native-anonymous .box-model-content { fill: var(--highlighter-box-content-color); } -.box-model-padding { +:-moz-native-anonymous .box-model-padding { fill: var(--highlighter-box-padding-color); } -.box-model-border { +:-moz-native-anonymous .box-model-border { fill: var(--highlighter-box-border-color); } -.box-model-margin { +:-moz-native-anonymous .box-model-margin { fill: var(--highlighter-box-margin-color); } -.box-model-content, -.box-model-padding, -.box-model-border, -.box-model-margin { +:-moz-native-anonymous .box-model-content, +:-moz-native-anonymous .box-model-padding, +:-moz-native-anonymous .box-model-border, +:-moz-native-anonymous .box-model-margin { stroke: none; } -.box-model-guide-top, -.box-model-guide-right, -.box-model-guide-bottom, -.box-model-guide-left { +:-moz-native-anonymous .box-model-guide-top, +:-moz-native-anonymous .box-model-guide-right, +:-moz-native-anonymous .box-model-guide-bottom, +:-moz-native-anonymous .box-model-guide-left { stroke: var(--highlighter-guide-color); stroke-dasharray: 5 3; shape-rendering: crispEdges; } @media (prefers-reduced-motion) { - .use-simple-highlighters :is( + :-moz-native-anonymous .use-simple-highlighters :is( .box-model-content, .box-model-padding, .box-model-border, @@ -115,26 +138,26 @@ stroke-width: 3; } - .use-simple-highlighters .box-model-content { + :-moz-native-anonymous .use-simple-highlighters .box-model-content { stroke: var(--highlighter-box-content-color); } - .use-simple-highlighters .box-model-padding { + :-moz-native-anonymous .use-simple-highlighters .box-model-padding { stroke: var(--highlighter-box-padding-color); } - .use-simple-highlighters .box-model-border { + :-moz-native-anonymous .use-simple-highlighters .box-model-border { stroke: var(--highlighter-box-border-color); } - .use-simple-highlighters .box-model-margin { + :-moz-native-anonymous .use-simple-highlighters .box-model-margin { stroke: var(--highlighter-box-margin-color); } } /* Highlighter - Infobar */ -[class$="infobar-container"] { +:-moz-native-anonymous [class$="infobar-container"] { position: absolute; max-width: 95%; @@ -142,7 +165,7 @@ font-size: var(--highlighter-font-size); } -[class$="infobar"] { +:-moz-native-anonymous [class$="infobar"] { position: relative; padding: 5px; @@ -159,19 +182,21 @@ /* Arrows */ -[class$="infobar-container"] > [class$="infobar"]:before { +:-moz-native-anonymous + [class$="infobar-container"] + > [class$="infobar"]:before { left: calc(50% - var(--highlighter-bubble-arrow-size)); border: var(--highlighter-bubble-arrow-size) solid var(--highlighter-bubble-border-color); } -[class$="infobar-container"] > [class$="infobar"]:after { +:-moz-native-anonymous [class$="infobar-container"] > [class$="infobar"]:after { left: calc(50% - 7px); border: 7px solid var(--highlighter-bubble-background-color); } -[class$="infobar-container"] > [class$="infobar"]:before, -[class$="infobar-container"] > [class$="infobar"]:after { +:-moz-native-anonymous [class$="infobar-container"] > [class$="infobar"]:before, +:-moz-native-anonymous [class$="infobar-container"] > [class$="infobar"]:after { content: ""; display: none; position: absolute; @@ -181,18 +206,22 @@ border-right-color: transparent; } -[class$="infobar-container"][position="top"]:not([hide-arrow]) +:-moz-native-anonymous + [class$="infobar-container"][position="top"]:not([hide-arrow]) > [class$="infobar"]:before, -[class$="infobar-container"][position="top"]:not([hide-arrow]) +:-moz-native-anonymous + [class$="infobar-container"][position="top"]:not([hide-arrow]) > [class$="infobar"]:after { border-bottom: 0; top: 100%; display: block; } -[class$="infobar-container"][position="bottom"]:not([hide-arrow]) +:-moz-native-anonymous + [class$="infobar-container"][position="bottom"]:not([hide-arrow]) > [class$="infobar"]:before, -[class$="infobar-container"][position="bottom"]:not([hide-arrow]) +:-moz-native-anonymous + [class$="infobar-container"][position="bottom"]:not([hide-arrow]) > [class$="infobar"]:after { border-top: 0; bottom: 100%; @@ -201,7 +230,7 @@ /* Text Container */ -[class$="infobar-text"] { +:-moz-native-anonymous [class$="infobar-text"] { overflow: hidden; white-space: nowrap; direction: ltr; @@ -211,48 +240,48 @@ max-width: 768px; } -.box-model-infobar-tagname { +:-moz-native-anonymous .box-model-infobar-tagname { color: hsl(285, 100%, 75%); } -.box-model-infobar-id { +:-moz-native-anonymous .box-model-infobar-id { color: hsl(103, 46%, 54%); overflow: hidden; text-overflow: ellipsis; } -.box-model-infobar-classes, -.box-model-infobar-pseudo-classes { +:-moz-native-anonymous .box-model-infobar-classes, +:-moz-native-anonymous .box-model-infobar-pseudo-classes { color: hsl(200, 74%, 57%); overflow: hidden; text-overflow: ellipsis; } -[class$="infobar-dimensions"], -[class$="infobar-grid-type"], -[class$="infobar-flex-type"] { +:-moz-native-anonymous [class$="infobar-dimensions"], +:-moz-native-anonymous [class$="infobar-grid-type"], +:-moz-native-anonymous [class$="infobar-flex-type"] { border-inline-start: 1px solid #5a6169; margin-inline-start: 6px; padding-inline-start: 6px; } -[class$="infobar-grid-type"]:empty, -[class$="infobar-flex-type"]:empty { +:-moz-native-anonymous [class$="infobar-grid-type"]:empty, +:-moz-native-anonymous [class$="infobar-flex-type"]:empty { display: none; } -[class$="infobar-dimensions"] { +:-moz-native-anonymous [class$="infobar-dimensions"] { color: var(--highlighter-infobar-color); } -[class$="infobar-grid-type"], -[class$="infobar-flex-type"] { +:-moz-native-anonymous [class$="infobar-grid-type"], +:-moz-native-anonymous [class$="infobar-flex-type"] { color: var(--grey-40); } /* CSS Grid Highlighter */ -.css-grid-canvas { +:-moz-native-anonymous .css-grid-canvas { position: absolute; pointer-events: none; top: 0; @@ -260,23 +289,23 @@ image-rendering: -moz-crisp-edges; } -.css-grid-regions { +:-moz-native-anonymous .css-grid-regions { opacity: 0.6; } -.css-grid-areas, -.css-grid-cells { +:-moz-native-anonymous .css-grid-areas, +:-moz-native-anonymous .css-grid-cells { opacity: 0.5; stroke: none; } -.css-grid-area-infobar-name, -.css-grid-cell-infobar-position, -.css-grid-line-infobar-number { +:-moz-native-anonymous .css-grid-area-infobar-name, +:-moz-native-anonymous .css-grid-cell-infobar-position, +:-moz-native-anonymous .css-grid-line-infobar-number { color: hsl(285, 100%, 75%); } -.css-grid-line-infobar-names:not(:empty) { +:-moz-native-anonymous .css-grid-line-infobar-names:not(:empty) { color: var(--highlighter-infobar-color); border-inline-start: 1px solid #5a6169; margin-inline-start: 6px; @@ -285,19 +314,19 @@ /* CSS Transform Highlighter */ -.css-transform-transformed { +:-moz-native-anonymous .css-transform-transformed { fill: var(--highlighter-box-content-color); opacity: 0.8; } -.css-transform-untransformed { +:-moz-native-anonymous .css-transform-untransformed { fill: #66cc52; opacity: 0.8; } -.css-transform-transformed, -.css-transform-untransformed, -.css-transform-line { +:-moz-native-anonymous .css-transform-transformed, +:-moz-native-anonymous .css-transform-untransformed, +:-moz-native-anonymous .css-transform-line { stroke: var(--highlighter-guide-color); stroke-dasharray: 5 3; stroke-width: 2; @@ -305,67 +334,67 @@ /* Element Geometry Highlighter */ -.geometry-editor-root { +:-moz-native-anonymous .geometry-editor-root { /* The geometry editor can be interacted with, so it needs to react to pointer events */ pointer-events: auto; user-select: none; } -.geometry-editor-offset-parent { +:-moz-native-anonymous .geometry-editor-offset-parent { stroke: var(--highlighter-guide-color); shape-rendering: crispEdges; stroke-dasharray: 5 3; fill: transparent; } -.geometry-editor-current-node { +:-moz-native-anonymous .geometry-editor-current-node { stroke: var(--highlighter-guide-color); fill: var(--highlighter-box-content-color); shape-rendering: crispEdges; opacity: 0.6; } -.geometry-editor-arrow { +:-moz-native-anonymous .geometry-editor-arrow { stroke: var(--highlighter-guide-color); shape-rendering: crispEdges; } -.geometry-editor-root circle { +:-moz-native-anonymous .geometry-editor-root circle { stroke: var(--highlighter-guide-color); fill: var(--highlighter-box-content-color); } -.geometry-editor-handler-top, -.geometry-editor-handler-bottom { +:-moz-native-anonymous .geometry-editor-handler-top, +:-moz-native-anonymous .geometry-editor-handler-bottom { cursor: ns-resize; } -.geometry-editor-handler-right, -.geometry-editor-handler-left { +:-moz-native-anonymous .geometry-editor-handler-right, +:-moz-native-anonymous .geometry-editor-handler-left { cursor: ew-resize; } -[dragging] .geometry-editor-handler-top, -[dragging] .geometry-editor-handler-right, -[dragging] .geometry-editor-handler-bottom, -[dragging] .geometry-editor-handler-left { +:-moz-native-anonymous [dragging] .geometry-editor-handler-top, +:-moz-native-anonymous [dragging] .geometry-editor-handler-right, +:-moz-native-anonymous [dragging] .geometry-editor-handler-bottom, +:-moz-native-anonymous [dragging] .geometry-editor-handler-left { cursor: grabbing; } -.geometry-editor-handler-top.dragging, -.geometry-editor-handler-right.dragging, -.geometry-editor-handler-bottom.dragging, -.geometry-editor-handler-left.dragging { +:-moz-native-anonymous .geometry-editor-handler-top.dragging, +:-moz-native-anonymous .geometry-editor-handler-right.dragging, +:-moz-native-anonymous .geometry-editor-handler-bottom.dragging, +:-moz-native-anonymous .geometry-editor-handler-left.dragging { fill: var(--highlighter-guide-color); } -.geometry-editor-label-bubble { +:-moz-native-anonymous .geometry-editor-label-bubble { fill: var(--highlighter-bubble-background-color); shape-rendering: crispEdges; } -.geometry-editor-label-text { +:-moz-native-anonymous .geometry-editor-label-text { fill: var(--highlighter-bubble-text-color); font: var(--highlighter-font-family); font-size: 10px; @@ -375,7 +404,7 @@ /* Rulers Highlighter */ -.rulers-highlighter-elements { +:-moz-native-anonymous .rulers-highlighter-elements { shape-rendering: crispEdges; pointer-events: none; position: fixed; @@ -383,24 +412,24 @@ left: 0; } -.rulers-highlighter-elements > g { +:-moz-native-anonymous .rulers-highlighter-elements > g { opacity: 0.8; } -.rulers-highlighter-elements > g > rect { +:-moz-native-anonymous .rulers-highlighter-elements > g > rect { fill: #fff; } -.rulers-highlighter-ruler-graduations { +:-moz-native-anonymous .rulers-highlighter-ruler-graduations { stroke: #bebebe; } -.rulers-highlighter-ruler-markers { +:-moz-native-anonymous .rulers-highlighter-ruler-markers { stroke: #202020; } -.rulers-highlighter-horizontal-labels > text, -.rulers-highlighter-vertical-labels > text { +:-moz-native-anonymous .rulers-highlighter-horizontal-labels > text, +:-moz-native-anonymous .rulers-highlighter-vertical-labels > text { stroke: none; fill: #202020; font: var(--highlighter-font-family); @@ -408,16 +437,16 @@ dominant-baseline: hanging; } -.rulers-highlighter-horizontal-labels > text { +:-moz-native-anonymous .rulers-highlighter-horizontal-labels > text { text-anchor: start; } -.rulers-highlighter-vertical-labels > text { +:-moz-native-anonymous .rulers-highlighter-vertical-labels > text { transform: rotate(-90deg); text-anchor: end; } -.viewport-size-highlighter-viewport-infobar-container { +:-moz-native-anonymous .viewport-size-highlighter-viewport-infobar-container { shape-rendering: crispEdges; background-color: rgba(255, 255, 255, 0.7); font: var(--highlighter-font-family); @@ -430,11 +459,11 @@ /* Measuring Tool Highlighter */ -.measuring-tool-tool { +:-moz-native-anonymous .measuring-tool-tool { pointer-events: auto; } -.measuring-tool-root { +:-moz-native-anonymous .measuring-tool-root { position: absolute; top: 0; left: 0; @@ -442,69 +471,69 @@ cursor: crosshair; } -.measuring-tool-elements { +:-moz-native-anonymous .measuring-tool-elements { position: absolute; } -.measuring-tool-root path { +:-moz-native-anonymous .measuring-tool-root path { shape-rendering: geometricPrecision; pointer-events: auto; } -.measuring-tool-root .measuring-tool-box-path, -.measuring-tool-root .measuring-tool-diagonal-path { +:-moz-native-anonymous .measuring-tool-root .measuring-tool-box-path, +:-moz-native-anonymous .measuring-tool-root .measuring-tool-diagonal-path { fill: rgba(135, 206, 235, 0.6); stroke: var(--highlighter-guide-color); } -.measuring-tool-root circle { +:-moz-native-anonymous .measuring-tool-root circle { stroke: var(--highlighter-guide-color); stroke-width: 2px; fill: #fff; vector-effect: non-scaling-stroke; } -.measuring-tool-handler-top, -.measuring-tool-handler-bottom { +:-moz-native-anonymous .measuring-tool-handler-top, +:-moz-native-anonymous .measuring-tool-handler-bottom { cursor: ns-resize; } -.measuring-tool-handler-right, -.measuring-tool-handler-left { +:-moz-native-anonymous .measuring-tool-handler-right, +:-moz-native-anonymous .measuring-tool-handler-left { cursor: ew-resize; } -.measuring-tool-handler-topleft, -.measuring-tool-handler-bottomright { +:-moz-native-anonymous .measuring-tool-handler-topleft, +:-moz-native-anonymous .measuring-tool-handler-bottomright { cursor: nwse-resize; } -.measuring-tool-handler-topright, -.measuring-tool-handler-bottomleft { +:-moz-native-anonymous .measuring-tool-handler-topright, +:-moz-native-anonymous .measuring-tool-handler-bottomleft { cursor: nesw-resize; } -.mirrored .measuring-tool-handler-topleft, -.mirrored .measuring-tool-handler-bottomright { +:-moz-native-anonymous .mirrored .measuring-tool-handler-topleft, +:-moz-native-anonymous .mirrored .measuring-tool-handler-bottomright { cursor: nesw-resize; } -.mirrored .measuring-tool-handler-topright, -.mirrored .measuring-tool-handler-bottomleft { +:-moz-native-anonymous .mirrored .measuring-tool-handler-topright, +:-moz-native-anonymous .mirrored .measuring-tool-handler-bottomleft { cursor: nwse-resize; } -[class^=measuring-tool-handler].dragging { +:-moz-native-anonymous [class^=measuring-tool-handler].dragging { fill: var(--highlighter-guide-color); } -.dragging .measuring-tool-box-path, -.dragging .measuring-tool-diagonal-path { +:-moz-native-anonymous .dragging .measuring-tool-box-path, +:-moz-native-anonymous .dragging .measuring-tool-diagonal-path { opacity: 0.45; } -.measuring-tool-label-size, -.measuring-tool-label-position { +:-moz-native-anonymous .measuring-tool-label-size, +:-moz-native-anonymous .measuring-tool-label-position { position: absolute; top: 0; left: 0; @@ -519,19 +548,19 @@ box-sizing: border-box; } -.measuring-tool-label-position { +:-moz-native-anonymous .measuring-tool-label-position { color: #fff; background: hsla(214, 13%, 24%, 0.8); } -.measuring-tool-label-size { +:-moz-native-anonymous .measuring-tool-label-size { color: var(--highlighter-bubble-text-color); background: var(--highlighter-bubble-background-color); border: 1px solid var(--highlighter-bubble-border-color); line-height: 1.5em; } -[class^=measuring-tool-guide] { +:-moz-native-anonymous [class^=measuring-tool-guide] { stroke: var(--highlighter-guide-color); stroke-dasharray: 5 3; shape-rendering: crispEdges; @@ -539,7 +568,7 @@ /* Eye Dropper */ -.eye-dropper-root { +:-moz-native-anonymous .eye-dropper-root { --magnifier-width: 96px; --magnifier-height: 96px; /* Width accounts for all color formats (hsl being the longest) */ @@ -569,7 +598,7 @@ direction: ltr; } -.eye-dropper-canvas { +:-moz-native-anonymous .eye-dropper-canvas { image-rendering: -moz-crisp-edges; cursor: none; width: var(--magnifier-width); @@ -579,7 +608,7 @@ display: block; } -.eye-dropper-color-container { +:-moz-native-anonymous .eye-dropper-color-container { background-color: var(--background-color); border-radius: 2px; width: var(--label-width); @@ -604,31 +633,33 @@ } /* If there isn't enough space below the canvas, we move the label container to the top */ -.eye-dropper-root[top] .eye-dropper-color-container { +:-moz-native-anonymous .eye-dropper-root[top] .eye-dropper-color-container { transform: var(--label-horizontal-center) var(--label-vertical-top); } /* If there isn't enough space right of the canvas to horizontally center the label container, offset it to the left */ -.eye-dropper-root[left] .eye-dropper-color-container { +:-moz-native-anonymous .eye-dropper-root[left] .eye-dropper-color-container { transform: var(--label-horizontal-left); } - -.eye-dropper-root[left][top] .eye-dropper-color-container { +:-moz-native-anonymous + .eye-dropper-root[left][top] + .eye-dropper-color-container { transform: var(--label-horizontal-left) var(--label-vertical-top); } /* If there isn't enough space left of the canvas to horizontally center the label container, offset it to the right */ -.eye-dropper-root[right] .eye-dropper-color-container { +:-moz-native-anonymous .eye-dropper-root[right] .eye-dropper-color-container { transform: var(--label-horizontal-right); } - -.eye-dropper-root[right][top] .eye-dropper-color-container { +:-moz-native-anonymous + .eye-dropper-root[right][top] + .eye-dropper-color-container { transform: var(--label-horizontal-right) var(--label-vertical-top); } -.eye-dropper-color-preview { +:-moz-native-anonymous .eye-dropper-color-preview { width: 16px; height: 16px; position: absolute; @@ -638,7 +669,7 @@ border: solid 1px #fff; } -.eye-dropper-color-value { +:-moz-native-anonymous .eye-dropper-color-value { text-shadow: 1px 1px 1px #fff; font: var(--highlighter-font-family); font-size: var(--highlighter-font-size); @@ -648,10 +679,11 @@ /* Paused Debugger Overlay */ -.paused-dbg-root { +:-moz-native-anonymous .paused-dbg-root { position: fixed; top: 0; left: 0; + zoom: 1; right: 0; bottom: 0; @@ -671,12 +703,12 @@ --overlay-background: #dde1e4a8; } -.paused-dbg-root[overlay] { +:-moz-native-anonymous .paused-dbg-root[overlay] { background-color: var(--overlay-background); pointer-events: auto; } -.paused-dbg-toolbar { +:-moz-native-anonymous .paused-dbg-toolbar { /* Show the toolbar at the top, but not too high to prevent it overlaping OS toolbar on Android */ margin-top: 30px; display: inline-flex; @@ -692,7 +724,7 @@ font-size: var(--highlighter-font-size); } -.paused-dbg-toolbar button { +:-moz-native-anonymous .paused-dbg-toolbar button { margin: 8px 4px 6px 6px; width: 16px; height: 16px; @@ -705,46 +737,46 @@ appearance: none; } -.paused-dbg-divider { +:-moz-native-anonymous .paused-dbg-divider { width: 1px; height: 16px; margin-top: 10px; background-color: var(--toolbar-border); } -.paused-dbg-reason, -.paused-dbg-step-button-wrapper, -.paused-dbg-resume-button-wrapper { +:-moz-native-anonymous .paused-dbg-reason, +:-moz-native-anonymous .paused-dbg-step-button-wrapper, +:-moz-native-anonymous .paused-dbg-resume-button-wrapper { margin-top: 2px; margin-bottom: 2px; } -.paused-dbg-step-button-wrapper, -.paused-dbg-resume-button-wrapper { +:-moz-native-anonymous .paused-dbg-step-button-wrapper, +:-moz-native-anonymous .paused-dbg-resume-button-wrapper { margin-left: 2px; margin-right: 2px; } -button.paused-dbg-step-button { +:-moz-native-anonymous button.paused-dbg-step-button { margin-left: 6px; margin-right: 6px; - mask-image: url(resource://devtools-shared-images/stepOver.svg); + mask-image: url(chrome://devtools/content/shared/images/stepOver.svg); padding: 0; } -button.paused-dbg-resume-button { +:-moz-native-anonymous button.paused-dbg-resume-button { margin-right: 6px; - mask-image: url(resource://devtools-shared-images/resume.svg); + mask-image: url(chrome://devtools/content/shared/images/resume.svg); padding: 0; } -.paused-dbg-step-button-wrapper.hover, -.paused-dbg-resume-button-wrapper.hover { +:-moz-native-anonymous .paused-dbg-step-button-wrapper.hover, +:-moz-native-anonymous .paused-dbg-resume-button-wrapper.hover { background-color: var(--toolbar-border); border-radius: 2px; } -.paused-dbg-reason { +:-moz-native-anonymous .paused-dbg-reason { padding: 3px 16px; margin: 8px 0px; font: var(--highlighter-font-family); @@ -754,13 +786,14 @@ button.paused-dbg-resume-button { /* Remote Node Picker Notice Highlighter */ -#node-picker-notice-root { +:-moz-native-anonymous #node-picker-notice-root { position: fixed; max-width: 100vw; /* Position at the bottom of the screen so it doesn't get into the user's way */ bottom: 0; left: 0; right: 0; + zoom: 1; z-index: 2; @@ -777,11 +810,11 @@ button.paused-dbg-resume-button { --toolbar-box-shadow: 0 2px 2px 0 rgba(155, 155, 155, 0.26); /* --rdm-box-shadow */ } -#node-picker-notice-root[overlay] { +:-moz-native-anonymous #node-picker-notice-root[overlay] { pointer-events: auto; } -#node-picker-notice-toolbar { +:-moz-native-anonymous #node-picker-notice-toolbar { display: flex; align-items: center; gap: 8px; @@ -800,17 +833,17 @@ button.paused-dbg-resume-button { user-select: none; } -#node-picker-notice-info { +:-moz-native-anonymous #node-picker-notice-info { font: var(--highlighter-font-family); font-size: var(--highlighter-font-size); text-align: center; } -#node-picker-notice-icon { +:-moz-native-anonymous #node-picker-notice-icon { width: 16px; height: 16px; - background-image: url(resource://devtools-shared-images/command-pick.svg); + background-image: url(chrome://devtools/content/shared/images/command-pick.svg); -moz-context-properties: fill; fill: currentColor; @@ -818,12 +851,12 @@ button.paused-dbg-resume-button { background-repeat: no-repeat; } -#node-picker-notice-icon.touch { - background-image: url(resource://devtools-shared-images/command-pick-remote-touch.svg); +:-moz-native-anonymous #node-picker-notice-icon.touch { + background-image: url(chrome://devtools/content/shared/images/command-pick-remote-touch.svg); } -#node-picker-notice-hide-button { +:-moz-native-anonymous #node-picker-notice-hide-button { border: 0px; border-radius: 2px; appearance: none; @@ -834,52 +867,52 @@ button.paused-dbg-resume-button { } /* We can't use :hover as it wouldn't work if the page is paused, so we add a specific class for this */ -#node-picker-notice-hide-button.hover { +:-moz-native-anonymous #node-picker-notice-hide-button.hover { background-color: var(--toolbar-button-hover-background); } /* Shapes highlighter */ -.shapes-root { +:-moz-native-anonymous .shapes-root { pointer-events: none; } -.shapes-shape-container { +:-moz-native-anonymous .shapes-shape-container { position: absolute; overflow: visible; } -.shapes-polygon, -.shapes-ellipse, -.shapes-rect, -.shapes-bounding-box, -.shapes-rotate-line, -.shapes-quad { +:-moz-native-anonymous .shapes-polygon, +:-moz-native-anonymous .shapes-ellipse, +:-moz-native-anonymous .shapes-rect, +:-moz-native-anonymous .shapes-bounding-box, +:-moz-native-anonymous .shapes-rotate-line, +:-moz-native-anonymous .shapes-quad { fill: transparent; stroke: var(--highlighter-guide-color); shape-rendering: geometricPrecision; vector-effect: non-scaling-stroke; } -.shapes-markers { +:-moz-native-anonymous .shapes-markers { fill: #fff; } -.shapes-markers-outline { +:-moz-native-anonymous .shapes-markers-outline { fill: var(--highlighter-guide-color); } -.shapes-marker-hover { +:-moz-native-anonymous .shapes-marker-hover { fill: var(--highlighter-guide-color); } /* Accessible highlighter */ -.accessible-infobar { +:-moz-native-anonymous .accessible-infobar { min-width: unset; } -.accessible-infobar-text { +:-moz-native-anonymous .accessible-infobar-text { display: grid; grid-template-areas: "role name" @@ -887,46 +920,46 @@ button.paused-dbg-resume-button { grid-template-columns: min-content 1fr; } -.accessible-infobar-role { +:-moz-native-anonymous .accessible-infobar-role { grid-area: role; color: #9cdcfe; } -.accessible-infobar-name { +:-moz-native-anonymous .accessible-infobar-name { grid-area: name; } -.accessible-infobar-audit { +:-moz-native-anonymous .accessible-infobar-audit { grid-area: audit; padding-top: 5px; padding-bottom: 2px; } -.accessible-bounds { +:-moz-native-anonymous .accessible-bounds { fill: var(--highlighter-accessibility-bounds-color); opacity: var(--highlighter-accessibility-bounds-opacity); } @media (prefers-reduced-motion) { - .use-simple-highlighters .accessible-bounds { + :-moz-native-anonymous .use-simple-highlighters .accessible-bounds { fill: none; stroke: var(--highlighter-accessibility-bounds-color); stroke-width: 3; } } -.accessible-infobar-name, -.accessible-infobar-audit { +:-moz-native-anonymous .accessible-infobar-name, +:-moz-native-anonymous .accessible-infobar-audit { color: var(--highlighter-infobar-color); } -.accessible-infobar-audit .accessible-contrast-ratio:empty::before, -.accessible-infobar-audit .accessible-contrast-ratio:empty::after, -.accessible-infobar-name:empty { +:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:empty::before, +:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:empty::after, +:-moz-native-anonymous .accessible-infobar-name:empty { display: none; } -.accessible-infobar-audit .accessible-contrast-ratio::before { +:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio::before { content: ""; height: 8px; width: 8px; @@ -939,17 +972,17 @@ button.paused-dbg-resume-button { margin-inline-end: 9px; } -.accessible-infobar-audit .accessible-contrast-ratio::after { +:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio::after { margin-inline-start: 2px; } -.accessible-infobar-audit .accessible-contrast-ratio.AA::after, -.accessible-infobar-audit .accessible-contrast-ratio.AAA::after { +:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio.AA::after, +:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio.AAA::after { color: #90E274; } -.accessible-infobar-audit .accessible-audit::before, -.accessible-infobar-audit .accessible-contrast-ratio.FAIL::after { +:-moz-native-anonymous .accessible-infobar-audit .accessible-audit::before, +:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio.FAIL::after { display: inline-block; width: 12px; height: 12px; @@ -960,61 +993,61 @@ button.paused-dbg-resume-button { -moz-context-properties: fill; } -.accessible-infobar-audit .accessible-contrast-ratio.FAIL:after { +:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio.FAIL:after { color: #E57180; margin-inline-start: 3px; - background-image: url(resource://devtools-shared-images/error-small.svg); + background-image: url(chrome://devtools/skin/images/error-small.svg); fill: var(--red-40); } -.accessible-infobar-audit .accessible-contrast-ratio.AA::after { +:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio.AA::after { content: "AA\2713"; } -.accessible-infobar-audit .accessible-contrast-ratio.AAA::after { +:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio.AAA::after { content: "AAA\2713"; } -.accessible-infobar-audit .accessible-contrast-ratio-label, -.accessible-infobar-audit .accessible-contrast-ratio-separator::before { +:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio-label, +:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio-separator::before { margin-inline-end: 3px; } -.accessible-infobar-audit .accessible-contrast-ratio-separator::before { +:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio-separator::before { content: "-"; margin-inline-start: 3px; } -.accessible-infobar-audit .accessible-audit { +:-moz-native-anonymous .accessible-infobar-audit .accessible-audit { display: block; padding-block-end: 5px; } -.accessible-infobar-audit .accessible-audit:last-child { +:-moz-native-anonymous .accessible-infobar-audit .accessible-audit:last-child { padding-block-end: 0; } -.accessible-infobar-audit .accessible-audit::before { +:-moz-native-anonymous .accessible-infobar-audit .accessible-audit::before { margin-inline-end: 4px; background-image: none; fill: currentColor; } -.accessible-infobar-audit .accessible-audit.FAIL::before { - background-image: url(resource://devtools-shared-images/error-small.svg); +:-moz-native-anonymous .accessible-infobar-audit .accessible-audit.FAIL::before { + background-image: url(chrome://devtools/skin/images/error-small.svg); fill: var(--red-40); } -.accessible-infobar-audit .accessible-audit.WARNING::before { +:-moz-native-anonymous .accessible-infobar-audit .accessible-audit.WARNING::before { background-image: url(chrome://devtools/skin/images/alert-small.svg); fill: var(--yellow-60); } -.accessible-infobar-audit .accessible-audit.BEST_PRACTICES::before { +:-moz-native-anonymous .accessible-infobar-audit .accessible-audit.BEST_PRACTICES::before { background-image: url(chrome://devtools/skin/images/info-small.svg); } -.accessible-infobar-name { +:-moz-native-anonymous .accessible-infobar-name { border-inline-start: 1px solid #5a6169; margin-inline-start: 6px; padding-inline-start: 6px; @@ -1022,34 +1055,34 @@ button.paused-dbg-resume-button { /* Tabbing-order highlighter */ -.tabbing-order-infobar { +:-moz-native-anonymous .tabbing-order-infobar { min-width: unset; } -.tabbing-order .tabbing-order-infobar-container { +:-moz-native-anonymous .tabbing-order .tabbing-order-infobar-container { font-size:calc(var(--highlighter-font-size) + 2px); } -.tabbing-order .tabbing-order-bounds { +:-moz-native-anonymous .tabbing-order .tabbing-order-bounds { position: absolute; display: block; outline: 2px solid #000; outline-offset: -2px; } -.tabbing-order.focused .tabbing-order-bounds { +:-moz-native-anonymous .tabbing-order.focused .tabbing-order-bounds { outline-color: var(--blue-60); } -.tabbing-order.focused .tabbing-order-infobar { +:-moz-native-anonymous .tabbing-order.focused .tabbing-order-infobar { background-color: var(--blue-60); } -.tabbing-order.focused .tabbing-order-infobar-text { +:-moz-native-anonymous .tabbing-order.focused .tabbing-order-infobar-text { text-decoration: underline; } -.tabbing-order.focused .tabbing-order-infobar:after { +:-moz-native-anonymous .tabbing-order.focused .tabbing-order-infobar:after { border-top-color: var(--blue-60); border-bottom-color: var(--blue-60); } diff --git a/devtools/server/actors/highlighters/css-grid.js b/devtools/server/actors/highlighters/css-grid.js index 04c612eb02a6..a3b4ebbaf40c 100644 --- a/devtools/server/actors/highlighters/css-grid.js +++ b/devtools/server/actors/highlighters/css-grid.js @@ -1801,10 +1801,7 @@ class CssGridHighlighter extends AutoRefreshHighlighter { setIgnoreLayoutChanges(true); // Set z-index. - this.markup.content.root.firstElementChild.style.setProperty( - "z-index", - this.options.zIndex - ); + this.markup.content.setStyle("z-index", this.options.zIndex); const root = this.getElement("root"); const cells = this.getElement("cells"); diff --git a/devtools/server/actors/highlighters/css/moz.build b/devtools/server/actors/highlighters/css/moz.build deleted file mode 100644 index 6bdf0f9579fd..000000000000 --- a/devtools/server/actors/highlighters/css/moz.build +++ /dev/null @@ -1,9 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -DevToolsModules( - "highlighters.css", -) diff --git a/devtools/server/actors/highlighters/moz.build b/devtools/server/actors/highlighters/moz.build index eeaca8999282..d5005ea79ebb 100644 --- a/devtools/server/actors/highlighters/moz.build +++ b/devtools/server/actors/highlighters/moz.build @@ -6,7 +6,6 @@ DIRS += [ "utils", - "css", ] DevToolsModules( diff --git a/devtools/server/actors/highlighters/utils/accessibility.js b/devtools/server/actors/highlighters/utils/accessibility.js index 23c4210a6534..d44b9a1e5efb 100644 --- a/devtools/server/actors/highlighters/utils/accessibility.js +++ b/devtools/server/actors/highlighters/utils/accessibility.js @@ -205,8 +205,7 @@ class Infobar { */ getTextContent(id) { const anonymousContent = this.markup.content; - return anonymousContent.root.getElementById(`${this.prefix}${id}`) - .textContent; + return anonymousContent.getTextContentForElement(`${this.prefix}${id}`); } /** diff --git a/devtools/server/actors/highlighters/utils/markup.js b/devtools/server/actors/highlighters/utils/markup.js index cc42c143518d..158ef07261d3 100644 --- a/devtools/server/actors/highlighters/utils/markup.js +++ b/devtools/server/actors/highlighters/utils/markup.js @@ -8,6 +8,7 @@ const { getCurrentZoom, getWindowDimensions, getViewportDimensions, + loadSheet, } = require("resource://devtools/shared/layout/utils.js"); const EventEmitter = require("resource://devtools/shared/event-emitter.js"); @@ -44,8 +45,7 @@ exports.removePseudoClassLock = (...args) => const SVG_NS = "http://www.w3.org/2000/svg"; const XHTML_NS = "http://www.w3.org/1999/xhtml"; const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; -const STYLESHEET_URI = - "resource://devtools-highlighter-styles/highlighters.css"; +const STYLESHEET_URI = "resource://devtools/server/actors/highlighters.css"; const _tokens = Symbol("classList/tokens"); @@ -239,6 +239,14 @@ CanvasFrameAnonymousContentHelper.prototype = { this.anonymousContentWindow = this.highlighterEnv.window; this.pageListenerTarget = this.highlighterEnv.pageListenerTarget; + // For now highlighters.css is injected in content as a ua sheet because + // we no longer support scoped style sheets (see bug 1345702). + // If it did, highlighters.css would be injected as an anonymous content + // node using CanvasFrameAnonymousContentHelper instead. + loadSheet(this.anonymousContentWindow, STYLESHEET_URI); + + const node = this.nodeBuilder(); + // It was stated that hidden documents don't accept // `insertAnonymousContent` calls yet. That doesn't seems the case anymore, // at least on desktop. Therefore, removing the code that was dealing with @@ -249,6 +257,7 @@ CanvasFrameAnonymousContentHelper.prototype = { // to ensure the anonymous content will be rendered (see Bug 1580394). const forceSynchronousLayoutUpdate = !this.waitForDocumentToLoad; this._content = this.anonymousContentDocument.insertAnonymousContent( + node, forceSynchronousLayoutUpdate ); } catch (e) { @@ -269,18 +278,13 @@ CanvasFrameAnonymousContentHelper.prototype = { { once: true } ); }); - this._content = this.anonymousContentDocument.insertAnonymousContent(); + this._content = + this.anonymousContentDocument.insertAnonymousContent(node); } else { throw e; } } - const link = this.anonymousContentDocument.createElement("link"); - link.href = STYLESHEET_URI; - link.rel = "stylesheet"; - this._content.root.appendChild(link); - this._content.root.appendChild(this.nodeBuilder()); - this._initialized(); }, @@ -308,42 +312,36 @@ CanvasFrameAnonymousContentHelper.prototype = { } }, - _getNodeById(id) { - return this.content?.root.getElementById(id); - }, - getComputedStylePropertyValue(id, property) { - const node = this._getNodeById(id); - if (!node) { - return null; - } - return this.anonymousContentWindow - .getComputedStyle(node) - .getPropertyValue(property); + return ( + this.content && this.content.getComputedStylePropertyValue(id, property) + ); }, getTextContentForElement(id) { - return this._getNodeById(id)?.textContent; + return this.content && this.content.getTextContentForElement(id); }, setTextContentForElement(id, text) { - const node = this._getNodeById(id); - if (!node) { - return; + if (this.content) { + this.content.setTextContentForElement(id, text); } - node.textContent = text; }, setAttributeForElement(id, name, value) { - this._getNodeById(id)?.setAttribute(name, value); + if (this.content) { + this.content.setAttributeForElement(id, name, value); + } }, getAttributeForElement(id, name) { - return this._getNodeById(id)?.getAttribute(name); + return this.content && this.content.getAttributeForElement(id, name); }, removeAttributeForElement(id, name) { - this._getNodeById(id)?.removeAttribute(name); + if (this.content) { + this.content.removeAttributeForElement(id, name); + } }, hasAttributeForElement(id, name) { @@ -351,7 +349,7 @@ CanvasFrameAnonymousContentHelper.prototype = { }, getCanvasContext(id, type = "2d") { - return this._getNodeById(id)?.getContext(type); + return this.content && this.content.getCanvasContext(id, type); }, /** @@ -546,8 +544,7 @@ CanvasFrameAnonymousContentHelper.prototype = { const zoom = getCurrentZoom(node); // Hide the root element and force the reflow in order to get the proper window's // dimensions without increasing them. - const root = this._getNodeById(id); - root.style.display = "none"; + this.setAttributeForElement(id, "style", "display: none"); node.offsetWidth; let { width, height } = getWindowDimensions(boundaryWindow); @@ -559,8 +556,9 @@ CanvasFrameAnonymousContentHelper.prototype = { height *= zoom; } - value += `position:absolute; width:${width}px;height:${height}px; overflow:hidden;`; - root.style = value; + value += `position:absolute; width:${width}px;height:${height}px; overflow:hidden`; + + this.setAttributeForElement(id, "style", value); }, /** diff --git a/devtools/server/actors/moz.build b/devtools/server/actors/moz.build index 6da10fbc3d8a..b2db9eb8bd63 100644 --- a/devtools/server/actors/moz.build +++ b/devtools/server/actors/moz.build @@ -37,6 +37,7 @@ DevToolsModules( "errordocs.js", "frame.js", "heap-snapshot-file.js", + "highlighters.css", "highlighters.js", "layout.js", "manifest.js", diff --git a/devtools/server/actors/utils/stylesheets-manager.js b/devtools/server/actors/utils/stylesheets-manager.js index 6df044b04870..76902b946b64 100644 --- a/devtools/server/actors/utils/stylesheets-manager.js +++ b/devtools/server/actors/utils/stylesheets-manager.js @@ -663,17 +663,7 @@ class StyleSheetsManager extends EventEmitter { this._targetActor.window.document, true ); - let i = 0; - for (const sheet of styleSheets) { - if (!this._shouldListSheet(sheet)) { - continue; - } - if (sheet == styleSheet) { - return i; - } - i++; - } - return -1; + return styleSheets.indexOf(styleSheet); } /** @@ -825,18 +815,13 @@ class StyleSheetsManager extends EventEmitter { * @returns {Boolean} */ _shouldListSheet(styleSheet) { - // Special case about:PreferenceStyleSheet, as it is generated on the fly - // and the URI is not registered with the about: handler. + // Special case about:PreferenceStyleSheet, as it is generated on the + // fly and the URI is not registered with the about: handler. // https://bugzilla.mozilla.org/show_bug.cgi?id=935803#c37 - const href = styleSheet.href?.toLowerCase(); - if (href === "about:preferencestylesheet") { - return false; - } - // FIXME(bug 1826538): Make accessiblecaret.css and similar UA-widget - // sheets system sheets, then remove this special-case. - if (href === "resource://content-accessible/accessiblecaret.css") { + if (styleSheet.href?.toLowerCase() === "about:preferencestylesheet") { return false; } + return true; } diff --git a/devtools/server/tests/chrome/test_css-logic-specificity.html b/devtools/server/tests/chrome/test_css-logic-specificity.html index c6cf0ca83637..1930e069072b 100644 --- a/devtools/server/tests/chrome/test_css-logic-specificity.html +++ b/devtools/server/tests/chrome/test_css-logic-specificity.html @@ -3,11 +3,13 @@ - -Test css-logic specificity - + + + Test css-logic specificity + + - - + + + Test for Bug 1020244 - Test the chrome-only AnonymousContent API + + + + Mozilla Bug 1020244 - + + + diff --git a/dom/base/test/test_anonymousContent_append_after_reflow.html b/dom/base/test/test_anonymousContent_append_after_reflow.html index 0bdca2c502ff..1e1e62d3d568 100644 --- a/dom/base/test/test_anonymousContent_append_after_reflow.html +++ b/dom/base/test/test_anonymousContent_append_after_reflow.html @@ -1,22 +1,25 @@ - -Test for Bug 1020244 - Make sure anonymous content still works after a reflow (after the canvasframe has been reconstructed) - - + + + Test for Bug 1020244 - Make sure anonymous content still works after a reflow (after the canvasframe has been reconstructed) + + + +
text content
- + + diff --git a/dom/base/test/test_anonymousContent_canvas.html b/dom/base/test/test_anonymousContent_canvas.html index d5a5a1e6c4a1..cca364a52d02 100644 --- a/dom/base/test/test_anonymousContent_canvas.html +++ b/dom/base/test/test_anonymousContent_canvas.html @@ -3,46 +3,57 @@ - -Test for Bug 1212477 - Needs a way to access to <canvas>'s context (2d, webgl) from Anonymous Content API - - -Mozilla Bug 1212477 -
-
text content
- - - -
- + + + + Mozilla Bug 1212477 +
+
text content
+ + + +
+ + const normalWebGL = document.createElement('canvas').getContext('webgl'); + if (normalWebGL) { + let webgl = anonymousContent.getCanvasContext("canvas-webgl", "webgl"); + + is(webgl.toString(), "[object WebGLRenderingContext]", + "WebGL Context is returned properly"); + + is(webgl.canvas, null, + "WebGL context's canvas property is null in anonymous content"); + } + chromeDocument.removeAnonymousContent(anonymousContent); + + + diff --git a/dom/base/test/test_anonymousContent_insert.html b/dom/base/test/test_anonymousContent_insert.html index ce73a1521fde..81e03cb45b9f 100644 --- a/dom/base/test/test_anonymousContent_insert.html +++ b/dom/base/test/test_anonymousContent_insert.html @@ -3,15 +3,18 @@ - -Test for Bug 1020244 - Insert content using the AnonymousContent API, several times, and don't remove it - - + + + Test for Bug 1020244 - Insert content using the AnonymousContent API, several times, and don't remove it + + + + Mozilla Bug 1020244
text content
- + + + diff --git a/dom/base/test/test_anonymousContent_manipulate_content.html b/dom/base/test/test_anonymousContent_manipulate_content.html index e67bfdfea673..eb4bcb6be385 100644 --- a/dom/base/test/test_anonymousContent_manipulate_content.html +++ b/dom/base/test/test_anonymousContent_manipulate_content.html @@ -3,33 +3,64 @@ - -Test for Bug 1020244 - Manipulate content created with the AnonymousContent API - - + + + Test for Bug 1020244 - Manipulate content created with the AnonymousContent API + + + + Mozilla Bug 1020244
text content
- + + + diff --git a/dom/base/test/test_anonymousContent_set_style.html b/dom/base/test/test_anonymousContent_set_style.html new file mode 100644 index 000000000000..75587b3e0f7f --- /dev/null +++ b/dom/base/test/test_anonymousContent_set_style.html @@ -0,0 +1,35 @@ + + + + + + Test for Bug 1571650 - Test AnonymousContent.setStyle() API + + + + +Mozilla Bug 1571650 + + + diff --git a/dom/base/test/test_anonymousContent_style_csp.html b/dom/base/test/test_anonymousContent_style_csp.html index 2aa82a6b2a3d..0eca83404c99 100644 --- a/dom/base/test/test_anonymousContent_style_csp.html +++ b/dom/base/test/test_anonymousContent_style_csp.html @@ -1,23 +1,28 @@ - -Test for Bug 1185351 - Make sure that we don't enforce CSP on styles for AnonymousContent - - + + + Test for Bug 1185351 - Make sure that we don't enforce CSP on styles for AnonymousContent + + + +
text content
- + + diff --git a/dom/webidl/AnonymousContent.webidl b/dom/webidl/AnonymousContent.webidl index 33a7cf0a5983..3dd6fd02648a 100644 --- a/dom/webidl/AnonymousContent.webidl +++ b/dom/webidl/AnonymousContent.webidl @@ -7,11 +7,94 @@ /* * This file declares the AnonymousContent interface which is used to * manipulate content that has been inserted into the document's canvasFrame - * anonymous container. See Document.insertAnonymousContent. - * Users of this API must never remove the host of the shadow root. + * anonymous container. + * See Document.insertAnonymousContent. + * + * This API never returns a reference to the actual inserted DOM node on + * purpose. This is to make sure the content cannot be randomly changed and the + * DOM cannot be traversed from the node, so that Gecko can remain in control of + * the inserted content. */ [ChromeOnly, Exposed=Window] interface AnonymousContent { - readonly attribute ShadowRoot root; + /** + * Get the text content of an element inside this custom anonymous content. + */ + [Throws] + DOMString getTextContentForElement(DOMString elementId); + + /** + * Set the text content of an element inside this custom anonymous content. + */ + [Throws] + undefined setTextContentForElement(DOMString elementId, DOMString text); + + /** + * Get the value of an attribute of an element inside this custom anonymous + * content. + */ + [Throws] + DOMString? getAttributeForElement(DOMString elementId, + DOMString attributeName); + + /** + * Set the value of an attribute of an element inside this custom anonymous + * content. + */ + [NeedsSubjectPrincipal=NonSystem, Throws] + undefined setAttributeForElement(DOMString elementId, + DOMString attributeName, + DOMString value); + + /** + * Remove an attribute from an element inside this custom anonymous content. + */ + [Throws] + undefined removeAttributeForElement(DOMString elementId, + DOMString attributeName); + + /** + * Get the canvas' context for the element specified if it's a + * node, `null` otherwise. + */ + [Throws] + nsISupports? getCanvasContext(DOMString elementId, + DOMString contextId); + + [Throws] + Animation setAnimationForElement(DOMString elementId, + object? keyframes, + optional UnrestrictedDoubleOrKeyframeAnimationOptions + options = {}); + + /** + * Accepts a list of (possibly overlapping) DOMRects which describe a shape + * in CSS pixels relative to the element's border box. This shape will be + * excluded from the element's background color rendering. The element will + * not render any background images once this method has been called. + */ + [Throws] + undefined setCutoutRectsForElement(DOMString elementId, + sequence rects); + + /** + * Get the computed value of a property on an element inside this custom + * anonymous content. + */ + [Throws] + UTF8String? getComputedStylePropertyValue(DOMString elementId, + UTF8String propertyName); + + /** + * If event's original target is in the anonymous content, this returns the id + * attribute value of the target. + */ + DOMString? getTargetIdForEvent(Event event); + + /** + * Set given style to this AnonymousContent. + */ + [Throws] + undefined setStyle(UTF8String property, UTF8String value); }; diff --git a/dom/webidl/Document.webidl b/dom/webidl/Document.webidl index 0a0970c29061..5b1f4baec3cf 100644 --- a/dom/webidl/Document.webidl +++ b/dom/webidl/Document.webidl @@ -506,14 +506,20 @@ partial interface Document { * Chrome document anonymous content management. * This is a Chrome-only API that allows inserting fixed positioned anonymous * content on top of the current page displayed in the document. + * The supplied content is cloned and inserted into the document's CanvasFrame. + * Note that this only works for HTML documents. */ partial interface Document { /** + * Deep-clones the provided element and inserts it into the CanvasFrame. + * Returns an AnonymousContent instance that can be used to manipulate the + * inserted element. + * * If aForce is true, tries to update layout to be able to insert the element * synchronously. */ [ChromeOnly, NewObject, Throws] - AnonymousContent insertAnonymousContent(optional boolean aForce = false); + AnonymousContent insertAnonymousContent(Element aElement, optional boolean aForce = false); /** * Removes the element inserted into the CanvasFrame given an AnonymousContent diff --git a/layout/base/AccessibleCaret.cpp b/layout/base/AccessibleCaret.cpp index 4981f0b70315..f05e8f61c799 100644 --- a/layout/base/AccessibleCaret.cpp +++ b/layout/base/AccessibleCaret.cpp @@ -7,19 +7,15 @@ #include "AccessibleCaret.h" #include "AccessibleCaretLogger.h" -#include "mozilla/Assertions.h" -#include "mozilla/ErrorResult.h" #include "mozilla/FloatingPoint.h" #include "mozilla/PresShell.h" #include "mozilla/StaticPrefs_layout.h" #include "mozilla/dom/Document.h" -#include "mozilla/dom/ShadowRoot.h" #include "mozilla/ToString.h" #include "nsCanvasFrame.h" #include "nsCaret.h" #include "nsCSSFrameConstructor.h" #include "nsDOMTokenList.h" -#include "nsGenericHTMLElement.h" #include "nsIFrame.h" #include "nsLayoutUtils.h" #include "nsPlaceholderFrame.h" @@ -37,8 +33,9 @@ using namespace dom; NS_IMPL_ISUPPORTS(AccessibleCaret::DummyTouchListener, nsIDOMEventListener) -static constexpr auto kTextOverlayElementId = u"text-overlay"_ns; -static constexpr auto kCaretImageElementId = u"image"_ns; +const nsLiteralString AccessibleCaret::sTextOverlayElementId = + u"text-overlay"_ns; +const nsLiteralString AccessibleCaret::sCaretImageElementId = u"image"_ns; #define AC_PROCESS_ENUM_TO_STREAM(e) \ case (e): \ @@ -78,6 +75,7 @@ AccessibleCaret::AccessibleCaret(PresShell* aPresShell) : mPresShell(aPresShell) { // Check all resources required. if (mPresShell) { + MOZ_ASSERT(RootFrame()); MOZ_ASSERT(mPresShell->GetDocument()); InjectCaretElement(mPresShell->GetDocument()); } @@ -89,20 +87,12 @@ AccessibleCaret::~AccessibleCaret() { } } -dom::Element* AccessibleCaret::TextOverlayElement() const { - return mCaretElementHolder->Root()->GetElementById(kTextOverlayElementId); -} - -dom::Element* AccessibleCaret::CaretImageElement() const { - return mCaretElementHolder->Root()->GetElementById(kCaretImageElementId); -} - void AccessibleCaret::SetAppearance(Appearance aAppearance) { if (mAppearance == aAppearance) { return; } - IgnoredErrorResult rv; + ErrorResult rv; CaretElement().ClassList()->Remove(AppearanceString(mAppearance), rv); MOZ_ASSERT(!rv.Failed(), "Remove old appearance failed!"); @@ -181,6 +171,7 @@ void AccessibleCaret::EnsureApzAware() { // if that's the case we register a dummy listener if there isn't one on // the element already. if (!CaretElement().IsApzAware()) { + // FIXME(emilio): Is this needed anymore? CaretElement().AddEventListener(u"touchstart"_ns, mDummyTouchListener, false); } @@ -192,53 +183,43 @@ bool AccessibleCaret::IsInPositionFixedSubtree() const { } void AccessibleCaret::InjectCaretElement(Document* aDocument) { + IgnoredErrorResult rv; + RefPtr element = CreateCaretElement(aDocument); mCaretElementHolder = - aDocument->InsertAnonymousContent(/* aForce = */ false, IgnoreErrors()); - MOZ_RELEASE_ASSERT(mCaretElementHolder, "We must have anonymous content!"); + aDocument->InsertAnonymousContent(*element, /* aForce = */ false, rv); - CreateCaretElement(); + MOZ_ASSERT(!rv.Failed(), "Insert anonymous content should not fail!"); + MOZ_ASSERT(mCaretElementHolder, "We must have anonymous content!"); + + // InsertAnonymousContent will clone the element to make an AnonymousContent. + // Since event listeners are not being cloned when cloning a node, we need to + // add the listener here. EnsureApzAware(); } -void AccessibleCaret::CreateCaretElement() const { +already_AddRefed AccessibleCaret::CreateCaretElement( + Document* aDocument) const { // Content structure of AccessibleCaret //
<- CaretElement() - // <#shadow-root> - // - //
<- TextOverlayElement() - //
<- CaretImageElement() + //
<- TextOverlayElement() + //
<- CaretImageElement() - constexpr bool kNotify = false; + ErrorResult rv; + RefPtr parent = aDocument->CreateHTMLElement(nsGkAtoms::div); + parent->ClassList()->Add(u"moz-accessiblecaret"_ns, rv); + parent->ClassList()->Add(u"none"_ns, rv); - Element& host = CaretElement(); - host.SetAttr(kNameSpaceID_None, nsGkAtoms::_class, - u"moz-accessiblecaret none"_ns, kNotify); + auto CreateAndAppendChildElement = + [aDocument, &parent](const nsLiteralString& aElementId) { + RefPtr child = aDocument->CreateHTMLElement(nsGkAtoms::div); + child->SetAttr(kNameSpaceID_None, nsGkAtoms::id, aElementId, true); + parent->AppendChildTo(child, false, IgnoreErrors()); + }; - ShadowRoot* root = mCaretElementHolder->Root(); - Document* doc = host.OwnerDoc(); - { - RefPtr linkNodeInfo = doc->NodeInfoManager()->GetNodeInfo( - nsGkAtoms::link, nullptr, kNameSpaceID_XHTML, nsINode::ELEMENT_NODE); - RefPtr link = - NS_NewHTMLLinkElement(linkNodeInfo.forget()); - if (NS_WARN_IF(!link)) { - return; - } - link->SetAttr(nsGkAtoms::rel, u"stylesheet"_ns, IgnoreErrors()); - link->SetAttr(nsGkAtoms::href, - u"resource://content-accessible/accessiblecaret.css"_ns, - IgnoreErrors()); - root->AppendChildTo(link, kNotify, IgnoreErrors()); - } + CreateAndAppendChildElement(sTextOverlayElementId); + CreateAndAppendChildElement(sCaretImageElementId); - auto CreateAndAppendChildElement = [&](const nsLiteralString& aElementId) { - RefPtr child = doc->CreateHTMLElement(nsGkAtoms::div); - child->SetAttr(kNameSpaceID_None, nsGkAtoms::id, aElementId, kNotify); - mCaretElementHolder->Root()->AppendChildTo(child, kNotify, IgnoreErrors()); - }; - - CreateAndAppendChildElement(kTextOverlayElementId); - CreateAndAppendChildElement(kCaretImageElementId); + return parent.forget(); } void AccessibleCaret::RemoveCaretElement(Document* aDocument) { diff --git a/layout/base/AccessibleCaret.h b/layout/base/AccessibleCaret.h index 120cfc47fa00..979a52863997 100644 --- a/layout/base/AccessibleCaret.h +++ b/layout/base/AccessibleCaret.h @@ -130,7 +130,9 @@ class AccessibleCaret { // Element for 'Intersects' test. This is the container of the caret image // and text-overlay elements. See CreateCaretElement() for the content // structure. - dom::Element& CaretElement() const { return *mCaretElementHolder->Host(); } + dom::Element& CaretElement() const { + return mCaretElementHolder->ContentNode(); + } // Ensures that the caret element is made "APZ aware" so that the APZ code // doesn't scroll the page when the user is trying to drag the caret. @@ -148,10 +150,14 @@ class AccessibleCaret { float GetZoomLevel(); // Element which contains the text overly for the 'Contains' test. - dom::Element* TextOverlayElement() const; + dom::Element* TextOverlayElement() const { + return mCaretElementHolder->GetElementById(sTextOverlayElementId); + } // Element which contains the caret image for 'Contains' test. - dom::Element* CaretImageElement() const; + dom::Element* CaretImageElement() const { + return mCaretElementHolder->GetElementById(sCaretImageElementId); + } nsIFrame* RootFrame() const; @@ -160,7 +166,7 @@ class AccessibleCaret { // Transform Appearance to CSS id used in ua.css. static nsAutoString AppearanceString(Appearance aAppearance); - void CreateCaretElement() const; + already_AddRefed CreateCaretElement(dom::Document*) const; // Inject caret element into custom content container. void InjectCaretElement(dom::Document*); @@ -217,6 +223,11 @@ class AccessibleCaret { // A no-op touch-start listener which prevents APZ from panning when dragging // the caret. RefPtr mDummyTouchListener{new DummyTouchListener()}; + + // Static class variables + static const nsLiteralString sTextOverlayElementId; + static const nsLiteralString sCaretImageElementId; + }; // class AccessibleCaret std::ostream& operator<<(std::ostream& aStream, diff --git a/layout/base/AccessibleCaretEventHub.cpp b/layout/base/AccessibleCaretEventHub.cpp index d9cd91d86669..45887d17166d 100644 --- a/layout/base/AccessibleCaretEventHub.cpp +++ b/layout/base/AccessibleCaretEventHub.cpp @@ -332,7 +332,11 @@ AccessibleCaretEventHub::AccessibleCaretEventHub(PresShell* aPresShell) : mPresShell(aPresShell) {} void AccessibleCaretEventHub::Init() { - if (mInitialized || !mPresShell) { + if (mInitialized && mManager) { + mManager->OnFrameReconstruction(); + } + + if (mInitialized || !mPresShell || !mPresShell->GetCanvasFrame()) { return; } diff --git a/layout/base/AccessibleCaretManager.cpp b/layout/base/AccessibleCaretManager.cpp index 3f07fe22fed5..ece2ca0b8acf 100644 --- a/layout/base/AccessibleCaretManager.cpp +++ b/layout/base/AccessibleCaretManager.cpp @@ -798,6 +798,11 @@ void AccessibleCaretManager::OnKeyboardEvent() { } } +void AccessibleCaretManager::OnFrameReconstruction() { + mCarets.GetFirst()->EnsureApzAware(); + mCarets.GetSecond()->EnsureApzAware(); +} + void AccessibleCaretManager::SetLastInputSource(uint16_t aInputSource) { mLastInputSource = aInputSource; } diff --git a/layout/base/AccessibleCaretManager.h b/layout/base/AccessibleCaretManager.h index 036151d68a2d..ef78aa6c7420 100644 --- a/layout/base/AccessibleCaretManager.h +++ b/layout/base/AccessibleCaretManager.h @@ -115,6 +115,10 @@ class AccessibleCaretManager { MOZ_CAN_RUN_SCRIPT virtual void OnKeyboardEvent(); + // The canvas frame holding the accessible caret anonymous content elements + // was reconstructed, resulting in the content elements getting cloned. + virtual void OnFrameReconstruction(); + // Update the manager with the last input source that was observed. This // is used in part to determine if the carets should be shown or hidden. void SetLastInputSource(uint16_t aInputSource); diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index 61620baa6a74..bd8cfa12fa79 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -903,12 +903,11 @@ void PresShell::Init(nsPresContext* aPresContext, nsViewManager* aViewManager) { // Add the preference style sheet. UpdatePreferenceStyles(); - const bool accessibleCaretEnabled = + bool accessibleCaretEnabled = AccessibleCaretEnabled(mDocument->GetDocShell()); if (accessibleCaretEnabled) { // Need to happen before nsFrameSelection has been set up. mAccessibleCaretEventHub = new AccessibleCaretEventHub(this); - mAccessibleCaretEventHub->Init(); } mSelection = new nsFrameSelection(this, nullptr, accessibleCaretEnabled); diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 4236ddd66894..0dcb90a24a91 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -731,7 +731,7 @@ static bool HasVisibleAnonymousContents(Document* aDoc) { // For now we assume that if it has a frame, it is visible. We might be able // to refine this further by adding complexity if it turns out this // condition results in a lot of false positives. - if (ac->Host()->GetPrimaryFrame()) { + if (ac->ContentNode().GetPrimaryFrame()) { return true; } } diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index edbb56d8e973..2d7a844a2789 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -74,39 +74,6 @@ void nsCanvasFrame::HideCustomContentContainer() { } } -// Do this off a script-runner because some anon content might load CSS which we -// don't want to deal with while doing frame construction. -void InsertAnonymousContentInContainer(Document& aDoc, Element& aContainer) { - if (!aContainer.IsInComposedDoc() || aDoc.GetAnonymousContents().IsEmpty()) { - return; - } - for (RefPtr& anonContent : aDoc.GetAnonymousContents()) { - if (nsCOMPtr parent = anonContent->Host()->GetParentNode()) { - // Parent had better be an old custom content container already - // removed from a reframe. Forget about it since we're about to get - // inserted in a new one. - // - // TODO(emilio): Maybe we should extend PostDestroyData and do this - // stuff there instead, or something... - MOZ_ASSERT(parent != &aContainer); - MOZ_ASSERT(parent->IsElement()); - MOZ_ASSERT(parent->AsElement()->IsRootOfNativeAnonymousSubtree()); - MOZ_ASSERT(!parent->IsInComposedDoc()); - MOZ_ASSERT(!parent->GetParentNode()); - - parent->RemoveChildNode(anonContent->Host(), true); - } - aContainer.AppendChildTo(anonContent->Host(), true, IgnoreErrors()); - } - // Flush frames now. This is really sadly needed, but otherwise stylesheets - // inserted by the above DOM changes might not be processed in time for layout - // to run. - // FIXME(emilio): This is because we have a script-running checkpoint just - // after ProcessPendingRestyles but before DoReflow. That seems wrong! Ideally - // the whole layout / styling pass should be atomic. - aDoc.FlushPendingNotifications(FlushType::Frames); -} - nsresult nsCanvasFrame::CreateAnonymousContent( nsTArray& aElements) { MOZ_ASSERT(!mCustomContentContainer); @@ -115,7 +82,19 @@ nsresult nsCanvasFrame::CreateAnonymousContent( return NS_OK; } - Document* doc = mContent->OwnerDoc(); + nsCOMPtr doc = mContent->OwnerDoc(); + + RefPtr eventHub = + PresShell()->GetAccessibleCaretEventHub(); + + // This will go through InsertAnonymousContent and such, and we don't really + // want it to end up inserting into our content container. + // + // FIXME(emilio): The fact that this enters into InsertAnonymousContent is a + // bit nasty, can we avoid it, maybe doing this off a scriptrunner? + if (eventHub) { + eventHub->Init(); + } // Create the custom content container. mCustomContentContainer = doc->CreateHTMLElement(nsGkAtoms::div); @@ -150,12 +129,27 @@ nsresult nsCanvasFrame::CreateAnonymousContent( // Only create a frame for mCustomContentContainer if it has some children. if (doc->GetAnonymousContents().IsEmpty()) { HideCustomContentContainer(); - } else { - nsContentUtils::AddScriptRunner(NS_NewRunnableFunction( - "InsertAnonymousContentInContainer", - [doc = RefPtr{doc}, container = RefPtr{mCustomContentContainer.get()}] { - InsertAnonymousContentInContainer(*doc, *container); - })); + } + + for (RefPtr& anonContent : doc->GetAnonymousContents()) { + if (nsCOMPtr parent = anonContent->ContentNode().GetParentNode()) { + // Parent had better be an old custom content container already removed + // from a reframe. Forget about it since we're about to get inserted in a + // new one. + // + // TODO(emilio): Maybe we should extend PostDestroyData and do this stuff + // there instead, or something... + MOZ_ASSERT(parent != mCustomContentContainer); + MOZ_ASSERT(parent->IsElement()); + MOZ_ASSERT(parent->AsElement()->IsRootOfNativeAnonymousSubtree()); + MOZ_ASSERT(!parent->IsInComposedDoc()); + MOZ_ASSERT(!parent->GetParentNode()); + + parent->RemoveChildNode(&anonContent->ContentNode(), false); + } + + mCustomContentContainer->AppendChildTo(&anonContent->ContentNode(), false, + IgnoreErrors()); } // Create a popupgroup element for system privileged non-XUL documents to diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 928ce3996e89..d26d6fd4ff65 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -41,7 +41,6 @@ #include "mozilla/ViewportUtils.h" #include "nsCSSRendering.h" #include "nsCSSRenderingGradients.h" -#include "nsCaseTreatment.h" #include "nsRefreshDriver.h" #include "nsRegion.h" #include "nsStyleStructInlines.h" @@ -1384,9 +1383,8 @@ void nsDisplayListBuilder::MarkFramesForDisplayList( nsIContent* content = e->GetContent(); if (content && content->IsInNativeAnonymousSubtree() && content->IsElement()) { - const nsAttrValue* classes = content->AsElement()->GetClasses(); - if (classes && - classes->Contains(nsGkAtoms::mozAccessiblecaret, eCaseMatters)) { + auto* classList = content->AsElement()->ClassList(); + if (classList->Contains(u"moz-accessiblecaret"_ns)) { continue; } } diff --git a/layout/style/Loader.cpp b/layout/style/Loader.cpp index 7c9a03cafbbb..016fe9924988 100644 --- a/layout/style/Loader.cpp +++ b/layout/style/Loader.cpp @@ -904,22 +904,15 @@ nsresult Loader::CheckContentPolicy(nsIPrincipal* aLoadingPrincipal, } static void RecordUseCountersIfNeeded(Document* aDoc, - const StyleSheet& aSheet) { - if (!aDoc) { + const StyleUseCounters* aCounters) { + if (!aDoc || !aCounters) { return; } const StyleUseCounters* docCounters = aDoc->GetStyleUseCounters(); if (!docCounters) { return; } - if (aSheet.URLData()->ChromeRulesEnabled()) { - return; - } - auto* sheetCounters = aSheet.GetStyleUseCounters(); - if (!sheetCounters) { - return; - } - Servo_UseCounters_Merge(docCounters, sheetCounters); + Servo_UseCounters_Merge(docCounters, aCounters); aDoc->MaybeWarnAboutZoom(); } @@ -966,7 +959,7 @@ std::tuple, Loader::SheetState> Loader::CreateSheet( if (cacheResult.mCompleteValue) { sheet = cacheResult.mCompleteValue->Clone(nullptr, nullptr); mDocument->SetDidHitCompleteSheetCache(); - RecordUseCountersIfNeeded(mDocument, *sheet); + RecordUseCountersIfNeeded(mDocument, sheet->GetStyleUseCounters()); mLoadsPerformed.PutEntry(key); } else { MOZ_ASSERT(cacheResult.mLoadingOrPendingValue); @@ -1562,7 +1555,7 @@ Loader::Completed Loader::ParseSheet(const nsACString& aBytes, } void Loader::NotifyObservers(SheetLoadData& aData, nsresult aStatus) { - RecordUseCountersIfNeeded(mDocument, *aData.mSheet); + RecordUseCountersIfNeeded(mDocument, aData.mSheet->GetStyleUseCounters()); RefPtr loadDispatcher = aData.PrepareLoadEventIfNeeded(); if (aData.mURI) { mLoadsPerformed.PutEntry(SheetLoadDataHashKey(aData)); diff --git a/layout/style/StyleSheet.cpp b/layout/style/StyleSheet.cpp index dc174415f87c..53cefeb5a01c 100644 --- a/layout/style/StyleSheet.cpp +++ b/layout/style/StyleSheet.cpp @@ -764,7 +764,7 @@ void StyleSheet::ReplaceSync(const nsACString& aText, ErrorResult& aRv) { RefPtr rawContent = Servo_StyleSheet_FromUTF8Bytes( loader, this, - /* load_data = */ nullptr, &aText, mParsingMode, URLData(), + /* load_data = */ nullptr, &aText, mParsingMode, Inner().mURLData, /* line_number_offset = */ 0, mConstructorDocument->GetCompatibilityMode(), /* reusable_sheets = */ nullptr, @@ -1204,11 +1204,9 @@ RefPtr StyleSheet::ParseSheet( auto allowImportRules = SelfOrAncestorIsConstructed() ? StyleAllowImportRules::No : StyleAllowImportRules::Yes; - URLExtraData* urlData = URLData(); const bool shouldRecordCounters = - aLoader.GetDocument() && aLoader.GetDocument()->GetStyleUseCounters() && - !urlData->ChromeRulesEnabled(); - if (!AllowParallelParse(aLoader, urlData)) { + aLoader.GetDocument() && aLoader.GetDocument()->GetStyleUseCounters(); + if (!AllowParallelParse(aLoader, Inner().mURLData)) { UniquePtr counters; if (shouldRecordCounters) { counters.reset(Servo_UseCounters_Create()); @@ -1216,7 +1214,7 @@ RefPtr StyleSheet::ParseSheet( RefPtr contents = Servo_StyleSheet_FromUTF8Bytes( - &aLoader, this, &aLoadData, &aBytes, mParsingMode, urlData, + &aLoader, this, &aLoadData, &aBytes, mParsingMode, Inner().mURLData, aLoadData.mLineNumber, aLoadData.mCompatMode, /* reusable_sheets = */ nullptr, counters.get(), allowImportRules, StyleSanitizationKind::None, @@ -1226,7 +1224,7 @@ RefPtr StyleSheet::ParseSheet( } else { auto holder = MakeRefPtr(__func__, &aLoadData); Servo_StyleSheet_FromUTF8BytesAsync( - holder, urlData, &aBytes, mParsingMode, aLoadData.mLineNumber, + holder, Inner().mURLData, &aBytes, mParsingMode, aLoadData.mLineNumber, aLoadData.mCompatMode, shouldRecordCounters, allowImportRules); } @@ -1258,11 +1256,8 @@ void StyleSheet::ParseSheetSync( return eCompatibility_FullStandards; }(); - SetURLExtraData(); - - URLExtraData* urlData = URLData(); const StyleUseCounters* useCounters = - aLoader && aLoader->GetDocument() && !urlData->ChromeRulesEnabled() + aLoader && aLoader->GetDocument() ? aLoader->GetDocument()->GetStyleUseCounters() : nullptr; @@ -1270,11 +1265,12 @@ void StyleSheet::ParseSheetSync( ? StyleAllowImportRules::No : StyleAllowImportRules::Yes; + SetURLExtraData(); Inner().mContents = Servo_StyleSheet_FromUTF8Bytes( - aLoader, this, aLoadData, &aBytes, mParsingMode, urlData, aLineNumber, - compatMode, aReusableSheets, useCounters, allowImportRules, - StyleSanitizationKind::None, + aLoader, this, aLoadData, &aBytes, mParsingMode, Inner().mURLData, + aLineNumber, compatMode, aReusableSheets, useCounters, + allowImportRules, StyleSanitizationKind::None, /* sanitized_output = */ nullptr) .Consume(); @@ -1485,7 +1481,7 @@ void StyleSheet::SetSharedContents(const StyleLockedCssRules* aSharedRules) { SetURLExtraData(); Inner().mContents = - Servo_StyleSheet_FromSharedData(URLData(), aSharedRules).Consume(); + Servo_StyleSheet_FromSharedData(Inner().mURLData, aSharedRules).Consume(); // Don't call FinishParse(), since that tries to set source map URLs, // which we don't have. diff --git a/layout/style/moz.build b/layout/style/moz.build index 5a2e54a1117a..8328352acff0 100644 --- a/layout/style/moz.build +++ b/layout/style/moz.build @@ -274,7 +274,6 @@ RESOURCE_FILES += [ CONTENT_ACCESSIBLE_FILES += [ "ImageDocument.css", - "res/accessiblecaret.css", "res/details.css", "res/plaintext.css", "res/searchfield-cancel.svg", diff --git a/layout/style/res/accessiblecaret.css b/layout/style/res/accessiblecaret.css deleted file mode 100644 index 94325e1f6492..000000000000 --- a/layout/style/res/accessiblecaret.css +++ /dev/null @@ -1,108 +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/. */ - -:host { - /* Add transition effect to make caret size changing smoother. */ - transition-property: width, height, margin-left; - - position: absolute; - z-index: 2147483647; -} - -#image, -#text-overlay { - width: 100%; - - /* Override this property in moz-custom-content-container to make dummy touch - * listener work. */ - pointer-events: auto; -} - -#image { - background-position: center top; - background-size: 100%; - background-repeat: no-repeat; - background-origin: content-box; -} - -:host(.normal) #image { - background-image: image-set( - url("resource://gre-resources/accessiblecaret-normal@1x.png"), - url("resource://gre-resources/accessiblecaret-normal@1.5x.png") 1.5x, - url("resource://gre-resources/accessiblecaret-normal@2x.png") 2x, - url("resource://gre-resources/accessiblecaret-normal@2.25x.png") 2.25x - ); -} - -:host(.left) #image, -:host(.left) #text-overlay { - margin-left: -39%; -} - -:host(.left) > #image { - background-image: image-set( - url("resource://gre-resources/accessiblecaret-tilt-left@1x.png"), - url("resource://gre-resources/accessiblecaret-tilt-left@1.5x.png") 1.5x, - url("resource://gre-resources/accessiblecaret-tilt-left@2x.png") 2x, - url("resource://gre-resources/accessiblecaret-tilt-left@2.25x.png") 2.25x - ); -} - -:host(.right) #image, -:host(.right) #text-overlay { - margin-left: 41%; -} - -:host(.right) #image { - background-image: image-set( - url("resource://gre-resources/accessiblecaret-tilt-right@1x.png"), - url("resource://gre-resources/accessiblecaret-tilt-right@1.5x.png") 1.5x, - url("resource://gre-resources/accessiblecaret-tilt-right@2x.png") 2x, - url("resource://gre-resources/accessiblecaret-tilt-right@2.25x.png") 2.25x - ); -} - -:host(.none) { - display: none; -} - -:host(.hidden) { - visibility: hidden; -} - -@media (-moz-platform: android) { - #image, - #text-overlay { - /* border: 0.1px solid red; */ /* Uncomment border to see the touch target. */ - padding-left: 59%; /* Enlarge the touch area. ((48-22)/2)px / 22px ~= 59% */ - padding-right: 59%; /* Enlarge the touch area. */ - margin-left: -59%; - } - - #image { - padding-bottom: 59%; /* Enlarge the touch area. */ - } - - :host(.normal) #image { - background-image: url("chrome://geckoview/skin/images/accessiblecaret-normal.svg"); - } - - :host(.left) #image, - :host(.left) #text-overlay { - margin-left: -109%; - } - - :host(.left) #image { - background-image: url("chrome://geckoview/skin/images/accessiblecaret-tilt-left.svg"); - } - - :host(.right) #image, - :host(.right) #text-overlay { - margin-left: -12%; - } - - :host(.right) #image { - background-image: url("chrome://geckoview/skin/images/accessiblecaret-tilt-right.svg"); - } -} diff --git a/layout/style/res/ua.css b/layout/style/res/ua.css index 42aa08ff85e0..71a0ad87d6af 100644 --- a/layout/style/res/ua.css +++ b/layout/style/res/ua.css @@ -443,9 +443,108 @@ parsererror|sourcetext { font-size: 12pt; } +div:-moz-native-anonymous.moz-accessiblecaret { + /* Add transition effect to make caret size changing smoother. */ + transition-property: width, height, margin-left; + + position: absolute; + z-index: 2147483647; +} + +div:-moz-native-anonymous.moz-accessiblecaret > :is(#text-overlay, #image) { + width: 100%; + + /* Override this property in moz-custom-content-container to make dummy touch + * listener work. */ + pointer-events: auto; +} + +div:-moz-native-anonymous.moz-accessiblecaret > #image { + background-position: center top; + background-size: 100%; + background-repeat: no-repeat; + background-origin: content-box; +} + +div:-moz-native-anonymous.moz-accessiblecaret.normal > #image { + background-image: image-set( + url("resource://gre-resources/accessiblecaret-normal@1x.png"), + url("resource://gre-resources/accessiblecaret-normal@1.5x.png") 1.5x, + url("resource://gre-resources/accessiblecaret-normal@2x.png") 2x, + url("resource://gre-resources/accessiblecaret-normal@2.25x.png") 2.25x + ); +} + +div:-moz-native-anonymous.moz-accessiblecaret.left > :is(#text-overlay, #image) { + margin-left: -39%; +} + +div:-moz-native-anonymous.moz-accessiblecaret.left > #image { + background-image: image-set( + url("resource://gre-resources/accessiblecaret-tilt-left@1x.png"), + url("resource://gre-resources/accessiblecaret-tilt-left@1.5x.png") 1.5x, + url("resource://gre-resources/accessiblecaret-tilt-left@2x.png") 2x, + url("resource://gre-resources/accessiblecaret-tilt-left@2.25x.png") 2.25x + ); +} + +div:-moz-native-anonymous.moz-accessiblecaret.right > :is(#text-overlay, #image) { + margin-left: 41%; +} + +div:-moz-native-anonymous.moz-accessiblecaret.right > #image { + background-image: image-set( + url("resource://gre-resources/accessiblecaret-tilt-right@1x.png"), + url("resource://gre-resources/accessiblecaret-tilt-right@1.5x.png") 1.5x, + url("resource://gre-resources/accessiblecaret-tilt-right@2x.png") 2x, + url("resource://gre-resources/accessiblecaret-tilt-right@2.25x.png") 2.25x + ); +} + +div:-moz-native-anonymous.moz-accessiblecaret.none { + display: none; +} + +div:-moz-native-anonymous.moz-accessiblecaret.hidden { + visibility: hidden; +} + +@media (-moz-platform: android) { + div:-moz-native-anonymous.moz-accessiblecaret > :is(#text-overlay, #image) { + /* border: 0.1px solid red; */ /* Uncomment border to see the touch target. */ + padding-left: 59%; /* Enlarge the touch area. ((48-22)/2)px / 22px ~= 59% */ + padding-right: 59%; /* Enlarge the touch area. */ + margin-left: -59%; + } + + div:-moz-native-anonymous.moz-accessiblecaret > #image { + padding-bottom: 59%; /* Enlarge the touch area. */ + } + + div:-moz-native-anonymous.moz-accessiblecaret.normal > #image { + background-image: url("chrome://geckoview/skin/images/accessiblecaret-normal.svg"); + } + + div:-moz-native-anonymous.moz-accessiblecaret.left > :is(#text-overlay, #image) { + margin-left: -109%; + } + + div:-moz-native-anonymous.moz-accessiblecaret.left > #image { + background-image: url("chrome://geckoview/skin/images/accessiblecaret-tilt-left.svg"); + } + + div:-moz-native-anonymous.moz-accessiblecaret.right > :is(#text-overlay, #image) { + margin-left: -12%; + } + + div:-moz-native-anonymous.moz-accessiblecaret.right > #image { + background-image: url("chrome://geckoview/skin/images/accessiblecaret-tilt-right.svg"); + } +} + /* Custom content container in the CanvasFrame, positioned on top of everything everything else, not reacting to pointer events. */ -.moz-custom-content-container:-moz-native-anonymous { +div:-moz-native-anonymous.moz-custom-content-container { pointer-events: none; user-select: none; -moz-top-layer: top; @@ -454,6 +553,4 @@ parsererror|sourcetext { left: 0; width: 100%; height: 100%; - /* Initial direction depends on the document, make sure to reset it */ - direction: ltr; } diff --git a/layout/style/test/chrome/test_bug1346623.html b/layout/style/test/chrome/test_bug1346623.html index 027f839ace58..30e21bcc3603 100644 --- a/layout/style/test/chrome/test_bug1346623.html +++ b/layout/style/test/chrome/test_bug1346623.html @@ -33,11 +33,10 @@ function startTest() { div.id = "ac-child"; div.textContent = " This div text should be green."; bq.appendChild(div); - var ac = document.insertAnonymousContent(); - ac.root.appendChild(bq); + var ac = document.insertAnonymousContent(bq); document.body.offsetWidth; - is(getComputedStyle(div).color, "rgb(0, 128, 0)", + is(ac.getComputedStylePropertyValue("ac-child", "color"), "rgb(0, 128, 0)", "color before reframing"); // reframe the root @@ -45,10 +44,10 @@ function startTest() { document.body.offsetWidth; // restyle the div - div.className = "abc"; + ac.setAttributeForElement("ac-child", "class", "abc"); document.body.offsetWidth; - is(getComputedStyle(div).color, "rgb(0, 128, 0)", + is(ac.getComputedStylePropertyValue("ac-child", "color"), "rgb(0, 128, 0)", "color after reframing"); SimpleTest.finish(); } diff --git a/layout/style/test/test_custom_content_inheritance.html b/layout/style/test/test_custom_content_inheritance.html index 625f1ad9c311..ccbce86574bb 100644 --- a/layout/style/test/test_custom_content_inheritance.html +++ b/layout/style/test/test_custom_content_inheritance.html @@ -6,18 +6,20 @@