Bug 836283 - In the Downloads View the Cancel button stops working. r=mak, mconley.
authorAsaf Romano <mano@mozilla.com>
Thu, 07 Feb 2013 22:52:23 +0200
changeset 131089 4a35361198341d6b7523b7dbb08bb8a9ce7ea66b
parent 131088 c3bf9571e80dcad03746da17ba4b33b8e55e499f
child 131090 9d977a94f4144bd61c3a0bfcbbc6c3a59625266b
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak, mconley
bugs836283
milestone21.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 836283 - In the Downloads View the Cancel button stops working. r=mak, mconley.
browser/components/downloads/content/allDownloadsViewOverlay.js
--- a/browser/components/downloads/content/allDownloadsViewOverlay.js
+++ b/browser/components/downloads/content/allDownloadsViewOverlay.js
@@ -1168,52 +1168,73 @@ DownloadsPlacesView.prototype = {
   function DPV_invalidateContainer(aContainer) {
     if (aContainer != this._resultNode)
       throw new Error("Unexpected container node");
     if (!aContainer.containerOpen)
       throw new Error("Root container for the downloads query cannot be closed");
 
     let suppressOnSelect = this._richlistbox.suppressOnSelect;
     this._richlistbox.suppressOnSelect = true;
-
-    // Remove the invalidated history downloads from the list and unset the
-    // places node for data downloads.
-    // Loop backwards since _removeHistoryDownloadFromView may removeChild().
-    for (let i = this._richlistbox.childNodes.length - 1; i >= 0; --i) {
-      let element = this._richlistbox.childNodes[i];
-      if (element._shell.placesNode)
-        this._removeHistoryDownloadFromView(element._shell.placesNode);
+    try {
+      // Remove the invalidated history downloads from the list and unset the
+      // places node for data downloads.
+      // Loop backwards since _removeHistoryDownloadFromView may removeChild().
+      for (let i = this._richlistbox.childNodes.length - 1; i >= 0; --i) {
+        let element = this._richlistbox.childNodes[i];
+        if (element._shell.placesNode)
+          this._removeHistoryDownloadFromView(element._shell.placesNode);
+      }
+    }
+    finally {
+      this._richlistbox.suppressOnSelect = suppressOnSelect;
     }
 
-    let elementsToAppendFragment = document.createDocumentFragment();
-    for (let i = 0; i < aContainer.childCount; i++) {
-      try {
-        this._addDownloadData(null, aContainer.getChild(i), false,
-                              elementsToAppendFragment);
+    if (aContainer.childCount > 0) {
+      let elementsToAppendFragment = document.createDocumentFragment();
+      for (let i = 0; i < aContainer.childCount; i++) {
+        try {
+          this._addDownloadData(null, aContainer.getChild(i), false,
+                                elementsToAppendFragment);
+        }
+        catch(ex) {
+          Cu.reportError(ex);
+        }
       }
-      catch(ex) {
-        Cu.reportError(ex);
+
+      // _addDownloadData may not add new elements if there were already
+      // data items in place.
+      if (elementsToAppendFragment.firstChild) {
+        this._appendDownloadsFragment(elementsToAppendFragment);
+        this._ensureVisibleElementsAreActive();
       }
     }
 
-    this._appendDownloadsFragment(elementsToAppendFragment);
-    this._ensureVisibleElementsAreActive();
-
-    this._richlistbox.suppressOnSelect = suppressOnSelect;
     goUpdateDownloadCommands();
   },
 
   _appendDownloadsFragment: function DPV__appendDownloadsFragment(aDOMFragment) {
     // Workaround multiple reflows hang by removing the richlistbox
     // and adding it back when we're done.
+
+    // Hack for bug 836283: reset xbl fields to their old values after the
+    // binding is reattached to avoid breaking the selection state
+    let xblFields = new Map();
+    for (let [key, value] in Iterator(this._richlistbox)) {
+      xblFields.set(key, value);
+    }
+
     let parentNode = this._richlistbox.parentNode;
     let nextSibling = this._richlistbox.nextSibling;
     parentNode.removeChild(this._richlistbox);
     this._richlistbox.appendChild(aDOMFragment);
     parentNode.insertBefore(this._richlistbox, nextSibling);
+
+    for (let [key, value] of xblFields) {
+      this._richlistbox[key] = value;
+    }
   },
 
   nodeInserted: function DPV_nodeInserted(aParent, aPlacesNode) {
     this._addDownloadData(null, aPlacesNode);
   },
 
   nodeRemoved: function DPV_nodeRemoved(aParent, aPlacesNode, aOldIndex) {
     this._removeHistoryDownloadFromView(aPlacesNode);