diff options
Diffstat (limited to 'devtools/client')
11 files changed, 95 insertions, 15 deletions
diff --git a/devtools/client/inspector/inspector.js b/devtools/client/inspector/inspector.js index c056c213f..d0458fc1f 100644 --- a/devtools/client/inspector/inspector.js +++ b/devtools/client/inspector/inspector.js @@ -169,6 +169,10 @@ Inspector.prototype = { return this._target.client.traits.getUniqueSelector; }, + get canGetCssPath() { + return this._target.client.traits.getCssPath; + }, + get canGetUsedFontFaces() { return this._target.client.traits.getUsedFontFaces; }, @@ -1074,6 +1078,15 @@ Inspector.prototype = { click: () => this.copyUniqueSelector(), })); copySubmenu.append(new MenuItem({ + id: "node-menu-copycsspath", + label: INSPECTOR_L10N.getStr("inspectorCopyCSSPath.label"), + accesskey: + INSPECTOR_L10N.getStr("inspectorCopyCSSPath.accesskey"), + disabled: !isSelectionElement, + hidden: !this.canGetCssPath, + click: () => this.copyCssPath(), + })); + copySubmenu.append(new MenuItem({ id: "node-menu-copyimagedatauri", label: INSPECTOR_L10N.getStr("inspectorImageDataUri.label"), disabled: !isSelectionElement || !markupContainer || @@ -1677,9 +1690,24 @@ Inspector.prototype = { return; } - this.selection.nodeFront.getUniqueSelector().then((selector) => { + this.telemetry.toolOpened("copyuniquecssselector"); + this.selection.nodeFront.getUniqueSelector().then(selector => { clipboardHelper.copyString(selector); - }).then(null, console.error); + }).catch(e => console.error); + }, + + /** + * Copy the full CSS Path of the selected Node to the clipboard. + */ + copyCssPath: function () { + if (!this.selection.isNode()) { + return; + } + + this.telemetry.toolOpened("copyfullcssselector"); + this.selection.nodeFront.getCssPath().then(path => { + clipboardHelper.copyString(path); + }).catch(e => console.error); }, /** diff --git a/devtools/client/inspector/markup/views/markup-container.js b/devtools/client/inspector/markup/views/markup-container.js index b54157242..44768b46c 100644 --- a/devtools/client/inspector/markup/views/markup-container.js +++ b/devtools/client/inspector/markup/views/markup-container.js @@ -211,10 +211,12 @@ MarkupContainer.prototype = { } if (this.showExpander) { + this.elt.classList.add("expandable"); this.expander.style.visibility = "visible"; // Update accessibility expanded state. this.tagLine.setAttribute("aria-expanded", this.expanded); } else { + this.elt.classList.remove("expandable"); this.expander.style.visibility = "hidden"; // No need for accessible expanded state indicator when expander is not // shown. diff --git a/devtools/client/inspector/shared/tooltips-overlay.js b/devtools/client/inspector/shared/tooltips-overlay.js index 8a02d7e3d..336dae05b 100644 --- a/devtools/client/inspector/shared/tooltips-overlay.js +++ b/devtools/client/inspector/shared/tooltips-overlay.js @@ -88,7 +88,9 @@ TooltipsOverlay.prototype = { if (this.isRuleView) { // Color picker tooltip - this.colorPicker = new SwatchColorPickerTooltip(toolbox.doc, this.view.inspector); + this.colorPicker = new SwatchColorPickerTooltip(toolbox.doc, + this.view.inspector, + this._cssProperties); // Cubic bezier tooltip this.cubicBezier = new SwatchCubicBezierTooltip(toolbox.doc); // Filter editor tooltip diff --git a/devtools/client/inspector/test/browser_inspector_menu-01-sensitivity.js b/devtools/client/inspector/test/browser_inspector_menu-01-sensitivity.js index 59dbbbcc0..052e9da68 100644 --- a/devtools/client/inspector/test/browser_inspector_menu-01-sensitivity.js +++ b/devtools/client/inspector/test/browser_inspector_menu-01-sensitivity.js @@ -26,6 +26,7 @@ const ALL_MENU_ITEMS = [ "node-menu-copyinner", "node-menu-copyouter", "node-menu-copyuniqueselector", + "node-menu-copycsspath", "node-menu-copyimagedatauri", "node-menu-delete", "node-menu-pseudo-hover", diff --git a/devtools/client/inspector/test/browser_inspector_menu-02-copy-items.js b/devtools/client/inspector/test/browser_inspector_menu-02-copy-items.js index 0c96e9bbe..57a5dbaa0 100644 --- a/devtools/client/inspector/test/browser_inspector_menu-02-copy-items.js +++ b/devtools/client/inspector/test/browser_inspector_menu-02-copy-items.js @@ -26,6 +26,12 @@ const COPY_ITEMS_TEST_DATA = [ text: "body > div:nth-child(1) > p:nth-child(2)", }, { + desc: "copy css path", + id: "node-menu-copycsspath", + selector: "[data-id=\"copy\"]", + text: "html body div p", + }, + { desc: "copy image data uri", id: "node-menu-copyimagedatauri", selector: "#copyimage", diff --git a/devtools/client/locales/en-US/inspector.properties b/devtools/client/locales/en-US/inspector.properties index 4f4829678..b6f3e072b 100644 --- a/devtools/client/locales/en-US/inspector.properties +++ b/devtools/client/locales/en-US/inspector.properties @@ -154,6 +154,12 @@ inspectorCopyOuterHTML.accesskey=O inspectorCopyCSSSelector.label=CSS Selector inspectorCopyCSSSelector.accesskey=S +# LOCALIZATION NOTE (inspectorCopyCSSPath.label): This is the label +# shown in the inspector contextual-menu for the item that lets users copy +# the full CSS path of the current node +inspectorCopyCSSPath.label=CSS Path +inspectorCopyCSSPath.accesskey=P + # LOCALIZATION NOTE (inspectorPasteOuterHTML.label): This is the label shown # in the inspector contextual-menu for the item that lets users paste outer # HTML in the current node diff --git a/devtools/client/shared/output-parser.js b/devtools/client/shared/output-parser.js index 726c93b8b..b4fb1c6aa 100644 --- a/devtools/client/shared/output-parser.js +++ b/devtools/client/shared/output-parser.js @@ -40,8 +40,11 @@ const CSS_GRID_ENABLED_PREF = "layout.css.grid.enabled"; * where CSS_TYPES is defined in devtools/shared/css/properties-db.js * @param {Function} isValidOnClient - A function that checks if a css property * name/value combo is valid. + * @param {Function} supportsCssColor4ColorFunction - A function for checking + * the supporting of css-color-4 color function. */ -function OutputParser(document, {supportsType, isValidOnClient}) { +function OutputParser(document, + {supportsType, isValidOnClient, supportsCssColor4ColorFunction}) { this.parsed = []; this.doc = document; this.supportsType = supportsType; @@ -50,6 +53,8 @@ function OutputParser(document, {supportsType, isValidOnClient}) { this.angleSwatches = new WeakMap(); this._onColorSwatchMouseDown = this._onColorSwatchMouseDown.bind(this); this._onAngleSwatchMouseDown = this._onAngleSwatchMouseDown.bind(this); + + this.cssColor4 = supportsCssColor4ColorFunction(); } exports.OutputParser = OutputParser; @@ -188,7 +193,8 @@ OutputParser.prototype = { if (options.expectCubicBezier && token.text === "cubic-bezier") { this._appendCubicBezier(functionText, options); - } else if (colorOK() && colorUtils.isValidCSSColor(functionText)) { + } else if (colorOK() && + colorUtils.isValidCSSColor(functionText, this.cssColor4)) { this._appendColor(functionText, options); } else { this._appendTextNode(functionText); @@ -205,7 +211,8 @@ OutputParser.prototype = { options.expectDisplay && token.text === "grid" && text === token.text) { this._appendGrid(token.text, options); - } else if (colorOK() && colorUtils.isValidCSSColor(token.text)) { + } else if (colorOK() && + colorUtils.isValidCSSColor(token.text, this.cssColor4)) { this._appendColor(token.text, options); } else if (angleOK(token.text)) { this._appendAngle(token.text, options); @@ -218,7 +225,7 @@ OutputParser.prototype = { case "id": case "hash": { let original = text.substring(token.startOffset, token.endOffset); - if (colorOK() && colorUtils.isValidCSSColor(original)) { + if (colorOK() && colorUtils.isValidCSSColor(original, this.cssColor4)) { this._appendColor(original, options); } else { this._appendTextNode(original); @@ -394,7 +401,7 @@ OutputParser.prototype = { * _mergeOptions(). */ _appendColor: function (color, options = {}) { - let colorObj = new colorUtils.CssColor(color); + let colorObj = new colorUtils.CssColor(color, this.cssColor4); if (this._isValidColor(colorObj)) { let container = this._createNode("span", { diff --git a/devtools/client/shared/telemetry.js b/devtools/client/shared/telemetry.js index 64a299581..38a21cef6 100644 --- a/devtools/client/shared/telemetry.js +++ b/devtools/client/shared/telemetry.js @@ -163,6 +163,12 @@ Telemetry.prototype = { toolbareyedropper: { histogram: "DEVTOOLS_TOOLBAR_EYEDROPPER_OPENED_COUNT", }, + copyuniquecssselector: { + histogram: "DEVTOOLS_COPY_UNIQUE_CSS_SELECTOR_OPENED_COUNT", + }, + copyfullcssselector: { + histogram: "DEVTOOLS_COPY_FULL_CSS_SELECTOR_OPENED_COUNT", + }, developertoolbar: { histogram: "DEVTOOLS_DEVELOPERTOOLBAR_OPENED_COUNT", timerHistogram: "DEVTOOLS_DEVELOPERTOOLBAR_TIME_ACTIVE_SECONDS" diff --git a/devtools/client/shared/test/unit/test_cssColor-03.js b/devtools/client/shared/test/unit/test_cssColor-03.js index c3ef5a5c2..a081f7698 100644 --- a/devtools/client/shared/test/unit/test_cssColor-03.js +++ b/devtools/client/shared/test/unit/test_cssColor-03.js @@ -42,15 +42,15 @@ const CSS_COLOR_4_TESTS = [ function run_test() { for (let test of OLD_STYLE_TESTS) { - let ours = colorUtils.colorToRGBA(test, true); + let ours = colorUtils.colorToRGBA(test, false); let platform = DOMUtils.colorToRGBA(test); deepEqual(ours, platform, "color " + test + " matches DOMUtils"); ok(ours !== null, "'" + test + "' is a color"); } for (let test of CSS_COLOR_4_TESTS) { - let oursOld = colorUtils.colorToRGBA(test, true); - let oursNew = colorUtils.colorToRGBA(test, false); + let oursOld = colorUtils.colorToRGBA(test, false); + let oursNew = colorUtils.colorToRGBA(test, true); let platform = DOMUtils.colorToRGBA(test); notEqual(oursOld, platform, "old style parser for color " + test + " should not match DOMUtils"); diff --git a/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js b/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js index bf211b8b9..6a18ec12c 100644 --- a/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js +++ b/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js @@ -28,8 +28,12 @@ const XHTML_NS = "http://www.w3.org/1999/xhtml"; * inline editor. * @param {InspectorPanel} inspector * The inspector panel, needed for the eyedropper. + * @param {Function} supportsCssColor4ColorFunction + * A function for checking the supporting of css-color-4 color function. */ -function SwatchColorPickerTooltip(document, inspector) { +function SwatchColorPickerTooltip(document, + inspector, + {supportsCssColor4ColorFunction}) { let stylesheet = "chrome://devtools/content/shared/widgets/spectrum.css"; SwatchBasedEditorTooltip.call(this, document, stylesheet); @@ -40,6 +44,7 @@ function SwatchColorPickerTooltip(document, inspector) { this.spectrum = this.setColorPickerContent([0, 0, 0, 1]); this._onSpectrumColorChange = this._onSpectrumColorChange.bind(this); this._openEyeDropper = this._openEyeDropper.bind(this); + this.cssColor4 = supportsCssColor4ColorFunction(); } SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.prototype, { @@ -159,14 +164,14 @@ SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.pr }, _colorToRgba: function (color) { - color = new colorUtils.CssColor(color); + color = new colorUtils.CssColor(color, this.cssColor4); let rgba = color._getRGBATuple(); return [rgba.r, rgba.g, rgba.b, rgba.a]; }, _toDefaultType: function (color) { let colorObj = new colorUtils.CssColor(color); - colorObj.setAuthoredUnitFromColor(this._originalColor); + colorObj.setAuthoredUnitFromColor(this._originalColor, this.cssColor4); return colorObj.toString(); }, diff --git a/devtools/client/themes/markup.css b/devtools/client/themes/markup.css index 4b4cfd031..0569b7ce7 100644 --- a/devtools/client/themes/markup.css +++ b/devtools/client/themes/markup.css @@ -197,6 +197,22 @@ ul.children + .tag-line::before { display: inline; } +.expandable.collapsed .close::before { + /* Display an ellipsis character in collapsed nodes that can be expanded. */ + content: "\2026"; + display: inline-block; + width: 12px; + height: 8px; + margin: 0 2px; + line-height: 3px; + color: var(--theme-body-color-inactive); + border-radius: 3px; + border-style: solid; + border-width: 1px; + text-align: center; + vertical-align: middle; +} + /* Hide HTML void elements (img, hr, br, …) closing tag when the element is not * expanded (it can be if it has pseudo-elements attached) */ .child.collapsed > .tag-line .void-element .close { @@ -318,7 +334,8 @@ ul.children + .tag-line::before { .theme-selected ~ .editor .theme-fg-color4, .theme-selected ~ .editor .theme-fg-color5, .theme-selected ~ .editor .theme-fg-color6, -.theme-selected ~ .editor .theme-fg-color7 { +.theme-selected ~ .editor .theme-fg-color7, +.theme-selected ~ .editor .close::before { color: var(--theme-selection-color); } |