michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: %tabBrowserDTD; michael@0: ]> michael@0: michael@0: # MAKE_E10S_WORK surrounds code needed to have the front-end try to be smart michael@0: # about using non-remote browsers for loading certain URIs when remote tabs michael@0: # (browser.tabs.remote) are enabled. michael@0: #define MAKE_E10S_WORK 1 michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: document.getElementById(this.getAttribute("tabcontainer")); michael@0: michael@0: michael@0: this.tabContainer.childNodes; michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: ({ ALL: 0, OTHER: 1, TO_END: 2 }); michael@0: michael@0: null michael@0: michael@0: michael@0: Components.classes["@mozilla.org/docshell/urifixup;1"] michael@0: .getService(Components.interfaces.nsIURIFixup); michael@0: michael@0: michael@0: Components.classes["@mozilla.org/browser/favicon-service;1"] michael@0: .getService(Components.interfaces.nsIFaviconService); michael@0: michael@0: michael@0: Components.classes["@mozilla.org/autocomplete/search;1?name=history"] michael@0: .getService(Components.interfaces.mozIPlacesAutoComplete); michael@0: michael@0: michael@0: Components.classes["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"] michael@0: .getService(Components.interfaces.mozIPlacesAutoComplete); michael@0: michael@0: michael@0: document.getAnonymousElementByAttribute(this, "anonid", "tabbox"); michael@0: michael@0: michael@0: document.getAnonymousElementByAttribute(this, "anonid", "panelcontainer"); michael@0: michael@0: michael@0: document.getAnonymousElementByAttribute(this, "anonid", "tbstringbundle"); michael@0: michael@0: michael@0: null michael@0: michael@0: michael@0: null michael@0: michael@0: michael@0: null michael@0: michael@0: michael@0: [] michael@0: michael@0: michael@0: [] michael@0: michael@0: michael@0: [] michael@0: michael@0: michael@0: [] michael@0: michael@0: michael@0: false michael@0: michael@0: michael@0: #ifdef XP_MACOSX michael@0: true michael@0: #else michael@0: false michael@0: #endif michael@0: michael@0: michael@0: michael@0: null michael@0: michael@0: michael@0: michael@0: false michael@0: michael@0: michael@0: michael@0: "" michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: real JS array michael@0: let prompts = Array.slice(els); michael@0: return prompts; michael@0: }, michael@0: }; michael@0: michael@0: return promptBox; michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: 0 && aStatus == NS_ERROR_UNKNOWN_HOST) { michael@0: // to prevent bug 235825: wait for the request handled michael@0: // by the automatic keyword resolver michael@0: return; michael@0: } michael@0: // since we (try to) only handle STATE_STOP of the last request, michael@0: // the count of open requests should now be 0 michael@0: this.mRequestCount = 0; michael@0: } michael@0: michael@0: if (aStateFlags & nsIWebProgressListener.STATE_START && michael@0: aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) { michael@0: // It's okay to clear what the user typed when we start michael@0: // loading a document. If the user types, this counter gets michael@0: // set to zero, if the document load ends without an michael@0: // onLocationChange, this counter gets decremented michael@0: // (so we keep it while switching tabs after failed loads) michael@0: // We need to add 2 because loadURIWithFlags may have michael@0: // cancelled a pending load which would have cleared michael@0: // its anchor scroll detection temporary increment. michael@0: if (aWebProgress.isTopLevel) michael@0: this.mBrowser.userTypedClear += 2; michael@0: michael@0: if (this._shouldShowProgress(aRequest)) { michael@0: if (!(aStateFlags & nsIWebProgressListener.STATE_RESTORING)) { michael@0: this.mTab.setAttribute("busy", "true"); michael@0: if (!(aWebProgress.loadType & Ci.nsIDocShell.LOAD_CMD_RELOAD)) michael@0: this.mTabBrowser.setTabTitleLoading(this.mTab); michael@0: } michael@0: michael@0: if (this.mTab.selected) michael@0: this.mTabBrowser.mIsBusy = true; michael@0: } michael@0: } michael@0: else if (aStateFlags & nsIWebProgressListener.STATE_STOP && michael@0: aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) { michael@0: michael@0: if (this.mTab.hasAttribute("busy")) { michael@0: this.mTab.removeAttribute("busy"); michael@0: this.mTabBrowser._tabAttrModified(this.mTab); michael@0: if (!this.mTab.selected) michael@0: this.mTab.setAttribute("unread", "true"); michael@0: } michael@0: this.mTab.removeAttribute("progress"); michael@0: michael@0: if (aWebProgress.isTopLevel) { michael@0: if (!Components.isSuccessCode(aStatus) && michael@0: !isTabEmpty(this.mTab)) { michael@0: // Restore the current document's location in case the michael@0: // request was stopped (possibly from a content script) michael@0: // before the location changed. michael@0: michael@0: this.mBrowser.userTypedValue = null; michael@0: michael@0: if (this.mTab.selected && gURLBar) michael@0: URLBarSetURI(); michael@0: } else { michael@0: // The document is done loading, we no longer want the michael@0: // value cleared. michael@0: michael@0: if (this.mBrowser.userTypedClear > 1) michael@0: this.mBrowser.userTypedClear -= 2; michael@0: else if (this.mBrowser.userTypedClear > 0) michael@0: this.mBrowser.userTypedClear--; michael@0: } michael@0: michael@0: if (!this.mBrowser.mIconURL) michael@0: this.mTabBrowser.useDefaultIcon(this.mTab); michael@0: } michael@0: michael@0: if (this.mBlank) michael@0: this.mBlank = false; michael@0: michael@0: var location = aRequest.QueryInterface(nsIChannel).URI; michael@0: michael@0: // For keyword URIs clear the user typed value since they will be changed into real URIs michael@0: if (location.scheme == "keyword") michael@0: this.mBrowser.userTypedValue = null; michael@0: michael@0: if (this.mTab.label == this.mTabBrowser.mStringBundle.getString("tabs.connecting")) michael@0: this.mTabBrowser.setTabTitle(this.mTab); michael@0: michael@0: if (this.mTab.selected) michael@0: this.mTabBrowser.mIsBusy = false; michael@0: } michael@0: michael@0: if (oldBlank) { michael@0: this._callProgressListeners("onUpdateCurrentBrowser", michael@0: [aStateFlags, aStatus, "", 0], michael@0: true, false); michael@0: } else { michael@0: this._callProgressListeners("onStateChange", michael@0: [aWebProgress, aRequest, aStateFlags, aStatus], michael@0: true, false); michael@0: } michael@0: michael@0: this._callProgressListeners("onStateChange", michael@0: [aWebProgress, aRequest, aStateFlags, aStatus], michael@0: false); michael@0: michael@0: if (aStateFlags & (nsIWebProgressListener.STATE_START | michael@0: nsIWebProgressListener.STATE_STOP)) { michael@0: // reset cached temporary values at beginning and end michael@0: this.mMessage = ""; michael@0: this.mTotalProgress = 0; michael@0: } michael@0: this.mStateFlags = aStateFlags; michael@0: this.mStatus = aStatus; michael@0: }, michael@0: michael@0: onLocationChange: function (aWebProgress, aRequest, aLocation, michael@0: aFlags) { michael@0: // OnLocationChange is called for both the top-level content michael@0: // and the subframes. michael@0: let topLevel = aWebProgress.isTopLevel; michael@0: michael@0: if (topLevel) { michael@0: // If userTypedClear > 0, the document loaded correctly and we should be michael@0: // clearing the user typed value. We also need to clear the typed value michael@0: // if the document failed to load, to make sure the urlbar reflects the michael@0: // failed URI (particularly for SSL errors). However, don't clear the value michael@0: // if the error page's URI is about:blank, because that causes complete michael@0: // loss of urlbar contents for invalid URI errors (see bug 867957). michael@0: if (this.mBrowser.userTypedClear > 0 || michael@0: ((aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) && michael@0: aLocation.spec != "about:blank")) michael@0: this.mBrowser.userTypedValue = null; michael@0: michael@0: // Clear out the missing plugins list since it's related to the michael@0: // previous location. michael@0: this.mBrowser.missingPlugins = null; michael@0: michael@0: if (this.mTabBrowser.isFindBarInitialized(this.mTab)) { michael@0: let findBar = this.mTabBrowser.getFindBar(this.mTab); michael@0: michael@0: // Close the Find toolbar if we're in old-style TAF mode michael@0: if (findBar.findMode != findBar.FIND_NORMAL) michael@0: findBar.close(); michael@0: michael@0: // fix bug 253793 - turn off highlight when page changes michael@0: findBar.getElement("highlight").checked = false; michael@0: } michael@0: michael@0: // Don't clear the favicon if this onLocationChange was michael@0: // triggered by a pushState or a replaceState. See bug 550565. michael@0: if (aWebProgress.isLoadingDocument && michael@0: !(aWebProgress.loadType & Ci.nsIDocShell.LOAD_CMD_PUSHSTATE)) { michael@0: this.mBrowser.mIconURL = null; michael@0: } michael@0: michael@0: let autocomplete = this.mTabBrowser._placesAutocomplete; michael@0: let unifiedComplete = this.mTabBrowser._unifiedComplete; michael@0: if (this.mBrowser.registeredOpenURI) { michael@0: autocomplete.unregisterOpenPage(this.mBrowser.registeredOpenURI); michael@0: unifiedComplete.unregisterOpenPage(this.mBrowser.registeredOpenURI); michael@0: delete this.mBrowser.registeredOpenURI; michael@0: } michael@0: // Tabs in private windows aren't registered as "Open" so michael@0: // that they don't appear as switch-to-tab candidates. michael@0: if (!isBlankPageURL(aLocation.spec) && michael@0: (!PrivateBrowsingUtils.isWindowPrivate(window) || michael@0: PrivateBrowsingUtils.permanentPrivateBrowsing)) { michael@0: autocomplete.registerOpenPage(aLocation); michael@0: unifiedComplete.registerOpenPage(aLocation); michael@0: this.mBrowser.registeredOpenURI = aLocation; michael@0: } michael@0: } michael@0: michael@0: if (!this.mBlank) { michael@0: this._callProgressListeners("onLocationChange", michael@0: [aWebProgress, aRequest, aLocation, michael@0: aFlags]); michael@0: } michael@0: michael@0: if (topLevel) { michael@0: this.mBrowser.lastURI = aLocation; michael@0: this.mBrowser.lastLocationChange = Date.now(); michael@0: } michael@0: }, michael@0: michael@0: onStatusChange: function (aWebProgress, aRequest, aStatus, aMessage) { michael@0: if (this.mBlank) michael@0: return; michael@0: michael@0: this._callProgressListeners("onStatusChange", michael@0: [aWebProgress, aRequest, aStatus, aMessage]); michael@0: michael@0: this.mMessage = aMessage; michael@0: }, michael@0: michael@0: onSecurityChange: function (aWebProgress, aRequest, aState) { michael@0: this._callProgressListeners("onSecurityChange", michael@0: [aWebProgress, aRequest, aState]); michael@0: }, michael@0: michael@0: onRefreshAttempted: function (aWebProgress, aURI, aDelay, aSameURI) { michael@0: return this._callProgressListeners("onRefreshAttempted", michael@0: [aWebProgress, aURI, aDelay, aSameURI]); michael@0: }, michael@0: michael@0: QueryInterface: function (aIID) { michael@0: if (aIID.equals(Components.interfaces.nsIWebProgressListener) || michael@0: aIID.equals(Components.interfaces.nsIWebProgressListener2) || michael@0: aIID.equals(Components.interfaces.nsISupportsWeakReference) || michael@0: aIID.equals(Components.interfaces.nsISupports)) michael@0: return this; michael@0: throw Components.results.NS_NOINTERFACE; michael@0: } michael@0: }); michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: 1 false/true NO michael@0: var multiple = aURIs.length > 1; michael@0: var owner = multiple || aLoadInBackground ? null : this.selectedTab; michael@0: var firstTabAdded = null; michael@0: michael@0: if (aReplace) { michael@0: try { michael@0: this.loadURI(aURIs[0], null, null); michael@0: } catch (e) { michael@0: // Ignore failure in case a URI is wrong, so we can continue michael@0: // opening the next ones. michael@0: } michael@0: } michael@0: else michael@0: firstTabAdded = this.addTab(aURIs[0], {ownerTab: owner, skipAnimation: multiple}); michael@0: michael@0: var tabNum = this.tabContainer.selectedIndex; michael@0: for (let i = 1; i < aURIs.length; ++i) { michael@0: let tab = this.addTab(aURIs[i], {skipAnimation: true}); michael@0: if (aReplace) michael@0: this.moveTabTo(tab, ++tabNum); michael@0: } michael@0: michael@0: if (!aLoadInBackground) { michael@0: if (firstTabAdded) { michael@0: // .selectedTab setter focuses the content area michael@0: this.selectedTab = firstTabAdded; michael@0: } michael@0: else michael@0: this.selectedBrowser.focus(); michael@0: } michael@0: ]]> michael@0: michael@0: michael@0: #ifdef MAKE_E10S_WORK michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: #endif michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: = 0; --i) { michael@0: tabsToEnd.push(tabs[i]); michael@0: } michael@0: return tabsToEnd.reverse(); michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: = 0; --i) { michael@0: this.removeTab(tabs[i], {animate: true}); michael@0: } michael@0: } michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: = 0; --i) { michael@0: if (tabs[i] != aTab && !tabs[i].pinned) michael@0: this.removeTab(tabs[i], {animate: true}); michael@0: } michael@0: } michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: [] michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: 3 /* don't want lots of concurrent animations */ || michael@0: aTab.getAttribute("fadein") != "true" /* fade-in transition hasn't been triggered yet */ || michael@0: window.getComputedStyle(aTab).maxWidth == "0.1px" /* fade-in transition hasn't moved yet */ || michael@0: !Services.prefs.getBoolPref("browser.tabs.animate")) { michael@0: this._endRemoveTab(aTab); michael@0: return; michael@0: } michael@0: michael@0: this.tabContainer._handleTabTelemetryStart(aTab); michael@0: michael@0: this._blurTab(aTab); michael@0: aTab.style.maxWidth = ""; // ensure that fade-out transition happens michael@0: aTab.removeAttribute("fadein"); michael@0: michael@0: setTimeout(function (tab, tabbrowser) { michael@0: if (tab.parentNode && michael@0: window.getComputedStyle(tab).maxWidth == "0.1px") { michael@0: NS_ASSERT(false, "Giving up waiting for the tab closing animation to finish (bug 608589)"); michael@0: tabbrowser._endRemoveTab(tab); michael@0: } michael@0: }, 3000, aTab, this); michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: false michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: this.mTabsProgressListeners.push(aListener); michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: = 0 && aIndex < tabs.length) michael@0: this.selectedTab = tabs[aIndex]; michael@0: michael@0: if (aEvent) { michael@0: aEvent.preventDefault(); michael@0: aEvent.stopPropagation(); michael@0: } michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: return this.mCurrentTab; michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: null michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: 0) michael@0: this.moveTabTo(this.mCurrentTab, 0); michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: Application.console.log("enterTabbedMode is an obsolete method and " + michael@0: "will be removed in a future release."); michael@0: michael@0: michael@0: true michael@0: michael@0: michael@0: michael@0: this.tabContainer.visible = aShow; michael@0: michael@0: michael@0: michael@0: michael@0: return this.tabContainer.visible; michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: null michael@0: null michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: # This is a hack to circumvent bug 472020, otherwise the tabs show up on the michael@0: # right of the newtab button. michael@0: michael@0: # This is to ensure anything extensions put here will go before the newtab michael@0: # button, necessary due to the previous hack. michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: document.getElementById(this.getAttribute("tabbrowser")); michael@0: michael@0: michael@0: michael@0: this.tabbrowser.mTabBox; michael@0: michael@0: michael@0: michael@0: document.getElementById("tabContextMenu"); michael@0: michael@0: michael@0: 0 michael@0: michael@0: michael@0: document.getAnonymousElementByAttribute(this, "anonid", "arrowscrollbox"); michael@0: michael@0: michael@0: null michael@0: null michael@0: null michael@0: null michael@0: null michael@0: null michael@0: michael@0: michael@0: michael@0: let root = document.documentElement; michael@0: return root.getAttribute("customizing") == "true" || michael@0: root.getAttribute("customize-exiting") == "true"; michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: false michael@0: michael@0: michael@0: document.getAnonymousElementByAttribute(this, "anonid", "tab-drop-indicator"); michael@0: michael@0: michael@0: 350 michael@0: 0 michael@0: michael@0: michael@0: michael@0: false michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: 2) { michael@0: // This is an optimization to avoid layout flushes by calling michael@0: // getBoundingClientRect() when we just opened a second tab. In michael@0: // this case it's highly unlikely that the tab width is smaller michael@0: // than mTabClipWidth and the tab close button obscures too much michael@0: // of the tab's label. In the edge case of the window being too michael@0: // narrow (or if tabClipWidth has been set to a way higher value), michael@0: // we'll correct the 'closebuttons' attribute after the tabopen michael@0: // animation has finished. michael@0: michael@0: let tab = this.tabbrowser.visibleTabs[this.tabbrowser._numPinnedTabs]; michael@0: if (tab && tab.getBoundingClientRect().width <= this.mTabClipWidth) { michael@0: this.setAttribute("closebuttons", "activetab"); michael@0: return; michael@0: } michael@0: } michael@0: this.removeAttribute("closebuttons"); michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: tabStrip.scrollSize) michael@0: tabStrip.scrollByPixels(-1); michael@0: } catch (e) {} michael@0: ]]> michael@0: michael@0: michael@0: michael@0: document.getAnonymousElementByAttribute(this, "anonid", "closing-tabs-spacer"); michael@0: michael@0: michael@0: NaN michael@0: false michael@0: false michael@0: michael@0: michael@0: michael@0: michael@0: tabs[tabs.length-1]._tPos); michael@0: var tabWidth = aTab.getBoundingClientRect().width; michael@0: michael@0: if (!this._tabDefaultMaxWidth) michael@0: this._tabDefaultMaxWidth = michael@0: parseFloat(window.getComputedStyle(aTab).maxWidth); michael@0: this._lastTabClosedByMouse = true; michael@0: michael@0: if (this.getAttribute("overflow") == "true") { michael@0: // Don't need to do anything if we're in overflow mode and aren't scrolled michael@0: // all the way to the right, or if we're closing the last tab. michael@0: if (isEndTab || !this.mTabstrip._scrollButtonDown.disabled) michael@0: return; michael@0: michael@0: // If the tab has an owner that will become the active tab, the owner will michael@0: // be to the left of it, so we actually want the left tab to slide over. michael@0: // This can't be done as easily in non-overflow mode, so we don't bother. michael@0: if (aTab.owner) michael@0: return; michael@0: michael@0: this._expandSpacerBy(tabWidth); michael@0: } else { // non-overflow mode michael@0: // Locking is neither in effect nor needed, so let tabs expand normally. michael@0: if (isEndTab && !this._hasTabTempMaxWidth) michael@0: return; michael@0: michael@0: let numPinned = this.tabbrowser._numPinnedTabs; michael@0: // Force tabs to stay the same width, unless we're closing the last tab, michael@0: // which case we need to let them expand just enough so that the overall michael@0: // tabbar width is the same. michael@0: if (isEndTab) { michael@0: let numNormalTabs = tabs.length - numPinned; michael@0: tabWidth = tabWidth * (numNormalTabs + 1) / numNormalTabs; michael@0: if (tabWidth > this._tabDefaultMaxWidth) michael@0: tabWidth = this._tabDefaultMaxWidth; michael@0: } michael@0: tabWidth += "px"; michael@0: for (let i = numPinned; i < tabs.length; i++) { michael@0: let tab = tabs[i]; michael@0: tab.style.setProperty("max-width", tabWidth, "important"); michael@0: if (!isEndTab) { // keep tabs the same width michael@0: tab.style.transition = "none"; michael@0: tab.clientTop; // flush styles to skip animation; see bug 649247 michael@0: tab.style.transition = ""; michael@0: } michael@0: } michael@0: this._hasTabTempMaxWidth = true; michael@0: this.tabbrowser.addEventListener("mousemove", this, false); michael@0: window.addEventListener("mouseout", this, false); michael@0: } michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: 0 michael@0: michael@0: 0; michael@0: michael@0: if (doPosition) { michael@0: this.setAttribute("positionpinnedtabs", "true"); michael@0: michael@0: let scrollButtonWidth = this.mTabstrip._scrollButtonDown.getBoundingClientRect().width; michael@0: let paddingStart = this.mTabstrip.scrollboxPaddingStart; michael@0: let width = 0; michael@0: michael@0: for (let i = numPinned - 1; i >= 0; i--) { michael@0: let tab = this.childNodes[i]; michael@0: width += tab.getBoundingClientRect().width; michael@0: tab.style.MozMarginStart = - (width + scrollButtonWidth + paddingStart) + "px"; michael@0: } michael@0: michael@0: this.style.MozPaddingStart = width + paddingStart + "px"; michael@0: michael@0: } else { michael@0: this.removeAttribute("positionpinnedtabs"); michael@0: michael@0: for (let i = 0; i < numPinned; i++) { michael@0: let tab = this.childNodes[i]; michael@0: tab.style.MozMarginStart = ""; michael@0: } michael@0: michael@0: this.style.MozPaddingStart = ""; michael@0: } michael@0: michael@0: if (this._lastNumPinned != numPinned) { michael@0: this._lastNumPinned = numPinned; michael@0: this._handleTabSelect(false); michael@0: } michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: draggedTab._dragData.animLastScreenX; michael@0: draggedTab._dragData.animLastScreenX = screenX; michael@0: michael@0: let rtl = (window.getComputedStyle(this).direction == "rtl"); michael@0: let pinned = draggedTab.pinned; michael@0: let numPinned = this.tabbrowser._numPinnedTabs; michael@0: let tabs = this.tabbrowser.visibleTabs michael@0: .slice(pinned ? 0 : numPinned, michael@0: pinned ? numPinned : undefined); michael@0: if (rtl) michael@0: tabs.reverse(); michael@0: let tabWidth = draggedTab.getBoundingClientRect().width; michael@0: michael@0: // Move the dragged tab based on the mouse position. michael@0: michael@0: let leftTab = tabs[0]; michael@0: let rightTab = tabs[tabs.length - 1]; michael@0: let tabScreenX = draggedTab.boxObject.screenX; michael@0: let translateX = screenX - draggedTab._dragData.screenX; michael@0: if (!pinned) michael@0: translateX += this.mTabstrip.scrollPosition - draggedTab._dragData.scrollX; michael@0: let leftBound = leftTab.boxObject.screenX - tabScreenX; michael@0: let rightBound = (rightTab.boxObject.screenX + rightTab.boxObject.width) - michael@0: (tabScreenX + tabWidth); michael@0: translateX = Math.max(translateX, leftBound); michael@0: translateX = Math.min(translateX, rightBound); michael@0: draggedTab.style.transform = "translateX(" + translateX + "px)"; michael@0: michael@0: // Determine what tab we're dragging over. michael@0: // * Point of reference is the center of the dragged tab. If that michael@0: // point touches a background tab, the dragged tab would take that michael@0: // tab's position when dropped. michael@0: // * We're doing a binary search in order to reduce the amount of michael@0: // tabs we need to check. michael@0: michael@0: let tabCenter = tabScreenX + translateX + tabWidth / 2; michael@0: let newIndex = -1; michael@0: let oldIndex = "animDropIndex" in draggedTab._dragData ? michael@0: draggedTab._dragData.animDropIndex : draggedTab._tPos; michael@0: let low = 0; michael@0: let high = tabs.length - 1; michael@0: while (low <= high) { michael@0: let mid = Math.floor((low + high) / 2); michael@0: if (tabs[mid] == draggedTab && michael@0: ++mid > high) michael@0: break; michael@0: let boxObject = tabs[mid].boxObject; michael@0: let screenX = boxObject.screenX + getTabShift(tabs[mid], oldIndex); michael@0: if (screenX > tabCenter) { michael@0: high = mid - 1; michael@0: } else if (screenX + boxObject.width < tabCenter) { michael@0: low = mid + 1; michael@0: } else { michael@0: newIndex = tabs[mid]._tPos; michael@0: break; michael@0: } michael@0: } michael@0: if (newIndex >= oldIndex) michael@0: newIndex++; michael@0: if (newIndex < 0 || newIndex == oldIndex) michael@0: return; michael@0: draggedTab._dragData.animDropIndex = newIndex; michael@0: michael@0: // Shift background tabs to leave a gap where the dragged tab michael@0: // would currently be dropped. michael@0: michael@0: for (let tab of tabs) { michael@0: if (tab != draggedTab) { michael@0: let shift = getTabShift(tab, newIndex); michael@0: tab.style.transform = shift ? "translateX(" + shift + "px)" : ""; michael@0: } michael@0: } michael@0: michael@0: function getTabShift(tab, dropIndex) { michael@0: if (tab._tPos < draggedTab._tPos && tab._tPos >= dropIndex) michael@0: return rtl ? -tabWidth : tabWidth; michael@0: if (tab._tPos > draggedTab._tPos && tab._tPos < dropIndex) michael@0: return rtl ? tabWidth : -tabWidth; michael@0: return 0; michael@0: } michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: 1) { michael@0: var width = this.mTabstrip.boxObject.width; michael@0: if (width != this.mTabstripWidth) { michael@0: this.adjustTabstrip(); michael@0: this._fillTrailingGap(); michael@0: this._handleTabSelect(); michael@0: this.mTabstripWidth = width; michael@0: } michael@0: } michael@0: michael@0: this.tabbrowser.updateWindowResizers(); michael@0: break; michael@0: case "mouseout": michael@0: // If the "related target" (the node to which the pointer went) is not michael@0: // a child of the current document, the mouse just left the window. michael@0: let relatedTarget = aEvent.relatedTarget; michael@0: if (relatedTarget && relatedTarget.ownerDocument == document) michael@0: break; michael@0: case "mousemove": michael@0: if (document.getElementById("tabContextMenu").state != "open") michael@0: this._unlockTabSizing(); michael@0: break; michael@0: } michael@0: ]]> michael@0: michael@0: michael@0: michael@0: this.mTabstrip._scrollButtonDown; michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: boxObject.screenX + boxObject.width * .75) michael@0: return null; michael@0: } michael@0: return tab; michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2) michael@0: return i; michael@0: } michael@0: return tabs.length; michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: 1) michael@0: return dt.effectAllowed = "none"; michael@0: michael@0: var types = dt.mozTypesAt(0); michael@0: var sourceNode = null; michael@0: // tabs are always added as the first type michael@0: if (types[0] == TAB_DROP_TYPE) { michael@0: var sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0); michael@0: if (sourceNode instanceof XULElement && michael@0: sourceNode.localName == "tab" && michael@0: sourceNode.ownerDocument.defaultView instanceof ChromeWindow && michael@0: sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser" && michael@0: sourceNode.ownerDocument.defaultView.gBrowser.tabContainer == sourceNode.parentNode) { michael@0: // Do not allow transfering a private tab to a non-private window michael@0: // and vice versa. michael@0: if (PrivateBrowsingUtils.isWindowPrivate(window) != michael@0: PrivateBrowsingUtils.isWindowPrivate(sourceNode.ownerDocument.defaultView)) michael@0: return dt.effectAllowed = "none"; michael@0: michael@0: if (window.gMultiProcessBrowser != michael@0: sourceNode.ownerDocument.defaultView.gMultiProcessBrowser) michael@0: return dt.effectAllowed = "none"; michael@0: michael@0: #ifdef XP_MACOSX michael@0: return dt.effectAllowed = event.altKey ? "copy" : "move"; michael@0: #else michael@0: return dt.effectAllowed = event.ctrlKey ? "copy" : "move"; michael@0: #endif michael@0: } michael@0: } michael@0: michael@0: if (browserDragAndDrop.canDropLink(event)) { michael@0: // Here we need to do this manually michael@0: return dt.effectAllowed = dt.dropEffect = "link"; michael@0: } michael@0: return dt.effectAllowed = "none"; michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: 1) { michael@0: let averageInterval = 0; michael@0: for (let i = 1; i < frameCount; i++) { michael@0: averageInterval += intervals[i]; michael@0: }; michael@0: averageInterval = averageInterval / (frameCount - 1); michael@0: michael@0: Services.telemetry.getHistogramById("FX_TAB_ANIM_ANY_FRAME_INTERVAL_MS").add(averageInterval); michael@0: michael@0: if (aTab._recordingTabOpenPlain) { michael@0: delete aTab._recordingTabOpenPlain; michael@0: // While we do have a telemetry probe NEWTAB_PAGE_ENABLED to monitor newtab preview, it'll be michael@0: // easier to overview the data without slicing by it. Hence the additional histograms with _PREVIEW. michael@0: let preview = this._browserNewtabpageEnabled ? "_PREVIEW" : ""; michael@0: Services.telemetry.getHistogramById("FX_TAB_ANIM_OPEN" + preview + "_FRAME_INTERVAL_MS").add(averageInterval); michael@0: } michael@0: } michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: 1 && !target._ignoredCloseButtonClicks) { michael@0: target._ignoredCloseButtonClicks = true; michael@0: event.stopPropagation(); michael@0: return; michael@0: } else { michael@0: // Reset the "ignored click" flag michael@0: target._ignoredCloseButtonClicks = false; michael@0: } michael@0: } michael@0: michael@0: /* Protects from close-tab-button errant doubleclick: michael@0: * Since we're removing the event target, if the user michael@0: * double-clicks the button, the dblclick event will be dispatched michael@0: * with the tabbar as its event target (and explicit/originalTarget), michael@0: * which treats that as a mouse gesture for opening a new tab. michael@0: * In this context, we're manually blocking the dblclick event michael@0: * (see tabbrowser-close-tab-button dblclick handler). michael@0: */ michael@0: if (this._blockDblClick) { michael@0: if (!("_clickedTabBarOnce" in this)) { michael@0: this._clickedTabBarOnce = true; michael@0: return; michael@0: } michael@0: delete this._clickedTabBarOnce; michael@0: this._blockDblClick = false; michael@0: } michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: = this._dragTime + this._dragOverDelay) michael@0: this.selectedItem = tab; michael@0: ind.collapsed = true; michael@0: return; michael@0: } michael@0: } michael@0: michael@0: var rect = tabStrip.getBoundingClientRect(); michael@0: var newMargin; michael@0: if (pixelsToScroll) { michael@0: // if we are scrolling, put the drop indicator at the edge michael@0: // so that it doesn't jump while scrolling michael@0: let scrollRect = tabStrip.scrollClientRect; michael@0: let minMargin = scrollRect.left - rect.left; michael@0: let maxMargin = Math.min(minMargin + scrollRect.width, michael@0: scrollRect.right); michael@0: if (!ltr) michael@0: [minMargin, maxMargin] = [this.clientWidth - maxMargin, michael@0: this.clientWidth - minMargin]; michael@0: newMargin = (pixelsToScroll > 0) ? maxMargin : minMargin; michael@0: } michael@0: else { michael@0: let newIndex = this._getDropIndex(event); michael@0: if (newIndex == this.childNodes.length) { michael@0: let tabRect = this.childNodes[newIndex-1].getBoundingClientRect(); michael@0: if (ltr) michael@0: newMargin = tabRect.right - rect.left; michael@0: else michael@0: newMargin = rect.right - tabRect.left; michael@0: } michael@0: else { michael@0: let tabRect = this.childNodes[newIndex].getBoundingClientRect(); michael@0: if (ltr) michael@0: newMargin = tabRect.left - rect.left; michael@0: else michael@0: newMargin = rect.right - tabRect.right; michael@0: } michael@0: } michael@0: michael@0: ind.collapsed = false; michael@0: michael@0: newMargin += ind.clientWidth / 2; michael@0: if (!ltr) michael@0: newMargin *= -1; michael@0: michael@0: ind.style.transform = "translate(" + Math.round(newMargin) + "px)"; michael@0: ind.style.MozMarginStart = (-ind.clientWidth) + "px"; michael@0: ]]> michael@0: michael@0: draggedTab._tPos) michael@0: newIndex--; michael@0: this.tabbrowser.moveTabTo(draggedTab, newIndex); michael@0: } michael@0: } else if (draggedTab) { michael@0: // swap the dropped tab with a new one we create and then close michael@0: // it in the other window (making it seem to have moved between michael@0: // windows) michael@0: let newIndex = this._getDropIndex(event); michael@0: let newTab = this.tabbrowser.addTab("about:blank"); michael@0: let newBrowser = this.tabbrowser.getBrowserForTab(newTab); michael@0: // Stop the about:blank load michael@0: newBrowser.stop(); michael@0: // make sure it has a docshell michael@0: newBrowser.docShell; michael@0: michael@0: let numPinned = this.tabbrowser._numPinnedTabs; michael@0: if (newIndex < numPinned || draggedTab.pinned && newIndex == numPinned) michael@0: this.tabbrowser.pinTab(newTab); michael@0: this.tabbrowser.moveTabTo(newTab, newIndex); michael@0: michael@0: // We need to select the tab before calling swapBrowsersAndCloseOther michael@0: // so that window.content in chrome windows points to the right tab michael@0: // when pagehide/show events are fired. michael@0: this.tabbrowser.selectedTab = newTab; michael@0: michael@0: draggedTab.parentNode._finishAnimateTabMove(); michael@0: this.tabbrowser.swapBrowsersAndCloseOther(newTab, draggedTab); michael@0: michael@0: // Call updateCurrentBrowser to make sure the URL bar is up to date michael@0: // for our new tab after we've done swapBrowsersAndCloseOther. michael@0: this.tabbrowser.updateCurrentBrowser(true); michael@0: } else { michael@0: // Pass true to disallow dropping javascript: or data: urls michael@0: let url; michael@0: try { michael@0: url = browserDragAndDrop.drop(event, { }, true); michael@0: } catch (ex) {} michael@0: michael@0: if (!url) michael@0: return; michael@0: michael@0: let bgLoad = Services.prefs.getBoolPref("browser.tabs.loadInBackground"); michael@0: michael@0: if (event.shiftKey) michael@0: bgLoad = !bgLoad; michael@0: michael@0: let tab = this._getDragTargetTab(event); michael@0: if (!tab || dropEffect == "copy") { michael@0: // We're adding a new tab. michael@0: let newIndex = this._getDropIndex(event); michael@0: let newTab = this.tabbrowser.loadOneTab(url, {inBackground: bgLoad, allowThirdPartyFixup: true}); michael@0: this.tabbrowser.moveTabTo(newTab, newIndex); michael@0: } else { michael@0: // Load in an existing tab. michael@0: try { michael@0: let webNav = Ci.nsIWebNavigation; michael@0: let flags = webNav.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP | michael@0: webNav.LOAD_FLAGS_FIXUP_SCHEME_TYPOS; michael@0: this.tabbrowser.getBrowserForTab(tab).loadURIWithFlags(url, flags); michael@0: if (!bgLoad) michael@0: this.selectedItem = tab; michael@0: } catch(ex) { michael@0: // Just ignore invalid urls michael@0: } michael@0: } michael@0: } michael@0: michael@0: if (draggedTab) { michael@0: delete draggedTab._dragData; michael@0: } michael@0: ]]> michael@0: michael@0: wX && eX < (wX + window.outerWidth)) { michael@0: let bo = this.mTabstrip.boxObject; michael@0: // also avoid detaching if the the tab was dropped too close to michael@0: // the tabbar (half a tab) michael@0: let endScreenY = bo.screenY + 1.5 * bo.height; michael@0: if (eY < endScreenY && eY > window.screenY) michael@0: return; michael@0: } michael@0: michael@0: // screen.availLeft et. al. only check the screen that this window is on, michael@0: // but we want to look at the screen the tab is being dropped onto. michael@0: var sX = {}, sY = {}, sWidth = {}, sHeight = {}; michael@0: Cc["@mozilla.org/gfx/screenmanager;1"] michael@0: .getService(Ci.nsIScreenManager) michael@0: .screenForRect(eX, eY, 1, 1) michael@0: .GetAvailRect(sX, sY, sWidth, sHeight); michael@0: // ensure new window entirely within screen michael@0: var winWidth = Math.min(window.outerWidth, sWidth.value); michael@0: var winHeight = Math.min(window.outerHeight, sHeight.value); michael@0: var left = Math.min(Math.max(eX - draggedTab._dragData.offsetX, sX.value), michael@0: sX.value + sWidth.value - winWidth); michael@0: var top = Math.min(Math.max(eY - draggedTab._dragData.offsetY, sY.value), michael@0: sY.value + sHeight.value - winHeight); michael@0: michael@0: delete draggedTab._dragData; michael@0: michael@0: if (this.tabbrowser.tabs.length == 1) { michael@0: // resize _before_ move to ensure the window fits the new screen. if michael@0: // the window is too large for its screen, the window manager may do michael@0: // automatic repositioning. michael@0: window.resizeTo(winWidth, winHeight); michael@0: window.moveTo(left, top); michael@0: window.focus(); michael@0: } else { michael@0: this.tabbrowser.replaceTabWithWindow(draggedTab, { screenX: left, michael@0: screenY: top, michael@0: #ifndef XP_WIN michael@0: outerWidth: winWidth, michael@0: outerHeight: winHeight michael@0: #endif michael@0: }); michael@0: } michael@0: event.stopPropagation(); michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: // for the one-close-button case michael@0: event.stopPropagation(); michael@0: michael@0: michael@0: michael@0: event.stopPropagation(); michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: return this.getAttribute("label"); michael@0: michael@0: michael@0: this.setAttribute("label", val); michael@0: let event = new CustomEvent("TabLabelModified", { michael@0: bubbles: true, michael@0: cancelable: true michael@0: }); michael@0: this.dispatchEvent(event); michael@0: michael@0: // Let listeners prevent synchronizing the actual label to the michael@0: // visible label (allowing them to override the visible label). michael@0: if (!event.defaultPrevented) michael@0: this.visibleLabel = val; michael@0: michael@0: michael@0: michael@0: michael@0: return this.getAttribute("visibleLabel"); michael@0: michael@0: michael@0: this.setAttribute("visibleLabel", val); michael@0: michael@0: michael@0: michael@0: michael@0: return this.getAttribute("pinned") == "true"; michael@0: michael@0: michael@0: michael@0: michael@0: return this.getAttribute("hidden") == "true"; michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: return this.selected ? Date.now() : this._lastAccessed; michael@0: michael@0: michael@0: this._lastAccessed = val; michael@0: michael@0: michael@0: 0 michael@0: michael@0: false michael@0: null michael@0: false michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: this.style.MozUserFocus = ''; michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: this.style.MozUserFocus = ''; michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: = tabstripBO.screenX && michael@0: curTabBO.screenX + curTabBO.width <= tabstripBO.screenX + tabstripBO.width) michael@0: this.childNodes[i].setAttribute("tabIsVisible", "true"); michael@0: else michael@0: this.childNodes[i].removeAttribute("tabIsVisible"); michael@0: } michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: 0; i--) { michael@0: let menuItem = this.childNodes[i]; michael@0: if (menuItem.tab) { michael@0: menuItem.tab.mCorrespondingMenuitem = null; michael@0: this.removeChild(menuItem); michael@0: } michael@0: } michael@0: var tabcontainer = gBrowser.tabContainer; michael@0: tabcontainer.mTabstrip.removeEventListener("scroll", this, false); michael@0: tabcontainer.removeEventListener("TabAttrModified", this, false); michael@0: tabcontainer.removeEventListener("TabClose", this, false); michael@0: ]]> michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: return this.hasAttribute("inactive") ? "" : this.getAttribute("label"); michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: this._mirror(); michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: this._mirror(); michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: if (this.hasAttribute("mirror")) michael@0: this.removeAttribute("mirror"); michael@0: else michael@0: this.setAttribute("mirror", "true"); michael@0: michael@0: if (!this.hasAttribute("sizelimit")) { michael@0: this.setAttribute("sizelimit", "true"); michael@0: this._calcMouseTargetRect(); michael@0: } michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: