Bug 1499704 - Use html:progress for downloads. r=dao,bgrins
authorPaolo Amadini <paolo.mozmail@amadzone.org>
Wed, 17 Oct 2018 15:25:00 +0100
changeset 490232 87a982cbe3319558d1c54d1b448316bd300411d5
parent 490231 1d7feb40277692c23edf72c421558d0177480256
child 490233 6d6b5c10bba56bc286ae66cf9d72948a6a03d200
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersdao, bgrins
bugs1499704
milestone64.0a1
Bug 1499704 - Use html:progress for downloads. r=dao,bgrins Differential Revision: https://phabricator.services.mozilla.com/D8973
browser/components/downloads/DownloadsViewUI.jsm
browser/components/downloads/content/downloadsPanel.inc.xul
browser/themes/osx/downloads/allDownloadsView.css
browser/themes/osx/downloads/downloads.css
browser/themes/shared/downloads/progressmeter.inc.css
browser/themes/windows/downloads/allDownloadsView.css
browser/themes/windows/downloads/downloads.css
--- a/browser/components/downloads/DownloadsViewUI.jsm
+++ b/browser/components/downloads/DownloadsViewUI.jsm
@@ -9,27 +9,28 @@
 
 "use strict";
 
 var EXPORTED_SYMBOLS = [
   "DownloadsViewUI",
 ];
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
   Downloads: "resource://gre/modules/Downloads.jsm",
   DownloadUtils: "resource://gre/modules/DownloadUtils.jsm",
   DownloadsCommon: "resource:///modules/DownloadsCommon.jsm",
   FileUtils: "resource://gre/modules/FileUtils.jsm",
   OS: "resource://gre/modules/osfile.jsm",
 });
 
+const HTML_NS = "http://www.w3.org/1999/xhtml";
+
 var gDownloadElementButtons = {
   cancel: {
     commandName: "downloadsCmd_cancel",
     l10nId: "download-cancel",
     descriptionL10nId: "download-cancel-description",
     iconClass: "downloadIconCancel",
   },
   retry: {
@@ -172,17 +173,16 @@ this.DownloadsViewUI.DownloadElementShel
       downloadListItemFragment = MozXULElement.parseXULToFragment(`
         <hbox class="downloadMainArea" flex="1" align="center">
           <stack>
             <image class="downloadTypeIcon" validate="always"/>
             <image class="downloadBlockedBadge" />
           </stack>
           <vbox class="downloadContainer" flex="1" pack="center">
             <description class="downloadTarget" crop="center"/>
-            <progressmeter class="downloadProgress" min="0" max="100"/>
             <description class="downloadDetails downloadDetailsNormal"
                          crop="end"/>
             <description class="downloadDetails downloadDetailsHover"
                          crop="end"/>
             <description class="downloadDetails downloadDetailsButtonHover"
                          crop="end"/>
           </vbox>
         </hbox>
@@ -196,24 +196,30 @@ this.DownloadsViewUI.DownloadElementShel
     this.element.setAttribute("orient", "horizontal");
     this.element.setAttribute("onclick",
                               "DownloadsView.onDownloadClick(event);");
     this.element.appendChild(document.importNode(downloadListItemFragment,
                                                  true));
     for (let [propertyName, selector] of [
       ["_downloadTypeIcon", ".downloadTypeIcon"],
       ["_downloadTarget", ".downloadTarget"],
-      ["_downloadProgress", ".downloadProgress"],
       ["_downloadDetailsNormal", ".downloadDetailsNormal"],
       ["_downloadDetailsHover", ".downloadDetailsHover"],
       ["_downloadDetailsButtonHover", ".downloadDetailsButtonHover"],
       ["_downloadButton", ".downloadButton"],
     ]) {
       this[propertyName] = this.element.querySelector(selector);
     }
+
+    // HTML elements can be created directly without using parseXULToFragment.
+    let progress = this._downloadProgress =
+                   document.createElementNS(HTML_NS, "progress");
+    progress.className = "downloadProgress";
+    progress.setAttribute("max", "100");
+    this._downloadTarget.insertAdjacentElement("afterend", progress);
   },
 
   /**
    * Returns a string from the downloads stringbundleset, which contains legacy
    * strings that are loaded from DTD files instead of properties files. This
    * won't be necessary once localization is converted to Fluent (bug 1452637).
    */
   string(l10nId) {
@@ -265,38 +271,22 @@ this.DownloadsViewUI.DownloadElementShel
    * @param mode
    *        Either "normal" or "undetermined".
    * @param value
    *        Percentage of the progress bar to display, from 0 to 100.
    * @param paused
    *        True to display the progress bar style for paused downloads.
    */
   showProgress(mode, value, paused) {
-    // The "undetermined" mode of the progressmeter is implemented with a
-    // different element structure, and with support from platform code as well.
-    // On Linux only, this mode isn't compatible with the custom styling that we
-    // apply separately with the "progress-undetermined" attribute.
-    this._downloadProgress.setAttribute("mode",
-      AppConstants.platform == "linux" ? "normal" : mode);
     if (mode == "undetermined") {
-      this._downloadProgress.setAttribute("progress-undetermined", "true");
+      this._downloadProgress.removeAttribute("value");
     } else {
-      this._downloadProgress.removeAttribute("progress-undetermined");
+      this._downloadProgress.setAttribute("value", value);
     }
-    this._downloadProgress.setAttribute("value", value);
-    if (paused) {
-      this._downloadProgress.setAttribute("paused", "true");
-    } else {
-      this._downloadProgress.removeAttribute("paused");
-    }
-
-    // Dispatch the ValueChange event for accessibility.
-    let event = this.element.ownerDocument.createEvent("Events");
-    event.initEvent("ValueChange", true, true);
-    this._downloadProgress.dispatchEvent(event);
+    this._downloadProgress.toggleAttribute("paused", !!paused);
   },
 
   /**
    * Updates the full status line.
    *
    * @param status
    *        Status line of the Downloads Panel or the Downloads View.
    * @param hoverStatus
--- a/browser/components/downloads/content/downloadsPanel.inc.xul
+++ b/browser/components/downloads/content/downloadsPanel.inc.xul
@@ -123,21 +123,19 @@
                 orient="horizontal"
                 onkeydown="DownloadsSummary.onKeyDown(event);"
                 onclick="DownloadsSummary.onClick(event);">
             <image class="downloadTypeIcon" />
             <vbox pack="center"
                   flex="1"
                   class="downloadContainer">
               <description id="downloadsSummaryDescription"/>
-              <progressmeter id="downloadsSummaryProgress"
+              <html:progress id="downloadsSummaryProgress"
                              class="downloadProgress"
-                             min="0"
-                             max="100"
-                             mode="normal" />
+                             max="100"/>
               <description id="downloadsSummaryDetails"
                            crop="end"/>
             </vbox>
           </hbox>
           <hbox id="downloadsFooterButtons">
             <button id="downloadsHistory"
                     class="downloadsPanelFooterButton"
                     label="&downloadsHistory.label;"
--- a/browser/themes/osx/downloads/allDownloadsView.css
+++ b/browser/themes/osx/downloads/allDownloadsView.css
@@ -5,15 +5,15 @@
 %include ../../shared/downloads/allDownloadsView.inc.css
 
 /*** List items ***/
 
 :root {
   --downloads-item-height: 6em;
 }
 
-.downloadProgress > .progress-bar {
+.downloadProgress::-moz-progress-bar {
   background-color: #3c9af8;
 }
 
-.downloadProgress[paused="true"] > .progress-bar {
+.downloadProgress[paused]::-moz-progress-bar {
   background-color: #a6a6a6;
 }
--- a/browser/themes/osx/downloads/downloads.css
+++ b/browser/themes/osx/downloads/downloads.css
@@ -28,21 +28,21 @@
 @item@[verdict="Malware"]:not(:hover) {
   color: #aa1b08;
 }
 
 :root[lwt-popup-brighttext] @item@[verdict="Malware"]:not(:hover) {
   color: #ff0039;
 }
 
-.downloadProgress > .progress-bar {
+.downloadProgress::-moz-progress-bar {
   background-color: #3c9af8;
 }
 
-.downloadProgress[paused="true"] > .progress-bar {
+.downloadProgress[paused]::-moz-progress-bar {
   background-color: #a6a6a6;
 }
 
 /*** Highlighted list items ***/
 
 @keyfocus@ @itemFocused@ {
   outline: 2px -moz-mac-focusring solid;
   outline-offset: -2px;
--- a/browser/themes/shared/downloads/progressmeter.inc.css
+++ b/browser/themes/shared/downloads/progressmeter.inc.css
@@ -1,65 +1,58 @@
 /*** Common-styled progressmeter ***/
+
+/*
+ * Styling "html:progress" is limited by the fact that a number of properties
+ * are intentionally locked at the UA stylesheet level. We have to use a border
+ * instead of an outline because the latter would be drawn over the progress
+ * bar and we cannot change its z-index. This means we have to use a negative
+ * margin, except when the value is zero, and adjust the width calculation for
+ * the indeterminate state.
+ */
+
 .downloadProgress {
-  height: 8px;
-  border-radius: 1px;
+  -moz-appearance: none;
+  display: -moz-box;
   margin: 4px 0 0;
   margin-inline-end: 12px;
-
-  /* for overriding rules in progressmeter.css */
-  -moz-appearance: none;
-  border-style: none;
-  background-color: transparent;
-  min-width: initial;
-  min-height: initial;
+  border: 1px solid ButtonShadow;
+  height: 6px;
+  background-color: ButtonFace;
 }
 
-.downloadProgress > .progress-bar {
+.downloadProgress::-moz-progress-bar {
+  -moz-appearance: none;
   background-color: Highlight;
-
-  /* for overriding rules in progressmeter.css */
-  -moz-appearance: none;
 }
 
-.downloadProgress[paused="true"] > .progress-bar {
+.downloadProgress[paused]::-moz-progress-bar {
   background-color: GrayText;
 }
 
-.downloadProgress[progress-undetermined] > .progress-bar {
+.downloadProgress:not([value="0"])::-moz-progress-bar {
+  margin: -1px;
+  height: 8px;
+}
+
+.downloadProgress:indeterminate::-moz-progress-bar {
+  width: calc(100% + 2px);
   /* Make a white reflecting animation.
      Create a gradient with 2 identical pattern, and enlarge the size to 200%.
      This allows us to animate background-position with percentage. */
   background-image: linear-gradient(90deg, transparent 0%,
                                            rgba(255,255,255,0.5) 25%,
                                            transparent 50%,
                                            rgba(255,255,255,0.5) 75%,
                                            transparent 100%);
   background-blend-mode: lighten;
   background-size: 200% 100%;
   animation: downloadProgressSlideX 1.5s linear infinite;
 }
 
-.downloadProgress > .progress-remainder {
-  border: solid ButtonShadow;
-  border-block-start-width: 1px;
-  border-block-end-width: 1px;
-  border-inline-start-width: 0;
-  border-inline-end-width: 1px;
-  background-color: ButtonFace;
-}
-
-.downloadProgress[value="0"] > .progress-remainder {
-  border-width: 1px;
-}
-
-.downloadProgress[progress-undetermined] > .progress-remainder {
-  border: none;
-}
-
 @keyframes downloadProgressSlideX {
   0% {
     background-position: 0 0;
   }
   100% {
     background-position: -100% 0;
   }
 }
--- a/browser/themes/windows/downloads/allDownloadsView.css
+++ b/browser/themes/windows/downloads/allDownloadsView.css
@@ -6,19 +6,23 @@
 
 /*** List items ***/
 
 :root {
   --downloads-item-height: 6em;
 }
 
 @media (-moz-windows-default-theme) {
-  .downloadProgress > .progress-bar {
+  .downloadProgress::-moz-progress-bar {
     background-color: #3c9af8;
   }
+
+  .downloadProgress[paused]::-moz-progress-bar {
+    background-color: #a6a6a6;
+  }
 }
 
 /*** Highlighted list items ***/
 
 @media (-moz-windows-default-theme) {
   /*
   -moz-appearance: menuitem is almost right, but the hover effect is not
   transparent and is lighter than desired.
--- a/browser/themes/windows/downloads/downloads.css
+++ b/browser/themes/windows/downloads/downloads.css
@@ -32,24 +32,23 @@
     color: #aa1b08;
   }
 
   :root[lwt-popup-brighttext] @item@[verdict="Malware"]:not(:hover) {
     color: #ff0039;
   }
 
   /* Use unified color for the progressbar on default theme */
-  .downloadProgress > .progress-bar {
+  .downloadProgress::-moz-progress-bar {
     background-color: #3c9af8;
   }
 
-  .downloadProgress[paused="true"] > .progress-bar {
+  .downloadProgress[paused]::-moz-progress-bar {
     background-color: #a6a6a6;
   }
-
 }
 
 /*** Highlighted list items ***/
 
 @keyfocus@ @itemFocused@ {
   outline: 1px -moz-dialogtext dotted;
   outline-offset: -1px;
 }