browser/base/content/browser-fullScreen.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 # -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 # This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 # License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 5
michael@0 6 var FullScreen = {
michael@0 7 _XULNS: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
michael@0 8 get _fullScrToggler() {
michael@0 9 delete this._fullScrToggler;
michael@0 10 return this._fullScrToggler = document.getElementById("fullscr-toggler");
michael@0 11 },
michael@0 12 toggle: function (event) {
michael@0 13 var enterFS = window.fullScreen;
michael@0 14
michael@0 15 // We get the fullscreen event _before_ the window transitions into or out of FS mode.
michael@0 16 if (event && event.type == "fullscreen")
michael@0 17 enterFS = !enterFS;
michael@0 18
michael@0 19 // Toggle the View:FullScreen command, which controls elements like the
michael@0 20 // fullscreen menuitem, and menubars.
michael@0 21 let fullscreenCommand = document.getElementById("View:FullScreen");
michael@0 22 if (enterFS) {
michael@0 23 fullscreenCommand.setAttribute("checked", enterFS);
michael@0 24 } else {
michael@0 25 fullscreenCommand.removeAttribute("checked");
michael@0 26 }
michael@0 27
michael@0 28 #ifdef XP_MACOSX
michael@0 29 // Make sure the menu items are adjusted.
michael@0 30 document.getElementById("enterFullScreenItem").hidden = enterFS;
michael@0 31 document.getElementById("exitFullScreenItem").hidden = !enterFS;
michael@0 32 #endif
michael@0 33
michael@0 34 // On OS X Lion we don't want to hide toolbars when entering fullscreen, unless
michael@0 35 // we're entering DOM fullscreen, in which case we should hide the toolbars.
michael@0 36 // If we're leaving fullscreen, then we'll go through the exit code below to
michael@0 37 // make sure toolbars are made visible in the case of DOM fullscreen.
michael@0 38 if (enterFS && this.useLionFullScreen) {
michael@0 39 if (document.mozFullScreen) {
michael@0 40 this.showXULChrome("toolbar", false);
michael@0 41 }
michael@0 42 else {
michael@0 43 gNavToolbox.setAttribute("inFullscreen", true);
michael@0 44 document.documentElement.setAttribute("inFullscreen", true);
michael@0 45 }
michael@0 46 return;
michael@0 47 }
michael@0 48
michael@0 49 // show/hide menubars, toolbars (except the full screen toolbar)
michael@0 50 this.showXULChrome("toolbar", !enterFS);
michael@0 51
michael@0 52 if (enterFS) {
michael@0 53 // Add a tiny toolbar to receive mouseover and dragenter events, and provide affordance.
michael@0 54 // This will help simulate the "collapse" metaphor while also requiring less code and
michael@0 55 // events than raw listening of mouse coords. We don't add the toolbar in DOM full-screen
michael@0 56 // mode, only browser full-screen mode.
michael@0 57 if (!document.mozFullScreen) {
michael@0 58 this._fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
michael@0 59 this._fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
michael@0 60 }
michael@0 61 if (gPrefService.getBoolPref("browser.fullscreen.autohide"))
michael@0 62 gBrowser.mPanelContainer.addEventListener("mousemove",
michael@0 63 this._collapseCallback, false);
michael@0 64
michael@0 65 document.addEventListener("keypress", this._keyToggleCallback, false);
michael@0 66 document.addEventListener("popupshown", this._setPopupOpen, false);
michael@0 67 document.addEventListener("popuphidden", this._setPopupOpen, false);
michael@0 68 // We don't animate the toolbar collapse if in DOM full-screen mode,
michael@0 69 // as the size of the content area would still be changing after the
michael@0 70 // mozfullscreenchange event fired, which could confuse content script.
michael@0 71 this._shouldAnimate = !document.mozFullScreen;
michael@0 72 this.mouseoverToggle(false);
michael@0 73
michael@0 74 // Autohide prefs
michael@0 75 gPrefService.addObserver("browser.fullscreen", this, false);
michael@0 76 }
michael@0 77 else {
michael@0 78 // The user may quit fullscreen during an animation
michael@0 79 this._cancelAnimation();
michael@0 80 gNavToolbox.style.marginTop = "";
michael@0 81 if (this._isChromeCollapsed)
michael@0 82 this.mouseoverToggle(true);
michael@0 83 // This is needed if they use the context menu to quit fullscreen
michael@0 84 this._isPopupOpen = false;
michael@0 85
michael@0 86 this.cleanup();
michael@0 87 }
michael@0 88 },
michael@0 89
michael@0 90 exitDomFullScreen : function() {
michael@0 91 document.mozCancelFullScreen();
michael@0 92 },
michael@0 93
michael@0 94 handleEvent: function (event) {
michael@0 95 switch (event.type) {
michael@0 96 case "activate":
michael@0 97 if (document.mozFullScreen) {
michael@0 98 this.showWarning(this.fullscreenDoc);
michael@0 99 }
michael@0 100 break;
michael@0 101 case "transitionend":
michael@0 102 if (event.propertyName == "opacity")
michael@0 103 this.cancelWarning();
michael@0 104 break;
michael@0 105 }
michael@0 106 },
michael@0 107
michael@0 108 enterDomFullscreen : function(event) {
michael@0 109 if (!document.mozFullScreen)
michael@0 110 return;
michael@0 111
michael@0 112 // However, if we receive a "MozEnteredDomFullScreen" event for a document
michael@0 113 // which is not a subdocument of a currently active (ie. visible) browser
michael@0 114 // or iframe, we know that we've switched to a different frame since the
michael@0 115 // request to enter full-screen was made, so we should exit full-screen
michael@0 116 // since the "full-screen document" isn't acutally visible.
michael@0 117 if (!event.target.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
michael@0 118 .getInterface(Ci.nsIWebNavigation)
michael@0 119 .QueryInterface(Ci.nsIDocShell).isActive) {
michael@0 120 document.mozCancelFullScreen();
michael@0 121 return;
michael@0 122 }
michael@0 123
michael@0 124 let focusManager = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
michael@0 125 if (focusManager.activeWindow != window) {
michael@0 126 // The top-level window has lost focus since the request to enter
michael@0 127 // full-screen was made. Cancel full-screen.
michael@0 128 document.mozCancelFullScreen();
michael@0 129 return;
michael@0 130 }
michael@0 131
michael@0 132 // Ensure the sidebar is hidden.
michael@0 133 if (!document.getElementById("sidebar-box").hidden)
michael@0 134 toggleSidebar();
michael@0 135
michael@0 136 if (gFindBarInitialized)
michael@0 137 gFindBar.close();
michael@0 138
michael@0 139 this.showWarning(event.target);
michael@0 140
michael@0 141 // Exit DOM full-screen mode upon open, close, or change tab.
michael@0 142 gBrowser.tabContainer.addEventListener("TabOpen", this.exitDomFullScreen);
michael@0 143 gBrowser.tabContainer.addEventListener("TabClose", this.exitDomFullScreen);
michael@0 144 gBrowser.tabContainer.addEventListener("TabSelect", this.exitDomFullScreen);
michael@0 145
michael@0 146 // Add listener to detect when the fullscreen window is re-focused.
michael@0 147 // If a fullscreen window loses focus, we show a warning when the
michael@0 148 // fullscreen window is refocused.
michael@0 149 if (!this.useLionFullScreen) {
michael@0 150 window.addEventListener("activate", this);
michael@0 151 }
michael@0 152
michael@0 153 // Cancel any "hide the toolbar" animation which is in progress, and make
michael@0 154 // the toolbar hide immediately.
michael@0 155 this._cancelAnimation();
michael@0 156 this.mouseoverToggle(false);
michael@0 157
michael@0 158 // Remove listeners on the full-screen toggler, so that mouseover
michael@0 159 // the top of the screen will not cause the toolbar to re-appear.
michael@0 160 this._fullScrToggler.removeEventListener("mouseover", this._expandCallback, false);
michael@0 161 this._fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
michael@0 162 },
michael@0 163
michael@0 164 cleanup: function () {
michael@0 165 if (window.fullScreen) {
michael@0 166 gBrowser.mPanelContainer.removeEventListener("mousemove",
michael@0 167 this._collapseCallback, false);
michael@0 168 document.removeEventListener("keypress", this._keyToggleCallback, false);
michael@0 169 document.removeEventListener("popupshown", this._setPopupOpen, false);
michael@0 170 document.removeEventListener("popuphidden", this._setPopupOpen, false);
michael@0 171 gPrefService.removeObserver("browser.fullscreen", this);
michael@0 172
michael@0 173 this._fullScrToggler.removeEventListener("mouseover", this._expandCallback, false);
michael@0 174 this._fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
michael@0 175 this.cancelWarning();
michael@0 176 gBrowser.tabContainer.removeEventListener("TabOpen", this.exitDomFullScreen);
michael@0 177 gBrowser.tabContainer.removeEventListener("TabClose", this.exitDomFullScreen);
michael@0 178 gBrowser.tabContainer.removeEventListener("TabSelect", this.exitDomFullScreen);
michael@0 179 if (!this.useLionFullScreen)
michael@0 180 window.removeEventListener("activate", this);
michael@0 181 this.fullscreenDoc = null;
michael@0 182 }
michael@0 183 },
michael@0 184
michael@0 185 observe: function(aSubject, aTopic, aData)
michael@0 186 {
michael@0 187 if (aData == "browser.fullscreen.autohide") {
michael@0 188 if (gPrefService.getBoolPref("browser.fullscreen.autohide")) {
michael@0 189 gBrowser.mPanelContainer.addEventListener("mousemove",
michael@0 190 this._collapseCallback, false);
michael@0 191 }
michael@0 192 else {
michael@0 193 gBrowser.mPanelContainer.removeEventListener("mousemove",
michael@0 194 this._collapseCallback, false);
michael@0 195 }
michael@0 196 }
michael@0 197 },
michael@0 198
michael@0 199 // Event callbacks
michael@0 200 _expandCallback: function()
michael@0 201 {
michael@0 202 FullScreen.mouseoverToggle(true);
michael@0 203 },
michael@0 204 _collapseCallback: function()
michael@0 205 {
michael@0 206 FullScreen.mouseoverToggle(false);
michael@0 207 },
michael@0 208 _keyToggleCallback: function(aEvent)
michael@0 209 {
michael@0 210 // if we can use the keyboard (eg Ctrl+L or Ctrl+E) to open the toolbars, we
michael@0 211 // should provide a way to collapse them too.
michael@0 212 if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
michael@0 213 FullScreen._shouldAnimate = false;
michael@0 214 FullScreen.mouseoverToggle(false, true);
michael@0 215 }
michael@0 216 // F6 is another shortcut to the address bar, but its not covered in OpenLocation()
michael@0 217 else if (aEvent.keyCode == aEvent.DOM_VK_F6)
michael@0 218 FullScreen.mouseoverToggle(true);
michael@0 219 },
michael@0 220
michael@0 221 // Checks whether we are allowed to collapse the chrome
michael@0 222 _isPopupOpen: false,
michael@0 223 _isChromeCollapsed: false,
michael@0 224 _safeToCollapse: function(forceHide)
michael@0 225 {
michael@0 226 if (!gPrefService.getBoolPref("browser.fullscreen.autohide"))
michael@0 227 return false;
michael@0 228
michael@0 229 // a popup menu is open in chrome: don't collapse chrome
michael@0 230 if (!forceHide && this._isPopupOpen)
michael@0 231 return false;
michael@0 232
michael@0 233 // a textbox in chrome is focused (location bar anyone?): don't collapse chrome
michael@0 234 if (document.commandDispatcher.focusedElement &&
michael@0 235 document.commandDispatcher.focusedElement.ownerDocument == document &&
michael@0 236 document.commandDispatcher.focusedElement.localName == "input") {
michael@0 237 if (forceHide)
michael@0 238 // hidden textboxes that still have focus are bad bad bad
michael@0 239 document.commandDispatcher.focusedElement.blur();
michael@0 240 else
michael@0 241 return false;
michael@0 242 }
michael@0 243 return true;
michael@0 244 },
michael@0 245
michael@0 246 _setPopupOpen: function(aEvent)
michael@0 247 {
michael@0 248 // Popups should only veto chrome collapsing if they were opened when the chrome was not collapsed.
michael@0 249 // Otherwise, they would not affect chrome and the user would expect the chrome to go away.
michael@0 250 // e.g. we wouldn't want the autoscroll icon firing this event, so when the user
michael@0 251 // toggles chrome when moving mouse to the top, it doesn't go away again.
michael@0 252 if (aEvent.type == "popupshown" && !FullScreen._isChromeCollapsed &&
michael@0 253 aEvent.target.localName != "tooltip" && aEvent.target.localName != "window")
michael@0 254 FullScreen._isPopupOpen = true;
michael@0 255 else if (aEvent.type == "popuphidden" && aEvent.target.localName != "tooltip" &&
michael@0 256 aEvent.target.localName != "window")
michael@0 257 FullScreen._isPopupOpen = false;
michael@0 258 },
michael@0 259
michael@0 260 // Autohide helpers for the context menu item
michael@0 261 getAutohide: function(aItem)
michael@0 262 {
michael@0 263 aItem.setAttribute("checked", gPrefService.getBoolPref("browser.fullscreen.autohide"));
michael@0 264 },
michael@0 265 setAutohide: function()
michael@0 266 {
michael@0 267 gPrefService.setBoolPref("browser.fullscreen.autohide", !gPrefService.getBoolPref("browser.fullscreen.autohide"));
michael@0 268 },
michael@0 269
michael@0 270 // Animate the toolbars disappearing
michael@0 271 _shouldAnimate: true,
michael@0 272 _isAnimating: false,
michael@0 273 _animationTimeout: 0,
michael@0 274 _animationHandle: 0,
michael@0 275 _animateUp: function() {
michael@0 276 // check again, the user may have done something before the animation was due to start
michael@0 277 if (!window.fullScreen || !this._safeToCollapse(false)) {
michael@0 278 this._isAnimating = false;
michael@0 279 this._shouldAnimate = true;
michael@0 280 return;
michael@0 281 }
michael@0 282
michael@0 283 this._animateStartTime = window.mozAnimationStartTime;
michael@0 284 if (!this._animationHandle)
michael@0 285 this._animationHandle = window.mozRequestAnimationFrame(this);
michael@0 286 },
michael@0 287
michael@0 288 sample: function (timeStamp) {
michael@0 289 const duration = 1500;
michael@0 290 const timePassed = timeStamp - this._animateStartTime;
michael@0 291 const pos = timePassed >= duration ? 1 :
michael@0 292 1 - Math.pow(1 - timePassed / duration, 4);
michael@0 293
michael@0 294 if (pos >= 1) {
michael@0 295 // We've animated enough
michael@0 296 this._cancelAnimation();
michael@0 297 gNavToolbox.style.marginTop = "";
michael@0 298 this.mouseoverToggle(false);
michael@0 299 return;
michael@0 300 }
michael@0 301
michael@0 302 gNavToolbox.style.marginTop = (gNavToolbox.boxObject.height * pos * -1) + "px";
michael@0 303 this._animationHandle = window.mozRequestAnimationFrame(this);
michael@0 304 },
michael@0 305
michael@0 306 _cancelAnimation: function() {
michael@0 307 window.mozCancelAnimationFrame(this._animationHandle);
michael@0 308 this._animationHandle = 0;
michael@0 309 clearTimeout(this._animationTimeout);
michael@0 310 this._isAnimating = false;
michael@0 311 this._shouldAnimate = false;
michael@0 312 },
michael@0 313
michael@0 314 cancelWarning: function(event) {
michael@0 315 if (!this.warningBox)
michael@0 316 return;
michael@0 317 this.warningBox.removeEventListener("transitionend", this);
michael@0 318 if (this.warningFadeOutTimeout) {
michael@0 319 clearTimeout(this.warningFadeOutTimeout);
michael@0 320 this.warningFadeOutTimeout = null;
michael@0 321 }
michael@0 322
michael@0 323 // Ensure focus switches away from the (now hidden) warning box. If the user
michael@0 324 // clicked buttons in the fullscreen key authorization UI, it would have been
michael@0 325 // focused, and any key events would be directed at the (now hidden) chrome
michael@0 326 // document instead of the target document.
michael@0 327 gBrowser.selectedBrowser.focus();
michael@0 328
michael@0 329 this.warningBox.setAttribute("hidden", true);
michael@0 330 this.warningBox.removeAttribute("fade-warning-out");
michael@0 331 this.warningBox.removeAttribute("obscure-browser");
michael@0 332 this.warningBox = null;
michael@0 333 },
michael@0 334
michael@0 335 setFullscreenAllowed: function(isApproved) {
michael@0 336 // The "remember decision" checkbox is hidden when showing for documents that
michael@0 337 // the permission manager can't handle (documents with URIs without a host).
michael@0 338 // We simply require those to be approved every time instead.
michael@0 339 let rememberCheckbox = document.getElementById("full-screen-remember-decision");
michael@0 340 let uri = this.fullscreenDoc.nodePrincipal.URI;
michael@0 341 if (!rememberCheckbox.hidden) {
michael@0 342 if (rememberCheckbox.checked)
michael@0 343 Services.perms.add(uri,
michael@0 344 "fullscreen",
michael@0 345 isApproved ? Services.perms.ALLOW_ACTION : Services.perms.DENY_ACTION,
michael@0 346 Services.perms.EXPIRE_NEVER);
michael@0 347 else if (isApproved) {
michael@0 348 // The user has only temporarily approved fullscren for this fullscreen
michael@0 349 // session only. Add the permission (so Gecko knows to approve any further
michael@0 350 // fullscreen requests for this host in this fullscreen session) but add
michael@0 351 // a listener to revoke the permission when the chrome document exits
michael@0 352 // fullscreen.
michael@0 353 Services.perms.add(uri,
michael@0 354 "fullscreen",
michael@0 355 Services.perms.ALLOW_ACTION,
michael@0 356 Services.perms.EXPIRE_SESSION);
michael@0 357 let host = uri.host;
michael@0 358 var onFullscreenchange = function onFullscreenchange(event) {
michael@0 359 if (event.target == document && document.mozFullScreenElement == null) {
michael@0 360 // The chrome document has left fullscreen. Remove the temporary permission grant.
michael@0 361 Services.perms.remove(host, "fullscreen");
michael@0 362 document.removeEventListener("mozfullscreenchange", onFullscreenchange);
michael@0 363 }
michael@0 364 }
michael@0 365 document.addEventListener("mozfullscreenchange", onFullscreenchange);
michael@0 366 }
michael@0 367 }
michael@0 368 if (this.warningBox)
michael@0 369 this.warningBox.setAttribute("fade-warning-out", "true");
michael@0 370 // If the document has been granted fullscreen, notify Gecko so it can resume
michael@0 371 // any pending pointer lock requests, otherwise exit fullscreen; the user denied
michael@0 372 // the fullscreen request.
michael@0 373 if (isApproved)
michael@0 374 Services.obs.notifyObservers(this.fullscreenDoc, "fullscreen-approved", "");
michael@0 375 else
michael@0 376 document.mozCancelFullScreen();
michael@0 377 },
michael@0 378
michael@0 379 warningBox: null,
michael@0 380 warningFadeOutTimeout: null,
michael@0 381 fullscreenDoc: null,
michael@0 382
michael@0 383 // Shows the fullscreen approval UI, or if the domain has already been approved
michael@0 384 // for fullscreen, shows a warning that the site has entered fullscreen for a short
michael@0 385 // duration.
michael@0 386 showWarning: function(targetDoc) {
michael@0 387 if (!document.mozFullScreen ||
michael@0 388 !gPrefService.getBoolPref("full-screen-api.approval-required"))
michael@0 389 return;
michael@0 390
michael@0 391 // Set the strings on the fullscreen approval UI.
michael@0 392 this.fullscreenDoc = targetDoc;
michael@0 393 let uri = this.fullscreenDoc.nodePrincipal.URI;
michael@0 394 let host = null;
michael@0 395 try {
michael@0 396 host = uri.host;
michael@0 397 } catch (e) { }
michael@0 398 let hostLabel = document.getElementById("full-screen-domain-text");
michael@0 399 let rememberCheckbox = document.getElementById("full-screen-remember-decision");
michael@0 400 let isApproved = false;
michael@0 401 if (host) {
michael@0 402 // Document's principal's URI has a host. Display a warning including the hostname and
michael@0 403 // show UI to enable the user to permanently grant this host permission to enter fullscreen.
michael@0 404 let utils = {};
michael@0 405 Cu.import("resource://gre/modules/DownloadUtils.jsm", utils);
michael@0 406 let displayHost = utils.DownloadUtils.getURIHost(uri.spec)[0];
michael@0 407 let bundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
michael@0 408
michael@0 409 hostLabel.textContent = bundle.formatStringFromName("fullscreen.entered", [displayHost], 1);
michael@0 410 hostLabel.removeAttribute("hidden");
michael@0 411
michael@0 412 rememberCheckbox.label = bundle.formatStringFromName("fullscreen.rememberDecision", [displayHost], 1);
michael@0 413 rememberCheckbox.checked = false;
michael@0 414 rememberCheckbox.removeAttribute("hidden");
michael@0 415
michael@0 416 // Note we only allow documents whose principal's URI has a host to
michael@0 417 // store permission grants.
michael@0 418 isApproved = Services.perms.testPermission(uri, "fullscreen") == Services.perms.ALLOW_ACTION;
michael@0 419 } else {
michael@0 420 hostLabel.setAttribute("hidden", "true");
michael@0 421 rememberCheckbox.setAttribute("hidden", "true");
michael@0 422 }
michael@0 423
michael@0 424 // Note: the warning box can be non-null if the warning box from the previous request
michael@0 425 // wasn't hidden before another request was made.
michael@0 426 if (!this.warningBox) {
michael@0 427 this.warningBox = document.getElementById("full-screen-warning-container");
michael@0 428 // Add a listener to clean up state after the warning is hidden.
michael@0 429 this.warningBox.addEventListener("transitionend", this);
michael@0 430 this.warningBox.removeAttribute("hidden");
michael@0 431 } else {
michael@0 432 if (this.warningFadeOutTimeout) {
michael@0 433 clearTimeout(this.warningFadeOutTimeout);
michael@0 434 this.warningFadeOutTimeout = null;
michael@0 435 }
michael@0 436 this.warningBox.removeAttribute("fade-warning-out");
michael@0 437 }
michael@0 438
michael@0 439 // If fullscreen mode has not yet been approved for the fullscreen
michael@0 440 // document's domain, show the approval UI and don't auto fade out the
michael@0 441 // fullscreen warning box. Otherwise, we're just notifying of entry into
michael@0 442 // fullscreen mode. Note if the resource's host is null, we must be
michael@0 443 // showing a local file or a local data URI, and we require explicit
michael@0 444 // approval every time.
michael@0 445 let authUI = document.getElementById("full-screen-approval-pane");
michael@0 446 if (isApproved) {
michael@0 447 authUI.setAttribute("hidden", "true");
michael@0 448 this.warningBox.removeAttribute("obscure-browser");
michael@0 449 } else {
michael@0 450 // Partially obscure the <browser> element underneath the approval UI.
michael@0 451 this.warningBox.setAttribute("obscure-browser", "true");
michael@0 452 authUI.removeAttribute("hidden");
michael@0 453 }
michael@0 454
michael@0 455 // If we're not showing the fullscreen approval UI, we're just notifying the user
michael@0 456 // of the transition, so set a timeout to fade the warning out after a few moments.
michael@0 457 if (isApproved)
michael@0 458 this.warningFadeOutTimeout =
michael@0 459 setTimeout(
michael@0 460 function() {
michael@0 461 if (this.warningBox)
michael@0 462 this.warningBox.setAttribute("fade-warning-out", "true");
michael@0 463 }.bind(this),
michael@0 464 3000);
michael@0 465 },
michael@0 466
michael@0 467 mouseoverToggle: function(aShow, forceHide)
michael@0 468 {
michael@0 469 // Don't do anything if:
michael@0 470 // a) we're already in the state we want,
michael@0 471 // b) we're animating and will become collapsed soon, or
michael@0 472 // c) we can't collapse because it would be undesirable right now
michael@0 473 if (aShow != this._isChromeCollapsed || (!aShow && this._isAnimating) ||
michael@0 474 (!aShow && !this._safeToCollapse(forceHide)))
michael@0 475 return;
michael@0 476
michael@0 477 // browser.fullscreen.animateUp
michael@0 478 // 0 - never animate up
michael@0 479 // 1 - animate only for first collapse after entering fullscreen (default for perf's sake)
michael@0 480 // 2 - animate every time it collapses
michael@0 481 if (gPrefService.getIntPref("browser.fullscreen.animateUp") == 0)
michael@0 482 this._shouldAnimate = false;
michael@0 483
michael@0 484 if (!aShow && this._shouldAnimate) {
michael@0 485 this._isAnimating = true;
michael@0 486 this._shouldAnimate = false;
michael@0 487 this._animationTimeout = setTimeout(this._animateUp.bind(this), 800);
michael@0 488 return;
michael@0 489 }
michael@0 490
michael@0 491 // The chrome is collapsed so don't spam needless mousemove events
michael@0 492 if (aShow) {
michael@0 493 gBrowser.mPanelContainer.addEventListener("mousemove",
michael@0 494 this._collapseCallback, false);
michael@0 495 }
michael@0 496 else {
michael@0 497 gBrowser.mPanelContainer.removeEventListener("mousemove",
michael@0 498 this._collapseCallback, false);
michael@0 499 }
michael@0 500
michael@0 501 // Hiding/collapsing the toolbox interferes with the tab bar's scrollbox,
michael@0 502 // so we just move it off-screen instead. See bug 430687.
michael@0 503 gNavToolbox.style.marginTop =
michael@0 504 aShow ? "" : -gNavToolbox.getBoundingClientRect().height + "px";
michael@0 505
michael@0 506 this._fullScrToggler.collapsed = aShow;
michael@0 507 this._isChromeCollapsed = !aShow;
michael@0 508 if (gPrefService.getIntPref("browser.fullscreen.animateUp") == 2)
michael@0 509 this._shouldAnimate = true;
michael@0 510 },
michael@0 511
michael@0 512 showXULChrome: function(aTag, aShow)
michael@0 513 {
michael@0 514 var els = document.getElementsByTagNameNS(this._XULNS, aTag);
michael@0 515
michael@0 516 for (let el of els) {
michael@0 517 // XXX don't interfere with previously collapsed toolbars
michael@0 518 if (el.getAttribute("fullscreentoolbar") == "true") {
michael@0 519 if (!aShow) {
michael@0 520 // Give the main nav bar and the tab bar the fullscreen context menu,
michael@0 521 // otherwise remove context menu to prevent breakage
michael@0 522 el.setAttribute("saved-context", el.getAttribute("context"));
michael@0 523 if (el.id == "nav-bar" || el.id == "TabsToolbar")
michael@0 524 el.setAttribute("context", "autohide-context");
michael@0 525 else
michael@0 526 el.removeAttribute("context");
michael@0 527
michael@0 528 // Set the inFullscreen attribute to allow specific styling
michael@0 529 // in fullscreen mode
michael@0 530 el.setAttribute("inFullscreen", true);
michael@0 531 }
michael@0 532 else {
michael@0 533 if (el.hasAttribute("saved-context")) {
michael@0 534 el.setAttribute("context", el.getAttribute("saved-context"));
michael@0 535 el.removeAttribute("saved-context");
michael@0 536 }
michael@0 537 el.removeAttribute("inFullscreen");
michael@0 538 }
michael@0 539 } else {
michael@0 540 // use moz-collapsed so it doesn't persist hidden/collapsed,
michael@0 541 // so that new windows don't have missing toolbars
michael@0 542 if (aShow)
michael@0 543 el.removeAttribute("moz-collapsed");
michael@0 544 else
michael@0 545 el.setAttribute("moz-collapsed", "true");
michael@0 546 }
michael@0 547 }
michael@0 548
michael@0 549 if (aShow) {
michael@0 550 gNavToolbox.removeAttribute("inFullscreen");
michael@0 551 document.documentElement.removeAttribute("inFullscreen");
michael@0 552 } else {
michael@0 553 gNavToolbox.setAttribute("inFullscreen", true);
michael@0 554 document.documentElement.setAttribute("inFullscreen", true);
michael@0 555 }
michael@0 556
michael@0 557 var fullscreenctls = document.getElementById("window-controls");
michael@0 558 var navbar = document.getElementById("nav-bar");
michael@0 559 var ctlsOnTabbar = window.toolbar.visible;
michael@0 560 if (fullscreenctls.parentNode == navbar && ctlsOnTabbar) {
michael@0 561 fullscreenctls.removeAttribute("flex");
michael@0 562 document.getElementById("TabsToolbar").appendChild(fullscreenctls);
michael@0 563 }
michael@0 564 else if (fullscreenctls.parentNode.id == "TabsToolbar" && !ctlsOnTabbar) {
michael@0 565 fullscreenctls.setAttribute("flex", "1");
michael@0 566 navbar.appendChild(fullscreenctls);
michael@0 567 }
michael@0 568 fullscreenctls.hidden = aShow;
michael@0 569
michael@0 570 ToolbarIconColor.inferFromText();
michael@0 571 }
michael@0 572 };
michael@0 573 XPCOMUtils.defineLazyGetter(FullScreen, "useLionFullScreen", function() {
michael@0 574 // We'll only use OS X Lion full screen if we're
michael@0 575 // * on OS X
michael@0 576 // * on Lion or higher (Darwin 11+)
michael@0 577 // * have fullscreenbutton="true"
michael@0 578 #ifdef XP_MACOSX
michael@0 579 return parseFloat(Services.sysinfo.getProperty("version")) >= 11 &&
michael@0 580 document.documentElement.getAttribute("fullscreenbutton") == "true";
michael@0 581 #else
michael@0 582 return false;
michael@0 583 #endif
michael@0 584 });

mercurial