Bug 600645 - App tabs don't appear in the group app tab tray if their icon fails to load [r=ian, a=beltzner]
authorRaymond Lee <raymond@raysquare.com>
Wed, 24 Nov 2010 03:30:16 +0800
changeset 58107 597e4c5ded14d831c734957b71a97bd0ac0a72b5
parent 58106 041430229f5ea29a136f496206d026d09f6ac348
child 58108 57e37b269291bdd32f9c7b6217d4c3a4ed42cb92
child 58127 b014423f755bd073a9ecbb3a50530ee699426b4d
push id17157
push userian@iangilman.com
push dateTue, 23 Nov 2010 22:33:58 +0000
treeherdermozilla-central@597e4c5ded14 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersian, beltzner
bugs600645
milestone2.0b8pre
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 600645 - App tabs don't appear in the group app tab tray if their icon fails to load [r=ian, a=beltzner]
browser/base/content/tabview/groupitems.js
browser/base/content/tabview/tabitems.js
browser/base/content/test/tabview/Makefile.in
browser/base/content/test/tabview/browser_tabview_bug600645.js
browser/base/content/test/tabview/test_bug600645.html
--- a/browser/base/content/tabview/groupitems.js
+++ b/browser/base/content/tabview/groupitems.js
@@ -987,27 +987,41 @@ GroupItem.prototype = Utils.extend(new I
   // Removes all of the groupItem's children.
   removeAll: function GroupItem_removeAll() {
     var self = this;
     var toRemove = this._children.concat();
     toRemove.forEach(function(child) {
       self.remove(child, {dontArrange: true});
     });
   },
+  
+  // ----------
+  // Handles error event for loading app tab's fav icon.
+  _onAppTabError : function(event) {
+    iQ(".appTabIcon", this.$appTabTray).each(function(icon) {
+      let $icon = iQ(icon);
+      if ($icon.data("xulTab") == event.target) {
+        $icon.attr("src", Utils.defaultFaviconURL);
+        return true;
+      }
+    });
+  },
 
   // ----------
   // Adds the given xul:tab as an app tab in this group's apptab tray
   addAppTab: function GroupItem_addAppTab(xulTab) {
     let self = this;
 
+    xulTab.addEventListener("error", this._onAppTabError, false);
+
     // add the icon
-    let icon = xulTab.image || Utils.defaultFaviconURL;
+    let iconUrl = xulTab.image || Utils.defaultFaviconURL;
     let $appTab = iQ("<img>")
       .addClass("appTabIcon")
-      .attr("src", icon)
+      .attr("src", iconUrl)
       .data("xulTab", xulTab)
       .appendTo(this.$appTabTray)
       .click(function(event) {
         if (Utils.isRightClick(event))
           return;
 
         GroupItems.setActiveGroupItem(self);
         UI.goToTab(iQ(this).data("xulTab"));
@@ -1033,16 +1047,18 @@ GroupItem.prototype = Utils.extend(new I
       $icon.remove();
     });
     
     // adjust the tray
     if (!iQ(".appTabIcon", this.$appTabTray).length) {
       this.$appTabTray.css({width: 0});
       this.arrange();
     }
+
+    xulTab.removeEventListener("error", this._onAppTabError, false);
   },
 
   // ----------
   // Function: hideExpandControl
   // Hide the control which expands a stacked groupItem into a quick-look view.
   hideExpandControl: function GroupItem_hideExpandControl() {
     this.$expander.hide();
   },
--- a/browser/base/content/tabview/tabitems.js
+++ b/browser/base/content/tabview/tabitems.js
@@ -874,17 +874,17 @@ let TabItems = {
         this._tabsWaitingForUpdate.splice(index, 1);
 
       // ___ get the TabItem
       Utils.assertThrow(tab.tabItem, "must already be linked");
       let tabItem = tab.tabItem;
 
       // ___ icon
       let iconUrl = tab.image;
-      if (iconUrl == null)
+      if (!iconUrl)
         iconUrl = Utils.defaultFaviconURL;
 
       if (iconUrl != tabItem.favImgEl.src)
         tabItem.favImgEl.src = iconUrl;
 
       // ___ URL
       let tabUrl = tab.linkedBrowser.currentURI.spec;
       if (tabUrl != tabItem.url) {
--- a/browser/base/content/test/tabview/Makefile.in
+++ b/browser/base/content/test/tabview/Makefile.in
@@ -61,16 +61,17 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_bug595804.js \
                  browser_tabview_bug595930.js \
                  browser_tabview_bug595943.js \
                  browser_tabview_bug596781.js \
                  browser_tabview_bug597248.js \
                  browser_tabview_bug597399.js \
                  browser_tabview_bug598600.js \
                  browser_tabview_bug599626.js \
+                 browser_tabview_bug600645.js \
                  browser_tabview_dragdrop.js \
                  browser_tabview_exit_button.js \
                  browser_tabview_group.js \
                  browser_tabview_launch.js \
                  browser_tabview_orphaned_tabs.js \
                  browser_tabview_privatebrowsing.js \
                  browser_tabview_rtl.js \
                  browser_tabview_search.js \
@@ -78,15 +79,16 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_startup_transitions.js \
                  browser_tabview_undo_group.js \
                  browser_tabview_firstrun_pref.js \
                  dummy_page.html \
                  head.js \
                  search1.html \
                  search2.html \
                  test_bug599626.html \
+                 test_bug600645.html \
                  $(NULL)
 
 # compartments: test disabled
 #                 browser_tabview_multiwindow_search.js \
 
 libs::	$(_BROWSER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabview/browser_tabview_bug600645.js
@@ -0,0 +1,93 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is tabview bug600645 test.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Raymond Lee <raymond@appcoast.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+let newTab;
+
+function test() {
+  waitForExplicitFinish();
+
+  newTab = gBrowser.addTab();
+  gBrowser.pinTab(newTab);
+
+  window.addEventListener("tabviewshown", onTabViewWindowLoaded, false);
+  TabView.toggle();
+}
+
+function onTabViewWindowLoaded() {
+  window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
+
+  let contentWindow = document.getElementById("tab-view").contentWindow;
+  is(contentWindow.GroupItems.groupItems.length, 1, 
+     "There is one group item on startup");
+
+  let groupItem = contentWindow.GroupItems.groupItems[0];
+  let icon = contentWindow.iQ(".appTabIcon", groupItem.$appTabTray)[0];
+  let $icon = contentWindow.iQ(icon);
+
+  is($icon.data("xulTab"), newTab, 
+     "The app tab icon has the right tab reference")
+  // check to see whether it's showing the default one or not.
+  is($icon.attr("src"), contentWindow.Utils.defaultFaviconURL, 
+     "The icon is showing the default fav icon for blank tab");
+
+  let errorHandler = function(event) {
+    newTab.removeEventListener("error", errorHandler, false);
+
+    // since the browser code and test code are invoked when an error event is 
+    // fired, a delay is used here to avoid the test code run before the browser 
+    // code.
+    executeSoon(function() {
+      is($icon.attr("src"), contentWindow.Utils.defaultFaviconURL, 
+         "The icon is showing th default fav icon");
+
+      // clean up
+      gBrowser.removeTab(newTab);
+      let endGame = function() {
+        window.removeEventListener("tabviewhidden", endGame, false);
+
+        ok(!TabView.isVisible(), "Tab View is hidden");
+        finish();
+      }
+      window.addEventListener("tabviewhidden", endGame, false);
+      TabView.toggle();
+    });
+  };
+  newTab.addEventListener("error", errorHandler, false);
+
+  newTab.linkedBrowser.loadURI(
+    "http://mochi.test:8888/browser/browser/base/content/test/tabview/test_bug600645.html");
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabview/test_bug600645.html
@@ -0,0 +1,5 @@
+<html>
+<title>Fav Icon Test</title>
+<link rel="shortcut icon" href="favicon.ico">
+<body>Fav Icon Test</body>
+</html>