Mass backout to fix OS X 64 Leak.
authorKyle Huey <khuey@kylehuey.com>
Wed, 24 Nov 2010 00:59:48 -0500
changeset 58127 b014423f755b
parent 58107 597e4c5ded14
child 58128 ef38031be209
push id17171
push userkhuey@kylehuey.com
push dateWed, 24 Nov 2010 06:12:07 +0000
treeherdermozilla-central@ef38031be209 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
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
Mass backout to fix OS X 64 Leak.
browser/base/content/tabview/groupitems.js
browser/base/content/tabview/search.js
browser/base/content/tabview/tabitems.js
browser/base/content/tabview/tabview.css
browser/base/content/tabview/tabview.html
browser/base/content/tabview/ui.js
browser/base/content/test/tabview/Makefile.in
browser/base/content/test/tabview/browser_tabview_bug587351.js
browser/base/content/test/tabview/browser_tabview_bug596781.js
browser/base/content/test/tabview/browser_tabview_bug597248.js
browser/base/content/test/tabview/browser_tabview_bug600645.js
browser/base/content/test/tabview/test_bug600645.html
browser/themes/gnomestripe/browser/tabview/search.png
browser/themes/gnomestripe/browser/tabview/tabview.css
browser/themes/pinstripe/browser/tabview/search.png
browser/themes/pinstripe/browser/tabview/tabview.css
browser/themes/winstripe/browser/tabview/search.png
browser/themes/winstripe/browser/tabview/tabview.css
--- a/browser/base/content/tabview/groupitems.js
+++ b/browser/base/content/tabview/groupitems.js
@@ -143,26 +143,26 @@ function GroupItem(listOfEls, options) {
   this.$resizer = iQ("<div>")
     .addClass('resizer')
     .appendTo($container)
     .hide();
 
   // ___ Titlebar
   var html =
     "<div class='title-container'>" +
-      "<input class='name' />" +
+      "<input class='name'/>" +
       "<div class='title-shield' />" +
     "</div>";
 
   this.$titlebar = iQ('<div>')
     .addClass('titlebar')
     .html(html)
     .appendTo($container);
 
-  this.$closeButton = iQ('<div>')
+  var $close = iQ('<div>')
     .addClass('close')
     .click(function() {
       self.closeAll();
     })
     .appendTo($container);
 
   // ___ Title
   this.$titleContainer = iQ('.title-container', this.$titlebar);
@@ -271,17 +271,17 @@ function GroupItem(listOfEls, options) {
       self.addAppTab(xulTab);
   });
 
   // ___ locking
   if (this.locked.bounds)
     $container.css({cursor: 'default'});
 
   if (this.locked.close)
-    this.$closeButton.hide();
+    $close.hide();
 
   // ___ Undo Close
   this.$undoContainer = null;
   this._undoButtonTimeoutId = null;
 
   // ___ Superclass initialization
   this._init($container[0]);
 
@@ -309,18 +309,16 @@ function GroupItem(listOfEls, options) {
   } else
     // Calling snap will also trigger pushAway
     this.snap(immediately);
   if ($container)
     this.setBounds(rectToBe, immediately);
 
   this._inited = true;
   this.save();
-
-  GroupItems.updateGroupCloseButtons();
 };
 
 // ----------
 GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
   // ----------
   // Variable: defaultName
   // The prompt text for the title field.
   defaultName: tabviewString('groupItem.defaultName'),
@@ -564,17 +562,16 @@ GroupItem.prototype = Utils.extend(new I
   // ----------
   // Function: close
   // Closes the groupItem, removing (but not closing) all of its children.
   close: function GroupItem_close() {
     this.removeAll();
     GroupItems.unregister(this);
     this._sendToSubscribers("close");
     this.removeTrenches();
-    GroupItems.updateGroupCloseButtons();
 
     if (this.hidden) {
       iQ(this.container).remove();
       if (this.$undoContainer) {
         this.$undoContainer.remove();
         this.$undoContainer = null;
        }
       Items.unsquish();
@@ -640,17 +637,16 @@ GroupItem.prototype = Utils.extend(new I
       duration: 170,
       complete: function() {
         self._children.forEach(function(child) {
           iQ(child.container).show();
         });
       }
     });
 
-    GroupItems.updateGroupCloseButtons();
     self._sendToSubscribers("groupShown", { groupItemId: self.id });
   },
 
   // ----------
   // Function: closeHidden
   // Removes the group item, its children and its container.
   closeHidden: function GroupItem_closeHidden() {
     let self = this;
@@ -773,18 +769,16 @@ GroupItem.prototype = Utils.extend(new I
     // Cancel the fadeaway if you move the mouse over the undo
     // button, and restart the countdown once you move out of it.
     this.$undoContainer.mouseover(function() { 
       self._cancelFadeAwayUndoButtonTimer();
     });
     this.$undoContainer.mouseout(function() {
       self.setupFadeAwayUndoButtonTimer();
     });
-
-    GroupItems.updateGroupCloseButtons();
   },
 
   // ----------
   // Sets up fade away undo button timeout. 
   setupFadeAwayUndoButtonTimer: function() {
     let self = this;
 
     if (!this._undoButtonTimeoutId) {
@@ -964,64 +958,50 @@ GroupItem.prototype = Utils.extend(new I
       item.setRotation(0);
 
       item.droppable(true);
       item.removeSubscriber(this, "close");
 
       if (typeof item.setResizable == 'function')
         item.setResizable(true, options.immediately);
 
-      if (!this._children.length && !this.locked.close && !this.getTitle() && 
-          !options.dontClose && !GroupItems.getUnclosableGroupItem()) {
+      if (!this._children.length && !this.locked.close && !this.getTitle() && !options.dontClose) {
         this.close();
       } else if (!options.dontArrange) {
         this.arrange({animate: !options.immediately});
       }
 
       this._sendToSubscribers("childRemoved",{ groupItemId: this.id, item: item });
+
     } catch(e) {
       Utils.log(e);
     }
   },
 
   // ----------
   // Function: removeAll
   // 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 iconUrl = xulTab.image || Utils.defaultFaviconURL;
+    let icon = xulTab.image || Utils.defaultFaviconURL;
     let $appTab = iQ("<img>")
       .addClass("appTabIcon")
-      .attr("src", iconUrl)
+      .attr("src", icon)
       .data("xulTab", xulTab)
       .appendTo(this.$appTabTray)
       .click(function(event) {
         if (Utils.isRightClick(event))
           return;
 
         GroupItems.setActiveGroupItem(self);
         UI.goToTab(iQ(this).data("xulTab"));
@@ -1047,18 +1027,16 @@ 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();
   },
@@ -1654,27 +1632,25 @@ let GroupItems = {
 
   // ----------
   // Function: addAppTab
   // Adds the given xul:tab to the app tab tray in all groups
   addAppTab: function GroupItems_addAppTab(xulTab) {
     this.groupItems.forEach(function(groupItem) {
       groupItem.addAppTab(xulTab);
     });
-    this.updateGroupCloseButtons();
   },
 
   // ----------
   // Function: removeAppTab
   // Removes the given xul:tab from the app tab tray in all groups
   removeAppTab: function GroupItems_removeAppTab(xulTab) {
     this.groupItems.forEach(function(groupItem) {
       groupItem.removeAppTab(xulTab);
     });
-    this.updateGroupCloseButtons();
   },
 
   // ----------
   // Function: getNextID
   // Returns the next unused groupItem ID.
   getNextID: function GroupItems_getNextID() {
     var result = this.nextID;
     this.nextID++;
@@ -1897,17 +1873,17 @@ let GroupItems = {
       gBrowser.visibleTabs.some(function(tab) {
         if (!tab.pinned && tab != tabItem.tab) {
           otherTab = tab;
           return true;
         }
         return false;
       });
 
-      if (otherTab && otherTab.tabItem) {
+      if (otherTab) {
         // the first visible tab belongs to a group, add the new tabItem into 
         // that group
         if (otherTab.tabItem.parent) {
           let groupItem = otherTab.tabItem.parent;
           groupItem.add(tabItem);
           this.setActiveGroupItem(groupItem);
           return;
         }
@@ -2226,43 +2202,10 @@ let GroupItems = {
 
     let groupItems = this.groupItems.concat();
     groupItems.forEach(function(groupItem) {
       if (groupItem.hidden)
         groupItem.closeHidden();
      });
 
     this._removingHiddenGroups = false;
-  },
-
-  // ----------
-  // Function: getUnclosableGroupItem
-  // If there's only one (non-hidden) group, and there are app tabs present, 
-  // returns that group.
-  // Return the <GroupItem>
-  getUnclosableGroupItem: function GroupItems_getUnclosableGroupItem() {
-    let unclosableGroupItem = null;
-
-    if (gBrowser._numPinnedTabs > 0) {
-      let groupItems = this.groupItems.filter(function(groupItem) {
-        return !groupItem.hidden;
-      });
-      if (groupItems.length == 1)
-        unclosableGroupItem = groupItems[0];
-    }
-    return unclosableGroupItem;
-  },
-
-  // ----------
-  // Function: updateGroupCloseButtons
-  // Updates group close buttons.
-  updateGroupCloseButtons: function GroupItems_updateGroupCloseButtons() {
-    let unclosableGroupItem = this.getUnclosableGroupItem();
-
-    if (unclosableGroupItem) {
-      unclosableGroupItem.$closeButton.hide();
-    } else {
-      this.groupItems.forEach(function(groupItem) {
-        groupItem.$closeButton.show();
-      });
-    }
   }
 };
--- a/browser/base/content/tabview/search.js
+++ b/browser/base/content/tabview/search.js
@@ -510,16 +510,17 @@ function performSearch() {
   matcher.doSearch(TabHandlers.onMatch, TabHandlers.onUnmatch, TabHandlers.onOther);
 }
 
 function ensureSearchShown(event){
   var $search = iQ("#search");
   var $searchbox = iQ("#searchbox");
   iQ("#searchbutton").css({ opacity: 1 });
 
+
   if (!isSearchEnabled()) {
     $search.show();
     var mainWindow = gWindow.document.getElementById("main-window");
     mainWindow.setAttribute("activetitlebarcolor", "#717171");       
 
     // Marshal the focusing, otherwise you end up with
     // a race condition where only sometimes would the
     // first keystroke be registered by the search box.
--- a/browser/base/content/tabview/tabitems.js
+++ b/browser/base/content/tabview/tabitems.js
@@ -63,19 +63,18 @@ function TabItem(tab, options) {
     .addClass('tab')
     .html("<div class='thumb'>" +
           "<img class='cached-thumb' style='display:none'/><canvas/></div>" +
           "<div class='favicon'><img/></div>" +
           "<span class='tab-title'>&nbsp;</span>"
     )
     .appendTo('body');
 
-  this._cachedImageData = null;
-  this.shouldHideCachedData = false;
   this.canvasSizeForced = false;
+  this.isShowingCachedData = false;
   this.favEl = (iQ('.favicon', $div))[0];
   this.favImgEl = (iQ('.favicon>img', $div))[0];
   this.nameEl = (iQ('.tab-title', $div))[0];
   this.thumbEl = (iQ('.thumb', $div))[0];
   this.canvasEl = (iQ('.thumb canvas', $div))[0];
   this.cachedThumbEl = (iQ('img.cached-thumb', $div))[0];
 
   this.tabCanvas = new TabCanvas(this.tab, this.canvasEl);
@@ -183,20 +182,19 @@ function TabItem(tab, options) {
   });
 
   $div.mouseup(function(e) {
     var same = (e.target == self.lastMouseDownTarget);
     self.lastMouseDownTarget = null;
     if (!same)
       return;
 
-    // press close button or middle mouse click
-    if (iQ(e.target).hasClass("close") || e.button == 1) {
+    if (iQ(e.target).hasClass("close"))
       self.close();
-    } else {
+    else {
       if (!Items.item(this).isDragging)
         self.zoomIn();
     }
   });
 
   iQ("<div>")
     .addClass('close')
     .appendTo($div);
@@ -239,85 +237,54 @@ TabItem.prototype = Utils.extend(new Ite
   // size of thumbnail on screen. Note that this call does not nest, unlike
   // <TabItems.resumePainting>; if you call forceCanvasSize multiple
   // times, you just need a single unforce to clear them all.
   unforceCanvasSize: function TabItem_unforceCanvasSize() {
     this.canvasSizeForced = false;
   },
 
   // ----------
-  // Function: isShowingCachedData
-  // Returns a boolean indicates whether the cached data is being displayed or
-  // not. 
-  isShowingCachedData: function() {
-    return (this._cachedImageData != null);
-  },
-
-  // ----------
   // Function: showCachedData
   // Shows the cached data i.e. image and title.  Note: this method should only
   // be called at browser startup with the cached data avaliable.
-  //
-  // Parameters:
-  //   tabData - the tab data
   showCachedData: function TabItem_showCachedData(tabData) {
-    if (!this._cachedImageData) {
-      TabItems.cachedDataCounter++;
-      this.tab.linkedBrowser._tabViewTabItemWithCachedData = this;
-      if (TabItems.cachedDataCounter == 1)
-        gBrowser.addTabsProgressListener(TabItems.tabsProgressListener);
-    }
-    this._cachedImageData = tabData.imageData;
-    let $nameElement = iQ(this.nameEl);
-    let $canvasElement = iQ(this.canvasEl);
-    let $cachedThumbElement = iQ(this.cachedThumbEl);
-    $cachedThumbElement.attr("src", this._cachedImageData).show();
+    this.isShowingCachedData = true;
+    var $nameElement = iQ(this.nameEl);
+    var $canvasElement = iQ(this.canvasEl);
+    var $cachedThumbElement = iQ(this.cachedThumbEl);
+    $cachedThumbElement.attr("src", tabData.imageData).show();
     $canvasElement.css({opacity: 0.0});
     $nameElement.text(tabData.title ? tabData.title : "");
   },
 
   // ----------
   // Function: hideCachedData
   // Hides the cached data i.e. image and title and show the canvas.
   hideCachedData: function TabItem_hideCachedData() {
-    let $canvasElement = iQ(this.canvasEl);
-    let $cachedThumbElement = iQ(this.cachedThumbEl);
+    var $canvasElement = iQ(this.canvasEl);
+    var $cachedThumbElement = iQ(this.cachedThumbEl);
     $cachedThumbElement.hide();
     $canvasElement.css({opacity: 1.0});
-    if (this._cachedImageData) {
-      TabItems.cachedDataCounter--;
-      this._cachedImageData = null;
-      this.tab.linkedBrowser._tabViewTabItemWithCachedData = null;
-      if (TabItems.cachedDataCounter == 0)
-        gBrowser.removeTabsProgressListener(TabItems.tabsProgressListener);
-    }
+    this.isShowingCachedData = false;
   },
 
   // ----------
   // Function: getStorageData
   // Get data to be used for persistent storage of this object.
   //
   // Parameters:
   //   getImageData - true to include thumbnail pixels (and page title as well); default false
   getStorageData: function TabItem_getStorageData(getImageData) {
-    let imageData = null;
-
-    if (getImageData) { 
-      if (this._cachedImageData)
-        imageData = this._cachedImageData;
-      else if (this.tabCanvas)
-        imageData = this.tabCanvas.toImageData();
-    }
-
     return {
       bounds: this.getBounds(),
       userSize: (Utils.isPoint(this.userSize) ? new Point(this.userSize) : null),
       url: this.tab.linkedBrowser.currentURI.spec,
       groupID: (this.parent ? this.parent.id : 0),
-      imageData: imageData,
+      imageData: (getImageData && this.tabCanvas ?
+                  this.tabCanvas.toImageData() : null),
       title: getImageData && this.tab.label || null
     };
   },
 
   // ----------
   // Function: save
   // Store persistent for this object.
   //
@@ -730,53 +697,39 @@ TabItem.prototype = Utils.extend(new Ite
 // Singleton for managing <TabItem>s
 let TabItems = {
   minTabWidth: 40,
   tabWidth: 160,
   tabHeight: 120,
   fontSize: 9,
   items: [],
   paintingPaused: 0,
-  cachedDataCounter: 0,  // total number of cached data being displayed.
-  tabsProgressListener: null,
   _tabsWaitingForUpdate: [],
   _heartbeatOn: false, // see explanation at startHeartbeat() below
   _heartbeatTiming: 100, // milliseconds between _checkHeartbeat() calls
   _lastUpdateTime: Date.now(),
   _eventListeners: [],
   tempCanvas: null,
 
   // ----------
   // Function: init
   // Set up the necessary tracking to maintain the <TabItems>s.
   init: function TabItems_init() {
     Utils.assert(window.AllTabs, "AllTabs must be initialized first");
-    let self = this;
+    var self = this;
 
     let $canvas = iQ("<canvas>");
     $canvas.appendTo(iQ("body"));
     $canvas.hide();
     this.tempCanvas = $canvas[0];
     // 150 pixels is an empirical size, below which FF's drawWindow()
     // algorithm breaks down
     this.tempCanvas.width = 150;
     this.tempCanvas.height = 150;
 
-    this.tabsProgressListener = {
-      onStateChange: function(browser, webProgress, request, stateFlags, status) {
-        if ((stateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
-            (stateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW)) {
-          // browser would only has _tabViewTabItemWithCachedData if 
-          // it's showing cached data.
-          if (browser._tabViewTabItemWithCachedData)
-            browser._tabViewTabItemWithCachedData.shouldHideCachedData = true;
-        }
-      }
-    };
-
     // When a tab is opened, create the TabItem
     this._eventListeners["open"] = function(tab) {
       if (tab.ownerDocument.defaultView != gWindow || tab.pinned)
         return;
 
       self.link(tab);
     }
     // When a tab's content is loaded, show the canvas and hide the cached data
@@ -806,19 +759,16 @@ let TabItems = {
       self.link(tab, {immediately: true});
       self.update(tab);
     });
   },
 
   // ----------
   // Function: uninit
   uninit: function TabItems_uninit() {
-    if (this.tabsProgressListener)
-      gBrowser.removeTabsProgressListener(this.tabsProgressListener);
-
     for (let name in this._eventListeners) {
       AllTabs.unregister(name, this._eventListeners[name]);
     }
     this.items.forEach(function(tabItem) {
       for (let x in tabItem) {
         if (typeof tabItem[x] == "object")
           tabItem[x] = null;
       }
@@ -841,17 +791,17 @@ let TabItems = {
 
       let shouldDefer = (
         this.isPaintingPaused() ||
         this._tabsWaitingForUpdate.length ||
         Date.now() - this._lastUpdateTime < this._heartbeatTiming
       );
 
       let isCurrentTab = (
-        !UI.isTabViewVisible() &&
+        !UI._isTabViewVisible() &&
         tab == gBrowser.selectedTab
       );
 
       if (shouldDefer && !isCurrentTab) {
         if (this._tabsWaitingForUpdate.indexOf(tab) == -1)
           this._tabsWaitingForUpdate.push(tab);
         this.startHeartbeat();
       } else
@@ -874,17 +824,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)
+      if (iconUrl == null)
         iconUrl = Utils.defaultFaviconURL;
 
       if (iconUrl != tabItem.favImgEl.src)
         tabItem.favImgEl.src = iconUrl;
 
       // ___ URL
       let tabUrl = tab.linkedBrowser.currentURI.spec;
       if (tabUrl != tabItem.url) {
@@ -895,17 +845,17 @@ let TabItems = {
           this.reconnect(tabItem);
 
         tabItem.save();
       }
 
       // ___ label
       let label = tab.label;
       let $name = iQ(tabItem.nameEl);
-      if (!tabItem.isShowingCachedData() && $name.text() != label)
+      if (!tabItem.isShowingCachedData && $name.text() != label)
         $name.text(label);
 
       // ___ thumbnail
       let $canvas = iQ(tabItem.canvasEl);
       if (!tabItem.canvasSizeForced) {
         let w = $canvas.width();
         let h = $canvas.height();
         if (w != tabItem.canvasEl.width || h != tabItem.canvasEl.height) {
@@ -915,17 +865,18 @@ let TabItems = {
       }
 
       this._lastUpdateTime = Date.now();
       tabItem._lastTabUpdateTime = this._lastUpdateTime;
 
       tabItem.tabCanvas.paint();
 
       // ___ cache
-      if (tabItem.isShowingCachedData() && tabItem.shouldHideCachedData)
+      // TODO: this logic needs to be better; hiding too soon now
+      if (tabItem.isShowingCachedData && !tab.hasAttribute("busy"))
         tabItem.hideCachedData();
     } catch(e) {
       Utils.log(e);
     }
   },
 
   // ----------
   // Function: link
@@ -1134,18 +1085,26 @@ let TabItems = {
             // if it matches the selected tab or no active tab and the browser 
             // tab is hidden, the active group item would be set.
             if (item.tab == gBrowser.selectedTab || 
                 (!GroupItems.getActiveGroupItem() && !item.tab.hidden))
               GroupItems.setActiveGroupItem(item.parent);
           }
         }
 
-        if (tabData.imageData)
+        if (tabData.imageData) {
           item.showCachedData(tabData);
+          // the code in the progress listener doesn't fire sometimes because
+          // tab is being restored so need to catch that.
+          setTimeout(function() {
+            if (item && item.isShowingCachedData) {
+              item.hideCachedData();
+            }
+          }, 15000);
+        }
 
         item.reconnected = true;
         found = {addedToGroup: tabData.groupID};
       } else {
         // We should never have any orphaned tabs. Therefore, item is not 
         // connected if it has no parent and GroupItems.newTab() would handle 
         // the group creation.
         item.reconnected = (item.parent != null);
--- a/browser/base/content/tabview/tabview.css
+++ b/browser/base/content/tabview/tabview.css
@@ -194,16 +194,17 @@ body {
 ----------------------------------*/
 #exit-button {
   position: absolute;
   z-index: 1000;
 }
 
 /* Search
 ----------------------------------*/
+
 #search{
   position: absolute;
   top: 0px;
   left: 0px;
   z-index: 1000;  
 }
 
 html[dir=rtl] #search {
@@ -222,17 +223,17 @@ html[dir=rtl] #searchbox {
   right: auto;
   left: 20px;
 }
 
 #actions{
   position: absolute;
   top: 100px;
   right: 0px;
-  z-index: 10;
+  z-index:10;
 }
 
 html[dir=rtl] #actions {
   right: auto;
   left: 0;
 }
 
 #actions #searchbutton{
--- a/browser/base/content/tabview/tabview.html
+++ b/browser/base/content/tabview/tabview.html
@@ -5,17 +5,17 @@
   <title>&nbsp;</title>
   <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
   <link rel="stylesheet" href="tabview.css" type="text/css"/>
   <link rel="stylesheet" href="chrome://browser/skin/tabview/tabview.css" type="text/css"/>
 </head>
 
 <body transparent="true">
   <div id="content">
-    <input id="exit-button" type="image" alt="" groups="0" />
+    <input id="exit-button" type="image" alt=""/>
     <div id="actions">
       <input id="searchbutton" type="button"/>
     </div>
     <div id="bg" />
   </div>
   
   <div id="search">
     <input id="searchbox" type="text"/>
--- a/browser/base/content/tabview/ui.js
+++ b/browser/base/content/tabview/ui.js
@@ -143,18 +143,17 @@ let UI = {
       if (false)
         this._addDevMenu();
 
       // When you click on the background/empty part of TabView,
       // we create a new groupItem.
       iQ(gTabViewFrame.contentDocument).mousedown(function(e) {
         if (iQ(":focus").length > 0) {
           iQ(":focus").each(function(element) {
-            // don't fire blur event if the same input element is clicked.
-            if (e.target != element && element.nodeName == "INPUT")
+            if (element.nodeName == "INPUT")
               element.blur();
           });
         }
         if (e.originalTarget.id == "content")
           self._createGroupItemOnDrag(e)
       });
 
       iQ(window).bind("beforeunload", function() {
@@ -206,17 +205,17 @@ let UI = {
       iQ(window).resize(function() {
         self._resize();
       });
 
       // ___ setup observer to save canvas images
       var observer = {
         observe : function(subject, topic, data) {
           if (topic == "quit-application-requested") {
-            if (self.isTabViewVisible()) {
+            if (self._isTabViewVisible()) {
               GroupItems.removeHiddenGroups();
               TabItems.saveAll(true);
             }
             self._save();
           }
         }
       };
       Services.obs.addObserver(observer, "quit-application-requested", false);
@@ -375,19 +374,19 @@ let UI = {
         self._activeTab = null;
       });
 
       this._activeTab.makeActive();
     }
   },
 
   // ----------
-  // Function: isTabViewVisible
+  // Function: _isTabViewVisible
   // Returns true if the TabView UI is currently shown.
-  isTabViewVisible: function UI_isTabViewVisible() {
+  _isTabViewVisible: function UI__isTabViewVisible() {
     return gTabViewDeck.selectedIndex == 1;
   },
 
   // ---------
   // Function: _initPageDirection
   // Initializes the page base direction
   _initPageDirection: function UI__initPageDirection() {
     let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"].
@@ -398,17 +397,17 @@ let UI = {
   },
 
   // ----------
   // Function: showTabView
   // Shows TabView and hides the main browser UI.
   // Parameters:
   //   zoomOut - true for zoom out animation, false for nothing.
   showTabView: function UI_showTabView(zoomOut) {
-    if (this.isTabViewVisible())
+    if (this._isTabViewVisible())
       return;
 
     // initialize the direction of the page
     this._initPageDirection();
 
     var self = this;
     var currentTab = this._currentTab;
     var item = null;
@@ -464,17 +463,17 @@ let UI = {
 
     TabItems.resumePainting();
   },
 
   // ----------
   // Function: hideTabView
   // Hides TabView and shows the main browser UI.
   hideTabView: function UI_hideTabView() {
-    if (!this.isTabViewVisible())
+    if (!this._isTabViewVisible())
       return;
 
     // another tab might be select if user decides to stay on a page when
     // a onclose confirmation prompts.
     GroupItems.removeHiddenGroups();
     TabItems.pausePainting();
 
     this._reorderTabsOnHide.forEach(function(groupItem) {
@@ -563,18 +562,18 @@ let UI = {
     // don't reenter Panorama due to all of the session restore tab
     // manipulation (which otherwise we might). When transitioning away from
     // PB, we reenter Panorama if we had been there directly before PB.
     function pbObserver(aSubject, aTopic, aData) {
       if (aTopic == "private-browsing") {
         self._privateBrowsing.transitionStage = 3;
         if (aData == "enter") {
           // If we are in Tab View, exit. 
-          self._privateBrowsing.wasInTabView = self.isTabViewVisible();
-          if (self.isTabViewVisible())
+          self._privateBrowsing.wasInTabView = self._isTabViewVisible();
+          if (self._isTabViewVisible())
             self.goToTab(gBrowser.selectedTab);
         }
       } else if (aTopic == "private-browsing-change-granted") {
         if (aData == "enter" || aData == "exit") {
           self._privateBrowsing.transitionStage = 1;
           self._privateBrowsing.transitionMode = aData;
         }
       }
@@ -602,17 +601,17 @@ let UI = {
     this._eventListeners.close = function(tab) {
       if (tab.ownerDocument.defaultView != gWindow)
         return;
 
       // if it's an app tab, remove it from all the group items
       if (tab.pinned)
         GroupItems.removeAppTab(tab);
         
-      if (self.isTabViewVisible()) {
+      if (self._isTabViewVisible()) {
         // just closed the selected tab in the TabView interface.
         if (self._currentTab == tab)
           self._closedSelectedTabInTabView = true;
       } else {
         // If we're currently in the process of entering private browsing,
         // we don't want to go to the Tab View UI. 
         if (self._privateBrowsing.transitionStage > 0)
           return; 
@@ -715,29 +714,29 @@ let UI = {
   // ----------
   // Function: onTabSelect
   // Called when the user switches from one tab to another outside of the TabView UI.
   onTabSelect: function UI_onTabSelect(tab) {
     let currentTab = this._currentTab;
     this._currentTab = tab;
 
     // if the last visible tab has just been closed, don't show the chrome UI.
-    if (this.isTabViewVisible() &&
+    if (this._isTabViewVisible() &&
         (this._closedLastVisibleTab || this._closedSelectedTabInTabView)) {
       this._closedLastVisibleTab = false;
       this._closedSelectedTabInTabView = false;
       return;
     }
     // reset these vars, just in case.
     this._closedLastVisibleTab = false;
     this._closedSelectedTabInTabView = false;
 
     // if TabView is visible but we didn't just close the last tab or
     // selected tab, show chrome.
-    if (this.isTabViewVisible())
+    if (this._isTabViewVisible())
       this.hideTabView();
 
     // another tab might be selected when hideTabView() is invoked so a
     // validation is needed.
     if (this._currentTab != tab)
       return;
 
     let oldItem = null;
@@ -785,45 +784,42 @@ let UI = {
 
   // ----------
   // Function: setReorderTabsOnHide
   // Sets the groupItem which the tab items' tabs should be re-ordered when
   // switching to the main browser UI.
   // Parameters:
   //   groupItem - the groupItem which would be used for re-ordering tabs.
   setReorderTabsOnHide: function UI_setReorderTabsOnHide(groupItem) {
-    if (this.isTabViewVisible()) {
+    if (this._isTabViewVisible()) {
       var index = this._reorderTabsOnHide.indexOf(groupItem);
       if (index == -1)
         this._reorderTabsOnHide.push(groupItem);
     }
   },
 
   // ----------
   // Function: setReorderTabItemsOnShow
   // Sets the groupItem which the tab items should be re-ordered when
   // switching to the tab view UI.
   // Parameters:
   //   groupItem - the groupItem which would be used for re-ordering tab items.
   setReorderTabItemsOnShow: function UI_setReorderTabItemsOnShow(groupItem) {
-    if (!this.isTabViewVisible()) {
+    if (!this._isTabViewVisible()) {
       var index = this._reorderTabItemsOnShow.indexOf(groupItem);
       if (index == -1)
         this._reorderTabItemsOnShow.push(groupItem);
     }
   },
   
   // ----------
-  updateTabButton: function UI__updateTabButton() {
+  updateTabButton: function UI__updateTabButton(){
     let groupsNumber = gWindow.document.getElementById("tabviewGroupsNumber");
-    let exitButton = document.getElementById("exit-button");
     let numberOfGroups = GroupItems.groupItems.length;
-
     groupsNumber.setAttribute("groups", numberOfGroups);
-    exitButton.setAttribute("groups", numberOfGroups);
   },
 
   // ----------
   // Function: getClosestTab
   // Convenience function to get the next tab closest to the entered position
   getClosestTab: function UI_getClosestTab(tabCenter) {
     let cl = null;
     let clDist;
@@ -850,18 +846,17 @@ let UI = {
       if (!event.metaKey) 
         Keys.meta = false;
     });
 
     iQ(window).keydown(function(event) {
       if (event.metaKey) 
         Keys.meta = true;
 
-      if ((iQ(":focus").length > 0 && iQ(":focus")[0].nodeName == "INPUT") || 
-          isSearchEnabled())
+      if (isSearchEnabled())
         return;
 
       function getClosestTabBy(norm) {
         if (!self.getActiveTab())
           return null;
         var centers =
           [[item.bounds.center(), item]
              for each(item in TabItems.getItems()) if (!item.parent || !item.parent.hidden)];
@@ -1083,17 +1078,17 @@ let UI = {
     if (typeof force == "undefined")
       force = false;
 
     if (!this._pageBounds)
       return;
 
     // If TabView isn't focused and is not showing, don't perform a resize.
     // This resize really slows things down.
-    if (!force && !this.isTabViewVisible())
+    if (!force && !this._isTabViewVisible())
       return;
 
     var oldPageBounds = new Rect(this._pageBounds);
     var newPageBounds = Items.getPageBounds();
     if (newPageBounds.equals(oldPageBounds))
       return;
 
     var items = Items.getTopLevelItems();
--- a/browser/base/content/test/tabview/Makefile.in
+++ b/browser/base/content/test/tabview/Makefile.in
@@ -44,34 +44,30 @@ include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_FILES = \
                  browser_tabview_alltabs.js \
                  browser_tabview_apptabs.js \
                  browser_tabview_bug580412.js \
                  browser_tabview_bug587043.js \
                  browser_tabview_bug587231.js \
-                 browser_tabview_bug587351.js \
                  browser_tabview_bug587990.js \
                  browser_tabview_bug589324.js \
                  browser_tabview_bug590606.js \
                  browser_tabview_bug591706.js \
                  browser_tabview_bug594176.js \
                  browser_tabview_bug595191.js \
                  browser_tabview_bug595518.js \
                  browser_tabview_bug595521.js \
                  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 \
@@ -79,16 +75,15 @@ 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)
deleted file mode 100644
--- a/browser/base/content/test/tabview/browser_tabview_bug587351.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/* ***** 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 a test for bug 587351.
- *
- * 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();
-
-  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, "Has one group only");
-
-  let tabItems = contentWindow.GroupItems.groupItems[0].getChildren();
-  ok(tabItems.length, 2, "There are two tabItems in the group");
-
-  is(tabItems[1].tab, newTab, "The second tabItem is linked to the new tab");
-
-  EventUtils.sendMouseEvent({ type: "mousedown", button: 1 }, tabItems[1].container, contentWindow);
-  EventUtils.sendMouseEvent({ type: "mouseup", button: 1 }, tabItems[1].container, contentWindow);
-
-  ok(tabItems.length, 1, "There is only one tabItem in the group");
-
-  let endGame = function() {
-    window.removeEventListener("tabviewhidden", endGame, false);
-
-    finish();
-  };
-  window.addEventListener("tabviewhidden", endGame, false);
-  TabView.toggle();
-}
deleted file mode 100644
--- a/browser/base/content/test/tabview/browser_tabview_bug596781.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/* ***** 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 bug 596781 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);
-  ok(TabView.isVisible(), "Tab View is visible");
-
-  let contentWindow = document.getElementById("tab-view").contentWindow;
-
-  is(contentWindow.GroupItems.groupItems.length, 1, "Only one group exists"); 
-  is(gBrowser.tabs.length, 2, "Only one tab exists");
-  ok(newTab.pinned, "The original tab is pinned");
-
-  let groupItem = contentWindow.GroupItems.groupItems[0];
-  is(groupItem.$closeButton[0].style.display, "none", 
-     "The close button is hidden");
-
-  gBrowser.unpinTab(newTab);
-  is(groupItem.$closeButton[0].style.display, "", 
-     "The close button is visible");
-
-  function onTabViewHidden() {
-    window.removeEventListener("tabviewhidden", onTabViewHidden, false);
-    gBrowser.removeTab(newTab);
-    finish();
-  }
-  window.addEventListener("tabviewhidden", onTabViewHidden, false);
-  TabView.toggle();
-}
deleted file mode 100644
--- a/browser/base/content/test/tabview/browser_tabview_bug597248.js
+++ /dev/null
@@ -1,192 +0,0 @@
-/* ***** 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 bug 597248 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 newWin;
-let restoredWin;
-let newTabOne;
-let newTabTwo;
-let restoredNewTabOneLoaded = false;
-let restoredNewTabTwoLoaded = false;
-let frameInitialized = false;
-
-function test() {
-  waitForExplicitFinish();
-
-  // open a new window 
-  newWin = openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no");
-  newWin.addEventListener("load", function(event) {
-    newWin.removeEventListener("load", arguments.callee, false);
-    setupOne();
-  }, false);
-}
-
-function setupOne() {
-  let loadedCount = 0;
-  let allLoaded = function() {
-    if (++loadedCount == 2) {
-      newWin.addEventListener("tabviewshown", setupTwo, false);
-      newWin.TabView.toggle();
-    }
-  }
-  
-  newTabOne = newWin.gBrowser.tabs[0];
-  newTabTwo = newWin.gBrowser.addTab();
-  load(newTabOne, "http://mochi.test:8888/", allLoaded);
-  load(newTabTwo, "http://mochi.test:8888/browser/browser/base/content/test/tabview/dummy_page.html", allLoaded);
-}
-
-function setupTwo() {
-  newWin.removeEventListener("tabviewshown", setupTwo, false);
-
-  let contentWindow = newWin.document.getElementById("tab-view").contentWindow;
-
-  let tabItems = contentWindow.TabItems.getItems();
-  is(tabItems.length, 2, "There should be 2 tab items before closing");
-
-  // force all canvas to update
-  tabItems.forEach(function(tabItem) {
-    contentWindow.TabItems._update(tabItem.tab);
-  });
-  
-  // stimulate a quit application requested so the image data gets stored.
-  let quitRequestObserver = function(aSubject, aTopic, aData) {
-    ok(aTopic == "quit-application-requested" &&
-        aSubject instanceof Ci.nsISupportsPRBool,
-        "Received a quit request and going to deny it");
-    Services.obs.removeObserver(quitRequestObserver, "quit-application-requested", false);
-
-    aSubject.data = true;
-  }
-  Services.obs.addObserver(quitRequestObserver, "quit-application-requested", false);
-  ok(!Application.quit(), "Tried to quit and canceled it");
-
-  // check the storage for stored image data.
-  tabItems.forEach(function(tabItem) {
-    let tabData = contentWindow.Storage.getTabData(tabItem.tab);
-    ok(tabData && tabData.imageData, "TabItem has stored image data before closing");
-  });
-
-  // close the new window and restore it.
-  newWin.addEventListener("unload", function(event) {
-    newWin.removeEventListener("unload", arguments.callee, false);
-    newWin = null;
-
-    // restore window and test it
-    restoredWin = undoCloseWindow();
-    restoredWin.addEventListener("load", function(event) {
-      restoredWin.removeEventListener("load", arguments.callee, false);
-
-      // setup tab variables and listen to the load progress.
-      newTabOne = restoredWin.gBrowser.tabs[0];
-      newTabTwo = restoredWin.gBrowser.tabs[1];
-      restoredWin.gBrowser.addTabsProgressListener(gTabsProgressListener);
-
-      // execute code when the frame isninitialized.
-      restoredWin.addEventListener("tabviewframeinitialized", onTabViewFrameInitialized, false);
-    }, false);
-  }, false);
-
-  newWin.close();
-}
-
-let gTabsProgressListener = {
-  onStateChange: function(browser, webProgress, request, stateFlags, status) {
-    if (stateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
-         stateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) {
-      if (newTabOne.linkedBrowser == browser)
-        restoredNewTabOneLoaded = true;
-      else if (newTabTwo.linkedBrowser == browser)
-        restoredNewTabTwoLoaded = true;
- 
-      // since we are not sure whether the frame is initialized first or two tabs
-      // compete loading first so we need this.
-      if (restoredNewTabOneLoaded && restoredNewTabTwoLoaded) {
-        if (frameInitialized) {
-          // since a tabs progress listener is used in the code to set 
-          // tabItem.shouldHideCachedData, executeSoon is used to avoid a racing
-          // condition.
-          executeSoon(updateAndCheck); 
-        }
-        restoredWin.gBrowser.removeTabsProgressListener(gTabsProgressListener);
-      }
-    }
-  }
-};
-
-function onTabViewFrameInitialized() {
-  restoredWin.removeEventListener("tabviewframeinitialized", onTabViewFrameInitialized, false);
-
-  let contentWindow = restoredWin.document.getElementById("tab-view").contentWindow;
-
-  let tabItems = contentWindow.TabItems.getItems();
-  tabItems.forEach(function(tabItem) {
-    ok(tabItem.isShowingCachedData(), "Tab item is showing cached data");
-  });
-
-  // since we are not sure whether the frame is initialized first or two tabs
-  // compete loading first so we need this.
-  if (restoredNewTabOneLoaded && restoredNewTabTwoLoaded) {
-    // executeSoon is used to ensure tabItem.shouldHideCachedData is set
-    // because tabs progress listener might run at the same time as this test code.
-    executeSoon(updateAndCheck);
-  } else
-    frameInitialized = true;
-}
-
-function updateAndCheck() {
-  // force all canvas to update
-  let contentWindow = restoredWin.document.getElementById("tab-view").contentWindow;
-
-  let tabItems = contentWindow.TabItems.getItems();
-  tabItems.forEach(function(tabItem) {
-    contentWindow.TabItems._update(tabItem.tab);
-    ok(!tabItem.isShowingCachedData(), "Tab item is not showing cached data anymore");
-  });
-
-  // clean up and finish
-  restoredWin.close();
-  finish();
-}
-
-function load(tab, url, callback) {
-  tab.linkedBrowser.addEventListener("load", function (event) {
-    tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
-    callback();
-  }, true);
-  tab.linkedBrowser.loadURI(url);
-}
-
deleted file mode 100644
--- a/browser/base/content/test/tabview/browser_tabview_bug600645.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/* ***** 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");
-}
deleted file mode 100644
--- a/browser/base/content/test/tabview/test_bug600645.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
-<title>Fav Icon Test</title>
-<link rel="shortcut icon" href="favicon.ico">
-<body>Fav Icon Test</body>
-</html>
index df7212d78c8f86e7abe5073d85bf419786993550..b7c76d55fc349e6fbef71572efd8677904993d0b
GIT binary patch
literal 580
zc$@)50=xZ*P)<h;3K|Lk000e1NJLTq000yK000yS1^@s6jfou%00004b3#c}2nYxW
zd<bNS00009a7bBm000XT000XT0n*)m`~Uy|9CSrkbW?9;ba!ELWdK2BZ(?O2Mrm?o
zcW-iQb09-gGzPNMpa1{>6m&&cbVG7wVRUJ4ZXi@?ZDjyCFETGNFhWBKQ2+n|o=HSO
zR5*>Tlue4;KoCY>hinXn@mgR!*x<E}pc_nX5Z@qk1Rudim?P*2bA-;qOM`+zAPmM{
zH8fpaSwwPrgsdbp`Jhmvs($)P{bN*>|EW*iz!-xu24DtkfeO$hEbyhP>&H#1O6O8l
zb5*taTa~K5s_G?q_cG+{#_0wjgjoo|h7h!U=IMkG!X|`pY4f{30=@TJ@4b5Ot@nO5
z<idNOd+#r8-Qy_GIafL7)H#<A!8$qTwr$-TmmTM}C?c{Dksp)E#Et<)q!bZEWbnf&
z5D}@yU;xwU)V8&Q`Ohg37;P8ed_EWVV10+*MdaahI&H>)BJ$iiEJuMc#%+v|7~`&K
znn9;c(`;glPi@`czc$^bHpWob^$YM7xB@$%%(BeZbzK0@z*92!3KUtES>Sd!-T(oP
z$Kww8Hr93@I-k$&T_8YJRgbNswDpo-=eYzP`q0H<VebORbT}Mx;I$83E|)V%7UgfX
zTCJ>z6e4o%_G7w@{uv0cUaxJ8v4}BV+bC|y^!j>__WS)T<(QAahV-tM$Mh2(#cMvg
SZ&e-u0000<MNUMnLSTZ|`}$A-
--- a/browser/themes/gnomestripe/browser/tabview/tabview.css
+++ b/browser/themes/gnomestripe/browser/tabview/tabview.css
@@ -505,72 +505,60 @@ html[dir=rtl] .iq-resizable-se {
 }
 
 /* Exit button
 +----------------------------------*/
 #exit-button {
   cursor: default;
   top: 0;
   right: 0;
-  width: 16px;
-  height: 16px;
-  -moz-margin-end: 7px;
-  margin-top: 7px;
-  background-image: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 80, 16, 64);
-  background-attachment: scroll;
-  background-repeat: no-repeat;
-}
-
-#exit-button[groups="0"] {
-  background-image: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 16, 16, 0);
-}
-
-#exit-button[groups="1"] {
-  background-image: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 32, 16, 16);
-}
-
-#exit-button[groups="2"] {
-  background-image: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 48, 16, 32);
-}
-
-#exit-button[groups="3"] {
-  background-image: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 64, 16, 48);
+  width: 28px;
+  height: 27px;
+  background: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 16, 16, 0) no-repeat scroll 7px 7px #b7b7b7;
+  border-bottom: 1px solid #909090;
+  -moz-border-start: 1px solid #B7B7B7;
+  border-top: 1px solid #CFCFCF;
+  border-radius: 3px 0 0 3px;
 }
 
 html[dir=rtl] #exit-button {
   right: auto;
   left: 0;
   border-radius: 0 3px 3px 0;
 }
 
 /* Search
 ----------------------------------*/
+
 #search{
   background-color: rgba(0,0,0,.42);
   width: 100%;
   height: 100%;  
 }
 
 #searchbox{
   width: 270px;
   height: 30px;
   box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,1), 0px 0px 9px rgba(0,0,0,.8);
   color: white;
   border: none;
   background-color: #272727;
   border-radius: 0.4em;
   -moz-padding-start: 5px;
   -moz-padding-end: 5px;
-  font-size: 14px;
+  font-size: 14px;  
 }
 
 #actions{
-  width: 26px;
-  height: 26px;
+  width: 30px;
+  height: 30px;
+  background-color: #666;
   border: none;
+  box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,.8), inset 6px 6px 9px rgba(0,0,0,.56);
+  opacity: .64;
   text-align: center;
 }
 
 html[dir=ltr] #actions {
   border-bottom-left-radius: 0.4em;
   border-top-left-radius: 0.4em;    
 }
 
@@ -580,17 +568,22 @@ html[dir=rtl] #actions {
   box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,.8), inset -6px 6px 9px rgba(0,0,0,.56);
 }
 
 #actions #searchbutton{
   background: transparent url(chrome://browser/skin/tabview/search.png) no-repeat;
   border: none;
   width: 20px;
   height: 20px;
-  margin-top: 3px;
+  margin-top:5px;
+  opacity: .8;  
+}
+
+#actions #searchbutton:hover{
+  opacity: 1.0;
 }
 
 .notMainMatch{
   opacity: .70;
 }
 
 #otherresults {
   left: 0px;
index df7212d78c8f86e7abe5073d85bf419786993550..b7c76d55fc349e6fbef71572efd8677904993d0b
GIT binary patch
literal 580
zc$@)50=xZ*P)<h;3K|Lk000e1NJLTq000yK000yS1^@s6jfou%00004b3#c}2nYxW
zd<bNS00009a7bBm000XT000XT0n*)m`~Uy|9CSrkbW?9;ba!ELWdK2BZ(?O2Mrm?o
zcW-iQb09-gGzPNMpa1{>6m&&cbVG7wVRUJ4ZXi@?ZDjyCFETGNFhWBKQ2+n|o=HSO
zR5*>Tlue4;KoCY>hinXn@mgR!*x<E}pc_nX5Z@qk1Rudim?P*2bA-;qOM`+zAPmM{
zH8fpaSwwPrgsdbp`Jhmvs($)P{bN*>|EW*iz!-xu24DtkfeO$hEbyhP>&H#1O6O8l
zb5*taTa~K5s_G?q_cG+{#_0wjgjoo|h7h!U=IMkG!X|`pY4f{30=@TJ@4b5Ot@nO5
z<idNOd+#r8-Qy_GIafL7)H#<A!8$qTwr$-TmmTM}C?c{Dksp)E#Et<)q!bZEWbnf&
z5D}@yU;xwU)V8&Q`Ohg37;P8ed_EWVV10+*MdaahI&H>)BJ$iiEJuMc#%+v|7~`&K
znn9;c(`;glPi@`czc$^bHpWob^$YM7xB@$%%(BeZbzK0@z*92!3KUtES>Sd!-T(oP
z$Kww8Hr93@I-k$&T_8YJRgbNswDpo-=eYzP`q0H<VebORbT}Mx;I$83E|)V%7UgfX
zTCJ>z6e4o%_G7w@{uv0cUaxJ8v4}BV+bC|y^!j>__WS)T<(QAahV-tM$Mh2(#cMvg
SZ&e-u0000<MNUMnLSTZ|`}$A-
--- a/browser/themes/pinstripe/browser/tabview/tabview.css
+++ b/browser/themes/pinstripe/browser/tabview/tabview.css
@@ -496,73 +496,61 @@ html[dir=rtl] .iq-resizable-se {
   left: 1px;
 }
 
 /* Exit button
 +----------------------------------*/
 #exit-button {
   cursor: default;
   top: 0;
-  right: 1px;
-  width: 20px;
-  height: 20px;
-  -moz-margin-end: 2px;
-  margin-top: 2px;
-  background-image: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 100, 20, 80);
-  background-attachment: scroll;
-  background-repeat: no-repeat;
-}
-
-#exit-button[groups="0"] {
-  background-image: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 20, 20, 0);
-}
-
-#exit-button[groups="1"] {
-  background-image: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 40, 20, 20);
-}
-
-#exit-button[groups="2"] {
-  background-image: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 60, 20, 40);
-}
-
-#exit-button[groups="3"] {
-  background-image: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 80, 20, 60);
+  right: 0;
+  width: 28px;
+  height: 27px;
+  background: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 20, 20, 0) no-repeat scroll 4px 4px #b7b7b7;
+  border-bottom: 1px solid #909090;
+  -moz-border-start: 1px solid #B7B7B7;
+  border-top: 1px solid #CFCFCF;
+  border-radius: 3px 0 0 3px;
 }
 
 html[dir=rtl] #exit-button {
   right: auto;
   left: 0;
   border-radius: 0 3px 3px 0;
 }
 
 /* Search
 ----------------------------------*/
+
 #search {
   background-color: rgba(0,0,0,.42);
   width: 100%;
-  height: 100%;
+  height: 100%;  
 }
 
 #searchbox {
   width: 270px;
   height: 30px;
   box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,1), 0px 0px 13px rgba(0,0,0,.8);
   color: white;
   border: none;
   background-color: #272727;
   border-radius: 0.4em;
   -moz-padding-start: 5px;
   -moz-padding-end: 5px;
   font-size: 14px;  
 }
 
 #actions {
-  width: 26px;
-  height: 26px;
+  width: 30px;
+  height: 30px;
+  background-color: #666;
   border: none;
+  box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,.8), inset 6px 6px 13px rgba(0,0,0,.56);
+  opacity: .64;
   text-align: center;
 }
 
 html[dir=ltr] #actions {
   border-bottom-left-radius: 0.4em;
   border-top-left-radius: 0.4em;    
 }
 
@@ -572,17 +560,22 @@ html[dir=rtl] #actions {
   box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,.8), inset -6px 6px 13px rgba(0,0,0,.56);
 }
 
 #actions #searchbutton {
   background: transparent url(chrome://browser/skin/tabview/search.png) no-repeat;
   border: none;
   width: 20px;
   height: 20px;
-  margin-top: 3px;
+  margin-top:5px;
+  opacity: .8;  
+}
+
+#actions #searchbutton:hover {
+  opacity: 1.0;
 }
 
 .notMainMatch {
   opacity: .70;
 }
 
 #otherresults {
   left: 0px;
index df7212d78c8f86e7abe5073d85bf419786993550..b7c76d55fc349e6fbef71572efd8677904993d0b
GIT binary patch
literal 580
zc$@)50=xZ*P)<h;3K|Lk000e1NJLTq000yK000yS1^@s6jfou%00004b3#c}2nYxW
zd<bNS00009a7bBm000XT000XT0n*)m`~Uy|9CSrkbW?9;ba!ELWdK2BZ(?O2Mrm?o
zcW-iQb09-gGzPNMpa1{>6m&&cbVG7wVRUJ4ZXi@?ZDjyCFETGNFhWBKQ2+n|o=HSO
zR5*>Tlue4;KoCY>hinXn@mgR!*x<E}pc_nX5Z@qk1Rudim?P*2bA-;qOM`+zAPmM{
zH8fpaSwwPrgsdbp`Jhmvs($)P{bN*>|EW*iz!-xu24DtkfeO$hEbyhP>&H#1O6O8l
zb5*taTa~K5s_G?q_cG+{#_0wjgjoo|h7h!U=IMkG!X|`pY4f{30=@TJ@4b5Ot@nO5
z<idNOd+#r8-Qy_GIafL7)H#<A!8$qTwr$-TmmTM}C?c{Dksp)E#Et<)q!bZEWbnf&
z5D}@yU;xwU)V8&Q`Ohg37;P8ed_EWVV10+*MdaahI&H>)BJ$iiEJuMc#%+v|7~`&K
znn9;c(`;glPi@`czc$^bHpWob^$YM7xB@$%%(BeZbzK0@z*92!3KUtES>Sd!-T(oP
z$Kww8Hr93@I-k$&T_8YJRgbNswDpo-=eYzP`q0H<VebORbT}Mx;I$83E|)V%7UgfX
zTCJ>z6e4o%_G7w@{uv0cUaxJ8v4}BV+bC|y^!j>__WS)T<(QAahV-tM$Mh2(#cMvg
SZ&e-u0000<MNUMnLSTZ|`}$A-
--- a/browser/themes/winstripe/browser/tabview/tabview.css
+++ b/browser/themes/winstripe/browser/tabview/tabview.css
@@ -522,74 +522,62 @@ html[dir=rtl] .iq-resizable-se {
   right: auto;
   left: 1px;
 }
 
 /* Exit button
 +----------------------------------*/
 #exit-button {
   cursor: default;
-  top: 1px;
+  top: 0;
   right: 0;
-  width: 18px;
-  height: 18px;
-  -moz-margin-end: 3px;
-  margin-top: 3px;
-  background-image: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 90, 18, 72);
-  background-attachment: scroll;
-  background-repeat: no-repeat;
-}
-
-#exit-button[groups="0"] {
-  background-image: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 18, 18, 0);
-}
-
-#exit-button[groups="1"] {
-  background-image: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 36, 18, 18);
-}
-
-#exit-button[groups="2"] {
-  background-image: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 54, 18, 36);
-}
-
-#exit-button[groups="3"] {
-  background-image: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 72, 18, 54);
+  width: 28px;
+  height: 27px;
+  background: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 18, 18, 0) no-repeat scroll 4px 4px #b7b7b7;
+  border-bottom: 1px solid #909090;
+  -moz-border-start: 1px solid #B7B7B7;
+  border-top: 1px solid #CFCFCF;
+  border-radius: 3px 0 0 3px;
 }
 
 html[dir=rtl] #exit-button {
   right: auto;
   left: 0;
   border-radius: 0 3px 3px 0;
 }
 
 /* Search
 ----------------------------------*/
+
 #search{
   background-color: rgba(0,0,0,.42);
   width: 100%;
   height: 100%;  
 }
 
 #searchbox{
   width: 270px;
   height: 30px;
   box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,1), 0px 0px 9px rgba(0,0,0,.8);
   color: white;
   border: none;
   background-color: #272727;
   border-radius: 0.4em;
   -moz-padding-start: 5px;
   -moz-padding-end: 5px;
-  font-size: 14px;
+  font-size: 14px;  
 }
 
 #actions{
-  width: 26px;
-  height: 26px;
+  width: 30px;
+  height: 30px;
+  background-color: #CFDBE8;
   border: none;
+  box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,.8), inset 6px 6px 9px rgba(0,0,0,.56);
+  opacity: .64;
   text-align: center;
 }
 
 html[dir=ltr] #actions {
   border-bottom-left-radius: 0.4em;
   border-top-left-radius: 0.4em;
 }
 
@@ -599,17 +587,22 @@ html[dir=rtl] #actions {
   box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,.8), inset -6px 6px 9px rgba(0,0,0,.56);
 }
 
 #actions #searchbutton{
   background: transparent url(chrome://browser/skin/tabview/search.png) no-repeat;
   border: none;
   width: 20px;
   height: 20px;
-  margin-top: 3px;
+  margin-top:5px;
+  opacity: .8;  
+}
+
+#actions #searchbutton:hover{
+  opacity: 1.0;
 }
 
 .notMainMatch{
   opacity: .70;
 }
 
 #otherresults {
   left: 0px;