Bug 1282662 - Part 1: Redesign the detail description of Download item in normal or hover cases.; r?paolo draft
authorSean Lee <selee@mozilla.com>
Wed, 07 Dec 2016 11:54:41 -1000
changeset 479949 036beaa822961b25ccc38582a674c2bcdf320d38
parent 479651 af8a2573d0f1e9cc6f2ba0ab67d7a702a197f177
child 479950 cc814b3361b798e9f3b0f7d91d88ff17f1c56d4e
push id44402
push userbmo:selee@mozilla.com
push dateTue, 07 Feb 2017 14:42:47 +0000
reviewerspaolo
bugs1282662
milestone54.0a1
Bug 1282662 - Part 1: Redesign the detail description of Download item in normal or hover cases.; r?paolo MozReview-Commit-ID: ITkv5XdQxEI
browser/components/downloads/DownloadsViewUI.jsm
browser/components/downloads/content/allDownloadsViewOverlay.js
browser/components/downloads/content/download.xml
browser/locales/en-US/chrome/browser/downloads/downloads.properties
browser/themes/shared/downloads/allDownloadsViewOverlay.inc.css
browser/themes/shared/downloads/downloads.inc.css
--- a/browser/components/downloads/DownloadsViewUI.jsm
+++ b/browser/components/downloads/DownloadsViewUI.jsm
@@ -164,76 +164,78 @@ this.DownloadsViewUI.DownloadElementShel
 
     // Dispatch the ValueChange event for accessibility, if possible.
     if (this._progressElement) {
       let event = this.element.ownerDocument.createEvent("Events");
       event.initEvent("ValueChange", true, true);
       this._progressElement.dispatchEvent(event);
     }
 
-    let status = this.statusTextAndTip;
-    this.element.setAttribute("status", status.text);
-    this.element.setAttribute("statusTip", status.tip);
+    let labels = this.statusLabels;
+    this.element.setAttribute("status", labels.status);
+    this.element.setAttribute("hoverStatus", labels.hoverStatus);
+    this.element.setAttribute("fullStatus", labels.fullStatus);
   },
 
   lastEstimatedSecondsLeft: Infinity,
 
   /**
-   * Returns the text for the status line and the associated tooltip. These are
-   * returned by a single property because they are computed together. The
-   * result may be overridden by derived objects.
+   * Returns the labels for the status of normal, full, and hovering cases. These
+   * are returned by a single property because they are computed together.
    */
-  get statusTextAndTip() {
-    return this.rawStatusTextAndTip;
-  },
-
-  /**
-   * Derived objects may call this to get the status text.
-   */
-  get rawStatusTextAndTip() {
+  get statusLabels() {
     let s = DownloadsCommon.strings;
 
-    let text = "";
-    let tip = "";
+    let status = "";
+    let hoverStatus = "";
+    let fullStatus = "";
 
     if (!this.download.stopped) {
       let totalBytes = this.download.hasProgress ? this.download.totalBytes
                                                  : -1;
       let newEstimatedSecondsLeft;
-      [text, newEstimatedSecondsLeft] = DownloadUtils.getDownloadStatus(
+      [status, newEstimatedSecondsLeft] = DownloadUtils.getDownloadStatus(
                                           this.download.currentBytes,
                                           totalBytes,
                                           this.download.speed,
                                           this.lastEstimatedSecondsLeft);
       this.lastEstimatedSecondsLeft = newEstimatedSecondsLeft;
+      hoverStatus = status;
     } else if (this.download.canceled && this.download.hasPartialData) {
       let totalBytes = this.download.hasProgress ? this.download.totalBytes
                                                  : -1;
       let transfer = DownloadUtils.getTransferTotal(this.download.currentBytes,
                                                     totalBytes);
 
       // We use the same XUL label to display both the state and the amount
       // transferred, for example "Paused -  1.1 MB".
-      text = s.statusSeparatorBeforeNumber(s.statePaused, transfer);
+      status = s.statusSeparatorBeforeNumber(s.statePaused, transfer);
+      hoverStatus = status;
     } else if (!this.download.succeeded && !this.download.canceled &&
                !this.download.error) {
-      text = s.stateStarting;
+      status = s.stateStarting;
+      hoverStatus = status;
     } else {
       let stateLabel;
 
-      if (this.download.succeeded) {
+      if (this.download.succeeded && !this.download.target.exists) {
+        stateLabel = s.fileMovedOrMissing;
+        hoverStatus = stateLabel;
+      } else if (this.download.succeeded) {
         // For completed downloads, show the file size (e.g. "1.5 MB").
         if (this.download.target.size !== undefined) {
           let [size, unit] =
             DownloadUtils.convertByteUnits(this.download.target.size);
           stateLabel = s.sizeWithUnits(size, unit);
         } else {
           // History downloads may not have a size defined.
           stateLabel = s.sizeUnknown;
         }
+        status = s.stateCompleted;
+        hoverStatus = status;
       } else if (this.download.canceled) {
         stateLabel = s.stateCanceled;
       } else if (this.download.error.becauseBlockedByParentalControls) {
         stateLabel = s.stateBlockedParentalControls;
       } else if (this.download.error.becauseBlockedByReputationCheck) {
         stateLabel = this.rawBlockedTitleAndDetails[0];
       } else {
         stateLabel = s.stateFailed;
@@ -241,21 +243,25 @@ this.DownloadsViewUI.DownloadElementShel
 
       let referrer = this.download.source.referrer || this.download.source.url;
       let [displayHost, fullHost] = DownloadUtils.getURIHost(referrer);
 
       let date = new Date(this.download.endTime);
       let [displayDate, fullDate] = DownloadUtils.getReadableDates(date);
 
       let firstPart = s.statusSeparator(stateLabel, displayHost);
-      text = s.statusSeparator(firstPart, displayDate);
-      tip = s.statusSeparator(fullHost, fullDate);
+      fullStatus = s.statusSeparator(firstPart, displayDate);
+      status = status || stateLabel;
     }
 
-    return { text, tip: tip || text };
+    return {
+      status,
+      hoverStatus: hoverStatus || fullStatus,
+      fullStatus: fullStatus || status,
+    };
   },
 
   /**
    * Returns [title, [details1, details2]] for blocked downloads.
    */
   get rawBlockedTitleAndDetails() {
     let s = DownloadsCommon.strings;
     if (!this.download.error ||
--- a/browser/components/downloads/content/allDownloadsViewOverlay.js
+++ b/browser/components/downloads/content/allDownloadsViewOverlay.js
@@ -279,29 +279,16 @@ HistoryDownloadElementShell.prototype = 
     }
 
     // Since the state changed, we may need to check the target file again.
     this._targetFileChecked = false;
 
     this._updateState();
   },
 
-  get statusTextAndTip() {
-    let status = this.rawStatusTextAndTip;
-
-    // The base object would show extended progress information in the tooltip,
-    // but we move this to the main view and never display a tooltip.
-    if (!this.download.stopped) {
-      status.text = status.tip;
-    }
-    status.tip = "";
-
-    return status;
-  },
-
   onStateChanged() {
     this._updateState();
 
     if (this.element.selected) {
       goUpdateDownloadCommands();
     } else {
       // If a state change occurs in an item that is not currently selected,
       // this is the only command that may be affected.
--- a/browser/components/downloads/content/download.xml
+++ b/browser/components/downloads/content/download.xml
@@ -41,19 +41,25 @@
                            crop="center"
                            style="min-width: &downloadsSummary.minWidth2;"
                            xbl:inherits="value=displayName,tooltiptext=displayName"/>
           <xul:progressmeter anonid="progressmeter"
                              class="downloadProgress"
                              min="0"
                              max="100"
                              xbl:inherits="mode=progressmode,value=progress,paused=progresspaused"/>
-          <xul:description class="downloadDetails"
+          <xul:description class="downloadDetails downloadDetailsNormal"
+                           crop="end"
+                           xbl:inherits="value=status"/>
+          <xul:description class="downloadDetails downloadDetailsHover"
                            crop="end"
-                           xbl:inherits="value=status,tooltiptext=statusTip"/>
+                           xbl:inherits="value=hoverStatus"/>
+          <xul:description class="downloadDetails downloadDetailsFull"
+                           crop="end"
+                           xbl:inherits="value=fullStatus,tooltiptext=fullStatus"/>
         </xul:vbox>
       </xul:hbox>
       <xul:toolbarseparator />
       <xul:stack class="downloadButtonArea">
         <xul:button class="downloadButton downloadCancel downloadIconCancel"
                     tooltiptext="&cmd.cancel.label;"
                     oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_cancel');"/>
         <xul:button class="downloadButton downloadRetry downloadIconRetry"
--- a/browser/locales/en-US/chrome/browser/downloads/downloads.properties
+++ b/browser/locales/en-US/chrome/browser/downloads/downloads.properties
@@ -12,16 +12,19 @@ stateScanning=Scanning for viruses…
 # Indicates that the download failed because of an error.
 stateFailed=Failed
 # LOCALIZATION NOTE (statePaused):
 # Indicates that the download was paused by the user.
 statePaused=Paused
 # LOCALIZATION NOTE (stateCanceled):
 # Indicates that the download was canceled by the user.
 stateCanceled=Canceled
+# LOCALIZATION NOTE (stateCompleted):
+# Indicates that the download was completed.
+stateCompleted=Completed
 # LOCALIZATION NOTE (stateBlockedParentalControls):
 # Indicates that the download was blocked by the Parental Controls feature of
 # Windows.  "Parental Controls" should be consistently named and capitalized
 # with the display of this feature in Windows.  The following article can
 # provide a reference for the translation of "Parental Controls" in various
 # languages:
 # http://windows.microsoft.com/en-US/windows-vista/Set-up-Parental-Controls
 stateBlockedParentalControls=Blocked by Parental Controls
@@ -44,16 +47,20 @@ stateDirty=Blocked: May contain a virus 
 # are immediately followed by the "Learn More" link, thus they must end with a
 # period.  You may need to adjust "downloadDetails.width" in "downloads.dtd" if
 # this turns out to be longer than the other existing status strings.
 # Note: These strings don't exist in the UI yet.  See bug 1053890.
 blockedMalware=This file contains a virus or malware.
 blockedPotentiallyUnwanted=This file may harm your computer.
 blockedUncommon2=This file is not commonly downloaded.
 
+# LOCALIZATION NOTE (fileMovedOrMissing):
+# Displayed when a complete download which is not at the original folder.
+fileMovedOrMissing=File moved or missing
+
 # LOCALIZATION NOTE (unblockHeaderUnblock, unblockHeaderOpen,
 #                    unblockTypeMalware, unblockTypePotentiallyUnwanted2,
 #                    unblockTypeUncommon2, unblockTip2, unblockButtonOpen,
 #                    unblockButtonUnblock, unblockButtonConfirmBlock):
 # These strings are displayed in the dialog shown when the user asks a blocked
 # download to be unblocked.  The severity of the threat is expressed in
 # descending order by the unblockType strings, it is higher for files detected
 # as malware and lower for uncommon downloads.
--- a/browser/themes/shared/downloads/allDownloadsViewOverlay.inc.css
+++ b/browser/themes/shared/downloads/allDownloadsViewOverlay.inc.css
@@ -55,16 +55,21 @@
 .downloadDetails {
   opacity: 0.7;
   font-size: 95%;
   /* Use calc() to keep the height consistent with .downloadTarget, so that the
      progress bar can be vertically centered. */
   margin: 4px 0 calc(1em / 0.95 - 1em);
 }
 
+.downloadDetailsNormal,
+.downloadDetailsHover {
+  display: none;
+}
+
 .downloadButton {
   -moz-appearance: none;
   -moz-box-align: center;
   background: transparent;
   min-width: 0;
   min-height: 0;
   margin: 0;
   border: none;
--- a/browser/themes/shared/downloads/downloads.inc.css
+++ b/browser/themes/shared/downloads/downloads.inc.css
@@ -227,16 +227,22 @@ richlistitem[type="download"]:last-child
 #downloadsSummaryDetails,
 .downloadDetails {
   opacity: var(--downloads-item-details-opacity);
   /* Use calc() to keep the height consistent with .downloadTarget, so that the
      progress bar can be vertically centered. */
   margin: 4px 0 calc(1em / var(--downloads-item-font-size-factor) - 1em);
 }
 
+@item@:hover > .downloadMainArea > .downloadContainer > .downloadDetailsNormal,
+@item@:not(:hover) > .downloadMainArea > .downloadContainer > .downloadDetailsHover,
+.downloadDetailsFull {
+  display: none;
+}
+
 @item@[verdict] > toolbarseparator {
   visibility: hidden;
 }
 
 .downloadButton {
   -moz-appearance: none;
   min-width: 58px;
   margin: 0;