mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 758812 - Break up browser.js into smaller pieces, Phase 1 (FullScreen). r=gavin
This commit is contained in:
parent
ea19fb9df6
commit
6561b33856
612
browser/base/content/browser-fullScreen.js
Normal file
612
browser/base/content/browser-fullScreen.js
Normal file
@ -0,0 +1,612 @@
|
||||
# -*- 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);
|
||||
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 (var i = 0; i < els.length; ++i) {
|
||||
// XXX don't interfere with previously collapsed toolbars
|
||||
if (els[i].getAttribute("fullscreentoolbar") == "true") {
|
||||
if (!aShow) {
|
||||
|
||||
var toolbarMode = els[i].getAttribute("mode");
|
||||
if (toolbarMode != "text") {
|
||||
els[i].setAttribute("saved-mode", toolbarMode);
|
||||
els[i].setAttribute("saved-iconsize",
|
||||
els[i].getAttribute("iconsize"));
|
||||
els[i].setAttribute("mode", "icons");
|
||||
els[i].setAttribute("iconsize", "small");
|
||||
}
|
||||
|
||||
// Give the main nav bar and the tab bar the fullscreen context menu,
|
||||
// otherwise remove context menu to prevent breakage
|
||||
els[i].setAttribute("saved-context",
|
||||
els[i].getAttribute("context"));
|
||||
if (els[i].id == "nav-bar" || els[i].id == "TabsToolbar")
|
||||
els[i].setAttribute("context", "autohide-context");
|
||||
else
|
||||
els[i].removeAttribute("context");
|
||||
|
||||
// Set the inFullscreen attribute to allow specific styling
|
||||
// in fullscreen mode
|
||||
els[i].setAttribute("inFullscreen", true);
|
||||
}
|
||||
else {
|
||||
function restoreAttr(attrName) {
|
||||
var savedAttr = "saved-" + attrName;
|
||||
if (els[i].hasAttribute(savedAttr)) {
|
||||
els[i].setAttribute(attrName, els[i].getAttribute(savedAttr));
|
||||
els[i].removeAttribute(savedAttr);
|
||||
}
|
||||
}
|
||||
|
||||
restoreAttr("mode");
|
||||
restoreAttr("iconsize");
|
||||
restoreAttr("context");
|
||||
|
||||
els[i].removeAttribute("inFullscreen");
|
||||
}
|
||||
} else {
|
||||
// use moz-collapsed so it doesn't persist hidden/collapsed,
|
||||
// so that new windows don't have missing toolbars
|
||||
if (aShow)
|
||||
els[i].removeAttribute("moz-collapsed");
|
||||
else
|
||||
els[i].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);
|
||||
}
|
||||
|
||||
var controls = document.getElementsByAttribute("fullscreencontrol", "true");
|
||||
for (var i = 0; i < controls.length; ++i)
|
||||
controls[i].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
|
||||
});
|
@ -143,6 +143,7 @@ let gInitialPages = [
|
||||
|
||||
#include browser-addons.js
|
||||
#include browser-feeds.js
|
||||
#include browser-fullScreen.js
|
||||
#include browser-fullZoom.js
|
||||
#include browser-places.js
|
||||
#include browser-plugins.js
|
||||
@ -3687,614 +3688,6 @@ function updateEditUIVisibility()
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
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 (var i = 0; i < els.length; ++i) {
|
||||
// XXX don't interfere with previously collapsed toolbars
|
||||
if (els[i].getAttribute("fullscreentoolbar") == "true") {
|
||||
if (!aShow) {
|
||||
|
||||
var toolbarMode = els[i].getAttribute("mode");
|
||||
if (toolbarMode != "text") {
|
||||
els[i].setAttribute("saved-mode", toolbarMode);
|
||||
els[i].setAttribute("saved-iconsize",
|
||||
els[i].getAttribute("iconsize"));
|
||||
els[i].setAttribute("mode", "icons");
|
||||
els[i].setAttribute("iconsize", "small");
|
||||
}
|
||||
|
||||
// Give the main nav bar and the tab bar the fullscreen context menu,
|
||||
// otherwise remove context menu to prevent breakage
|
||||
els[i].setAttribute("saved-context",
|
||||
els[i].getAttribute("context"));
|
||||
if (els[i].id == "nav-bar" || els[i].id == "TabsToolbar")
|
||||
els[i].setAttribute("context", "autohide-context");
|
||||
else
|
||||
els[i].removeAttribute("context");
|
||||
|
||||
// Set the inFullscreen attribute to allow specific styling
|
||||
// in fullscreen mode
|
||||
els[i].setAttribute("inFullscreen", true);
|
||||
}
|
||||
else {
|
||||
function restoreAttr(attrName) {
|
||||
var savedAttr = "saved-" + attrName;
|
||||
if (els[i].hasAttribute(savedAttr)) {
|
||||
els[i].setAttribute(attrName, els[i].getAttribute(savedAttr));
|
||||
els[i].removeAttribute(savedAttr);
|
||||
}
|
||||
}
|
||||
|
||||
restoreAttr("mode");
|
||||
restoreAttr("iconsize");
|
||||
restoreAttr("context");
|
||||
|
||||
els[i].removeAttribute("inFullscreen");
|
||||
}
|
||||
} else {
|
||||
// use moz-collapsed so it doesn't persist hidden/collapsed,
|
||||
// so that new windows don't have missing toolbars
|
||||
if (aShow)
|
||||
els[i].removeAttribute("moz-collapsed");
|
||||
else
|
||||
els[i].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);
|
||||
}
|
||||
|
||||
var controls = document.getElementsByAttribute("fullscreencontrol", "true");
|
||||
for (var i = 0; i < controls.length; ++i)
|
||||
controls[i].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
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns true if |aMimeType| is text-based, false otherwise.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user