From f3bd9d72621c3824674f792ab2d60f8042e778a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Tue, 4 Nov 2008 09:19:55 +0100 Subject: [PATCH] Bug 456088 - Ctrl+Tab revision. r=connor --- browser/app/profile/firefox.js | 1 - browser/base/content/browser-tabPreviews.js | 559 ++++++++---------- browser/base/content/browser.css | 16 +- browser/base/content/browser.xul | 35 +- browser/base/content/test/browser_ctrlTab.js | 2 +- .../themes/gnomestripe/browser/browser.css | 40 +- browser/themes/pinstripe/browser/browser.css | 53 +- .../themes/winstripe/browser/browser-aero.css | 5 - browser/themes/winstripe/browser/browser.css | 52 +- 9 files changed, 360 insertions(+), 403 deletions(-) diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 15c442d39f53..b9093342d9dd 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -341,7 +341,6 @@ pref("browser.tabs.selectOwnerOnClose", true); pref("browser.ctrlTab.mostRecentlyUsed", true); pref("browser.ctrlTab.recentlyUsedLimit", 7); -pref("browser.ctrlTab.smoothScroll", true); // Default bookmark sorting pref("browser.bookmarks.sort.direction", "descending"); diff --git a/browser/base/content/browser-tabPreviews.js b/browser/base/content/browser-tabPreviews.js index f003158da03f..931a7460f823 100644 --- a/browser/base/content/browser-tabPreviews.js +++ b/browser/base/content/browser-tabPreviews.js @@ -77,12 +77,11 @@ var tabPreviews = { ctx.drawWindow(win, win.scrollX, win.scrollY, snippetWidth, snippetWidth * this.aspectRatio, "rgb(255,255,255)"); - var data = thumbnail.toDataURL("image/jpeg", "quality=60"); if (aStore) { - aTab.__thumbnail = data; + aTab.__thumbnail = thumbnail; aTab.__thumbnail_lastURI = aTab.linkedBrowser.currentURI.spec; } - return data; + return thumbnail; }, handleEvent: function (event) { switch (event.type) { @@ -114,8 +113,6 @@ var tabPreviews = { * Ctrl-Tab panel */ var ctrlTab = { - visibleCount: 3, - _uniqid: 0, get panel () { delete this.panel; return this.panel = document.getElementById("ctrlTab-panel"); @@ -124,29 +121,18 @@ var ctrlTab = { delete this.label; return this.label = document.getElementById("ctrlTab-label"); }, - get svgRoot () { - delete this.svgRoot; - - let (groundFade = document.getElementById("ctrlTab-groundFade")) { - groundFade.setAttribute("height", Math.ceil(tabPreviews.height * .25) + 1); - groundFade.setAttribute("y", tabPreviews.height + 1); - } - - this.svgRoot = document.getElementById("ctrlTab-svgRoot"); - this.svgRoot.setAttribute("height", tabPreviews.height * 1.25 + 2); - return this.svgRoot; + get pagesBar () { + delete this.pagesBar; + return this.pagesBar = document.getElementById("ctrlTab-pages"); }, - get container () { - delete this.container; - return this.container = document.getElementById("ctrlTab-container"); + get thumbnails () { + delete this.thumbnails; + return this.thumbnails = this.panel.getElementsByClassName("ctrlTab-thumbnail"); }, - get rtl () { - delete this.rtl; - return this.rtl = getComputedStyle(this.panel, "").direction == "rtl"; - }, - get iconSize () { - delete this.iconSize; - return this.iconSize = Math.max(16, Math.round(tabPreviews.height / 5)); + get columns () { + delete this.columns; + return this.columns = this.thumbnails.length / + this.panel.getElementsByClassName("ctrlTab-row").length; }, get closeCharCode () { delete this.closeCharCode; @@ -158,24 +144,43 @@ var ctrlTab = { delete this.recentlyUsedLimit; return this.recentlyUsedLimit = gPrefService.getIntPref("browser.ctrlTab.recentlyUsedLimit"); }, - get smoothScroll () { - delete this.smoothScroll; - return this.smoothScroll = gPrefService.getBoolPref("browser.ctrlTab.smoothScroll"); + selectedIndex: 0, + get selected () this.thumbnails.item(this.selectedIndex), + get isOpen () this.panel.state == "open" || this.panel.state == "showing", + get tabCount () gBrowser.mTabs.length - (this._closing ? 1 : 0), + get pages () Math.ceil(this.tabCount / this.thumbnails.length), + get page () this._page || 0, + set page (page) { + if (page < 0) + page = this.pages - 1; + else if (page >= this.pages) + page = 0; + + if (this.pagesBar.childNodes.length) { + this.pagesBar.childNodes[this.page].removeAttribute("selected"); + this.pagesBar.childNodes[page].setAttribute("selected", "true"); + } + + this._page = page; + this.updatePreviews(); + return page; }, - get tabCount () { - return gBrowser.mTabs.length; - }, - get offscreenStart () { - return Array.indexOf(this.container.childNodes, this.selected) - 1; - }, - get offscreenEnd () { - return this.container.childNodes.length - this.visibleCount - this.offscreenStart; - }, - get offsetX () { - return - tabPreviews.width * (this.rtl ? this.offscreenEnd : this.offscreenStart); - }, - get isOpen () { - return this.panel.state == "open" || this.panel.state == "showing"; + get tabList () { + var list = Array.slice(gBrowser.mTabs); + if (this._closing) + this.detachTab(this._closing, list); + for (let i = 0; i < gBrowser.tabContainer.selectedIndex; i++) + list.push(list.shift()); + if (!this._useTabBarOrder && this.recentlyUsedLimit != 0) { + let recentlyUsedTabs = this._recentlyUsedTabs; + if (this.recentlyUsedLimit > 0) + recentlyUsedTabs = this._recentlyUsedTabs.slice(0, this.recentlyUsedLimit); + for (let i = recentlyUsedTabs.length - 1; i >= 0; i--) { + list.splice(list.indexOf(recentlyUsedTabs[i]), 1); + list.unshift(recentlyUsedTabs[i]); + } + } + return list; }, init: function () { if (this._recentlyUsedTabs) @@ -200,246 +205,128 @@ var ctrlTab = { this.panel.removeEventListener("popuphiding", this, false); document.removeEventListener("keypress", this, false); + gBrowser.mTabBox.handleCtrlTab = true; }, - addBox: function (aAtStart) { - const SVGNS = "http://www.w3.org/2000/svg"; - - var thumbnail = document.createElementNS(SVGNS, "image"); - thumbnail.setAttribute("class", "ctrlTab-thumbnail"); - thumbnail.setAttribute("height", tabPreviews.height); - thumbnail.setAttribute("width", tabPreviews.width); - - var thumbnail_border = document.createElementNS(SVGNS, "rect"); - thumbnail_border.setAttribute("class", "ctrlTab-thumbnailborder"); - thumbnail_border.setAttribute("height", tabPreviews.height); - thumbnail_border.setAttribute("width", tabPreviews.width); - - var icon = document.createElementNS(SVGNS, "image"); - icon.setAttribute("class", "ctrlTab-icon"); - icon.setAttribute("height", this.iconSize); - icon.setAttribute("width", this.iconSize); - icon.setAttribute("x", - this.iconSize * .2); - icon.setAttribute("y", tabPreviews.height - this.iconSize * 1.2); - - var thumbnail_and_icon = document.createElementNS(SVGNS, "g"); - thumbnail_and_icon.appendChild(thumbnail); - thumbnail_and_icon.appendChild(thumbnail_border); - thumbnail_and_icon.appendChild(icon); - - var reflection = document.createElementNS(SVGNS, "use"); - reflection.setAttribute("class", "ctrlTab-reflection"); - var ref_scale = .5; - reflection.setAttribute("transform", "scale(1,-" + ref_scale + ")"); - reflection.setAttribute("y", - ((1 / ref_scale + 1) * tabPreviews.height + - (1 / ref_scale) * 2)); - - var box = document.createElementNS(SVGNS, "g"); - box.setAttribute("class", "ctrlTab-box"); - box.setAttribute("onclick", "ctrlTab.pick(this);"); - box.appendChild(thumbnail_and_icon); - box.appendChild(reflection); - - if (aAtStart) - this.container.insertBefore(box, this.container.firstChild); - else - this.container.appendChild(box); - return box; - }, - removeBox: function (aBox) { - this.container.removeChild(aBox); - if (!Array.some(this.container.childNodes, function (box) box._tab == aBox._tab)) - aBox._tab.removeEventListener("DOMAttrModified", this, false); - aBox._tab = null; - }, - addPreview: function (aBox, aTab) { - const XLinkNS = "http://www.w3.org/1999/xlink"; - - aBox._tab = aTab; - let (thumbnail = aBox.firstChild.firstChild) - thumbnail.setAttributeNS(XLinkNS, "href", tabPreviews.get(aTab)); - this.updateIcon(aBox); - - aTab.addEventListener("DOMAttrModified", this, false); - - if (!aBox.firstChild.hasAttribute("id")) { - // set up reflection - this._uniqid++; - aBox.firstChild.setAttribute("id", "ctrlTab-preview-" + this._uniqid); - aBox.lastChild.setAttributeNS(XLinkNS, "href", "#ctrlTab-preview-" + this._uniqid); + buildPagesBar: function () { + var pages = this.pages; + if (pages == 1) + pages = 0; + while (this.pagesBar.childNodes.length > pages) + this.pagesBar.removeChild(this.pagesBar.lastChild); + while (this.pagesBar.childNodes.length < pages) { + let pointer = document.createElement("spacer"); + pointer.setAttribute("onclick", "ctrlTab.goToPage(" + this.pagesBar.childNodes.length + ");"); + pointer.setAttribute("class", "ctrlTab-pagePointer"); + this.pagesBar.appendChild(pointer); } }, - updateIcon: function (aBox) { - const XLinkNS = "http://www.w3.org/1999/xlink"; - var url = aBox._tab.hasAttribute("busy") ? - "chrome://global/skin/icons/loading_16.png" : - aBox._tab.getAttribute("image"); - var icon = aBox.firstChild.lastChild; - if (url) - icon.setAttributeNS(XLinkNS, "href", url); - else - icon.removeAttributeNS(XLinkNS, "href"); + goToPage: function (aPage, aIndex) { + if (this.page != aPage) + this.page = aPage; + this.selected.removeAttribute("selected"); + if (aIndex) { + this.selectedIndex = aIndex; + while (!this.selected || !this.selected.hasAttribute("valid")) + this.selectedIndex--; + } else { + this.selectedIndex = 0; + } + this.updateSelected(); + }, + updatePreviews: function () { + var tabs = this.tabList; + var offset = this.page * this.thumbnails.length; + for (let i = 0; i < this.thumbnails.length; i++) + this.updatePreview(this.thumbnails[i], tabs[i + offset]); + }, + updatePreview: function (aThumbnail, aTab) { + do { + if (aThumbnail._tab) { + if (aThumbnail._tab == aTab) + break; + aThumbnail._tab.removeEventListener("DOMAttrModified", this, false); + } + aThumbnail._tab = aTab; + if (aTab) + aTab.addEventListener("DOMAttrModified", this, false); + } while (false); + + if (aThumbnail.firstChild) + aThumbnail.removeChild(aThumbnail.firstChild); + if (aTab) { + aThumbnail.appendChild(tabPreviews.get(aTab)); + aThumbnail.setAttribute("valid", "true"); + } else { + aThumbnail.removeAttribute("valid"); + } + aThumbnail.width = tabPreviews.width; + aThumbnail.height = tabPreviews.height; }, tabAttrModified: function (aTab, aAttrName) { switch (aAttrName) { case "busy": - case "image": - Array.forEach(this.container.childNodes, function (box) { - if (box._tab == aTab) { - if (aAttrName == "busy") - this.addPreview(box, aTab); - else - this.updateIcon(box); - } - }, this); - break; - case "label": - case "crop": - if (!this._scrollTimer) { - let boxes = this.container.childNodes; - for (let i = boxes.length - 1; i >= 0; i--) { - if (boxes[i]._tab == aTab && boxes[i] == this.selected) { - this.label[aAttrName == "label" ? "value" : aAttrName] = - aTab.getAttribute(aAttrName); - break; - } + for (let i = this.thumbnails.length - 1; i >= 0; i--) { + if (this.thumbnails[i]._tab == aTab) { + this.updatePreview(this.thumbnails[i], aTab); + break; } } break; - } - }, - scroll: function () { - if (!this.smoothScroll) { - this.advanceSelected(); - this.arrangeBoxes(); - return; - } - - this.stopScroll(); - let (next = this.invertDirection ? this.selected.previousSibling : this.selected.nextSibling) { - this.setStatusbarValue(next); - this.label.value = next._tab.label; - this.label.crop = next._tab.crop; - } - - const FRAME_LENGTH = 40; - var x = this.offsetX; - var scrollAmounts = let (tenth = tabPreviews.width / (this.invertDirection == this.rtl ? -10 : 10)) - [3 * tenth, 4 * tenth, 2 * tenth, tenth]; - - function processFrame(self, lateness) { - lateness += FRAME_LENGTH / 2; - do { - x += scrollAmounts.shift(); - lateness -= FRAME_LENGTH; - } while (lateness > 0 && scrollAmounts.length); - self.container.setAttribute("transform", "translate("+ x +",0)"); - self.svgRoot.forceRedraw(); - if (!scrollAmounts.length) - self.stopScroll(); - } - - this._scrollTimer = setInterval(processFrame, FRAME_LENGTH, this); - processFrame(this, 0); - }, - stopScroll: function () { - if (this._scrollTimer) { - clearInterval(this._scrollTimer); - this._scrollTimer = 0; - this.advanceSelected(); - this.arrangeBoxes(); + case "label": + case "crop": + if (this.selected._tab == aTab) + this.label[aAttrName == "label" ? "value" : aAttrName] = aTab[aAttrName]; + break; } }, advanceSelected: function () { - // regardless of visibleCount, the new highlighted tab will be - // the first or third-visible tab, depending on whether Shift is pressed - var index = ((this.invertDirection ? 0 : 2) + this.offscreenStart + this.tabCount) - % this.tabCount; - if (index < 2) - index += this.tabCount; - if (index > this.container.childNodes.length - this.visibleCount + 1) - index -= this.tabCount; - this.selected = this.container.childNodes[index]; - }, - arrangeBoxes: function () { - this.addOffscreenBox(this.invertDirection); - this.addOffscreenBox(!this.invertDirection); + this.selected.removeAttribute("selected"); - // having lots of off-screen boxes reduces the scrolling speed, remove some - for (let i = this.offscreenStart; i > 1; i--) - this.removeBox(this.container.firstChild); - for (let i = this.offscreenEnd; i > 1; i--) - this.removeBox(this.container.lastChild); - - this.container.setAttribute("transform", "translate("+ this.offsetX +", 0)"); - - for (let i = 0, l = this.container.childNodes.length; i < l; i++) - this.arrange(i); - }, - addOffscreenBox: function (aAtStart) { - if (this.container.childNodes.length < this.tabCount + this.visibleCount + 1 && - !(aAtStart ? this.offscreenStart : this.offscreenEnd)) { - let tabs = this.getTabList(); - let i = aAtStart ? - tabs.indexOf(this.container.firstChild._tab) - 1: - tabs.indexOf(this.container.lastChild._tab) + 1; - i = (i + tabs.length) % tabs.length; - this.addPreview(this.addBox(aAtStart), tabs[i]); + this.selectedIndex += this.invertDirection ? -1 : 1; + if (this.selectedIndex < 0) { + this.page--; + this.selectedIndex = this.thumbnails.length - 1; + while (!this.selected.hasAttribute("valid")) + this.selectedIndex--; + } else if (this.selectedIndex >= this.thumbnails.length || !this.selected.hasAttribute("valid")) { + this.page++; + this.selectedIndex = 0; } + this.updateSelected(); }, - arrange: function (aIndex) { - var box = this.container.childNodes[aIndex]; - var selected = box == this.selected; - if (selected) { - box.setAttribute("selected", "true"); - this.setStatusbarValue(box); - this.label.value = box._tab.label; - this.label.crop = box._tab.crop; + updateSelected: function () { + var thumbnail = this.selected; + thumbnail.setAttribute("selected", "true"); + this.label.value = thumbnail._tab.label; + this.label.crop = thumbnail._tab.crop; + var url = thumbnail._tab.linkedBrowser.currentURI.spec; + if (url == "about:blank") { + // XXXhack: Passing a space here (and not "") + // to make sure the browser implementation would + // still consider it a hovered link. + url = " "; } else { - box.removeAttribute("selected"); + try { + url = decodeURI(url); + } catch (e) {} } - var scale = selected ? 1 : .75; - var pos = this.rtl ? this.container.childNodes.length - 1 - aIndex : aIndex; - var trans_x = tabPreviews.width * (pos + (1 - scale) / 2) / scale; - var trans_y = (tabPreviews.height + 1) * (1 / scale - 1); - box.setAttribute("transform", "scale(" + scale + "," + scale + ") " + - "translate("+ trans_x + "," + trans_y + ")"); + XULBrowserWindow.setOverLink(url, null); }, - pick: function (aBox) { - this.stopScroll(); - var selectedTab = (aBox || this.selected)._tab; + thumbnailClick: function (event) { + switch (event.button) { + case 0: + this.selectThumbnail(event.currentTarget); + break; + case 1: + gBrowser.removeTab(event.currentTarget._tab); + break; + } + }, + selectThumbnail: function (aThumbnail) { + var selectedTab = (aThumbnail || this.selected)._tab; this.panel.hidePopup(); gBrowser.selectedTab = selectedTab; }, - setStatusbarValue: function (aBox) { - var value = ""; - if (aBox) { - value = aBox._tab.linkedBrowser.currentURI.spec; - if (value == "about:blank") { - // XXXhack: Passing a space here (and not "") - // to make sure the browser implementation would - // still consider it a hovered link. - value = " "; - } else { - try { - value = decodeURI(value); - } catch (e) {} - } - } - XULBrowserWindow.setOverLink(value, null); - }, - getTabList: function () { - var list = Array.slice(gBrowser.mTabs); - for (let i = 0; i < gBrowser.tabContainer.selectedIndex; i++) - list.push(list.shift()); - if (!this._useTabBarOrder && this.recentlyUsedLimit > 0) { - let recentlyUsedTabs = this._recentlyUsedTabs.slice(0, this.recentlyUsedLimit); - for (let i = recentlyUsedTabs.length - 1; i >= 0; i--) { - list.splice(list.indexOf(recentlyUsedTabs[i]), 1); - list.unshift(recentlyUsedTabs[i]); - } - } - return list; - }, attachTab: function (aTab, aPos) { if (aPos == 0) this._recentlyUsedTabs.unshift(aTab); @@ -448,37 +335,35 @@ var ctrlTab = { else this._recentlyUsedTabs.push(aTab); }, - detachTab: function (aTab) { - var i = this._recentlyUsedTabs.indexOf(aTab); + detachTab: function (aTab, aTabs) { + var tabs = aTabs || this._recentlyUsedTabs; + var i = tabs.indexOf(aTab); if (i >= 0) - this._recentlyUsedTabs.splice(i, 1); + tabs.splice(i, 1); }, open: function () { + if (window.allTabs) + allTabs.close(); + this._deferOnTabSelect = []; if (this.invertDirection) this._useTabBarOrder = true; + this._tabBarHandlesCtrlPageUpDown = gBrowser.mTabBox.handleCtrlPageUpDown; + gBrowser.mTabBox.handleCtrlPageUpDown = false; + document.addEventListener("keyup", this, false); document.addEventListener("keydown", this, false); this.panel.addEventListener("popuphiding", this, false); this.panel.hidden = false; - this.panel.width = tabPreviews.width * this.visibleCount; + this.panel.width = screen.availWidth * .9; this.panel.openPopupAtScreen(screen.availLeft + (screen.availWidth - this.panel.width) / 2, - screen.availTop + (screen.availHeight - this.svgRoot.getAttribute("height")) / 2, + screen.availTop + screen.availHeight * .1, false); - - // display $visibleCount tabs, starting with the first or - // the second to the last tab, depending on whether Shift is pressed - { - let tabs = this.getTabList(); - let index = this.invertDirection ? tabs.length - 2 : 0; - for (let i = this.visibleCount; i > 0; i--) - this.addPreview(this.addBox(), tabs[index++ % tabs.length]); - } - - // regardless of visibleCount, highlight the second-visible tab - this.selected = this.container.childNodes[1]; - this.arrangeBoxes(); + this.buildPagesBar(); + this.selectedIndex = 0; + this.page = 0; + this.advanceSelected(); }, onKeyPress: function (event) { var isOpen = this.isOpen; @@ -489,22 +374,74 @@ var ctrlTab = { propagate = false; this.invertDirection = event.shiftKey; if (isOpen) - this.scroll(); + this.advanceSelected(); else if (this.tabCount == 2) - gBrowser.selectedTab = this.getTabList()[1]; + gBrowser.selectedTab = this.tabList[1]; else if (this.tabCount > 2) this.open(); } break; + case event.DOM_VK_UP: + if (isOpen) { + let index = this.selectedIndex - this.columns; + if (index < 0) { + this.goToPage(this.page - 1, this.thumbnails.length + index); + } else { + this.selected.removeAttribute("selected"); + this.selectedIndex = index; + this.updateSelected(); + } + } + break; + case event.DOM_VK_DOWN: + if (isOpen) { + let index = this.selectedIndex + this.columns; + if (index >= this.thumbnails.length || !this.thumbnails[index].hasAttribute("valid")) { + this.goToPage(this.page + 1, this.selectedIndex % this.columns); + } else { + this.selected.removeAttribute("selected"); + this.selectedIndex = index; + while (!this.selected.hasAttribute("valid")) + this.selectedIndex--; + this.updateSelected(); + } + } + break; + case event.DOM_VK_LEFT: + if (isOpen) { + this.invertDirection = true; + this.advanceSelected(); + } + break; + case event.DOM_VK_RIGHT: + if (isOpen) { + this.invertDirection = false; + this.advanceSelected(); + } + break; + case event.DOM_VK_HOME: + if (isOpen) + this.goToPage(0); + break; + case event.DOM_VK_END: + if (isOpen) + this.goToPage(this.pages - 1, this.thumbnails.length - 1); + break; + case event.DOM_VK_PAGE_UP: + if (isOpen) + this.goToPage(this.page - 1); + break; + case event.DOM_VK_PAGE_DOWN: + if (isOpen) + this.goToPage(this.page + 1); + break; case event.DOM_VK_ESCAPE: if (isOpen) this.panel.hidePopup(); break; default: - if (isOpen && event.charCode == this.closeCharCode) { - this.stopScroll(); + if (isOpen && event.charCode == this.closeCharCode) gBrowser.removeTab(this.selected._tab); - } } if (!propagate) { event.stopPropagation(); @@ -512,19 +449,23 @@ var ctrlTab = { } }, onPopupHiding: function () { - this.stopScroll(); + gBrowser.mTabBox.handleCtrlPageUpDown = this._tabBarHandlesCtrlPageUpDown; document.removeEventListener("keyup", this, false); document.removeEventListener("keydown", this, false); - while (this.container.childNodes.length) - this.removeBox(this.container.lastChild); - this.selected = null; + + this.selected.removeAttribute("selected"); + if (this.pagesBar.childNodes.length) + this.pagesBar.childNodes[this.page].removeAttribute("selected"); + + Array.forEach(this.thumbnails, function (thumbnail) { + this.updatePreview(thumbnail, null); + }, this); + this.invertDirection = false; this._useTabBarOrder = false; - this._uniqid = 0; this.label.value = ""; - this.setStatusbarValue(); - this.container.removeAttribute("transform"); - this.svgRoot.forceRedraw(); + XULBrowserWindow.setOverLink("", null); + this._page = null; this._deferOnTabSelect.forEach(this.onTabSelect, this); this._deferOnTabSelect = null; @@ -535,6 +476,20 @@ var ctrlTab = { this.attachTab(aTab, 0); } }, + removeClosingTabFromUI: function (aTab) { + this._closing = aTab; + if (this.tabCount == 1) { + this.panel.hidePopup(); + } else { + this.buildPagesBar(); + this.updatePreviews(); + if (!this.selected.hasAttribute("valid")) + this.advanceSelected(); + else + this.updateSelected(); + } + this._closing = null; + }, handleEvent: function (event) { switch (event.type) { case "DOMAttrModified": @@ -551,23 +506,9 @@ var ctrlTab = { this.attachTab(event.target, 1); break; case "TabClose": - if (this.isOpen) { - if (this.tabCount == 2) { - // we have two tabs, one is being closed, so the panel isn't needed anymore - this.panel.hidePopup(); - } else { - if (event.target == this.selected._tab) - this.advanceSelected(); - this.detachTab(event.target); - Array.slice(this.container.childNodes).forEach(function (box) { - if (box._tab == event.target) { - this.removeBox(box); - this.arrangeBoxes(); - } - }, this); - } - } this.detachTab(event.target); + if (this.isOpen) + this.removeClosingTabFromUI(event.target); break; case "keypress": this.onKeyPress(event); @@ -578,7 +519,7 @@ var ctrlTab = { event.stopPropagation(); event.preventDefault(); if (event.type == "keyup" && event.keyCode == event.DOM_VK_CONTROL) - this.pick(); + this.selectThumbnail(); break; case "popuphiding": this.onPopupHiding(); diff --git a/browser/base/content/browser.css b/browser/base/content/browser.css index f303548fe67b..adcc43bc29ee 100644 --- a/browser/base/content/browser.css +++ b/browser/base/content/browser.css @@ -1,6 +1,5 @@ @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); -@namespace svg url("http://www.w3.org/2000/svg"); -@namespace xlink url("http://www.w3.org/1999/xlink"); +@namespace html url("http://www.w3.org/1999/xhtml"); searchbar { -moz-binding: url("chrome://browser/content/search/search.xml#searchbar"); @@ -99,15 +98,6 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m } /* Tab Previews */ -svg|*.ctrlTab-icon:not([xlink|href]) , -svg|*.ctrlTab-thumbnail:not([xlink|href]) { - display: none; -} - -svg|*.ctrlTab-thumbnailborder { - fill: transparent; -} - -svg|*.ctrlTab-icon { - filter: url(chrome://browser/content/browser.xul#ctrlTab-iconShadow); +.ctrlTab-thumbnail:not([valid]) { + visibility: hidden; } diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul index 9cbd47a5dc30..35458313d681 100644 --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -240,25 +240,22 @@ #endif >