%tabBrowserDTD; %globalDTD; ]> Components.classes['@mozilla.org/preferences-service;1'] .getService(Components.interfaces.nsIPrefService) .getBranch(null); Components.classes["@mozilla.org/docshell/urifixup;1"] .getService(Components.interfaces.nsIURIFixup); Components.classes["@mozilla.org/browser/favicon-service;1"] .getService(Components.interfaces.nsIFaviconService); document.getAnonymousElementByAttribute(this, "anonid", "tabbox"); this.mTabBox.childNodes[0] document.getAnonymousElementByAttribute(this, "anonid", "strip"); document.getAnonymousElementByAttribute(this, "anonid", "tabcontainer"); document.getAnonymousElementByAttribute(this, "anonid", "panelcontainer"); this.mTabContainer.childNodes document.getAnonymousElementByAttribute(this, "anonid", "tbstringbundle"); document.getAnonymousElementByAttribute(this, "anonid", "undoCloseTabMenuItem"); null null [] new Array() new Array() false false null #ifdef XP_MACOSX true #else false #endif false null false null 0 && aStatus == NS_ERROR_UNKNOWN_HOST) { // to prevent bug 235825: wait for the request handled // by the automatic keyword resolver return; } // since we (try to) only handle STATE_STOP of the last request, // the count of open requests should now be 0 this.mRequestCount = 0; } if (aStateFlags & nsIWebProgressListener.STATE_START && aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) { // It's okay to clear what the user typed when we start // loading a document. If the user types, this counter gets // set to zero, if the document load ends without an // onLocationChange, this counter gets decremented // (so we keep it while switching tabs after failed loads) // We need to add 2 because loadURIWithFlags may have // cancelled a pending load which would have cleared // its anchor scroll detection temporary increment. if (aWebProgress.DOMWindow == this.mBrowser.contentWindow) this.mBrowser.userTypedClear += 2; if (!this.mBlank) { this.mTab.setAttribute("busy", "true"); this.mTabBrowser.updateIcon(this.mTab); this.mTabBrowser.setTabTitleLoading(this.mTab); if (this.mTabBrowser.mCurrentTab == this.mTab) this.mTabBrowser.mIsBusy = true; } } else if (aStateFlags & nsIWebProgressListener.STATE_STOP && aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) { if (aWebProgress.DOMWindow == this.mBrowser.contentWindow) { // The document is done loading, we no longer want the // value cleared. if (this.mBrowser.userTypedClear > 1) this.mBrowser.userTypedClear -= 2; else if (this.mBrowser.userTypedClear > 0) this.mBrowser.userTypedClear--; if (!this.mBrowser.mIconURL) this.mTabBrowser.useDefaultIcon(this.mTab); } if (this.mBlank) this.mBlank = false; this.mTab.removeAttribute("busy"); this.mTabBrowser.updateIcon(this.mTab); var location = aRequest.QueryInterface(nsIChannel).URI; // For keyword URIs clear the user typed value since they will be changed into real URIs if (location.scheme == "keyword") this.mBrowser.userTypedValue = null; if (this.mTab.label == this.mTabBrowser.mStringBundle.getString("tabs.loading")) this.mTabBrowser.setTabTitle(this.mTab); if (this.mTabBrowser.mCurrentTab == this.mTab) this.mTabBrowser.mIsBusy = false; } if (this.mTabBrowser.mCurrentTab == this.mTab) { for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) { var p = this.mTabBrowser.mProgressListeners[i]; if (p) try { if (!oldBlank) p.onStateChange(aWebProgress, aRequest, aStateFlags, aStatus); // make sure that the visible status of new blank tabs is correctly set else if ("onUpdateCurrentBrowser" in p) p.onUpdateCurrentBrowser(aStateFlags, aStatus, "", 0); } catch (e) { // don't inhibit other listeners or following code Components.utils.reportError(e); } } } if (aStateFlags & (nsIWebProgressListener.STATE_START | nsIWebProgressListener.STATE_STOP)) { // reset cached temporary values at beginning and end this.mMessage = ""; this.mTotalProgress = 0; } this.mStateFlags = aStateFlags; this.mStatus = aStatus; }, onLocationChange : function(aWebProgress, aRequest, aLocation) { // The document loaded correctly, clear the value if we should if (this.mBrowser.userTypedClear > 0) this.mBrowser.userTypedValue = null; if (aWebProgress.DOMWindow == this.mBrowser.contentWindow && aWebProgress.isLoadingDocument) this.mTabBrowser.setIcon(this.mTab, null); // changing location, clear out the missing plugins list this.mBrowser.missingPlugins = null; if (!this.mBlank && this.mTabBrowser.mCurrentTab == this.mTab) { for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) { var p = this.mTabBrowser.mProgressListeners[i]; if (p) try { p.onLocationChange(aWebProgress, aRequest, aLocation); } catch (e) { // don't inhibit other listeners Components.utils.reportError(e); } } } }, onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage) { if (this.mBlank) return; if (this.mTabBrowser.mCurrentTab == this.mTab) { for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) { var p = this.mTabBrowser.mProgressListeners[i]; if (p) try { p.onStatusChange(aWebProgress, aRequest, aStatus, aMessage); } catch (e) { // don't inhibit other listeners or following code Components.utils.reportError(e); } } } this.mMessage = aMessage; }, onSecurityChange : function(aWebProgress, aRequest, aState) { if (this.mTabBrowser.mCurrentTab == this.mTab) { for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) { var p = this.mTabBrowser.mProgressListeners[i]; if (p) try { p.onSecurityChange(aWebProgress, aRequest, aState); } catch (e) { // don't inhibit other listeners Components.utils.reportError(e); } } } }, onRefreshAttempted : function(aWebProgress, aURI, aDelay, aSameURI) { var allowRefresh = true; for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) { var p = this.mTabBrowser.mProgressListeners[i]; if (p && "onRefreshAttempted" in p) { try { if (!p.onRefreshAttempted(aWebProgress, aURI, aDelay, aSameURI)) allowRefresh = false; } catch (e) { // don't inhibit other listeners or following code Components.utils.reportError(e); } } } return allowRefresh; }, QueryInterface : function(aIID) { if (aIID.equals(Components.interfaces.nsIWebProgressListener) || aIID.equals(Components.interfaces.nsIWebProgressListener2) || aIID.equals(Components.interfaces.nsISupportsWeakReference) || aIID.equals(Components.interfaces.nsISupports)) return this; throw Components.results.NS_NOINTERFACE; } }); ]]> sz || req.image.height > sz) return; this.setIcon(aTab, browser.currentURI.spec); } catch (e) { } } } else if (this.shouldLoadFavIcon(browser.currentURI)) { var url = browser.currentURI.prePath + "/favicon.ico"; if (!this.isFailedIcon(url)) this.setIcon(aTab, url); } ]]> return !this.mStrip.collapsed; 0) { // Use the filter hooked up in our addProgressListener filter = this.mTabFilters[0]; } else { // create a filter and hook it up to our first browser filter = Components.classes["@mozilla.org/appshell/component/browser-status-filter;1"] .createInstance(Components.interfaces.nsIWebProgress); this.mTabFilters[0] = filter; this.mCurrentBrowser.webProgress.addProgressListener(filter, Components.interfaces.nsIWebProgress.NOTIFY_ALL); } // Remove all our progress listeners from the active browser's filter. for (var i = 0; i < this.mProgressListeners.length; i++) { var p = this.mProgressListeners[i]; if (p) filter.removeProgressListener(p); } // Wire up a progress listener to our filter. const listener = this.mTabProgressListener(this.mCurrentTab, this.mCurrentBrowser, false); filter.addProgressListener(listener, Components.interfaces.nsIWebProgress.NOTIFY_ALL); this.mTabListeners[0] = listener; ]]> 1 false/true NO var owner = (aURIs.length > 1) || aLoadInBackground ? null : this.selectedTab; var firstTabAdded = null; if (aReplace) this.loadURI(aURIs[0], null, null); else firstTabAdded = this.addTab(aURIs[0], null, null, null, owner, false); var tabNum = this.mTabContainer.selectedIndex; for (let i = 1; i < aURIs.length; ++i) { let tab = this.addTab(aURIs[i]); if (aReplace) this.moveTabTo(tab, ++tabNum); } if (!aLoadInBackground) { if (firstTabAdded) { // .selectedTab setter focuses the content area this.selectedTab = firstTabAdded; } else window.content.focus(); } ]]> = 0; --i) { if (childNodes[i] != aTab) this.removeTab(childNodes[i]); } } ]]> = scrolledSize.value) { tabStrip.scrollByPixels(-1 * this.mTabContainer.firstChild .boxObject.width); } } catch (ex) { } // Find the tab to select var newIndex = -1; if (currentIndex > index) newIndex = currentIndex-1; else if (currentIndex < index) newIndex = currentIndex; else { if ("owner" in oldTab && oldTab.owner && this.mPrefs.getBoolPref("browser.tabs.selectOwnerOnClose")) { for (i = 0; i < this.mTabContainer.childNodes.length; ++i) { tab = this.mTabContainer.childNodes[i]; if (tab == oldTab.owner) { newIndex = i; break; } } } if (newIndex == -1) newIndex = (index == l - 1) ? index - 1 : index; } // Select the new tab this.selectedTab = this.mTabContainer.childNodes[newIndex]; for (i = oldTab._tPos; i < this.mTabContainer.childNodes.length; i++) { this.mTabContainer.childNodes[i]._tPos = i; } this.mTabBox.selectedPanel = this.getBrowserForTab(this.mCurrentTab).parentNode; this.mCurrentTab._selected = true; this.updateCurrentBrowser(); // see comment above destroy above oldBrowser.focusedWindow = null; oldBrowser.focusedElement = null; ]]> return this.mTabContainer; return this.mTabBox.selectedTab; ' + aEvent.target.label + ''); } else { aXferData.data.addDataForFlavour("text/unicode", "about:blank"); } } ]]> = aDragSession.sourceNode.boxObject.screenX && aEvent.screenX <= (aDragSession.sourceNode.boxObject.screenX + aDragSession.sourceNode.boxObject.width))) return false; return true; ]]> 0 350 = this.mDragTime + this.mDragOverDelay) this.mTabContainer.selectedItem = aEvent.target; return; } var newIndex = this.getNewIndex(aEvent); var ib = this.mTabDropIndicatorBar; var ind = ib.firstChild; var tabStripBoxObject = tabStrip.scrollBoxObject; var minMargin = tabStripBoxObject.x - this.boxObject.x; // make sure we don't place the tab drop indicator past the // edge, or the containing box will flex and stretch // the tab drop indicator bar, which will flex the url bar. // XXX todo // just use first value if you can figure out how to get // the tab drop indicator to crop instead of flex and stretch // the tab drop indicator bar. var maxMargin = Math.min(minMargin + tabStripBoxObject.width, ib.boxObject.x + ib.boxObject.width - ind.boxObject.width); if (!ltr) [minMargin, maxMargin] = [this.boxObject.width - maxMargin, this.boxObject.width - minMargin]; var newMargin, tabBoxObject; if (pixelsToScroll) { // if we are scrolling, put the drop indicator at the edge // so that it doesn't jump while scrolling newMargin = (pixelsToScroll > 0) ? maxMargin : minMargin; } else { if (newIndex == this.mTabs.length) { tabBoxObject = this.mTabs[newIndex-1].boxObject; if (ltr) newMargin = tabBoxObject.screenX - this.boxObject.screenX + tabBoxObject.width; else newMargin = this.boxObject.screenX - tabBoxObject.screenX + this.boxObject.width; } else { tabBoxObject = this.mTabs[newIndex].boxObject; if (ltr) newMargin = tabBoxObject.screenX - this.boxObject.screenX; else newMargin = this.boxObject.screenX - tabBoxObject.screenX + this.boxObject.width - tabBoxObject.width; } // ensure we never place the drop indicator beyond our limits if (newMargin < minMargin) newMargin = minMargin; else if (newMargin > maxMargin) newMargin = maxMargin; } ind.style.MozMarginStart = newMargin + 'px'; ib.collapsed = !aDragSession.canDrop; ]]> draggedTab._tPos) newIndex--; if (newIndex != draggedTab._tPos) this.moveTabTo(draggedTab, newIndex); } } else if (draggedTab) { // copy the dropped tab and remove it from the other window // (making it seem to have moved between windows) newIndex = this.getNewIndex(aEvent); newTab = this.duplicateTab(draggedTab); this.moveTabTo(newTab, newIndex); this.selectedTab = newTab; var remoteBrowser = draggedTab.ownerDocument.defaultView.getBrowser(); var tabCount = remoteBrowser.tabContainer.childNodes.length; remoteBrowser.removeTab(draggedTab); // close the other window if this was its last tab if (tabCount == 1) draggedTab.ownerDocument.defaultView.close(); } else { var url = transferUtils.retrieveURLFromData(aXferData.data, aXferData.flavour.contentType); // valid urls don't contain spaces ' '; if we have a space it isn't a valid url. // Also disallow dropping javascript: or data: urls--bail out if (!url || !url.length || url.indexOf(" ", 0) != -1 || /^\s*(javascript|data):/.test(url)) return; nsDragAndDrop.dragDropSecurityCheck(aEvent, aDragSession, url); var bgLoad = true; try { bgLoad = this.mPrefs.getBoolPref("browser.tabs.loadInBackground"); } catch (e) { } if (aEvent.shiftKey) bgLoad = !bgLoad; if (document.getBindingParent(aEvent.originalTarget).localName != "tab" || accelKeyPressed) { // We're adding a new tab. newIndex = this.getNewIndex(aEvent); newTab = this.loadOneTab(getShortcutOrURI(url), null, null, null, bgLoad, false); this.moveTabTo(newTab, newIndex); } else { // Load in an existing tab. var tab = aEvent.target; try { this.getBrowserForTab(tab).loadURI(getShortcutOrURI(url)); if (this.mCurrentTab != tab && !bgLoad) this.selectedTab = tab; } catch(ex) { // Just ignore invalid urls } } } ]]> this.mTabs[i].boxObject.screenX + this.mTabs[i].boxObject.width / 2) return i; } return this.mTabs.length; ]]> 0) { this.moveTabTo(this.mCurrentTab, tabPos - 1); this.mCurrentTab.focus(); } else if (this.arrowKeysShouldWrap) this.moveTabToEnd(); ]]> 0) { this.moveTabTo(this.mCurrentTab, 0); this.mCurrentTab.focus(); } ]]> null #ifdef XP_MACOSX document.getAnonymousElementByAttribute(this, "anonid", "down-box"); document.getAnonymousElementByAttribute(this, "anonid", "down-box-animate"); #endif #ifdef XP_MACOSX #endif #ifdef XP_MACOSX #endif #ifdef XP_MACOSX #endif 0 document.getAnonymousElementByAttribute(this, "anonid", "arrowscrollbox"); #ifdef XP_MACOSX document.getAnonymousElementByAttribute(this, "anonid", "tabstrip-closebutton"); #else document.getAnonymousElementByAttribute(this, "anonid", "tabs-closebutton"); #endif ({ tabbox: this, observe: function(subject, topic, data) { if (topic == "nsPref:changed") { switch (data) { case "browser.tabs.closeButtons": subject.QueryInterface(Components.interfaces.nsIPrefBranch); this.tabbox.mCloseButtons = subject.getIntPref("browser.tabs.closeButtons"); this.tabbox.adjustTabstrip(); break; } } }, QueryInterface: function(aIID) { if (aIID.equals(Components.interfaces.nsIObserver) || aIID.equals(Components.interfaces.nsISupports)) return this; throw Components.results.NS_NOINTERFACE; } }); 100 250 140 1 this.mTabClipWidth || width == 0) this.setAttribute("closebuttons", "alltabs"); else this.setAttribute("closebuttons", "activetab"); break; case 2: case 3: this.setAttribute("closebuttons", "noclose"); break; } this.mTabstripClosebutton.collapsed = this.mCloseButtons != 3; ]]> null document.getAnonymousElementByAttribute(this, "anonid", "alltabs-popup"); document.getAnonymousElementByAttribute(this, "anonid", "alltabs-box-animate"); #ifdef XP_MACOSX this.mTabstrip._scrollButtonDownBoxAnimate; #endif document.getAnonymousElementByAttribute(this, "anonid", "alltabs-button"); null -1 25 [1.00, 0.85, 0.80, 0.75, 0.71, 0.68, 0.65, 0.62, 0.59, 0.57, 0.54, 0.52, 0.50, 0.47, 0.45, 0.44, 0.42, 0.40, 0.38, 0.37, 0.35, 0.34, 0.32, 0.31, 0.30, 0.29, 0.28, 0.27, 0.26, 0.25, 0.24, 0.23, 0.23, 0.22, 0.22, 0.21, 0.21, 0.21, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.19, 0.19, 0.19, 0.18, 0.18, 0.17, 0.17, 0.16, 0.15, 0.14, 0.13, 0.11, 0.09, 0.06] null = tabstripBO.screenX && curTabBO.screenX + curTabBO.width <= tabstripBO.screenX + tabstripBO.width) this.childNodes[i].setAttribute("tabIsVisible", "true"); else this.childNodes[i].removeAttribute("tabIsVisible"); } ]]> 1 && !this._ignoredClick) { this._ignoredClick = true; return; } // Reset the "ignored click" flag this._ignoredClick = false; tabbedBrowser.removeTab(bindingParent); tabbedBrowser._blockDblClick = true; /* XXXmano hack (see bug 343628): * Since we're removing the event target, if the user * double-clicks this button, the dblclick event will be dispatched * with the tabbar as its event target (and explicit/originalTarget), * which treats that as a mouse gesture for opening a new tab. * In this context, we're manually blocking the dblclick event * (see onTabBarDblClick). */ var clickedOnce = false; function enableDblClick(event) { if (event.detail == 1 && !clickedOnce) { clickedOnce = true; return; } setTimeout(function() { tabbedBrowser._blockDblClick = false; }, 0); tabbedBrowser.removeEventListener("click", enableDblClick, false); } tabbedBrowser.addEventListener("click", enableDblClick, false); } else // "tabs" tabbedBrowser.removeCurrentTab(); } ]]> // for the one-close-button case event.stopPropagation(); #ifdef XP_MACOSX #else #endif false null var anonid = event.originalTarget.getAttribute("anonid"); if (anonid == "close-button") this.mOverCloseButton = true; var anonid = event.originalTarget.getAttribute("anonid"); if (anonid == "close-button") this.mOverCloseButton = false;