Bug 1320182 - Remove -moz-element background from breadcrumbs and use linear-gradient instead; r=jdescottes draft
authorPatrick Brosset <pbrosset@mozilla.com>
Thu, 12 Jan 2017 10:50:39 +0100
changeset 459622 3e5a915f3f4c4ab43501e9fe2448925493725adc
parent 458532 7011ed1427de2b6f075c46cc6f4618d3e9fcd2a4
child 541941 3af5a9ec2914a022930c730afce74f46114f901b
push id41272
push userbmo:pbrosset@mozilla.com
push dateThu, 12 Jan 2017 09:58:31 +0000
reviewersjdescottes
bugs1320182
milestone53.0a1
Bug 1320182 - Remove -moz-element background from breadcrumbs and use linear-gradient instead; r=jdescottes MozReview-Commit-ID: 6TNwZs0PHA4
devtools/client/inspector/breadcrumbs.js
devtools/client/jar.mn
devtools/client/shared/widgets/BreadcrumbsWidget.jsm
devtools/client/themes/images/breadcrumbs-divider@2x.png
devtools/client/themes/toolbars.css
devtools/client/themes/widgets.css
--- a/devtools/client/inspector/breadcrumbs.js
+++ b/devtools/client/inspector/breadcrumbs.js
@@ -375,26 +375,16 @@ HTMLBreadcrumbs.prototype = {
     this.arrowScrollBox = new ArrowScrollBox(
         this.win,
         this.outer);
 
     this.container = this.arrowScrollBox.inner;
     this.scroll = this.scroll.bind(this);
     this.arrowScrollBox.on("overflow", this.scroll);
 
-    // These separators are used for CSS purposes only, and are positioned
-    // off screen, but displayed with -moz-element.
-    this.separators = this.doc.createElementNS(NS_XHTML, "div");
-    this.separators.className = "breadcrumb-separator-container";
-    this.separators.innerHTML =
-                      "<div id='breadcrumb-separator-before'></div>" +
-                      "<div id='breadcrumb-separator-after'></div>" +
-                      "<div id='breadcrumb-separator-normal'></div>";
-    this.container.parentNode.appendChild(this.separators);
-
     this.outer.addEventListener("click", this, true);
     this.outer.addEventListener("mouseover", this, true);
     this.outer.addEventListener("mouseout", this, true);
     this.outer.addEventListener("focus", this, true);
 
     this.shortcuts = new KeyShortcuts({ window: this.win, target: this.outer });
     this.handleShortcut = this.handleShortcut.bind(this);
 
@@ -622,24 +612,22 @@ HTMLBreadcrumbs.prototype = {
 
     this.container.removeEventListener("click", this, true);
     this.container.removeEventListener("mouseover", this, true);
     this.container.removeEventListener("mouseout", this, true);
     this.container.removeEventListener("focus", this, true);
     this.shortcuts.destroy();
 
     this.empty();
-    this.separators.remove();
 
     this.arrowScrollBox.off("overflow", this.scroll);
     this.arrowScrollBox.destroy();
     this.arrowScrollBox = null;
     this.outer = null;
     this.container = null;
-    this.separators = null;
     this.nodeHierarchy = null;
 
     this.isDestroyed = true;
   },
 
   /**
    * Empty the breadcrumbs container.
    */
--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -164,17 +164,16 @@ devtools.jar:
     skin/images/command-rulers.svg (themes/images/command-rulers.svg)
     skin/images/command-measure.svg (themes/images/command-measure.svg)
     skin/images/command-noautohide.svg (themes/images/command-noautohide.svg)
     skin/markup.css (themes/markup.css)
     skin/images/editor-error.png (themes/images/editor-error.png)
     skin/images/breakpoint.svg (themes/images/breakpoint.svg)
     skin/webconsole.css (themes/webconsole.css)
     skin/images/webconsole.svg (themes/images/webconsole.svg)
-    skin/images/breadcrumbs-divider@2x.png (themes/images/breadcrumbs-divider@2x.png)
     skin/images/breadcrumbs-scrollbutton.png (themes/images/breadcrumbs-scrollbutton.png)
     skin/images/breadcrumbs-scrollbutton@2x.png (themes/images/breadcrumbs-scrollbutton@2x.png)
     skin/animationinspector.css (themes/animationinspector.css)
     skin/canvasdebugger.css (themes/canvasdebugger.css)
     skin/debugger.css (themes/debugger.css)
     skin/netmonitor.css (themes/netmonitor.css)
     skin/performance.css (themes/performance.css)
     skin/memory.css (themes/memory.css)
--- a/devtools/client/shared/widgets/BreadcrumbsWidget.jsm
+++ b/devtools/client/shared/widgets/BreadcrumbsWidget.jsm
@@ -44,26 +44,16 @@ this.BreadcrumbsWidget = function Breadc
 
   // By default, hide the arrows. We let the arrowscrollbox show them
   // in case of overflow.
   this._list._scrollButtonUp.collapsed = true;
   this._list._scrollButtonDown.collapsed = true;
   this._list.addEventListener("underflow", this._onUnderflow.bind(this), false);
   this._list.addEventListener("overflow", this._onOverflow.bind(this), false);
 
-  // These separators are used for CSS purposes only, and are positioned
-  // off screen, but displayed with -moz-element.
-  this._separators = this.document.createElement("box");
-  this._separators.className = "breadcrumb-separator-container";
-  this._separators.innerHTML =
-                    "<box id='breadcrumb-separator-before'></box>" +
-                    "<box id='breadcrumb-separator-after'></box>" +
-                    "<box id='breadcrumb-separator-normal'></box>";
-  this._parent.appendChild(this._separators);
-
   // This widget emits events that can be handled in a MenuContainer.
   EventEmitter.decorate(this);
 
   // Delegate some of the associated node's methods to satisfy the interface
   // required by MenuContainer instances.
   ViewHelpers.delegateWidgetAttributeMethods(this, aNode);
   ViewHelpers.delegateWidgetEventMethods(this, aNode);
 };
deleted file mode 100644
index 3eed133af4d706589203ee96f6bcb80b11a26c09..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
--- a/devtools/client/themes/toolbars.css
+++ b/devtools/client/themes/toolbars.css
@@ -185,17 +185,16 @@
 }
 
 /* Invert the colors of certain light theme images for displaying
  * inside of the dark theme.
  */
 .devtools-tab.icon-invertable > img,
 .devtools-toolbarbutton > image,
 .devtools-button::before,
-#breadcrumb-separator-normal,
 .scrollbutton-up > .toolbarbutton-icon,
 .scrollbutton-down > .toolbarbutton-icon,
 #black-boxed-message-button .button-icon,
 #canvas-debugging-empty-notice-button .button-icon,
 #toggle-breakpoints[checked] > image,
 .event-tooltip-debugger-icon {
   filter: var(--icon-filter);
 }
--- a/devtools/client/themes/widgets.css
+++ b/devtools/client/themes/widgets.css
@@ -184,96 +184,126 @@
   border-color: transparent;
 }
 
 .scrollbutton-up > .toolbarbutton-icon:-moz-locale-dir(rtl),
 .scrollbutton-down > .toolbarbutton-icon:-moz-locale-dir(ltr) {
   transform: scaleX(-1);
 }
 
-/* The breadcrumb separator elements are used as background images with
- * -moz-element, so we position them offscreen since we don't care about
- * seeing the original elements.
- */
-.breadcrumb-separator-container {
-  position: fixed;
-  top: -1000px;
-  left: -1000px;
-}
-
-#breadcrumb-separator-before,
-#breadcrumb-separator-after,
-#breadcrumb-separator-normal {
-  width: 12px;
-  height: 24px;
-  overflow: hidden;
-}
-
-#breadcrumb-separator-before,
-#breadcrumb-separator-after:after {
-  background: var(--theme-selection-background);
-}
-
-#breadcrumb-separator-after,
-#breadcrumb-separator-before:after {
-  background: var(--theme-body-background);
-}
-
-/* This chevron arrow cannot be replicated easily in CSS, so we are using
- * a background image for it (still keeping it in a separate element so
- * we can handle RTL support with a CSS transform).
- */
-#breadcrumb-separator-normal {
-  background: url(images/breadcrumbs-divider@2x.png) no-repeat center right;
-  background-size: 12px 24px;
-}
-
-/* Fake a triangle by rotating a rectangle inside the elements */
-#breadcrumb-separator-before:after,
-#breadcrumb-separator-after:after {
-  content: "";
-  display: block;
-  width: 25px;
-  height: 24px;
-  transform: translateX(-18px) rotate(45deg);
-  -moz-box-sizing: border-box;
-}
-
 .breadcrumbs-widget-item {
   background-color: transparent;
   -moz-appearance: none;
   min-height: 24px;
   min-width: 65px;
   margin: 0;
   padding: 0 8px 0 20px;
   border: none;
   outline: none;
   color: hsl(210,30%,85%);
+  position: relative;
 }
 
 .breadcrumbs-widget-item > .button-box {
   border: none;
   padding-top: 0;
   padding-bottom: 0;
 }
 
 :root[platform="win"] .breadcrumbs-widget-item:-moz-focusring > .button-box {
   border-width: 0;
 }
 
-.breadcrumbs-widget-item:not([checked]) {
-  background: -moz-element(#breadcrumb-separator-normal) no-repeat center left;
+.breadcrumbs-widget-item::before {
+  content: "";
+  position: absolute;
+  top: 1px;
+  offset-inline-start: 0;
+  width: 12px;
+  height: 22px;
+  background-repeat: no-repeat;
+  /* Given the 1/2 aspect ratio of the separator pseudo-element and the 45deg angle of
+     the arrow shape, we need the arrow edges to be at this position from the start of
+     the gradient line. */
+  --position: 66.5%;
+  /* The color of the thin line in the arrow-shaped separator between 2 unselected
+     crumbs. There is no theme variable for this, this used to be an image. */
+  --line-color: #ACACAC;
+  --background-color: var(--theme-body-background);
+}
+
+#debugger-toolbar .breadcrumbs-widget-item::before {
+  --background-color: var(--theme-toolbar-background);
+}
+
+.theme-dark .breadcrumbs-widget-item::before {
+  --line-color: #6E6E6E;
+}
+
+.breadcrumbs-widget-item:first-child::before {
+  /* The first crumb does not need any separator before itself */
+  content: unset;
+}
+
+.breadcrumbs-widget-item:dir(rtl)::before {
+  transform: scaleX(-1);
 }
 
-.breadcrumbs-widget-item[checked] + .breadcrumbs-widget-item {
-  background: -moz-element(#breadcrumb-separator-after) no-repeat 0 0;
+.breadcrumbs-widget-item:not([checked])::before {
+  background-color: var(--background-color);
+  background-image:
+    linear-gradient(45deg,
+                    var(--background-color) 30%,
+                    transparent),
+    linear-gradient(-45deg,
+                    transparent,
+                    var(--background-color) 70%,
+                    var(--background-color)),
+    linear-gradient(45deg,
+                    transparent var(--position),
+                    var(--line-color) var(--position),
+                    var(--line-color) calc(var(--position) + 1px),
+                    transparent 0),
+    linear-gradient(-45deg,
+                    transparent calc(100% - var(--position)),
+                    var(--line-color) calc(100% - var(--position)),
+                    var(--line-color) calc(calc(100% - var(--position)) + 1px),
+                    transparent 0);
+  background-size:
+    100% 50%,
+    100% 50%,
+    100%,
+    100%;
+  background-position:
+    left bottom,
+    left top,
+    left top,
+    left top;
 }
 
-.breadcrumbs-widget-item[checked] {
-  background: -moz-element(#breadcrumb-separator-before) no-repeat 0 0;
+.breadcrumbs-widget-item[checked] + .breadcrumbs-widget-item::before {
+  background-color: var(--theme-selection-background);
+  background-image:
+    linear-gradient(45deg,
+                    transparent var(--position),
+                    var(--background-color) 0),
+    linear-gradient(-45deg,
+                    var(--background-color) calc(100% - var(--position)),
+                    transparent 0);
+  background-size: unset;
+}
+
+.breadcrumbs-widget-item[checked]::before {
+  background-image:
+    linear-gradient(45deg,
+                    transparent var(--position),
+                    var(--theme-selection-background) 0),
+    linear-gradient(-45deg,
+                    var(--theme-selection-background) calc(100% - var(--position)),
+                    var(--background-color) 0);
 }
 
 .breadcrumbs-widget-item[checked] {
   background-color: var(--theme-selection-background);
 }
 
 .breadcrumbs-widget-item:first-child {
   background-image: none;
@@ -286,27 +316,16 @@
   padding: 0 20px 0 8px;
 }
 
 .breadcrumbs-widget-item:dir(rtl),
 .breadcrumbs-widget-item[checked] + .breadcrumbs-widget-item:dir(rtl) {
   background-position: center right;
 }
 
-#breadcrumb-separator-before:dir(rtl),
-#breadcrumb-separator-after:dir(rtl),
-#breadcrumb-separator-normal:dir(rtl) {
-  transform: scaleX(-1);
-}
-
-#breadcrumb-separator-before:dir(rtl):after,
-#breadcrumb-separator-after:dir(rtl):after {
-  transform: translateX(-5px) rotate(45deg);
-}
-
 .breadcrumbs-widget-item[checked] .breadcrumbs-widget-item-id,
 .breadcrumbs-widget-item[checked] .breadcrumbs-widget-item-tag,
 .breadcrumbs-widget-item[checked] .breadcrumbs-widget-item-pseudo-classes,
 .breadcrumbs-widget-item[checked] .breadcrumbs-widget-item-classes {
   color: var(--theme-selection-color);
 }
 
 .theme-dark .breadcrumbs-widget-item {
@@ -368,16 +387,17 @@
 }
 
 .theme-firebug .breadcrumbs-widget-item:first-child {
   margin: 0;
 }
 
 .theme-firebug .breadcrumbs-widget-item:not(:first-child)::before {
   content: url(chrome://devtools/skin/images/firebug/breadcrumbs-divider.svg);
+  background: none;
   position: relative;
   left: -3px;
   margin: 0 0 0 -5px;
   padding: 0;
   width: 5px;
 }
 
 /* Breadcrumbs Separators (reset selection styles) */