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