forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			612 lines
		
	
	
	
		
			24 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			612 lines
		
	
	
	
		
			24 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| # -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 | |
| # This Source Code Form is subject to the terms of the Mozilla Public
 | |
| # License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
| # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | |
| 
 | |
| var FullScreen = {
 | |
|   _XULNS: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
 | |
|   toggle: function (event) {
 | |
|     var enterFS = window.fullScreen;
 | |
| 
 | |
|     // We get the fullscreen event _before_ the window transitions into or out of FS mode.
 | |
|     if (event && event.type == "fullscreen")
 | |
|       enterFS = !enterFS;
 | |
| 
 | |
|     // Toggle the View:FullScreen command, which controls elements like the
 | |
|     // fullscreen menuitem, menubars, and the appmenu.
 | |
|     document.getElementById("View:FullScreen").setAttribute("checked", enterFS);
 | |
| 
 | |
| #ifdef XP_MACOSX
 | |
|     // Make sure the menu items are adjusted.
 | |
|     document.getElementById("enterFullScreenItem").hidden = enterFS;
 | |
|     document.getElementById("exitFullScreenItem").hidden = !enterFS;
 | |
| #endif
 | |
| 
 | |
|     // On OS X Lion we don't want to hide toolbars when entering fullscreen, unless
 | |
|     // we're entering DOM fullscreen, in which case we should hide the toolbars.
 | |
|     // If we're leaving fullscreen, then we'll go through the exit code below to
 | |
|     // make sure toolbars are made visible in the case of DOM fullscreen.
 | |
|     if (enterFS && this.useLionFullScreen) {
 | |
|       if (document.mozFullScreen) {
 | |
|         this.showXULChrome("toolbar", false);
 | |
|       }
 | |
|       else {
 | |
|         gNavToolbox.setAttribute("inFullscreen", true);
 | |
|         document.documentElement.setAttribute("inFullscreen", true);
 | |
|       }
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     // show/hide menubars, toolbars (except the full screen toolbar)
 | |
|     this.showXULChrome("toolbar", !enterFS);
 | |
| 
 | |
|     if (enterFS) {
 | |
|       // Add a tiny toolbar to receive mouseover and dragenter events, and provide affordance.
 | |
|       // This will help simulate the "collapse" metaphor while also requiring less code and
 | |
|       // events than raw listening of mouse coords. We don't add the toolbar in DOM full-screen
 | |
|       // mode, only browser full-screen mode.
 | |
|       if (!document.mozFullScreen) {
 | |
|         let fullScrToggler = document.getElementById("fullscr-toggler");
 | |
|         if (!fullScrToggler) {
 | |
|           fullScrToggler = document.createElement("hbox");
 | |
|           fullScrToggler.id = "fullscr-toggler";
 | |
|           fullScrToggler.collapsed = true;
 | |
|           gNavToolbox.parentNode.insertBefore(fullScrToggler, gNavToolbox.nextSibling);
 | |
|         }
 | |
|         fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
 | |
|         fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
 | |
|       }
 | |
|       if (gPrefService.getBoolPref("browser.fullscreen.autohide"))
 | |
|         gBrowser.mPanelContainer.addEventListener("mousemove",
 | |
|                                                   this._collapseCallback, false);
 | |
| 
 | |
|       document.addEventListener("keypress", this._keyToggleCallback, false);
 | |
|       document.addEventListener("popupshown", this._setPopupOpen, false);
 | |
|       document.addEventListener("popuphidden", this._setPopupOpen, false);
 | |
|       // We don't animate the toolbar collapse if in DOM full-screen mode,
 | |
|       // as the size of the content area would still be changing after the
 | |
|       // mozfullscreenchange event fired, which could confuse content script.
 | |
|       this._shouldAnimate = !document.mozFullScreen;
 | |
|       this.mouseoverToggle(false);
 | |
| 
 | |
|       // Autohide prefs
 | |
|       gPrefService.addObserver("browser.fullscreen", this, false);
 | |
|     }
 | |
|     else {
 | |
|       // The user may quit fullscreen during an animation
 | |
|       this._cancelAnimation();
 | |
|       gNavToolbox.style.marginTop = "";
 | |
|       if (this._isChromeCollapsed)
 | |
|         this.mouseoverToggle(true);
 | |
|       // This is needed if they use the context menu to quit fullscreen
 | |
|       this._isPopupOpen = false;
 | |
| 
 | |
|       this.cleanup();
 | |
|     }
 | |
|   },
 | |
| 
 | |
|   exitDomFullScreen : function() {
 | |
|     document.mozCancelFullScreen();
 | |
|   },
 | |
| 
 | |
|   handleEvent: function (event) {
 | |
|     switch (event.type) {
 | |
|       case "deactivate":
 | |
|         // We must call exitDomFullScreen asynchronously, since "deactivate" is
 | |
|         // dispatched in the middle of the focus manager's window lowering code,
 | |
|         // and the focus manager gets confused if we exit fullscreen mode in the
 | |
|         // middle of window lowering. See bug 729872.
 | |
|         setTimeout(this.exitDomFullScreen.bind(this), 0);
 | |
|         break;
 | |
|       case "transitionend":
 | |
|         if (event.propertyName == "opacity")
 | |
|           this.cancelWarning();
 | |
|         break;
 | |
|     }
 | |
|   },
 | |
| 
 | |
|   enterDomFullscreen : function(event) {
 | |
|     if (!document.mozFullScreen)
 | |
|       return;
 | |
| 
 | |
|     // However, if we receive a "MozEnteredDomFullScreen" event for a document
 | |
|     // which is not a subdocument of the currently selected tab, we know that
 | |
|     // we've switched tabs since the request to enter full-screen was made,
 | |
|     // so we should exit full-screen since the "full-screen document" isn't
 | |
|     // acutally visible.
 | |
|     if (event.target.defaultView.top != gBrowser.contentWindow) {
 | |
|       document.mozCancelFullScreen();
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     let focusManager = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
 | |
|     if (focusManager.activeWindow != window) {
 | |
|       // The top-level window has lost focus since the request to enter
 | |
|       // full-screen was made. Cancel full-screen.
 | |
|       document.mozCancelFullScreen();
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     // Ensure the sidebar is hidden.
 | |
|     if (!document.getElementById("sidebar-box").hidden)
 | |
|       toggleSidebar();
 | |
| 
 | |
|     if (gFindBarInitialized)
 | |
|       gFindBar.close();
 | |
| 
 | |
|     this.showWarning(event.target);
 | |
| 
 | |
|     // Exit DOM full-screen mode upon open, close, or change tab.
 | |
|     gBrowser.tabContainer.addEventListener("TabOpen", this.exitDomFullScreen);
 | |
|     gBrowser.tabContainer.addEventListener("TabClose", this.exitDomFullScreen);
 | |
|     gBrowser.tabContainer.addEventListener("TabSelect", this.exitDomFullScreen);
 | |
| 
 | |
|     // Exit DOM full-screen mode when the browser window loses focus (ALT+TAB, etc).
 | |
|     if (!this.useLionFullScreen &&
 | |
|         gPrefService.getBoolPref("full-screen-api.exit-on-deactivate")) {
 | |
|       window.addEventListener("deactivate", this);
 | |
|     }
 | |
| 
 | |
|     // Cancel any "hide the toolbar" animation which is in progress, and make
 | |
|     // the toolbar hide immediately.
 | |
|     this._cancelAnimation();
 | |
|     this.mouseoverToggle(false);
 | |
| 
 | |
|     // If there's a full-screen toggler, remove its listeners, so that mouseover
 | |
|     // the top of the screen will not cause the toolbar to re-appear.
 | |
|     let fullScrToggler = document.getElementById("fullscr-toggler");
 | |
|     if (fullScrToggler) {
 | |
|       fullScrToggler.removeEventListener("mouseover", this._expandCallback, false);
 | |
|       fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
 | |
|     }
 | |
|   },
 | |
| 
 | |
|   cleanup: function () {
 | |
|     if (window.fullScreen) {
 | |
|       gBrowser.mPanelContainer.removeEventListener("mousemove",
 | |
|                                                    this._collapseCallback, false);
 | |
|       document.removeEventListener("keypress", this._keyToggleCallback, false);
 | |
|       document.removeEventListener("popupshown", this._setPopupOpen, false);
 | |
|       document.removeEventListener("popuphidden", this._setPopupOpen, false);
 | |
|       gPrefService.removeObserver("browser.fullscreen", this);
 | |
| 
 | |
|       let fullScrToggler = document.getElementById("fullscr-toggler");
 | |
|       if (fullScrToggler) {
 | |
|         fullScrToggler.removeEventListener("mouseover", this._expandCallback, false);
 | |
|         fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
 | |
|       }
 | |
|       this.cancelWarning();
 | |
|       gBrowser.tabContainer.removeEventListener("TabOpen", this.exitDomFullScreen);
 | |
|       gBrowser.tabContainer.removeEventListener("TabClose", this.exitDomFullScreen);
 | |
|       gBrowser.tabContainer.removeEventListener("TabSelect", this.exitDomFullScreen);
 | |
|       if (!this.useLionFullScreen)
 | |
|         window.removeEventListener("deactivate", this);
 | |
|     }
 | |
|   },
 | |
| 
 | |
|   observe: function(aSubject, aTopic, aData)
 | |
|   {
 | |
|     if (aData == "browser.fullscreen.autohide") {
 | |
|       if (gPrefService.getBoolPref("browser.fullscreen.autohide")) {
 | |
|         gBrowser.mPanelContainer.addEventListener("mousemove",
 | |
|                                                   this._collapseCallback, false);
 | |
|       }
 | |
|       else {
 | |
|         gBrowser.mPanelContainer.removeEventListener("mousemove",
 | |
|                                                      this._collapseCallback, false);
 | |
|       }
 | |
|     }
 | |
|   },
 | |
| 
 | |
|   // Event callbacks
 | |
|   _expandCallback: function()
 | |
|   {
 | |
|     FullScreen.mouseoverToggle(true);
 | |
|   },
 | |
|   _collapseCallback: function()
 | |
|   {
 | |
|     FullScreen.mouseoverToggle(false);
 | |
|   },
 | |
|   _keyToggleCallback: function(aEvent)
 | |
|   {
 | |
|     // if we can use the keyboard (eg Ctrl+L or Ctrl+E) to open the toolbars, we
 | |
|     // should provide a way to collapse them too.
 | |
|     if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
 | |
|       FullScreen._shouldAnimate = false;
 | |
|       FullScreen.mouseoverToggle(false, true);
 | |
|     }
 | |
|     // F6 is another shortcut to the address bar, but its not covered in OpenLocation()
 | |
|     else if (aEvent.keyCode == aEvent.DOM_VK_F6)
 | |
|       FullScreen.mouseoverToggle(true);
 | |
|   },
 | |
| 
 | |
|   // Checks whether we are allowed to collapse the chrome
 | |
|   _isPopupOpen: false,
 | |
|   _isChromeCollapsed: false,
 | |
|   _safeToCollapse: function(forceHide)
 | |
|   {
 | |
|     if (!gPrefService.getBoolPref("browser.fullscreen.autohide"))
 | |
|       return false;
 | |
| 
 | |
|     // a popup menu is open in chrome: don't collapse chrome
 | |
|     if (!forceHide && this._isPopupOpen)
 | |
|       return false;
 | |
| 
 | |
|     // a textbox in chrome is focused (location bar anyone?): don't collapse chrome
 | |
|     if (document.commandDispatcher.focusedElement &&
 | |
|         document.commandDispatcher.focusedElement.ownerDocument == document &&
 | |
|         document.commandDispatcher.focusedElement.localName == "input") {
 | |
|       if (forceHide)
 | |
|         // hidden textboxes that still have focus are bad bad bad
 | |
|         document.commandDispatcher.focusedElement.blur();
 | |
|       else
 | |
|         return false;
 | |
|     }
 | |
|     return true;
 | |
|   },
 | |
| 
 | |
|   _setPopupOpen: function(aEvent)
 | |
|   {
 | |
|     // Popups should only veto chrome collapsing if they were opened when the chrome was not collapsed.
 | |
|     // Otherwise, they would not affect chrome and the user would expect the chrome to go away.
 | |
|     // e.g. we wouldn't want the autoscroll icon firing this event, so when the user
 | |
|     // toggles chrome when moving mouse to the top, it doesn't go away again.
 | |
|     if (aEvent.type == "popupshown" && !FullScreen._isChromeCollapsed &&
 | |
|         aEvent.target.localName != "tooltip" && aEvent.target.localName != "window")
 | |
|       FullScreen._isPopupOpen = true;
 | |
|     else if (aEvent.type == "popuphidden" && aEvent.target.localName != "tooltip" &&
 | |
|              aEvent.target.localName != "window")
 | |
|       FullScreen._isPopupOpen = false;
 | |
|   },
 | |
| 
 | |
|   // Autohide helpers for the context menu item
 | |
|   getAutohide: function(aItem)
 | |
|   {
 | |
|     aItem.setAttribute("checked", gPrefService.getBoolPref("browser.fullscreen.autohide"));
 | |
|   },
 | |
|   setAutohide: function()
 | |
|   {
 | |
|     gPrefService.setBoolPref("browser.fullscreen.autohide", !gPrefService.getBoolPref("browser.fullscreen.autohide"));
 | |
|   },
 | |
| 
 | |
|   // Animate the toolbars disappearing
 | |
|   _shouldAnimate: true,
 | |
|   _isAnimating: false,
 | |
|   _animationTimeout: 0,
 | |
|   _animationHandle: 0,
 | |
|   _animateUp: function() {
 | |
|     // check again, the user may have done something before the animation was due to start
 | |
|     if (!window.fullScreen || !this._safeToCollapse(false)) {
 | |
|       this._isAnimating = false;
 | |
|       this._shouldAnimate = true;
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     this._animateStartTime = window.mozAnimationStartTime;
 | |
|     if (!this._animationHandle)
 | |
|       this._animationHandle = window.mozRequestAnimationFrame(this);
 | |
|   },
 | |
| 
 | |
|   sample: function (timeStamp) {
 | |
|     const duration = 1500;
 | |
|     const timePassed = timeStamp - this._animateStartTime;
 | |
|     const pos = timePassed >= duration ? 1 :
 | |
|                 1 - Math.pow(1 - timePassed / duration, 4);
 | |
| 
 | |
|     if (pos >= 1) {
 | |
|       // We've animated enough
 | |
|       this._cancelAnimation();
 | |
|       gNavToolbox.style.marginTop = "";
 | |
|       this.mouseoverToggle(false);
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     gNavToolbox.style.marginTop = (gNavToolbox.boxObject.height * pos * -1) + "px";
 | |
|     this._animationHandle = window.mozRequestAnimationFrame(this);
 | |
|   },
 | |
| 
 | |
|   _cancelAnimation: function() {
 | |
|     window.mozCancelAnimationFrame(this._animationHandle);
 | |
|     this._animationHandle = 0;
 | |
|     clearTimeout(this._animationTimeout);
 | |
|     this._isAnimating = false;
 | |
|     this._shouldAnimate = false;
 | |
|   },
 | |
| 
 | |
|   cancelWarning: function(event) {
 | |
|     if (!this.warningBox)
 | |
|       return;
 | |
|     this.fullscreenDoc = null;
 | |
|     this.warningBox.removeEventListener("transitionend", this);
 | |
|     if (this.warningFadeOutTimeout) {
 | |
|       clearTimeout(this.warningFadeOutTimeout);
 | |
|       this.warningFadeOutTimeout = null;
 | |
|     }
 | |
| 
 | |
|     // Ensure focus switches away from the (now hidden) warning box. If the user
 | |
|     // clicked buttons in the fullscreen key authorization UI, it would have been
 | |
|     // focused, and any key events would be directed at the (now hidden) chrome
 | |
|     // document instead of the target document.
 | |
|     gBrowser.selectedBrowser.focus();
 | |
| 
 | |
|     this.warningBox.setAttribute("hidden", true);
 | |
|     this.warningBox.removeAttribute("fade-warning-out");
 | |
|     this.warningBox.removeAttribute("obscure-browser");
 | |
|     this.warningBox = null;
 | |
|   },
 | |
| 
 | |
|   setFullscreenAllowed: function(isApproved) {
 | |
|     // The "remember decision" checkbox is hidden when showing for documents that
 | |
|     // the permission manager can't handle (documents with URIs without a host).
 | |
|     // We simply require those to be approved every time instead.
 | |
|     let rememberCheckbox = document.getElementById("full-screen-remember-decision");
 | |
|     let uri = this.fullscreenDoc.nodePrincipal.URI;
 | |
|     if (!rememberCheckbox.hidden) {
 | |
|       if (rememberCheckbox.checked)
 | |
|         Services.perms.add(uri,
 | |
|                            "fullscreen",
 | |
|                            isApproved ? Services.perms.ALLOW_ACTION : Services.perms.DENY_ACTION,
 | |
|                            Services.perms.EXPIRE_NEVER);
 | |
|       else if (isApproved) {
 | |
|         // The user has only temporarily approved fullscren for this fullscreen
 | |
|         // session only. Add the permission (so Gecko knows to approve any further
 | |
|         // fullscreen requests for this host in this fullscreen session) but add
 | |
|         // a listener to revoke the permission when the chrome document exits
 | |
|         // fullscreen.
 | |
|         Services.perms.add(uri,
 | |
|                            "fullscreen",
 | |
|                            Services.perms.ALLOW_ACTION,
 | |
|                            Services.perms.EXPIRE_SESSION);
 | |
|         let host = uri.host;
 | |
|         function onFullscreenchange(event) {
 | |
|           if (event.target == document && document.mozFullScreenElement == null) {
 | |
|             // The chrome document has left fullscreen. Remove the temporary permission grant.
 | |
|             Services.perms.remove(host, "fullscreen");
 | |
|             document.removeEventListener("mozfullscreenchange", onFullscreenchange);
 | |
|           }
 | |
|         }
 | |
|         document.addEventListener("mozfullscreenchange", onFullscreenchange);
 | |
|       }
 | |
|     }
 | |
|     if (this.warningBox)
 | |
|       this.warningBox.setAttribute("fade-warning-out", "true");
 | |
|     // If the document has been granted fullscreen, notify Gecko so it can resume
 | |
|     // any pending pointer lock requests, otherwise exit fullscreen; the user denied
 | |
|     // the fullscreen request.
 | |
|     if (isApproved)
 | |
|       Services.obs.notifyObservers(this.fullscreenDoc, "fullscreen-approved", "");
 | |
|     else
 | |
|       document.mozCancelFullScreen();
 | |
|   },
 | |
| 
 | |
|   warningBox: null,
 | |
|   warningFadeOutTimeout: null,
 | |
|   fullscreenDoc: null,
 | |
| 
 | |
|   // Shows the fullscreen approval UI, or if the domain has already been approved
 | |
|   // for fullscreen, shows a warning that the site has entered fullscreen for a short
 | |
|   // duration.
 | |
|   showWarning: function(targetDoc) {
 | |
|     if (!document.mozFullScreen ||
 | |
|         !gPrefService.getBoolPref("full-screen-api.approval-required"))
 | |
|       return;
 | |
| 
 | |
|     // Set the strings on the fullscreen approval UI.
 | |
|     this.fullscreenDoc = targetDoc;
 | |
|     let uri = this.fullscreenDoc.nodePrincipal.URI;
 | |
|     let host = null;
 | |
|     try {
 | |
|       host = uri.host;
 | |
|     } catch (e) { }
 | |
|     let hostLabel = document.getElementById("full-screen-domain-text");
 | |
|     let rememberCheckbox = document.getElementById("full-screen-remember-decision");
 | |
|     let isApproved = false;
 | |
|     if (host) {
 | |
|       // Document's principal's URI has a host. Display a warning including the hostname and
 | |
|       // show UI to enable the user to permanently grant this host permission to enter fullscreen.
 | |
|       let utils = {};
 | |
|       Cu.import("resource://gre/modules/DownloadUtils.jsm", utils);
 | |
|       let displayHost = utils.DownloadUtils.getURIHost(uri.spec)[0];
 | |
|       let bundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
 | |
| 
 | |
|       hostLabel.textContent = bundle.formatStringFromName("fullscreen.entered", [displayHost], 1);
 | |
|       hostLabel.removeAttribute("hidden");
 | |
| 
 | |
|       rememberCheckbox.label = bundle.formatStringFromName("fullscreen.rememberDecision", [displayHost], 1);
 | |
|       rememberCheckbox.checked = false;
 | |
|       rememberCheckbox.removeAttribute("hidden");
 | |
| 
 | |
|       // Note we only allow documents whose principal's URI has a host to
 | |
|       // store permission grants.
 | |
|       isApproved = Services.perms.testPermission(uri, "fullscreen") == Services.perms.ALLOW_ACTION;
 | |
|     } else {
 | |
|       hostLabel.setAttribute("hidden", "true");
 | |
|       rememberCheckbox.setAttribute("hidden", "true");
 | |
|     }
 | |
| 
 | |
|     // Note: the warning box can be non-null if the warning box from the previous request
 | |
|     // wasn't hidden before another request was made.
 | |
|     if (!this.warningBox) {
 | |
|       this.warningBox = document.getElementById("full-screen-warning-container");
 | |
|       // Add a listener to clean up state after the warning is hidden.
 | |
|       this.warningBox.addEventListener("transitionend", this);
 | |
|       this.warningBox.removeAttribute("hidden");
 | |
|     } else {
 | |
|       if (this.warningFadeOutTimeout) {
 | |
|         clearTimeout(this.warningFadeOutTimeout);
 | |
|         this.warningFadeOutTimeout = null;
 | |
|       }
 | |
|       this.warningBox.removeAttribute("fade-warning-out");
 | |
|     }
 | |
| 
 | |
|     // If fullscreen mode has not yet been approved for the fullscreen
 | |
|     // document's domain, show the approval UI and don't auto fade out the
 | |
|     // fullscreen warning box. Otherwise, we're just notifying of entry into
 | |
|     // fullscreen mode. Note if the resource's host is null, we must be
 | |
|     // showing a local file or a local data URI, and we require explicit
 | |
|     // approval every time.
 | |
|     let authUI = document.getElementById("full-screen-approval-pane");
 | |
|     if (isApproved) {
 | |
|       authUI.setAttribute("hidden", "true");
 | |
|       this.warningBox.removeAttribute("obscure-browser");
 | |
|     } else {
 | |
|       // Partially obscure the <browser> element underneath the approval UI.
 | |
|       this.warningBox.setAttribute("obscure-browser", "true");
 | |
|       authUI.removeAttribute("hidden");
 | |
|     }
 | |
| 
 | |
|     // If we're not showing the fullscreen approval UI, we're just notifying the user
 | |
|     // of the transition, so set a timeout to fade the warning out after a few moments.
 | |
|     if (isApproved)
 | |
|       this.warningFadeOutTimeout =
 | |
|         setTimeout(
 | |
|           function() {
 | |
|             if (this.warningBox)
 | |
|               this.warningBox.setAttribute("fade-warning-out", "true");
 | |
|           }.bind(this),
 | |
|           3000);
 | |
|   },
 | |
| 
 | |
|   mouseoverToggle: function(aShow, forceHide)
 | |
|   {
 | |
|     // Don't do anything if:
 | |
|     // a) we're already in the state we want,
 | |
|     // b) we're animating and will become collapsed soon, or
 | |
|     // c) we can't collapse because it would be undesirable right now
 | |
|     if (aShow != this._isChromeCollapsed || (!aShow && this._isAnimating) ||
 | |
|         (!aShow && !this._safeToCollapse(forceHide)))
 | |
|       return;
 | |
| 
 | |
|     // browser.fullscreen.animateUp
 | |
|     // 0 - never animate up
 | |
|     // 1 - animate only for first collapse after entering fullscreen (default for perf's sake)
 | |
|     // 2 - animate every time it collapses
 | |
|     if (gPrefService.getIntPref("browser.fullscreen.animateUp") == 0)
 | |
|       this._shouldAnimate = false;
 | |
| 
 | |
|     if (!aShow && this._shouldAnimate) {
 | |
|       this._isAnimating = true;
 | |
|       this._shouldAnimate = false;
 | |
|       this._animationTimeout = setTimeout(this._animateUp.bind(this), 800);
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     // The chrome is collapsed so don't spam needless mousemove events
 | |
|     if (aShow) {
 | |
|       gBrowser.mPanelContainer.addEventListener("mousemove",
 | |
|                                                 this._collapseCallback, false);
 | |
|     }
 | |
|     else {
 | |
|       gBrowser.mPanelContainer.removeEventListener("mousemove",
 | |
|                                                    this._collapseCallback, false);
 | |
|     }
 | |
| 
 | |
|     // Hiding/collapsing the toolbox interferes with the tab bar's scrollbox,
 | |
|     // so we just move it off-screen instead. See bug 430687.
 | |
|     gNavToolbox.style.marginTop =
 | |
|       aShow ? "" : -gNavToolbox.getBoundingClientRect().height + "px";
 | |
| 
 | |
|     let toggler = document.getElementById("fullscr-toggler");
 | |
|     if (toggler) {
 | |
|       toggler.collapsed = aShow;
 | |
|     }
 | |
|     this._isChromeCollapsed = !aShow;
 | |
|     if (gPrefService.getIntPref("browser.fullscreen.animateUp") == 2)
 | |
|       this._shouldAnimate = true;
 | |
|   },
 | |
| 
 | |
|   showXULChrome: function(aTag, aShow)
 | |
|   {
 | |
|     var els = document.getElementsByTagNameNS(this._XULNS, aTag);
 | |
| 
 | |
|     for (let el of els) {
 | |
|       // XXX don't interfere with previously collapsed toolbars
 | |
|       if (el.getAttribute("fullscreentoolbar") == "true") {
 | |
|         if (!aShow) {
 | |
| 
 | |
|           var toolbarMode = el.getAttribute("mode");
 | |
|           if (toolbarMode != "text") {
 | |
|             el.setAttribute("saved-mode", toolbarMode);
 | |
|             el.setAttribute("saved-iconsize", el.getAttribute("iconsize"));
 | |
|             el.setAttribute("mode", "icons");
 | |
|             el.setAttribute("iconsize", "small");
 | |
|           }
 | |
| 
 | |
|           // Give the main nav bar and the tab bar the fullscreen context menu,
 | |
|           // otherwise remove context menu to prevent breakage
 | |
|           el.setAttribute("saved-context", el.getAttribute("context"));
 | |
|           if (el.id == "nav-bar" || el.id == "TabsToolbar")
 | |
|             el.setAttribute("context", "autohide-context");
 | |
|           else
 | |
|             el.removeAttribute("context");
 | |
| 
 | |
|           // Set the inFullscreen attribute to allow specific styling
 | |
|           // in fullscreen mode
 | |
|           el.setAttribute("inFullscreen", true);
 | |
|         }
 | |
|         else {
 | |
|           function restoreAttr(attrName) {
 | |
|             var savedAttr = "saved-" + attrName;
 | |
|             if (el.hasAttribute(savedAttr)) {
 | |
|               el.setAttribute(attrName, el.getAttribute(savedAttr));
 | |
|               el.removeAttribute(savedAttr);
 | |
|             }
 | |
|           }
 | |
| 
 | |
|           restoreAttr("mode");
 | |
|           restoreAttr("iconsize");
 | |
|           restoreAttr("context");
 | |
| 
 | |
|           el.removeAttribute("inFullscreen");
 | |
|         }
 | |
|       } else {
 | |
|         // use moz-collapsed so it doesn't persist hidden/collapsed,
 | |
|         // so that new windows don't have missing toolbars
 | |
|         if (aShow)
 | |
|           el.removeAttribute("moz-collapsed");
 | |
|         else
 | |
|           el.setAttribute("moz-collapsed", "true");
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (aShow) {
 | |
|       gNavToolbox.removeAttribute("inFullscreen");
 | |
|       document.documentElement.removeAttribute("inFullscreen");
 | |
|     } else {
 | |
|       gNavToolbox.setAttribute("inFullscreen", true);
 | |
|       document.documentElement.setAttribute("inFullscreen", true);
 | |
|     }
 | |
| 
 | |
|     // In tabs-on-top mode, move window controls to the tab bar,
 | |
|     // and in tabs-on-bottom mode, move them back to the navigation toolbar.
 | |
|     // When there is a chance the tab bar may be collapsed, put window
 | |
|     // controls on nav bar.
 | |
|     var fullscreenctls = document.getElementById("window-controls");
 | |
|     var navbar = document.getElementById("nav-bar");
 | |
|     var ctlsOnTabbar = window.toolbar.visible &&
 | |
|                        (navbar.collapsed ||
 | |
|                           (TabsOnTop.enabled &&
 | |
|                            !gPrefService.getBoolPref("browser.tabs.autoHide")));
 | |
|     if (fullscreenctls.parentNode == navbar && ctlsOnTabbar) {
 | |
|       fullscreenctls.removeAttribute("flex");
 | |
|       document.getElementById("TabsToolbar").appendChild(fullscreenctls);
 | |
|     }
 | |
|     else if (fullscreenctls.parentNode.id == "TabsToolbar" && !ctlsOnTabbar) {
 | |
|       fullscreenctls.setAttribute("flex", "1");
 | |
|       navbar.appendChild(fullscreenctls);
 | |
|     }
 | |
|     fullscreenctls.hidden = aShow;
 | |
|   }
 | |
| };
 | |
| XPCOMUtils.defineLazyGetter(FullScreen, "useLionFullScreen", function() {
 | |
|   // We'll only use OS X Lion full screen if we're
 | |
|   // * on OS X
 | |
|   // * on Lion or higher (Darwin 11+)
 | |
|   // * have fullscreenbutton="true"
 | |
| #ifdef XP_MACOSX
 | |
|   return parseFloat(Services.sysinfo.getProperty("version")) >= 11 &&
 | |
|          document.documentElement.getAttribute("fullscreenbutton") == "true";
 | |
| #else
 | |
|   return false;
 | |
| #endif
 | |
| });
 | 
