summaryrefslogtreecommitdiffstats
path: root/base/content
diff options
context:
space:
mode:
authorThomas Groman <tgroman@nuegia.net>2020-04-20 20:49:37 -0700
committerThomas Groman <tgroman@nuegia.net>2020-04-20 20:49:37 -0700
commitf9cab004186edb425a9b88ad649726605080a17c (patch)
treee2dae51d3144e83d097a12e7a1499e3ea93f90be /base/content
parentf428692de8b59ab89a66502c079e1823dfda8aeb (diff)
downloadwebbrowser-f9cab004186edb425a9b88ad649726605080a17c.tar
webbrowser-f9cab004186edb425a9b88ad649726605080a17c.tar.gz
webbrowser-f9cab004186edb425a9b88ad649726605080a17c.tar.lz
webbrowser-f9cab004186edb425a9b88ad649726605080a17c.tar.xz
webbrowser-f9cab004186edb425a9b88ad649726605080a17c.zip
move browser to webbrowser/
Diffstat (limited to 'base/content')
-rw-r--r--base/content/aboutDialog.css74
-rw-r--r--base/content/aboutDialog.js62
-rw-r--r--base/content/aboutDialog.xul86
-rw-r--r--base/content/autocomplete.css17
-rw-r--r--base/content/autocomplete.xml2128
-rw-r--r--base/content/autorecovery.js60
-rw-r--r--base/content/autorecovery.xul12
-rw-r--r--base/content/baseMenuOverlay.xul114
-rw-r--r--base/content/browser-addons.js537
-rw-r--r--base/content/browser-appmenu.inc381
-rw-r--r--base/content/browser-charsetmenu.inc62
-rw-r--r--base/content/browser-context.inc384
-rw-r--r--base/content/browser-devtools-theme.js91
-rw-r--r--base/content/browser-doctype.inc19
-rw-r--r--base/content/browser-feeds.js224
-rw-r--r--base/content/browser-fullScreen.js462
-rw-r--r--base/content/browser-fullZoom.js526
-rw-r--r--base/content/browser-gestureSupport.js1059
-rw-r--r--base/content/browser-menubar.inc564
-rw-r--r--base/content/browser-menudragging.js340
-rw-r--r--base/content/browser-menudragging.xul13
-rw-r--r--base/content/browser-places.js1316
-rw-r--r--base/content/browser-plugins.js781
-rw-r--r--base/content/browser-sets.inc357
-rw-r--r--base/content/browser-syncui.js472
-rw-r--r--base/content/browser-tabPreviews.js1058
-rw-r--r--base/content/browser-tabPreviews.xml78
-rw-r--r--base/content/browser-thumbnails.js203
-rw-r--r--base/content/browser-title.css204
-rw-r--r--base/content/browser-uacompat.js45
-rw-r--r--base/content/browser-webrtcUI.js55
-rw-r--r--base/content/browser.css759
-rw-r--r--base/content/browser.js7440
-rw-r--r--base/content/browser.xul1046
-rw-r--r--base/content/browserMountPoints.inc12
-rw-r--r--base/content/content.js177
-rw-r--r--base/content/downloadManagerOverlay.xul32
-rw-r--r--base/content/global-devtools-theme-scripts.inc6
-rw-r--r--base/content/global-scripts.inc13
-rw-r--r--base/content/hiddenWindow.xul19
-rw-r--r--base/content/highlighter.css105
-rw-r--r--base/content/jsConsoleOverlay.xul18
-rw-r--r--base/content/macBrowserOverlay.xul67
-rw-r--r--base/content/nsContextMenu.js1603
-rw-r--r--base/content/openLocation.js150
-rw-r--r--base/content/openLocation.xul57
-rw-r--r--base/content/overrides/app-license.html6
-rw-r--r--base/content/padlock.css203
-rw-r--r--base/content/padlock.js234
-rw-r--r--base/content/padlock.xul63
-rw-r--r--base/content/padlock_classic_broken.pngbin726 -> 0 bytes
-rw-r--r--base/content/padlock_classic_ev.pngbin566 -> 0 bytes
-rw-r--r--base/content/padlock_classic_https.pngbin589 -> 0 bytes
-rw-r--r--base/content/padlock_classic_low.pngbin682 -> 0 bytes
-rw-r--r--base/content/padlock_mod_broken.pngbin728 -> 0 bytes
-rw-r--r--base/content/padlock_mod_ev.pngbin290 -> 0 bytes
-rw-r--r--base/content/padlock_mod_https.pngbin338 -> 0 bytes
-rw-r--r--base/content/padlock_mod_low.pngbin386 -> 0 bytes
-rw-r--r--base/content/palemoon.xhtml66
-rw-r--r--base/content/popup-notifications.inc104
-rw-r--r--base/content/safeMode.css8
-rw-r--r--base/content/safeMode.js128
-rw-r--r--base/content/safeMode.xul55
-rw-r--r--base/content/sanitize.js534
-rw-r--r--base/content/sanitize.xul190
-rw-r--r--base/content/sanitizeDialog.css23
-rw-r--r--base/content/sanitizeDialog.js910
-rw-r--r--base/content/softwareUpdateOverlay.xul18
-rw-r--r--base/content/tabbrowser.css77
-rw-r--r--base/content/tabbrowser.xml5403
-rw-r--r--base/content/test/general/audio.oggbin47411 -> 0 bytes
-rw-r--r--base/content/urlbarBindings.xml1800
-rw-r--r--base/content/utilityOverlay.js901
-rw-r--r--base/content/viewSourceOverlay.xul26
-rw-r--r--base/content/web-panels.js102
-rw-r--r--base/content/web-panels.xul84
-rw-r--r--base/content/win6BrowserOverlay.xul12
77 files changed, 0 insertions, 34235 deletions
diff --git a/base/content/aboutDialog.css b/base/content/aboutDialog.css
deleted file mode 100644
index d96eba5..0000000
--- a/base/content/aboutDialog.css
+++ /dev/null
@@ -1,74 +0,0 @@
-/* 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/. */
-
-#aboutPMDialogContainer {
- width: 700px;
- height: 410px;
-}
-
-#aboutVersionBox {
- font-family: Arial, helvetica;
- height: 38 px;
-}
-
-#aboutVersion {
- text-align: center;
- font-size: 18px;
- font-weight: bold;
- margin: 4px;
-}
-
-#distribution,
-#distributionId {
- text-align: center;
- font-size: 14px;
- font-weight: bold;
- display: none;
- margin-top: 0;
- margin-bottom: 0;
-}
-
-#aboutTextBox {
- font-family: Arial, helvetica;
- font-size: 14px;
- margin: 5px 20px;
- padding: 4px 10px 0px;
- border-radius: 3px;
- color: black;
- background-color: rgba(240, 240, 240, .6);
-}
-
-#aboutLinkBox {
- font-family: Arial, helvetica;
-}
-
-.text-credits {
- margin: 5px 0px;
-}
-
-.text-center {
- text-align: center;
-}
-
-.text-link,
-.text-link:focus {
- margin: 0px;
- padding: 0px;
-}
-
-.bottom-link,
-.bottom-link:focus {
- text-align: center;
- text-decoration: none !important;
- padding: 4px;
- border-radius: 3px;
- color: #244C8A;
- background-color: rgba(240, 240, 240, .7);
- margin: 0 40px;
- transition: background-color 0.5s ease-out;
-}
-
-.bottom-link:hover {
- background-color: rgba(240, 240, 255, .95);
-}
diff --git a/base/content/aboutDialog.js b/base/content/aboutDialog.js
deleted file mode 100644
index e4e18f2..0000000
--- a/base/content/aboutDialog.js
+++ /dev/null
@@ -1,62 +0,0 @@
-# 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/.
-
-// Services = object with smart getters for common XPCOM services
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-function init(aEvent)
-{
- if (aEvent.target != document)
- return;
-
- try {
- var distroId = Services.prefs.getCharPref("distribution.id");
- if (distroId) {
- var distroVersion = Services.prefs.getCharPref("distribution.version");
-
- var distroIdField = document.getElementById("distributionId");
- distroIdField.value = distroId + " - " + distroVersion;
- distroIdField.style.display = "block";
-
- try {
- // This is in its own try catch due to bug 895473 and bug 900925.
- var distroAbout = Services.prefs.getComplexValue("distribution.about",
- Components.interfaces.nsISupportsString);
- var distroField = document.getElementById("distribution");
- distroField.value = distroAbout;
- distroField.style.display = "block";
- }
- catch (ex) {
- // Pref is unset
- Components.utils.reportError(ex);
- }
- }
- }
- catch (e) {
- // Pref is unset
- }
-
- // Include the build ID if this is an "a#" or "b#" build
- let version = Services.appinfo.version;
- if (/[ab]\d+$/.test(version)) {
- let buildID = Services.appinfo.appBuildID;
- let buildDate = buildID.slice(0,4) + "-" + buildID.slice(4,6) + "-" + buildID.slice(6,8);
- document.getElementById("aboutVersion").textContent += " (" + buildDate + ")";
- }
-
-#ifdef XP_MACOSX
- // it may not be sized at this point, and we need its width to calculate its position
- window.sizeToContent();
- window.moveTo((screen.availWidth / 2) - (window.outerWidth / 2), screen.availHeight / 5);
-#endif
-
-// get release notes URL from prefs
- var formatter = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
- .getService(Components.interfaces.nsIURLFormatter);
- var releaseNotesURL = formatter.formatURLPref("app.releaseNotesURL");
- if (releaseNotesURL != "about:blank") {
- var relnotes = document.getElementById("releaseNotesURL");
- relnotes.setAttribute("href", releaseNotesURL);
- }
-}
diff --git a/base/content/aboutDialog.xul b/base/content/aboutDialog.xul
deleted file mode 100644
index 91fa81e..0000000
--- a/base/content/aboutDialog.xul
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0"?> <!-- -*- Mode: HTML -*- -->
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://browser/content/aboutDialog.css" type="text/css"?>
-<?xml-stylesheet href="chrome://branding/content/aboutDialog.css" type="text/css"?>
-
-<!DOCTYPE window [
-<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
-%brandDTD;
-<!ENTITY % aboutDialogDTD SYSTEM "chrome://browser/locale/aboutDialog.dtd" >
-%aboutDialogDTD;
-]>
-
-#ifdef XP_MACOSX
-<?xul-overlay href="chrome://browser/content/macBrowserOverlay.xul"?>
-#endif
-
-<window xmlns:html="http://www.w3.org/1999/xhtml"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- id="PMaboutDialog"
- windowtype="Browser:About"
- onload="init(event);"
-#ifdef XP_MACOSX
- inwindowmenu="false"
-#else
- title="&aboutDialog.title;"
-#endif
- role="dialog"
- aria-describedby="version distribution distributionId communityDesc contributeDesc trademark"
- >
-
- <script type="application/javascript" src="chrome://browser/content/aboutDialog.js"/>
-
- <vbox id="aboutPMDialogContainer" flex="1">
- <vbox id="aboutHeaderBox" />
- <vbox id="aboutVersionBox" flex="3">
-#ifdef HAVE_64BIT_BUILD
-#expand <label id="aboutVersion">Version: __MOZ_APP_VERSION__ (64-bit)</label>
-#else
-#expand <label id="aboutVersion">Version: __MOZ_APP_VERSION__ (32-bit)</label>
-#endif
- <label id="distribution" class="text-blurb"/>
- <label id="distributionId" class="text-blurb"/>
-
- </vbox>
- <vbox id="aboutTextBox" flex="1">
- <description class="text-credits text-center">
-#if defined(MOZ_OFFICIAL_BRANDING) || defined(MC_OFFICIAL)
-#ifdef MC_PRIVATE_BUILD
- This is a private build of Pale Moon. If you did not manually build this copy from source yourself, then please download an official version from the <label class="text-link" href="http://www.palemoon.org/">Pale Moon website</label>.
-#else
- <label class="text-link" href="http://www.palemoon.org">Pale Moon</label> is released by <label class="text-link" href="http://www.moonchildproductions.info">Moonchild Productions</label>.
- </description>
- <description class="text-credits text-center">
- Special thanks to all our supporters and donors for making this browser possible!
- </description>
- <description class="text-credits">
- If you wish to contribute, please consider helping out by providing support to other users on the <label class="text-link" href="https://forum.palemoon.org/">Pale Moon forum</label>
- or getting involved in our development by tackling some of the issues found in our GitHub issue tracker.
-#endif
-#else
- &brandFullName; is released by &vendorShortName;.
- </description>
- <description class="text-credits">
- This is an experimental build of Web Browser.
-#endif
- </description>
- </vbox>
- <vbox id="aboutLinkBox">
- <hbox pack="center">
- <label class="text-link bottom-link" href="about:rights">End-user rights</label>
- <label class="text-link bottom-link" href="about:license">Licensing information</label>
- <label class="text-link bottom-link" id="releaseNotesURL">Release notes</label>
- </hbox>
- <description id="aboutPMtrademark">&trademarkInfo.part1;</description>
- </vbox>
- </vbox>
-
- <keyset>
- <key keycode="VK_ESCAPE" oncommand="window.close();"/>
- </keyset>
-
-#ifdef XP_MACOSX
-#include browserMountPoints.inc
-#endif
-</window>
diff --git a/base/content/autocomplete.css b/base/content/autocomplete.css
deleted file mode 100644
index 960bdc4..0000000
--- a/base/content/autocomplete.css
+++ /dev/null
@@ -1,17 +0,0 @@
-/* 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/. */
-
-@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
-@namespace html url("http://www.w3.org/1999/xhtml");
-
-/* Apply crisp rendering for favicons at exactly 2dppx resolution */
-@media (resolution: 2dppx) {
- .ac-site-icon {
- image-rendering: -moz-crisp-edges;
- }
-}
-
-richlistitem > .ac-title-box > .ac-title > .ac-comment:not([selected]) > html|span.ac-selected-text {
- display: none;
-}
diff --git a/base/content/autocomplete.xml b/base/content/autocomplete.xml
deleted file mode 100644
index bd09284..0000000
--- a/base/content/autocomplete.xml
+++ /dev/null
@@ -1,2128 +0,0 @@
-<?xml version="1.0"?>
-<!-- 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/. -->
-
-<bindings id="privateAutocompleteBindings"
- xmlns="http://www.mozilla.org/xbl"
- xmlns:html="http://www.w3.org/1999/xhtml"
- xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- xmlns:xbl="http://www.mozilla.org/xbl">
-
- <binding id="private-autocomplete" role="xul:combobox"
- extends="chrome://global/content/bindings/textbox.xml#textbox">
- <resources>
- <stylesheet src="chrome://browser/content/autocomplete.css"/>
- <stylesheet src="chrome://browser/skin/autocomplete.css"/>
- </resources>
-
- <content sizetopopup="pref">
- <xul:hbox class="private-autocomplete-textbox-container" flex="1" xbl:inherits="focused">
- <children includes="image|deck|stack|box">
- <xul:image class="private-autocomplete-icon" allowevents="true"/>
- </children>
-
- <xul:hbox anonid="textbox-input-box" class="textbox-input-box" flex="1" xbl:inherits="tooltiptext=inputtooltiptext">
- <children/>
- <html:input anonid="input" class="private-autocomplete-textbox textbox-input"
- allowevents="true"
- xbl:inherits="tooltiptext=inputtooltiptext,value,type=inputtype,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey,mozactionhint"/>
- </xul:hbox>
- <children includes="hbox"/>
- </xul:hbox>
-
- <xul:dropmarker anonid="historydropmarker" class="private-autocomplete-history-dropmarker"
- allowevents="true"
- xbl:inherits="open,enablehistory,parentfocused=focused"/>
-
- <xul:popupset anonid="popupset" class="private-autocomplete-result-popupset"/>
-
- <children includes="toolbarbutton"/>
- </content>
-
- <implementation implements="nsIAutoCompleteInput, nsIDOMXULMenuListElement">
- <field name="mController">null</field>
- <field name="mSearchNames">null</field>
- <field name="mIgnoreInput">false</field>
- <field name="mEnterEvent">null</field>
-
- <field name="_searchBeginHandler">null</field>
- <field name="_searchCompleteHandler">null</field>
- <field name="_textEnteredHandler">null</field>
- <field name="_textRevertedHandler">null</field>
-
- <constructor><![CDATA[
- this.mController = Components.classes["@mozilla.org/autocomplete/controller;1"].
- getService(Components.interfaces.nsIAutoCompleteController);
-
- this._searchBeginHandler = this.initEventHandler("searchbegin");
- this._searchCompleteHandler = this.initEventHandler("searchcomplete");
- this._textEnteredHandler = this.initEventHandler("textentered");
- this._textRevertedHandler = this.initEventHandler("textreverted");
-
- // For security reasons delay searches on pasted values.
- this.inputField.controllers.insertControllerAt(0, this._pasteController);
- ]]></constructor>
-
- <destructor><![CDATA[
- this.inputField.controllers.removeController(this._pasteController);
- ]]></destructor>
-
- <!-- =================== nsIAutoCompleteInput =================== -->
-
- <field name="popup"><![CDATA[
- // Wrap in a block so that the let statements don't
- // create properties on 'this' (bug 635252).
- {
- let popup = null;
- let popupId = this.getAttribute("autocompletepopup");
- if (popupId)
- popup = document.getElementById(popupId);
- if (!popup) {
- popup = document.createElement("panel");
- popup.setAttribute("type", "autocomplete");
- popup.setAttribute("noautofocus", "true");
-
- let popupset = document.getAnonymousElementByAttribute(this, "anonid", "popupset");
- popupset.appendChild(popup);
- }
- popup.mInput = this;
- popup;
- }
- ]]></field>
-
- <property name="controller" onget="return this.mController;" readonly="true"/>
-
- <property name="popupOpen"
- onget="return this.popup.popupOpen;"
- onset="if (val) this.openPopup(); else this.closePopup();"/>
-
- <property name="disableAutoComplete"
- onset="this.setAttribute('disableautocomplete', val); return val;"
- onget="return this.getAttribute('disableautocomplete') == 'true';"/>
-
- <property name="completeDefaultIndex"
- onset="this.setAttribute('completedefaultindex', val); return val;"
- onget="return this.getAttribute('completedefaultindex') == 'true';"/>
-
- <property name="completeSelectedIndex"
- onset="this.setAttribute('completeselectedindex', val); return val;"
- onget="return this.getAttribute('completeselectedindex') == 'true';"/>
-
- <property name="forceComplete"
- onset="this.setAttribute('forcecomplete', val); return val;"
- onget="return this.getAttribute('forcecomplete') == 'true';"/>
-
- <property name="minResultsForPopup"
- onset="this.setAttribute('minresultsforpopup', val); return val;"
- onget="var m = parseInt(this.getAttribute('minresultsforpopup')); return isNaN(m) ? 1 : m;"/>
-
- <property name="showCommentColumn"
- onset="this.setAttribute('showcommentcolumn', val); return val;"
- onget="return this.getAttribute('showcommentcolumn') == 'true';"/>
-
- <property name="showImageColumn"
- onset="this.setAttribute('showimagecolumn', val); return val;"
- onget="return this.getAttribute('showimagecolumn') == 'true';"/>
-
- <property name="timeout"
- onset="this.setAttribute('timeout', val); return val;">
- <getter><![CDATA[
- // For security reasons delay searches on pasted values.
- if (this._valueIsPasted) {
- let t = parseInt(this.getAttribute('pastetimeout'));
- return isNaN(t) ? 1000 : t;
- }
-
- let t = parseInt(this.getAttribute('timeout'));
- return isNaN(t) ? 50 : t;
- ]]></getter>
- </property>
-
- <property name="searchParam"
- onget="return this.getAttribute('autocompletesearchparam') || '';"
- onset="this.setAttribute('autocompletesearchparam', val); return val;"/>
-
- <property name="searchCount" readonly="true"
- onget="this.initSearchNames(); return this.mSearchNames.length;"/>
-
- <field name="shrinkDelay" readonly="true">
- parseInt(this.getAttribute("shrinkdelay")) || 0
- </field>
-
- <field name="PrivateBrowsingUtils" readonly="true">
- {
- let utils = {};
- Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm", utils);
- utils.PrivateBrowsingUtils
- }
- </field>
-
- <property name="inPrivateContext" readonly="true"
- onget="return this.PrivateBrowsingUtils.isWindowPrivate(window);"/>
-
- <property name="noRollupOnCaretMove" readonly="true"
- onget="return this.popup.getAttribute('norolluponanchor') == 'true'"/>
-
- <!-- This is the maximum number of drop-down rows we get when we
- hit the drop marker beside fields that have it (like the URLbar).-->
- <field name="maxDropMarkerRows" readonly="true">14</field>
-
- <method name="getSearchAt">
- <parameter name="aIndex"/>
- <body><![CDATA[
- this.initSearchNames();
- return this.mSearchNames[aIndex];
- ]]></body>
- </method>
-
- <property name="textValue"
- onget="return this.value;">
- <setter><![CDATA[
- // Completing a result should simulate the user typing the result,
- // so fire an input event.
- // Trim popup selected values, but never trim results coming from
- // autofill.
- if (this.popup.selectedIndex == -1)
- this._disableTrim = true;
- this.value = val;
- this._disableTrim = false;
-
- var evt = document.createEvent("UIEvents");
- evt.initUIEvent("input", true, false, window, 0);
- this.mIgnoreInput = true;
- this.dispatchEvent(evt);
- this.mIgnoreInput = false;
- return this.value;
- ]]></setter>
- </property>
-
- <method name="selectTextRange">
- <parameter name="aStartIndex"/>
- <parameter name="aEndIndex"/>
- <body><![CDATA[
- this.inputField.setSelectionRange(aStartIndex, aEndIndex);
- ]]></body>
- </method>
-
- <method name="onSearchBegin">
- <body><![CDATA[
- if (this.popup && typeof this.popup.onSearchBegin == "function")
- this.popup.onSearchBegin();
- if (this._searchBeginHandler)
- this._searchBeginHandler();
- ]]></body>
- </method>
-
- <method name="onSearchComplete">
- <body><![CDATA[
- if (this.mController.matchCount == 0)
- this.setAttribute("nomatch", "true");
- else
- this.removeAttribute("nomatch");
-
- if (this.ignoreBlurWhileSearching && !this.focused) {
- this.handleEnter();
- this.detachController();
- }
-
- if (this._searchCompleteHandler)
- this._searchCompleteHandler();
- ]]></body>
- </method>
-
- <method name="onTextEntered">
- <body><![CDATA[
- let rv = false;
- if (this._textEnteredHandler)
- rv = this._textEnteredHandler(this.mEnterEvent);
- this.mEnterEvent = null;
- return rv;
- ]]></body>
- </method>
-
- <method name="onTextReverted">
- <body><![CDATA[
- if (this._textRevertedHandler)
- return this._textRevertedHandler();
- return false;
- ]]></body>
- </method>
-
- <!-- =================== nsIDOMXULMenuListElement =================== -->
-
- <property name="editable" readonly="true"
- onget="return true;" />
-
- <property name="crop"
- onset="this.setAttribute('crop',val); return val;"
- onget="return this.getAttribute('crop');"/>
-
- <property name="open"
- onget="return this.getAttribute('open') == 'true';">
- <setter><![CDATA[
- if (val)
- this.showHistoryPopup();
- else
- this.closePopup();
- ]]></setter>
- </property>
-
- <!-- =================== PUBLIC MEMBERS =================== -->
-
- <field name="valueIsTyped">false</field>
- <field name="_disableTrim">false</field>
- <property name="value">
- <getter><![CDATA[
- if (typeof this.onBeforeValueGet == "function") {
- var result = this.onBeforeValueGet();
- if (result)
- return result.value;
- }
- return this.inputField.value;
- ]]></getter>
- <setter><![CDATA[
- this.mIgnoreInput = true;
-
- if (typeof this.onBeforeValueSet == "function")
- val = this.onBeforeValueSet(val);
-
- if (typeof this.trimValue == "function" && !this._disableTrim)
- val = this.trimValue(val);
-
- this.valueIsTyped = false;
- this.inputField.value = val;
-
- if (typeof this.formatValue == "function")
- this.formatValue();
-
- this.mIgnoreInput = false;
- var event = document.createEvent('Events');
- event.initEvent('ValueChange', true, true);
- this.inputField.dispatchEvent(event);
- return val;
- ]]></setter>
- </property>
-
- <property name="focused" readonly="true"
- onget="return this.getAttribute('focused') == 'true';"/>
-
- <!-- maximum number of rows to display at a time -->
- <property name="maxRows"
- onset="this.setAttribute('maxrows', val); return val;"
- onget="return parseInt(this.getAttribute('maxrows')) || 0;"/>
-
- <!-- option to allow scrolling through the list via the tab key, rather than
- tab moving focus out of the textbox -->
- <property name="tabScrolling"
- onset="this.setAttribute('tabscrolling', val); return val;"
- onget="return this.getAttribute('tabscrolling') == 'true';"/>
-
- <!-- option to completely ignore any blur events while searches are
- still going on. -->
- <property name="ignoreBlurWhileSearching"
- onset="this.setAttribute('ignoreblurwhilesearching', val); return val;"
- onget="return this.getAttribute('ignoreblurwhilesearching') == 'true';"/>
-
- <!-- disable key navigation handling in the popup results -->
- <property name="disableKeyNavigation"
- onset="this.setAttribute('disablekeynavigation', val); return val;"
- onget="return this.getAttribute('disablekeynavigation') == 'true';"/>
-
- <!-- option to highlight entries that don't have any matches -->
- <property name="highlightNonMatches"
- onset="this.setAttribute('highlightnonmatches', val); return val;"
- onget="return this.getAttribute('highlightnonmatches') == 'true';"/>
-
- <!-- =================== PRIVATE MEMBERS =================== -->
-
- <!-- ::::::::::::: autocomplete controller ::::::::::::: -->
-
- <method name="attachController">
- <body><![CDATA[
- this.mController.input = this;
- ]]></body>
- </method>
-
- <method name="detachController">
- <body><![CDATA[
- if (this.mController.input == this)
- this.mController.input = null;
- ]]></body>
- </method>
-
- <!-- ::::::::::::: popup opening ::::::::::::: -->
-
- <method name="openPopup">
- <body><![CDATA[
- if (this.focused)
- this.popup.openAutocompletePopup(this, this);
- ]]></body>
- </method>
-
- <method name="closePopup">
- <body><![CDATA[
- this.popup.closePopup();
- ]]></body>
- </method>
-
- <method name="showHistoryPopup">
- <body><![CDATA[
- // history dropmarker pushed state
- function cleanup(popup) {
- popup.removeEventListener("popupshowing", onShow, false);
- }
- function onShow(event) {
- var popup = event.target, input = popup.input;
- cleanup(popup);
- input.setAttribute("open", "true");
- function onHide() {
- input.removeAttribute("open");
- popup.removeEventListener("popuphiding", onHide, false);
- }
- popup.addEventListener("popuphiding", onHide, false);
- }
- this.popup.addEventListener("popupshowing", onShow, false);
- setTimeout(cleanup, 1000, this.popup);
-
- // Store our "normal" maxRows on the popup, so that it can reset the
- // value when the popup is hidden.
- this.popup._normalMaxRows = this.maxRows;
-
- // Increase our maxRows temporarily, since we want the dropdown to
- // be bigger in this case. The popup's popupshowing/popuphiding
- // handlers will take care of resetting this.
- this.maxRows = this.maxDropMarkerRows;
-
- // Ensure that we have focus.
- if (!this.focused)
- this.focus();
- this.attachController();
- this.mController.startSearch("");
- ]]></body>
- </method>
-
- <method name="toggleHistoryPopup">
- <body><![CDATA[
- // If this method is called on the same event tick as the popup gets
- // hidden, do nothing to avoid re-opening the popup when the drop
- // marker is clicked while the popup is still open.
- if (!this.popup.isPopupHidingTick && !this.popup.popupOpen)
- this.showHistoryPopup();
- else
- this.closePopup();
- ]]></body>
- </method>
-
- <!-- ::::::::::::: event dispatching ::::::::::::: -->
-
- <method name="initEventHandler">
- <parameter name="aEventType"/>
- <body><![CDATA[
- let handlerString = this.getAttribute("on" + aEventType);
- if (handlerString) {
- return (new Function("eventType", "param", handlerString)).bind(this, aEventType);
- }
- return null;
- ]]></body>
- </method>
-
- <!-- ::::::::::::: key handling ::::::::::::: -->
-
- <field name="_selectionDetails">null</field>
- <method name="onKeyPress">
- <parameter name="aEvent"/>
- <body><![CDATA[
- return this.handleKeyPress(aEvent);
- ]]></body>
- </method>
-
- <method name="handleKeyPress">
- <parameter name="aEvent"/>
- <body><![CDATA[
- if (aEvent.target.localName != "textbox")
- return true; // Let child buttons of autocomplete take input
-
- //XXXpch this is so bogus...
- if (aEvent.defaultPrevented)
- return false;
-
- var cancel = false;
-
- let { AppConstants } =
- Components.utils.import("resource://gre/modules/AppConstants.jsm", {});
- // Catch any keys that could potentially move the caret. Ctrl can be
- // used in combination with these keys on Windows and Linux; and Alt
- // can be used on OS X, so make sure the unused one isn't used.
- let metaKey = AppConstants.platform == "macosx" ? aEvent.ctrlKey : aEvent.altKey;
- if (!this.disableKeyNavigation && !metaKey) {
- switch (aEvent.keyCode) {
- case KeyEvent.DOM_VK_LEFT:
- case KeyEvent.DOM_VK_RIGHT:
- case KeyEvent.DOM_VK_HOME:
- cancel = this.mController.handleKeyNavigation(aEvent.keyCode);
- break;
- }
- }
-
- // Handle keys that are not part of a keyboard shortcut (no Ctrl or Alt)
- if (!this.disableKeyNavigation && !aEvent.ctrlKey && !aEvent.altKey) {
- switch (aEvent.keyCode) {
- case KeyEvent.DOM_VK_TAB:
- if (this.tabScrolling && this.popup.popupOpen)
- cancel = this.mController.handleKeyNavigation(aEvent.shiftKey ?
- KeyEvent.DOM_VK_UP :
- KeyEvent.DOM_VK_DOWN);
- else if (this.forceComplete && this.mController.matchCount >= 1)
- this.mController.handleTab();
- break;
- case KeyEvent.DOM_VK_UP:
- case KeyEvent.DOM_VK_DOWN:
- case KeyEvent.DOM_VK_PAGE_UP:
- case KeyEvent.DOM_VK_PAGE_DOWN:
- cancel = this.mController.handleKeyNavigation(aEvent.keyCode);
- break;
- }
- }
-
- // Handle keys we know aren't part of a shortcut, even with Alt or
- // Ctrl.
- switch (aEvent.keyCode) {
- case KeyEvent.DOM_VK_ESCAPE:
- cancel = this.mController.handleEscape();
- break;
- case KeyEvent.DOM_VK_RETURN:
- if (AppConstants.platform == "macosx") {
- // Prevent the default action, since it will beep on Mac
- if (aEvent.metaKey)
- aEvent.preventDefault();
- }
- this.mEnterEvent = aEvent;
- if (this.mController.selection) {
- this._selectionDetails = {
- index: this.mController.selection.currentIndex,
- kind: "key"
- };
- }
- cancel = this.handleEnter();
- break;
- case KeyEvent.DOM_VK_DELETE:
- if (AppConstants.platform == "macosx" && !aEvent.shiftKey) {
- break;
- }
- cancel = this.handleDelete();
- break;
- case KeyEvent.DOM_VK_BACK_SPACE:
- if (AppConstants.platform == "macosx" && aEvent.shiftKey) {
- cancel = this.handleDelete();
- }
- break;
- case KeyEvent.DOM_VK_DOWN:
- case KeyEvent.DOM_VK_UP:
- if (aEvent.altKey)
- this.toggleHistoryPopup();
- break;
- case KeyEvent.DOM_VK_F4:
- if (AppConstants.platform != "macosx") {
- this.toggleHistoryPopup();
- }
- break;
- }
-
- if (cancel) {
- aEvent.stopPropagation();
- aEvent.preventDefault();
- }
-
- return true;
- ]]></body>
- </method>
-
- <method name="handleEnter">
- <body><![CDATA[
- return this.mController.handleEnter(false);
- ]]></body>
- </method>
-
- <method name="handleDelete">
- <body><![CDATA[
- return this.mController.handleDelete();
- ]]></body>
- </method>
-
- <!-- ::::::::::::: miscellaneous ::::::::::::: -->
-
- <method name="initSearchNames">
- <body><![CDATA[
- if (!this.mSearchNames) {
- var names = this.getAttribute("autocompletesearch");
- if (!names)
- this.mSearchNames = [];
- else
- this.mSearchNames = names.split(" ");
- }
- ]]></body>
- </method>
-
- <method name="_focus">
- <!-- doesn't reset this.mController -->
- <body><![CDATA[
- this._dontBlur = true;
- this.focus();
- this._dontBlur = false;
- ]]></body>
- </method>
-
- <method name="resetActionType">
- <body><![CDATA[
- if (this.mIgnoreInput)
- return;
- this.removeAttribute("actiontype");
- ]]></body>
- </method>
-
- <field name="_valueIsPasted">false</field>
- <field name="_pasteController"><![CDATA[
- ({
- _autocomplete: this,
- _kGlobalClipboard: Components.interfaces.nsIClipboard.kGlobalClipboard,
- supportsCommand: aCommand => aCommand == "cmd_paste",
- doCommand: function(aCommand) {
- this._autocomplete._valueIsPasted = true;
- this._autocomplete.editor.paste(this._kGlobalClipboard);
- this._autocomplete._valueIsPasted = false;
- },
- isCommandEnabled: function(aCommand) {
- return this._autocomplete.editor.isSelectionEditable &&
- this._autocomplete.editor.canPaste(this._kGlobalClipboard);
- },
- onEvent: function() {}
- })
- ]]></field>
-
- <method name="onInput">
- <parameter name="aEvent"/>
- <body><![CDATA[
- if (!this.mIgnoreInput && this.mController.input == this) {
- this.valueIsTyped = true;
- this.mController.handleText();
- }
- this.resetActionType();
- ]]></body>
- </method>
- </implementation>
-
- <handlers>
- <handler event="input"><![CDATA[
- this.onInput(event);
- ]]></handler>
-
- <handler event="keypress" phase="capturing"
- action="return this.onKeyPress(event);"/>
-
- <handler event="compositionstart" phase="capturing"
- action="if (this.mController.input == this) this.mController.handleStartComposition();"/>
-
- <handler event="compositionend" phase="capturing"
- action="if (this.mController.input == this) this.mController.handleEndComposition();"/>
-
- <handler event="focus" phase="capturing"
- action="this.attachController();"/>
-
- <handler event="blur" phase="capturing"><![CDATA[
- if (!this._dontBlur) {
- if (this.forceComplete && this.mController.matchCount >= 1) {
- // mousemove sets selected index. Don't blindly use that selected
- // index in this blur handler since if the popup is open you can
- // easily "select" another match just by moving the mouse over it.
- let filledVal = this.value.replace(/.+ >> /, "").toLowerCase();
- let selectedVal = null;
- if (this.popup.selectedIndex >= 0) {
- selectedVal = this.mController.getFinalCompleteValueAt(
- this.popup.selectedIndex);
- }
- if (selectedVal && filledVal != selectedVal.toLowerCase()) {
- for (let i = 0; i < this.mController.matchCount; i++) {
- let matchVal = this.mController.getFinalCompleteValueAt(i);
- if (matchVal.toLowerCase() == filledVal) {
- this.popup.selectedIndex = i;
- break;
- }
- }
- }
- this.mController.handleEnter(false);
- }
- if (!this.ignoreBlurWhileSearching)
- this.detachController();
- }
- ]]></handler>
- </handlers>
- </binding>
-
- <binding id="private-autocomplete-result-popup" extends="chrome://browser/content/autocomplete.xml#private-autocomplete-base-popup">
- <resources>
- <stylesheet src="chrome://browser/content/autocomplete.css"/>
- <stylesheet src="chrome://global/skin/tree.css"/>
- <stylesheet src="chrome://browser/skin/autocomplete.css"/>
- </resources>
-
- <content ignorekeys="true" level="top" consumeoutsideclicks="never">
- <xul:tree anonid="tree" class="private-autocomplete-tree plain" hidecolumnpicker="true" flex="1" seltype="single">
- <xul:treecols anonid="treecols">
- <xul:treecol id="treecolAutoCompleteValue" class="private-autocomplete-treecol" flex="1" overflow="true"/>
- </xul:treecols>
- <xul:treechildren class="private-autocomplete-treebody"/>
- </xul:tree>
- </content>
-
- <implementation>
- <field name="mShowCommentColumn">false</field>
- <field name="mShowImageColumn">false</field>
-
- <property name="showCommentColumn"
- onget="return this.mShowCommentColumn;">
- <setter>
- <![CDATA[
- if (!val && this.mShowCommentColumn) {
- // reset the flex on the value column and remove the comment column
- document.getElementById("treecolAutoCompleteValue").setAttribute("flex", 1);
- this.removeColumn("treecolAutoCompleteComment");
- } else if (val && !this.mShowCommentColumn) {
- // reset the flex on the value column and add the comment column
- document.getElementById("treecolAutoCompleteValue").setAttribute("flex", 2);
- this.addColumn({id: "treecolAutoCompleteComment", flex: 1});
- }
- this.mShowCommentColumn = val;
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="showImageColumn"
- onget="return this.mShowImageColumn;">
- <setter>
- <![CDATA[
- if (!val && this.mShowImageColumn) {
- // remove the image column
- this.removeColumn("treecolAutoCompleteImage");
- } else if (val && !this.mShowImageColumn) {
- // add the image column
- this.addColumn({id: "treecolAutoCompleteImage", flex: 1});
- }
- this.mShowImageColumn = val;
- return val;
- ]]>
- </setter>
- </property>
-
-
- <method name="addColumn">
- <parameter name="aAttrs"/>
- <body>
- <![CDATA[
- var col = document.createElement("treecol");
- col.setAttribute("class", "private-autocomplete-treecol");
- for (var name in aAttrs)
- col.setAttribute(name, aAttrs[name]);
- this.treecols.appendChild(col);
- return col;
- ]]>
- </body>
- </method>
-
- <method name="removeColumn">
- <parameter name="aColId"/>
- <body>
- <![CDATA[
- return this.treecols.removeChild(document.getElementById(aColId));
- ]]>
- </body>
- </method>
-
- <property name="selectedIndex"
- onget="return this.tree.currentIndex;">
- <setter>
- <![CDATA[
- this.tree.view.selection.select(val);
- if (this.tree.treeBoxObject.height > 0)
- this.tree.treeBoxObject.ensureRowIsVisible(val < 0 ? 0 : val);
- // Fire select event on xul:tree so that accessibility API
- // support layer can fire appropriate accessibility events.
- var event = document.createEvent('Events');
- event.initEvent("select", true, true);
- this.tree.dispatchEvent(event);
- return val;
- ]]></setter>
- </property>
-
- <method name="adjustHeight">
- <body>
- <![CDATA[
- // detect the desired height of the tree
- var bx = this.tree.treeBoxObject;
- var view = this.tree.view;
- if (!view)
- return;
- var rows = this.maxRows;
- if (!view.rowCount || (rows && view.rowCount < rows))
- rows = view.rowCount;
-
- var height = rows * bx.rowHeight;
-
- if (height == 0) {
- this.tree.setAttribute("collapsed", "true");
- } else {
- if (this.tree.hasAttribute("collapsed"))
- this.tree.removeAttribute("collapsed");
-
- this.tree.setAttribute("height", height);
- }
- this.tree.setAttribute("hidescrollbar", view.rowCount <= rows);
- ]]>
- </body>
- </method>
-
- <method name="openAutocompletePopup">
- <parameter name="aInput"/>
- <parameter name="aElement"/>
- <body><![CDATA[
- // until we have "baseBinding", (see bug #373652) this allows
- // us to override openAutocompletePopup(), but still call
- // the method on the base class
- this._openAutocompletePopup(aInput, aElement);
- ]]></body>
- </method>
-
- <method name="_openAutocompletePopup">
- <parameter name="aInput"/>
- <parameter name="aElement"/>
- <body><![CDATA[
- if (!this.mPopupOpen) {
- this.mInput = aInput;
- this.view = aInput.controller.QueryInterface(Components.interfaces.nsITreeView);
- this.invalidate();
-
- this.showCommentColumn = this.mInput.showCommentColumn;
- this.showImageColumn = this.mInput.showImageColumn;
-
- var rect = aElement.getBoundingClientRect();
- var nav = aElement.ownerDocument.defaultView.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIWebNavigation);
- var docShell = nav.QueryInterface(Components.interfaces.nsIDocShell);
- var docViewer = docShell.contentViewer;
- var width = (rect.right - rect.left) * docViewer.fullZoom;
- this.setAttribute("width", width > 100 ? width : 100);
-
- // Adjust the direction of the autocomplete popup list based on the textbox direction, bug 649840
- var popupDirection = aElement.ownerDocument.defaultView.getComputedStyle(aElement).direction;
- this.style.direction = popupDirection;
-
- this.openPopup(aElement, "after_start", 0, 0, false, false);
- }
- ]]></body>
- </method>
-
- <method name="invalidate">
- <body><![CDATA[
- this.adjustHeight();
- this.tree.treeBoxObject.invalidate();
- ]]></body>
- </method>
-
- <method name="selectBy">
- <parameter name="aReverse"/>
- <parameter name="aPage"/>
- <body><![CDATA[
- try {
- var amount = aPage ? 5 : 1;
- this.selectedIndex = this.getNextIndex(aReverse, amount, this.selectedIndex, this.tree.view.rowCount-1);
- if (this.selectedIndex == -1) {
- this.input._focus();
- }
- } catch (ex) {
- // do nothing - occasionally timer-related js errors happen here
- // e.g. "this.selectedIndex has no properties", when you type fast and hit a
- // navigation key before this popup has opened
- }
- ]]></body>
- </method>
-
- <!-- =================== PUBLIC MEMBERS =================== -->
-
- <field name="tree">
- document.getAnonymousElementByAttribute(this, "anonid", "tree");
- </field>
-
- <field name="treecols">
- document.getAnonymousElementByAttribute(this, "anonid", "treecols");
- </field>
-
- <property name="view"
- onget="return this.mView;">
- <setter><![CDATA[
- // We must do this by hand because the tree binding may not be ready yet
- this.mView = val;
- this.tree.boxObject.view = val;
- ]]></setter>
- </property>
-
- </implementation>
- </binding>
-
- <binding id="private-autocomplete-base-popup" role="none"
-extends="chrome://global/content/bindings/popup.xml#popup">
- <implementation implements="nsIAutoCompletePopup">
- <field name="mInput">null</field>
- <field name="mPopupOpen">false</field>
- <field name="mIsPopupHidingTick">false</field>
-
- <!-- =================== nsIAutoCompletePopup =================== -->
-
- <property name="input" readonly="true"
- onget="return this.mInput"/>
-
- <property name="overrideValue" readonly="true"
- onget="return null;"/>
-
- <property name="popupOpen" readonly="true"
- onget="return this.mPopupOpen;"/>
-
- <property name="isPopupHidingTick" readonly="true"
- onget="return this.mIsPopupHidingTick;"/>
-
- <method name="closePopup">
- <body>
- <![CDATA[
- if (this.mPopupOpen) {
- this.hidePopup();
- this.removeAttribute("width");
- }
- ]]>
- </body>
- </method>
-
- <!-- This is the default number of rows that we give the autocomplete
- popup when the textbox doesn't have a "maxrows" attribute
- for us to use. -->
- <field name="defaultMaxRows" readonly="true">6</field>
-
- <!-- In some cases (e.g. when the input's dropmarker button is clicked),
- the input wants to display a popup with more rows. In that case, it
- should increase its maxRows property and store the "normal" maxRows
- in this field. When the popup is hidden, we restore the input's
- maxRows to the value stored in this field.
-
- This field is set to -1 between uses so that we can tell when it's
- been set by the input and when we need to set it in the popupshowing
- handler. -->
- <field name="_normalMaxRows">-1</field>
-
- <property name="maxRows" readonly="true">
- <getter>
- <![CDATA[
- return (this.mInput && this.mInput.maxRows) || this.defaultMaxRows;
- ]]>
- </getter>
- </property>
-
- <method name="getNextIndex">
- <parameter name="aReverse"/>
- <parameter name="aAmount"/>
- <parameter name="aIndex"/>
- <parameter name="aMaxRow"/>
- <body><![CDATA[
- if (aMaxRow < 0)
- return -1;
-
- var newIdx = aIndex + (aReverse?-1:1)*aAmount;
- if (aReverse && aIndex == -1 || newIdx > aMaxRow && aIndex != aMaxRow)
- newIdx = aMaxRow;
- else if (!aReverse && aIndex == -1 || newIdx < 0 && aIndex != 0)
- newIdx = 0;
-
- if (newIdx < 0 && aIndex == 0 || newIdx > aMaxRow && aIndex == aMaxRow)
- aIndex = -1;
- else
- aIndex = newIdx;
-
- return aIndex;
- ]]></body>
- </method>
-
- <method name="onPopupClick">
- <parameter name="aEvent"/>
- <body><![CDATA[
- var controller = this.view.QueryInterface(Components.interfaces.nsIAutoCompleteController);
- controller.handleEnter(true);
- ]]></body>
- </method>
- </implementation>
-
- <handlers>
- <handler event="popupshowing"><![CDATA[
- // If normalMaxRows wasn't already set by the input, then set it here
- // so that we restore the correct number when the popup is hidden.
-
- // Null-check this.mInput; see bug 1017914
- if (this._normalMaxRows < 0 && this.mInput) {
- this._normalMaxRows = this.mInput.maxRows;
- }
-
- // Set an attribute for styling the popup based on the input.
- let inputID = "";
- if (this.mInput && this.mInput.ownerDocument &&
- this.mInput.ownerDocument.documentURIObject.schemeIs("chrome")) {
- inputID = this.mInput.id;
- // Take care of elements with no id that are inside xbl bindings
- if (!inputID) {
- let bindingParent = this.mInput.ownerDocument.getBindingParent(this.mInput);
- if (bindingParent) {
- inputID = bindingParent.id;
- }
- }
- }
- this.setAttribute("autocompleteinput", inputID);
-
- this.mPopupOpen = true;
- ]]></handler>
-
- <handler event="popuphiding"><![CDATA[
- var isListActive = true;
- if (this.selectedIndex == -1)
- isListActive = false;
- var controller = this.view.QueryInterface(Components.interfaces.nsIAutoCompleteController);
- controller.stopSearch();
-
- this.removeAttribute("autocompleteinput");
- this.mPopupOpen = false;
-
- // Prevent opening popup from historydropmarker mousedown handler
- // on the same event tick the popup is hidden by the same mousedown
- // event.
- this.mIsPopupHidingTick = true;
- setTimeout(() => {
- this.mIsPopupHidingTick = false;
- }, 0);
-
- // Reset the maxRows property to the cached "normal" value, and reset
- // _normalMaxRows so that we can detect whether it was set by the input
- // when the popupshowing handler runs.
-
- // Null-check this.mInput; see bug 1017914
- if (this.mInput)
- this.mInput.maxRows = this._normalMaxRows;
- this._normalMaxRows = -1;
- // If the list was being navigated and then closed, make sure
- // we fire accessible focus event back to textbox
-
- // Null-check this.mInput; see bug 1017914
- if (isListActive && this.mInput) {
- this.mInput.mIgnoreFocus = true;
- this.mInput._focus();
- this.mInput.mIgnoreFocus = false;
- }
- ]]></handler>
- </handlers>
- </binding>
-
- <binding id="private-autocomplete-rich-result-popup" extends="chrome://browser/content/autocomplete.xml#private-autocomplete-base-popup">
- <resources>
- <stylesheet src="chrome://browser/content/autocomplete.css"/>
- <stylesheet src="chrome://browser/skin/autocomplete.css"/>
- </resources>
-
- <content ignorekeys="true" level="top" consumeoutsideclicks="never">
- <xul:richlistbox anonid="richlistbox" class="private-autocomplete-richlistbox" flex="1"/>
- <xul:hbox>
- <children/>
- </xul:hbox>
- </content>
-
- <implementation implements="nsIAutoCompletePopup">
- <field name="_currentIndex">0</field>
- <field name="_rowHeight">0</field>
- <field name="_rlbAnimated">false</field>
-
- <!-- =================== nsIAutoCompletePopup =================== -->
-
- <property name="selectedIndex"
- onget="return this.richlistbox.selectedIndex;">
- <setter>
- <![CDATA[
- this.richlistbox.selectedIndex = val;
-
- // when clearing the selection (val == -1, so selectedItem will be
- // null), we want to scroll back to the top. see bug #406194
- this.richlistbox.ensureElementIsVisible(
- this.richlistbox.selectedItem || this.richlistbox.firstChild);
-
- return val;
- ]]>
- </setter>
- </property>
-
- <method name="onSearchBegin">
- <body><![CDATA[
- this.richlistbox.mouseSelectedIndex = -1;
- ]]></body>
- </method>
-
- <method name="openAutocompletePopup">
- <parameter name="aInput"/>
- <parameter name="aElement"/>
- <body>
- <![CDATA[
- // until we have "baseBinding", (see bug #373652) this allows
- // us to override openAutocompletePopup(), but still call
- // the method on the base class
- this._openAutocompletePopup(aInput, aElement);
- ]]>
- </body>
- </method>
-
- <method name="_openAutocompletePopup">
- <parameter name="aInput"/>
- <parameter name="aElement"/>
- <body>
- <![CDATA[
- if (!this.mPopupOpen) {
- this.mInput = aInput;
- // clear any previous selection, see bugs 400671 and 488357
- this.selectedIndex = -1;
-
- var width = aElement.getBoundingClientRect().width;
- this.setAttribute("width", width > 100 ? width : 100);
- // invalidate() depends on the width attribute
- this._invalidate();
-
- this.openPopup(aElement, "after_start", 0, 0, false, false);
- }
- ]]>
- </body>
- </method>
-
- <method name="invalidate">
- <parameter name="reason"/>
- <body>
- <![CDATA[
- // Don't bother doing work if we're not even showing
- if (!this.mPopupOpen)
- return;
-
- this._invalidate(reason);
- ]]>
- </body>
- </method>
-
- <method name="_invalidate">
- <parameter name="reason"/>
- <body>
- <![CDATA[
- // collapsed if no matches
- this.richlistbox.collapsed = (this._matchCount == 0);
-
- // Update the richlistbox height.
- if (this._adjustHeightTimeout) {
- clearTimeout(this._adjustHeightTimeout);
- }
- if (this._shrinkTimeout) {
- clearTimeout(this._shrinkTimeout);
- }
- this._adjustHeightTimeout = setTimeout(() => this.adjustHeight(), 0);
-
- this._currentIndex = 0;
- if (this._appendResultTimeout) {
- clearTimeout(this._appendResultTimeout);
- }
- this._appendCurrentResult(reason);
- ]]>
- </body>
- </method>
-
- <property name="maxResults" readonly="true">
- <getter>
- <![CDATA[
- // this is how many richlistitems will be kept around
- // (note, this getter may be overridden)
- return 20;
- ]]>
- </getter>
- </property>
-
- <property name="_matchCount" readonly="true">
- <getter>
- <![CDATA[
- return Math.min(this.mInput.controller.matchCount, this.maxResults);
- ]]>
- </getter>
- </property>
-
- <method name="_collapseUnusedItems">
- <body>
- <![CDATA[
- let existingItemsCount = this.richlistbox.childNodes.length;
- for (let i = this._matchCount; i < existingItemsCount; ++i) {
- this.richlistbox.childNodes[i].collapsed = true;
- }
- ]]>
- </body>
- </method>
-
- <method name="adjustHeight">
- <body>
- <![CDATA[
- // Figure out how many rows to show
- let rows = this.richlistbox.childNodes;
- let numRows = Math.min(this._matchCount, this.maxRows, rows.length);
-
- this.removeAttribute("height");
-
- // Default the height to 0 if we have no rows to show
- let height = 0;
- if (numRows) {
- if (!this._rowHeight) {
- let firstRowRect = rows[0].getBoundingClientRect();
- this._rowHeight = firstRowRect.height;
-
- let transition =
- window.getComputedStyle(this.richlistbox).transitionProperty;
- this._rlbAnimated = transition && transition != "none";
-
- // Set a fixed max-height to avoid flicker when growing the panel.
- this.richlistbox.style.maxHeight = (this._rowHeight * this.maxRows) + "px";
- }
-
- // Calculate the height to have the first row to last row shown
- height = this._rowHeight * numRows;
- }
-
- let animate = this._rlbAnimated &&
- this.getAttribute("dontanimate") != "true";
- let currentHeight = this.richlistbox.getBoundingClientRect().height;
- if (height > currentHeight) {
- // Grow immediately.
- if (animate) {
- this.richlistbox.removeAttribute("height");
- this.richlistbox.style.height = height + "px";
- } else {
- this.richlistbox.style.removeProperty("height");
- this.richlistbox.height = height;
- }
- } else {
- // Delay shrinking to avoid flicker.
- this._shrinkTimeout = setTimeout(() => {
- this._collapseUnusedItems();
- if (animate) {
- this.richlistbox.removeAttribute("height");
- this.richlistbox.style.height = height + "px";
- } else {
- this.richlistbox.style.removeProperty("height");
- this.richlistbox.height = height;
- }
- }, this.mInput.shrinkDelay);
- }
- ]]>
- </body>
- </method>
-
- <method name="_appendCurrentResult">
- <parameter name="invalidateReason"/>
- <body>
- <![CDATA[
- var controller = this.mInput.controller;
- var matchCount = this._matchCount;
- var existingItemsCount = this.richlistbox.childNodes.length;
-
- // Process maxRows per chunk to improve performance and user experience
- for (let i = 0; i < this.maxRows; i++) {
- if (this._currentIndex >= matchCount)
- break;
-
- var item;
-
- // trim the leading/trailing whitespace
- var trimmedSearchString = controller.searchString.replace(/^\s+/, "").replace(/\s+$/, "");
-
- let url = controller.getValueAt(this._currentIndex);
-
- if (this._currentIndex < existingItemsCount) {
- // re-use the existing item
- item = this.richlistbox.childNodes[this._currentIndex];
-
- // Completely reuse the existing richlistitem for invalidation
- // due to new results, but only when: the item is the same, *OR*
- // we are about to replace the currently mouse-selected item, to
- // avoid surprising the user.
- let iface = Components.interfaces.nsIAutoCompletePopup;
- if (item.getAttribute("text") == trimmedSearchString &&
- invalidateReason == iface.INVALIDATE_REASON_NEW_RESULT &&
- (item.getAttribute("url") == url ||
- this.richlistbox.mouseSelectedIndex === this._currentIndex)) {
- item.collapsed = false;
- this._currentIndex++;
- continue;
- }
- }
- else {
- // need to create a new item
- item = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "richlistitem");
- }
-
- // set these attributes before we set the class
- // so that we can use them from the constructor
- let iconURI = controller.getImageAt(this._currentIndex);
- item.setAttribute("image", iconURI);
- item.setAttribute("url", url);
- item.setAttribute("title", controller.getCommentAt(this._currentIndex));
- item.setAttribute("type", controller.getStyleAt(this._currentIndex));
- item.setAttribute("text", trimmedSearchString);
-
- if (this._currentIndex < existingItemsCount) {
- // re-use the existing item
- item._adjustAcItem();
- item.collapsed = false;
- }
- else {
- // set the class at the end so we can use the attributes
- // in the xbl constructor
- item.className = "private-autocomplete-richlistitem";
- this.richlistbox.appendChild(item);
- }
-
- this._currentIndex++;
- }
-
- if (typeof this.onResultsAdded == "function")
- this.onResultsAdded();
-
- if (this._currentIndex < matchCount) {
- // yield after each batch of items so that typing the url bar is
- // responsive
- this._appendResultTimeout = setTimeout(() => this._appendCurrentResult(), 0);
- }
- ]]>
- </body>
- </method>
-
- <method name="selectBy">
- <parameter name="aReverse"/>
- <parameter name="aPage"/>
- <body>
- <![CDATA[
- try {
- var amount = aPage ? 5 : 1;
-
- // because we collapsed unused items, we can't use this.richlistbox.getRowCount(), we need to use the matchCount
- this.selectedIndex = this.getNextIndex(aReverse, amount, this.selectedIndex, this._matchCount - 1);
- if (this.selectedIndex == -1) {
- this.input._focus();
- }
- } catch (ex) {
- // do nothing - occasionally timer-related js errors happen here
- // e.g. "this.selectedIndex has no properties", when you type fast and hit a
- // navigation key before this popup has opened
- }
- ]]>
- </body>
- </method>
-
- <field name="richlistbox">
- document.getAnonymousElementByAttribute(this, "anonid", "richlistbox");
- </field>
-
- <property name="view"
- onget="return this.mInput.controller;"
- onset="return val;"/>
-
- </implementation>
- </binding>
-
- <binding id="private-autocomplete-richlistitem" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
- <content>
- <xul:hbox align="center" class="ac-title-box">
- <xul:image xbl:inherits="src=image" class="ac-site-icon"/>
- <xul:hbox anonid="title-box" class="ac-title" flex="1"
- onunderflow="_doUnderflow('_title');"
- onoverflow="_doOverflow('_title');">
- <xul:description anonid="title" class="ac-normal-text ac-comment" xbl:inherits="selected"/>
- </xul:hbox>
- <xul:label anonid="title-overflow-ellipsis" xbl:inherits="selected"
- class="ac-ellipsis-after ac-comment"/>
- <xul:hbox anonid="extra-box" class="ac-extra" align="center" hidden="true">
- <xul:image class="ac-result-type-tag"/>
- <xul:label class="ac-normal-text ac-comment" xbl:inherits="selected" value=":"/>
- <xul:description anonid="extra" class="ac-normal-text ac-comment" xbl:inherits="selected"/>
- </xul:hbox>
- <xul:image anonid="type-image" class="ac-type-icon" xbl:inherits="selected"/>
- </xul:hbox>
- <xul:hbox align="center" class="ac-url-box">
- <xul:spacer class="ac-site-icon"/>
- <xul:image class="ac-action-icon"/>
- <xul:hbox anonid="url-box" class="ac-url" flex="1"
- onunderflow="_doUnderflow('_url');"
- onoverflow="_doOverflow('_url');">
- <xul:description anonid="url" class="ac-normal-text ac-url-text"
- xbl:inherits="selected type"/>
- <xul:description anonid="action" class="ac-normal-text ac-action-text"
- xbl:inherits="selected type"/>
- </xul:hbox>
- <xul:label anonid="url-overflow-ellipsis" xbl:inherits="selected"
- class="ac-ellipsis-after ac-url-text"/>
- <xul:spacer class="ac-type-icon"/>
- </xul:hbox>
- </content>
- <implementation implements="nsIDOMXULSelectControlItemElement">
- <constructor>
- <![CDATA[
- let ellipsis = "\u2026";
- try {
- ellipsis = Components.classes["@mozilla.org/preferences-service;1"].
- getService(Components.interfaces.nsIPrefBranch).
- getComplexValue("intl.ellipsis",
- Components.interfaces.nsIPrefLocalizedString).data;
- } catch (ex) {
- // Do nothing.. we already have a default
- }
-
- this._urlOverflowEllipsis = document.getAnonymousElementByAttribute(this, "anonid", "url-overflow-ellipsis");
- this._titleOverflowEllipsis = document.getAnonymousElementByAttribute(this, "anonid", "title-overflow-ellipsis");
-
- this._urlOverflowEllipsis.value = ellipsis;
- this._titleOverflowEllipsis.value = ellipsis;
-
- this._typeImage = document.getAnonymousElementByAttribute(this, "anonid", "type-image");
-
- this._urlBox = document.getAnonymousElementByAttribute(this, "anonid", "url-box");
- this._url = document.getAnonymousElementByAttribute(this, "anonid", "url");
- this._action = document.getAnonymousElementByAttribute(this, "anonid", "action");
-
- this._titleBox = document.getAnonymousElementByAttribute(this, "anonid", "title-box");
- this._title = document.getAnonymousElementByAttribute(this, "anonid", "title");
-
- this._extraBox = document.getAnonymousElementByAttribute(this, "anonid", "extra-box");
- this._extra = document.getAnonymousElementByAttribute(this, "anonid", "extra");
-
- this._adjustAcItem();
- ]]>
- </constructor>
-
- <property name="label" readonly="true">
- <getter>
- <![CDATA[
- // This property is a string that is read aloud by screen readers,
- // so it must not contain anything that should not be user-facing.
-
- let parts = [
- this.getAttribute("title"),
- this.getAttribute("displayurl"),
- ];
- let label = parts.filter(str => str).join(" ")
-
- // allow consumers that have extended popups to override
- // the label values for the richlistitems
- let panel = this.parentNode.parentNode;
- if (panel.createResultLabel) {
- return panel.createResultLabel(this, label);
- }
-
- return label;
- ]]>
- </getter>
- </property>
-
- <property name="_stringBundle">
- <getter><![CDATA[
- if (!this.__stringBundle) {
- this.__stringBundle = Services.strings.createBundle("chrome://global/locale/autocomplete.properties");
- }
- return this.__stringBundle;
- ]]></getter>
- </property>
-
- <field name="_boundaryCutoff">null</field>
-
- <property name="boundaryCutoff" readonly="true">
- <getter>
- <![CDATA[
- if (!this._boundaryCutoff) {
- this._boundaryCutoff =
- Components.classes["@mozilla.org/preferences-service;1"].
- getService(Components.interfaces.nsIPrefBranch).
- getIntPref("toolkit.autocomplete.richBoundaryCutoff");
- }
- return this._boundaryCutoff;
- ]]>
- </getter>
- </property>
-
- <method name="_getBoundaryIndices">
- <parameter name="aText"/>
- <parameter name="aSearchTokens"/>
- <body>
- <![CDATA[
- // Short circuit for empty search ([""] == "")
- if (aSearchTokens == "")
- return [0, aText.length];
-
- // Find which regions of text match the search terms
- let regions = [];
- for (let search of Array.prototype.slice.call(aSearchTokens)) {
- let matchIndex = -1;
- let searchLen = search.length;
-
- // Find all matches of the search terms, but stop early for perf
- let lowerText = aText.substr(0, this.boundaryCutoff).toLowerCase();
- while ((matchIndex = lowerText.indexOf(search, matchIndex + 1)) >= 0) {
- regions.push([matchIndex, matchIndex + searchLen]);
- }
- }
-
- // Sort the regions by start position then end position
- regions = regions.sort((a, b) => {
- let start = a[0] - b[0];
- return (start == 0) ? a[1] - b[1] : start;
- });
-
- // Generate the boundary indices from each region
- let start = 0;
- let end = 0;
- let boundaries = [];
- let len = regions.length;
- for (let i = 0; i < len; i++) {
- // We have a new boundary if the start of the next is past the end
- let region = regions[i];
- if (region[0] > end) {
- // First index is the beginning of match
- boundaries.push(start);
- // Second index is the beginning of non-match
- boundaries.push(end);
-
- // Track the new region now that we've stored the previous one
- start = region[0];
- }
-
- // Push back the end index for the current or new region
- end = Math.max(end, region[1]);
- }
-
- // Add the last region
- boundaries.push(start);
- boundaries.push(end);
-
- // Put on the end boundary if necessary
- if (end < aText.length)
- boundaries.push(aText.length);
-
- // Skip the first item because it's always 0
- return boundaries.slice(1);
- ]]>
- </body>
- </method>
-
- <method name="_getSearchTokens">
- <parameter name="aSearch"/>
- <body>
- <![CDATA[
- let search = aSearch.toLowerCase();
- return search.split(/\s+/);
- ]]>
- </body>
- </method>
-
- <method name="_setUpDescription">
- <parameter name="aDescriptionElement"/>
- <parameter name="aText"/>
- <parameter name="aNoEmphasis"/>
- <body>
- <![CDATA[
- // Get rid of all previous text
- while (aDescriptionElement.hasChildNodes())
- aDescriptionElement.removeChild(aDescriptionElement.firstChild);
-
- // If aNoEmphasis is specified, don't add any emphasis
- if (aNoEmphasis) {
- aDescriptionElement.appendChild(document.createTextNode(aText));
- return;
- }
-
- // Get the indices that separate match and non-match text
- let search = this.getAttribute("text");
- let tokens = this._getSearchTokens(search);
- let indices = this._getBoundaryIndices(aText, tokens);
-
- let next;
- let start = 0;
- let len = indices.length;
- // Even indexed boundaries are matches, so skip the 0th if it's empty
- for (let i = indices[0] == 0 ? 1 : 0; i < len; i++) {
- next = indices[i];
- let text = aText.substr(start, next - start);
- start = next;
-
- if (i % 2 == 0) {
- // Emphasize the text for even indices
- let span = aDescriptionElement.appendChild(
- document.createElementNS("http://www.w3.org/1999/xhtml", "span"));
- span.className = "ac-emphasize-text";
- span.textContent = text;
- } else {
- // Otherwise, it's plain text
- aDescriptionElement.appendChild(document.createTextNode(text));
- }
- }
- ]]>
- </body>
- </method>
-
- <!--
- This will generate an array of emphasis pairs for use with
- _setUpEmphasisedSections(). Each pair is a tuple (array) that
- represents a block of text - containing the text of that block, and a
- boolean for whether that block should have an emphasis styling applied
- to it.
-
- These pairs are generated by parsing a localised string (aSourceString)
- with parameters, in the format that is used by
- nsIStringBundle.formatStringFromName():
-
- "textA %1$S textB textC %2$S"
-
- Or:
-
- "textA %S"
-
- Where "%1$S", "%2$S", and "%S" are intended to be replaced by provided
- replacement strings. These are specified an array of tuples
- (aReplacements), each containing the replacement text and a boolean for
- whether that text should have an emphasis styling applied. This is used
- as a 1-based array - ie, "%1$S" is replaced by the item in the first
- index of aReplacements, "%2$S" by the second, etc. "%S" will always
- match the first index.
- -->
- <method name="_generateEmphasisPairs">
- <parameter name="aSourceString"/>
- <parameter name="aReplacements"/>
- <body>
- <![CDATA[
- let pairs = [];
-
- // Split on %S, %1$S, %2$S, etc. ie:
- // "textA %S"
- // becomes ["textA ", "%S"]
- // "textA %1$S textB textC %2$S"
- // becomes ["textA ", "%1$S", " textB textC ", "%2$S"]
- let parts = aSourceString.split(/(%(?:[0-9]+\$)?S)/);
-
- for (let part of parts) {
- // The above regex will actually give us an empty string at the
- // end - we don't want that, as we don't want to later generate an
- // empty text node for it.
- if (part.length === 0)
- continue;
-
- // Determine if this token is a replacement token or a normal text
- // token. If it is a replacement token, we want to extract the
- // numerical number. However, we still want to match on "$S".
- let match = part.match(/^%(?:([0-9]+)\$)?S$/);
-
- if (match) {
- // "%S" doesn't have a numerical number in it, but will always
- // be assumed to be 1. Furthermore, the input string specifies
- // these with a 1-based index, but we want a 0-based index.
- let index = (match[1] || 1) - 1;
-
- if (index >= 0 && index < aReplacements.length) {
- pairs.push([...aReplacements[index]]);
- }
- } else {
- pairs.push([part]);
- }
- }
-
- return pairs;
- ]]>
- </body>
- </method>
-
- <!--
- _setUpEmphasisedSections() has the same use as _setUpDescription,
- except instead of taking a string and highlighting given tokens, it takes
- an array of pairs generated by _generateEmphasisPairs(). This allows
- control over emphasising based on specific blocks of text, rather than
- search for substrings.
- -->
- <method name="_setUpEmphasisedSections">
- <parameter name="aDescriptionElement"/>
- <parameter name="aTextPairs"/>
- <body>
- <![CDATA[
- // Get rid of all previous text
- while (aDescriptionElement.hasChildNodes())
- aDescriptionElement.firstChild.remove();
-
- for (let [text, emphasise] of aTextPairs) {
- if (emphasise) {
- let span = aDescriptionElement.appendChild(
- document.createElementNS("http://www.w3.org/1999/xhtml", "span"));
- span.textContent = text;
- switch(emphasise) {
- case "match":
- span.className = "ac-emphasize-text";
- break;
- case "selected":
- span.className = "ac-selected-text";
- break;
- }
- } else {
- aDescriptionElement.appendChild(document.createTextNode(text));
- }
- }
- ]]>
- </body>
- </method>
-
- <field name="_textToSubURI">null</field>
- <method name="_unescapeUrl">
- <parameter name="url"/>
- <body>
- <![CDATA[
- if (!this._textToSubURI) {
- this._textToSubURI =
- Components.classes["@mozilla.org/intl/texttosuburi;1"]
- .getService(Components.interfaces.nsITextToSubURI);
- }
- return this._textToSubURI.unEscapeURIForUI("UTF-8", url);
- ]]>
- </body>
- </method>
-
- <method name="_adjustAcItem">
- <body>
- <![CDATA[
- let originalUrl = this.getAttribute("url");
- let title = this.getAttribute("title");
- let type = this.getAttribute("type");
-
- let displayUrl;
- let emphasiseTitle = true;
- let emphasiseUrl = true;
-
- // Hide the title's extra box by default, until we find out later if
- // we need extra stuff.
- this._extraBox.hidden = true;
- this._titleBox.flex = 1;
- this._typeImage.hidden = false;
-
- this.removeAttribute("actiontype");
- this.classList.remove("overridable-action");
-
- // The ellipses are hidden via their visibility so that they always
- // take up space and don't pop in on top of text when shown. For
- // keyword searches, however, the title ellipsis should not take up
- // space when hidden. Setting the hidden property accomplishes that.
- this._titleOverflowEllipsis.hidden = false;
-
- let types = new Set(type.split(/\s+/));
-
- // Remove types that should ultimately not be in the `type` string.
- let initialTypes = new Set(types);
- types.delete("action");
- types.delete("autofill");
- types.delete("heuristic");
- types.delete("search");
-
- type = [...types][0] || "";
-
- // If the type includes an action, set up the item appropriately.
- if (initialTypes.has("action")) {
- let action = this._parseActionUrl(originalUrl);
- this.setAttribute("actiontype", action.type);
-
- if (action.type == "switchtab") {
- this.classList.add("overridable-action");
- displayUrl = this._unescapeUrl(action.params.url);
- let desc = this._stringBundle.GetStringFromName("switchToTab");
- this._setUpDescription(this._action, desc, true);
- } else if (action.type == "remotetab") {
- displayUrl = this._unescapeUrl(action.params.url);
- let desc = action.params.deviceName;
- this._setUpDescription(this._action, desc, true);
- } else if (action.type == "searchengine") {
- emphasiseUrl = false;
-
- // The order here is not localizable, we default to appending
- // "- Search with Engine" to the search string, to be able to
- // properly generate emphasis pairs. That said, no localization
- // changed the order while it was possible, so doesn't look like
- // there's a strong need for that.
- let {engineName, searchSuggestion, searchQuery} = action.params;
- let engineStr = " - " +
- this._stringBundle.formatStringFromName("searchWithEngine",
- [engineName], 1);
-
- // Make the title by generating an array of pairs and its
- // corresponding interpolation string (e.g., "%1$S") to pass to
- // _generateEmphasisPairs.
- let pairs;
- if (searchSuggestion) {
- // Check if the search query appears in the suggestion. It may
- // not. If it does, then emphasize the query in the suggestion
- // and otherwise just include the suggestion without emphasis.
- let idx = searchSuggestion.indexOf(searchQuery);
- if (idx >= 0) {
- pairs = [
- [searchSuggestion.substring(0, idx), ""],
- [searchQuery, "match"],
- [searchSuggestion.substring(idx + searchQuery.length), ""],
- ];
- } else {
- pairs = [
- [searchSuggestion, ""],
- ];
- }
- } else {
- pairs = [
- [searchQuery, ""],
- ];
- }
- pairs.push([engineStr, "selected"]);
- let interpStr = pairs.map((pair, i) => `%${i + 1}$S`).join("");
- title = this._generateEmphasisPairs(interpStr, pairs);
-
- // If this is a default search match, we remove the image so we
- // can style it ourselves with a generic search icon.
- // We don't do this when matching an aliased search engine,
- // because the icon helps with recognising which engine will be
- // used (when using the default engine, we don't need that
- // recognition).
- if (!action.params.alias) {
- this.removeAttribute("image");
- }
- } else if (action.type == "visiturl") {
- emphasiseUrl = false;
- displayUrl = this._unescapeUrl(action.params.url);
- let sourceStr = this._stringBundle.GetStringFromName("visitURL");
- title = this._generateEmphasisPairs(sourceStr, [
- [displayUrl, "match"],
- ]);
- }
- }
-
- // Check if we have a search engine name
- if (initialTypes.has("search")) {
- emphasiseUrl = false;
-
- const TITLE_SEARCH_ENGINE_SEPARATOR = " \u00B7\u2013\u00B7 ";
-
- let searchEngine = "";
- [title, searchEngine] = title.split(TITLE_SEARCH_ENGINE_SEPARATOR);
- displayUrl = this._stringBundle.formatStringFromName("searchWithEngine", [searchEngine], 1);
- }
-
- if (!displayUrl) {
- let input = this.parentNode.parentNode.input;
- let url = typeof(input.trimValue) == "function" ?
- input.trimValue(originalUrl) :
- originalUrl;
- displayUrl = this._unescapeUrl(url);
- }
- this.setAttribute("displayurl", displayUrl);
-
- // Check if we have an auto-fill URL
- if (initialTypes.has("autofill")) {
- emphasiseUrl = false;
-
- let sourceStr = this._stringBundle.GetStringFromName("visitURL");
- title = this._generateEmphasisPairs(sourceStr, [
- [displayUrl, "match"],
- ]);
- }
-
- // If we have a tag match, show the tags and icon
- if (type == "tag" || type == "bookmark-tag") {
- // Configure the extra box for tags display
- this._extraBox.hidden = false;
- this._extraBox.childNodes[0].hidden = false;
- this._extraBox.childNodes[1].hidden = true;
- this._extraBox.pack = "end";
- this._titleBox.flex = 1;
-
- // The title is separated from the tags by an endash
- let tags;
- [, title, tags] = title.match(/^(.+) \u2013 (.+)$/);
-
- // Each tag is split by a comma in an undefined order, so sort it
- let sortedTags = tags.split(",").sort().join(", ");
-
- // Emphasize the matching text in the tags
- this._setUpDescription(this._extra, sortedTags);
-
- // If we're suggesting bookmarks, then treat tagged matches as
- // bookmarks for the star.
- if (type == "bookmark-tag") {
- type = "bookmark";
- } else {
- this._typeImage.hidden = true;
- }
- // keyword and favicon type results for search engines
- // have an extra magnifying glass icon after them
- } else if (type == "keyword" || (initialTypes.has("search") &&
- initialTypes.has("favicon"))) {
- // Configure the extra box for keyword display
- this._extraBox.hidden = false;
- this._extraBox.childNodes[0].hidden = true;
- // The second child node is ":" and it should be hidden for non keyword types
- this._extraBox.childNodes[1].hidden = type == "keyword" ? false : true;
- this._extraBox.pack = "start";
- this._titleBox.flex = 0;
-
- // Hide the ellipsis so it doesn't take up space.
- this._titleOverflowEllipsis.hidden = true;
-
- if (type == "keyword") {
- // Put the parameters next to the title if we have any
- let search = this.getAttribute("text");
- let params = "";
- let paramsIndex = search.indexOf(" ");
- if (paramsIndex != -1)
- params = search.substr(paramsIndex + 1);
-
- // Emphasize the keyword parameters
- this._setUpDescription(this._extra, params);
-
- // Don't emphasize keyword searches in the title or url
- emphasiseUrl = false;
- emphasiseTitle = false;
- } else {
- // Don't show any description for non keyword types.
- this._setUpDescription(this._extra, "", true);
- }
- // If the result has the type favicon and a known search provider,
- // customize it the same way as a keyword result.
- type = "keyword";
- }
-
- // Give the image the icon style and a special one for the type
- this._typeImage.className = "ac-type-icon" +
- (type ? " ac-result-type-" + type : "");
-
- // Show the domain as the title if we don't have a title.
- if (title == "") {
- title = displayUrl;
- try {
- let uri = Services.io.newURI(originalUrl, null, null);
- // Not all valid URLs have a domain.
- if (uri.host)
- title = uri.host;
- } catch (e) {}
- }
-
- // Emphasize the matching search terms for the description
- if (Array.isArray(title))
- this._setUpEmphasisedSections(this._title, title);
- else
- this._setUpDescription(this._title, title, !emphasiseTitle);
-
- this._setUpDescription(this._url, displayUrl, !emphasiseUrl);
-
- // Set up overflow on a timeout because the contents of the box
- // might not have a width yet even though we just changed them
- setTimeout(this._setUpOverflow, 0, this._titleBox, this._titleOverflowEllipsis);
- setTimeout(this._setUpOverflow, 0, this._urlBox, this._urlOverflowEllipsis);
- ]]>
- </body>
- </method>
-
- <method name="_parseActionUrl">
- <parameter name="aUrl"/>
- <body><![CDATA[
- if (!aUrl.startsWith("moz-action:"))
- return null;
-
- // URL is in the format moz-action:ACTION,PARAMS
- // Where PARAMS is a JSON encoded object.
- let [, type, params] = aUrl.match(/^moz-action:([^,]+),(.*)$/);
-
- let action = {
- type: type,
- };
-
- try {
- action.params = JSON.parse(params);
- for (let key in action.params) {
- action.params[key] = decodeURIComponent(action.params[key]);
- }
- } catch (e) {
- // If this failed, we assume that params is not a JSON object, and
- // is instead just a flat string. This will happen when
- // UnifiedComplete is disabled - in which case, the param is always
- // a URL.
- action.params = {
- url: params,
- }
- }
-
- return action;
- ]]></body>
- </method>
-
- <method name="_setUpOverflow">
- <parameter name="aParentBox"/>
- <parameter name="aEllipsis"/>
- <body>
- <![CDATA[
- // Hide the ellipsis incase there's just enough to not underflow
- aEllipsis.style.visibility = "hidden";
-
- // Start with the parent's width and subtract off its children
- let tooltip = [];
- let children = aParentBox.childNodes;
- let widthDiff = aParentBox.boxObject.width;
-
- for (let i = 0; i < children.length; i++) {
- // Only consider a child if it actually takes up space
- let childWidth = children[i].boxObject.width;
- if (childWidth > 0) {
- // Subtract a little less to account for subpixel rounding
- widthDiff -= childWidth - .5;
-
- // Add to the tooltip if it's not hidden and has text
- let childText = children[i].textContent;
- if (childText)
- tooltip.push(childText);
- }
- }
-
- // If the children take up more space than the parent.. overflow!
- if (widthDiff < 0) {
- // Re-show the ellipsis now that we know it's needed
- aEllipsis.style.visibility = "visible";
-
- // Separate text components with a ndash --
- aParentBox.tooltipText = tooltip.join(" \u2013 ");
- }
- ]]>
- </body>
- </method>
-
- <method name="_doUnderflow">
- <parameter name="aName"/>
- <body>
- <![CDATA[
- // Hide the ellipsis right when we know we're underflowing instead of
- // waiting for the timeout to trigger the _setUpOverflow calculations
- this[aName + "Box"].tooltipText = "";
- this[aName + "OverflowEllipsis"].style.visibility = "hidden";
- ]]>
- </body>
- </method>
-
- <method name="_doOverflow">
- <parameter name="aName"/>
- <body>
- <![CDATA[
- this._setUpOverflow(this[aName + "Box"],
- this[aName + "OverflowEllipsis"]);
- ]]>
- </body>
- </method>
-
- </implementation>
- </binding>
-
- <binding id="private-autocomplete-tree" extends="chrome://global/content/bindings/tree.xml#tree">
- <content>
- <children includes="treecols"/>
- <xul:treerows class="private-autocomplete-treerows tree-rows" xbl:inherits="hidescrollbar" flex="1">
- <children/>
- </xul:treerows>
- </content>
- </binding>
-
- <binding id="private-autocomplete-richlistbox" extends="chrome://global/content/bindings/richlistbox.xml#richlistbox">
- <implementation>
- <field name="mLastMoveTime">Date.now()</field>
- <field name="mouseSelectedIndex">-1</field>
- </implementation>
- <handlers>
- <handler event="mouseup">
- <![CDATA[
- // don't call onPopupClick for the scrollbar buttons, thumb, slider, etc.
- let item = event.originalTarget;
- while (item && item.localName != "richlistitem") {
- item = item.parentNode;
- }
-
- if (!item)
- return;
-
- this.parentNode.onPopupClick(event);
- ]]>
- </handler>
-
- <handler event="mousemove">
- <![CDATA[
- if (Date.now() - this.mLastMoveTime > 30) {
- let item = event.target;
- while (item && item.localName != "richlistitem") {
- item = item.parentNode;
- }
-
- if (!item)
- return;
-
- let index = this.getIndexOfItem(item);
- if (index != this.selectedIndex) {
- this.mouseSelectedIndex = this.selectedIndex = index;
- }
-
- this.mLastMoveTime = Date.now();
- }
- ]]>
- </handler>
- </handlers>
- </binding>
-
- <binding id="private-autocomplete-treebody">
- <implementation>
- <field name="mLastMoveTime">Date.now()</field>
- </implementation>
-
- <handlers>
- <handler event="mouseup" action="this.parentNode.parentNode.onPopupClick(event);"/>
-
- <handler event="mousedown"><![CDATA[
- var rc = this.parentNode.treeBoxObject.getRowAt(event.clientX, event.clientY);
- if (rc != this.parentNode.currentIndex)
- this.parentNode.view.selection.select(rc);
- ]]></handler>
-
- <handler event="mousemove"><![CDATA[
- if (Date.now() - this.mLastMoveTime > 30) {
- var rc = this.parentNode.treeBoxObject.getRowAt(event.clientX, event.clientY);
- if (rc != this.parentNode.currentIndex)
- this.parentNode.view.selection.select(rc);
- this.mLastMoveTime = Date.now();
- }
- ]]></handler>
- </handlers>
- </binding>
-
- <binding id="private-autocomplete-treerows">
- <content>
- <xul:hbox flex="1" class="tree-bodybox">
- <children/>
- </xul:hbox>
- <xul:scrollbar xbl:inherits="collapsed=hidescrollbar" orient="vertical" class="tree-scrollbar"/>
- </content>
- </binding>
-
- <binding id="private-history-dropmarker" extends="chrome://global/content/bindings/general.xml#dropmarker">
- <handlers>
- <handler event="mousedown" button="0"><![CDATA[
- document.getBindingParent(this).toggleHistoryPopup();
- ]]></handler>
- </handlers>
- </binding>
-
-</bindings>
diff --git a/base/content/autorecovery.js b/base/content/autorecovery.js
deleted file mode 100644
index 01a092f..0000000
--- a/base/content/autorecovery.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/* 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/. */
-
-/* Auto-recovery module.
- * This module aims to catch fatal browser initialization errors and either
- * automatically correct likely causes from them, or automatically restarting
- * the browser in safe mode. This is hooked into the browser's "onload"
- * event because it can be assumed that at that point, everything must
- * have been properly initialized already.
- */
-
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-
-// Services = object with smart getters for common XPCOM services
-Cu.import("resource://gre/modules/Services.jsm");
-
-var browser_autoRecovery =
-{
- onLoad: function() {
-
- var nsIAS = Ci.nsIAppStartup; // Application startup interface
-
- if (typeof gBrowser === "undefined") {
- // gBrowser should always be defined at this point, but if it is not, then most likely
- // it is due to an incompatible or outdated language pack being installed and selected.
- // In this case, we reset "general.useragent.locale" to try to recover browser startup.
- if (Services.prefs.prefHasUserValue("general.useragent.locale")) {
- // Restart automatically in en-US.
- Services.prefs.clearUserPref("general.useragent.locale");
- Cc["@mozilla.org/toolkit/app-startup;1"].getService(nsIAS).quit(nsIAS.eRestart | nsIAS.eAttemptQuit);
- } else if (!Services.appinfo.inSafeMode) {
- // gBrowser isn't defined, and we're not using a custom locale. Most likely
- // a user-installed add-on causes issues here, so we restart in Safe Mode.
- let RISM = Services.prompt.confirm(null, "Error",
- "The Browser didn't start properly!\n"+
- "This is usually caused by an add-on or misconfiguration.\n\n"+
- "Restart in Safe Mode?");
- if (RISM) {
- Cc["@mozilla.org/toolkit/app-startup;1"].getService(nsIAS).restartInSafeMode(nsIAS.eRestart | nsIAS.eAttemptQuit);
- } else {
- // Force quit application
- Cc["@mozilla.org/toolkit/app-startup;1"].getService(nsIAS).quit(nsIAS.eForceQuit);
- }
- }
- // Something else caused this issue and we're already in Safe Mode, so we return
- // without doing anything else, and let normal error handling take place.
- return;
- } // gBrowser undefined
-
- // Other checks than gBrowser undefined can go here!
-
- // Remove our listener, since we don't want this to fire on every load.
- window.removeEventListener("load", browser_autoRecovery.onLoad, false);
- }
-};
-
-window.addEventListener("load", browser_autoRecovery.onLoad, false);
diff --git a/base/content/autorecovery.xul b/base/content/autorecovery.xul
deleted file mode 100644
index 866bdf2..0000000
--- a/base/content/autorecovery.xul
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0"?>
-
-<overlay
- id="autorecovery"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<script type="application/x-javascript" src="chrome://browser/content/autorecovery.js"/>
-
-<!-- This is an empty overlay to allow separation of the script into its
- own context (needed for locale issues preventing browser start) -->
-
-</overlay>
diff --git a/base/content/baseMenuOverlay.xul b/base/content/baseMenuOverlay.xul
deleted file mode 100644
index bccdec2..0000000
--- a/base/content/baseMenuOverlay.xul
+++ /dev/null
@@ -1,114 +0,0 @@
-<?xml version="1.0"?>
-
-# 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/.
-
-<!DOCTYPE overlay [
-<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
-%brandDTD;
-<!ENTITY % baseMenuOverlayDTD SYSTEM "chrome://browser/locale/baseMenuOverlay.dtd">
-%baseMenuOverlayDTD;
-]>
-<overlay id="baseMenuOverlay"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
-
-#ifdef XP_MACOSX
-<!-- nsMenuBarX hides these and uses them to build the Application menu.
- When using Carbon widgets for Mac OS X widgets, some of these are not
- used as they only apply to Cocoa widget builds. All version of Firefox
- through Firefox 2 will use Carbon widgets. -->
- <menupopup id="menu_ToolsPopup">
- <menuitem id="menu_preferences" label="&preferencesCmdMac.label;" key="key_preferencesCmdMac" oncommand="openPreferences();"/>
- <menuitem id="menu_mac_services" label="&servicesMenuMac.label;"/>
- <menuitem id="menu_mac_hide_app" label="&hideThisAppCmdMac.label;" key="key_hideThisAppCmdMac"/>
- <menuitem id="menu_mac_hide_others" label="&hideOtherAppsCmdMac.label;" key="key_hideOtherAppsCmdMac"/>
- <menuitem id="menu_mac_show_all" label="&showAllAppsCmdMac.label;"/>
- </menupopup>
-<!-- Mac window menu -->
-#include ../../../../toolkit/content/macWindowMenu.inc
-#endif
-
-#ifdef XP_WIN
- <menu id="helpMenu"
- label="&helpMenuWin.label;"
- accesskey="&helpMenuWin.accesskey;">
-#else
- <menu id="helpMenu"
- label="&helpMenu.label;"
- accesskey="&helpMenu.accesskey;">
-#endif
- <menupopup id="menu_HelpPopup" onpopupshowing="buildHelpMenu();">
- <menuitem id="menu_openHelp"
- oncommand="openHelpLink('firefox-help')"
- onclick="checkForMiddleClick(this, event);"
- label="&productHelp.label;"
- accesskey="&productHelp.accesskey;"
-#ifdef XP_MACOSX
- key="key_openHelpMac"/>
-#else
- />
-#endif
- <menuitem id="troubleShooting"
- accesskey="&helpTroubleshootingInfo.accesskey;"
- label="&helpTroubleshootingInfo.label;"
- oncommand="openTroubleshootingPage()"
- onclick="checkForMiddleClick(this, event);"/>
- <menuitem id="helpSafeMode"
- accesskey="&helpSafeMode.accesskey;"
- label="&helpSafeMode.label;"
- oncommand="restart(true);"/>
- <menuseparator/>
- <menuitem id="releaseNotes"
- accesskey="&helpReleaseNotes.accesskey;"
- label="&helpReleaseNotes.label;"
- oncommand="openReleaseNotes();"
- onclick="checkForMiddleClick(this, event);"/>
- <menuitem id="feedbackPage"
- accesskey="&helpFeedbackPage.accesskey;"
- label="&helpFeedbackPage.label;"
- oncommand="openFeedbackPage()"
- onclick="checkForMiddleClick(this, event);"/>
- <menuseparator id="updatesSeparator"/>
- <menuitem id="checkForUpdates" class="menuitem-iconic"
-#ifdef MOZ_UPDATER
- label="&updateCmd.label;"
- oncommand="checkForUpdates();"/>
-#else
- hidden="true"/>
-#endif
- <menuseparator id="aboutSeparator"/>
- <menuitem id="aboutName"
- accesskey="&aboutProduct.accesskey;"
- label="&aboutProduct.label;"
- oncommand="openAboutDialog();"/>
- </menupopup>
- </menu>
-
- <keyset id="baseMenuKeyset">
-#ifdef XP_MACOSX
- <key id="key_openHelpMac"
- oncommand="openHelpLink('firefox-osxkey');"
- key="&helpMac.commandkey;"
- modifiers="accel"/>
-<!-- These are used to build the Application menu under Cocoa widgets -->
- <key id="key_preferencesCmdMac"
- key="&preferencesCmdMac.commandkey;"
- modifiers="accel"/>
- <key id="key_hideThisAppCmdMac"
- key="&hideThisAppCmdMac.commandkey;"
- modifiers="accel"/>
- <key id="key_hideOtherAppsCmdMac"
- key="&hideOtherAppsCmdMac.commandkey;"
- modifiers="accel,alt"/>
-#endif
- </keyset>
-
- <stringbundleset id="stringbundleset">
- <stringbundle id="bundle_browser" src="chrome://browser/locale/browser.properties"/>
- <stringbundle id="bundle_browser_region" src="chrome://browser-region/locale/region.properties"/>
- </stringbundleset>
-</overlay>
diff --git a/base/content/browser-addons.js b/base/content/browser-addons.js
deleted file mode 100644
index 630a0cf..0000000
--- a/base/content/browser-addons.js
+++ /dev/null
@@ -1,537 +0,0 @@
-# -*- 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/.
-
-// Removes a doorhanger notification if all of the installs it was notifying
-// about have ended in some way.
-function removeNotificationOnEnd(notification, installs) {
- let count = installs.length;
-
- function maybeRemove(install) {
- install.removeListener(this);
-
- if (--count == 0) {
- // Check that the notification is still showing
- let current = PopupNotifications.getNotification(notification.id, notification.browser);
- if (current === notification)
- notification.remove();
- }
- }
-
- for (let install of installs) {
- install.addListener({
- onDownloadCancelled: maybeRemove,
- onDownloadFailed: maybeRemove,
- onInstallFailed: maybeRemove,
- onInstallEnded: maybeRemove
- });
- }
-}
-
-const gXPInstallObserver = {
- _findChildShell: function (aDocShell, aSoughtShell)
- {
- if (aDocShell == aSoughtShell)
- return aDocShell;
-
- var node = aDocShell.QueryInterface(Components.interfaces.nsIDocShellTreeItem);
- for (var i = 0; i < node.childCount; ++i) {
- var docShell = node.getChildAt(i);
- docShell = this._findChildShell(docShell, aSoughtShell);
- if (docShell == aSoughtShell)
- return docShell;
- }
- return null;
- },
-
- _getBrowser: function (aDocShell)
- {
- for (let browser of gBrowser.browsers) {
- if (this._findChildShell(browser.docShell, aDocShell))
- return browser;
- }
- return null;
- },
-
- observe: function (aSubject, aTopic, aData)
- {
- var brandBundle = document.getElementById("bundle_brand");
- var installInfo = aSubject.QueryInterface(Components.interfaces.amIWebInstallInfo);
- var browser = installInfo.browser;
-
- // Make sure the browser is still alive.
- if (!browser || gBrowser.browsers.indexOf(browser) == -1)
- return;
-
- const anchorID = "addons-notification-icon";
- var messageString, action;
- var brandShortName = brandBundle.getString("brandShortName");
-
- var notificationID = aTopic;
- // Make notifications persist a minimum of 30 seconds
- var options = {
- timeout: Date.now() + 30000
- };
-
- switch (aTopic) {
- case "addon-install-disabled":
- notificationID = "xpinstall-disabled"
-
- if (gPrefService.prefIsLocked("xpinstall.enabled")) {
- messageString = gNavigatorBundle.getString("xpinstallDisabledMessageLocked");
- buttons = [];
- }
- else {
- messageString = gNavigatorBundle.getString("xpinstallDisabledMessage");
-
- action = {
- label: gNavigatorBundle.getString("xpinstallDisabledButton"),
- accessKey: gNavigatorBundle.getString("xpinstallDisabledButton.accesskey"),
- callback: function editPrefs() {
- gPrefService.setBoolPref("xpinstall.enabled", true);
- }
- };
- }
-
- PopupNotifications.show(browser, notificationID, messageString, anchorID,
- action, null, options);
- break;
- case "addon-install-origin-blocked": {
- messageString = gNavigatorBundle.getFormattedString("xpinstallPromptWarningOrigin",
- [brandShortName]);
-
- let popup = PopupNotifications.show(browser, notificationID,
- messageString, anchorID,
- null, null, options);
- removeNotificationOnEnd(popup, installInfo.installs);
- break; }
- case "addon-install-blocked":
- let originatingHost;
- try {
- originatingHost = installInfo.originatingURI.host;
- } catch (ex) {
- // Need to deal with missing originatingURI and with about:/data: URIs more gracefully,
- // see bug 1063418 - but for now, bail:
- return;
- }
- messageString = gNavigatorBundle.getFormattedString("xpinstallPromptWarning",
- [brandShortName, originatingHost]);
-
- action = {
- label: gNavigatorBundle.getString("xpinstallPromptAllowButton"),
- accessKey: gNavigatorBundle.getString("xpinstallPromptAllowButton.accesskey"),
- callback: function() {
- installInfo.install();
- }
- };
-
- let popup = PopupNotifications.show(browser, notificationID, messageString,
- anchorID, action, null, options);
- removeNotificationOnEnd(popup, installInfo.installs);
- break;
- case "addon-install-started":
- var needsDownload = function needsDownload(aInstall) {
- return aInstall.state != AddonManager.STATE_DOWNLOADED;
- }
- // If all installs have already been downloaded then there is no need to
- // show the download progress
- if (!installInfo.installs.some(needsDownload))
- return;
- notificationID = "addon-progress";
- messageString = gNavigatorBundle.getString("addonDownloading");
- messageString = PluralForm.get(installInfo.installs.length, messageString);
- options.installs = installInfo.installs;
- options.contentWindow = browser.contentWindow;
- options.sourceURI = browser.currentURI;
- options.eventCallback = function(aEvent) {
- if (aEvent != "removed")
- return;
- options.contentWindow = null;
- options.sourceURI = null;
- };
- PopupNotifications.show(browser, notificationID, messageString, anchorID,
- null, null, options);
- break;
- case "addon-install-failed":
- // TODO This isn't terribly ideal for the multiple failure case
- for (let install of installInfo.installs) {
- let host = (installInfo.originatingURI instanceof Ci.nsIStandardURL) &&
- installInfo.originatingURI.host;
- if (!host)
- host = (install.sourceURI instanceof Ci.nsIStandardURL) &&
- install.sourceURI.host;
-
- let error = (host || install.error == 0) ? "addonError" : "addonLocalError";
- if (install.error != 0)
- error += install.error;
- else if (install.addon.jetsdk)
- error += "JetSDK";
- else if (install.addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED)
- error += "Blocklisted";
- else
- error += "Incompatible";
-
- messageString = gNavigatorBundle.getString(error);
- messageString = messageString.replace("#1", install.name);
- if (host)
- messageString = messageString.replace("#2", host);
- messageString = messageString.replace("#3", brandShortName);
- messageString = messageString.replace("#4", Services.appinfo.version);
-
- PopupNotifications.show(browser, notificationID, messageString, anchorID,
- action, null, options);
- }
- break;
- case "addon-install-complete":
- var needsRestart = installInfo.installs.some(function(i) {
- return i.addon.pendingOperations != AddonManager.PENDING_NONE;
- });
-
- if (needsRestart) {
- messageString = gNavigatorBundle.getString("addonsInstalledNeedsRestart");
- action = {
- label: gNavigatorBundle.getString("addonInstallRestartButton"),
- accessKey: gNavigatorBundle.getString("addonInstallRestartButton.accesskey"),
- callback: function() {
- Application.restart();
- }
- };
- }
- else {
- messageString = gNavigatorBundle.getString("addonsInstalled");
- action = null;
- }
-
- messageString = PluralForm.get(installInfo.installs.length, messageString);
- messageString = messageString.replace("#1", installInfo.installs[0].name);
- messageString = messageString.replace("#2", installInfo.installs.length);
- messageString = messageString.replace("#3", brandShortName);
-
- // Remove notificaion on dismissal, since it's possible to cancel the
- // install through the addons manager UI, making the "restart" prompt
- // irrelevant.
- options.removeOnDismissal = true;
-
- PopupNotifications.show(browser, notificationID, messageString, anchorID,
- action, null, options);
- break;
- }
- }
-};
-
-/*
- * When addons are installed/uninstalled, check and see if the number of items
- * on the add-on bar changed:
- * - If an add-on was installed, incrementing the count, show the bar.
- * - If an add-on was uninstalled, and no more items are left, hide the bar.
- */
-var AddonsMgrListener = {
- get addonBar() document.getElementById("addon-bar"),
- get statusBar() document.getElementById("status-bar"),
- getAddonBarItemCount: function() {
- // Take into account the contents of the status bar shim for the count.
- var itemCount = this.statusBar.childNodes.length;
-
- var defaultOrNoninteractive = this.addonBar.getAttribute("defaultset")
- .split(",")
- .concat(["separator", "spacer", "spring"]);
- for (let item of this.addonBar.currentSet.split(",")) {
- if (defaultOrNoninteractive.indexOf(item) == -1)
- itemCount++;
- }
-
- return itemCount;
- },
- onInstalling: function(aAddon) {
- this.lastAddonBarCount = this.getAddonBarItemCount();
- },
- onInstalled: function(aAddon) {
- if (this.getAddonBarItemCount() > this.lastAddonBarCount)
- setToolbarVisibility(this.addonBar, true);
- },
- onUninstalling: function(aAddon) {
- this.lastAddonBarCount = this.getAddonBarItemCount();
- },
- onUninstalled: function(aAddon) {
- if (this.getAddonBarItemCount() == 0)
- setToolbarVisibility(this.addonBar, false);
- },
- onEnabling: function(aAddon) this.onInstalling(),
- onEnabled: function(aAddon) this.onInstalled(),
- onDisabling: function(aAddon) this.onUninstalling(),
- onDisabled: function(aAddon) this.onUninstalled(),
-};
-
-#ifdef MOZ_PERSONAS
-var LightWeightThemeWebInstaller = {
- handleEvent: function (event) {
- switch (event.type) {
- case "InstallBrowserTheme":
- case "PreviewBrowserTheme":
- case "ResetBrowserThemePreview":
- // ignore requests from background tabs
- if (event.target.ownerDocument.defaultView.top != content)
- return;
- }
- switch (event.type) {
- case "InstallBrowserTheme":
- this._installRequest(event);
- break;
- case "PreviewBrowserTheme":
- this._preview(event);
- break;
- case "ResetBrowserThemePreview":
- this._resetPreview(event);
- break;
- case "pagehide":
- case "TabSelect":
- this._resetPreview();
- break;
- }
- },
-
- get _manager () {
- var temp = {};
- Cu.import("resource://gre/modules/LightweightThemeManager.jsm", temp);
- delete this._manager;
- return this._manager = temp.LightweightThemeManager;
- },
-
- _installRequest: function (event) {
- var node = event.target;
- var data = this._getThemeFromNode(node);
- if (!data)
- return;
-
- if (this._isAllowed(node)) {
- this._install(data);
- return;
- }
-
- var allowButtonText =
- gNavigatorBundle.getString("lwthemeInstallRequest.allowButton");
- var allowButtonAccesskey =
- gNavigatorBundle.getString("lwthemeInstallRequest.allowButton.accesskey");
- var message =
- gNavigatorBundle.getFormattedString("lwthemeInstallRequest.message",
- [node.ownerDocument.location.host]);
- var buttons = [{
- label: allowButtonText,
- accessKey: allowButtonAccesskey,
- callback: function () {
- LightWeightThemeWebInstaller._install(data);
- }
- }];
-
- this._removePreviousNotifications();
-
- var notificationBox = gBrowser.getNotificationBox();
- var notificationBar =
- notificationBox.appendNotification(message, "lwtheme-install-request", "",
- notificationBox.PRIORITY_INFO_MEDIUM,
- buttons);
- notificationBar.persistence = 1;
- },
-
- _install: function (newLWTheme) {
- var previousLWTheme = this._manager.currentTheme;
-
- var listener = {
- onEnabling: function(aAddon, aRequiresRestart) {
- if (!aRequiresRestart)
- return;
-
- let messageString = gNavigatorBundle.getFormattedString("lwthemeNeedsRestart.message",
- [aAddon.name], 1);
-
- let action = {
- label: gNavigatorBundle.getString("lwthemeNeedsRestart.button"),
- accessKey: gNavigatorBundle.getString("lwthemeNeedsRestart.accesskey"),
- callback: function () {
- Application.restart();
- }
- };
-
- let options = {
- timeout: Date.now() + 30000
- };
-
- PopupNotifications.show(gBrowser.selectedBrowser, "addon-theme-change",
- messageString, "addons-notification-icon",
- action, null, options);
- },
-
- onEnabled: function(aAddon) {
- LightWeightThemeWebInstaller._postInstallNotification(newLWTheme, previousLWTheme);
- }
- };
-
- AddonManager.addAddonListener(listener);
- this._manager.currentTheme = newLWTheme;
- AddonManager.removeAddonListener(listener);
- },
-
- _postInstallNotification: function (newTheme, previousTheme) {
- function text(id) {
- return gNavigatorBundle.getString("lwthemePostInstallNotification." + id);
- }
-
- var buttons = [{
- label: text("undoButton"),
- accessKey: text("undoButton.accesskey"),
- callback: function () {
- LightWeightThemeWebInstaller._manager.forgetUsedTheme(newTheme.id);
- LightWeightThemeWebInstaller._manager.currentTheme = previousTheme;
- }
- }, {
- label: text("manageButton"),
- accessKey: text("manageButton.accesskey"),
- callback: function () {
- BrowserOpenAddonsMgr("addons://list/theme");
- }
- }];
-
- this._removePreviousNotifications();
-
- var notificationBox = gBrowser.getNotificationBox();
- var notificationBar =
- notificationBox.appendNotification(text("message"),
- "lwtheme-install-notification", "",
- notificationBox.PRIORITY_INFO_MEDIUM,
- buttons);
- notificationBar.persistence = 1;
- notificationBar.timeout = Date.now() + 20000; // 20 seconds
- },
-
- _removePreviousNotifications: function () {
- var box = gBrowser.getNotificationBox();
-
- ["lwtheme-install-request",
- "lwtheme-install-notification"].forEach(function (value) {
- var notification = box.getNotificationWithValue(value);
- if (notification)
- box.removeNotification(notification);
- });
- },
-
- _previewWindow: null,
- _preview: function (event) {
- if (!this._isAllowed(event.target))
- return;
-
- var data = this._getThemeFromNode(event.target);
- if (!data)
- return;
-
- this._resetPreview();
-
- this._previewWindow = event.target.ownerDocument.defaultView;
- this._previewWindow.addEventListener("pagehide", this, true);
- gBrowser.tabContainer.addEventListener("TabSelect", this, false);
-
- this._manager.previewTheme(data);
- },
-
- _resetPreview: function (event) {
- if (!this._previewWindow ||
- event && !this._isAllowed(event.target))
- return;
-
- this._previewWindow.removeEventListener("pagehide", this, true);
- this._previewWindow = null;
- gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
-
- this._manager.resetPreview();
- },
-
- _isAllowed: function (node) {
- var pm = Services.perms;
-
- var uri = node.ownerDocument.documentURIObject;
- return pm.testPermission(uri, "install") == pm.ALLOW_ACTION;
- },
-
- _getThemeFromNode: function (node) {
- return this._manager.parseTheme(node.getAttribute("data-browsertheme"),
- node.baseURI);
- }
-}
-
-/*
- * Listen for Lightweight Theme styling changes and update the browser's theme accordingly.
- */
-var LightweightThemeListener = {
- _modifiedStyles: [],
-
- init: function () {
- XPCOMUtils.defineLazyGetter(this, "styleSheet", function() {
- for (let i = document.styleSheets.length - 1; i >= 0; i--) {
- let sheet = document.styleSheets[i];
- if (sheet.href == "chrome://browser/skin/browser-lightweightTheme.css")
- return sheet;
- }
- });
-
- Services.obs.addObserver(this, "lightweight-theme-styling-update", false);
- Services.obs.addObserver(this, "lightweight-theme-optimized", false);
- if (document.documentElement.hasAttribute("lwtheme"))
- this.updateStyleSheet(document.documentElement.style.backgroundImage);
- },
-
- uninit: function () {
- Services.obs.removeObserver(this, "lightweight-theme-styling-update");
- Services.obs.removeObserver(this, "lightweight-theme-optimized");
- },
-
- /**
- * Append the headerImage to the background-image property of all rulesets in
- * browser-lightweightTheme.css.
- *
- * @param headerImage - a string containing a CSS image for the lightweight theme header.
- */
- updateStyleSheet: function(headerImage) {
- if (!this.styleSheet)
- return;
- this.substituteRules(this.styleSheet.cssRules, headerImage);
- },
-
- substituteRules: function(ruleList, headerImage, existingStyleRulesModified = 0) {
- let styleRulesModified = 0;
- for (let i = 0; i < ruleList.length; i++) {
- let rule = ruleList[i];
- if (rule instanceof Ci.nsIDOMCSSGroupingRule) {
- // Add the number of modified sub-rules to the modified count
- styleRulesModified += this.substituteRules(rule.cssRules, headerImage, existingStyleRulesModified + styleRulesModified);
- } else if (rule instanceof Ci.nsIDOMCSSStyleRule) {
- if (!rule.style.backgroundImage)
- continue;
- let modifiedIndex = existingStyleRulesModified + styleRulesModified;
- if (!this._modifiedStyles[modifiedIndex])
- this._modifiedStyles[modifiedIndex] = { backgroundImage: rule.style.backgroundImage };
-
- rule.style.backgroundImage = this._modifiedStyles[modifiedIndex].backgroundImage + ", " + headerImage;
- styleRulesModified++;
- } else {
- Cu.reportError("Unsupported rule encountered");
- }
- }
- return styleRulesModified;
- },
-
- // nsIObserver
- observe: function (aSubject, aTopic, aData) {
- if ((aTopic != "lightweight-theme-styling-update" && aTopic != "lightweight-theme-optimized") ||
- !this.styleSheet)
- return;
-
- if (aTopic == "lightweight-theme-optimized" && aSubject != window)
- return;
-
- let themeData = JSON.parse(aData);
- if (!themeData)
- return;
- this.updateStyleSheet("url(" + themeData.headerURL + ")");
- },
-};
-#endif
diff --git a/base/content/browser-appmenu.inc b/base/content/browser-appmenu.inc
deleted file mode 100644
index 9d202c9..0000000
--- a/base/content/browser-appmenu.inc
+++ /dev/null
@@ -1,381 +0,0 @@
-# -*- Mode: HTML -*-
-# 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/.
-
-<menupopup id="appmenu-popup"
- onpopupshowing="if (event.target == this) {
- updateEditUIVisibility();
-#ifdef MOZ_SERVICES_SYNC
- gSyncUI.updateUI();
-#endif
- return;
- }
- updateCharacterEncodingMenuState();
- if (event.target.parentNode.parentNode.parentNode.parentNode == this)
- this._currentPopup = event.target;">
- <hbox>
- <vbox id="appmenuPrimaryPane">
- <menuitem id="appmenu_newTab_popup"
- label="&tabCmd.label;"
- command="cmd_newNavigatorTab"
- key="key_newNavigatorTab"/>
- <menuitem id="appmenu_newNavigator"
- label="&newNavigatorCmd.label;"
- command="cmd_newNavigator"
- key="key_newNavigator"/>
- <menuitem id="appmenu_newPrivateWindow"
- class="menuitem-iconic menuitem-iconic-tooltip"
- label="&newPrivateWindow.label;"
- command="Tools:PrivateBrowsing"
- key="key_privatebrowsing"/>
- <menuitem label="&goOfflineCmd.label;"
- id="appmenu_offlineModeRecovery"
- type="checkbox"
- observes="workOfflineMenuitemState"
- oncommand="BrowserOffline.toggleOfflineStatus();"/>
- <menuseparator class="appmenu-menuseparator"/>
- <hbox>
- <menuitem id="appmenu-edit-label"
- label="&appMenuEdit.label;"
- disabled="true"/>
- <toolbarbutton id="appmenu-cut"
- class="appmenu-edit-button"
- command="cmd_cut"
- onclick="if (!this.disabled) hidePopup();"
- tooltiptext="&cutButton.tooltip;"/>
- <toolbarbutton id="appmenu-copy"
- class="appmenu-edit-button"
- command="cmd_copy"
- onclick="if (!this.disabled) hidePopup();"
- tooltiptext="&copyButton.tooltip;"/>
- <toolbarbutton id="appmenu-paste"
- class="appmenu-edit-button"
- command="cmd_paste"
- onclick="if (!this.disabled) hidePopup();"
- tooltiptext="&pasteButton.tooltip;"/>
- <spacer flex="1"/>
- <menu id="appmenu-editmenu">
- <menupopup id="appmenu-editmenu-menupopup">
- <menuitem id="appmenu-editmenu-cut"
- class="menuitem-iconic"
- label="&cutCmd.label;"
- key="key_cut"
- command="cmd_cut"/>
- <menuitem id="appmenu-editmenu-copy"
- class="menuitem-iconic"
- label="&copyCmd.label;"
- key="key_copy"
- command="cmd_copy"/>
- <menuitem id="appmenu-editmenu-paste"
- class="menuitem-iconic"
- label="&pasteCmd.label;"
- key="key_paste"
- command="cmd_paste"/>
- <menuseparator/>
- <menuitem id="appmenu-editmenu-undo"
- label="&undoCmd.label;"
- key="key_undo"
- command="cmd_undo"/>
- <menuitem id="appmenu-editmenu-redo"
- label="&redoCmd.label;"
- key="key_redo"
- command="cmd_redo"/>
- <menuseparator/>
- <menuitem id="appmenu-editmenu-selectAll"
- label="&selectAllCmd.label;"
- key="key_selectAll"
- command="cmd_selectAll"/>
- <menuseparator/>
- <menuitem id="appmenu-editmenu-delete"
- label="&deleteCmd.label;"
- key="key_delete"
- command="cmd_delete"/>
- </menupopup>
- </menu>
- </hbox>
- <menuitem id="appmenu_find"
- class="menuitem-tooltip"
- label="&appMenuFind.label;"
- command="cmd_find"
- key="key_find"/>
- <menuseparator class="appmenu-menuseparator"/>
- <menuitem id="appmenu_openFile"
- label="&openFileCmd.label;"
- command="Browser:OpenFile"
- key="openFileKb"/>
- <menuitem id="appmenu_savePage"
- class="menuitem-tooltip"
- label="&savePageCmd.label;"
- command="Browser:SavePage"
- key="key_savePage"/>
- <menuitem id="appmenu_sendLink"
- label="&emailPageCmd.label;"
- command="Browser:SendLink"/>
- <splitmenu id="appmenu_print"
- iconic="true"
- label="&printCmd.label;"
- command="cmd_print">
- <menupopup>
- <menuitem id="appmenu_print_popup"
- class="menuitem-iconic"
- label="&printCmd.label;"
- command="cmd_print"
- key="printKb"/>
- <menuitem id="appmenu_printPreview"
- label="&printPreviewCmd.label;"
- command="cmd_printPreview"/>
- <menuitem id="appmenu_printSetup"
- label="&printSetupCmd.label;"
- command="cmd_pageSetup"/>
- </menupopup>
- </splitmenu>
- <menuseparator class="appmenu-menuseparator"/>
- <splitmenu id="appmenu_webDeveloper"
- label="&appMenuWebDeveloper.label;">
- <menupopup id="appmenu_webDeveloper_popup">
-#define ID_PREFIX appmenu_developer_
-#define OMIT_ACCESSKEYS
-#include browser-charsetmenu.inc
-#undef ID_PREFIX
-#undef OMIT_ACCESSKEYS
- <menuitem label="&goOfflineCmd.label;"
- type="checkbox"
- observes="workOfflineMenuitemState"
- oncommand="BrowserOffline.toggleOfflineStatus();"/>
- <menuseparator/>
- <menuitem id="appmenu_pageSource"
- observes="devtoolsMenuBroadcaster_PageSource"/>
- <menuitem id="appmenu_javascriptConsole"
- observes="devtoolsMenuBroadcaster_ErrorConsole"/>
- </menupopup>
- </splitmenu>
- <menuseparator class="appmenu-menuseparator"/>
-#define ID_PREFIX appmenu_
-#define OMIT_ACCESSKEYS
-#include browser-charsetmenu.inc
-#undef ID_PREFIX
-#undef OMIT_ACCESSKEYS
- <menuitem id="appmenu_fullScreen"
- class="menuitem-tooltip"
- label="&fullScreenCmd.label;"
- type="checkbox"
- observes="View:FullScreen"
- key="key_fullScreen"/>
- <menuitem id="appmenu_restart"
- class="menuitem-iconic"
- label="&appMenuRestart.label;"
- command="cmd_restartApplication"/>
- <menuitem id="appmenu-quit"
- class="menuitem-iconic"
-#ifdef XP_WIN
- label="&quitApplicationCmdWin.label;"
-#else
- label="&quitApplicationCmd.label;"
-#endif
- command="cmd_quitApplication"/>
- </vbox>
- <vbox id="appmenuSecondaryPane">
- <splitmenu id="appmenu_bookmarks"
- iconic="true"
- label="&bookmarksMenu.label;"
- command="Browser:ShowAllBookmarks">
- <menupopup id="appmenu_bookmarksPopup"
- placespopup="true"
- context="placesContext"
- openInTabs="children"
- oncommand="BookmarksEventHandler.onCommand(event, this.parentNode._placesView);"
- onclick="BookmarksEventHandler.onClick(event, this.parentNode._placesView);"
- onpopupshowing="BookmarkingUI.onPopupShowing(event);
- if (!this.parentNode._placesView)
- new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
- tooltip="bhTooltip"
- popupsinherittooltip="true">
- <menuitem id="appmenu_showAllBookmarks"
- class="menuitem-iconic"
- label="&organizeBookmarks.label;"
- command="Browser:ShowAllBookmarks"
- context=""
- key="manBookmarkKb"/>
- <menuseparator/>
- <menuitem id="appmenu_bookmarkThisPage"
- class="menuitem-iconic"
- label="&bookmarkThisPageCmd.label;"
- command="Browser:AddBookmarkAs"
- key="addBookmarkAsKb"/>
- <menuitem id="appmenu_subscribeToPage"
- class="menuitem-iconic"
- label="&subscribeToPageMenuitem.label;"
- oncommand="return FeedHandler.subscribeToFeed(null, event);"
- onclick="checkForMiddleClick(this, event);"
- observes="singleFeedMenuitemState"/>
- <menu id="appmenu_subscribeToPageMenu"
- class="menu-iconic"
- label="&subscribeToPageMenupopup.label;"
- observes="multipleFeedsMenuState">
- <menupopup id="appmenu_subscribeToPageMenupopup"
- onpopupshowing="return FeedHandler.buildFeedList(event.target);"
- oncommand="return FeedHandler.subscribeToFeed(null, event);"
- onclick="checkForMiddleClick(this, event);"/>
- </menu>
- <menuseparator/>
- <menu id="appmenu_bookmarksToolbar"
- placesanonid="toolbar-autohide"
- class="menu-iconic bookmark-item"
- label="&personalbarCmd.label;"
- container="true">
- <menupopup id="appmenu_bookmarksToolbarPopup"
- placespopup="true"
- context="placesContext"
- onpopupshowing="if (!this.parentNode._placesView)
- new PlacesMenu(event, 'place:folder=TOOLBAR');"/>
- </menu>
- <menuseparator/>
- <!-- Bookmarks menu items -->
- <menuseparator builder="end"
- class="hide-if-empty-places-result"/>
- <menuitem id="appmenu_unsortedBookmarks"
- class="menuitem-iconic"
- label="&appMenuUnsorted.label;"
- oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"/>
- </menupopup>
- </splitmenu>
- <splitmenu id="appmenu_history"
- iconic="true"
- label="&historyMenu.label;"
- command="Browser:ShowAllHistory">
- <menupopup id="appmenu_historyMenupopup"
- placespopup="true"
- context="placesContext"
- oncommand="this.parentNode._placesView._onCommand(event);"
- onclick="checkForMiddleClick(this, event);"
- onpopupshowing="if (!this.parentNode._placesView)
- new HistoryMenu(event);"
- tooltip="bhTooltip"
- popupsinherittooltip="true">
- <menuitem id="appmenu_showAllHistory"
- class="menuitem-iconic"
- label="&showAllHistoryCmd2.label;"
- command="Browser:ShowAllHistory"
- key="showAllHistoryKb"/>
- <menuseparator/>
- <menuitem id="appmenu_sanitizeHistory"
- class="menuitem-iconic"
- label="&clearRecentHistory.label;"
- key="key_sanitize"
- command="Tools:Sanitize"/>
- <menuseparator class="hide-if-empty-places-result"/>
-#ifdef MOZ_SERVICES_SYNC
- <menuitem id="appmenu_sync-tabs"
- class="syncTabsMenuItem"
- label="&syncTabsMenu2.label;"
- oncommand="BrowserOpenSyncTabs();"
- disabled="true"/>
-#endif
- <menuitem id="appmenu_restoreLastSession"
- label="&historyRestoreLastSession.label;"
- command="Browser:RestoreLastSession"/>
- <menu id="appmenu_recentlyClosedTabsMenu"
- class="recentlyClosedTabsMenu"
- label="&historyUndoMenu.label;"
- disabled="true">
- <menupopup id="appmenu_recentlyClosedTabsMenupopup"
- onpopupshowing="document.getElementById('appmenu_history')._placesView.populateUndoSubmenu();"/>
- </menu>
- <menu id="appmenu_recentlyClosedWindowsMenu"
- class="recentlyClosedWindowsMenu"
- label="&historyUndoWindowMenu.label;"
- disabled="true">
- <menupopup id="appmenu_recentlyClosedWindowsMenupopup"
- onpopupshowing="document.getElementById('appmenu_history')._placesView.populateUndoWindowSubmenu();"/>
- </menu>
- <menuseparator/>
- </menupopup>
- </splitmenu>
- <menuitem id="appmenu_downloads"
- class="menuitem-tooltip"
- label="&downloads.label;"
- command="Tools:Downloads"
- key="key_openDownloads"/>
- <spacer id="appmenuSecondaryPane-spacer"/>
- <menuitem id="appmenu_addons"
- class="menuitem-iconic menuitem-iconic-tooltip"
- label="&addons.label;"
- command="Tools:Addons"
- key="key_openAddons"/>
- <menuitem id="appmenu_permissions"
- class="menuitem-iconic"
- label="&permissions.label;"
- command="Tools:Permissions"
- key="key_openPermissions"/>
-#ifdef MOZ_SERVICES_SYNC
- <!-- only one of sync-setup or sync-syncnow will be showing at once -->
- <menuitem id="sync-setup-appmenu"
- label="&syncSetup.label;"
- observes="sync-setup-state"
- oncommand="gSyncUI.openSetup()"/>
- <menuitem id="sync-syncnowitem-appmenu"
- label="&syncSyncNowItem.label;"
- observes="sync-syncnow-state"
- oncommand="gSyncUI.doSync(event);"/>
-#endif
- <splitmenu id="appmenu_customize"
- label="&preferencesCmd2.label;"
- oncommand="openPreferences();">
- <menupopup id="appmenu_customizeMenu"
- onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleToolbarsSeparator'));">
- <menuitem id="appmenu_preferences"
- label="&preferencesCmd2.label;"
- oncommand="openPreferences();"/>
- <menuseparator/>
- <menuseparator id="appmenu_toggleToolbarsSeparator"/>
- <menuitem id="appmenu_toggleTabsOnTop"
- label="&viewTabsOnTop.label;"
- type="checkbox"
- command="cmd_ToggleTabsOnTop"/>
- <menuitem id="appmenu_toolbarLayout"
- label="&appMenuToolbarLayout.label;"
- command="cmd_CustomizeToolbars"/>
- </menupopup>
- </splitmenu>
- <splitmenu id="appmenu_help"
- label="&helpMenu.label;"
- oncommand="openHelpLink('firefox-help')">
- <menupopup id="appmenu_helpMenupopup" onpopupshowing="buildHelpMenu();">
- <menuitem id="appmenu_openHelp"
- label="&helpMenu.label;"
- oncommand="openHelpLink('firefox-help')"
- onclick="checkForMiddleClick(this, event);"/>
- <menuitem id="appmenu_troubleshootingInfo"
- label="&helpTroubleshootingInfo.label;"
- oncommand="openTroubleshootingPage()"
- onclick="checkForMiddleClick(this,event);"/>
- <menuitem id="appmenu_safeMode"
- label="&appMenuSafeMode.label;"
- oncommand="restart(true);"/>
- <menuseparator/>
- <menuitem id="appmenu_releaseNotes"
- accesskey="&helpReleaseNotes.accesskey;"
- label="&helpReleaseNotes.label;"
- oncommand="openReleaseNotes();"
- onclick="checkForMiddleClick(this, event);"/>
- <menuitem id="appmenu_feedbackPage"
- label="&helpFeedbackPage.label;"
- oncommand="openFeedbackPage()"
- onclick="checkForMiddleClick(this, event);"/>
-#ifdef MOZ_UPDATER
- <menuseparator/>
- <menuitem id="appmenu_checkForUpdates"
- class="menuitem-iconic"
- label="&updateCmd.label;"
- oncommand="checkForUpdates();"/>
-#endif
- <menuseparator/>
- <menuitem id="appmenu_about"
- label="&aboutProduct.label;"
- oncommand="openAboutDialog();"/>
- </menupopup>
- </splitmenu>
- </vbox>
- </hbox>
-</menupopup>
diff --git a/base/content/browser-charsetmenu.inc b/base/content/browser-charsetmenu.inc
deleted file mode 100644
index 628de13..0000000
--- a/base/content/browser-charsetmenu.inc
+++ /dev/null
@@ -1,62 +0,0 @@
-# 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/.
-
-#filter substitution
-
-#expand <menu id="__ID_PREFIX__charsetMenu"
- label="&charsetMenu.label;"
-#ifndef OMIT_ACCESSKEYS
- accesskey="&charsetMenu.accesskey;"
-#endif
- oncommand="MultiplexHandler(event)"
-#ifdef OMIT_ACCESSKEYS
-#expand onpopupshowing="CharsetMenu.build(event, '__ID_PREFIX__');"
-#else
-#expand onpopupshowing="CharsetMenu.build(event, '__ID_PREFIX__', true);"
-#endif
- onpopupshown="UpdateMenus(event);">
- <menupopup>
- <menu label="&charsetMenuAutodet.label;"
-#ifndef OMIT_ACCESSKEYS
- accesskey="&charsetMenuAutodet.accesskey;"
-#endif
- >
- <menupopup>
- <menuitem type="radio"
- name="detectorGroup"
-#expand id="__ID_PREFIX__chardet.off"
- label="&charsetMenuAutodet.off.label;"
-#ifndef OMIT_ACCESSKEYS
- accesskey="&charsetMenuAutodet.off.accesskey;"
-#endif
- />
- <menuitem type="radio"
- name="detectorGroup"
-#expand id="__ID_PREFIX__chardet.ja_parallel_state_machine"
- label="&charsetMenuAutodet.ja.label;"
-#ifndef OMIT_ACCESSKEYS
- accesskey="&charsetMenuAutodet.ja.accesskey;"
-#endif
- />
- <menuitem type="radio"
- name="detectorGroup"
-#expand id="__ID_PREFIX__chardet.ruprob"
- label="&charsetMenuAutodet.ru.label;"
-#ifndef OMIT_ACCESSKEYS
- accesskey="&charsetMenuAutodet.ru.accesskey;"
-#endif
- />
- <menuitem type="radio"
- name="detectorGroup"
-#expand id="__ID_PREFIX__chardet.ukprob"
- label="&charsetMenuAutodet.uk.label;"
-#ifndef OMIT_ACCESSKEYS
- accesskey="&charsetMenuAutodet.uk.accesskey;"
-#endif
- />
- </menupopup>
- </menu>
- <menuseparator/>
- </menupopup>
-</menu>
diff --git a/base/content/browser-context.inc b/base/content/browser-context.inc
deleted file mode 100644
index 38c4725..0000000
--- a/base/content/browser-context.inc
+++ /dev/null
@@ -1,384 +0,0 @@
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# 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/.
-
- <menuseparator id="page-menu-separator"/>
- <menuitem id="spell-no-suggestions"
- disabled="true"
- label="&spellNoSuggestions.label;"/>
- <menuitem id="spell-add-to-dictionary"
- label="&spellAddToDictionary.label;"
- accesskey="&spellAddToDictionary.accesskey;"
- oncommand="InlineSpellCheckerUI.addToDictionary();"/>
- <menuitem id="spell-undo-add-to-dictionary"
- label="&spellUndoAddToDictionary.label;"
- accesskey="&spellUndoAddToDictionary.accesskey;"
- oncommand="InlineSpellCheckerUI.undoAddToDictionary();" />
- <menuseparator id="spell-suggestions-separator"/>
- <menuitem id="context-openlinkintab"
- label="&openLinkCmdInTab.label;"
- accesskey="&openLinkCmdInTab.accesskey;"
- oncommand="gContextMenu.openLinkInTab();"/>
- <menuitem id="context-openlink"
- label="&openLinkCmd.label;"
- accesskey="&openLinkCmd.accesskey;"
- oncommand="gContextMenu.openLink();"/>
- <menuitem id="context-openlinkprivate"
- label="&openLinkInPrivateWindowCmd.label;"
- accesskey="&openLinkInPrivateWindowCmd.accesskey;"
- oncommand="gContextMenu.openLinkInPrivateWindow();"/>
- <menuitem id="context-openlinkincurrent"
- label="&openLinkCmdInCurrent.label;"
- accesskey="&openLinkCmdInCurrent.accesskey;"
- oncommand="gContextMenu.openLinkInCurrent();"/>
- <menuseparator id="context-sep-open"/>
- <menuitem id="context-bookmarklink"
- label="&bookmarkThisLinkCmd.label;"
- accesskey="&bookmarkThisLinkCmd.accesskey;"
- oncommand="gContextMenu.bookmarkLink();"/>
- <menuitem id="context-savelink"
- label="&saveLinkCmd.label;"
- accesskey="&saveLinkCmd.accesskey;"
- oncommand="gContextMenu.saveLink();"/>
- <menuitem id="context-sendlink"
- label="&sendLinkCmd.label;"
- accesskey="&sendLinkCmd.accesskey;"
- oncommand="gContextMenu.sendLink();"/>
- <menuitem id="context-copyemail"
- label="&copyEmailCmd.label;"
- accesskey="&copyEmailCmd.accesskey;"
- oncommand="gContextMenu.copyEmail();"/>
- <menuitem id="context-copylink"
- label="&copyLinkCmd.label;"
- accesskey="&copyLinkCmd.accesskey;"
- oncommand="goDoCommand('cmd_copyLink');"/>
- <menuseparator id="context-sep-copylink"/>
- <menuitem id="context-media-play"
- label="&mediaPlay.label;"
- accesskey="&mediaPlay.accesskey;"
- oncommand="gContextMenu.mediaCommand('play');"/>
- <menuitem id="context-media-pause"
- label="&mediaPause.label;"
- accesskey="&mediaPause.accesskey;"
- oncommand="gContextMenu.mediaCommand('pause');"/>
- <menuitem id="context-media-mute"
- label="&mediaMute.label;"
- accesskey="&mediaMute.accesskey;"
- oncommand="gContextMenu.mediaCommand('mute');"/>
- <menuitem id="context-media-unmute"
- label="&mediaUnmute.label;"
- accesskey="&mediaUnmute.accesskey;"
- oncommand="gContextMenu.mediaCommand('unmute');"/>
- <menu id="context-media-playbackrate" label="&mediaPlaybackRate2.label;" accesskey="&mediaPlaybackRate2.accesskey;">
- <menupopup>
- <menuitem id="context-media-playbackrate-050x"
- label="&mediaPlaybackRate050x.label;"
- accesskey="&mediaPlaybackRate050x.accesskey;"
- type="radio"
- name="playbackrate"
- oncommand="gContextMenu.mediaCommand('playbackRate', 0.5);"/>
- <menuitem id="context-media-playbackrate-100x"
- label="&mediaPlaybackRate100x.label;"
- accesskey="&mediaPlaybackRate100x.accesskey;"
- type="radio"
- name="playbackrate"
- checked="true"
- oncommand="gContextMenu.mediaCommand('playbackRate', 1.0);"/>
- <menuitem id="context-media-playbackrate-150x"
- label="&mediaPlaybackRate150x.label;"
- accesskey="&mediaPlaybackRate150x.accesskey;"
- type="radio"
- name="playbackrate"
- oncommand="gContextMenu.mediaCommand('playbackRate', 1.5);"/>
- <menuitem id="context-media-playbackrate-200x"
- label="&mediaPlaybackRate200x.label;"
- accesskey="&mediaPlaybackRate200x.accesskey;"
- type="radio"
- name="playbackrate"
- oncommand="gContextMenu.mediaCommand('playbackRate', 2.0);"/>
- </menupopup>
- </menu>
- <menuitem id="context-media-loop"
- label="&mediaLoop.label;"
- accesskey="&mediaLoop.accesskey;"
- type="checkbox"
- oncommand="gContextMenu.mediaCommand('loop');"/>
- <menuitem id="context-media-showcontrols"
- label="&mediaShowControls.label;"
- accesskey="&mediaShowControls.accesskey;"
- oncommand="gContextMenu.mediaCommand('showcontrols');"/>
- <menuitem id="context-media-hidecontrols"
- label="&mediaHideControls.label;"
- accesskey="&mediaHideControls.accesskey;"
- oncommand="gContextMenu.mediaCommand('hidecontrols');"/>
- <menuitem id="context-video-showstats"
- accesskey="&videoShowStats.accesskey;"
- label="&videoShowStats.label;"
- oncommand="gContextMenu.mediaCommand('showstats');"/>
- <menuitem id="context-video-hidestats"
- accesskey="&videoHideStats.accesskey;"
- label="&videoHideStats.label;"
- oncommand="gContextMenu.mediaCommand('hidestats');"/>
- <menuitem id="context-video-fullscreen"
- accesskey="&videoFullScreen.accesskey;"
- label="&videoFullScreen.label;"
- oncommand="gContextMenu.fullScreenVideo();"/>
- <menuitem id="context-leave-dom-fullscreen"
- accesskey="&leaveDOMFullScreen.accesskey;"
- label="&leaveDOMFullScreen.label;"
- oncommand="gContextMenu.leaveDOMFullScreen();"/>
- <menuseparator id="context-media-sep-commands"/>
- <menuitem id="context-reloadimage"
- label="&reloadImageCmd.label;"
- accesskey="&reloadImageCmd.accesskey;"
- oncommand="gContextMenu.reloadImage();"/>
- <menuitem id="context-viewimage"
- label="&viewImageCmd.label;"
- accesskey="&viewImageCmd.accesskey;"
- oncommand="gContextMenu.viewMedia(event);"
- onclick="checkForMiddleClick(this, event);"/>
- <menuitem id="context-viewvideo"
- label="&viewVideoCmd.label;"
- accesskey="&viewVideoCmd.accesskey;"
- oncommand="gContextMenu.viewMedia(event);"
- onclick="checkForMiddleClick(this, event);"/>
-#ifdef CONTEXT_COPY_IMAGE_CONTENTS
- <menuitem id="context-copyimage-contents"
- label="&copyImageContentsCmd.label;"
- accesskey="&copyImageContentsCmd.accesskey;"
- oncommand="goDoCommand('cmd_copyImage');"/>
-#endif
- <menuitem id="context-copyimage"
- label="&copyImageCmd.label;"
- accesskey="&copyImageCmd.accesskey;"
- oncommand="gContextMenu.copyMediaLocation();"/>
- <menuitem id="context-copyvideourl"
- label="&copyVideoURLCmd.label;"
- accesskey="&copyVideoURLCmd.accesskey;"
- oncommand="gContextMenu.copyMediaLocation();"/>
- <menuitem id="context-copyaudiourl"
- label="&copyAudioURLCmd.label;"
- accesskey="&copyAudioURLCmd.accesskey;"
- oncommand="gContextMenu.copyMediaLocation();"/>
- <menuseparator id="context-sep-copyimage"/>
- <menuitem id="context-saveimage"
- label="&saveImageCmd.label;"
- accesskey="&saveImageCmd.accesskey;"
- oncommand="gContextMenu.saveMedia();"/>
- <menuitem id="context-sendimage"
- label="&emailImageCmd.label;"
- accesskey="&emailImageCmd.accesskey;"
- oncommand="gContextMenu.sendMedia();"/>
- <menuitem id="context-setDesktopBackground"
- label="&setDesktopBackgroundCmd.label;"
- accesskey="&setDesktopBackgroundCmd.accesskey;"
- oncommand="gContextMenu.setDesktopBackground();"/>
- <menuitem id="context-viewimageinfo"
- label="&viewImageInfoCmd.label;"
- accesskey="&viewImageInfoCmd.accesskey;"
- oncommand="gContextMenu.viewImageInfo();"/>
- <menuitem id="context-savevideo"
- label="&saveVideoCmd.label;"
- accesskey="&saveVideoCmd.accesskey;"
- oncommand="gContextMenu.saveMedia();"/>
- <menuitem id="context-saveaudio"
- label="&saveAudioCmd.label;"
- accesskey="&saveAudioCmd.accesskey;"
- oncommand="gContextMenu.saveMedia();"/>
- <menuitem id="context-video-saveimage"
- accesskey="&videoSaveImage.accesskey;"
- label="&videoSaveImage.label;"
- oncommand="gContextMenu.saveVideoFrameAsImage();"/>
- <menuitem id="context-sendvideo"
- label="&emailVideoCmd.label;"
- accesskey="&emailVideoCmd.accesskey;"
- oncommand="gContextMenu.sendMedia();"/>
- <menuitem id="context-sendaudio"
- label="&emailAudioCmd.label;"
- accesskey="&emailAudioCmd.accesskey;"
- oncommand="gContextMenu.sendMedia();"/>
- <menuitem id="context-ctp-play"
- label="&playPluginCmd.label;"
- accesskey="&playPluginCmd.accesskey;"
- oncommand="gContextMenu.playPlugin();"/>
- <menuitem id="context-ctp-hide"
- label="&hidePluginCmd.label;"
- accesskey="&hidePluginCmd.accesskey;"
- oncommand="gContextMenu.hidePlugin();"/>
- <menuseparator id="context-sep-ctp"/>
- <menuitem id="context-back"
- label="&backCmd.label;"
- accesskey="&backCmd.accesskey;"
- command="Browser:BackOrBackDuplicate"
- onclick="checkForMiddleClick(this, event);"/>
- <menuitem id="context-forward"
- label="&forwardCmd.label;"
- accesskey="&forwardCmd.accesskey;"
- command="Browser:ForwardOrForwardDuplicate"
- onclick="checkForMiddleClick(this, event);"/>
- <menuitem id="context-reload"
- label="&reloadCmd.label;"
- accesskey="&reloadCmd.accesskey;"
- oncommand="gContextMenu.reload(event);"
- onclick="checkForMiddleClick(this, event);"/>
- <menuitem id="context-stop"
- label="&stopCmd.label;"
- accesskey="&stopCmd.accesskey;"
- command="Browser:Stop"/>
- <menuseparator id="context-sep-stop"/>
- <menuitem id="context-bookmarkpage"
- label="&bookmarkPageCmd2.label;"
- accesskey="&bookmarkPageCmd2.accesskey;"
- oncommand="gContextMenu.bookmarkThisPage();"/>
- <menuitem id="context-savepage"
- label="&savePageCmd.label;"
- accesskey="&savePageCmd.accesskey2;"
- oncommand="gContextMenu.savePageAs();"/>
- <menuitem id="context-sendpage"
- label="&sendPageCmd.label;"
- accesskey="&sendPageCmd.accesskey;"
- oncommand="gContextMenu.sendPage();"/>
- <menuseparator id="context-sep-viewbgimage"/>
- <menuitem id="context-viewbgimage"
- label="&viewBGImageCmd.label;"
- accesskey="&viewBGImageCmd.accesskey;"
- oncommand="gContextMenu.viewBGImage(event);"
- onclick="checkForMiddleClick(this, event);"/>
- <menuitem id="context-undo"
- label="&undoCmd.label;"
- accesskey="&undoCmd.accesskey;"
- command="cmd_undo"/>
- <menuseparator id="context-sep-undo"/>
- <menuitem id="context-cut"
- label="&cutCmd.label;"
- accesskey="&cutCmd.accesskey;"
- command="cmd_cut"/>
- <menuitem id="context-copy"
- label="&copyCmd.label;"
- accesskey="&copyCmd.accesskey;"
- command="cmd_copy"/>
- <menuitem id="context-paste"
- label="&pasteCmd.label;"
- accesskey="&pasteCmd.accesskey;"
- command="cmd_paste"/>
- <menuitem id="context-delete"
- label="&deleteCmd.label;"
- accesskey="&deleteCmd.accesskey;"
- command="cmd_delete"/>
- <menuseparator id="context-sep-paste"/>
- <menuitem id="context-selectall"
- label="&selectAllCmd.label;"
- accesskey="&selectAllCmd.accesskey;"
- command="cmd_selectAll"/>
- <menuseparator id="context-sep-selectall"/>
- <menuitem id="context-keywordfield"
- label="&keywordfield.label;"
- accesskey="&keywordfield.accesskey;"
- oncommand="AddKeywordForSearchField();"/>
- <menuitem id="context-searchselect"
- oncommand="BrowserSearch.loadSearchFromContext(this.searchTerms);"/>
- <menuseparator id="frame-sep"/>
- <menu id="frame" label="&thisFrameMenu.label;" accesskey="&thisFrameMenu.accesskey;">
- <menupopup>
- <menuitem id="context-showonlythisframe"
- label="&showOnlyThisFrameCmd.label;"
- accesskey="&showOnlyThisFrameCmd.accesskey;"
- oncommand="gContextMenu.showOnlyThisFrame();"/>
- <menuitem id="context-openframeintab"
- label="&openFrameCmdInTab.label;"
- accesskey="&openFrameCmdInTab.accesskey;"
- oncommand="gContextMenu.openFrameInTab();"/>
- <menuitem id="context-openframe"
- label="&openFrameCmd.label;"
- accesskey="&openFrameCmd.accesskey;"
- oncommand="gContextMenu.openFrame();"/>
- <menuseparator id="open-frame-sep"/>
- <menuitem id="context-reloadframe"
- label="&reloadFrameCmd.label;"
- accesskey="&reloadFrameCmd.accesskey;"
- oncommand="gContextMenu.reloadFrame();"/>
- <menuseparator/>
- <menuitem id="context-bookmarkframe"
- label="&bookmarkThisFrameCmd.label;"
- accesskey="&bookmarkThisFrameCmd.accesskey;"
- oncommand="gContextMenu.addBookmarkForFrame();"/>
- <menuitem id="context-saveframe"
- label="&saveFrameCmd.label;"
- accesskey="&saveFrameCmd.accesskey;"
- oncommand="gContextMenu.saveFrame();"/>
- <menuseparator/>
- <menuitem id="context-printframe"
- label="&printFrameCmd.label;"
- accesskey="&printFrameCmd.accesskey;"
- oncommand="gContextMenu.printFrame();"/>
- <menuseparator/>
- <menuitem id="context-viewframesource"
- label="&viewFrameSourceCmd.label;"
- accesskey="&viewFrameSourceCmd.accesskey;"
- oncommand="gContextMenu.viewFrameSource();"
- observes="isFrameImage"/>
- <menuitem id="context-viewframeinfo"
- label="&viewFrameInfoCmd.label;"
- accesskey="&viewFrameInfoCmd.accesskey;"
- oncommand="gContextMenu.viewFrameInfo();"/>
- </menupopup>
- </menu>
- <menuitem id="context-viewpartialsource-selection"
- label="&viewPartialSourceForSelectionCmd.label;"
- accesskey="&viewPartialSourceCmd.accesskey;"
- oncommand="gContextMenu.viewPartialSource('selection');"
- observes="isImage"/>
- <menuitem id="context-viewpartialsource-mathml"
- label="&viewPartialSourceForMathMLCmd.label;"
- accesskey="&viewPartialSourceCmd.accesskey;"
- oncommand="gContextMenu.viewPartialSource('mathml');"
- observes="isImage"/>
- <menuseparator id="context-sep-viewsource"/>
- <menuitem id="context-viewsource"
- label="&viewPageSourceCmd.label;"
- accesskey="&viewPageSourceCmd.accesskey;"
- oncommand="BrowserViewSourceOfDocument(gContextMenu.browser.contentDocument);"
- observes="isImage"/>
- <menuitem id="context-viewinfo"
- label="&viewPageInfoCmd.label;"
- accesskey="&viewPageInfoCmd.accesskey;"
- oncommand="gContextMenu.viewInfo();"/>
- <menuseparator id="spell-separator"/>
- <menuitem id="spell-check-enabled"
- label="&spellCheckToggle.label;"
- type="checkbox"
- accesskey="&spellCheckToggle.accesskey;"
- oncommand="InlineSpellCheckerUI.toggleEnabled();"/>
- <menuitem id="spell-add-dictionaries-main"
- label="&spellAddDictionaries.label;"
- accesskey="&spellAddDictionaries.accesskey;"
- oncommand="gContextMenu.addDictionaries();"/>
- <menu id="spell-dictionaries"
- label="&spellDictionaries.label;"
- accesskey="&spellDictionaries.accesskey;">
- <menupopup id="spell-dictionaries-menu">
- <menuseparator id="spell-language-separator"/>
- <menuitem id="spell-add-dictionaries"
- label="&spellAddDictionaries.label;"
- accesskey="&spellAddDictionaries.accesskey;"
- oncommand="gContextMenu.addDictionaries();"/>
- </menupopup>
- </menu>
- <menuseparator hidden="true" id="context-sep-bidi"/>
- <menuitem hidden="true" id="context-bidi-text-direction-toggle"
- label="&bidiSwitchTextDirectionItem.label;"
- accesskey="&bidiSwitchTextDirectionItem.accesskey;"
- command="cmd_switchTextDirection"/>
- <menuitem hidden="true" id="context-bidi-page-direction-toggle"
- label="&bidiSwitchPageDirectionItem.label;"
- accesskey="&bidiSwitchPageDirectionItem.accesskey;"
- oncommand="gContextMenu.switchPageDirection();"/>
-#ifdef MOZ_DEVTOOLS
- <menuseparator id="inspect-separator" hidden="true"/>
- <menuitem id="context-inspect"
- hidden="true"
- label="&inspectContextMenu.label;"
- accesskey="&inspectContextMenu.accesskey;"
- oncommand="gContextMenu.inspectNode();"/>
-#endif
diff --git a/base/content/browser-devtools-theme.js b/base/content/browser-devtools-theme.js
deleted file mode 100644
index 7b21dde..0000000
--- a/base/content/browser-devtools-theme.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/* 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/. */
-
-/**
- * Listeners for the DevTools theme.
- */
-var DevToolsTheme = {
- _devtoolsThemePrefName: "devtools.theme",
- styleSheet: null,
- initialized: false,
-
- get isStyleSheetEnabled() {
- return this.styleSheet && !this.styleSheet.sheet.disabled;
- },
-
- init: function () {
- this.initialized = true;
- Services.prefs.addObserver(this._devtoolsThemePrefName, this, false);
- Services.obs.addObserver(this, "lightweight-theme-styling-update", false);
- Services.obs.addObserver(this, "lightweight-theme-window-updated", false);
- this._updateDevtoolsThemeAttribute();
- },
-
- observe: function (subject, topic, data) {
- if (topic == "lightweight-theme-styling-update") {
- let newTheme = JSON.parse(data);
- this._toggleStyleSheet();
- }
-
- if (topic == "nsPref:changed" && data == this._devtoolsThemePrefName) {
- this._updateDevtoolsThemeAttribute();
- }
- },
-
- _inferBrightness: function() {
- ToolbarIconColor.inferFromText();
- // Get an inverted full screen button if the dark theme is applied.
- if (this.isStyleSheetEnabled &&
- document.documentElement.getAttribute("devtoolstheme") == "dark") {
- document.documentElement.setAttribute("brighttitlebarforeground", "true");
- } else {
- document.documentElement.removeAttribute("brighttitlebarforeground");
- }
- },
-
- _updateDevtoolsThemeAttribute: function() {
- // Set an attribute on root element to make it possible
- // to change colors based on the selected devtools theme.
- let devtoolsTheme = Services.prefs.getCharPref(this._devtoolsThemePrefName);
- if (devtoolsTheme != "dark") {
- devtoolsTheme = "light";
- }
- document.documentElement.setAttribute("devtoolstheme", devtoolsTheme);
- this._inferBrightness();
- },
-
- handleEvent: function(e) {
- if (e.type === "load") {
- this.styleSheet.removeEventListener("load", this);
- this.refreshBrowserDisplay();
- }
- },
-
- refreshBrowserDisplay: function() {
- // Don't touch things on the browser if gBrowserInit.onLoad hasn't
- // yet fired.
- if (this.initialized) {
- gBrowser.tabContainer._positionPinnedTabs();
- this._inferBrightness();
- }
- },
-
- _toggleStyleSheet: function() {
- let wasEnabled = this.isStyleSheetEnabled;
- if (wasEnabled) {
- this.styleSheet.sheet.disabled = true;
- this.refreshBrowserDisplay();
- }
- },
-
- uninit: function () {
- Services.prefs.removeObserver(this._devtoolsThemePrefName, this);
- Services.obs.removeObserver(this, "lightweight-theme-styling-update", false);
- Services.obs.removeObserver(this, "lightweight-theme-window-updated", false);
- if (this.styleSheet) {
- this.styleSheet.removeEventListener("load", this);
- }
- this.styleSheet = null;
- }
-};
diff --git a/base/content/browser-doctype.inc b/base/content/browser-doctype.inc
deleted file mode 100644
index 6ee6384..0000000
--- a/base/content/browser-doctype.inc
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE window [
-<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
-%brandDTD;
-<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
-%browserDTD;
-<!ENTITY % baseMenuDTD SYSTEM "chrome://browser/locale/baseMenuOverlay.dtd" >
-%baseMenuDTD;
-<!ENTITY % charsetDTD SYSTEM "chrome://browser/locale/charsetMenu.dtd" >
-%charsetDTD;
-<!ENTITY % textcontextDTD SYSTEM "chrome://global/locale/textcontext.dtd" >
-%textcontextDTD;
-<!ENTITY % customizeToolbarDTD SYSTEM "chrome://global/locale/customizeToolbar.dtd">
- %customizeToolbarDTD;
-<!ENTITY % placesDTD SYSTEM "chrome://browser/locale/places/places.dtd">
-%placesDTD;
-<!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
-%aboutHomeDTD;
-]>
-
diff --git a/base/content/browser-feeds.js b/base/content/browser-feeds.js
deleted file mode 100644
index c678772..0000000
--- a/base/content/browser-feeds.js
+++ /dev/null
@@ -1,224 +0,0 @@
-# -*- 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/.
-
-/**
- * The Feed Handler object manages discovery of RSS/ATOM feeds in web pages
- * and shows UI when they are discovered.
- */
-var FeedHandler = {
-
- /* Pale Moon: Address Bar: Feeds
- * The click handler for the Feed icon in the location bar. Opens the
- * subscription page if user is not given a choice of feeds.
- * (Otherwise the list of available feeds will be presented to the
- * user in a popup menu.)
- */
- onFeedButtonPMClick: function(event) {
- event.stopPropagation();
-
- if (event.target.hasAttribute("feed") &&
- event.eventPhase == Event.AT_TARGET &&
- (event.button == 0 || event.button == 1)) {
- this.subscribeToFeed(null, event);
- }
- },
-
- /**
- * The click handler for the Feed icon in the toolbar. Opens the
- * subscription page if user is not given a choice of feeds.
- * (Otherwise the list of available feeds will be presented to the
- * user in a popup menu.)
- */
- onFeedButtonClick: function(event) {
- event.stopPropagation();
-
- let feeds = gBrowser.selectedBrowser.feeds || [];
- // If there are multiple feeds, the menu will open, so no need to do
- // anything. If there are no feeds, nothing to do either.
- if (feeds.length != 1)
- return;
-
- if (event.eventPhase == Event.AT_TARGET &&
- (event.button == 0 || event.button == 1)) {
- this.subscribeToFeed(feeds[0].href, event);
- }
- },
-
- /** Called when the user clicks on the Subscribe to This Page... menu item.
- * Builds a menu of unique feeds associated with the page, and if there
- * is only one, shows the feed inline in the browser window.
- * @param menuPopup
- * The feed list menupopup to be populated.
- * @returns true if the menu should be shown, false if there was only
- * one feed and the feed should be shown inline in the browser
- * window (do not show the menupopup).
- */
- buildFeedList: function(menuPopup) {
- var feeds = gBrowser.selectedBrowser.feeds;
- if (feeds == null) {
- // XXX hack -- menu opening depends on setting of an "open"
- // attribute, and the menu refuses to open if that attribute is
- // set (because it thinks it's already open). onpopupshowing gets
- // called after the attribute is unset, and it doesn't get unset
- // if we return false. so we unset it here; otherwise, the menu
- // refuses to work past this point.
- menuPopup.parentNode.removeAttribute("open");
- return false;
- }
-
- while (menuPopup.firstChild)
- menuPopup.removeChild(menuPopup.firstChild);
-
- if (feeds.length == 1) {
- var feedButtonPM = document.getElementById("ub-feed-button");
- if (feedButtonPM)
- feedButtonPM.setAttribute("feed", feeds[0].href);
- return false;
- }
-
- if (feeds.length <= 1)
- return false;
-
- // Build the menu showing the available feed choices for viewing.
- for (let feedInfo of feeds) {
- var menuItem = document.createElement("menuitem");
- var baseTitle = feedInfo.title || feedInfo.href;
- var labelStr = gNavigatorBundle.getFormattedString("feedShowFeedNew", [baseTitle]);
- menuItem.setAttribute("class", "feed-menuitem");
- menuItem.setAttribute("label", labelStr);
- menuItem.setAttribute("feed", feedInfo.href);
- menuItem.setAttribute("tooltiptext", feedInfo.href);
- menuItem.setAttribute("crop", "center");
- menuPopup.appendChild(menuItem);
- }
- return true;
- },
-
- /**
- * Subscribe to a given feed. Called when
- * 1. Page has a single feed and user clicks feed icon in location bar
- * 2. Page has a single feed and user selects Subscribe menu item
- * 3. Page has multiple feeds and user selects from feed icon popup
- * 4. Page has multiple feeds and user selects from Subscribe submenu
- * @param href
- * The feed to subscribe to. May be null, in which case the
- * event target's feed attribute is examined.
- * @param event
- * The event this method is handling. Used to decide where
- * to open the preview UI. (Optional, unless href is null)
- */
- subscribeToFeed: function(href, event) {
- // Just load the feed in the content area to either subscribe or show the
- // preview UI
- if (!href)
- href = event.target.getAttribute("feed");
- urlSecurityCheck(href, gBrowser.contentPrincipal,
- Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
- var feedURI = makeURI(href, document.characterSet);
- // Use the feed scheme so X-Moz-Is-Feed will be set
- // The value doesn't matter
- if (/^https?$/.test(feedURI.scheme))
- href = "feed:" + href;
- this.loadFeed(href, event);
- },
-
- loadFeed: function(href, event) {
- var feeds = gBrowser.selectedBrowser.feeds;
- try {
- openUILink(href, event, { ignoreAlt: true });
- }
- finally {
- // We might default to a livebookmarks modal dialog,
- // so reset that if the user happens to click it again
- gBrowser.selectedBrowser.feeds = feeds;
- }
- },
-
- get _feedMenuitem() {
- delete this._feedMenuitem;
- return this._feedMenuitem = document.getElementById("singleFeedMenuitemState");
- },
-
- get _feedMenupopup() {
- delete this._feedMenupopup;
- return this._feedMenupopup = document.getElementById("multipleFeedsMenuState");
- },
-
- /**
- * Update the browser UI to show whether or not feeds are available when
- * a page is loaded or the user switches tabs to a page that has feeds.
- */
- updateFeeds: function() {
- if (this._updateFeedTimeout)
- clearTimeout(this._updateFeedTimeout);
-
- var feeds = gBrowser.selectedBrowser.feeds;
- var haveFeeds = feeds && feeds.length > 0;
-
- var feedButtonPM = document.getElementById("ub-feed-button");
-
- var feedButton = document.getElementById("feed-button");
-
- if (feedButton)
- feedButton.disabled = !haveFeeds;
-
- if (feedButtonPM) {
- if (!haveFeeds) {
- feedButtonPM.collapsed = true;
- feedButtonPM.removeAttribute("feed");
- } else {
- feedButtonPM.collapsed = !gPrefService.getBoolPref("browser.urlbar.rss");
- }
- }
-
- if (!haveFeeds) {
- this._feedMenuitem.setAttribute("disabled", "true");
- this._feedMenuitem.removeAttribute("hidden");
- this._feedMenupopup.setAttribute("hidden", "true");
- return;
- }
-
- if (feeds.length > 1) {
- if (feedButtonPM)
- feedButtonPM.removeAttribute("feed");
- this._feedMenuitem.setAttribute("hidden", "true");
- this._feedMenupopup.removeAttribute("hidden");
- } else {
- if (feedButtonPM)
- feedButtonPM.setAttribute("feed", feeds[0].href);
- this._feedMenuitem.setAttribute("feed", feeds[0].href);
- this._feedMenuitem.removeAttribute("disabled");
- this._feedMenuitem.removeAttribute("hidden");
- this._feedMenupopup.setAttribute("hidden", "true");
- }
- },
-
- addFeed: function(link, targetDoc) {
- // find which tab this is for, and set the attribute on the browser
- var browserForLink = gBrowser.getBrowserForDocument(targetDoc);
- if (!browserForLink) {
- // ignore feeds loaded in subframes (see bug 305472)
- return;
- }
-
- if (!browserForLink.feeds)
- browserForLink.feeds = [];
-
- browserForLink.feeds.push({ href: link.href, title: link.title });
-
- // If this addition was for the current browser, update the UI. For
- // background browsers, we'll update on tab switch.
- if (browserForLink == gBrowser.selectedBrowser) {
- var feedButtonPM = document.getElementById("ub-feed-button");
- if (feedButtonPM)
- feedButtonPM.collapsed = !gPrefService.getBoolPref("browser.urlbar.rss");
- // Batch updates to avoid updating the UI for multiple onLinkAdded events
- // fired within 100ms of each other.
- if (this._updateFeedTimeout)
- clearTimeout(this._updateFeedTimeout);
- this._updateFeedTimeout = setTimeout(this.updateFeeds.bind(this), 100);
- }
- }
-};
diff --git a/base/content/browser-fullScreen.js b/base/content/browser-fullScreen.js
deleted file mode 100644
index e816ce5..0000000
--- a/base/content/browser-fullScreen.js
+++ /dev/null
@@ -1,462 +0,0 @@
-# -*- 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 () {
- var enterFS = window.fullScreen;
-
- // Toggle the View:FullScreen command, which controls elements like the
- // fullscreen menuitem, menubars, and the appmenu.
- let fullscreenCommand = document.getElementById("View:FullScreen");
- if (enterFS) {
- fullscreenCommand.setAttribute("checked", enterFS);
- } else {
- fullscreenCommand.removeAttribute("checked");
- }
-
-#ifdef XP_MACOSX
- // Make sure the menu items are adjusted.
- document.getElementById("enterFullScreenItem").hidden = enterFS;
- document.getElementById("exitFullScreenItem").hidden = !enterFS;
-#endif
-
- if (!this._fullScrToggler) {
- this._fullScrToggler = document.getElementById("fullscr-toggler");
- this._fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
- this._fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
- }
-
- // On OS X Lion we don't want to hide toolbars when entering fullscreen, unless
- // we're entering DOM fullscreen, in which case we should hide the toolbars.
- // If we're leaving fullscreen, then we'll go through the exit code below to
- // make sure toolbars are made visible in the case of DOM fullscreen.
- if (enterFS && this.useLionFullScreen) {
- if (document.mozFullScreen) {
- this.showXULChrome("toolbar", false);
- }
- else {
- gNavToolbox.setAttribute("inFullscreen", true);
- document.documentElement.setAttribute("inFullscreen", true);
- }
- return;
- }
-
- // show/hide menubars, toolbars (except the full screen toolbar)
- this.showXULChrome("toolbar", !enterFS);
-
- if (enterFS) {
- document.addEventListener("keypress", this._keyToggleCallback, false);
- document.addEventListener("popupshown", this._setPopupOpen, false);
- document.addEventListener("popuphidden", this._setPopupOpen, false);
- this._shouldAnimate = true;
- if (gPrefService.getBoolPref("browser.fullscreen.autohide")) {
- gBrowser.mPanelContainer.addEventListener("mousemove",
- this._collapseCallback, 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.hideNavToolbox(document.mozFullScreen);
- }
- else {
- this.showNavToolbox(false);
- // This is needed if they use the context menu to quit fullscreen
- this._isPopupOpen = false;
-
- document.documentElement.removeAttribute("inDOMFullscreen");
-
- this.cleanup();
- }
- },
-
- exitDomFullScreen : function() {
- document.mozCancelFullScreen();
- },
-
- handleEvent: function (event) {
- switch (event.type) {
- case "activate":
- if (document.mozFullScreen) {
- this.showWarning(this.fullscreenDoc);
- }
- break;
- case "transitionend":
- if (event.propertyName == "opacity")
- this.cancelWarning();
- break;
- }
- },
-
- enterDomFullscreen : function(event) {
- if (!document.mozFullScreen)
- return;
-
- // However, if we receive a "MozDOMFullscreen:NewOrigin" event for a document
- // which is not a subdocument of a currently active (ie. visible) browser
- // or iframe, we know that we've switched to a different frame 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.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell).isActive) {
- 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;
- }
-
- document.documentElement.setAttribute("inDOMFullscreen", true);
-
- 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);
-
- // Add listener to detect when the fullscreen window is re-focused.
- // If a fullscreen window loses focus, we show a warning when the
- // fullscreen window is refocused.
- if (!this.useLionFullScreen) {
- window.addEventListener("activate", this);
- }
-
- // Cancel any "hide the toolbar" animation which is in progress, and make
- // the toolbar hide immediately.
- this.hideNavToolbox(true);
- },
-
- 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);
-
- 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("activate", this);
- this.fullscreenDoc = null;
- }
- },
-
- // Event callbacks
- _expandCallback: function()
- {
- FullScreen.showNavToolbox();
- },
- _collapseCallback: function()
- {
- FullScreen.hideNavToolbox();
- },
- _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.hideNavToolbox(true);
- }
- // F6 is another shortcut to the address bar, but its not covered in OpenLocation()
- else if (aEvent.keyCode == aEvent.DOM_VK_F6)
- FullScreen.showNavToolbox();
- },
-
- // 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,
-
- cancelWarning: function(event) {
- if (!this.warningBox)
- return;
- 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 = null;
- },
-
- warningBox: null,
- warningFadeOutTimeout: null,
- fullscreenDoc: null,
-
- // Shows a warning that the site has entered fullscreen for a short duration.
- showWarning: function(targetDoc) {
- let timeout = gPrefService.getIntPref("full-screen-api.warning.timeout");
- if (!document.mozFullScreen || timeout <= 0)
- return;
-
- // Set the strings on the fullscreen warning 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");
- if (host) {
- // Document's principal's URI has a host. Display a warning including the hostname.
- 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");
- } else {
- hostLabel.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");
- }
-
- // Set a timeout to fade the warning out after a few moments.
- this.warningFadeOutTimeout = setTimeout(() => {
- if (this.warningBox) {
- this.warningBox.setAttribute("fade-warning-out", "true");
- }
- }, timeout);
- },
-
- showNavToolbox: function(trackMouse = true) {
- this._fullScrToggler.hidden = true;
- gNavToolbox.removeAttribute("fullscreenShouldAnimate");
- gNavToolbox.style.marginTop = "";
-
- if (!this._isChromeCollapsed) {
- return;
- }
-
- // Track whether mouse is near the toolbox
- this._isChromeCollapsed = false;
- if (trackMouse) {
- gBrowser.mPanelContainer.addEventListener("mousemove",
- this._collapseCallback, false);
- }
- },
-
- hideNavToolbox: function(forceHide = false) {
- this._fullScrToggler.hidden = document.mozFullScreen;
- if (this._isChromeCollapsed) {
- if (forceHide) {
- gNavToolbox.removeAttribute("fullscreenShouldAnimate");
- }
- return;
- }
- if (!this._safeToCollapse(forceHide)) {
- this._fullScrToggler.hidden = true;
- 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
- let animateUp = gPrefService.getIntPref("browser.fullscreen.animateUp");
- if (animateUp == 0) {
- this._shouldAnimate = false;
- } else if (animateUp == 2) {
- this._shouldAnimate = true;
- }
- if (this._shouldAnimate && !forceHide) {
- gNavToolbox.setAttribute("fullscreenShouldAnimate", true);
- this._shouldAnimate = false;
- // Hide the fullscreen toggler until the transition ends.
- let listener = () => {
- gNavToolbox.removeEventListener("transitionend", listener, true);
- if (this._isChromeCollapsed)
- this._fullScrToggler.hidden = false;
- };
- gNavToolbox.addEventListener("transitionend", listener, true);
- this._fullScrToggler.hidden = true;
- }
-
- gNavToolbox.style.marginTop =
- -gNavToolbox.getBoundingClientRect().height + "px";
- this._isChromeCollapsed = true;
- gBrowser.mPanelContainer.removeEventListener("mousemove",
- this._collapseCallback, false);
- },
-
- showXULChrome: function(aTag, aShow)
- {
- var els = document.getElementsByTagNameNS(this._XULNS, aTag);
-
- for (let el of els) {
- // XXX don't interfere with previously collapsed toolbars
- if (el.getAttribute("fullscreentoolbar") == "true") {
- if (!aShow) {
-
- var toolbarMode = el.getAttribute("mode");
- if (toolbarMode != "text") {
- el.setAttribute("saved-mode", toolbarMode);
- el.setAttribute("saved-iconsize", el.getAttribute("iconsize"));
- el.setAttribute("mode", "icons");
- el.setAttribute("iconsize", "small");
- }
-
- // Give the main nav bar and the tab bar the fullscreen context menu,
- // otherwise remove context menu to prevent breakage
- el.setAttribute("saved-context", el.getAttribute("context"));
- if (el.id == "nav-bar" || el.id == "TabsToolbar")
- el.setAttribute("context", "autohide-context");
- else
- el.removeAttribute("context");
-
- // Set the inFullscreen attribute to allow specific styling
- // in fullscreen mode
- el.setAttribute("inFullscreen", true);
- }
- else {
- var restoreAttr = function restoreAttr(attrName) {
- var savedAttr = "saved-" + attrName;
- if (el.hasAttribute(savedAttr)) {
- el.setAttribute(attrName, el.getAttribute(savedAttr));
- el.removeAttribute(savedAttr);
- }
- }
-
- restoreAttr("mode");
- restoreAttr("iconsize");
- restoreAttr("context");
-
- el.removeAttribute("inFullscreen");
- }
- } else {
- // use moz-collapsed so it doesn't persist hidden/collapsed,
- // so that new windows don't have missing toolbars
- if (aShow)
- el.removeAttribute("moz-collapsed");
- else
- el.setAttribute("moz-collapsed", "true");
- }
- }
-
- if (aShow) {
- gNavToolbox.removeAttribute("inFullscreen");
- document.documentElement.removeAttribute("inFullscreen");
- } else {
- gNavToolbox.setAttribute("inFullscreen", true);
- document.documentElement.setAttribute("inFullscreen", true);
- }
-
- // In tabs-on-top mode, move window controls to the tab bar,
- // and in tabs-on-bottom mode, move them back to the navigation toolbar.
- // When there is a chance the tab bar may be collapsed, put window
- // controls on nav bar.
- var fullscreenctls = document.getElementById("window-controls");
- var navbar = document.getElementById("nav-bar");
- var ctlsOnTabbar = window.toolbar.visible &&
- (navbar.collapsed || (TabsOnTop.enabled &&
- !gPrefService.getBoolPref("browser.tabs.autoHide")));
- if (fullscreenctls.parentNode == navbar && ctlsOnTabbar) {
- fullscreenctls.removeAttribute("flex");
- document.getElementById("TabsToolbar").appendChild(fullscreenctls);
- }
- else if (fullscreenctls.parentNode.id == "TabsToolbar" && !ctlsOnTabbar) {
- fullscreenctls.setAttribute("flex", "1");
- navbar.appendChild(fullscreenctls);
- }
- fullscreenctls.hidden = aShow;
-
- ToolbarIconColor.inferFromText();
- }
-};
-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
-});
diff --git a/base/content/browser-fullZoom.js b/base/content/browser-fullZoom.js
deleted file mode 100644
index 890cd84..0000000
--- a/base/content/browser-fullZoom.js
+++ /dev/null
@@ -1,526 +0,0 @@
-/* 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/. */
-
-/**
- * Controls the "full zoom" setting and its site-specific preferences.
- */
-var FullZoom = {
- // Identifies the setting in the content prefs database.
- name: "browser.content.full-zoom",
-
- // browser.zoom.siteSpecific preference cache
- _siteSpecificPref: undefined,
-
- // browser.zoom.updateBackgroundTabs preference cache
- updateBackgroundTabs: undefined,
-
- // This maps the browser to monotonically increasing integer
- // tokens. _browserTokenMap[browser] is increased each time the zoom is
- // changed in the browser. See _getBrowserToken and _ignorePendingZoomAccesses.
- _browserTokenMap: new WeakMap(),
-
- // Stores initial locations if we receive onLocationChange
- // events before we're initialized.
- _initialLocations: new WeakMap(),
-
- get siteSpecific() {
- return this._siteSpecificPref;
- },
-
- // nsISupports
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMEventListener,
- Ci.nsIObserver,
- Ci.nsIContentPrefObserver,
- Ci.nsISupportsWeakReference,
- Ci.nsISupports]),
-
- // Initialization & Destruction
-
- init: function FullZoom_init() {
- gBrowser.addEventListener("ZoomChangeUsingMouseWheel", this);
-
- // Register ourselves with the service so we know when our pref changes.
- this._cps2 = Cc["@mozilla.org/content-pref/service;1"].
- getService(Ci.nsIContentPrefService2);
- this._cps2.addObserverForName(this.name, this);
-
- this._siteSpecificPref =
- gPrefService.getBoolPref("browser.zoom.siteSpecific");
- this.updateBackgroundTabs =
- gPrefService.getBoolPref("browser.zoom.updateBackgroundTabs");
- // Listen for changes to the browser.zoom branch so we can enable/disable
- // updating background tabs and per-site saving and restoring of zoom levels.
- gPrefService.addObserver("browser.zoom.", this, true);
-
- // If we received onLocationChange events for any of the current browsers
- // before we were initialized we want to replay those upon initialization.
- for (let browser of gBrowser.browsers) {
- if (this._initialLocations.has(browser)) {
- this.onLocationChange(...this._initialLocations.get(browser), browser);
- }
- }
-
- // This should be nulled after initialization.
- this._initialLocations = null;
- },
-
- destroy: function FullZoom_destroy() {
- gPrefService.removeObserver("browser.zoom.", this);
- this._cps2.removeObserverForName(this.name, this);
- gBrowser.removeEventListener("ZoomChangeUsingMouseWheel", this);
- },
-
-
- // Event Handlers
-
- // nsIDOMEventListener
-
- handleEvent: function FullZoom_handleEvent(event) {
- switch (event.type) {
- case "ZoomChangeUsingMouseWheel":
- let browser = this._getTargetedBrowser(event);
- this._ignorePendingZoomAccesses(browser);
- this._applyZoomToPref(browser);
- break;
- }
- },
-
- // nsIObserver
-
- observe: function (aSubject, aTopic, aData) {
- switch (aTopic) {
- case "nsPref:changed":
- switch (aData) {
- case "browser.zoom.siteSpecific":
- this._siteSpecificPref =
- gPrefService.getBoolPref("browser.zoom.siteSpecific");
- break;
- case "browser.zoom.updateBackgroundTabs":
- this.updateBackgroundTabs =
- gPrefService.getBoolPref("browser.zoom.updateBackgroundTabs");
- break;
- }
- break;
- }
- },
-
- // nsIContentPrefObserver
-
- onContentPrefSet: function FullZoom_onContentPrefSet(aGroup, aName, aValue, aIsPrivate) {
- this._onContentPrefChanged(aGroup, aValue, aIsPrivate);
- },
-
- onContentPrefRemoved: function FullZoom_onContentPrefRemoved(aGroup, aName, aIsPrivate) {
- this._onContentPrefChanged(aGroup, undefined, aIsPrivate);
- },
-
- /**
- * Appropriately updates the zoom level after a content preference has
- * changed.
- *
- * @param aGroup The group of the changed preference.
- * @param aValue The new value of the changed preference. Pass undefined to
- * indicate the preference's removal.
- */
- _onContentPrefChanged: function FullZoom__onContentPrefChanged(aGroup, aValue, aIsPrivate) {
- if (this._isNextContentPrefChangeInternal) {
- // Ignore changes that FullZoom itself makes. This works because the
- // content pref service calls callbacks before notifying observers, and it
- // does both in the same turn of the event loop.
- delete this._isNextContentPrefChangeInternal;
- return;
- }
-
- let browser = gBrowser.selectedBrowser;
- if (!browser.currentURI)
- return;
-
- let ctxt = this._loadContextFromBrowser(browser);
- let domain = this._cps2.extractDomain(browser.currentURI.spec);
- if (aGroup) {
- if (aGroup == domain && ctxt.usePrivateBrowsing == aIsPrivate)
- this._applyPrefToZoom(aValue, browser);
- return;
- }
-
- this._globalValue = aValue === undefined ? aValue :
- this._ensureValid(aValue);
-
- // If the current page doesn't have a site-specific preference, then its
- // zoom should be set to the new global preference now that the global
- // preference has changed.
- let hasPref = false;
- let token = this._getBrowserToken(browser);
- this._cps2.getByDomainAndName(browser.currentURI.spec, this.name, ctxt, {
- handleResult: function () { hasPref = true; },
- handleCompletion: function () {
- if (!hasPref && token.isCurrent)
- this._applyPrefToZoom(undefined, browser);
- }.bind(this)
- });
- },
-
- // location change observer
-
- /**
- * Called when the location of a tab changes.
- * When that happens, we need to update the current zoom level if appropriate.
- *
- * @param aURI
- * A URI object representing the new location.
- * @param aIsTabSwitch
- * Whether this location change has happened because of a tab switch.
- * @param aBrowser
- * (optional) browser object displaying the document
- */
- onLocationChange: function FullZoom_onLocationChange(aURI, aIsTabSwitch, aBrowser) {
- let browser = aBrowser || gBrowser.selectedBrowser;
-
- // If we haven't been initialized yet but receive an onLocationChange
- // notification then let's store and replay it upon initialization.
- if (this._initialLocations) {
- this._initialLocations.set(browser, [aURI, aIsTabSwitch]);
- return;
- }
-
- // Ignore all pending async zoom accesses in the browser. Pending accesses
- // that started before the location change will be prevented from applying
- // to the new location.
- this._ignorePendingZoomAccesses(browser);
-
- if (!aURI || (aIsTabSwitch && !this.siteSpecific)) {
- this._notifyOnLocationChange(browser);
- return;
- }
-
- // Avoid the cps roundtrip and apply the default/global pref.
- if (aURI.spec == "about:blank") {
- this._applyPrefToZoom(undefined, browser,
- this._notifyOnLocationChange.bind(this, browser));
- return;
- }
-
- // Media documents should always start at 1, and are not affected by prefs.
- if (!aIsTabSwitch && browser.isSyntheticDocument) {
- ZoomManager.setZoomForBrowser(browser, 1);
- // _ignorePendingZoomAccesses already called above, so no need here.
- this._notifyOnLocationChange(browser);
- return;
- }
-
- // See if the zoom pref is cached.
- let ctxt = this._loadContextFromBrowser(browser);
- let pref = this._cps2.getCachedByDomainAndName(aURI.spec, this.name, ctxt);
- if (pref) {
- this._applyPrefToZoom(pref.value, browser,
- this._notifyOnLocationChange.bind(this, browser));
- return;
- }
-
- // It's not cached, so we have to asynchronously fetch it.
- let value = undefined;
- let token = this._getBrowserToken(browser);
- this._cps2.getByDomainAndName(aURI.spec, this.name, ctxt, {
- handleResult: function (resultPref) { value = resultPref.value; },
- handleCompletion: function () {
- if (!token.isCurrent) {
- this._notifyOnLocationChange(browser);
- return;
- }
- this._applyPrefToZoom(value, browser,
- this._notifyOnLocationChange.bind(this, browser));
- }.bind(this)
- });
- },
-
- // update state of zoom type menu item
-
- updateMenu: function FullZoom_updateMenu() {
- var menuItem = document.getElementById("toggle_zoom");
-
- menuItem.setAttribute("checked", !ZoomManager.useFullZoom);
- },
-
- // Setting & Pref Manipulation
-
- /**
- * Reduces the zoom level of the page in the current browser.
- */
- reduce: function FullZoom_reduce() {
- ZoomManager.reduce();
- let browser = gBrowser.selectedBrowser;
- this._ignorePendingZoomAccesses(browser);
- this._applyZoomToPref(browser);
- },
-
- /**
- * Enlarges the zoom level of the page in the current browser.
- */
- enlarge: function FullZoom_enlarge() {
- ZoomManager.enlarge();
- let browser = gBrowser.selectedBrowser;
- this._ignorePendingZoomAccesses(browser);
- this._applyZoomToPref(browser);
- },
-
- /**
- * Sets the zoom level for the given browser to the given floating
- * point value, where 1 is the default zoom level.
- */
- setZoom: function (value, browser = gBrowser.selectedBrowser) {
- ZoomManager.setZoomForBrowser(browser, value);
- this._ignorePendingZoomAccesses(browser);
- this._applyZoomToPref(browser);
- },
-
- /**
- * Sets the zoom level of the page in the given browser to the global zoom
- * level.
- *
- * @return A promise which resolves when the zoom reset has been applied.
- */
- reset: function FullZoom_reset(browser = gBrowser.selectedBrowser) {
- let token = this._getBrowserToken(browser);
- let result = this._getGlobalValue(browser).then(value => {
- if (token.isCurrent) {
- ZoomManager.setZoomForBrowser(browser, value === undefined ? 1 : value);
- this._ignorePendingZoomAccesses(browser);
- Services.obs.notifyObservers(browser, "browser-fullZoom:zoomReset", "");
- }
- });
- this._removePref(browser);
- return result;
- },
-
- /**
- * Set the zoom level for a given browser.
- *
- * Per nsPresContext::setFullZoom, we can set the zoom to its current value
- * without significant impact on performance, as the setting is only applied
- * if it differs from the current setting. In fact getting the zoom and then
- * checking ourselves if it differs costs more.
- *
- * And perhaps we should always set the zoom even if it was more expensive,
- * since nsDocumentViewer::SetTextZoom claims that child documents can have
- * a different text zoom (although it would be unusual), and it implies that
- * those child text zooms should get updated when the parent zoom gets set,
- * and perhaps the same is true for full zoom
- * (although nsDocumentViewer::SetFullZoom doesn't mention it).
- *
- * So when we apply new zoom values to the browser, we simply set the zoom.
- * We don't check first to see if the new value is the same as the current
- * one.
- *
- * @param aValue The zoom level value.
- * @param aBrowser The zoom is set in this browser. Required.
- * @param aCallback If given, it's asynchronously called when complete.
- */
- _applyPrefToZoom: function FullZoom__applyPrefToZoom(aValue, aBrowser, aCallback) {
- if (!this.siteSpecific || gInPrintPreviewMode) {
- this._executeSoon(aCallback);
- return;
- }
-
- // The browser is sometimes half-destroyed because this method is called
- // by content pref service callbacks, which themselves can be called at any
- // time, even after browsers are closed.
- if (!aBrowser.parentNode || aBrowser.isSyntheticDocument) {
- this._executeSoon(aCallback);
- return;
- }
-
- if (aValue !== undefined) {
- ZoomManager.setZoomForBrowser(aBrowser, this._ensureValid(aValue));
- this._ignorePendingZoomAccesses(aBrowser);
- this._executeSoon(aCallback);
- return;
- }
-
- let token = this._getBrowserToken(aBrowser);
- this._getGlobalValue(aBrowser).then(value => {
- if (token.isCurrent) {
- ZoomManager.setZoomForBrowser(aBrowser, value === undefined ? 1 : value);
- this._ignorePendingZoomAccesses(aBrowser);
- }
- this._executeSoon(aCallback);
- });
- },
-
- /**
- * Saves the zoom level of the page in the given browser to the content
- * prefs store.
- *
- * @param browser The zoom of this browser will be saved. Required.
- */
- _applyZoomToPref: function FullZoom__applyZoomToPref(browser) {
- Services.obs.notifyObservers(browser, "browser-fullZoom:zoomChange", "");
- if (!this.siteSpecific ||
- gInPrintPreviewMode ||
- browser.isSyntheticDocument)
- return;
-
- this._cps2.set(browser.currentURI.spec, this.name,
- ZoomManager.getZoomForBrowser(browser),
- this._loadContextFromBrowser(browser), {
- handleCompletion: function () {
- this._isNextContentPrefChangeInternal = true;
- }.bind(this),
- });
- },
-
- /**
- * Removes from the content prefs store the zoom level of the given browser.
- *
- * @param browser The zoom of this browser will be removed. Required.
- */
- _removePref: function FullZoom__removePref(browser) {
- Services.obs.notifyObservers(browser, "browser-fullZoom:zoomReset", "");
- if (browser.isSyntheticDocument)
- return;
- let ctxt = this._loadContextFromBrowser(browser);
- this._cps2.removeByDomainAndName(browser.currentURI.spec, this.name, ctxt, {
- handleCompletion: function () {
- this._isNextContentPrefChangeInternal = true;
- }.bind(this),
- });
- },
-
- // Utilities
-
- /**
- * Returns the zoom change token of the given browser. Asynchronous
- * operations that access the given browser's zoom should use this method to
- * capture the token before starting and use token.isCurrent to determine if
- * it's safe to access the zoom when done. If token.isCurrent is false, then
- * after the async operation started, either the browser's zoom was changed or
- * the browser was destroyed, and depending on what the operation is doing, it
- * may no longer be safe to set and get its zoom.
- *
- * @param browser The token of this browser will be returned.
- * @return An object with an "isCurrent" getter.
- */
- _getBrowserToken: function FullZoom__getBrowserToken(browser) {
- let map = this._browserTokenMap;
- if (!map.has(browser))
- map.set(browser, 0);
- return {
- token: map.get(browser),
- get isCurrent() {
- // At this point, the browser may have been destructed and unbound but
- // its outer ID not removed from the map because outer-window-destroyed
- // hasn't been received yet. In that case, the browser is unusable, it
- // has no properties, so return false. Check for this case by getting a
- // property, say, docShell.
- return map.get(browser) === this.token && browser.parentNode;
- },
- };
- },
-
- /**
- * Returns the browser that the supplied zoom event is associated with.
- * @param event The ZoomChangeUsingMouseWheel event.
- * @return The associated browser element, if one exists, otherwise null.
- */
- _getTargetedBrowser: function FullZoom__getTargetedBrowser(event) {
- let target = event.originalTarget;
-
- // With remote content browsers, the event's target is the browser
- // we're looking for.
- const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- if (target instanceof window.XULElement &&
- target.localName == "browser" &&
- target.namespaceURI == XUL_NS)
- return target;
-
- // With in-process content browsers, the event's target is the content
- // document.
- if (target.nodeType == Node.DOCUMENT_NODE)
- return gBrowser.getBrowserForDocument(target);
-
- throw new Error("Unexpected ZoomChangeUsingMouseWheel event source");
- },
-
- /**
- * Increments the zoom change token for the given browser so that pending
- * async operations know that it may be unsafe to access they zoom when they
- * finish.
- *
- * @param browser Pending accesses in this browser will be ignored.
- */
- _ignorePendingZoomAccesses: function FullZoom__ignorePendingZoomAccesses(browser) {
- let map = this._browserTokenMap;
- map.set(browser, (map.get(browser) || 0) + 1);
- },
-
- _ensureValid: function FullZoom__ensureValid(aValue) {
- // Note that undefined is a valid value for aValue that indicates a known-
- // not-to-exist value.
- if (isNaN(aValue))
- return 1;
-
- if (aValue < ZoomManager.MIN)
- return ZoomManager.MIN;
-
- if (aValue > ZoomManager.MAX)
- return ZoomManager.MAX;
-
- return aValue;
- },
-
- /**
- * Gets the global browser.content.full-zoom content preference.
- *
- * @param browser The browser pertaining to the zoom.
- * @returns Promise<prefValue>
- * Resolves to the preference value when done.
- */
- _getGlobalValue: function FullZoom__getGlobalValue(browser) {
- // * !("_globalValue" in this) => global value not yet cached.
- // * this._globalValue === undefined => global value known not to exist.
- // * Otherwise, this._globalValue is a number, the global value.
- return new Promise(resolve => {
- if ("_globalValue" in this) {
- resolve(this._globalValue);
- return;
- }
- let value = undefined;
- this._cps2.getGlobal(this.name, this._loadContextFromBrowser(browser), {
- handleResult: function (pref) { value = pref.value; },
- handleCompletion: (reason) => {
- this._globalValue = this._ensureValid(value);
- resolve(this._globalValue);
- }
- });
- });
- },
-
- /**
- * Gets the load context from the given Browser.
- *
- * @param Browser The Browser whose load context will be returned.
- * @return The nsILoadContext of the given Browser.
- */
- _loadContextFromBrowser: function FullZoom__loadContextFromBrowser(browser) {
- return browser.loadContext;
- },
-
- /**
- * Asynchronously broadcasts "browser-fullZoom:location-change" so that
- * listeners can be notified when the zoom levels on those pages change.
- * The notification is always asynchronous so that observers are guaranteed a
- * consistent behavior.
- */
- _notifyOnLocationChange: function FullZoom__notifyOnLocationChange(browser) {
- this._executeSoon(function () {
- Services.obs.notifyObservers(browser, "browser-fullZoom:location-change", "");
- });
- },
-
- _executeSoon: function FullZoom__executeSoon(callback) {
- if (!callback)
- return;
- Services.tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
- },
-};
diff --git a/base/content/browser-gestureSupport.js b/base/content/browser-gestureSupport.js
deleted file mode 100644
index 13eb71b..0000000
--- a/base/content/browser-gestureSupport.js
+++ /dev/null
@@ -1,1059 +0,0 @@
-# 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/.
-
-// Simple gestures support
-//
-// As per bug #412486, web content must not be allowed to receive any
-// simple gesture events. Multi-touch gesture APIs are in their
-// infancy and we do NOT want to be forced into supporting an API that
-// will probably have to change in the future. (The current Mac OS X
-// API is undocumented and was reverse-engineered.) Until support is
-// implemented in the event dispatcher to keep these events as
-// chrome-only, we must listen for the simple gesture events during
-// the capturing phase and call stopPropagation on every event.
-
-var gGestureSupport = {
- _currentRotation: 0,
- _lastRotateDelta: 0,
- _rotateMomentumThreshold: .75,
-
- /**
- * Add or remove mouse gesture event listeners
- *
- * @param aAddListener
- * True to add/init listeners and false to remove/uninit
- */
- init: function GS_init(aAddListener) {
- // Bug 863514 - Make gesture support work in electrolysis
- if (gMultiProcessBrowser)
- return;
-
- const gestureEvents = ["SwipeGestureStart",
- "SwipeGestureUpdate", "SwipeGestureEnd", "SwipeGesture",
- "MagnifyGestureStart", "MagnifyGestureUpdate", "MagnifyGesture",
- "RotateGestureStart", "RotateGestureUpdate", "RotateGesture",
- "TapGesture", "PressTapGesture"];
-
- let addRemove = aAddListener ? window.addEventListener :
- window.removeEventListener;
-
- gestureEvents.forEach(function (event) addRemove("Moz" + event, this, true),
- this);
- },
-
- /**
- * Dispatch events based on the type of mouse gesture event. For now, make
- * sure to stop propagation of every gesture event so that web content cannot
- * receive gesture events.
- *
- * @param aEvent
- * The gesture event to handle
- */
- handleEvent: function GS_handleEvent(aEvent) {
- if (!Services.prefs.getBoolPref(
- "dom.debug.propagate_gesture_events_through_content")) {
- aEvent.stopPropagation();
- }
-
- // Create a preference object with some defaults
- let def = function(aThreshold, aLatched)
- ({ threshold: aThreshold, latched: !!aLatched });
-
- switch (aEvent.type) {
- case "MozSwipeGestureStart":
- aEvent.preventDefault();
- this._setupSwipeGesture(aEvent);
- break;
- case "MozSwipeGestureUpdate":
- aEvent.preventDefault();
- this._doUpdate(aEvent);
- break;
- case "MozSwipeGestureEnd":
- aEvent.preventDefault();
- this._doEnd(aEvent);
- break;
- case "MozSwipeGesture":
- aEvent.preventDefault();
- this.onSwipe(aEvent);
- break;
- case "MozMagnifyGestureStart":
- aEvent.preventDefault();
-#ifdef XP_WIN
- this._setupGesture(aEvent, "pinch", def(25, 0), "out", "in");
-#else
- this._setupGesture(aEvent, "pinch", def(150, 1), "out", "in");
-#endif
- break;
- case "MozRotateGestureStart":
- aEvent.preventDefault();
- this._setupGesture(aEvent, "twist", def(25, 0), "right", "left");
- break;
- case "MozMagnifyGestureUpdate":
- case "MozRotateGestureUpdate":
- aEvent.preventDefault();
- this._doUpdate(aEvent);
- break;
- case "MozTapGesture":
- aEvent.preventDefault();
- this._doAction(aEvent, ["tap"]);
- break;
- case "MozRotateGesture":
- aEvent.preventDefault();
- this._doAction(aEvent, ["twist", "end"]);
- break;
- /* case "MozPressTapGesture":
- break; */
- }
- },
-
- /**
- * Called at the start of "pinch" and "twist" gestures to setup all of the
- * information needed to process the gesture
- *
- * @param aEvent
- * The continual motion start event to handle
- * @param aGesture
- * Name of the gesture to handle
- * @param aPref
- * Preference object with the names of preferences and defaults
- * @param aInc
- * Command to trigger for increasing motion (without gesture name)
- * @param aDec
- * Command to trigger for decreasing motion (without gesture name)
- */
- _setupGesture: function GS__setupGesture(aEvent, aGesture, aPref, aInc, aDec) {
- // Try to load user-set values from preferences
- for (let [pref, def] in Iterator(aPref))
- aPref[pref] = this._getPref(aGesture + "." + pref, def);
-
- // Keep track of the total deltas and latching behavior
- let offset = 0;
- let latchDir = aEvent.delta > 0 ? 1 : -1;
- let isLatched = false;
-
- // Create the update function here to capture closure state
- this._doUpdate = function GS__doUpdate(aEvent) {
- // Update the offset with new event data
- offset += aEvent.delta;
-
- // Check if the cumulative deltas exceed the threshold
- if (Math.abs(offset) > aPref["threshold"]) {
- // Trigger the action if we don't care about latching; otherwise, make
- // sure either we're not latched and going the same direction of the
- // initial motion; or we're latched and going the opposite way
- let sameDir = (latchDir ^ offset) >= 0;
- if (!aPref["latched"] || (isLatched ^ sameDir)) {
- this._doAction(aEvent, [aGesture, offset > 0 ? aInc : aDec]);
-
- // We must be getting latched or leaving it, so just toggle
- isLatched = !isLatched;
- }
-
- // Reset motion counter to prepare for more of the same gesture
- offset = 0;
- }
- };
-
- // The start event also contains deltas, so handle an update right away
- this._doUpdate(aEvent);
- },
-
- /**
- * Checks whether a swipe gesture event can navigate the browser history or
- * not.
- *
- * @param aEvent
- * The swipe gesture event.
- * @return true if the swipe event may navigate the history, false othwerwise.
- */
- _swipeNavigatesHistory: function GS__swipeNavigatesHistory(aEvent) {
- return this._getCommand(aEvent, ["swipe", "left"])
- == "Browser:BackOrBackDuplicate" &&
- this._getCommand(aEvent, ["swipe", "right"])
- == "Browser:ForwardOrForwardDuplicate";
- },
-
- /**
- * Sets up the history swipe animations for a swipe gesture event, if enabled.
- *
- * @param aEvent
- * The swipe gesture start event.
- */
- _setupSwipeGesture: function GS__setupSwipeGesture(aEvent) {
- if (!this._swipeNavigatesHistory(aEvent))
- return;
-
- let canGoBack = gHistorySwipeAnimation.canGoBack();
- let canGoForward = gHistorySwipeAnimation.canGoForward();
- let isLTR = gHistorySwipeAnimation.isLTR;
-
- if (canGoBack)
- aEvent.allowedDirections |= isLTR ? aEvent.DIRECTION_LEFT :
- aEvent.DIRECTION_RIGHT;
- if (canGoForward)
- aEvent.allowedDirections |= isLTR ? aEvent.DIRECTION_RIGHT :
- aEvent.DIRECTION_LEFT;
-
- gHistorySwipeAnimation.startAnimation();
-
- this._doUpdate = function GS__doUpdate(aEvent) {
- gHistorySwipeAnimation.updateAnimation(aEvent.delta);
- };
-
- this._doEnd = function GS__doEnd(aEvent) {
- gHistorySwipeAnimation.swipeEndEventReceived();
-
- this._doUpdate = function (aEvent) {};
- this._doEnd = function (aEvent) {};
- }
- },
-
- /**
- * Generator producing the powerset of the input array where the first result
- * is the complete set and the last result (before StopIteration) is empty.
- *
- * @param aArray
- * Source array containing any number of elements
- * @yield Array that is a subset of the input array from full set to empty
- */
- _power: function GS__power(aArray) {
- // Create a bitmask based on the length of the array
- let num = 1 << aArray.length;
- while (--num >= 0) {
- // Only select array elements where the current bit is set
- yield aArray.reduce(function (aPrev, aCurr, aIndex) {
- if (num & 1 << aIndex)
- aPrev.push(aCurr);
- return aPrev;
- }, []);
- }
- },
-
- /**
- * Determine what action to do for the gesture based on which keys are
- * pressed and which commands are set, and execute the command.
- *
- * @param aEvent
- * The original gesture event to convert into a fake click event
- * @param aGesture
- * Array of gesture name parts (to be joined by periods)
- * @return Name of the executed command. Returns null if no command is
- * found.
- */
- _doAction: function GS__doAction(aEvent, aGesture) {
- let command = this._getCommand(aEvent, aGesture);
- return command && this._doCommand(aEvent, command);
- },
-
- /**
- * Determine what action to do for the gesture based on which keys are
- * pressed and which commands are set
- *
- * @param aEvent
- * The original gesture event to convert into a fake click event
- * @param aGesture
- * Array of gesture name parts (to be joined by periods)
- */
- _getCommand: function GS__getCommand(aEvent, aGesture) {
- // Create an array of pressed keys in a fixed order so that a command for
- // "meta" is preferred over "ctrl" when both buttons are pressed (and a
- // command for both don't exist)
- let keyCombos = [];
- ["shift", "alt", "ctrl", "meta"].forEach(function (key) {
- if (aEvent[key + "Key"])
- keyCombos.push(key);
- });
-
- // Try each combination of key presses in decreasing order for commands
- for (let subCombo of this._power(keyCombos)) {
- // Convert a gesture and pressed keys into the corresponding command
- // action where the preference has the gesture before "shift" before
- // "alt" before "ctrl" before "meta" all separated by periods
- let command;
- try {
- command = this._getPref(aGesture.concat(subCombo).join("."));
- } catch (e) {}
-
- if (command)
- return command;
- }
- return null;
- },
-
- /**
- * Execute the specified command.
- *
- * @param aEvent
- * The original gesture event to convert into a fake click event
- * @param aCommand
- * Name of the command found for the event's keys and gesture.
- */
- _doCommand: function GS__doCommand(aEvent, aCommand) {
- let node = document.getElementById(aCommand);
- if (node) {
- if (node.getAttribute("disabled") != "true") {
- let cmdEvent = document.createEvent("xulcommandevent");
- cmdEvent.initCommandEvent("command", true, true, window, 0,
- aEvent.ctrlKey, aEvent.altKey,
- aEvent.shiftKey, aEvent.metaKey, aEvent);
- node.dispatchEvent(cmdEvent);
- }
-
- }
- else {
- goDoCommand(aCommand);
- }
- },
-
- /**
- * Handle continual motion events. This function will be set by
- * _setupGesture or _setupSwipe.
- *
- * @param aEvent
- * The continual motion update event to handle
- */
- _doUpdate: function(aEvent) {},
-
- /**
- * Handle gesture end events. This function will be set by _setupSwipe.
- *
- * @param aEvent
- * The gesture end event to handle
- */
- _doEnd: function(aEvent) {},
-
- /**
- * Convert the swipe gesture into a browser action based on the direction.
- *
- * @param aEvent
- * The swipe event to handle
- */
- onSwipe: function GS_onSwipe(aEvent) {
- // Figure out which one (and only one) direction was triggered
- for (let dir of ["UP", "RIGHT", "DOWN", "LEFT"]) {
- if (aEvent.direction == aEvent["DIRECTION_" + dir]) {
- this._coordinateSwipeEventWithAnimation(aEvent, dir);
- break;
- }
- }
- },
-
- /**
- * Process a swipe event based on the given direction.
- *
- * @param aEvent
- * The swipe event to handle
- * @param aDir
- * The direction for the swipe event
- */
- processSwipeEvent: function GS_processSwipeEvent(aEvent, aDir) {
- this._doAction(aEvent, ["swipe", aDir.toLowerCase()]);
- },
-
- /**
- * Coordinates the swipe event with the swipe animation, if any.
- * If an animation is currently running, the swipe event will be
- * processed once the animation stops. This will guarantee a fluid
- * motion of the animation.
- *
- * @param aEvent
- * The swipe event to handle
- * @param aDir
- * The direction for the swipe event
- */
- _coordinateSwipeEventWithAnimation:
- function GS__coordinateSwipeEventWithAnimation(aEvent, aDir) {
- if ((gHistorySwipeAnimation.isAnimationRunning()) &&
- (aDir == "RIGHT" || aDir == "LEFT")) {
- gHistorySwipeAnimation.processSwipeEvent(aEvent, aDir);
- }
- else {
- this.processSwipeEvent(aEvent, aDir);
- }
- },
-
- /**
- * Get a gesture preference or use a default if it doesn't exist
- *
- * @param aPref
- * Name of the preference to load under the gesture branch
- * @param aDef
- * Default value if the preference doesn't exist
- */
- _getPref: function GS__getPref(aPref, aDef) {
- // Preferences branch under which all gestures preferences are stored
- const branch = "browser.gesture.";
-
- try {
- // Determine what type of data to load based on default value's type
- let type = typeof aDef;
- let getFunc = "get" + (type == "boolean" ? "Bool" :
- type == "number" ? "Int" : "Char") + "Pref";
- return gPrefService[getFunc](branch + aPref);
- }
- catch (e) {
- return aDef;
- }
- },
-
- /**
- * Perform rotation for ImageDocuments
- *
- * @param aEvent
- * The MozRotateGestureUpdate event triggering this call
- */
- rotate: function(aEvent) {
- if (!(content.document instanceof ImageDocument))
- return;
-
- let contentElement = content.document.body.firstElementChild;
- if (!contentElement)
- return;
- // If we're currently snapping, cancel that snap
- if (contentElement.classList.contains("completeRotation"))
- this._clearCompleteRotation();
-
- this.rotation = Math.round(this.rotation + aEvent.delta);
- contentElement.style.transform = "rotate(" + this.rotation + "deg)";
- this._lastRotateDelta = aEvent.delta;
- },
-
- /**
- * Perform a rotation end for ImageDocuments
- */
- rotateEnd: function() {
- if (!(content.document instanceof ImageDocument))
- return;
-
- let contentElement = content.document.body.firstElementChild;
- if (!contentElement)
- return;
-
- let transitionRotation = 0;
-
- // The reason that 360 is allowed here is because when rotating between
- // 315 and 360, setting rotate(0deg) will cause it to rotate the wrong
- // direction around--spinning wildly.
- if (this.rotation <= 45)
- transitionRotation = 0;
- else if (this.rotation > 45 && this.rotation <= 135)
- transitionRotation = 90;
- else if (this.rotation > 135 && this.rotation <= 225)
- transitionRotation = 180;
- else if (this.rotation > 225 && this.rotation <= 315)
- transitionRotation = 270;
- else
- transitionRotation = 360;
-
- // If we're going fast enough, and we didn't already snap ahead of rotation,
- // then snap ahead of rotation to simulate momentum
- if (this._lastRotateDelta > this._rotateMomentumThreshold &&
- this.rotation > transitionRotation)
- transitionRotation += 90;
- else if (this._lastRotateDelta < -1 * this._rotateMomentumThreshold &&
- this.rotation < transitionRotation)
- transitionRotation -= 90;
-
- // Only add the completeRotation class if it is is necessary
- if (transitionRotation != this.rotation) {
- contentElement.classList.add("completeRotation");
- contentElement.addEventListener("transitionend", this._clearCompleteRotation);
- }
-
- contentElement.style.transform = "rotate(" + transitionRotation + "deg)";
- this.rotation = transitionRotation;
- },
-
- /**
- * Gets the current rotation for the ImageDocument
- */
- get rotation() {
- return this._currentRotation;
- },
-
- /**
- * Sets the current rotation for the ImageDocument
- *
- * @param aVal
- * The new value to take. Can be any value, but it will be bounded to
- * 0 inclusive to 360 exclusive.
- */
- set rotation(aVal) {
- this._currentRotation = aVal % 360;
- if (this._currentRotation < 0)
- this._currentRotation += 360;
- return this._currentRotation;
- },
-
- /**
- * When the location/tab changes, need to reload the current rotation for the
- * image
- */
- restoreRotationState: function() {
- // Bug 863514 - Make gesture support work in electrolysis
- if (gMultiProcessBrowser)
- return;
-
- if (!(content.document instanceof ImageDocument))
- return;
-
- let contentElement = content.document.body.firstElementChild;
- let transformValue = content.window.getComputedStyle(contentElement, null)
- .transform;
-
- if (transformValue == "none") {
- this.rotation = 0;
- return;
- }
-
- // transformValue is a rotation matrix--split it and do mathemagic to
- // obtain the real rotation value
- transformValue = transformValue.split("(")[1]
- .split(")")[0]
- .split(",");
- this.rotation = Math.round(Math.atan2(transformValue[1], transformValue[0]) *
- (180 / Math.PI));
- },
-
- /**
- * Removes the transition rule by removing the completeRotation class
- */
- _clearCompleteRotation: function() {
- let contentElement = content.document &&
- content.document instanceof ImageDocument &&
- content.document.body &&
- content.document.body.firstElementChild;
- if (!contentElement)
- return;
- contentElement.classList.remove("completeRotation");
- contentElement.removeEventListener("transitionend", this._clearCompleteRotation);
- },
-};
-
-// History Swipe Animation Support (bug 678392)
-var gHistorySwipeAnimation = {
-
- active: false,
- isLTR: false,
-
- /**
- * Initializes the support for history swipe animations, if it is supported
- * by the platform/configuration.
- */
- init: function HSA_init() {
- if (!this._isSupported())
- return;
-
- this.active = false;
- this.isLTR = document.documentElement.mozMatchesSelector(
- ":-moz-locale-dir(ltr)");
- this._trackedSnapshots = [];
- this._historyIndex = -1;
- this._boxWidth = -1;
- this._maxSnapshots = this._getMaxSnapshots();
- this._lastSwipeDir = "";
-
- // We only want to activate history swipe animations if we store snapshots.
- // If we don't store any, we handle horizontal swipes without animations.
- if (this._maxSnapshots > 0) {
- this.active = true;
- gBrowser.addEventListener("pagehide", this, false);
- gBrowser.addEventListener("pageshow", this, false);
- gBrowser.addEventListener("popstate", this, false);
- gBrowser.tabContainer.addEventListener("TabClose", this, false);
- }
- },
-
- /**
- * Uninitializes the support for history swipe animations.
- */
- uninit: function HSA_uninit() {
- gBrowser.removeEventListener("pagehide", this, false);
- gBrowser.removeEventListener("pageshow", this, false);
- gBrowser.removeEventListener("popstate", this, false);
- gBrowser.tabContainer.removeEventListener("TabClose", this, false);
-
- this.active = false;
- this.isLTR = false;
- },
-
- /**
- * Starts the swipe animation and handles fast swiping (i.e. a swipe animation
- * is already in progress when a new one is initiated).
- */
- startAnimation: function HSA_startAnimation() {
- if (this.isAnimationRunning()) {
- gBrowser.stop();
- this._lastSwipeDir = "RELOAD"; // just ensure that != ""
- this._canGoBack = this.canGoBack();
- this._canGoForward = this.canGoForward();
- this._handleFastSwiping();
- }
- else {
- this._historyIndex = gBrowser.webNavigation.sessionHistory.index;
- this._canGoBack = this.canGoBack();
- this._canGoForward = this.canGoForward();
- if (this.active) {
- this._takeSnapshot();
- this._installPrevAndNextSnapshots();
- this._addBoxes();
- this._lastSwipeDir = "";
- }
- }
- this.updateAnimation(0);
- },
-
- /**
- * Stops the swipe animation.
- */
- stopAnimation: function HSA_stopAnimation() {
- gHistorySwipeAnimation._removeBoxes();
- },
-
- /**
- * Updates the animation between two pages in history.
- *
- * @param aVal
- * A floating point value that represents the progress of the
- * swipe gesture.
- */
- updateAnimation: function HSA_updateAnimation(aVal) {
- if (!this.isAnimationRunning())
- return;
-
- if ((aVal >= 0 && this.isLTR) ||
- (aVal <= 0 && !this.isLTR)) {
- if (aVal > 1)
- aVal = 1; // Cap value to avoid sliding the page further than allowed.
-
- if (this._canGoBack)
- this._prevBox.collapsed = false;
- else
- this._prevBox.collapsed = true;
-
- // The current page is pushed to the right (LTR) or left (RTL),
- // the intention is to go back.
- // If there is a page to go back to, it should show in the background.
- this._positionBox(this._curBox, aVal);
-
- // The forward page should be pushed offscreen all the way to the right.
- this._positionBox(this._nextBox, 1);
- }
- else {
- if (aVal < -1)
- aVal = -1; // Cap value to avoid sliding the page further than allowed.
-
- // The intention is to go forward. If there is a page to go forward to,
- // it should slide in from the right (LTR) or left (RTL).
- // Otherwise, the current page should slide to the left (LTR) or
- // right (RTL) and the backdrop should appear in the background.
- // For the backdrop to be visible in that case, the previous page needs
- // to be hidden (if it exists).
- if (this._canGoForward) {
- let offset = this.isLTR ? 1 : -1;
- this._positionBox(this._curBox, 0);
- this._positionBox(this._nextBox, offset + aVal); // aVal is negative
- }
- else {
- this._prevBox.collapsed = true;
- this._positionBox(this._curBox, aVal);
- }
- }
- },
-
- /**
- * Event handler for events relevant to the history swipe animation.
- *
- * @param aEvent
- * An event to process.
- */
- handleEvent: function HSA_handleEvent(aEvent) {
- switch (aEvent.type) {
- case "TabClose":
- let browser = gBrowser.getBrowserForTab(aEvent.target);
- this._removeTrackedSnapshot(-1, browser);
- break;
- case "pageshow":
- case "popstate":
- if (this.isAnimationRunning()) {
- if (aEvent.target != gBrowser.selectedBrowser.contentDocument)
- break;
- this.stopAnimation();
- }
- this._historyIndex = gBrowser.webNavigation.sessionHistory.index;
- break;
- case "pagehide":
- if (aEvent.target == gBrowser.selectedBrowser.contentDocument) {
- // Take a snapshot of a page whenever it's about to be navigated away
- // from.
- this._takeSnapshot();
- }
- break;
- }
- },
-
- /**
- * Checks whether the history swipe animation is currently running or not.
- *
- * @return true if the animation is currently running, false otherwise.
- */
- isAnimationRunning: function HSA_isAnimationRunning() {
- return !!this._container;
- },
-
- /**
- * Process a swipe event based on the given direction.
- *
- * @param aEvent
- * The swipe event to handle
- * @param aDir
- * The direction for the swipe event
- */
- processSwipeEvent: function HSA_processSwipeEvent(aEvent, aDir) {
- if (aDir == "RIGHT")
- this._historyIndex += this.isLTR ? 1 : -1;
- else if (aDir == "LEFT")
- this._historyIndex += this.isLTR ? -1 : 1;
- else
- return;
- this._lastSwipeDir = aDir;
- },
-
- /**
- * Checks if there is a page in the browser history to go back to.
- *
- * @return true if there is a previous page in history, false otherwise.
- */
- canGoBack: function HSA_canGoBack() {
- if (this.isAnimationRunning())
- return this._doesIndexExistInHistory(this._historyIndex - 1);
- return gBrowser.webNavigation.canGoBack;
- },
-
- /**
- * Checks if there is a page in the browser history to go forward to.
- *
- * @return true if there is a next page in history, false otherwise.
- */
- canGoForward: function HSA_canGoForward() {
- if (this.isAnimationRunning())
- return this._doesIndexExistInHistory(this._historyIndex + 1);
- return gBrowser.webNavigation.canGoForward;
- },
-
- /**
- * Used to notify the history swipe animation that the OS sent a swipe end
- * event and that we should navigate to the page that the user swiped to, if
- * any. This will also result in the animation overlay to be torn down.
- */
- swipeEndEventReceived: function HSA_swipeEndEventReceived() {
- if (this._lastSwipeDir != "")
- this._navigateToHistoryIndex();
- else
- this.stopAnimation();
- },
-
- /**
- * Checks whether a particular index exists in the browser history or not.
- *
- * @param aIndex
- * The index to check for availability for in the history.
- * @return true if the index exists in the browser history, false otherwise.
- */
- _doesIndexExistInHistory: function HSA__doesIndexExistInHistory(aIndex) {
- try {
- gBrowser.webNavigation.sessionHistory.getEntryAtIndex(aIndex, false);
- }
- catch(ex) {
- return false;
- }
- return true;
- },
-
- /**
- * Navigates to the index in history that is currently being tracked by
- * |this|.
- */
- _navigateToHistoryIndex: function HSA__navigateToHistoryIndex() {
- if (this._doesIndexExistInHistory(this._historyIndex)) {
- gBrowser.webNavigation.gotoIndex(this._historyIndex);
- }
- },
-
- /**
- * Checks to see if history swipe animations are supported by this
- * platform/configuration.
- *
- * return true if supported, false otherwise.
- */
- _isSupported: function HSA__isSupported() {
- return window.matchMedia("(-moz-swipe-animation-enabled)").matches;
- },
-
- /**
- * Handle fast swiping (i.e. a swipe animation is already in
- * progress when a new one is initiated). This will swap out the snapshots
- * used in the previous animation with the appropriate new ones.
- */
- _handleFastSwiping: function HSA__handleFastSwiping() {
- this._installCurrentPageSnapshot(null);
- this._installPrevAndNextSnapshots();
- },
-
- /**
- * Adds the boxes that contain the snapshots used during the swipe animation.
- */
- _addBoxes: function HSA__addBoxes() {
- let browserStack =
- document.getAnonymousElementByAttribute(gBrowser.getNotificationBox(),
- "class", "browserStack");
- this._container = this._createElement("historySwipeAnimationContainer",
- "stack");
- browserStack.appendChild(this._container);
-
- this._prevBox = this._createElement("historySwipeAnimationPreviousPage",
- "box");
- this._container.appendChild(this._prevBox);
-
- this._curBox = this._createElement("historySwipeAnimationCurrentPage",
- "box");
- this._container.appendChild(this._curBox);
-
- this._nextBox = this._createElement("historySwipeAnimationNextPage",
- "box");
- this._container.appendChild(this._nextBox);
-
- this._boxWidth = this._curBox.getBoundingClientRect().width; // cache width
- },
-
- /**
- * Removes the boxes.
- */
- _removeBoxes: function HSA__removeBoxes() {
- this._curBox = null;
- this._prevBox = null;
- this._nextBox = null;
- if (this._container)
- this._container.parentNode.removeChild(this._container);
- this._container = null;
- this._boxWidth = -1;
- },
-
- /**
- * Creates an element with a given identifier and tag name.
- *
- * @param aID
- * An identifier to create the element with.
- * @param aTagName
- * The name of the tag to create the element for.
- * @return the newly created element.
- */
- _createElement: function HSA__createElement(aID, aTagName) {
- let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- let element = document.createElementNS(XULNS, aTagName);
- element.id = aID;
- return element;
- },
-
- /**
- * Moves a given box to a given X coordinate position.
- *
- * @param aBox
- * The box element to position.
- * @param aPosition
- * The position (in X coordinates) to move the box element to.
- */
- _positionBox: function HSA__positionBox(aBox, aPosition) {
- aBox.style.transform = "translateX(" + this._boxWidth * aPosition + "px)";
- },
-
- /**
- * Takes a snapshot of the page the browser is currently on.
- */
- _takeSnapshot: function HSA__takeSnapshot() {
- if ((this._maxSnapshots < 1) ||
- (gBrowser.webNavigation.sessionHistory.index < 0))
- return;
-
- let browser = gBrowser.selectedBrowser;
- let r = browser.getBoundingClientRect();
- let canvas = document.createElementNS("http://www.w3.org/1999/xhtml",
- "canvas");
- canvas.mozOpaque = true;
- canvas.width = r.width;
- canvas.height = r.height;
- let ctx = canvas.getContext("2d");
- let zoom = browser.markupDocumentViewer.fullZoom;
- ctx.scale(zoom, zoom);
- ctx.drawWindow(browser.contentWindow, 0, 0, r.width, r.height, "white",
- ctx.DRAWWINDOW_DO_NOT_FLUSH | ctx.DRAWWINDOW_DRAW_VIEW |
- ctx.DRAWWINDOW_ASYNC_DECODE_IMAGES |
- ctx.DRAWWINDOW_USE_WIDGET_LAYERS);
-
- this._installCurrentPageSnapshot(canvas);
- this._assignSnapshotToCurrentBrowser(canvas);
- },
-
- /**
- * Retrieves the maximum number of snapshots that should be kept in memory.
- * This limit is a global limit and is valid across all open tabs.
- */
- _getMaxSnapshots: function HSA__getMaxSnapshots() {
- return gPrefService.getIntPref("browser.snapshots.limit");
- },
-
- /**
- * Adds a snapshot to the list and initiates the compression of said snapshot.
- * Once the compression is completed, it will replace the uncompressed
- * snapshot in the list.
- *
- * @param aCanvas
- * The snapshot to add to the list and compress.
- */
- _assignSnapshotToCurrentBrowser:
- function HSA__assignSnapshotToCurrentBrowser(aCanvas) {
- let browser = gBrowser.selectedBrowser;
- let currIndex = browser.webNavigation.sessionHistory.index;
-
- this._removeTrackedSnapshot(currIndex, browser);
- this._addSnapshotRefToArray(currIndex, browser);
-
- if (!("snapshots" in browser))
- browser.snapshots = [];
- let snapshots = browser.snapshots;
- // Temporarily store the canvas as the compressed snapshot.
- // This avoids a blank page if the user swipes quickly
- // between pages before the compression could complete.
- snapshots[currIndex] = aCanvas;
-
- // Kick off snapshot compression.
- aCanvas.toBlob(function(aBlob) {
- snapshots[currIndex] = aBlob;
- }, "image/png"
- );
- },
-
- /**
- * Removes a snapshot identified by the browser and index in the array of
- * snapshots for that browser, if present. If no snapshot could be identified
- * the method simply returns without taking any action. If aIndex is negative,
- * all snapshots for a particular browser will be removed.
- *
- * @param aIndex
- * The index in history of the new snapshot, or negative value if all
- * snapshots for a browser should be removed.
- * @param aBrowser
- * The browser the new snapshot was taken in.
- */
- _removeTrackedSnapshot: function HSA__removeTrackedSnapshot(aIndex, aBrowser) {
- let arr = this._trackedSnapshots;
- let requiresExactIndexMatch = aIndex >= 0;
- for (let i = 0; i < arr.length; i++) {
- if ((arr[i].browser == aBrowser) &&
- (aIndex < 0 || aIndex == arr[i].index)) {
- delete aBrowser.snapshots[arr[i].index];
- arr.splice(i, 1);
- if (requiresExactIndexMatch)
- return; // Found and removed the only element.
- i--; // Make sure to revisit the index that we just removed an
- // element at.
- }
- }
- },
-
- /**
- * Adds a new snapshot reference for a given index and browser to the array
- * of references to tracked snapshots.
- *
- * @param aIndex
- * The index in history of the new snapshot.
- * @param aBrowser
- * The browser the new snapshot was taken in.
- */
- _addSnapshotRefToArray:
- function HSA__addSnapshotRefToArray(aIndex, aBrowser) {
- let id = { index: aIndex,
- browser: aBrowser };
- let arr = this._trackedSnapshots;
- arr.unshift(id);
-
- while (arr.length > this._maxSnapshots) {
- let lastElem = arr[arr.length - 1];
- delete lastElem.browser.snapshots[lastElem.index];
- arr.splice(-1, 1);
- }
- },
-
- /**
- * Converts a compressed blob to an Image object. In some situations
- * (especially during fast swiping) aBlob may still be a canvas, not a
- * compressed blob. In this case, we simply return the canvas.
- *
- * @param aBlob
- * The compressed blob to convert, or a canvas if a blob compression
- * couldn't complete before this method was called.
- * @return A new Image object representing the converted blob.
- */
- _convertToImg: function HSA__convertToImg(aBlob) {
- if (!aBlob)
- return null;
-
- // Return aBlob if it's still a canvas and not a compressed blob yet.
- if (aBlob instanceof HTMLCanvasElement)
- return aBlob;
-
- let img = new Image();
- let url = URL.createObjectURL(aBlob);
- img.onload = function() {
- URL.revokeObjectURL(url);
- };
- img.src = url;
- return img;
- },
-
- /**
- * Sets the snapshot of the current page to the snapshot passed as parameter,
- * or to the one previously stored for the current index in history if the
- * parameter is null.
- *
- * @param aCanvas
- * The snapshot to set the current page to. If this parameter is null,
- * the previously stored snapshot for this index (if any) will be used.
- */
- _installCurrentPageSnapshot:
- function HSA__installCurrentPageSnapshot(aCanvas) {
- let currSnapshot = aCanvas;
- if (!currSnapshot) {
- let snapshots = gBrowser.selectedBrowser.snapshots || {};
- let currIndex = this._historyIndex;
- if (currIndex in snapshots)
- currSnapshot = this._convertToImg(snapshots[currIndex]);
- }
- document.mozSetImageElement("historySwipeAnimationCurrentPageSnapshot",
- currSnapshot);
- },
-
- /**
- * Sets the snapshots of the previous and next pages to the snapshots
- * previously stored for their respective indeces.
- */
- _installPrevAndNextSnapshots:
- function HSA__installPrevAndNextSnapshots() {
- let snapshots = gBrowser.selectedBrowser.snapshots || [];
- let currIndex = this._historyIndex;
- let prevIndex = currIndex - 1;
- let prevSnapshot = null;
- if (prevIndex in snapshots)
- prevSnapshot = this._convertToImg(snapshots[prevIndex]);
- document.mozSetImageElement("historySwipeAnimationPreviousPageSnapshot",
- prevSnapshot);
-
- let nextIndex = currIndex + 1;
- let nextSnapshot = null;
- if (nextIndex in snapshots)
- nextSnapshot = this._convertToImg(snapshots[nextIndex]);
- document.mozSetImageElement("historySwipeAnimationNextPageSnapshot",
- nextSnapshot);
- },
-};
diff --git a/base/content/browser-menubar.inc b/base/content/browser-menubar.inc
deleted file mode 100644
index fc6bc76..0000000
--- a/base/content/browser-menubar.inc
+++ /dev/null
@@ -1,564 +0,0 @@
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# 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/.
-
- <menubar id="main-menubar"
- onpopupshowing="if (event.target.parentNode.parentNode == this &amp;&amp;
- !('@mozilla.org/widget/nativemenuservice;1' in Cc))
- this.setAttribute('openedwithkey',
- event.target.parentNode.openedWithKey);"
- style="border:0px;padding:0px;margin:0px;-moz-appearance:none">
- <menu id="file-menu" label="&fileMenu.label;"
- accesskey="&fileMenu.accesskey;">
- <menupopup id="menu_FilePopup">
- <menuitem id="menu_newNavigatorTab"
- label="&tabCmd.label;"
- command="cmd_newNavigatorTab"
- key="key_newNavigatorTab"
- accesskey="&tabCmd.accesskey;"/>
- <menuitem id="menu_newNavigator"
- label="&newNavigatorCmd.label;"
- accesskey="&newNavigatorCmd.accesskey;"
- key="key_newNavigator"
- command="cmd_newNavigator"/>
- <menuitem id="menu_newPrivateWindow"
- label="&newPrivateWindow.label;"
- accesskey="&newPrivateWindow.accesskey;"
- command="Tools:PrivateBrowsing"
- key="key_privatebrowsing"/>
- <menuitem id="menu_openLocation"
- class="show-only-for-keyboard"
- label="&openLocationCmd.label;"
- command="Browser:OpenLocation"
- key="focusURLBar"
- accesskey="&openLocationCmd.accesskey;"/>
- <menuitem id="menu_openFile"
- label="&openFileCmd.label;"
- command="Browser:OpenFile"
- key="openFileKb"
- accesskey="&openFileCmd.accesskey;"/>
- <menuitem id="menu_close"
- class="show-only-for-keyboard"
- label="&closeCmd.label;"
- key="key_close"
- accesskey="&closeCmd.accesskey;"
- command="cmd_close"/>
- <menuitem id="menu_closeWindow"
- class="show-only-for-keyboard"
- hidden="true"
- command="cmd_closeWindow"
- key="key_closeWindow"
- label="&closeWindow.label;"
- accesskey="&closeWindow.accesskey;"/>
- <menuseparator/>
- <menuitem id="menu_savePage"
- label="&savePageCmd.label;"
- accesskey="&savePageCmd.accesskey;"
- key="key_savePage"
- command="Browser:SavePage"/>
- <menuitem id="menu_sendLink"
- label="&emailPageCmd.label;"
- accesskey="&emailPageCmd.accesskey;"
- command="Browser:SendLink"/>
- <menuseparator/>
- <menuitem id="menu_printSetup"
- label="&printSetupCmd.label;"
- accesskey="&printSetupCmd.accesskey;"
- command="cmd_pageSetup"/>
-#ifndef XP_MACOSX
- <menuitem id="menu_printPreview"
- label="&printPreviewCmd.label;"
- accesskey="&printPreviewCmd.accesskey;"
- command="cmd_printPreview"/>
-#endif
- <menuitem id="menu_print"
- label="&printCmd.label;"
- accesskey="&printCmd.accesskey;"
- key="printKb"
- command="cmd_print"/>
- <menuseparator/>
- <menuitem id="goOfflineMenuitem"
- label="&goOfflineCmd.label;"
- accesskey="&goOfflineCmd.accesskey;"
- type="checkbox"
- observes="workOfflineMenuitemState"
- oncommand="BrowserOffline.toggleOfflineStatus();"/>
- <menuitem id="menu_restart"
- label="&restartCmd.label;"
- accesskey="&restartCmd.accesskey;"
- command="cmd_restartApplication"/>
- <menuitem id="menu_FileQuitItem"
-#ifdef XP_WIN
- label="&quitApplicationCmdWin.label;"
- accesskey="&quitApplicationCmdWin.accesskey;"
-#else
-#ifdef XP_MACOSX
- label="&quitApplicationCmdMac.label;"
-#else
- label="&quitApplicationCmd.label;"
- accesskey="&quitApplicationCmd.accesskey;"
-#endif
-#ifdef XP_UNIX
- key="key_quitApplication"
-#endif
-#endif
- command="cmd_quitApplication"/>
- </menupopup>
- </menu>
-
- <menu id="edit-menu" label="&editMenu.label;"
- accesskey="&editMenu.accesskey;">
- <menupopup id="menu_EditPopup"
- onpopupshowing="updateEditUIVisibility()"
- onpopuphidden="updateEditUIVisibility()">
- <menuitem id="menu_undo"
- label="&undoCmd.label;"
- key="key_undo"
- accesskey="&undoCmd.accesskey;"
- command="cmd_undo"/>
- <menuitem id="menu_redo"
- label="&redoCmd.label;"
- key="key_redo"
- accesskey="&redoCmd.accesskey;"
- command="cmd_redo"/>
- <menuseparator/>
- <menuitem id="menu_cut"
- label="&cutCmd.label;"
- key="key_cut"
- accesskey="&cutCmd.accesskey;"
- command="cmd_cut"/>
- <menuitem id="menu_copy"
- label="&copyCmd.label;"
- key="key_copy"
- accesskey="&copyCmd.accesskey;"
- command="cmd_copy"/>
- <menuitem id="menu_paste"
- label="&pasteCmd.label;"
- key="key_paste"
- accesskey="&pasteCmd.accesskey;"
- command="cmd_paste"/>
- <menuitem id="menu_delete"
- label="&deleteCmd.label;"
- key="key_delete"
- accesskey="&deleteCmd.accesskey;"
- command="cmd_delete"/>
- <menuseparator/>
- <menuitem id="menu_selectAll"
- label="&selectAllCmd.label;"
- key="key_selectAll"
- accesskey="&selectAllCmd.accesskey;"
- command="cmd_selectAll"/>
- <menuseparator/>
- <menuitem id="menu_find"
- label="&findOnCmd.label;"
- accesskey="&findOnCmd.accesskey;"
- key="key_find"
- command="cmd_find"/>
- <menuitem id="menu_findAgain"
- class="show-only-for-keyboard"
- label="&findAgainCmd.label;"
- accesskey="&findAgainCmd.accesskey;"
- key="key_findAgain"
- command="cmd_findAgain"/>
- <menuseparator hidden="true" id="textfieldDirection-separator"/>
- <menuitem id="textfieldDirection-swap"
- command="cmd_switchTextDirection"
- key="key_switchTextDirection"
- label="&bidiSwitchTextDirectionItem.label;"
- accesskey="&bidiSwitchTextDirectionItem.accesskey;"
- hidden="true"/>
- </menupopup>
- </menu>
-
- <menu id="view-menu" label="&viewMenu.label;"
- accesskey="&viewMenu.accesskey;">
- <menupopup id="menu_viewPopup"
- onpopupshowing="updateCharacterEncodingMenuState();">
- <menu id="viewToolbarsMenu"
- label="&viewToolbarsMenu.label;"
- accesskey="&viewToolbarsMenu.accesskey;">
- <menupopup onpopupshowing="onViewToolbarsPopupShowing(event);">
- <menuseparator/>
- <menuitem id="menu_tabsOnTop"
- command="cmd_ToggleTabsOnTop"
- type="checkbox"
- label="&viewTabsOnTop.label;"
- accesskey="&viewTabsOnTop.accesskey;"/>
- <menuitem id="menu_customizeToolbars"
- label="&viewCustomizeToolbar.label;"
- accesskey="&viewCustomizeToolbar.accesskey;"
- command="cmd_CustomizeToolbars"/>
- </menupopup>
- </menu>
- <menu id="viewSidebarMenuMenu"
- label="&viewSidebarMenu.label;"
- accesskey="&viewSidebarMenu.accesskey;">
- <menupopup id="viewSidebarMenu">
- <menuitem id="menu_bookmarksSidebar"
- key="viewBookmarksSidebarKb"
- observes="viewBookmarksSidebar"
- label="&bookmarksButton.label;"/>
- <menuitem id="menu_historySidebar"
- key="key_gotoHistory"
- observes="viewHistorySidebar"
- label="&historyButton.label;"/>
- </menupopup>
- </menu>
- <menuseparator/>
- <menuitem id="menu_stop"
- class="show-only-for-keyboard"
- label="&stopCmd.label;"
- accesskey="&stopCmd.accesskey;"
- command="Browser:Stop"
-#ifdef XP_MACOSX
- key="key_stop_mac"/>
-#else
- key="key_stop"/>
-#endif
- <menuitem id="menu_reload"
- class="show-only-for-keyboard"
- label="&reloadCmd.label;"
- accesskey="&reloadCmd.accesskey;"
- key="key_reload"
- command="Browser:ReloadOrDuplicate"
- onclick="checkForMiddleClick(this, event);"/>
- <menuseparator class="show-only-for-keyboard"/>
- <menu id="viewFullZoomMenu" label="&fullZoom.label;"
- accesskey="&fullZoom.accesskey;"
- onpopupshowing="FullZoom.updateMenu();">
- <menupopup>
- <menuitem id="menu_zoomEnlarge"
- key="key_fullZoomEnlarge"
- label="&fullZoomEnlargeCmd.label;"
- accesskey="&fullZoomEnlargeCmd.accesskey;"
- command="cmd_fullZoomEnlarge"/>
- <menuitem id="menu_zoomReduce"
- key="key_fullZoomReduce"
- label="&fullZoomReduceCmd.label;"
- accesskey="&fullZoomReduceCmd.accesskey;"
- command="cmd_fullZoomReduce"/>
- <menuseparator/>
- <menuitem id="menu_zoomReset"
- key="key_fullZoomReset"
- label="&fullZoomResetCmd.label;"
- accesskey="&fullZoomResetCmd.accesskey;"
- command="cmd_fullZoomReset"/>
- <menuseparator/>
- <menuitem id="toggle_zoom"
- label="&fullZoomToggleCmd.label;"
- accesskey="&fullZoomToggleCmd.accesskey;"
- type="checkbox"
- command="cmd_fullZoomToggle"
- checked="false"/>
- </menupopup>
- </menu>
- <menu id="pageStyleMenu" label="&pageStyleMenu.label;"
- accesskey="&pageStyleMenu.accesskey;" observes="isImage">
- <menupopup onpopupshowing="gPageStyleMenu.fillPopup(this);">
- <menuitem id="menu_pageStyleNoStyle"
- label="&pageStyleNoStyle.label;"
- accesskey="&pageStyleNoStyle.accesskey;"
- oncommand="gPageStyleMenu.disableStyle();"
- type="radio"/>
- <menuitem id="menu_pageStylePersistentOnly"
- label="&pageStylePersistentOnly.label;"
- accesskey="&pageStylePersistentOnly.accesskey;"
- oncommand="gPageStyleMenu.switchStyleSheet('');"
- type="radio"
- checked="true"/>
- <menuseparator/>
- </menupopup>
- </menu>
-#include browser-charsetmenu.inc
- <menuseparator/>
-#ifdef XP_MACOSX
- <menuitem id="enterFullScreenItem"
- accesskey="&enterFullScreenCmd.accesskey;"
- label="&enterFullScreenCmd.label;"
- key="key_fullScreen">
- <observes element="View:FullScreen" attribute="oncommand"/>
- <observes element="View:FullScreen" attribute="disabled"/>
- </menuitem>
- <menuitem id="exitFullScreenItem"
- accesskey="&exitFullScreenCmd.accesskey;"
- label="&exitFullScreenCmd.label;"
- key="key_fullScreen"
- hidden="true">
- <observes element="View:FullScreen" attribute="oncommand"/>
- <observes element="View:FullScreen" attribute="disabled"/>
- </menuitem>
-#else
- <menuitem id="fullScreenItem"
- accesskey="&fullScreenCmd.accesskey;"
- label="&fullScreenCmd.label;"
- key="key_fullScreen"
- type="checkbox"
- observes="View:FullScreen"/>
-#endif
- <menuitem id="menu_showAllTabs"
- hidden="true"
- accesskey="&showAllTabsCmd.accesskey;"
- label="&showAllTabsCmd.label;"
- command="Browser:ShowAllTabs"
- key="key_showAllTabs"/>
- <menuseparator hidden="true" id="documentDirection-separator"/>
- <menuitem id="documentDirection-swap"
- hidden="true"
- label="&bidiSwitchPageDirectionItem.label;"
- accesskey="&bidiSwitchPageDirectionItem.accesskey;"
- oncommand="SwitchDocumentDirection(window.content)"/>
- </menupopup>
- </menu>
-
- <menu id="history-menu"
- label="&historyMenu.label;"
- accesskey="&historyMenu.accesskey;">
- <menupopup id="goPopup"
-#ifndef XP_MACOSX
- placespopup="true"
-#endif
- context="placesContext"
- oncommand="this.parentNode._placesView._onCommand(event);"
- onclick="checkForMiddleClick(this, event);"
- onpopupshowing="if (!this.parentNode._placesView)
- new HistoryMenu(event);"
- tooltip="bhTooltip"
- popupsinherittooltip="true">
- <menuitem id="historyMenuBack"
- class="show-only-for-keyboard"
- label="&backCmd.label;"
-#ifdef XP_MACOSX
- key="goBackKb2"
-#else
- key="goBackKb"
-#endif
- command="Browser:BackOrBackDuplicate"
- onclick="checkForMiddleClick(this, event);"/>
- <menuitem id="historyMenuForward"
- class="show-only-for-keyboard"
- label="&forwardCmd.label;"
-#ifdef XP_MACOSX
- key="goForwardKb2"
-#else
- key="goForwardKb"
-#endif
- command="Browser:ForwardOrForwardDuplicate"
- onclick="checkForMiddleClick(this, event);"/>
- <menuitem id="historyMenuHome"
- class="show-only-for-keyboard"
- label="&historyHomeCmd.label;"
- oncommand="BrowserGoHome(event);"
- onclick="checkForMiddleClick(this, event);"
- key="goHome"/>
- <menuseparator id="historyMenuHomeSeparator"
- class="show-only-for-keyboard"/>
- <menuitem id="menu_showAllHistory"
- label="&showAllHistoryCmd2.label;"
-#ifndef XP_MACOSX
- class="menuitem-iconic"
- key="showAllHistoryKb"
-#endif
- command="Browser:ShowAllHistory"/>
- <menuitem id="sanitizeItem"
-#ifndef XP_MACOSX
- class="menuitem-iconic"
-#endif
- label="&clearRecentHistory.label;"
- key="key_sanitize"
- command="Tools:Sanitize"/>
- <menuseparator id="sanitizeSeparator"/>
-#ifdef MOZ_SERVICES_SYNC
- <menuitem id="sync-tabs-menuitem"
- class="syncTabsMenuItem"
- label="&syncTabsMenu2.label;"
- oncommand="BrowserOpenSyncTabs();"
- disabled="true"/>
-#endif
- <menuitem id="historyRestoreLastSession"
- label="&historyRestoreLastSession.label;"
- command="Browser:RestoreLastSession"/>
- <menu id="historyUndoMenu"
- class="recentlyClosedTabsMenu"
- label="&historyUndoMenu.label;"
- disabled="true">
- <menupopup id="historyUndoPopup"
-#ifndef XP_MACOSX
- placespopup="true"
-#endif
- onpopupshowing="document.getElementById('history-menu')._placesView.populateUndoSubmenu();"/>
- </menu>
- <menu id="historyUndoWindowMenu"
- class="recentlyClosedWindowsMenu"
- label="&historyUndoWindowMenu.label;"
- disabled="true">
- <menupopup id="historyUndoWindowPopup"
-#ifndef XP_MACOSX
- placespopup="true"
-#endif
- onpopupshowing="document.getElementById('history-menu')._placesView.populateUndoWindowSubmenu();"/>
- </menu>
- <menuseparator id="startHistorySeparator"
- class="hide-if-empty-places-result"/>
- </menupopup>
- </menu>
-
- <menu id="bookmarksMenu"
- label="&bookmarksMenu.label;"
- accesskey="&bookmarksMenu.accesskey;"
- ondragenter="PlacesMenuDNDHandler.onDragEnter(event);"
- ondragover="PlacesMenuDNDHandler.onDragOver(event);"
- ondrop="PlacesMenuDNDHandler.onDrop(event);">
- <menupopup id="bookmarksMenuPopup"
-#ifndef XP_MACOSX
- placespopup="true"
-#endif
- context="placesContext"
- openInTabs="children"
- oncommand="BookmarksEventHandler.onCommand(event, this.parentNode._placesView);"
- onclick="BookmarksEventHandler.onClick(event, this.parentNode._placesView);"
- onpopupshowing="PlacesCommandHook.updateBookmarkAllTabsCommand();
- if (!this.parentNode._placesView)
- new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
- tooltip="bhTooltip" popupsinherittooltip="true">
- <menuitem id="bookmarksShowAll"
-#ifndef XP_MACOSX
- class="menuitem-iconic"
-#endif
- label="&organizeBookmarks.label;"
- command="Browser:ShowAllBookmarks"
- key="manBookmarkKb"/>
- <menuseparator id="organizeBookmarksSeparator"/>
- <menuitem id="menu_bookmarkThisPage"
-#ifndef XP_MACOSX
- class="menuitem-iconic"
-#endif
- label="&bookmarkThisPageCmd.label;"
- command="Browser:AddBookmarkAs"
- key="addBookmarkAsKb"/>
- <menuitem id="subscribeToPageMenuitem"
-#ifndef XP_MACOSX
- class="menuitem-iconic"
-#endif
- label="&subscribeToPageMenuitem.label;"
- oncommand="return FeedHandler.subscribeToFeed(null, event);"
- onclick="checkForMiddleClick(this, event);"
- observes="singleFeedMenuitemState"/>
- <menu id="subscribeToPageMenupopup"
-#ifndef XP_MACOSX
- class="menu-iconic"
-#endif
- label="&subscribeToPageMenupopup.label;"
- observes="multipleFeedsMenuState">
- <menupopup id="subscribeToPageSubmenuMenupopup"
- onpopupshowing="return FeedHandler.buildFeedList(event.target);"
- oncommand="return FeedHandler.subscribeToFeed(null, event);"
- onclick="checkForMiddleClick(this, event);"/>
- </menu>
- <menuitem id="menu_bookmarkAllTabs"
- label="&addCurPagesCmd.label;"
- class="show-only-for-keyboard"
- command="Browser:BookmarkAllTabs"
- key="bookmarkAllTabsKb"/>
- <menuseparator id="bookmarksToolbarSeparator"/>
- <menu id="bookmarksToolbarFolderMenu"
- class="menu-iconic bookmark-item"
- label="&personalbarCmd.label;"
- container="true">
- <menupopup id="bookmarksToolbarFolderPopup"
-#ifndef XP_MACOSX
- placespopup="true"
-#endif
- context="placesContext"
- onpopupshowing="if (!this.parentNode._placesView)
- new PlacesMenu(event, 'place:folder=TOOLBAR');"/>
- </menu>
- <menuseparator id="bookmarksMenuItemsSeparator"/>
- <!-- Bookmarks menu items -->
- <menuseparator builder="end"
- class="hide-if-empty-places-result"/>
- <menuitem id="menu_unsortedBookmarks"
-#ifndef XP_MACOSX
- class="menuitem-iconic"
-#endif
- label="&unsortedBookmarksCmd.label;"
- oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"/>
- </menupopup>
- </menu>
-
- <menu id="tools-menu"
- label="&toolsMenu.label;"
- accesskey="&toolsMenu.accesskey;">
- <menupopup id="menu_ToolsPopup"
-#ifdef MOZ_SERVICES_SYNC
- onpopupshowing="gSyncUI.updateUI();"
-#endif
- >
- <menuitem id="menu_search"
- class="show-only-for-keyboard"
- label="&search.label;"
- accesskey="&search.accesskey;"
- key="key_search"
- command="Tools:Search"/>
- <menuseparator id="browserToolsSeparator"
- class="show-only-for-keyboard"/>
- <menuitem id="menu_openDownloads"
- label="&downloads.label;"
- accesskey="&downloads.accesskey;"
- key="key_openDownloads"
- command="Tools:Downloads"/>
- <menuitem id="menu_openAddons"
- label="&addons.label;"
- accesskey="&addons.accesskey;"
- key="key_openAddons"
- command="Tools:Addons"/>
- <menuitem id="menu_openPermissions"
- label="&permissions.label;"
- command="Tools:Permissions"
- accesskey="&permissions.accesskey;"/>
-#ifdef MOZ_SERVICES_SYNC
- <!-- only one of sync-setup or sync-menu will be showing at once -->
- <menuitem id="sync-setup"
- label="&syncSetup.label;"
- accesskey="&syncSetup.accesskey;"
- observes="sync-setup-state"
- oncommand="gSyncUI.openSetup()"/>
- <menuitem id="sync-syncnowitem"
- label="&syncSyncNowItem.label;"
- accesskey="&syncSyncNowItem.accesskey;"
- observes="sync-syncnow-state"
- oncommand="gSyncUI.doSync(event);"/>
-#endif
- <menuseparator id="devToolsSeparator"/>
- <menu id="webDeveloperMenu"
- label="&webDeveloperMenu.label;"
- accesskey="&webDeveloperMenu.accesskey;">
- <menupopup id="menuWebDeveloperPopup">
- <menuitem id="menu_pageSource"
- observes="devtoolsMenuBroadcaster_PageSource"
- accesskey="&pageSourceCmd.accesskey;"/>
- <menuitem id="javascriptConsole"
- observes="devtoolsMenuBroadcaster_ErrorConsole"
- accesskey="&errorConsoleCmd.accesskey;"/>
- </menupopup>
- </menu>
- <menuitem id="menu_pageInfo"
- accesskey="&pageInfoCmd.accesskey;"
- label="&pageInfoCmd.label;"
-#ifndef XP_WIN
- key="key_viewInfo"
-#endif
- command="View:PageInfo"/>
- <menuseparator id="prefSep"/>
- <menuitem id="menu_preferences"
- label="&preferencesCmd2.label;"
- accesskey="&preferencesCmd2.accesskey;"
- oncommand="openPreferences();"/>
- </menupopup>
- </menu>
-
-#ifdef XP_MACOSX
- <menu id="windowMenu" />
-#endif
- <menu id="helpMenu" />
- </menubar>
diff --git a/base/content/browser-menudragging.js b/base/content/browser-menudragging.js
deleted file mode 100644
index f3f00d7..0000000
--- a/base/content/browser-menudragging.js
+++ /dev/null
@@ -1,340 +0,0 @@
-// 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/.
-//
-// Based on original code by alice0775 https://github.com/alice0775
-
-
-"use strict";
-var browserMenuDragging = {
- //-- config --
- STAY_OPEN_ONDRAGEXIT: false,
- DEBUG: false,
- //-- config --
-
- menupopup: ['bookmarksMenuPopup',
- 'PlacesToolbar',
- 'BMB_bookmarksPopup',
- 'appmenu_bookmarksPopup',
- 'BookmarksMenuToolButtonPopup',
- 'UnsortedBookmarksFolderToolButtonPopup',
- 'bookmarksMenuPopup-context'],
- timer:[],
- count:[],
-
-
- init: function(){
- window.removeEventListener('load', this, false);
- window.addEventListener('unload', this, false);
- this.addPrefListener(this.PrefListener);
-
- window.addEventListener('aftercustomization', this, false);
-
- this.initPref();
- this.delayedStartup();
- },
-
- uninit: function(){
- window.removeEventListener('unload', this, false);
- this.removePrefListener(this.PrefListener);
-
- window.removeEventListener('aftercustomization', this, false);
-
- for (var i = 0; i < this.menupopup.length; i++){
- var menupopup = document.getElementById(this.menupopup[i]);
- if (menupopup){
- menupopup.removeEventListener('popupshowing', this, false);
- menupopup.removeEventListener('popuphiding', this, false);
- }
- }
-
- },
-
- initPref: function(){
- this.STAY_OPEN_ONDRAGEXIT =
- Services.prefs.getBoolPref('browser.menu.dragging.stayOpen', false);
- this.DEBUG =
- Services.prefs.getBoolPref('browser.menu.dragging.debug', false);
- },
-
- //delayed startup
- delayedStartup: function(){
- //wait until construction of bookmarksBarContent is completed.
- for (var i = 0; i < this.menupopup.length; i++){
- this.count[i] = 0;
- this.timer[i] = setInterval(function(self, i){
- if(++self.count[i] > 50 || document.getElementById(self.menupopup[i])){
- clearInterval(self.timer[i]);
- var menupopup = document.getElementById(self.menupopup[i]);
- if (menupopup) {
- menupopup.addEventListener('popupshowing', self, false);
- menupopup.addEventListener('popuphiding', self, false);
- }
- }
- }, 250, this, i);
- }
- },
-
- handleEvent: function(event){
- switch (event.type) {
- case 'popupshowing':
- this.popupshowing(event);
- break;
- case 'popuphiding':
- this.popuphiding(event);
- break;
- case 'aftercustomization':
- setTimeout(function(self){self.delayedStartup(self);}, 0, this);
- break;
- case 'load':
- this.init();
- break;
- case 'unload':
- this.uninit();
- break;
- }
- },
-
- popuphiding: function(event) {
- var menupopup = event.originalTarget;
- menupopup.parentNode.parentNode.openNode = null;
-
- if (menupopup.parentNode.localName == 'toolbarbutton') {
- // Fix for Bug 225434 - dragging bookmark from personal toolbar and releasing
- // (on same bookmark or elsewhere) or clicking on bookmark menu then cancelling
- // leaves button depressed/sunken when hovered
- menupopup.parentNode.parentNode._openedMenuButton = null;
-
- if (!PlacesControllerDragHelper.getSession())
- // Clear the dragover attribute if present, if we are dragging into a
- // folder in the hierachy of current opened popup we don't clear
- // this attribute on clearOverFolder. See Notify for closeTimer.
- if (menupopup.parentNode.hasAttribute('dragover'))
- menupopup.parentNode.removeAttribute('dragover');
- }
- },
-
- popupshowing: function(event) {
- var menupopup = event.originalTarget;
- browserMenuDragging.debug("popupshowing ===============\n" + menupopup.parentNode.getAttribute('label'));
-
- var parentPopup = menupopup.parentNode.parentNode;
-
- if (!!parentPopup.openNode){
- try {
- parentPopup.openNode.hidePopup();
- } catch(e){}
- }
- parentPopup.openNode = menupopup;
-
- menupopup.onDragStart = function (event) {
- // Bug 555474 - While bookmark is dragged, the tooltip should not appear
- browserMenuDragging.hideTooltip();
- }
-
- menupopup.onDragOver = function (event) {
- // Bug 555474 - While bookmark is dragged, the tooltip should not appear
- browserMenuDragging.hideTooltip();
-
- var target = event.originalTarget;
- while (target) {
- if (/menupopup/.test(target.localName))
- break;
- target = target.parentNode;
- }
- if (this != target)
- return;
- event.stopPropagation();
- browserMenuDragging.debug("onDragOver " + "\n" + this.parentNode.getAttribute('label'));
-
- PlacesControllerDragHelper.currentDropTarget = event.target;
- let dt = event.dataTransfer;
-
- let dropPoint = this._getDropPoint(event);
-
- if (!dropPoint || !dropPoint.ip ||
- !PlacesControllerDragHelper.canDrop(dropPoint.ip, dt)) {
- this._indicatorBar.hidden = true;
- event.stopPropagation();
- return;
- }
-
- // Mark this popup as being dragged over.
- this.setAttribute('dragover', 'true');
-
- if (dropPoint.folderElt) {
- // We are dragging over a folder.
- // _overFolder should take the care of opening it on a timer.
- if (this._overFolder.elt &&
- this._overFolder.elt != dropPoint.folderElt) {
- }
- if (!this._overFolder.elt) {
- this._overFolder.elt = dropPoint.folderElt;
- // Create the timer to open this folder.
- this._overFolder.openTimer = this._overFolder
- .setTimer(this._overFolder.hoverTime);
- }
- }
- else {
- // We are not dragging over a folder.
- }
-
- // Autoscroll the popup strip if we drag over the scroll buttons.
- let anonid = event.originalTarget.getAttribute('anonid');
- let scrollDir = anonid == 'scrollbutton-up' ? -1 :
- anonid == 'scrollbutton-down' ? 1 : 0;
- if (scrollDir != 0) {
- this._scrollBox.scrollByIndex(scrollDir, false);
- }
-
- // Check if we should hide the drop indicator for this target.
- if (dropPoint.folderElt || this._hideDropIndicator(event)) {
- this._indicatorBar.hidden = true;
- event.preventDefault();
- event.stopPropagation();
- return;
- }
-
- // We should display the drop indicator relative to the arrowscrollbox.
- let sbo = this._scrollBox.scrollBoxObject;
- let newMarginTop = 0;
- if (scrollDir == 0) {
- let elt = this.firstChild;
- while (elt && event.screenY > elt.boxObject.screenY +
- elt.boxObject.height / 2)
- elt = elt.nextSibling;
- newMarginTop = elt ? elt.boxObject.screenY - sbo.screenY :
- sbo.height;
- }
- else if (scrollDir == 1)
- newMarginTop = sbo.height;
-
- // Set the new marginTop based on arrowscrollbox.
- newMarginTop += sbo.y - this._scrollBox.boxObject.y;
- this._indicatorBar.firstChild.style.marginTop = newMarginTop + 'px';
- this._indicatorBar.hidden = false;
-
- event.preventDefault();
- event.stopPropagation();
- }
-
- menupopup.onDragExit = function (event) {
- var target = event.originalTarget;
- while (target) {
- if (/menupopup/.test(target.localName))
- break;
- target = target.parentNode;
- }
- if (this != target)
- return;
- event.stopPropagation();
- browserMenuDragging.debug("onDragExit " + browserMenuDragging.STAY_OPEN_ONDRAGEXIT);
-
- PlacesControllerDragHelper.currentDropTarget = null;
- this.removeAttribute('dragover');
-
- // If we have not moved to a valid new target clear the drop indicator
- // this happens when moving out of the popup.
- target = event.relatedTarget;
- if (!target)
- this._indicatorBar.hidden = true;
-
- // Close any folder being hovered over
- if (this._overFolder.elt) {
- this._overFolder.closeTimer = this._overFolder
- .setTimer(this._overFolder.hoverTime);
- }
-
- // The auto-opened attribute is set when this folder was automatically
- // opened after the user dragged over it. If this attribute is set,
- // auto-close the folder on drag exit.
- // We should also try to close this popup if the drag has started
- // from here, the timer will check if we are dragging over a child.
- if (this.hasAttribute('autoopened') ||
- !browserMenuDragging.STAY_OPEN_ONDRAGEXIT &&
- this.hasAttribute('dragstart')) {
- this._overFolder.closeMenuTimer = this._overFolder
- .setTimer(this._overFolder.hoverTime);
- }
-
- event.stopPropagation();
- }
-
- menupopup.addEventListener('dragstart', menupopup.onDragStart, true);
- menupopup.addEventListener('dragover', menupopup.onDragOver, true);
- menupopup.addEventListener('dragleave', menupopup.onDragExit, true);
- },
-
- hideTooltip: function() {
- ['bhTooltip', 'btTooltip2'].forEach(function(id) {
- var tooltip = document.getElementById(id);
- if (tooltip)
- tooltip.hidePopup();
- });
- },
-
- get getVer(){
- const Cc = Components.classes;
- const Ci = Components.interfaces;
- var info = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
- var ver = parseInt(info.version.substr(0,3) * 10,10) / 10;
- return ver;
- },
-
- debug: function(aMsg){
- if (!browserMenuDragging.DEBUG)
- return;
- Components.classes["@mozilla.org/consoleservice;1"]
- .getService(Components.interfaces.nsIConsoleService)
- .logStringMessage(aMsg);
- },
-
- setPref: function(aPrefString, aPrefType, aValue){
- var xpPref = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefService);
- try{
- switch (aPrefType){
- case 'complex':
- return xpPref.setComplexValue(aPrefString, Components.interfaces.nsILocalFile, aValue); break;
- case 'str':
- return xpPref.setCharPref(aPrefString, aValue); break;
- case 'int':
- aValue = parseInt(aValue);
- return xpPref.setIntPref(aPrefString, aValue); break;
- case 'bool':
- default:
- return xpPref.setBoolPref(aPrefString, aValue); break;
- }
- }catch(e){
- }
- return null;
- },
-
- addPrefListener: function(aObserver) {
- try {
- var pbi = Components.classes["@mozilla.org/preferences;1"].
- getService(Components.interfaces.nsIPrefBranch2);
- pbi.addObserver(aObserver.domain, aObserver, false);
- } catch(e) {}
- },
-
- removePrefListener: function(aObserver) {
- try {
- var pbi = Components.classes["@mozilla.org/preferences;1"].
- getService(Components.interfaces.nsIPrefBranch2);
- pbi.removeObserver(aObserver.domain, aObserver);
- } catch(e) {}
- },
-
- PrefListener:{
- domain : 'browser.menu.dragging.stayOpen',
-
- observe : function(aSubject, aTopic, aPrefstring) {
- if (aTopic == 'nsPref:changed') {
- browserMenuDragging.initPref();
- }
- }
- }
-}
-
-window.addEventListener('load', browserMenuDragging, false); \ No newline at end of file
diff --git a/base/content/browser-menudragging.xul b/base/content/browser-menudragging.xul
deleted file mode 100644
index f5cabe5..0000000
--- a/base/content/browser-menudragging.xul
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0"?>
-
-
-<overlay id="menuDraggingOverlay"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<window id="main-window">
-
- <script type="application/x-javascript" src="chrome://browser/content/browser-menudragging.js" />
-
-</window>
-
-</overlay>
diff --git a/base/content/browser-places.js b/base/content/browser-places.js
deleted file mode 100644
index 590fe7e..0000000
--- a/base/content/browser-places.js
+++ /dev/null
@@ -1,1316 +0,0 @@
-# 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/.
-
-////////////////////////////////////////////////////////////////////////////////
-//// StarUI
-
-var StarUI = {
- _itemId: -1,
- uri: null,
- _batching: false,
-
- _element: function(aID) {
- return document.getElementById(aID);
- },
-
- // Edit-bookmark panel
- get panel() {
- delete this.panel;
- var element = this._element("editBookmarkPanel");
- // initially the panel is hidden
- // to avoid impacting startup / new window performance
- element.hidden = false;
- element.addEventListener("popuphidden", this, false);
- element.addEventListener("keypress", this, false);
- return this.panel = element;
- },
-
- // Array of command elements to disable when the panel is opened.
- get _blockedCommands() {
- delete this._blockedCommands;
- return this._blockedCommands =
- ["cmd_close", "cmd_closeWindow"].map(function (id) this._element(id), this);
- },
-
- _blockCommands: function SU__blockCommands() {
- this._blockedCommands.forEach(function (elt) {
- // make sure not to permanently disable this item (see bug 409155)
- if (elt.hasAttribute("wasDisabled"))
- return;
- if (elt.getAttribute("disabled") == "true") {
- elt.setAttribute("wasDisabled", "true");
- } else {
- elt.setAttribute("wasDisabled", "false");
- elt.setAttribute("disabled", "true");
- }
- });
- },
-
- _restoreCommandsState: function SU__restoreCommandsState() {
- this._blockedCommands.forEach(function (elt) {
- if (elt.getAttribute("wasDisabled") != "true")
- elt.removeAttribute("disabled");
- elt.removeAttribute("wasDisabled");
- });
- },
-
- // nsIDOMEventListener
- handleEvent: function SU_handleEvent(aEvent) {
- switch (aEvent.type) {
- case "popuphidden":
- if (aEvent.originalTarget == this.panel) {
- if (!this._element("editBookmarkPanelContent").hidden)
- this.quitEditMode();
-
- this._restoreCommandsState();
- this._itemId = -1;
- if (this._batching) {
- PlacesUtils.transactionManager.endBatch(false);
- this._batching = false;
- }
-
- switch (this._actionOnHide) {
- case "cancel": {
- PlacesUtils.transactionManager.undoTransaction();
- break;
- }
- case "remove": {
- // Remove all bookmarks for the bookmark's url, this also removes
- // the tags for the url.
- PlacesUtils.transactionManager.beginBatch(null);
- let itemIds = PlacesUtils.getBookmarksForURI(this._uriForRemoval);
- for (let i = 0; i < itemIds.length; i++) {
- let txn = new PlacesRemoveItemTransaction(itemIds[i]);
- PlacesUtils.transactionManager.doTransaction(txn);
- }
- PlacesUtils.transactionManager.endBatch(false);
- break;
- }
- }
- this._actionOnHide = "";
- }
- break;
- case "keypress":
- if (aEvent.defaultPrevented) {
- // The event has already been consumed inside of the panel.
- break;
- }
- switch (aEvent.keyCode) {
- case KeyEvent.DOM_VK_ESCAPE:
- if (!this._element("editBookmarkPanelContent").hidden)
- this.cancelButtonOnCommand();
- break;
- case KeyEvent.DOM_VK_RETURN:
- if (aEvent.target.className == "expander-up" ||
- aEvent.target.className == "expander-down" ||
- aEvent.target.id == "editBMPanel_newFolderButton") {
- //XXX Why is this necessary? The defaultPrevented check should
- // be enough.
- break;
- }
- this.panel.hidePopup();
- break;
- }
- break;
- }
- },
-
- _overlayLoaded: false,
- _overlayLoading: false,
- showEditBookmarkPopup:
- function SU_showEditBookmarkPopup(aItemId, aAnchorElement, aPosition) {
- // Performance: load the overlay the first time the panel is opened
- // (see bug 392443).
- if (this._overlayLoading)
- return;
-
- if (this._overlayLoaded) {
- this._doShowEditBookmarkPanel(aItemId, aAnchorElement, aPosition);
- return;
- }
-
- this._overlayLoading = true;
- document.loadOverlay(
- "chrome://browser/content/places/editBookmarkOverlay.xul",
- (function (aSubject, aTopic, aData) {
- //XXX We just caused localstore.rdf to be re-applied (bug 640158)
- retrieveToolbarIconsizesFromTheme();
-
- // Move the header (star, title, button) into the grid,
- // so that it aligns nicely with the other items (bug 484022).
- let header = this._element("editBookmarkPanelHeader");
- let rows = this._element("editBookmarkPanelGrid").lastChild;
- rows.insertBefore(header, rows.firstChild);
- header.hidden = false;
-
- this._overlayLoading = false;
- this._overlayLoaded = true;
- this._doShowEditBookmarkPanel(aItemId, aAnchorElement, aPosition);
- }).bind(this)
- );
- },
-
- _doShowEditBookmarkPanel:
- function SU__doShowEditBookmarkPanel(aItemId, aAnchorElement, aPosition) {
- if (this.panel.state != "closed")
- return;
-
- this._blockCommands(); // un-done in the popuphiding handler
-
- // Set panel title:
- // if we are batching, i.e. the bookmark has been added now,
- // then show Page Bookmarked, else if the bookmark did already exist,
- // we are about editing it, then use Edit This Bookmark.
- this._element("editBookmarkPanelTitle").value =
- this._batching ?
- gNavigatorBundle.getString("editBookmarkPanel.pageBookmarkedTitle") :
- gNavigatorBundle.getString("editBookmarkPanel.editBookmarkTitle");
-
- // No description; show the Done, Cancel;
- this._element("editBookmarkPanelDescription").textContent = "";
- this._element("editBookmarkPanelBottomButtons").hidden = false;
- this._element("editBookmarkPanelContent").hidden = false;
-
- // The remove button is shown only if we're not already batching, i.e.
- // if the cancel button/ESC does not remove the bookmark.
- this._element("editBookmarkPanelRemoveButton").hidden = this._batching;
-
- // The label of the remove button differs if the URI is bookmarked
- // multiple times.
- var bookmarks = PlacesUtils.getBookmarksForURI(gBrowser.currentURI);
- var forms = gNavigatorBundle.getString("editBookmark.removeBookmarks.label");
- var label = PluralForm.get(bookmarks.length, forms).replace("#1", bookmarks.length);
- this._element("editBookmarkPanelRemoveButton").label = label;
-
- // unset the unstarred state, if set
- this._element("editBookmarkPanelStarIcon").removeAttribute("unstarred");
-
- this._itemId = aItemId !== undefined ? aItemId : this._itemId;
- this.beginBatch();
-
- let onPanelReady = fn => {
- let target = this.panel;
- if (target.parentNode) {
- // By targeting the panel's parent and using a capturing listener, we
- // can have our listener called before others waiting for the panel to
- // be shown (which probably expect the panel to be fully initialized)
- target = target.parentNode;
- }
- target.addEventListener("popupshown", function(event) {
- fn();
- }, {"capture": true, "once": true});
- };
- gEditItemOverlay.initPanel(this._itemId,
- { onPanelReady,
- hiddenRows: ["description", "location",
- "loadInSidebar", "keyword"] });
-
- this.panel.openPopup(aAnchorElement, aPosition);
- },
-
- panelShown:
- function SU_panelShown(aEvent) {
- if (aEvent.target == this.panel) {
- if (!this._element("editBookmarkPanelContent").hidden) {
- let fieldToFocus = "editBMPanel_" +
- gPrefService.getCharPref("browser.bookmarks.editDialog.firstEditField");
- var elt = this._element(fieldToFocus);
- elt.focus();
- elt.select();
- }
- else {
- // Note this isn't actually used anymore, we should remove this
- // once we decide not to bring back the page bookmarked notification
- this.panel.focus();
- }
- }
- },
-
- quitEditMode: function SU_quitEditMode() {
- this._element("editBookmarkPanelContent").hidden = true;
- this._element("editBookmarkPanelBottomButtons").hidden = true;
- gEditItemOverlay.uninitPanel(true);
- },
-
- cancelButtonOnCommand: function SU_cancelButtonOnCommand() {
- this._actionOnHide = "cancel";
- this.panel.hidePopup();
- },
-
- removeBookmarkButtonCommand: function SU_removeBookmarkButtonCommand() {
- this._uriForRemoval = PlacesUtils.bookmarks.getBookmarkURI(this._itemId);
- this._actionOnHide = "remove";
- this.panel.hidePopup();
- },
-
- beginBatch: function SU_beginBatch() {
- if (!this._batching) {
- PlacesUtils.transactionManager.beginBatch(null);
- this._batching = true;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//// PlacesCommandHook
-
-var PlacesCommandHook = {
- /**
- * Adds a bookmark to the page loaded in the given browser.
- *
- * @param aBrowser
- * a <browser> element.
- * @param [optional] aParent
- * The folder in which to create a new bookmark if the page loaded in
- * aBrowser isn't bookmarked yet, defaults to the unfiled root.
- * @param [optional] aShowEditUI
- * whether or not to show the edit-bookmark UI for the bookmark item
- */
- bookmarkPage: function PCH_bookmarkPage(aBrowser, aParent, aShowEditUI) {
- var uri = aBrowser.currentURI;
- var itemId = PlacesUtils.getMostRecentBookmarkForURI(uri);
- if (itemId == -1) {
- // Copied over from addBookmarkForBrowser:
- // Bug 52536: We obtain the URL and title from the nsIWebNavigation
- // associated with a <browser/> rather than from a DOMWindow.
- // This is because when a full page plugin is loaded, there is
- // no DOMWindow (?) but information about the loaded document
- // may still be obtained from the webNavigation.
- var webNav = aBrowser.webNavigation;
- var url = webNav.currentURI;
- var title;
- var description;
- var charset;
- try {
- let isErrorPage = /^about:(neterror|certerror|blocked)/
- .test(webNav.document.documentURI);
- title = isErrorPage ? PlacesUtils.history.getPageTitle(url)
- : webNav.document.title;
- title = title || url.spec;
- description = PlacesUIUtils.getDescriptionFromDocument(webNav.document);
- charset = webNav.document.characterSet;
- }
- catch (e) { }
-
- if (aShowEditUI) {
- // If we bookmark the page here (i.e. page was not "starred" already)
- // but open right into the "edit" state, start batching here, so
- // "Cancel" in that state removes the bookmark.
- StarUI.beginBatch();
- }
-
- var parent = aParent != undefined ?
- aParent : PlacesUtils.unfiledBookmarksFolderId;
- var descAnno = { name: PlacesUIUtils.DESCRIPTION_ANNO, value: description };
- var txn = new PlacesCreateBookmarkTransaction(uri, parent,
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- title, null, [descAnno]);
- PlacesUtils.transactionManager.doTransaction(txn);
- itemId = txn.item.id;
- // Set the character-set
- if (charset && !PrivateBrowsingUtils.isWindowPrivate(aBrowser.contentWindow))
- PlacesUtils.setCharsetForURI(uri, charset);
- }
-
- // Revert the contents of the location bar
- if (gURLBar)
- gURLBar.handleRevert();
-
- // If it was not requested to open directly in "edit" mode, we are done.
- if (!aShowEditUI)
- return;
-
- // Try to dock the panel to:
- // 1. the bookmarks menu button
- // 2. the page-proxy-favicon
- // 3. the content area
- if (BookmarkingUI.anchor) {
- StarUI.showEditBookmarkPopup(itemId, BookmarkingUI.anchor,
- "bottomcenter topright");
- return;
- }
-
- let pageProxyFavicon = document.getElementById("page-proxy-favicon");
- if (isElementVisible(pageProxyFavicon)) {
- StarUI.showEditBookmarkPopup(itemId, pageProxyFavicon,
- "bottomcenter topright");
- } else {
- StarUI.showEditBookmarkPopup(itemId, aBrowser, "overlap");
- }
- },
-
- /**
- * Adds a bookmark to the page loaded in the current tab.
- */
- bookmarkCurrentPage: function PCH_bookmarkCurrentPage(aShowEditUI, aParent) {
- this.bookmarkPage(gBrowser.selectedBrowser, aParent, aShowEditUI);
- },
-
- /**
- * Adds a bookmark to the page targeted by a link.
- * @param aParent
- * The folder in which to create a new bookmark if aURL isn't
- * bookmarked.
- * @param aURL (string)
- * the address of the link target
- * @param aTitle
- * The link text
- */
- bookmarkLink: function PCH_bookmarkLink(aParent, aURL, aTitle) {
- var linkURI = makeURI(aURL);
- var itemId = PlacesUtils.getMostRecentBookmarkForURI(linkURI);
- if (itemId == -1) {
- PlacesUIUtils.showBookmarkDialog({ action: "add"
- , type: "bookmark"
- , uri: linkURI
- , title: aTitle
- , hiddenRows: [ "description"
- , "location"
- , "loadInSidebar"
- , "keyword" ]
- }, window);
- }
- else {
- PlacesUIUtils.showBookmarkDialog({ action: "edit"
- , type: "bookmark"
- , itemId: itemId
- }, window);
- }
- },
-
- /**
- * List of nsIURI objects characterizing the tabs currently open in the
- * browser, modulo pinned tabs. The URIs will be in the order in which their
- * corresponding tabs appeared and duplicates are discarded.
- */
- get uniqueCurrentPages() {
- let uniquePages = {};
- let URIs = [];
- gBrowser.visibleTabs.forEach(function (tab) {
- let spec = tab.linkedBrowser.currentURI.spec;
- if (!tab.pinned && !(spec in uniquePages)) {
- uniquePages[spec] = null;
- URIs.push(tab.linkedBrowser.currentURI);
- }
- });
- return URIs;
- },
-
- /**
- * Adds a folder with bookmarks to all of the currently open tabs in this
- * window.
- */
- bookmarkCurrentPages: function PCH_bookmarkCurrentPages() {
- let pages = this.uniqueCurrentPages;
- if (pages.length > 1) {
- PlacesUIUtils.showBookmarkDialog({ action: "add"
- , type: "folder"
- , URIList: pages
- , hiddenRows: [ "description" ]
- }, window);
- }
- },
-
- /**
- * Updates disabled state for the "Bookmark All Tabs" command.
- */
- updateBookmarkAllTabsCommand:
- function PCH_updateBookmarkAllTabsCommand() {
- // There's nothing to do in non-browser windows.
- if (window.location.href != getBrowserURL())
- return;
-
- // Disable "Bookmark All Tabs" if there are less than two
- // "unique current pages".
- goSetCommandEnabled("Browser:BookmarkAllTabs",
- this.uniqueCurrentPages.length >= 2);
- },
-
- /**
- * Adds a Live Bookmark to a feed associated with the current page.
- * @param url
- * The nsIURI of the page the feed was attached to
- * @title title
- * The title of the feed. Optional.
- * @subtitle subtitle
- * A short description of the feed. Optional.
- */
- addLiveBookmark: function PCH_addLiveBookmark(url, feedTitle, feedSubtitle) {
- let toolbarIP = new InsertionPoint(PlacesUtils.toolbarFolderId, -1);
-
- let feedURI = makeURI(url);
- let title = feedTitle || gBrowser.contentTitle;
- let description = feedSubtitle;
- if (!description) {
- description = PlacesUIUtils.getDescriptionFromDocument(gBrowser.contentDocument);
- }
-
- PlacesUIUtils.showBookmarkDialog({ action: "add"
- , type: "livemark"
- , feedURI: feedURI
- , siteURI: gBrowser.currentURI
- , title: title
- , description: description
- , defaultInsertionPoint: toolbarIP
- , hiddenRows: [ "feedLocation"
- , "siteLocation"
- , "description" ]
- }, window);
- },
-
- /**
- * Opens the Places Organizer.
- * @param aLeftPaneRoot
- * The query to select in the organizer window - options
- * are: History, AllBookmarks, BookmarksMenu, BookmarksToolbar,
- * UnfiledBookmarks, Tags and Downloads.
- */
- showPlacesOrganizer: function PCH_showPlacesOrganizer(aLeftPaneRoot) {
- var organizer = Services.wm.getMostRecentWindow("Places:Organizer");
- // Due to bug 528706, getMostRecentWindow can return closed windows.
- if (!organizer || organizer.closed) {
- // No currently open places window, so open one with the specified mode.
- openDialog("chrome://browser/content/places/places.xul",
- "", "chrome,toolbar=yes,dialog=no,resizable", aLeftPaneRoot);
- }
- else {
- organizer.PlacesOrganizer.selectLeftPaneQuery(aLeftPaneRoot);
- organizer.focus();
- }
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//// HistoryMenu
-
-// View for the history menu.
-function HistoryMenu(aPopupShowingEvent) {
- // Workaround for Bug 610187. The sidebar does not include all the Places
- // views definitions, and we don't need them there.
- // Defining the prototype inheritance in the prototype itself would cause
- // browser.js to halt on "PlacesMenu is not defined" error.
- this.__proto__.__proto__ = PlacesMenu.prototype;
- XPCOMUtils.defineLazyServiceGetter(this, "_ss",
- "@mozilla.org/browser/sessionstore;1",
- "nsISessionStore");
- PlacesMenu.call(this, aPopupShowingEvent,
- "place:sort=4&maxResults=15");
-}
-
-HistoryMenu.prototype = {
- toggleRestoreLastSession: function HM_toggleRestoreLastSession() {
- let restoreItem = this._rootElt.ownerDocument.getElementById("Browser:RestoreLastSession");
-
- if (this._ss.canRestoreLastSession &&
- !PrivateBrowsingUtils.isWindowPrivate(window))
- restoreItem.removeAttribute("disabled");
- else
- restoreItem.setAttribute("disabled", true);
- },
-
- toggleRecentlyClosedTabs: function HM_toggleRecentlyClosedTabs() {
- // enable/disable the Recently Closed Tabs sub menu
- var undoMenu = this._rootElt.getElementsByClassName("recentlyClosedTabsMenu")[0];
-
- // no restorable tabs, so disable menu
- if (this._ss.getClosedTabCount(window) == 0)
- undoMenu.setAttribute("disabled", true);
- else
- undoMenu.removeAttribute("disabled");
- },
-
- /**
- * Re-open a closed tab and put it to the end of the tab strip.
- * Used for a middle click.
- * @param aEvent
- * The event when the user clicks the menu item
- */
- _undoCloseMiddleClick: function PHM__undoCloseMiddleClick(aEvent) {
- if (aEvent.button != 1)
- return;
-
- undoCloseTab(aEvent.originalTarget.value);
- gBrowser.moveTabToEnd();
- },
-
- /**
- * Populate when the history menu is opened
- */
- populateUndoSubmenu: function PHM_populateUndoSubmenu() {
- var undoMenu = this._rootElt.getElementsByClassName("recentlyClosedTabsMenu")[0];
- var undoPopup = undoMenu.firstChild;
-
- // remove existing menu items
- while (undoPopup.hasChildNodes())
- undoPopup.removeChild(undoPopup.firstChild);
-
- // no restorable tabs, so make sure menu is disabled, and return
- if (this._ss.getClosedTabCount(window) == 0) {
- undoMenu.setAttribute("disabled", true);
- return;
- }
-
- // enable menu
- undoMenu.removeAttribute("disabled");
-
- // populate menu
- var undoItems = JSON.parse(this._ss.getClosedTabData(window));
- for (var i = 0; i < undoItems.length; i++) {
- var m = document.createElement("menuitem");
- m.setAttribute("label", undoItems[i].title);
- if (undoItems[i].image) {
- let iconURL = undoItems[i].image;
- // don't initiate a connection just to fetch a favicon (see bug 467828)
- if (/^https?:/.test(iconURL))
- iconURL = "moz-anno:favicon:" + iconURL;
- m.setAttribute("image", iconURL);
- }
- m.setAttribute("class", "menuitem-iconic bookmark-item menuitem-with-favicon");
- m.setAttribute("value", i);
- m.setAttribute("oncommand", "undoCloseTab(" + i + ");");
-
- // Set the targetURI attribute so it will be shown in tooltip and trigger
- // onLinkHovered. SessionStore uses one-based indexes, so we need to
- // normalize them.
- let tabData = undoItems[i].state;
- let activeIndex = (tabData.index || tabData.entries.length) - 1;
- if (activeIndex >= 0 && tabData.entries[activeIndex])
- m.setAttribute("targetURI", tabData.entries[activeIndex].url);
-
- m.addEventListener("click", this._undoCloseMiddleClick, false);
- if (i == 0)
- m.setAttribute("key", "key_undoCloseTab");
- undoPopup.appendChild(m);
- }
-
- // "Restore All Tabs"
- var strings = gNavigatorBundle;
- undoPopup.appendChild(document.createElement("menuseparator"));
- m = undoPopup.appendChild(document.createElement("menuitem"));
- m.id = "menu_restoreAllTabs";
- m.setAttribute("label", strings.getString("menuRestoreAllTabs.label"));
- m.addEventListener("command", function() {
- for (var i = 0; i < undoItems.length; i++)
- undoCloseTab();
- }, false);
- },
-
- toggleRecentlyClosedWindows: function PHM_toggleRecentlyClosedWindows() {
- // enable/disable the Recently Closed Windows sub menu
- var undoMenu = this._rootElt.getElementsByClassName("recentlyClosedWindowsMenu")[0];
-
- // no restorable windows, so disable menu
- if (this._ss.getClosedWindowCount() == 0)
- undoMenu.setAttribute("disabled", true);
- else
- undoMenu.removeAttribute("disabled");
- },
-
- /**
- * Populate when the history menu is opened
- */
- populateUndoWindowSubmenu: function PHM_populateUndoWindowSubmenu() {
- let undoMenu = this._rootElt.getElementsByClassName("recentlyClosedWindowsMenu")[0];
- let undoPopup = undoMenu.firstChild;
- let menuLabelString = gNavigatorBundle.getString("menuUndoCloseWindowLabel");
- let menuLabelStringSingleTab =
- gNavigatorBundle.getString("menuUndoCloseWindowSingleTabLabel");
-
- // remove existing menu items
- while (undoPopup.hasChildNodes())
- undoPopup.removeChild(undoPopup.firstChild);
-
- // no restorable windows, so make sure menu is disabled, and return
- if (this._ss.getClosedWindowCount() == 0) {
- undoMenu.setAttribute("disabled", true);
- return;
- }
-
- // enable menu
- undoMenu.removeAttribute("disabled");
-
- // populate menu
- let undoItems = JSON.parse(this._ss.getClosedWindowData());
- for (let i = 0; i < undoItems.length; i++) {
- let undoItem = undoItems[i];
- let otherTabsCount = undoItem.tabs.length - 1;
- let label = (otherTabsCount == 0) ? menuLabelStringSingleTab
- : PluralForm.get(otherTabsCount, menuLabelString);
- let menuLabel = label.replace("#1", undoItem.title)
- .replace("#2", otherTabsCount);
- let m = document.createElement("menuitem");
- m.setAttribute("label", menuLabel);
- let selectedTab = undoItem.tabs[undoItem.selected - 1];
- if (selectedTab.image) {
- let iconURL = selectedTab.image;
- // don't initiate a connection just to fetch a favicon (see bug 467828)
- if (/^https?:/.test(iconURL))
- iconURL = "moz-anno:favicon:" + iconURL;
- m.setAttribute("image", iconURL);
- }
- m.setAttribute("class", "menuitem-iconic bookmark-item menuitem-with-favicon");
- m.setAttribute("oncommand", "undoCloseWindow(" + i + ");");
-
- // Set the targetURI attribute so it will be shown in tooltip.
- // SessionStore uses one-based indexes, so we need to normalize them.
- let activeIndex = (selectedTab.index || selectedTab.entries.length) - 1;
- if (activeIndex >= 0 && selectedTab.entries[activeIndex])
- m.setAttribute("targetURI", selectedTab.entries[activeIndex].url);
-
- if (i == 0)
- m.setAttribute("key", "key_undoCloseWindow");
- undoPopup.appendChild(m);
- }
-
- // "Open All in Windows"
- undoPopup.appendChild(document.createElement("menuseparator"));
- let m = undoPopup.appendChild(document.createElement("menuitem"));
- m.id = "menu_restoreAllWindows";
- m.setAttribute("label", gNavigatorBundle.getString("menuRestoreAllWindows.label"));
- m.setAttribute("oncommand",
- "for (var i = 0; i < " + undoItems.length + "; i++) undoCloseWindow();");
- },
-
- toggleTabsFromOtherComputers: function PHM_toggleTabsFromOtherComputers() {
- // This is a no-op if MOZ_SERVICES_SYNC isn't defined
-#ifdef MOZ_SERVICES_SYNC
- // Enable/disable the Tabs From Other Computers menu. Some of the menus handled
- // by HistoryMenu do not have this menuitem.
- let menuitem = this._rootElt.getElementsByClassName("syncTabsMenuItem")[0];
- if (!menuitem)
- return;
-
- // If Sync isn't configured yet, then don't show the menuitem.
- if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED ||
- Weave.Svc.Prefs.get("firstSync", "") == "notReady") {
- menuitem.setAttribute("hidden", true);
- return;
- }
-
- // The tabs engine might never be inited (if services.sync.registerEngines
- // is modified), so make sure we avoid undefined errors.
- let enabled = Weave.Service.isLoggedIn &&
- Weave.Service.engineManager.get("tabs") &&
- Weave.Service.engineManager.get("tabs").enabled;
- menuitem.setAttribute("disabled", !enabled);
- menuitem.setAttribute("hidden", false);
-#endif
- },
-
- _onPopupShowing: function HM__onPopupShowing(aEvent) {
- PlacesMenu.prototype._onPopupShowing.apply(this, arguments);
-
- // Don't handle events for submenus.
- if (aEvent.target != aEvent.currentTarget)
- return;
-
- this.toggleRestoreLastSession();
- this.toggleRecentlyClosedTabs();
- this.toggleRecentlyClosedWindows();
- this.toggleTabsFromOtherComputers();
- },
-
- _onCommand: function HM__onCommand(aEvent) {
- let placesNode = aEvent.target._placesNode;
- if (placesNode) {
- if (!PrivateBrowsingUtils.isWindowPrivate(window))
- PlacesUIUtils.markPageAsTyped(placesNode.uri);
- openUILink(placesNode.uri, aEvent, { ignoreAlt: true });
- }
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//// BookmarksEventHandler
-
-/**
- * Functions for handling events in the Bookmarks Toolbar and menu.
- */
-var BookmarksEventHandler = {
- /**
- * Handler for click event for an item in the bookmarks toolbar or menu.
- * Menus and submenus from the folder buttons bubble up to this handler.
- * Left-click is handled in the onCommand function.
- * When items are middle-clicked (or clicked with modifier), open in tabs.
- * If the click came through a menu, close the menu.
- * @param aEvent
- * DOMEvent for the click
- * @param aView
- * The places view which aEvent should be associated with.
- */
- onClick: function BEH_onClick(aEvent, aView) {
- // Only handle middle-click or left-click with modifiers.
-#ifdef XP_MACOSX
- var modifKey = aEvent.metaKey || aEvent.shiftKey;
-#else
- var modifKey = aEvent.ctrlKey || aEvent.shiftKey;
-#endif
- if (aEvent.button == 2 || (aEvent.button == 0 && !modifKey))
- return;
-
- var target = aEvent.originalTarget;
- // If this event bubbled up from a menu or menuitem, close the menus.
- // Do this before opening tabs, to avoid hiding the open tabs confirm-dialog.
- if (target.localName == "menu" || target.localName == "menuitem") {
- for (node = target.parentNode; node; node = node.parentNode) {
- if (node.localName == "menupopup")
- node.hidePopup();
- else if (node.localName != "menu" &&
- node.localName != "splitmenu" &&
- node.localName != "hbox" &&
- node.localName != "vbox" )
- break;
- }
- }
-
- if (target._placesNode && PlacesUtils.nodeIsContainer(target._placesNode)) {
- // Don't open the root folder in tabs when the empty area on the toolbar
- // is middle-clicked or when a non-bookmark item except for Open in Tabs)
- // in a bookmarks menupopup is middle-clicked.
- if (target.localName == "menu" || target.localName == "toolbarbutton")
- PlacesUIUtils.openContainerNodeInTabs(target._placesNode, aEvent, aView);
- }
- else if (aEvent.button == 1) {
- // left-clicks with modifier are already served by onCommand
- this.onCommand(aEvent, aView);
- }
- },
-
- /**
- * Handler for command event for an item in the bookmarks toolbar.
- * Menus and submenus from the folder buttons bubble up to this handler.
- * Opens the item.
- * @param aEvent
- * DOMEvent for the command
- * @param aView
- * The places view which aEvent should be associated with.
- */
- onCommand: function BEH_onCommand(aEvent, aView) {
- var target = aEvent.originalTarget;
- if (target._placesNode)
- PlacesUIUtils.openNodeWithEvent(target._placesNode, aEvent, aView);
- },
-
- fillInBHTooltip: function BEH_fillInBHTooltip(aDocument, aEvent) {
- var node;
- var cropped = false;
- var targetURI;
-
- if (aDocument.tooltipNode.localName == "treechildren") {
- var tree = aDocument.tooltipNode.parentNode;
- var tbo = tree.treeBoxObject;
- var cell = tbo.getCellAt(aEvent.clientX, aEvent.clientY);
- if (cell.row == -1)
- return false;
- node = tree.view.nodeForTreeIndex(cell.row);
- cropped = tbo.isCellCropped(cell.row, cell.col);
- }
- else {
- // Check whether the tooltipNode is a Places node.
- // In such a case use it, otherwise check for targetURI attribute.
- var tooltipNode = aDocument.tooltipNode;
- if (tooltipNode._placesNode)
- node = tooltipNode._placesNode;
- else {
- // This is a static non-Places node.
- targetURI = tooltipNode.getAttribute("targetURI");
- }
- }
-
- if (!node && !targetURI)
- return false;
-
- // Show node.label as tooltip's title for non-Places nodes.
- var title = node ? node.title : tooltipNode.label;
-
- // Show URL only for Places URI-nodes or nodes with a targetURI attribute.
- var url;
- if (targetURI || PlacesUtils.nodeIsURI(node))
- url = targetURI || node.uri;
-
- // Show tooltip for containers only if their title is cropped.
- if (!cropped && !url)
- return false;
-
- var tooltipTitle = aDocument.getElementById("bhtTitleText");
- tooltipTitle.hidden = (!title || (title == url));
- if (!tooltipTitle.hidden)
- tooltipTitle.textContent = title;
-
- var tooltipUrl = aDocument.getElementById("bhtUrlText");
- tooltipUrl.hidden = !url;
- if (!tooltipUrl.hidden)
- tooltipUrl.value = url;
-
- // Show tooltip.
- return true;
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//// PlacesMenuDNDHandler
-
-// Handles special drag and drop functionality for Places menus that are not
-// part of a Places view (e.g. the bookmarks menu in the menubar).
-var PlacesMenuDNDHandler = {
- _springLoadDelay: 350, // milliseconds
- _loadTimer: null,
- _closerTimer: null,
-
- /**
- * Called when the user enters the <menu> element during a drag.
- * @param event
- * The DragEnter event that spawned the opening.
- */
- onDragEnter: function PMDH_onDragEnter(event) {
- // Opening menus in a Places popup is handled by the view itself.
- if (!this._isStaticContainer(event.target))
- return;
-
- let popup = event.target.lastChild;
- if (this._loadTimer || popup.state === "showing" || popup.state === "open")
- return;
-
- this._loadTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- this._loadTimer.initWithCallback(() => {
- this._loadTimer = null;
- popup.setAttribute("autoopened", "true");
- popup.showPopup(popup);
- }, this._springLoadDelay, Ci.nsITimer.TYPE_ONE_SHOT);
- event.preventDefault();
- event.stopPropagation();
- },
-
- /**
- * Handles dragleave on the <menu> element.
- * @returns true if the element is a container element (menu or
- * menu-toolbarbutton), false otherwise.
- */
- onDragLeave: function PMDH_onDragLeave(event) {
- // Handle menu-button separate targets.
- if (event.relatedTarget === event.currentTarget ||
- event.relatedTarget.parentNode === event.currentTarget)
- return;
-
- // Closing menus in a Places popup is handled by the view itself.
- if (!this._isStaticContainer(event.target))
- return;
-
- let popup = event.target.lastChild;
-
- if (this._loadTimer) {
- this._loadTimer.cancel();
- this._loadTimer = null;
- }
- this._closeTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- this._closeTimer.initWithCallback(function() {
- this._closeTimer = null;
- let node = PlacesControllerDragHelper.currentDropTarget;
- let inHierarchy = false;
- while (node && !inHierarchy) {
- inHierarchy = node == event.target;
- node = node.parentNode;
- }
- if (!inHierarchy && popup && popup.hasAttribute("autoopened")) {
- popup.removeAttribute("autoopened");
- popup.hidePopup();
- }
- }, this._springLoadDelay, Ci.nsITimer.TYPE_ONE_SHOT);
- },
-
- /**
- * Determines if a XUL element represents a static container.
- * @returns true if the element is a container element (menu or
- *` menu-toolbarbutton), false otherwise.
- */
- _isStaticContainer: function PMDH__isContainer(node) {
- let isMenu = node.localName == "menu" ||
- (node.localName == "toolbarbutton" &&
- (node.getAttribute("type") == "menu" ||
- node.getAttribute("type") == "menu-button"));
- let isStatic = !("_placesNode" in node) && node.lastChild &&
- node.lastChild.hasAttribute("placespopup") &&
- !node.parentNode.hasAttribute("placespopup");
- return isMenu && isStatic;
- },
-
- /**
- * Called when the user drags over the <menu> element.
- * @param event
- * The DragOver event.
- */
- onDragOver: function PMDH_onDragOver(event) {
- let ip = new InsertionPoint(PlacesUtils.bookmarksMenuFolderId,
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- Ci.nsITreeView.DROP_ON);
- if (ip && PlacesControllerDragHelper.canDrop(ip, event.dataTransfer))
- event.preventDefault();
-
- event.stopPropagation();
- },
-
- /**
- * Called when the user drops on the <menu> element.
- * @param event
- * The Drop event.
- */
- onDrop: function PMDH_onDrop(event) {
- // Put the item at the end of bookmark menu.
- let ip = new InsertionPoint(PlacesUtils.bookmarksMenuFolderId,
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- Ci.nsITreeView.DROP_ON);
- PlacesControllerDragHelper.onDrop(ip, event.dataTransfer);
- event.stopPropagation();
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//// PlacesToolbarHelper
-
-/**
- * This object handles the initialization and uninitialization of the bookmarks
- * toolbar.
- */
-var PlacesToolbarHelper = {
- _place: "place:folder=TOOLBAR",
-
- get _viewElt() {
- return document.getElementById("PlacesToolbar");
- },
-
- init: function PTH_init() {
- let viewElt = this._viewElt;
- if (!viewElt || viewElt._placesView)
- return;
-
- // If the bookmarks toolbar item is hidden because the parent toolbar is
- // collapsed or hidden (i.e. in a popup), spare the initialization. Also,
- // there is no need to initialize the toolbar if customizing because
- // init() will be called when the customization is done.
- let toolbar = viewElt.parentNode.parentNode;
- if (toolbar.collapsed ||
- getComputedStyle(toolbar, "").display == "none" ||
- this._isCustomizing)
- return;
-
- new PlacesToolbar(this._place);
- },
-
- customizeStart: function PTH_customizeStart() {
- let viewElt = this._viewElt;
- if (viewElt && viewElt._placesView)
- viewElt._placesView.uninit();
-
- this._isCustomizing = true;
- },
-
- customizeDone: function PTH_customizeDone() {
- this._isCustomizing = false;
- this.init();
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//// BookmarkingUI
-
-/**
- * Handles the bookmarks star button in the URL bar, as well as the bookmark
- * menu button.
- */
-
-var BookmarkingUI = {
- get button() {
- if (!this._button) {
- this._button = document.getElementById("bookmarks-menu-button");
- }
- return this._button;
- },
-
- get star() {
- if (!this._star) {
- this._star = document.getElementById("star-button");
- }
- return this._star;
- },
-
- get anchor() {
- if (this.star && isElementVisible(this.star)) {
- // Anchor to the icon, so the panel looks more natural.
- return this.star;
- }
- return null;
- },
-
- STATUS_UPDATING: -1,
- STATUS_UNSTARRED: 0,
- STATUS_STARRED: 1,
- get status() {
- if (this._pendingStmt)
- return this.STATUS_UPDATING;
- return this.star &&
- this.star.hasAttribute("starred") ? this.STATUS_STARRED
- : this.STATUS_UNSTARRED;
- },
-
- get _starredTooltip()
- {
- delete this._starredTooltip;
- return this._starredTooltip =
- gNavigatorBundle.getString("starButtonOn.tooltip");
- },
-
- get _unstarredTooltip()
- {
- delete this._unstarredTooltip;
- return this._unstarredTooltip =
- gNavigatorBundle.getString("starButtonOff.tooltip");
- },
-
- /**
- * The popup contents must be updated when the user customizes the UI, or
- * changes the personal toolbar collapsed status. In such a case, any needed
- * change should be handled in the popupshowing helper, for performance
- * reasons.
- */
- _popupNeedsUpdate: true,
- onToolbarVisibilityChange: function BUI_onToolbarVisibilityChange() {
- this._popupNeedsUpdate = true;
- },
-
- onPopupShowing: function BUI_onPopupShowing(event) {
- // Don't handle events for submenus.
- if (event.target != event.currentTarget)
- return;
-
- if (!this._popupNeedsUpdate)
- return;
- this._popupNeedsUpdate = false;
-
- let popup = event.target;
- let getPlacesAnonymousElement =
- aAnonId => document.getAnonymousElementByAttribute(popup.parentNode,
- "placesanonid",
- aAnonId);
-
- let viewToolbarMenuitem = getPlacesAnonymousElement("view-toolbar");
- if (viewToolbarMenuitem) {
- // Update View bookmarks toolbar checkbox menuitem.
- let personalToolbar = document.getElementById("PersonalToolbar");
- viewToolbarMenuitem.setAttribute("checked", !personalToolbar.collapsed);
- }
-
- let toolbarMenuitem = getPlacesAnonymousElement("toolbar-autohide");
- if (toolbarMenuitem) {
- // If bookmarks items are visible, hide Bookmarks Toolbar menu and the
- // separator after it.
- toolbarMenuitem.collapsed = toolbarMenuitem.nextSibling.collapsed =
- isElementVisible(document.getElementById("personal-bookmarks"));
- }
- },
-
- /**
- * Handles star styling based on page proxy state changes.
- */
- onPageProxyStateChanged: function BUI_onPageProxyStateChanged(aState) {
- if (!this.star) {
- return;
- }
-
- if (aState == "invalid") {
- this.star.setAttribute("disabled", "true");
- this.star.removeAttribute("starred");
- }
- else {
- this.star.removeAttribute("disabled");
- }
- },
-
- _updateToolbarStyle: function BUI__updateToolbarStyle() {
- if (!this.button) {
- return;
- }
-
- let personalToolbar = document.getElementById("PersonalToolbar");
- let onPersonalToolbar = this.button.parentNode == personalToolbar ||
- this.button.parentNode.parentNode == personalToolbar;
-
- if (onPersonalToolbar) {
- this.button.classList.add("bookmark-item");
- this.button.classList.remove("toolbarbutton-1");
- }
- else {
- this.button.classList.remove("bookmark-item");
- this.button.classList.add("toolbarbutton-1");
- }
- },
-
- _uninitView: function BUI__uninitView() {
- // When an element with a placesView attached is removed and re-inserted,
- // XBL reapplies the binding causing any kind of issues and possible leaks,
- // so kill current view and let popupshowing generate a new one.
- if (this.button && this.button._placesView) {
- this.button._placesView.uninit();
- }
- // Also uninit the main menubar placesView, since it would have the same
- // issues.
- let menubar = document.getElementById("bookmarksMenu");
- if (menubar && menubar._placesView) {
- menubar._placesView.uninit();
- }
- },
-
- customizeStart: function BUI_customizeStart() {
- this._uninitView();
- },
-
- customizeChange: function BUI_customizeChange() {
- this._updateToolbarStyle();
- },
-
- customizeDone: function BUI_customizeDone() {
- delete this._button;
- this.onToolbarVisibilityChange();
- this._updateToolbarStyle();
- },
-
- _hasBookmarksObserver: false,
- uninit: function BUI_uninit() {
- this._uninitView();
-
- if (this._hasBookmarksObserver) {
- PlacesUtils.removeLazyBookmarkObserver(this);
- }
-
- if (this._pendingStmt) {
- this._pendingStmt.cancel();
- delete this._pendingStmt;
- }
- },
-
- onLocationChange: function BUI_onLocationChange() {
- if (this._uri && gBrowser.currentURI.equals(this._uri)) {
- return;
- }
- this.updateStarState();
- },
-
- updateStarState: function BUI_updateStarState() {
- // Reset tracked values.
- this._uri = gBrowser.currentURI;
- this._itemIds = [];
-
- if (this._pendingStmt) {
- this._pendingStmt.cancel();
- delete this._pendingStmt;
- }
-
- // We can load about:blank before the actual page, but there is no point in handling that page.
- if (isBlankPageURL(this._uri.spec)) {
- return;
- }
-
- this._pendingStmt = PlacesUtils.asyncGetBookmarkIds(this._uri, (aItemIds, aURI) => {
- // Safety check that the bookmarked URI equals the tracked one.
- if (!aURI.equals(this._uri)) {
- Components.utils.reportError("BookmarkingUI did not receive current URI");
- return;
- }
-
- // It's possible that onItemAdded gets called before the async statement
- // calls back. For such an edge case, retain all unique entries from both
- // arrays.
- this._itemIds = this._itemIds.filter(
- function (id) aItemIds.indexOf(id) == -1
- ).concat(aItemIds);
-
- this._updateStar();
-
- // Start observing bookmarks if needed.
- if (!this._hasBookmarksObserver) {
- try {
- PlacesUtils.addLazyBookmarkObserver(this);
- this._hasBookmarksObserver = true;
- } catch(ex) {
- Components.utils.reportError("BookmarkingUI failed adding a bookmarks observer: " + ex);
- }
- }
-
- delete this._pendingStmt;
- }, this);
- },
-
- _updateStar: function BUI__updateStar() {
- if (!this.star) {
- return;
- }
-
- if (this._itemIds.length > 0) {
- this.star.setAttribute("starred", "true");
- this.star.setAttribute("tooltiptext", this._starredTooltip);
- }
- else {
- this.star.removeAttribute("starred");
- this.star.setAttribute("tooltiptext", this._unstarredTooltip);
- }
- },
-
- onCommand: function BUI_onCommand(aEvent) {
- if (aEvent.target != aEvent.currentTarget) {
- return;
- }
- // Ignore clicks on the star if we are updating its state.
- if (!this._pendingStmt) {
- PlacesCommandHook.bookmarkCurrentPage(this._itemIds.length > 0);
- }
- },
-
- // nsINavBookmarkObserver
- onItemAdded: function BUI_onItemAdded(aItemId, aParentId, aIndex, aItemType,
- aURI) {
- if (aURI && aURI.equals(this._uri)) {
- // If a new bookmark has been added to the tracked uri, register it.
- if (this._itemIds.indexOf(aItemId) == -1) {
- this._itemIds.push(aItemId);
- this._updateStar();
- }
- }
- },
-
- onItemRemoved: function BUI_onItemRemoved(aItemId) {
- let index = this._itemIds.indexOf(aItemId);
- // If one of the tracked bookmarks has been removed, unregister it.
- if (index != -1) {
- this._itemIds.splice(index, 1);
- this._updateStar();
- }
- },
-
- onItemChanged: function BUI_onItemChanged(aItemId, aProperty,
- aIsAnnotationProperty, aNewValue) {
- if (aProperty == "uri") {
- let index = this._itemIds.indexOf(aItemId);
- // If the changed bookmark was tracked, check if it is now pointing to
- // a different uri and unregister it.
- if (index != -1 && aNewValue != this._uri.spec) {
- this._itemIds.splice(index, 1);
- this._updateStar();
- }
- // If another bookmark is now pointing to the tracked uri, register it.
- else if (index == -1 && aNewValue == this._uri.spec) {
- this._itemIds.push(aItemId);
- this._updateStar();
- }
- }
- },
-
- onBeginUpdateBatch: function () {},
- onEndUpdateBatch: function () {},
- onBeforeItemRemoved: function () {},
- onItemVisited: function () {},
- onItemMoved: function () {},
-
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsINavBookmarkObserver
- ])
-};
diff --git a/base/content/browser-plugins.js b/base/content/browser-plugins.js
deleted file mode 100644
index 8382682..0000000
--- a/base/content/browser-plugins.js
+++ /dev/null
@@ -1,781 +0,0 @@
-# -*- 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/.
-
-const kPrefSessionPersistMinutes = "plugin.sessionPermissionNow.intervalInMinutes";
-const kPrefPersistentDays = "plugin.persistentPermissionAlways.intervalInDays";
-
-var gPluginHandler = {
- PLUGIN_SCRIPTED_STATE_NONE: 0,
- PLUGIN_SCRIPTED_STATE_FIRED: 1,
- PLUGIN_SCRIPTED_STATE_DONE: 2,
-
- getPluginUI: function (plugin, anonid) {
- return plugin.ownerDocument.
- getAnonymousElementByAttribute(plugin, "anonid", anonid);
- },
-
- _getPluginInfo: function (pluginElement) {
- let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
- pluginElement.QueryInterface(Ci.nsIObjectLoadingContent);
-
- let tagMimetype;
- let pluginName = gNavigatorBundle.getString("pluginInfo.unknownPlugin");
- let pluginTag = null;
- let permissionString = null;
- let fallbackType = null;
- let blocklistState = null;
-
- if (pluginElement instanceof HTMLAppletElement) {
- tagMimetype = "application/x-java-vm";
- } else {
- tagMimetype = pluginElement.actualType;
-
- if (tagMimetype == "") {
- tagMimetype = pluginElement.type;
- }
- }
-
- if (gPluginHandler.isKnownPlugin(pluginElement)) {
- pluginTag = pluginHost.getPluginTagForType(pluginElement.actualType);
- pluginName = gPluginHandler.makeNicePluginName(pluginTag.name);
-
- permissionString = pluginHost.getPermissionStringForType(pluginElement.actualType);
- fallbackType = pluginElement.defaultFallbackType;
- blocklistState = pluginHost.getBlocklistStateForType(pluginElement.actualType);
- // Make state-softblocked == state-notblocked for our purposes,
- // they have the same UI. STATE_OUTDATED should not exist for plugin
- // items, but let's alias it anyway, just in case.
- if (blocklistState == Ci.nsIBlocklistService.STATE_SOFTBLOCKED ||
- blocklistState == Ci.nsIBlocklistService.STATE_OUTDATED) {
- blocklistState = Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
- }
- }
-
- return { mimetype: tagMimetype,
- pluginName: pluginName,
- pluginTag: pluginTag,
- permissionString: permissionString,
- fallbackType: fallbackType,
- blocklistState: blocklistState,
- };
- },
-
- // Map the plugin's name to a filtered version more suitable for user UI.
- makeNicePluginName : function (aName) {
- if (aName == "Shockwave Flash")
- return "Adobe Flash";
-
- // Clean up the plugin name by stripping off any trailing version numbers
- // or "plugin". EG, "Foo Bar Plugin 1.23_02" --> "Foo Bar"
- // Do this by first stripping the numbers, etc. off the end, and then
- // removing "Plugin" (and then trimming to get rid of any whitespace).
- // (Otherwise, something like "Java(TM) Plug-in 1.7.0_07" gets mangled)
- let newName = aName.replace(/[\s\d\.\-\_\(\)]+$/, "").replace(/\bplug-?in\b/i, "").trim();
- return newName;
- },
-
- isTooSmall : function (plugin, overlay) {
- // Is the <object>'s size too small to hold what we want to show?
- let pluginRect = plugin.getBoundingClientRect();
- // XXX bug 446693. The text-shadow on the submitted-report text at
- // the bottom causes scrollHeight to be larger than it should be.
- // Clamp width/height to properly show CTP overlay on different
- // zoom levels when embedded in iframes (rounding bug). (Bug 972237)
- let overflows = (overlay.scrollWidth > Math.ceil(pluginRect.width)) ||
- (overlay.scrollHeight - 5 > Math.ceil(pluginRect.height));
- return overflows;
- },
-
- addLinkClickCallback: function (linkNode, callbackName /*callbackArgs...*/) {
- // XXX just doing (callback)(arg) was giving a same-origin error. bug?
- let self = this;
- let callbackArgs = Array.prototype.slice.call(arguments).slice(2);
- linkNode.addEventListener("click",
- function(evt) {
- if (!evt.isTrusted)
- return;
- evt.preventDefault();
- if (callbackArgs.length == 0)
- callbackArgs = [ evt ];
- (self[callbackName]).apply(self, callbackArgs);
- },
- true);
-
- linkNode.addEventListener("keydown",
- function(evt) {
- if (!evt.isTrusted)
- return;
- if (evt.keyCode == evt.DOM_VK_RETURN) {
- evt.preventDefault();
- if (callbackArgs.length == 0)
- callbackArgs = [ evt ];
- evt.preventDefault();
- (self[callbackName]).apply(self, callbackArgs);
- }
- },
- true);
- },
-
- // Helper to get the binding handler type from a plugin object
- _getBindingType : function(plugin) {
- if (!(plugin instanceof Ci.nsIObjectLoadingContent))
- return null;
-
- switch (plugin.pluginFallbackType) {
- case Ci.nsIObjectLoadingContent.PLUGIN_UNSUPPORTED:
- return "PluginNotFound";
- case Ci.nsIObjectLoadingContent.PLUGIN_DISABLED:
- return "PluginDisabled";
- case Ci.nsIObjectLoadingContent.PLUGIN_BLOCKLISTED:
- return "PluginBlocklisted";
- case Ci.nsIObjectLoadingContent.PLUGIN_OUTDATED:
- return "PluginOutdated";
- case Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY:
- return "PluginClickToPlay";
- case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE:
- return "PluginVulnerableUpdatable";
- case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE:
- return "PluginVulnerableNoUpdate";
- case Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW:
- return "PluginPlayPreview";
- default:
- // Not all states map to a handler
- return null;
- }
- },
-
- handleEvent : function(event) {
- let plugin;
- let doc;
-
- let eventType = event.type;
- if (eventType === "PluginRemoved") {
- doc = event.target;
- }
- else {
- plugin = event.target;
- doc = plugin.ownerDocument;
-
- if (!(plugin instanceof Ci.nsIObjectLoadingContent))
- return;
- }
-
- if (eventType == "PluginBindingAttached") {
- // The plugin binding fires this event when it is created.
- // As an untrusted event, ensure that this object actually has a binding
- // and make sure we don't handle it twice
- let overlay = this.getPluginUI(plugin, "main");
- if (!overlay || overlay._bindingHandled) {
- return;
- }
- overlay._bindingHandled = true;
-
- // Lookup the handler for this binding
- eventType = this._getBindingType(plugin);
- if (!eventType) {
- // Not all bindings have handlers
- return;
- }
- }
-
- let shouldShowNotification = false;
- let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
- if (!browser)
- return;
-
- switch (eventType) {
- case "PluginCrashed":
- this.pluginInstanceCrashed(plugin, event);
- break;
-
- case "PluginNotFound":
- /* No action (plugin finder obsolete) */
- break;
-
- case "PluginBlocklisted":
- case "PluginOutdated":
- shouldShowNotification = true;
- break;
-
- case "PluginVulnerableUpdatable":
- let updateLink = this.getPluginUI(plugin, "checkForUpdatesLink");
- this.addLinkClickCallback(updateLink, "openPluginUpdatePage");
- /* FALLTHRU */
-
- case "PluginVulnerableNoUpdate":
- case "PluginClickToPlay":
- this._handleClickToPlayEvent(plugin);
- let overlay = this.getPluginUI(plugin, "main");
- let pluginName = this._getPluginInfo(plugin).pluginName;
- let messageString = gNavigatorBundle.getFormattedString("PluginClickToActivate", [pluginName]);
- let overlayText = this.getPluginUI(plugin, "clickToPlay");
- overlayText.textContent = messageString;
- if (eventType == "PluginVulnerableUpdatable" ||
- eventType == "PluginVulnerableNoUpdate") {
- let vulnerabilityString = gNavigatorBundle.getString(eventType);
- let vulnerabilityText = this.getPluginUI(plugin, "vulnerabilityStatus");
- vulnerabilityText.textContent = vulnerabilityString;
- }
- shouldShowNotification = true;
- break;
-
- case "PluginPlayPreview":
- this._handlePlayPreviewEvent(plugin);
- break;
-
- case "PluginDisabled":
- let manageLink = this.getPluginUI(plugin, "managePluginsLink");
- this.addLinkClickCallback(manageLink, "managePlugins");
- shouldShowNotification = true;
- break;
-
- case "PluginInstantiated":
- //Pale Moon: don't show the indicator when plugins are enabled/allowed
- if (gPrefService.getBoolPref("plugins.always_show_indicator")) {
- shouldShowNotification = true;
- }
- break;
- case "PluginRemoved":
- shouldShowNotification = true;
- break;
- }
-
- // Show the in-content UI if it's not too big. The crashed plugin handler already did this.
- if (eventType != "PluginCrashed" && eventType != "PluginRemoved") {
- let overlay = this.getPluginUI(plugin, "main");
- if (overlay != null) {
- if (!this.isTooSmall(plugin, overlay)) {
- overlay.style.visibility = "visible";
- }
- plugin.addEventListener("overflow", function(event) {
- overlay.style.visibility = "hidden";
- });
- plugin.addEventListener("underflow", function(event) {
- // this is triggered if only one dimension underflows,
- // the other dimension might still overflow
- if (!gPluginHandler.isTooSmall(plugin, overlay)) {
- overlay.style.visibility = "visible";
- }
- });
- }
- }
-
- // Only show the notification after we've done the isTooSmall check, so
- // that the notification can decide whether to show the "alert" icon
- if (shouldShowNotification) {
- this._showClickToPlayNotification(browser);
- }
- },
-
- isKnownPlugin: function PH_isKnownPlugin(objLoadingContent) {
- return (objLoadingContent.getContentTypeForMIMEType(objLoadingContent.actualType) ==
- Ci.nsIObjectLoadingContent.TYPE_PLUGIN);
- },
-
- canActivatePlugin: function PH_canActivatePlugin(objLoadingContent) {
- // if this isn't a known plugin, we can't activate it
- // (this also guards pluginHost.getPermissionStringForType against
- // unexpected input)
- if (!gPluginHandler.isKnownPlugin(objLoadingContent))
- return false;
-
- let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
- let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
- let principal = objLoadingContent.ownerDocument.defaultView.top.document.nodePrincipal;
- let pluginPermission = Services.perms.testPermissionFromPrincipal(principal, permissionString);
-
- let isFallbackTypeValid =
- objLoadingContent.pluginFallbackType >= Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY &&
- objLoadingContent.pluginFallbackType <= Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE;
-
- if (objLoadingContent.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW) {
- // checking if play preview is subject to CTP rules
- let playPreviewInfo = pluginHost.getPlayPreviewInfo(objLoadingContent.actualType);
- isFallbackTypeValid = !playPreviewInfo.ignoreCTP;
- }
-
- return !objLoadingContent.activated &&
- pluginPermission != Ci.nsIPermissionManager.DENY_ACTION &&
- isFallbackTypeValid;
- },
-
- hideClickToPlayOverlay: function(aPlugin) {
- let overlay = this.getPluginUI(aPlugin, "main");
- if (overlay)
- overlay.style.visibility = "hidden";
- },
-
- stopPlayPreview: function PH_stopPlayPreview(aPlugin, aPlayPlugin) {
- let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
- if (objLoadingContent.activated)
- return;
-
- if (aPlayPlugin)
- objLoadingContent.playPlugin();
- else
- objLoadingContent.cancelPlayPreview();
- },
-
- // Callback for user clicking on a disabled plugin
- managePlugins: function (aEvent) {
- BrowserOpenAddonsMgr("addons://list/plugin");
- },
-
- // Callback for user clicking on the link in a click-to-play plugin
- // (where the plugin has an update)
- openPluginUpdatePage: function (aEvent) {
- openURL(Services.urlFormatter.formatURLPref("plugins.update.url"));
- },
-
- // Callback for user clicking a "reload page" link
- reloadPage: function (browser) {
- browser.reload();
- },
-
- // Callback for user clicking the help icon
- openHelpPage: function () {
- openHelpLink("plugin-crashed", false);
- },
-
- // Event listener for click-to-play plugins.
- _handleClickToPlayEvent: function PH_handleClickToPlayEvent(aPlugin) {
- let doc = aPlugin.ownerDocument;
- let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
- let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
- let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
- // guard against giving pluginHost.getPermissionStringForType a type
- // not associated with any known plugin
- if (!gPluginHandler.isKnownPlugin(objLoadingContent))
- return;
- let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
- let principal = doc.defaultView.top.document.nodePrincipal;
- let pluginPermission = Services.perms.testPermissionFromPrincipal(principal, permissionString);
-
- let overlay = this.getPluginUI(aPlugin, "main");
-
- if (pluginPermission == Ci.nsIPermissionManager.DENY_ACTION) {
- if (overlay)
- overlay.style.visibility = "hidden";
- return;
- }
-
- if (overlay) {
- overlay.addEventListener("click", gPluginHandler._overlayClickListener, true);
- let closeIcon = gPluginHandler.getPluginUI(aPlugin, "closeIcon");
- closeIcon.addEventListener("click", function(aEvent) {
- if (aEvent.button == 0 && aEvent.isTrusted)
- gPluginHandler.hideClickToPlayOverlay(aPlugin);
- }, true);
- }
- },
-
- _overlayClickListener: {
- handleEvent: function PH_handleOverlayClick(aEvent) {
- let plugin = document.getBindingParent(aEvent.target);
- let contentWindow = plugin.ownerDocument.defaultView.top;
- // gBrowser.getBrowserForDocument does not exist in the case where we
- // drag-and-dropped a tab from a window containing only that tab. In
- // that case, the window gets destroyed.
- let browser = gBrowser.getBrowserForDocument ?
- gBrowser.getBrowserForDocument(contentWindow.document) :
- null;
- // If browser is null here, we've been drag-and-dropped from another
- // window, and this is the wrong click handler.
- if (!browser) {
- aEvent.target.removeEventListener("click", gPluginHandler._overlayClickListener, true);
- return;
- }
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- // Have to check that the target is not the link to update the plugin
- if (!(aEvent.originalTarget instanceof HTMLAnchorElement) &&
- (aEvent.originalTarget.getAttribute('anonid') != 'closeIcon') &&
- aEvent.button == 0 && aEvent.isTrusted) {
- gPluginHandler._showClickToPlayNotification(browser, plugin);
- aEvent.stopPropagation();
- aEvent.preventDefault();
- }
- }
- },
-
- _handlePlayPreviewEvent: function PH_handlePlayPreviewEvent(aPlugin) {
- let doc = aPlugin.ownerDocument;
- let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
- let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
- let pluginInfo = this._getPluginInfo(aPlugin);
- let playPreviewInfo = pluginHost.getPlayPreviewInfo(pluginInfo.mimetype);
-
- let previewContent = this.getPluginUI(aPlugin, "previewPluginContent");
- let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0];
- if (!iframe) {
- // lazy initialization of the iframe
- iframe = doc.createElementNS("http://www.w3.org/1999/xhtml", "iframe");
- iframe.className = "previewPluginContentFrame";
- previewContent.appendChild(iframe);
-
- // Force a style flush, so that we ensure our binding is attached.
- aPlugin.clientTop;
- }
- iframe.src = playPreviewInfo.redirectURL;
-
- // MozPlayPlugin event can be dispatched from the extension chrome
- // code to replace the preview content with the native plugin
- previewContent.addEventListener("MozPlayPlugin", function playPluginHandler(aEvent) {
- if (!aEvent.isTrusted)
- return;
-
- previewContent.removeEventListener("MozPlayPlugin", playPluginHandler, true);
-
- let playPlugin = !aEvent.detail;
- gPluginHandler.stopPlayPreview(aPlugin, playPlugin);
-
- // cleaning up: removes overlay iframe from the DOM
- let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0];
- if (iframe)
- previewContent.removeChild(iframe);
- }, true);
-
- if (!playPreviewInfo.ignoreCTP) {
- gPluginHandler._showClickToPlayNotification(browser);
- }
- },
-
- reshowClickToPlayNotification: function PH_reshowClickToPlayNotification() {
- let browser = gBrowser.selectedBrowser;
- let contentWindow = browser.contentWindow;
- let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- let doc = contentWindow.document;
- let plugins = cwu.plugins;
- for (let plugin of plugins) {
- let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- if (overlay)
- overlay.removeEventListener("click", gPluginHandler._overlayClickListener, true);
- let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- if (gPluginHandler.canActivatePlugin(objLoadingContent))
- gPluginHandler._handleClickToPlayEvent(plugin);
- }
- gPluginHandler._showClickToPlayNotification(browser);
- },
-
- _clickToPlayNotificationEventCallback: function PH_ctpEventCallback(event) {
- if (event == "showing") {
- gPluginHandler._makeCenterActions(this);
- }
- else if (event == "dismissed") {
- // Once the popup is dismissed, clicking the icon should show the full
- // list again
- this.options.primaryPlugin = null;
- }
- },
-
- _makeCenterActions: function PH_makeCenterActions(notification) {
- let contentWindow = notification.browser.contentWindow;
- let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
-
- let principal = contentWindow.document.nodePrincipal;
-
- let centerActions = [];
- let pluginsFound = new Set();
- for (let plugin of cwu.plugins) {
- plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- if (plugin.getContentTypeForMIMEType(plugin.actualType) != Ci.nsIObjectLoadingContent.TYPE_PLUGIN) {
- continue;
- }
-
- let pluginInfo = this._getPluginInfo(plugin);
- if (pluginInfo.permissionString === null) {
- Components.utils.reportError("No permission string for active plugin.");
- continue;
- }
- if (pluginsFound.has(pluginInfo.permissionString)) {
- continue;
- }
- pluginsFound.add(pluginInfo.permissionString);
-
- // Add the per-site permissions and details URLs to pluginInfo here
- // because they are more expensive to compute and so we avoid it in
- // the tighter loop above.
- let permissionObj = Services.perms.
- getPermissionObject(principal, pluginInfo.permissionString, false);
- if (permissionObj) {
- pluginInfo.pluginPermissionPrePath = permissionObj.principal.originNoSuffix;
- pluginInfo.pluginPermissionType = permissionObj.expireType;
- }
- else {
- pluginInfo.pluginPermissionPrePath = principal.originNoSuffix;
- pluginInfo.pluginPermissionType = undefined;
- }
-
- let url;
- // TODO: allow the blocklist to specify a better link, bug 873093
- if (pluginInfo.blocklistState == Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE) {
- url = Services.urlFormatter.formatURLPref("plugins.update.url");
- }
- else if (pluginInfo.blocklistState != Ci.nsIBlocklistService.STATE_NOT_BLOCKED) {
- url = Services.blocklist.getPluginBlocklistURL(pluginInfo.pluginTag);
- }
- pluginInfo.detailsLink = url;
-
- centerActions.push(pluginInfo);
- }
- centerActions.sort(function(a, b) {
- return a.pluginName.localeCompare(b.pluginName);
- });
-
- notification.options.centerActions = centerActions;
- },
-
- /**
- * Called from the plugin doorhanger to set the new permissions for a plugin
- * and activate plugins if necessary.
- * aNewState should be either "allownow" "allowalways" or "block"
- */
- _updatePluginPermission: function PH_setPermissionForPlugins(aNotification, aPluginInfo, aNewState) {
- let permission;
- let expireType;
- let expireTime;
-
- switch (aNewState) {
- case "allownow":
- permission = Ci.nsIPermissionManager.ALLOW_ACTION;
- expireType = Ci.nsIPermissionManager.EXPIRE_SESSION;
- expireTime = Date.now() + Services.prefs.getIntPref(kPrefSessionPersistMinutes) * 60 * 1000;
- break;
-
- case "allowalways":
- permission = Ci.nsIPermissionManager.ALLOW_ACTION;
- expireType = Ci.nsIPermissionManager.EXPIRE_TIME;
- expireTime = Date.now() +
- Services.prefs.getIntPref(kPrefPersistentDays) * 24 * 60 * 60 * 1000;
- break;
-
- case "block":
- permission = Ci.nsIPermissionManager.PROMPT_ACTION;
- expireType = Ci.nsIPermissionManager.EXPIRE_NEVER;
- expireTime = 0;
- break;
-
- // In case a plugin has already been allowed in another tab, the "continue allowing" button
- // shouldn't change any permissions but should run the plugin-enablement code below.
- case "continue":
- break;
-
- default:
- Cu.reportError(Error("Unexpected plugin state: " + aNewState));
- return;
- }
-
- let browser = aNotification.browser;
- let contentWindow = browser.contentWindow;
- if (aNewState != "continue") {
- let principal = contentWindow.document.nodePrincipal;
- Services.perms.addFromPrincipal(principal, aPluginInfo.permissionString,
- permission, expireType, expireTime);
-
- if (aNewState == "block") {
- return;
- }
- }
-
- // Manually activate the plugins that would have been automatically
- // activated.
- let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- let plugins = cwu.plugins;
- let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
-
- for (let plugin of plugins) {
- plugin.QueryInterface(Ci.nsIObjectLoadingContent);
- // canActivatePlugin will return false if this isn't a known plugin type,
- // so the pluginHost.getPermissionStringForType call is protected
- if (gPluginHandler.canActivatePlugin(plugin) &&
- aPluginInfo.permissionString == pluginHost.getPermissionStringForType(plugin.actualType)) {
- plugin.playPlugin();
- }
- }
- },
-
- _showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser, aPrimaryPlugin) {
- let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
-
- let contentWindow = aBrowser.contentWindow;
- let contentDoc = aBrowser.contentDocument;
- let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- // Pale Moon: cwu.plugins may contain non-plugin <object>s, filter them out
- let plugins = cwu.plugins.filter(function(plugin) {
- return (plugin.getContentTypeForMIMEType(plugin.actualType) ==
- Ci.nsIObjectLoadingContent.TYPE_PLUGIN);
- });
- if (plugins.length == 0) {
- if (notification) {
- PopupNotifications.remove(notification);
- }
- return;
- }
-
- let icon = 'plugins-notification-icon';
- for (let plugin of plugins) {
- let fallbackType = plugin.pluginFallbackType;
- if (fallbackType == plugin.PLUGIN_VULNERABLE_UPDATABLE ||
- fallbackType == plugin.PLUGIN_VULNERABLE_NO_UPDATE ||
- fallbackType == plugin.PLUGIN_BLOCKLISTED) {
- icon = 'blocked-plugins-notification-icon';
- break;
- }
- if (fallbackType == plugin.PLUGIN_CLICK_TO_PLAY) {
- let overlay = contentDoc.getAnonymousElementByAttribute(plugin, "anonid", "main");
- if (!overlay || overlay.style.visibility == 'hidden') {
- icon = 'alert-plugins-notification-icon';
- }
- }
- }
-
- let dismissed = notification ? notification.dismissed : true;
- if (aPrimaryPlugin)
- dismissed = false;
-
- let primaryPluginPermission = null;
- if (aPrimaryPlugin) {
- primaryPluginPermission = this._getPluginInfo(aPrimaryPlugin).permissionString;
- }
-
- let options = {
- dismissed: dismissed,
- eventCallback: this._clickToPlayNotificationEventCallback,
- primaryPlugin: primaryPluginPermission
- };
- PopupNotifications.show(aBrowser, "click-to-play-plugins",
- "", icon,
- null, null, options);
- },
-
- // Crashed-plugin observer. Notified once per plugin crash, before events
- // are dispatched to individual plugin instances.
- pluginCrashed : function(subject, topic, data) {
- let propertyBag = subject;
- if (!(propertyBag instanceof Ci.nsIPropertyBag2) ||
- !(propertyBag instanceof Ci.nsIWritablePropertyBag2))
- return;
- },
-
- // Crashed-plugin event listener. Called for every instance of a
- // plugin in content.
- pluginInstanceCrashed: function (plugin, aEvent) {
- // Ensure the plugin and event are of the right type.
- if (!(aEvent instanceof Ci.nsIDOMDataContainerEvent))
- return;
-
- let submittedReport = aEvent.getData("submittedCrashReport");
- let doPrompt = true; // XXX followup for .getData("doPrompt");
- let submitReports = true; // XXX followup for .getData("submitReports");
- let pluginName = aEvent.getData("pluginName");
- let pluginDumpID = aEvent.getData("pluginDumpID");
- let browserDumpID = aEvent.getData("browserDumpID");
-
- // Remap the plugin name to a more user-presentable form.
- pluginName = this.makeNicePluginName(pluginName);
-
- let messageString = gNavigatorBundle.getFormattedString("crashedpluginsMessage.title", [pluginName]);
-
- //
- // Configure the crashed-plugin placeholder.
- //
-
- // Force a layout flush so the binding is attached.
- plugin.clientTop;
- let doc = plugin.ownerDocument;
- let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
- let statusDiv = doc.getAnonymousElementByAttribute(plugin, "class", "submitStatus");
-
- let crashText = doc.getAnonymousElementByAttribute(plugin, "class", "msgCrashedText");
- crashText.textContent = messageString;
-
- let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
-
- let link = doc.getAnonymousElementByAttribute(plugin, "class", "reloadLink");
- this.addLinkClickCallback(link, "reloadPage", browser);
-
- let notificationBox = gBrowser.getNotificationBox(browser);
-
- let isShowing = true;
-
- // Is the <object>'s size too small to hold what we want to show?
- if (this.isTooSmall(plugin, overlay)) {
- // First try hiding the crash report submission UI.
- statusDiv.removeAttribute("status");
-
- if (this.isTooSmall(plugin, overlay)) {
- // Hide the overlay's contents. Use visibility style, so that it doesn't
- // collapse down to 0x0.
- overlay.style.visibility = "hidden";
- isShowing = false;
- }
- }
-
- if (isShowing) {
- // If a previous plugin on the page was too small and resulted in adding a
- // notification bar, then remove it because this plugin instance it big
- // enough to serve as in-content notification.
- hideNotificationBar();
- doc.mozNoPluginCrashedNotification = true;
- } else {
- // If another plugin on the page was large enough to show our UI, we don't
- // want to show a notification bar.
- if (!doc.mozNoPluginCrashedNotification)
- showNotificationBar(pluginDumpID, browserDumpID);
- }
-
- function hideNotificationBar() {
- let notification = notificationBox.getNotificationWithValue("plugin-crashed");
- if (notification)
- notificationBox.removeNotification(notification, true);
- }
-
- function showNotificationBar(pluginDumpID, browserDumpID) {
- // If there's already an existing notification bar, don't do anything.
- let notification = notificationBox.getNotificationWithValue("plugin-crashed");
- if (notification)
- return;
-
- // Configure the notification bar
- let priority = notificationBox.PRIORITY_WARNING_MEDIUM;
- let iconURL = "chrome://mozapps/skin/plugins/notifyPluginCrashed.png";
- let reloadLabel = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.label");
- let reloadKey = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.accesskey");
- let submitLabel = gNavigatorBundle.getString("crashedpluginsMessage.submitButton.label");
- let submitKey = gNavigatorBundle.getString("crashedpluginsMessage.submitButton.accesskey");
-
- let buttons = [{
- label: reloadLabel,
- accessKey: reloadKey,
- popup: null,
- callback: function() { browser.reload(); },
- }];
-
- notification = notificationBox.appendNotification(messageString, "plugin-crashed",
- iconURL, priority, buttons);
-
- // Add the "learn more" link.
- let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- let link = notification.ownerDocument.createElementNS(XULNS, "label");
- link.className = "text-link";
- link.setAttribute("value", gNavigatorBundle.getString("crashedpluginsMessage.learnMore"));
- let crashurl = formatURL("app.support.baseURL", true);
- crashurl += "plugin-crashed-notificationbar";
- link.href = crashurl;
-
- let description = notification.ownerDocument.getAnonymousElementByAttribute(notification, "anonid", "messageText");
- description.appendChild(link);
-
- // Remove the notfication when the page is reloaded.
- doc.defaultView.top.addEventListener("unload", function() {
- notificationBox.removeNotification(notification);
- }, false);
- }
-
- }
-};
diff --git a/base/content/browser-sets.inc b/base/content/browser-sets.inc
deleted file mode 100644
index 78fce26..0000000
--- a/base/content/browser-sets.inc
+++ /dev/null
@@ -1,357 +0,0 @@
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# 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/.
-
-#ifdef XP_UNIX
-#ifndef XP_MACOSX
-#define XP_GNOME 1
-#endif
-#endif
-
- <stringbundleset id="stringbundleset">
- <stringbundle id="bundle_brand" src="chrome://branding/locale/brand.properties"/>
- <stringbundle id="bundle_shell" src="chrome://browser/locale/shellservice.properties"/>
- <stringbundle id="bundle_preferences" src="chrome://browser/locale/preferences/preferences.properties"/>
- </stringbundleset>
-
- <commandset id="mainCommandSet">
- <command id="cmd_newNavigator" oncommand="OpenBrowserWindow()"/>
- <command id="cmd_handleBackspace" oncommand="BrowserHandleBackspace();" />
- <command id="cmd_handleShiftBackspace" oncommand="BrowserHandleShiftBackspace();" />
-
- <command id="cmd_newNavigatorTab" oncommand="BrowserOpenTab();"/>
- <command id="Browser:OpenFile" oncommand="BrowserOpenFileWindow();"/>
- <command id="Browser:SavePage" oncommand="saveDocument(window.content.document);"/>
-
- <command id="Browser:SendLink"
- oncommand="MailIntegration.sendLinkForWindow(window.content);"/>
-
- <command id="cmd_pageSetup" oncommand="PrintUtils.showPageSetup();"/>
- <command id="cmd_print" oncommand="PrintUtils.print();"/>
- <command id="cmd_printPreview" oncommand="PrintUtils.printPreview(PrintPreviewListener);"/>
- <command id="cmd_close" oncommand="BrowserCloseTabOrWindow()"/>
- <command id="cmd_closeWindow" oncommand="BrowserTryToCloseWindow()"/>
- <command id="cmd_toggleMute" oncommand="gBrowser.selectedTab.toggleMuteAudio()"/>
- <command id="cmd_ToggleTabsOnTop" oncommand="TabsOnTop.toggle()"/>
- <command id="cmd_CustomizeToolbars" oncommand="BrowserCustomizeToolbar()"/>
- <command id="cmd_restartApplication" oncommand="restart(false);"/>
- <command id="cmd_quitApplication" oncommand="goQuitApplication()"/>
-
-
- <commandset id="editMenuCommands"/>
-
- <command id="View:PageSource" oncommand="BrowserViewSourceOfDocument(content.document);" observes="isImage"/>
- <command id="View:PageInfo" oncommand="BrowserPageInfo();"/>
- <command id="View:FullScreen" oncommand="BrowserFullScreen();"/>
- <command id="cmd_find"
- oncommand="gFindBar.onFindCommand();"
- observes="isImage"/>
- <command id="cmd_findAgain"
- oncommand="gFindBar.onFindAgainCommand(false);"
- observes="isImage"/>
- <command id="cmd_findPrevious"
- oncommand="gFindBar.onFindAgainCommand(true);"
- observes="isImage"/>
- <!-- work-around bug 392512 -->
- <command id="Browser:AddBookmarkAs"
- oncommand="PlacesCommandHook.bookmarkCurrentPage(true, PlacesUtils.bookmarksMenuFolderId);"/>
- <!-- The command disabled state must be manually updated through
- PlacesCommandHook.updateBookmarkAllTabsCommand() -->
- <command id="Browser:BookmarkAllTabs"
- oncommand="PlacesCommandHook.bookmarkCurrentPages();"/>
- <command id="Browser:Home" oncommand="BrowserHome();"/>
- <command id="Browser:Back" oncommand="BrowserBack();" disabled="true"/>
- <command id="Browser:BackOrBackDuplicate" oncommand="BrowserBack(event);" disabled="true">
- <observes element="Browser:Back" attribute="disabled"/>
- </command>
- <command id="Browser:Forward" oncommand="BrowserForward();" disabled="true"/>
- <command id="Browser:ForwardOrForwardDuplicate" oncommand="BrowserForward(event);" disabled="true">
- <observes element="Browser:Forward" attribute="disabled"/>
- </command>
- <command id="Browser:Stop" oncommand="BrowserStop();" disabled="true"/>
- <command id="Browser:Reload" oncommand="if (event.shiftKey) BrowserReloadSkipCache(); else BrowserReload()" disabled="true"/>
- <command id="Browser:ReloadOrDuplicate" oncommand="BrowserReloadOrDuplicate(event)" disabled="true">
- <observes element="Browser:Reload" attribute="disabled"/>
- </command>
- <command id="Browser:ReloadSkipCache" oncommand="BrowserReloadSkipCache()" disabled="true">
- <observes element="Browser:Reload" attribute="disabled"/>
- </command>
- <command id="Browser:NextTab" oncommand="gBrowser.tabContainer.advanceSelectedTab(1, true);"/>
- <command id="Browser:PrevTab" oncommand="gBrowser.tabContainer.advanceSelectedTab(-1, true);"/>
- <command id="Browser:ShowAllTabs" oncommand="allTabs.open();"/>
- <command id="cmd_fullZoomReduce" oncommand="FullZoom.reduce()"/>
- <command id="cmd_fullZoomEnlarge" oncommand="FullZoom.enlarge()"/>
- <command id="cmd_fullZoomReset" oncommand="FullZoom.reset()"/>
- <command id="cmd_fullZoomToggle" oncommand="ZoomManager.toggleZoom();"/>
- <command id="cmd_gestureRotateLeft" oncommand="gGestureSupport.rotate(event.sourceEvent)"/>
- <command id="cmd_gestureRotateRight" oncommand="gGestureSupport.rotate(event.sourceEvent)"/>
- <command id="cmd_gestureRotateEnd" oncommand="gGestureSupport.rotateEnd()"/>
- <command id="Browser:OpenLocation" oncommand="openLocation();"/>
- <command id="Browser:RestoreLastSession" oncommand="restoreLastSession();" disabled="true"/>
-
- <command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
- <command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/>
- <command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
- <command id="Tools:Permissions" oncommand="BrowserOpenPermissionsMgr();"/>
- <command id="Tools:ErrorConsole" oncommand="toJavaScriptConsole()" disabled="true" hidden="true"/>
- <command id="Tools:Sanitize"
- oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/>
- <command id="Tools:PrivateBrowsing"
- oncommand="OpenBrowserWindow({private: true});"/>
- <command id="History:UndoCloseTab" oncommand="undoCloseTab();"/>
- <command id="History:UndoCloseWindow" oncommand="undoCloseWindow();"/>
- <command id="Browser:ToggleAddonBar" oncommand="toggleAddonBar();"/>
- </commandset>
-
- <commandset id="placesCommands">
- <command id="Browser:ShowAllBookmarks"
- oncommand="PlacesCommandHook.showPlacesOrganizer('AllBookmarks');"/>
- <command id="Browser:ShowAllHistory"
- oncommand="PlacesCommandHook.showPlacesOrganizer('History');"/>
- </commandset>
-
- <broadcasterset id="mainBroadcasterSet">
- <broadcaster id="viewBookmarksSidebar" autoCheck="false" sidebartitle="&bookmarksButton.label;"
- type="checkbox" group="sidebar" sidebarurl="chrome://browser/content/bookmarks/bookmarksPanel.xul"
- oncommand="toggleSidebar('viewBookmarksSidebar');"/>
-
- <!-- for both places and non-places, the sidebar lives at
- chrome://browser/content/history/history-panel.xul so there are no
- problems when switching between versions -->
- <broadcaster id="viewHistorySidebar" autoCheck="false" sidebartitle="&historyButton.label;"
- type="checkbox" group="sidebar"
- sidebarurl="chrome://browser/content/history/history-panel.xul"
- oncommand="toggleSidebar('viewHistorySidebar');"/>
-
- <broadcaster id="viewWebPanelsSidebar" autoCheck="false"
- type="checkbox" group="sidebar" sidebarurl="chrome://browser/content/web-panels.xul"
- oncommand="toggleSidebar('viewWebPanelsSidebar');"/>
-
- <!-- popup blocking menu items -->
- <broadcaster id="blockedPopupAllowSite"
- accesskey="&allowPopups.accesskey;"
- oncommand="gPopupBlockerObserver.toggleAllowPopupsForSite(event);"/>
- <broadcaster id="blockedPopupEditSettings"
-#ifdef XP_WIN
- label="&editPopupSettings.label;"
-#else
- label="&editPopupSettingsUnix.label;"
-#endif
- accesskey="&editPopupSettings.accesskey;"
- oncommand="gPopupBlockerObserver.editPopupSettings();"/>
- <broadcaster id="blockedPopupDontShowMessage"
- accesskey="&dontShowMessage.accesskey;"
- type="checkbox"
- oncommand="gPopupBlockerObserver.dontShowMessage();"/>
- <broadcaster id="blockedPopupsSeparator"/>
- <broadcaster id="isImage"/>
- <broadcaster id="isFrameImage"/>
- <broadcaster id="singleFeedMenuitemState" disabled="true"/>
- <broadcaster id="multipleFeedsMenuState" hidden="true"/>
-#ifdef MOZ_SERVICES_SYNC
- <broadcaster id="sync-setup-state"/>
- <broadcaster id="sync-syncnow-state"/>
-#endif
- <broadcaster id="workOfflineMenuitemState"/>
-
- <broadcaster id="devtoolsMenuBroadcaster_PageSource"
- label="&pageSourceCmd.label;"
- key="key_viewSource"
- command="View:PageSource"/>
- <broadcaster id="devtoolsMenuBroadcaster_ErrorConsole"
- label="&errorConsoleCmd.label;"
- command="Tools:ErrorConsole"/>
- </broadcasterset>
-
- <keyset id="mainKeyset">
- <key id="key_newNavigator"
- key="&newNavigatorCmd.key;"
- command="cmd_newNavigator"
- modifiers="accel"/>
- <key id="key_newNavigatorTab" key="&tabCmd.commandkey;" modifiers="accel" command="cmd_newNavigatorTab"/>
- <key id="focusURLBar" key="&openCmd.commandkey;" command="Browser:OpenLocation"
- modifiers="accel"/>
-#ifndef XP_MACOSX
- <key id="focusURLBar2" key="&urlbar.accesskey;" command="Browser:OpenLocation"
- modifiers="alt"/>
-#endif
-
-#
-# Search Command Key Logic works like this:
-#
-# Unix: Ctrl+K (cross platform binding)
-# Ctrl+J (in case of emacs Ctrl-K conflict)
-# Mac: Cmd+K (cross platform binding)
-# Cmd+Opt+F (platform convention)
-# Win: Ctrl+K (cross platform binding)
-# Ctrl+E (IE compat)
-#
-# We support Ctrl+K on all platforms now and advertise it in the menu since it is
-# our standard - it is a "safe" choice since it is near no harmful keys like "W" as
-# "E" is. People mourning the loss of Ctrl+K for emacs compat can switch their GTK
-# system setting to use emacs emulation, and we should respect it. Focus-Search-Box
-# is a fundamental keybinding and we are maintaining a XP binding so that it is easy
-# for people to switch to Linux.
-#
- <key id="key_search" key="&searchFocus.commandkey;" command="Tools:Search" modifiers="accel"/>
-#ifdef XP_MACOSX
- <key id="key_search2" key="&findOnCmd.commandkey;" command="Tools:Search" modifiers="accel,alt"/>
-#endif
-#ifdef XP_WIN
- <key id="key_search2" key="&searchFocus.commandkey2;" command="Tools:Search" modifiers="accel"/>
-#endif
-#ifdef XP_GNOME
- <key id="key_search2" key="&searchFocusUnix.commandkey;" command="Tools:Search" modifiers="accel"/>
- <key id="key_openDownloads" key="&downloadsUnix.commandkey;" command="Tools:Downloads" modifiers="accel,shift"/>
-#else
- <key id="key_openDownloads" key="&downloads.commandkey;" command="Tools:Downloads" modifiers="accel"/>
-#endif
- <key id="key_openAddons" key="&addons.commandkey;" command="Tools:Addons" modifiers="accel,shift"/>
- <key id="openFileKb" key="&openFileCmd.commandkey;" command="Browser:OpenFile" modifiers="accel"/>
- <key id="key_savePage" key="&savePageCmd.commandkey;" command="Browser:SavePage" modifiers="accel"/>
- <key id="printKb" key="&printCmd.commandkey;" command="cmd_print" modifiers="accel"/>
- <key id="key_close" key="&closeCmd.key;" command="cmd_close" modifiers="accel"/>
- <key id="key_closeWindow" key="&closeCmd.key;" command="cmd_closeWindow" modifiers="accel,shift"/>
- <key id="key_toggleMute" key="&toggleMuteCmd.key;" command="cmd_toggleMute" modifiers="control"/>
- <key id="key_undo"
- key="&undoCmd.key;"
- modifiers="accel"/>
-#ifdef XP_UNIX
- <key id="key_redo" key="&undoCmd.key;" modifiers="accel,shift"/>
-#else
- <key id="key_redo" key="&redoCmd.key;" modifiers="accel"/>
-#endif
- <key id="key_cut"
- key="&cutCmd.key;"
- modifiers="accel"/>
- <key id="key_copy"
- key="&copyCmd.key;"
- modifiers="accel"/>
- <key id="key_paste"
- key="&pasteCmd.key;"
- modifiers="accel"/>
- <key id="key_delete" keycode="VK_DELETE" command="cmd_delete"/>
- <key id="key_selectAll" key="&selectAllCmd.key;" modifiers="accel"/>
-
- <key keycode="VK_BACK" command="cmd_handleBackspace"/>
- <key keycode="VK_BACK" command="cmd_handleShiftBackspace" modifiers="shift"/>
-#ifndef XP_MACOSX
- <key id="goBackKb" keycode="VK_LEFT" command="Browser:Back" modifiers="alt"/>
- <key id="goForwardKb" keycode="VK_RIGHT" command="Browser:Forward" modifiers="alt"/>
-#else
- <key id="goBackKb" keycode="VK_LEFT" command="Browser:Back" modifiers="accel" />
- <key id="goForwardKb" keycode="VK_RIGHT" command="Browser:Forward" modifiers="accel" />
-#endif
-#ifdef XP_UNIX
- <key id="goBackKb2" key="&goBackCmd.commandKey;" command="Browser:Back" modifiers="accel"/>
- <key id="goForwardKb2" key="&goForwardCmd.commandKey;" command="Browser:Forward" modifiers="accel"/>
-#endif
- <key id="goHome" keycode="VK_HOME" command="Browser:Home" modifiers="alt"/>
- <key keycode="VK_F5" command="Browser:Reload"/>
-#ifndef XP_MACOSX
- <key id="showAllHistoryKb" key="&showAllHistoryCmd.commandkey;" command="Browser:ShowAllHistory" modifiers="accel,shift"/>
- <key keycode="VK_F5" command="Browser:ReloadSkipCache" modifiers="accel"/>
- <key id="key_fullScreen" keycode="VK_F11" command="View:FullScreen"/>
-#else
- <key id="key_fullScreen" key="&fullScreenCmd.macCommandKey;" command="View:FullScreen" modifiers="accel,control"/>
- <key id="key_fullScreen_old" key="&fullScreenCmd.macCommandKey;" command="View:FullScreen" modifiers="accel,shift"/>
- <key keycode="VK_F11" command="View:FullScreen"/>
-#endif
- <key key="&reloadCmd.commandkey;" command="Browser:Reload" modifiers="accel" id="key_reload"/>
- <key key="&reloadCmd.commandkey;" command="Browser:ReloadSkipCache" modifiers="accel,shift"/>
- <key id="key_viewSource" key="&pageSourceCmd.commandkey;" command="View:PageSource" modifiers="accel"/>
-#ifndef XP_WIN
- <key id="key_viewInfo" key="&pageInfoCmd.commandkey;" command="View:PageInfo" modifiers="accel"/>
-#endif
- <key id="key_find" key="&findOnCmd.commandkey;" command="cmd_find" modifiers="accel"/>
- <key id="key_findAgain" key="&findAgainCmd.commandkey;" command="cmd_findAgain" modifiers="accel"/>
- <key id="key_findPrevious" key="&findAgainCmd.commandkey;" command="cmd_findPrevious" modifiers="accel,shift"/>
- <key keycode="&findAgainCmd.commandkey2;" command="cmd_findAgain"/>
- <key keycode="&findAgainCmd.commandkey2;" command="cmd_findPrevious" modifiers="shift"/>
-
- <key id="addBookmarkAsKb" key="&bookmarkThisPageCmd.commandkey;" command="Browser:AddBookmarkAs" modifiers="accel"/>
-# Accel+Shift+A-F are reserved on GTK
-#ifndef MOZ_WIDGET_GTK
- <key id="bookmarkAllTabsKb" key="&bookmarkThisPageCmd.commandkey;" oncommand="PlacesCommandHook.bookmarkCurrentPages();" modifiers="accel,shift"/>
- <key id="manBookmarkKb" key="&bookmarksCmd.commandkey;" command="Browser:ShowAllBookmarks" modifiers="accel,shift"/>
-#else
- <key id="manBookmarkKb" key="&bookmarksGtkCmd.commandkey;" command="Browser:ShowAllBookmarks" modifiers="accel,shift"/>
-#endif
- <key id="viewBookmarksSidebarKb" key="&bookmarksCmd.commandkey;" command="viewBookmarksSidebar" modifiers="accel"/>
-#ifdef XP_WIN
-# Cmd+I is conventially mapped to Info on MacOS X, thus it should not be
-# overridden for other purposes there.
- <key id="viewBookmarksSidebarWinKb" key="&bookmarksWinCmd.commandkey;" command="viewBookmarksSidebar" modifiers="accel"/>
-#endif
-
-# Navigation cancel keys: Esc performs a cancel on loading (i.e.: stop button equivalent)
-# Shift-Esc (and similar Shift-modified stop on Mac) performs a "superstop": this halts all
-# networking requests, XHR, animated gifs, etc.
- <key id="key_stop" keycode="VK_ESCAPE" command="Browser:Stop"/>
- <key id="key_stop_all" keycode="VK_ESCAPE" modifiers="shift" oncommand="BrowserStop();"/>
-#ifdef XP_MACOSX
- <key id="key_stop_mac" modifiers="accel" key="&stopCmd.macCommandKey;" command="Browser:Stop"/>
- <key id="key_stop_all_mac" modifiers="accel,shift" key="&stopCmd.macCommandKey;" oncommand="BrowserStop();"/>
-#endif
-
- <key id="key_gotoHistory"
- key="&historySidebarCmd.commandKey;"
-#ifdef XP_MACOSX
- modifiers="accel,shift"
-#else
- modifiers="accel"
-#endif
- command="viewHistorySidebar"/>
-
- <key id="key_fullZoomReduce" key="&fullZoomReduceCmd.commandkey;" command="cmd_fullZoomReduce" modifiers="accel"/>
- <key key="&fullZoomReduceCmd.commandkey2;" command="cmd_fullZoomReduce" modifiers="accel"/>
- <key id="key_fullZoomEnlarge" key="&fullZoomEnlargeCmd.commandkey;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
- <key key="&fullZoomEnlargeCmd.commandkey2;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
- <key key="&fullZoomEnlargeCmd.commandkey3;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
- <key id="key_fullZoomReset" key="&fullZoomResetCmd.commandkey;" command="cmd_fullZoomReset" modifiers="accel"/>
- <key key="&fullZoomResetCmd.commandkey2;" command="cmd_fullZoomReset" modifiers="accel"/>
-
- <key id="key_showAllTabs" command="Browser:ShowAllTabs" keycode="VK_TAB" modifiers="control,shift"/>
-
- <key id="key_switchTextDirection" key="&bidiSwitchTextDirectionItem.commandkey;" command="cmd_switchTextDirection" modifiers="accel,shift" />
-
- <key id="key_privatebrowsing" command="Tools:PrivateBrowsing" key="&privateBrowsingCmd.commandkey;" modifiers="accel,shift"/>
- <key id="key_sanitize" command="Tools:Sanitize" keycode="VK_DELETE" modifiers="accel,shift"/>
-#ifdef XP_MACOSX
- <key id="key_sanitize_mac" command="Tools:Sanitize" keycode="VK_BACK" modifiers="accel,shift"/>
-#endif
-#ifdef XP_UNIX
- <key id="key_quitApplication" key="&quitApplicationCmdUnix.key;" command="cmd_quitApplication" modifiers="accel"/>
-#endif
-
-#ifdef FULL_BROWSER_WINDOW
- <key id="key_undoCloseTab" command="History:UndoCloseTab" key="&tabCmd.commandkey;" modifiers="accel,shift"/>
-#endif
- <key id="key_undoCloseWindow" command="History:UndoCloseWindow" key="&newNavigatorCmd.key;" modifiers="accel,shift"/>
-
-#ifdef XP_GNOME
-#define NUM_SELECT_TAB_MODIFIER alt
-#else
-#define NUM_SELECT_TAB_MODIFIER accel
-#endif
-
-#expand <key id="key_selectTab1" oncommand="gBrowser.selectTabAtIndex(0, event);" key="1" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
-#expand <key id="key_selectTab2" oncommand="gBrowser.selectTabAtIndex(1, event);" key="2" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
-#expand <key id="key_selectTab3" oncommand="gBrowser.selectTabAtIndex(2, event);" key="3" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
-#expand <key id="key_selectTab4" oncommand="gBrowser.selectTabAtIndex(3, event);" key="4" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
-#expand <key id="key_selectTab5" oncommand="gBrowser.selectTabAtIndex(4, event);" key="5" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
-#expand <key id="key_selectTab6" oncommand="gBrowser.selectTabAtIndex(5, event);" key="6" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
-#expand <key id="key_selectTab7" oncommand="gBrowser.selectTabAtIndex(6, event);" key="7" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
-#expand <key id="key_selectTab8" oncommand="gBrowser.selectTabAtIndex(7, event);" key="8" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
-#expand <key id="key_selectLastTab" oncommand="gBrowser.selectTabAtIndex(-1, event);" key="9" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
-
- <key id="key_toggleAddonBar" command="Browser:ToggleAddonBar" key="&toggleAddonBarCmd.key;" modifiers="accel"/>
-
- </keyset>
-
-# Used by baseMenuOverlay
-#ifdef XP_MACOSX
- <commandset id="baseMenuCommandSet" />
-#endif
- <keyset id="baseMenuKeyset" />
diff --git a/base/content/browser-syncui.js b/base/content/browser-syncui.js
deleted file mode 100644
index 86f6f48..0000000
--- a/base/content/browser-syncui.js
+++ /dev/null
@@ -1,472 +0,0 @@
-# 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/.
-
-// gSyncUI handles updating the tools menu
-var gSyncUI = {
- _obs: ["weave:service:sync:start",
- "weave:service:sync:delayed",
- "weave:service:quota:remaining",
- "weave:service:setup-complete",
- "weave:service:login:start",
- "weave:service:login:finish",
- "weave:service:logout:finish",
- "weave:service:start-over",
- "weave:ui:login:error",
- "weave:ui:sync:error",
- "weave:ui:sync:finish",
- "weave:ui:clear-error",
- ],
-
- _unloaded: false,
-
- init: function SUI_init() {
- // Proceed to set up the UI if Sync has already started up.
- // Otherwise we'll do it when Sync is firing up.
- let xps = Components.classes["@mozilla.org/weave/service;1"]
- .getService(Components.interfaces.nsISupports)
- .wrappedJSObject;
- if (xps.ready) {
- this.initUI();
- return;
- }
-
- Services.obs.addObserver(this, "weave:service:ready", true);
-
- // Remove the observer if the window is closed before the observer
- // was triggered.
- window.addEventListener("unload", function onUnload() {
- gSyncUI._unloaded = true;
- window.removeEventListener("unload", onUnload, false);
- Services.obs.removeObserver(gSyncUI, "weave:service:ready");
-
- if (Weave.Status.ready) {
- gSyncUI._obs.forEach(function(topic) {
- Services.obs.removeObserver(gSyncUI, topic);
- });
- }
- }, false);
- },
-
- initUI: function SUI_initUI() {
- // If this is a browser window?
- if (gBrowser) {
- this._obs.push("weave:notification:added");
- }
-
- this._obs.forEach(function(topic) {
- Services.obs.addObserver(this, topic, true);
- }, this);
-
- if (gBrowser && Weave.Notifications.notifications.length) {
- this.initNotifications();
- }
- this.updateUI();
- },
-
- initNotifications: function SUI_initNotifications() {
- const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- let notificationbox = document.createElementNS(XULNS, "notificationbox");
- notificationbox.id = "sync-notifications";
- notificationbox.setAttribute("flex", "1");
-
- let bottombox = document.getElementById("browser-bottombox");
- bottombox.insertBefore(notificationbox, bottombox.firstChild);
-
- // Force a style flush to ensure that our binding is attached.
- notificationbox.clientTop;
-
- // notificationbox will listen to observers from now on.
- Services.obs.removeObserver(this, "weave:notification:added");
- },
-
- _wasDelayed: false,
-
- _needsSetup: function SUI__needsSetup() {
- let firstSync = Services.prefs.getCharPref("services.sync.firstSync", "");
- return Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED ||
- firstSync == "notReady";
- },
-
- updateUI: function SUI_updateUI() {
- let needsSetup = this._needsSetup();
- document.getElementById("sync-setup-state").hidden = !needsSetup;
- document.getElementById("sync-syncnow-state").hidden = needsSetup;
-
- if (!gBrowser) {
- return;
- }
-
- let button = document.getElementById("sync-button");
- if (!button) {
- return;
- }
-
- button.removeAttribute("status");
-
- this._updateLastSyncTime();
-
- if (needsSetup) {
- button.removeAttribute("tooltiptext");
- button.setAttribute("label", this._stringBundle.GetStringFromName("setupsync.label"));
- } else {
- button.setAttribute("label", this._stringBundle.GetStringFromName("syncnow.label"));
- }
- },
-
-
- // Functions called by observers
- onActivityStart: function SUI_onActivityStart() {
- if (!gBrowser)
- return;
-
- let button = document.getElementById("sync-button");
- if (!button)
- return;
-
- button.setAttribute("status", "active");
- button.setAttribute("label", this._stringBundle.GetStringFromName("syncing2.label"));
- },
-
- onSyncDelay: function SUI_onSyncDelay() {
- // basically, we want to just inform users that stuff is going to take a while
- let title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
- let description = this._stringBundle.GetStringFromName("error.sync.no_node_found");
- let buttons = [new Weave.NotificationButton(
- this._stringBundle.GetStringFromName("error.sync.serverStatusButton.label"),
- this._stringBundle.GetStringFromName("error.sync.serverStatusButton.accesskey"),
- function() { gSyncUI.openServerStatus(); return true; }
- )];
- let notification = new Weave.Notification(
- title, description, null, Weave.Notifications.PRIORITY_INFO, buttons);
- Weave.Notifications.replaceTitle(notification);
- this._wasDelayed = true;
- },
-
- onLoginFinish: function SUI_onLoginFinish() {
- // Clear out any login failure notifications
- let title = this._stringBundle.GetStringFromName("error.login.title");
- this.clearError(title);
- },
-
- onSetupComplete: function SUI_onSetupComplete() {
- this.onLoginFinish();
- },
-
- onLoginError: function SUI_onLoginError() {
- // if login fails, any other notifications are essentially moot
- Weave.Notifications.removeAll();
-
- // if we haven't set up the client, don't show errors
- if (this._needsSetup()) {
- this.updateUI();
- return;
- }
-
- let title = this._stringBundle.GetStringFromName("error.login.title");
-
- let description;
- if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) {
- // Convert to days
- let lastSync =
- Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400;
- description =
- this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1);
- } else {
- let reason = Weave.Utils.getErrorString(Weave.Status.login);
- description =
- this._stringBundle.formatStringFromName("error.sync.description", [reason], 1);
- }
-
- let buttons = [];
- buttons.push(new Weave.NotificationButton(
- this._stringBundle.GetStringFromName("error.login.prefs.label"),
- this._stringBundle.GetStringFromName("error.login.prefs.accesskey"),
- function() { gSyncUI.openPrefs(); return true; }
- ));
-
- let notification = new Weave.Notification(title, description, null,
- Weave.Notifications.PRIORITY_WARNING, buttons);
- Weave.Notifications.replaceTitle(notification);
- this.updateUI();
- },
-
- onLogout: function SUI_onLogout() {
- this.updateUI();
- },
-
- onStartOver: function SUI_onStartOver() {
- this.clearError();
- },
-
- onQuotaNotice: function onQuotaNotice(subject, data) {
- let title = this._stringBundle.GetStringFromName("warning.sync.quota.label");
- let description = this._stringBundle.GetStringFromName("warning.sync.quota.description");
- let buttons = [];
- buttons.push(new Weave.NotificationButton(
- this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.label"),
- this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.accesskey"),
- function() { gSyncUI.openQuotaDialog(); return true; }
- ));
-
- let notification = new Weave.Notification(
- title, description, null, Weave.Notifications.PRIORITY_WARNING, buttons);
- Weave.Notifications.replaceTitle(notification);
- },
-
- openServerStatus: function () {
- let statusURL = Services.prefs.getCharPref("services.sync.statusURL");
- window.openUILinkIn(statusURL, "tab");
- },
-
- // Commands
- doSync: function SUI_doSync() {
- setTimeout(function() Weave.Service.errorHandler.syncAndReportErrors(), 0);
- },
-
- handleToolbarButton: function SUI_handleStatusbarButton() {
- if (this._needsSetup())
- this.openSetup();
- else
- this.doSync();
- },
-
- //XXXzpao should be part of syncCommon.js - which we might want to make a module...
- // To be fixed in a followup (bug 583366)
-
- /**
- * Invoke the Sync setup wizard.
- *
- * @param wizardType
- * Indicates type of wizard to launch:
- * null -- regular set up wizard
- * "pair" -- pair a device first
- * "reset" -- reset sync
- */
-
- openSetup: function SUI_openSetup(wizardType) {
- let win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
- if (win)
- win.focus();
- else {
- window.openDialog("chrome://browser/content/sync/setup.xul",
- "weaveSetup", "centerscreen,chrome,resizable=no",
- wizardType);
- }
- },
-
- openAddDevice: function () {
- if (!Weave.Utils.ensureMPUnlocked())
- return;
-
- let win = Services.wm.getMostRecentWindow("Sync:AddDevice");
- if (win)
- win.focus();
- else
- window.openDialog("chrome://browser/content/sync/addDevice.xul",
- "syncAddDevice", "centerscreen,chrome,resizable=no");
- },
-
- openQuotaDialog: function SUI_openQuotaDialog() {
- let win = Services.wm.getMostRecentWindow("Sync:ViewQuota");
- if (win)
- win.focus();
- else
- Services.ww.activeWindow.openDialog(
- "chrome://browser/content/sync/quota.xul", "",
- "centerscreen,chrome,dialog,modal");
- },
-
- openPrefs: function SUI_openPrefs() {
- openPreferences("paneSync");
- },
-
-
- // Helpers
- _updateLastSyncTime: function SUI__updateLastSyncTime() {
- if (!gBrowser)
- return;
-
- let syncButton = document.getElementById("sync-button");
- if (!syncButton)
- return;
-
- let lastSync = Services.prefs.getCharPref("services.sync.lastSync", "");
- if (!lastSync || this._needsSetup()) {
- syncButton.removeAttribute("tooltiptext");
- return;
- }
-
- // Show the day-of-week and time (HH:MM) of last sync
- let lastSyncDate = new Date(lastSync).toLocaleFormat("%a %H:%M");
- let lastSyncLabel =
- this._stringBundle.formatStringFromName("lastSync2.label", [lastSyncDate], 1);
-
- syncButton.setAttribute("tooltiptext", lastSyncLabel);
- },
-
- clearError: function SUI_clearError(errorString) {
- Weave.Notifications.removeAll(errorString);
- this.updateUI();
- },
-
- onSyncFinish: function SUI_onSyncFinish() {
- let title = this._stringBundle.GetStringFromName("error.sync.title");
-
- // Clear out sync failures on a successful sync
- this.clearError(title);
-
- if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) {
- title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
- this.clearError(title);
- this._wasDelayed = false;
- }
- },
-
- onSyncError: function SUI_onSyncError() {
- let title = this._stringBundle.GetStringFromName("error.sync.title");
-
- if (Weave.Status.login != Weave.LOGIN_SUCCEEDED) {
- this.onLoginError();
- return;
- }
-
- let description;
- if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) {
- // Convert to days
- let lastSync =
- Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400;
- description =
- this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1);
- } else {
- let error = Weave.Utils.getErrorString(Weave.Status.sync);
- description =
- this._stringBundle.formatStringFromName("error.sync.description", [error], 1);
- }
- let priority = Weave.Notifications.PRIORITY_WARNING;
- let buttons = [];
-
- // Check if the client is outdated in some way
- let outdated = Weave.Status.sync == Weave.VERSION_OUT_OF_DATE;
- for (let [engine, reason] in Iterator(Weave.Status.engines))
- outdated = outdated || reason == Weave.VERSION_OUT_OF_DATE;
-
- if (outdated) {
- description = this._stringBundle.GetStringFromName(
- "error.sync.needUpdate.description");
- buttons.push(new Weave.NotificationButton(
- this._stringBundle.GetStringFromName("error.sync.needUpdate.label"),
- this._stringBundle.GetStringFromName("error.sync.needUpdate.accesskey"),
- function() {
- window.openUILinkIn(Services.prefs.getCharPref("services.sync.outdated.url"), "tab");
- return true;
- }
- ));
- }
- else if (Weave.Status.sync == Weave.OVER_QUOTA) {
- description = this._stringBundle.GetStringFromName(
- "error.sync.quota.description");
- buttons.push(new Weave.NotificationButton(
- this._stringBundle.GetStringFromName(
- "error.sync.viewQuotaButton.label"),
- this._stringBundle.GetStringFromName(
- "error.sync.viewQuotaButton.accesskey"),
- function() { gSyncUI.openQuotaDialog(); return true; } )
- );
- }
- else if (Weave.Status.enforceBackoff) {
- priority = Weave.Notifications.PRIORITY_INFO;
- buttons.push(new Weave.NotificationButton(
- this._stringBundle.GetStringFromName("error.sync.serverStatusButton.label"),
- this._stringBundle.GetStringFromName("error.sync.serverStatusButton.accesskey"),
- function() { gSyncUI.openServerStatus(); return true; }
- ));
- }
- else {
- priority = Weave.Notifications.PRIORITY_INFO;
- buttons.push(new Weave.NotificationButton(
- this._stringBundle.GetStringFromName("error.sync.tryAgainButton.label"),
- this._stringBundle.GetStringFromName("error.sync.tryAgainButton.accesskey"),
- function() { gSyncUI.doSync(); return true; }
- ));
- }
-
- let notification =
- new Weave.Notification(title, description, null, priority, buttons);
- Weave.Notifications.replaceTitle(notification);
-
- if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) {
- title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
- Weave.Notifications.removeAll(title);
- this._wasDelayed = false;
- }
-
- this.updateUI();
- },
-
- observe: function SUI_observe(subject, topic, data) {
- if (this._unloaded) {
- Cu.reportError("SyncUI observer called after unload: " + topic);
- return;
- }
-
- switch (topic) {
- case "weave:service:sync:start":
- this.onActivityStart();
- break;
- case "weave:ui:sync:finish":
- this.onSyncFinish();
- break;
- case "weave:ui:sync:error":
- this.onSyncError();
- break;
- case "weave:service:sync:delayed":
- this.onSyncDelay();
- break;
- case "weave:service:quota:remaining":
- this.onQuotaNotice();
- break;
- case "weave:service:setup-complete":
- this.onSetupComplete();
- break;
- case "weave:service:login:start":
- this.onActivityStart();
- break;
- case "weave:service:login:finish":
- this.onLoginFinish();
- break;
- case "weave:ui:login:error":
- this.onLoginError();
- break;
- case "weave:service:logout:finish":
- this.onLogout();
- break;
- case "weave:service:start-over":
- this.onStartOver();
- break;
- case "weave:service:ready":
- this.initUI();
- break;
- case "weave:notification:added":
- this.initNotifications();
- break;
- case "weave:ui:clear-error":
- this.clearError();
- break;
- }
- },
-
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsIObserver,
- Ci.nsISupportsWeakReference
- ])
-};
-
-XPCOMUtils.defineLazyGetter(gSyncUI, "_stringBundle", function() {
- //XXXzpao these strings should probably be moved from /services to /browser... (bug 583381)
- // but for now just make it work
- return Cc["@mozilla.org/intl/stringbundle;1"].
- getService(Ci.nsIStringBundleService).
- createBundle("chrome://weave/locale/services/sync.properties");
-});
-
diff --git a/base/content/browser-tabPreviews.js b/base/content/browser-tabPreviews.js
deleted file mode 100644
index e0755b8..0000000
--- a/base/content/browser-tabPreviews.js
+++ /dev/null
@@ -1,1058 +0,0 @@
-/*
-#ifdef 0
- * 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/.
-#endif
- */
-
-/**
- * Tab previews utility, produces thumbnails
- */
-var tabPreviews = {
- aspectRatio: 0.5625, // 16:9
-
- get width() {
- delete this.width;
- return this.width = Math.ceil(screen.availWidth / 5.75);
- },
-
- get height() {
- delete this.height;
- return this.height = Math.round(this.width * this.aspectRatio);
- },
-
- init: function tabPreviews_init() {
- if (this._selectedTab)
- return;
- this._selectedTab = gBrowser.selectedTab;
-
- gBrowser.tabContainer.addEventListener("TabSelect", this, false);
- gBrowser.tabContainer.addEventListener("SSTabRestored", this, false);
- },
-
- get: function tabPreviews_get(aTab) {
- let uri = aTab.linkedBrowser.currentURI.spec;
-
- if (aTab.__thumbnail_lastURI &&
- aTab.__thumbnail_lastURI != uri) {
- aTab.__thumbnail = null;
- aTab.__thumbnail_lastURI = null;
- }
-
- if (aTab.__thumbnail)
- return aTab.__thumbnail;
-
- if (aTab.getAttribute("pending") == "true") {
- let img = new Image;
- img.src = PageThumbs.getThumbnailURL(uri);
- return img;
- }
-
- return this.capture(aTab, !aTab.hasAttribute("busy"));
- },
-
- capture: function tabPreviews_capture(aTab, aStore) {
- var thumbnail = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
- thumbnail.mozOpaque = true;
- thumbnail.height = this.height;
- thumbnail.width = this.width;
-
- var ctx = thumbnail.getContext("2d");
- var win = aTab.linkedBrowser.contentWindow;
- var snippetWidth = win.innerWidth * .6;
- var scale = this.width / snippetWidth;
- ctx.scale(scale, scale);
- ctx.drawWindow(win, win.scrollX, win.scrollY,
- snippetWidth, snippetWidth * this.aspectRatio, "rgb(255,255,255)");
-
- if (aStore &&
- aTab.linkedBrowser /* bug 795608: the tab may got removed while drawing the thumbnail */) {
- aTab.__thumbnail = thumbnail;
- aTab.__thumbnail_lastURI = aTab.linkedBrowser.currentURI.spec;
- }
-
- return thumbnail;
- },
-
- handleEvent: function tabPreviews_handleEvent(event) {
- switch (event.type) {
- case "TabSelect":
- if (this._selectedTab &&
- this._selectedTab.parentNode &&
- !this._pendingUpdate) {
- // Generate a thumbnail for the tab that was selected.
- // The timeout keeps the UI snappy and prevents us from generating thumbnails
- // for tabs that will be closed. During that timeout, don't generate other
- // thumbnails in case multiple TabSelect events occur fast in succession.
- this._pendingUpdate = true;
- setTimeout(function (self, aTab) {
- self._pendingUpdate = false;
- if (aTab.parentNode &&
- !aTab.hasAttribute("busy") &&
- !aTab.hasAttribute("pending"))
- self.capture(aTab, true);
- }, 2000, this, this._selectedTab);
- }
- this._selectedTab = event.target;
- break;
- case "SSTabRestored":
- this.capture(event.target, true);
- break;
- }
- }
-};
-
-var tabPreviewPanelHelper = {
- opening: function (host) {
- host.panel.hidden = false;
-
- var handler = this._generateHandler(host);
- host.panel.addEventListener("popupshown", handler, false);
- host.panel.addEventListener("popuphiding", handler, false);
-
- host._prevFocus = document.commandDispatcher.focusedElement;
- },
- _generateHandler: function (host) {
- var self = this;
- return function (event) {
- if (event.target == host.panel) {
- host.panel.removeEventListener(event.type, arguments.callee, false);
- self["_" + event.type](host);
- }
- };
- },
- _popupshown: function (host) {
- if ("setupGUI" in host)
- host.setupGUI();
- },
- _popuphiding: function (host) {
- if ("suspendGUI" in host)
- host.suspendGUI();
-
- if (host._prevFocus) {
- Cc["@mozilla.org/focus-manager;1"]
- .getService(Ci.nsIFocusManager)
- .setFocus(host._prevFocus, Ci.nsIFocusManager.FLAG_NOSCROLL);
- host._prevFocus = null;
- } else
- gBrowser.selectedBrowser.focus();
-
- if (host.tabToSelect) {
- gBrowser.selectedTab = host.tabToSelect;
- host.tabToSelect = null;
- }
- }
-};
-
-/**
- * Ctrl-Tab panel
- */
-var ctrlTab = {
- get panel () {
- delete this.panel;
- return this.panel = document.getElementById("ctrlTab-panel");
- },
- get showAllButton () {
- delete this.showAllButton;
- return this.showAllButton = document.getElementById("ctrlTab-showAll");
- },
- get previews () {
- delete this.previews;
- return this.previews = this.panel.getElementsByClassName("ctrlTab-preview");
- },
- get recentlyUsedLimit () {
- delete this.recentlyUsedLimit;
- return this.recentlyUsedLimit = gPrefService.getIntPref("browser.ctrlTab.recentlyUsedLimit");
- },
- get keys () {
- var keys = {};
- ["close", "find", "selectAll"].forEach(function (key) {
- keys[key] = document.getElementById("key_" + key)
- .getAttribute("key")
- .toLocaleLowerCase().charCodeAt(0);
- });
- delete this.keys;
- return this.keys = keys;
- },
- _selectedIndex: 0,
- get selected () this._selectedIndex < 0 ?
- document.activeElement :
- this.previews.item(this._selectedIndex),
- get isOpen () this.panel.state == "open" || this.panel.state == "showing" || this._timer,
- get tabCount () this.tabList.length,
- get tabPreviewCount () Math.min(this.previews.length - 1, this.tabCount),
- get canvasWidth () Math.min(tabPreviews.width,
- Math.ceil(screen.availWidth * .85 / this.tabPreviewCount)),
- get canvasHeight () Math.round(this.canvasWidth * tabPreviews.aspectRatio),
-
- get tabList () {
- if (this._tabList)
- return this._tabList;
-
- // Using gBrowser.tabs instead of gBrowser.visibleTabs, as the latter
- // exlcudes closing tabs, breaking the following loop in case the the
- // selected tab is closing.
- let list = Array.filter(gBrowser.tabs, function (tab) !tab.hidden);
-
- // Rotate the list until the selected tab is first
- while (!list[0].selected)
- list.push(list.shift());
-
- list = list.filter(function (tab) !tab.closing);
-
- if (this.recentlyUsedLimit != 0) {
- let recentlyUsedTabs = [];
- for (let tab of this._recentlyUsedTabs) {
- if (!tab.hidden && !tab.closing) {
- recentlyUsedTabs.push(tab);
- if (this.recentlyUsedLimit > 0 && recentlyUsedTabs.length >= this.recentlyUsedLimit)
- break;
- }
- }
- for (let i = recentlyUsedTabs.length - 1; i >= 0; i--) {
- list.splice(list.indexOf(recentlyUsedTabs[i]), 1);
- list.unshift(recentlyUsedTabs[i]);
- }
- }
-
- return this._tabList = list;
- },
-
- init: function ctrlTab_init() {
- if (!this._recentlyUsedTabs) {
- tabPreviews.init();
-
- this._recentlyUsedTabs = [gBrowser.selectedTab];
- this._init(true);
- }
- },
-
- uninit: function ctrlTab_uninit() {
- this._recentlyUsedTabs = null;
- this._init(false);
- },
-
- prefName: "browser.ctrlTab.previews",
- readPref: function ctrlTab_readPref() {
- var enable =
- gPrefService.getBoolPref(this.prefName) &&
- (!gPrefService.prefHasUserValue("browser.ctrlTab.disallowForScreenReaders") ||
- !gPrefService.getBoolPref("browser.ctrlTab.disallowForScreenReaders"));
-
- if (enable)
- this.init();
- else
- this.uninit();
- },
- observe: function (aSubject, aTopic, aPrefName) {
- this.readPref();
- },
-
- updatePreviews: function ctrlTab_updatePreviews() {
- for (let i = 0; i < this.previews.length; i++)
- this.updatePreview(this.previews[i], this.tabList[i]);
-
- var showAllLabel = gNavigatorBundle.getString("ctrlTab.showAll.label");
- this.showAllButton.label =
- PluralForm.get(this.tabCount, showAllLabel).replace("#1", this.tabCount);
- },
-
- updatePreview: function ctrlTab_updatePreview(aPreview, aTab) {
- if (aPreview == this.showAllButton)
- return;
-
- aPreview._tab = aTab;
-
- if (aPreview.firstChild)
- aPreview.removeChild(aPreview.firstChild);
- if (aTab) {
- let canvasWidth = this.canvasWidth;
- let canvasHeight = this.canvasHeight;
- aPreview.appendChild(tabPreviews.get(aTab));
- aPreview.setAttribute("label", aTab.label);
- aPreview.setAttribute("tooltiptext", aTab.label);
- aPreview.setAttribute("crop", aTab.crop);
- aPreview.setAttribute("canvaswidth", canvasWidth);
- aPreview.setAttribute("canvasstyle",
- "max-width:" + canvasWidth + "px;" +
- "min-width:" + canvasWidth + "px;" +
- "max-height:" + canvasHeight + "px;" +
- "min-height:" + canvasHeight + "px;");
- if (aTab.image)
- aPreview.setAttribute("image", aTab.image);
- else
- aPreview.removeAttribute("image");
- aPreview.hidden = false;
- } else {
- aPreview.hidden = true;
- aPreview.removeAttribute("label");
- aPreview.removeAttribute("tooltiptext");
- aPreview.removeAttribute("image");
- }
- },
-
- advanceFocus: function ctrlTab_advanceFocus(aForward) {
- let selectedIndex = Array.indexOf(this.previews, this.selected);
- do {
- selectedIndex += aForward ? 1 : -1;
- if (selectedIndex < 0)
- selectedIndex = this.previews.length - 1;
- else if (selectedIndex >= this.previews.length)
- selectedIndex = 0;
- } while (this.previews[selectedIndex].hidden);
-
- if (this._selectedIndex == -1) {
- // Focus is already in the panel.
- this.previews[selectedIndex].focus();
- } else {
- this._selectedIndex = selectedIndex;
- }
-
- if (this._timer) {
- clearTimeout(this._timer);
- this._timer = null;
- this._openPanel();
- }
- },
-
- _mouseOverFocus: function ctrlTab_mouseOverFocus(aPreview) {
- if (this._trackMouseOver)
- aPreview.focus();
- },
-
- pick: function ctrlTab_pick(aPreview) {
- if (!this.tabCount)
- return;
-
- var select = (aPreview || this.selected);
-
- if (select == this.showAllButton)
- this.showAllTabs();
- else
- this.close(select._tab);
- },
-
- showAllTabs: function ctrlTab_showAllTabs(aPreview) {
- this.close();
- document.getElementById("Browser:ShowAllTabs").doCommand();
- },
-
- remove: function ctrlTab_remove(aPreview) {
- if (aPreview._tab)
- gBrowser.removeTab(aPreview._tab);
- },
-
- attachTab: function ctrlTab_attachTab(aTab, aPos) {
- if (aPos == 0)
- this._recentlyUsedTabs.unshift(aTab);
- else if (aPos)
- this._recentlyUsedTabs.splice(aPos, 0, aTab);
- else
- this._recentlyUsedTabs.push(aTab);
- },
- detachTab: function ctrlTab_detachTab(aTab) {
- var i = this._recentlyUsedTabs.indexOf(aTab);
- if (i >= 0)
- this._recentlyUsedTabs.splice(i, 1);
- },
-
- open: function ctrlTab_open() {
- if (this.isOpen)
- return;
-
- allTabs.close();
-
- document.addEventListener("keyup", this, true);
-
- this.updatePreviews();
- this._selectedIndex = 1;
-
- // Add a slight delay before showing the UI, so that a quick
- // "ctrl-tab" keypress just flips back to the MRU tab.
- this._timer = setTimeout(function (self) {
- self._timer = null;
- self._openPanel();
- }, 200, this);
- },
-
- _openPanel: function ctrlTab_openPanel() {
- tabPreviewPanelHelper.opening(this);
-
- this.panel.width = Math.min(screen.availWidth * .99,
- this.canvasWidth * 1.25 * this.tabPreviewCount);
- var estimateHeight = this.canvasHeight * 1.25 + 75;
- this.panel.openPopupAtScreen(screen.availLeft + (screen.availWidth - this.panel.width) / 2,
- screen.availTop + (screen.availHeight - estimateHeight) / 2,
- false);
- },
-
- close: function ctrlTab_close(aTabToSelect) {
- if (!this.isOpen)
- return;
-
- if (this._timer) {
- clearTimeout(this._timer);
- this._timer = null;
- this.suspendGUI();
- if (aTabToSelect)
- gBrowser.selectedTab = aTabToSelect;
- return;
- }
-
- this.tabToSelect = aTabToSelect;
- this.panel.hidePopup();
- },
-
- setupGUI: function ctrlTab_setupGUI() {
- this.selected.focus();
- this._selectedIndex = -1;
-
- // Track mouse movement after a brief delay so that the item that happens
- // to be under the mouse pointer initially won't be selected unintentionally.
- this._trackMouseOver = false;
- setTimeout(function (self) {
- if (self.isOpen)
- self._trackMouseOver = true;
- }, 0, this);
- },
-
- suspendGUI: function ctrlTab_suspendGUI() {
- document.removeEventListener("keyup", this, true);
-
- Array.forEach(this.previews, function (preview) {
- this.updatePreview(preview, null);
- }, this);
-
- this._tabList = null;
- },
-
- onKeyPress: function ctrlTab_onKeyPress(event) {
- var isOpen = this.isOpen;
-
- if (isOpen) {
- event.preventDefault();
- event.stopPropagation();
- }
-
- switch (event.keyCode) {
- case event.DOM_VK_TAB:
- if (event.ctrlKey && !event.altKey && !event.metaKey) {
- if (isOpen) {
- this.advanceFocus(!event.shiftKey);
- } else if (!event.shiftKey) {
- event.preventDefault();
- event.stopPropagation();
- let tabs = gBrowser.visibleTabs;
- if (tabs.length > 2) {
- this.open();
- } else if (tabs.length == 2) {
- let index = tabs[0].selected ? 1 : 0;
- gBrowser.selectedTab = tabs[index];
- }
- }
- }
- break;
- default:
- if (isOpen && event.ctrlKey) {
- if (event.keyCode == event.DOM_VK_DELETE) {
- this.remove(this.selected);
- break;
- }
- switch (event.charCode) {
- case this.keys.close:
- this.remove(this.selected);
- break;
- case this.keys.find:
- case this.keys.selectAll:
- this.showAllTabs();
- break;
- }
- }
- }
- },
-
- removeClosingTabFromUI: function ctrlTab_removeClosingTabFromUI(aTab) {
- if (this.tabCount == 2) {
- this.close();
- return;
- }
-
- this._tabList = null;
- this.updatePreviews();
-
- if (this.selected.hidden)
- this.advanceFocus(false);
- if (this.selected == this.showAllButton)
- this.advanceFocus(false);
-
- // If the current tab is removed, another tab can steal our focus.
- if (aTab.selected && this.panel.state == "open") {
- setTimeout(function (selected) {
- selected.focus();
- }, 0, this.selected);
- }
- },
-
- handleEvent: function ctrlTab_handleEvent(event) {
- switch (event.type) {
- case "TabAttrModified":
- // tab attribute modified (e.g. label, crop, busy, image, selected)
- for (let i = this.previews.length - 1; i >= 0; i--) {
- if (this.previews[i]._tab && this.previews[i]._tab == event.target) {
- this.updatePreview(this.previews[i], event.target);
- break;
- }
- }
- break;
- case "TabSelect":
- this.detachTab(event.target);
- this.attachTab(event.target, 0);
- break;
- case "TabOpen":
- this.attachTab(event.target, 1);
- break;
- case "TabClose":
- this.detachTab(event.target);
- if (this.isOpen)
- this.removeClosingTabFromUI(event.target);
- break;
- case "keypress":
- this.onKeyPress(event);
- break;
- case "keyup":
- if (event.keyCode == event.DOM_VK_CONTROL)
- this.pick();
- break;
- }
- },
-
- _init: function ctrlTab__init(enable) {
- var toggleEventListener = enable ? "addEventListener" : "removeEventListener";
-
- var tabContainer = gBrowser.tabContainer;
- tabContainer[toggleEventListener]("TabOpen", this, false);
- tabContainer[toggleEventListener]("TabAttrModified", this, false);
- tabContainer[toggleEventListener]("TabSelect", this, false);
- tabContainer[toggleEventListener]("TabClose", this, false);
-
- document[toggleEventListener]("keypress", this, false);
- gBrowser.mTabBox.handleCtrlTab = !enable;
-
- // If we're not running, hide the "Show All Tabs" menu item,
- // as Shift+Ctrl+Tab will be handled by the tab bar.
- document.getElementById("menu_showAllTabs").hidden = !enable;
-
- // Also disable the <key> to ensure Shift+Ctrl+Tab never triggers
- // Show All Tabs.
- var key_showAllTabs = document.getElementById("key_showAllTabs");
- if (enable)
- key_showAllTabs.removeAttribute("disabled");
- else
- key_showAllTabs.setAttribute("disabled", "true");
- }
-};
-
-
-/**
- * All Tabs panel
- */
-var allTabs = {
- get panel () {
- delete this.panel;
- return this.panel = document.getElementById("allTabs-panel");
- },
- get filterField () {
- delete this.filterField;
- return this.filterField = document.getElementById("allTabs-filter");
- },
- get container () {
- delete this.container;
- return this.container = document.getElementById("allTabs-container");
- },
- get tabCloseButton () {
- delete this.tabCloseButton;
- return this.tabCloseButton = document.getElementById("allTabs-tab-close-button");
- },
- get toolbarButton() document.getElementById("alltabs-button"),
- get previews () this.container.getElementsByClassName("allTabs-preview"),
- get isOpen () this.panel.state == "open" || this.panel.state == "showing",
-
- init: function allTabs_init() {
- if (this._initiated)
- return;
- this._initiated = true;
-
- tabPreviews.init();
-
- Array.forEach(gBrowser.tabs, function (tab) {
- this._addPreview(tab);
- }, this);
-
- gBrowser.tabContainer.addEventListener("TabOpen", this, false);
- gBrowser.tabContainer.addEventListener("TabAttrModified", this, false);
- gBrowser.tabContainer.addEventListener("TabMove", this, false);
- gBrowser.tabContainer.addEventListener("TabClose", this, false);
- },
-
- uninit: function allTabs_uninit() {
- if (!this._initiated)
- return;
-
- gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
- gBrowser.tabContainer.removeEventListener("TabAttrModified", this, false);
- gBrowser.tabContainer.removeEventListener("TabMove", this, false);
- gBrowser.tabContainer.removeEventListener("TabClose", this, false);
-
- while (this.container.hasChildNodes())
- this.container.removeChild(this.container.firstChild);
-
- this._initiated = false;
- },
-
- prefName: "browser.allTabs.previews",
- readPref: function allTabs_readPref() {
- var allTabsButton = this.toolbarButton;
- if (!allTabsButton)
- return;
-
- if (gPrefService.getBoolPref(this.prefName)) {
- allTabsButton.removeAttribute("type");
- allTabsButton.setAttribute("command", "Browser:ShowAllTabs");
- } else {
- allTabsButton.setAttribute("type", "menu");
- allTabsButton.removeAttribute("command");
- allTabsButton.removeAttribute("oncommand");
- }
- },
- observe: function (aSubject, aTopic, aPrefName) {
- this.readPref();
- },
-
- pick: function allTabs_pick(aPreview) {
- if (!aPreview)
- aPreview = this._firstVisiblePreview;
- if (aPreview)
- this.tabToSelect = aPreview._tab;
-
- this.close();
- },
-
- closeTab: function allTabs_closeTab(event) {
- this.filterField.focus();
- gBrowser.removeTab(event.currentTarget._targetPreview._tab);
- },
-
- filter: function allTabs_filter() {
- if (this._currentFilter == this.filterField.value)
- return;
-
- this._currentFilter = this.filterField.value;
-
- var filter = this._currentFilter.split(/\s+/g);
- this._visible = 0;
- Array.forEach(this.previews, function (preview) {
- var tab = preview._tab;
- var matches = 0;
- if (filter.length && !tab.hidden) {
- let tabstring = tab.linkedBrowser.currentURI.spec;
- try {
- tabstring = decodeURI(tabstring);
- } catch (e) {}
- tabstring = tab.label + " " + tab.label.toLocaleLowerCase() + " " + tabstring;
- for (let i = 0; i < filter.length; i++)
- matches += tabstring.includes(filter[i]);
- }
- if (matches < filter.length || tab.hidden) {
- preview.hidden = true;
- }
- else {
- this._visible++;
- this._updatePreview(preview);
- preview.hidden = false;
- }
- }, this);
-
- this._reflow();
- },
-
- open: function allTabs_open() {
- var allTabsButton = this.toolbarButton;
- if (allTabsButton &&
- allTabsButton.getAttribute("type") == "menu") {
- // Without setTimeout, the menupopup won't stay open when invoking
- // "View > Show All Tabs" and the menu bar auto-hides.
- setTimeout(function () {
- allTabsButton.open = true;
- }, 0);
- return;
- }
-
- this.init();
-
- if (this.isOpen)
- return;
-
- this._maxPanelHeight = Math.max(gBrowser.clientHeight, screen.availHeight / 2);
- this._maxPanelWidth = Math.max(gBrowser.clientWidth, screen.availWidth / 2);
-
- this.filter();
-
- tabPreviewPanelHelper.opening(this);
-
- this.panel.popupBoxObject.setConsumeRollupEvent(PopupBoxObject.ROLLUP_NO_CONSUME);
- this.panel.openPopup(gBrowser, "overlap", 0, 0, false, true);
- },
-
- close: function allTabs_close() {
- this.panel.hidePopup();
- },
-
- setupGUI: function allTabs_setupGUI() {
- this.filterField.focus();
- this.filterField.placeholder = this.filterField.tooltipText;
-
- this.panel.addEventListener("keypress", this, false);
- this.panel.addEventListener("keypress", this, true);
- this._browserCommandSet.addEventListener("command", this, false);
-
- // When the panel is open, a second click on the all tabs button should
- // close the panel but not re-open it.
- document.getElementById("Browser:ShowAllTabs").setAttribute("disabled", "true");
- },
-
- suspendGUI: function allTabs_suspendGUI() {
- this.filterField.placeholder = "";
- this.filterField.value = "";
- this._currentFilter = null;
-
- this._updateTabCloseButton();
-
- this.panel.removeEventListener("keypress", this, false);
- this.panel.removeEventListener("keypress", this, true);
- this._browserCommandSet.removeEventListener("command", this, false);
-
- setTimeout(function () {
- document.getElementById("Browser:ShowAllTabs").removeAttribute("disabled");
- }, 300);
- },
-
- handleEvent: function allTabs_handleEvent(event) {
- if (event.type.startsWith("Tab")) {
- var tab = event.target;
- if (event.type != "TabOpen")
- var preview = this._getPreview(tab);
- }
- switch (event.type) {
- case "TabAttrModified":
- // tab attribute modified (e.g. label, crop, busy, image)
- if (!preview.hidden)
- this._updatePreview(preview);
- break;
- case "TabOpen":
- if (this.isOpen)
- this.close();
- this._addPreview(tab);
- break;
- case "TabMove":
- let siblingPreview = tab.nextSibling &&
- this._getPreview(tab.nextSibling);
- if (siblingPreview)
- siblingPreview.parentNode.insertBefore(preview, siblingPreview);
- else
- this.container.lastChild.appendChild(preview);
- if (this.isOpen && !preview.hidden) {
- this._reflow();
- preview.focus();
- }
- break;
- case "TabClose":
- this._removePreview(preview);
- break;
- case "keypress":
- this._onKeyPress(event);
- break;
- case "command":
- if (event.target.id != "Browser:ShowAllTabs") {
- // Close the panel when there's a browser command executing in the background.
- this.close();
- }
- break;
- }
- },
-
- _visible: 0,
- _currentFilter: null,
- get _stack () {
- delete this._stack;
- return this._stack = document.getElementById("allTabs-stack");
- },
- get _browserCommandSet () {
- delete this._browserCommandSet;
- return this._browserCommandSet = document.getElementById("mainCommandSet");
- },
- get _previewLabelHeight () {
- delete this._previewLabelHeight;
- return this._previewLabelHeight = parseInt(getComputedStyle(this.previews[0], "").lineHeight);
- },
-
- get _visiblePreviews ()
- Array.filter(this.previews, function (preview) !preview.hidden),
-
- get _firstVisiblePreview () {
- if (this._visible == 0)
- return null;
- var previews = this.previews;
- for (let i = 0; i < previews.length; i++) {
- if (!previews[i].hidden)
- return previews[i];
- }
- return null;
- },
-
- _reflow: function allTabs_reflow() {
- this._updateTabCloseButton();
-
- const CONTAINER_MAX_WIDTH = this._maxPanelWidth * .95;
- const CONTAINER_MAX_HEIGHT = this._maxPanelHeight - 35;
- // the size of the whole preview relative to the thumbnail
- const REL_PREVIEW_THUMBNAIL = 1.2;
- const REL_PREVIEW_HEIGHT_WIDTH = tabPreviews.height / tabPreviews.width;
- const PREVIEW_MAX_WIDTH = tabPreviews.width * REL_PREVIEW_THUMBNAIL;
-
- var rows, previewHeight, previewWidth, outerHeight;
- this._columns = Math.floor(CONTAINER_MAX_WIDTH / PREVIEW_MAX_WIDTH);
- do {
- rows = Math.ceil(this._visible / this._columns);
- previewWidth = Math.min(PREVIEW_MAX_WIDTH,
- Math.round(CONTAINER_MAX_WIDTH / this._columns));
- previewHeight = Math.round(previewWidth * REL_PREVIEW_HEIGHT_WIDTH);
- outerHeight = previewHeight + this._previewLabelHeight;
- } while (rows * outerHeight > CONTAINER_MAX_HEIGHT && ++this._columns);
-
- var outerWidth = previewWidth;
- {
- let innerWidth = Math.ceil(previewWidth / REL_PREVIEW_THUMBNAIL);
- let innerHeight = Math.ceil(previewHeight / REL_PREVIEW_THUMBNAIL);
- var canvasStyle = "max-width:" + innerWidth + "px;" +
- "min-width:" + innerWidth + "px;" +
- "max-height:" + innerHeight + "px;" +
- "min-height:" + innerHeight + "px;";
- }
-
- var previews = Array.slice(this.previews);
-
- while (this.container.hasChildNodes())
- this.container.removeChild(this.container.firstChild);
- for (let i = rows || 1; i > 0; i--)
- this.container.appendChild(document.createElement("hbox"));
-
- var row = this.container.firstChild;
- var colCount = 0;
- previews.forEach(function (preview) {
- if (!preview.hidden &&
- ++colCount > this._columns) {
- row = row.nextSibling;
- colCount = 1;
- }
- preview.setAttribute("minwidth", outerWidth);
- preview.setAttribute("height", outerHeight);
- preview.setAttribute("canvasstyle", canvasStyle);
- preview.removeAttribute("closebuttonhover");
- row.appendChild(preview);
- }, this);
-
- this._stack.width = this._maxPanelWidth;
- this.container.width = Math.ceil(outerWidth * Math.min(this._columns, this._visible));
- this.container.left = Math.round((this._maxPanelWidth - this.container.width) / 2);
- this.container.maxWidth = this._maxPanelWidth - this.container.left;
- this.container.maxHeight = rows * outerHeight;
- },
-
- _addPreview: function allTabs_addPreview(aTab) {
- var preview = document.createElement("button");
- preview.className = "allTabs-preview";
- preview._tab = aTab;
- this.container.lastChild.appendChild(preview);
- },
-
- _removePreview: function allTabs_removePreview(aPreview) {
- var updateUI = (this.isOpen && !aPreview.hidden);
- aPreview._tab = null;
- aPreview.parentNode.removeChild(aPreview);
- if (updateUI) {
- this._visible--;
- this._reflow();
- this.filterField.focus();
- }
- },
-
- _getPreview: function allTabs_getPreview(aTab) {
- var previews = this.previews;
- for (let i = 0; i < previews.length; i++)
- if (previews[i]._tab == aTab)
- return previews[i];
- return null;
- },
-
- _updateTabCloseButton: function allTabs_updateTabCloseButton(event) {
- if (event && event.target == this.tabCloseButton)
- return;
-
- if (this.tabCloseButton._targetPreview) {
- if (event && event.target == this.tabCloseButton._targetPreview)
- return;
-
- this.tabCloseButton._targetPreview.removeAttribute("closebuttonhover");
- }
-
- if (event &&
- event.target.parentNode.parentNode == this.container &&
- (event.target._tab.previousSibling || event.target._tab.nextSibling)) {
- let canvas = event.target.firstChild.getBoundingClientRect();
- let container = this.container.getBoundingClientRect();
- let tabCloseButton = this.tabCloseButton.getBoundingClientRect();
- let alignLeft = getComputedStyle(this.panel, "").direction == "rtl";
-#ifdef XP_MACOSX
- alignLeft = !alignLeft;
-#endif
- this.tabCloseButton.left = canvas.left -
- container.left +
- parseInt(this.container.left) +
- (alignLeft ? 0 :
- canvas.width - tabCloseButton.width);
- this.tabCloseButton.top = canvas.top - container.top;
- this.tabCloseButton._targetPreview = event.target;
- this.tabCloseButton.style.visibility = "visible";
- event.target.setAttribute("closebuttonhover", "true");
- } else {
- this.tabCloseButton.style.visibility = "hidden";
- this.tabCloseButton.left = this.tabCloseButton.top = 0;
- this.tabCloseButton._targetPreview = null;
- }
- },
-
- _updatePreview: function allTabs_updatePreview(aPreview) {
- aPreview.setAttribute("label", aPreview._tab.label);
- aPreview.setAttribute("tooltiptext", aPreview._tab.label);
- aPreview.setAttribute("crop", aPreview._tab.crop);
- if (aPreview._tab.image)
- aPreview.setAttribute("image", aPreview._tab.image);
- else
- aPreview.removeAttribute("image");
-
- aPreview.removeAttribute("soundplaying");
- aPreview.removeAttribute("muted");
- if (aPreview._tab.hasAttribute("muted"))
- aPreview.setAttribute("muted", "true");
- else if (aPreview._tab.hasAttribute("soundplaying"))
- aPreview.setAttribute("soundplaying", "true");
-
- var thumbnail = tabPreviews.get(aPreview._tab);
- if (aPreview.firstChild) {
- if (aPreview.firstChild == thumbnail)
- return;
- aPreview.removeChild(aPreview.firstChild);
- }
- aPreview.appendChild(thumbnail);
- },
-
- _onKeyPress: function allTabs_onKeyPress(event) {
- if (event.eventPhase == event.CAPTURING_PHASE) {
- this._onCapturingKeyPress(event);
- return;
- }
-
- if (event.keyCode == event.DOM_VK_ESCAPE) {
- this.close();
- event.preventDefault();
- event.stopPropagation();
- return;
- }
-
- if (event.target == this.filterField) {
- switch (event.keyCode) {
- case event.DOM_VK_UP:
- if (this._visible) {
- let previews = this._visiblePreviews;
- let columns = Math.min(previews.length, this._columns);
- previews[Math.floor(previews.length / columns) * columns - 1].focus();
- event.preventDefault();
- event.stopPropagation();
- }
- break;
- case event.DOM_VK_DOWN:
- if (this._visible) {
- this._firstVisiblePreview.focus();
- event.preventDefault();
- event.stopPropagation();
- }
- break;
- }
- }
- },
-
- _onCapturingKeyPress: function allTabs_onCapturingKeyPress(event) {
- switch (event.keyCode) {
- case event.DOM_VK_UP:
- case event.DOM_VK_DOWN:
- if (event.target != this.filterField)
- this._advanceFocusVertically(event);
- break;
- case event.DOM_VK_RETURN:
- if (event.target == this.filterField) {
- this.filter();
- this.pick();
- event.preventDefault();
- event.stopPropagation();
- }
- break;
- }
- },
-
- _advanceFocusVertically: function allTabs_advanceFocusVertically(event) {
- var preview = document.activeElement;
- if (!preview || preview.parentNode.parentNode != this.container)
- return;
-
- event.stopPropagation();
-
- var up = (event.keyCode == event.DOM_VK_UP);
- var previews = this._visiblePreviews;
-
- if (up && preview == previews[0]) {
- this.filterField.focus();
- return;
- }
-
- var i = previews.indexOf(preview);
- var columns = Math.min(previews.length, this._columns);
- var column = i % columns;
- var row = Math.floor(i / columns);
-
- function newIndex() row * columns + column;
- function outOfBounds() newIndex() >= previews.length;
-
- if (up) {
- row--;
- if (row < 0) {
- let rows = Math.ceil(previews.length / columns);
- row = rows - 1;
- column--;
- if (outOfBounds())
- row--;
- }
- } else {
- row++;
- if (outOfBounds()) {
- if (column == columns - 1) {
- this.filterField.focus();
- return;
- }
- row = 0;
- column++;
- }
- }
- previews[newIndex()].focus();
- }
-};
diff --git a/base/content/browser-tabPreviews.xml b/base/content/browser-tabPreviews.xml
deleted file mode 100644
index 4f54321..0000000
--- a/base/content/browser-tabPreviews.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0"?>
-
-# -*- Mode: HTML -*-
-# 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/.
-
-<bindings id="tabPreviews"
- xmlns="http://www.mozilla.org/xbl"
- xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- xmlns:xbl="http://www.mozilla.org/xbl">
- <binding id="ctrlTab-preview" extends="chrome://global/content/bindings/button.xml#button-base">
- <content pack="center">
- <xul:stack>
- <xul:vbox class="ctrlTab-preview-inner" align="center" pack="center"
- xbl:inherits="width=canvaswidth">
- <xul:hbox class="tabPreview-canvas" xbl:inherits="style=canvasstyle">
- <children/>
- </xul:hbox>
- <xul:label xbl:inherits="value=label,crop" class="plain"/>
- </xul:vbox>
- <xul:hbox class="ctrlTab-favicon-container" xbl:inherits="hidden=noicon">
- <xul:image class="ctrlTab-favicon" xbl:inherits="src=image"/>
- </xul:hbox>
- </xul:stack>
- </content>
- <handlers>
- <handler event="mouseover" action="ctrlTab._mouseOverFocus(this);"/>
- <handler event="command" action="ctrlTab.pick(this);"/>
- <handler event="click" button="1" action="ctrlTab.remove(this);"/>
-#ifdef XP_MACOSX
-# Control+click is a right click on OS X
- <handler event="click" button="2" action="ctrlTab.pick(this);"/>
-#endif
- </handlers>
- </binding>
-
- <binding id="allTabs-preview" extends="chrome://global/content/bindings/button.xml#button-base">
- <content pack="center" align="center">
- <xul:stack>
- <xul:vbox class="allTabs-preview-inner" align="center" pack="center">
- <xul:hbox class="tabPreview-canvas" xbl:inherits="style=canvasstyle">
- <children/>
- </xul:hbox>
- <xul:hbox align="center">
- <xul:image xbl:inherits="soundplaying,muted" class="allTabs-endimage"/>
- <xul:label flex="1" xbl:inherits="value=label,crop" class="allTabs-preview-label plain"/>
- </xul:hbox>
- </xul:vbox>
- <xul:hbox class="allTabs-favicon-container">
- <xul:image class="allTabs-favicon" xbl:inherits="src=image"/>
- </xul:hbox>
- </xul:stack>
- </content>
- <handlers>
- <handler event="command" action="allTabs.pick(this);"/>
- <handler event="click" button="1" action="gBrowser.removeTab(this._tab);"/>
-
- <handler event="dragstart"><![CDATA[
- event.dataTransfer.mozSetDataAt("application/x-moz-node", this._tab, 0);
- ]]></handler>
-
- <handler event="dragover"><![CDATA[
- let tab = event.dataTransfer.mozGetDataAt("application/x-moz-node", 0);
- if (tab && tab.parentNode == gBrowser.tabContainer)
- event.preventDefault();
- ]]></handler>
-
- <handler event="drop"><![CDATA[
- let tab = event.dataTransfer.mozGetDataAt("application/x-moz-node", 0);
- if (tab && tab.parentNode == gBrowser.tabContainer) {
- let newIndex = Array.indexOf(gBrowser.tabs, this._tab);
- gBrowser.moveTabTo(tab, newIndex);
- }
- ]]></handler>
- </handlers>
- </binding>
-</bindings>
diff --git a/base/content/browser-thumbnails.js b/base/content/browser-thumbnails.js
deleted file mode 100644
index 079b0ac..0000000
--- a/base/content/browser-thumbnails.js
+++ /dev/null
@@ -1,203 +0,0 @@
-#ifdef 0
-/* 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/. */
-#endif
-
-/**
- * Keeps thumbnails of open web pages up-to-date.
- */
-var gBrowserThumbnails = {
- /**
- * Pref that controls whether we can store SSL content on disk
- */
- PREF_DISK_CACHE_SSL: "browser.cache.disk_cache_ssl",
-
- _captureDelayMS: 1000,
-
- /**
- * Used to keep track of disk_cache_ssl preference
- */
- _sslDiskCacheEnabled: null,
-
- /**
- * Map of capture() timeouts assigned to their browsers.
- */
- _timeouts: null,
-
- /**
- * List of tab events we want to listen for.
- */
- _tabEvents: ["TabClose", "TabSelect"],
-
- init: function Thumbnails_init() {
- // Bug 863512 - Make page thumbnails work in electrolysis
- if (gMultiProcessBrowser)
- return;
-
- try {
- if (Services.prefs.getBoolPref("browser.pagethumbnails.capturing_disabled"))
- return;
- } catch (e) {}
-
- PageThumbs.addExpirationFilter(this);
- gBrowser.addTabsProgressListener(this);
- Services.prefs.addObserver(this.PREF_DISK_CACHE_SSL, this, false);
-
- this._sslDiskCacheEnabled =
- Services.prefs.getBoolPref(this.PREF_DISK_CACHE_SSL);
-
- this._tabEvents.forEach(function (aEvent) {
- gBrowser.tabContainer.addEventListener(aEvent, this, false);
- }, this);
-
- this._timeouts = new WeakMap();
- },
-
- uninit: function Thumbnails_uninit() {
- // Bug 863512 - Make page thumbnails work in electrolysis
- if (gMultiProcessBrowser)
- return;
-
- PageThumbs.removeExpirationFilter(this);
- gBrowser.removeTabsProgressListener(this);
- Services.prefs.removeObserver(this.PREF_DISK_CACHE_SSL, this);
-
- this._tabEvents.forEach(function (aEvent) {
- gBrowser.tabContainer.removeEventListener(aEvent, this, false);
- }, this);
- },
-
- handleEvent: function Thumbnails_handleEvent(aEvent) {
- switch (aEvent.type) {
- case "scroll":
- let browser = aEvent.currentTarget;
- if (this._timeouts.has(browser))
- this._delayedCapture(browser);
- break;
- case "TabSelect":
- this._delayedCapture(aEvent.target.linkedBrowser);
- break;
- case "TabClose": {
- this._clearTimeout(aEvent.target.linkedBrowser);
- break;
- }
- }
- },
-
- observe: function Thumbnails_observe() {
- this._sslDiskCacheEnabled =
- Services.prefs.getBoolPref(this.PREF_DISK_CACHE_SSL);
- },
-
- filterForThumbnailExpiration:
- function Thumbnails_filterForThumbnailExpiration(aCallback) {
- // Tycho: aCallback([browser.currentURI.spec for (browser of gBrowser.browsers)]);
- let result = [];
- for (let browser of gBrowser.browsers) {
- result.push(browser.currentURI.spec);
- }
- aCallback(result);
- },
-
- /**
- * State change progress listener for all tabs.
- */
- onStateChange: function Thumbnails_onStateChange(aBrowser, aWebProgress,
- aRequest, aStateFlags, aStatus) {
- if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
- aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK)
- this._delayedCapture(aBrowser);
- },
-
- _capture: function Thumbnails_capture(aBrowser) {
- if (this._shouldCapture(aBrowser))
- PageThumbs.captureAndStore(aBrowser);
- },
-
- _delayedCapture: function Thumbnails_delayedCapture(aBrowser) {
- if (this._timeouts.has(aBrowser))
- clearTimeout(this._timeouts.get(aBrowser));
- else
- aBrowser.addEventListener("scroll", this, true);
-
- let timeout = setTimeout(function () {
- this._clearTimeout(aBrowser);
- this._capture(aBrowser);
- }.bind(this), this._captureDelayMS);
-
- this._timeouts.set(aBrowser, timeout);
- },
-
- _shouldCapture: function Thumbnails_shouldCapture(aBrowser) {
- // Capture only if it's the currently selected tab.
- if (aBrowser != gBrowser.selectedBrowser)
- return false;
-
- // Don't capture in per-window private browsing mode.
- if (PrivateBrowsingUtils.isWindowPrivate(window))
- return false;
-
- let doc = aBrowser.contentDocument;
-
- // FIXME Bug 720575 - Don't capture thumbnails for SVG or XML documents as
- // that currently regresses Talos SVG tests.
- if (doc instanceof XMLDocument)
- return false;
-
- // There's no point in taking screenshot of loading pages.
- if (aBrowser.docShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
- return false;
-
- // Don't take screenshots of about: pages.
- if (aBrowser.currentURI.schemeIs("about"))
- return false;
-
- let channel = aBrowser.docShell.currentDocumentChannel;
-
- // No valid document channel. We shouldn't take a screenshot.
- if (!channel)
- return false;
-
- // Don't take screenshots of internally redirecting about: pages.
- // This includes error pages.
- let uri = channel.originalURI;
- if (uri.schemeIs("about"))
- return false;
-
- let httpChannel;
- try {
- httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
- } catch (e) { /* Not an HTTP channel. */ }
-
- if (httpChannel) {
- // Continue only if we have a 2xx status code.
- try {
- if (Math.floor(httpChannel.responseStatus / 100) != 2)
- return false;
- } catch (e) {
- // Can't get response information from the httpChannel
- // because mResponseHead is not available.
- return false;
- }
-
- // Cache-Control: no-store.
- if (httpChannel.isNoStoreResponse())
- return false;
-
- // Don't capture HTTPS pages unless the user explicitly enabled it.
- if (uri.schemeIs("https") && !this._sslDiskCacheEnabled)
- return false;
- }
-
- return true;
- },
-
- _clearTimeout: function Thumbnails_clearTimeout(aBrowser) {
- if (this._timeouts.has(aBrowser)) {
- aBrowser.removeEventListener("scroll", this, false);
- clearTimeout(this._timeouts.get(aBrowser));
- this._timeouts.delete(aBrowser);
- }
- }
-};
diff --git a/base/content/browser-title.css b/base/content/browser-title.css
deleted file mode 100644
index 5f7e775..0000000
--- a/base/content/browser-title.css
+++ /dev/null
@@ -1,204 +0,0 @@
-/* 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/. */
-
-#main-window::after {
- content: attr(title);
- line-height: 50px;
- max-height: 50px;
- overflow: -moz-hidden-unscrollable;
- pointer-events: none;
- position: fixed;
- word-wrap: break-word;
- -moz-hyphens: auto;
- color: CaptionText;
- font-weight: bold;
- text-align: left;
-}
-
-#main-window:-moz-window-inactive::after {
- color: InactiveCaptionText;
-}
-
-/* Win10 doesn't respond to inactive caption, so dim it instead */
-@media (-moz-os-version: windows-win10) {
- #main-window:-moz-window-inactive::after {
- opacity: 0.5;
- }
-}
-
-/* Hide in fullscreen/TiT mode */
-#main-window[inFullscreen="true"]::after,
-#main-window[sizemode="maximized"][tabsintitlebar="true"]::after,
-#main-window:not([chromemargin])::after {
- opacity: 0 !important;
-}
-
-
-#main-window::after {
- padding: 0 132px; /* AppMenu button/wincontrols width offset */
- left: 0;
- right: 0;
-}
-
-#main-window[privatebrowsingmode=temporary]::after {
- padding: 0px 132px 0px 152px; /* AppMenu button width offset for PB mode */
-}
-
-#main-window[sizemode="normal"]::after {
- left: -12px;
- right: -12px;
-}
-
-/* Windows Classic theme */
-
-@media all and (-moz-windows-classic) {
-
- #main-window::after {
- top: -13px;
- text-shadow: none !important;
- background-position: 2px 18px;
- }
-
-}
-
-
-/* Windows Aero (Vista, non-glass 7/8) */
-
-@media all and (-moz-windows-theme: aero) {
-
- #main-window::after {
- top: -11px;
- font-weight: normal;
- text-shadow: none;
- background-position: 2px 17px;
- }
-
- #main-window[sizemode="maximized"]::after {
- top: -7px;
- }
-
-}
-
-
-/* Windows Aero Glass */
-
-@media (-moz-windows-glass) {
-
- #main-window::after {
- top: -13px;
- color: black;
- text-shadow: rgba(255,255,255,.6) 7px -1px 12px,
- rgba(255,255,255,.6) 6px -1px 13px,
- rgba(255,255,255,.9) 5px -1px 14px,
- rgba(255,255,255,.6) -7px -1px 12px,
- rgba(255,255,255,.6) -6px -1px 13px,
- rgba(255,255,255,.9) -5px -1px 14px;
- z-index: -99999;
- background-position: 2px 18px;
- font-weight: bold;
- }
-
- #main-window[sizemode="maximized"]::after {
- top: -7px;
- }
-
- #main-window:-moz-window-inactive::after {
- opacity: .9;
- color: black;
- text-shadow: rgba(255,255,255,.7) 7px -1px 12px,
- rgba(255,255,255,.5) 6px -1px 13px,
- rgba(255,255,255,.5) 5px -1px 14px,
- rgba(255,255,255,.7) -7px -1px 12px,
- rgba(255,255,255,.5) -6px -1px 13px,
- rgba(255,255,255,.5) -5px -1px 14px;
- }
-
-}
-
-
-/* Generic other themes */
-
-@media all and (-moz-windows-theme: generic) {
-
- #main-window::after {
- font-family: trebuchet MS;
- font-size: 13px;
- text-shadow: 1px 1px rgba(0, 0, 0, .2);
- top: -9px;
- background-position: 2px 16px;
- }
-
- #main-window:-moz-window-inactive::after {
- text-shadow: none;
- }
-
-}
-
-
-/* Compositor style for Win 8/10 */
-
-@media all and (-moz-windows-compositor) {
- @media not all and (-moz-windows-glass) {
-
- #main-window::after {
- background-position: 4px 17px;
- top: -13px;
- }
-
- @media (-moz-os-version: windows-win8) {
- #main-window::after {
- font-size: 15px;
- text-align: center;
- }
-
- #main-window[darkwindowframe="true"]:not(:-moz-window-inactive):not(:-moz-lwtheme)::after {
- /* Dark window frame/accent color on Win 8 */
- color: white;
- }
- }
-
- @media (-moz-os-version: windows-win10) {
- #main-window::after {
- text-align: left;
- }
-
- @media (-moz-windows-accent-color-applies: 0) {
- #main-window:not(:-moz-window-inactive):not(:-moz-lwtheme)::after {
- /* Default Windows 10 styling is white - apply black text styling */
- color: black;
- }
- }
-
- @media (-moz-windows-accent-color-applies) {
- #main-window:not(:-moz-window-inactive):not(:-moz-lwtheme)::after {
- /* Accent color is applied - use the associated text styling */
- color: -moz-win-accentcolortext;
- }
- }
- }
-
- #main-window[sizemode="maximized"]::after {
- top: -5px;
- }
- }
-
-}
-
-/* Lightweight Themes */
-
-#main-window:-moz-lwtheme::after {
- color: inherit;
- text-shadow: inherit;
-}
-
-
-/* Hide for small windows */
-
-@media not all and (min-width: 320px) {
-
- #main-window::after {
- opacity: 0 !important;
- }
-
-} \ No newline at end of file
diff --git a/base/content/browser-uacompat.js b/base/content/browser-uacompat.js
deleted file mode 100644
index 933aa55..0000000
--- a/base/content/browser-uacompat.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* 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 UserAgentCompatibility = {
- PREF_UA_COMPAT: "general.useragent.compatMode",
- PREF_UA_COMPAT_GECKO: "general.useragent.compatMode.gecko",
- PREF_UA_COMPAT_FIREFOX: "general.useragent.compatMode.firefox",
-
- init: function() {
- this.checkPreferences();
- Services.prefs.addObserver(this.PREF_UA_COMPAT, this, false);
- Services.prefs.addObserver(this.PREF_UA_COMPAT_GECKO, this, false);
- Services.prefs.addObserver(this.PREF_UA_COMPAT_FIREFOX, this, false);
- },
-
- uninit: function() {
- Services.prefs.removeObserver(this.PREF_UA_COMPAT, this, false);
- Services.prefs.removeObserver(this.PREF_UA_COMPAT_GECKO, this, false);
- Services.prefs.removeObserver(this.PREF_UA_COMPAT_FIREFOX, this, false);
- },
-
- observe: function() {
- this.checkPreferences();
- },
-
- checkPreferences: function() {
- var compatMode = Services.prefs.getIntPref(this.PREF_UA_COMPAT);
-
- switch(compatMode) {
- case 0:
- Services.prefs.setBoolPref(this.PREF_UA_COMPAT_GECKO, false);
- Services.prefs.setBoolPref(this.PREF_UA_COMPAT_FIREFOX, false);
- break;
- case 1:
- Services.prefs.setBoolPref(this.PREF_UA_COMPAT_GECKO, true);
- Services.prefs.setBoolPref(this.PREF_UA_COMPAT_FIREFOX, false);
- break;
- case 2:
- Services.prefs.setBoolPref(this.PREF_UA_COMPAT_GECKO, true);
- Services.prefs.setBoolPref(this.PREF_UA_COMPAT_FIREFOX, true);
- break;
- }
- }
-};
diff --git a/base/content/browser-webrtcUI.js b/base/content/browser-webrtcUI.js
deleted file mode 100644
index d59134c..0000000
--- a/base/content/browser-webrtcUI.js
+++ /dev/null
@@ -1,55 +0,0 @@
-# -*- 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 WebrtcIndicator = {
- init: function () {
- let temp = {};
- Cu.import("resource:///modules/webrtcUI.jsm", temp);
- this.UIModule = temp.webrtcUI;
-
- this.updateButton();
- },
-
- get button() {
- delete this.button;
- return this.button = document.getElementById("webrtc-status-button");
- },
-
- updateButton: function () {
- this.button.hidden = !this.UIModule.showGlobalIndicator;
- },
-
- fillPopup: function (aPopup) {
- this._menuitemData = new WeakMap;
- for (let streamData of this.UIModule.activeStreams) {
- let menuitem = document.createElement("menuitem");
- menuitem.setAttribute("label", streamData.uri);
- menuitem.setAttribute("tooltiptext", streamData.uri);
-
- this._menuitemData.set(menuitem, streamData);
-
- aPopup.appendChild(menuitem);
- }
- },
-
- clearPopup: function (aPopup) {
- while (aPopup.lastChild)
- aPopup.removeChild(aPopup.lastChild);
- },
-
- menuCommand: function (aMenuitem) {
- let streamData = this._menuitemData.get(aMenuitem);
- if (!streamData)
- return;
-
- let browserWindow = streamData.browser.ownerDocument.defaultView;
- if (streamData.tab) {
- browserWindow.gBrowser.selectedTab = streamData.tab;
- } else {
- streamData.browser.focus();
- }
- browserWindow.focus();
- }
-}
diff --git a/base/content/browser.css b/base/content/browser.css
deleted file mode 100644
index a2970ae..0000000
--- a/base/content/browser.css
+++ /dev/null
@@ -1,759 +0,0 @@
-/* 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/. */
-
-@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
-@namespace html url("http://www.w3.org/1999/xhtml");
-
-searchbar {
- -moz-binding: url("chrome://browser/content/search/search.xml#searchbar");
-}
-
-browser[remote="true"] {
- -moz-binding: url("chrome://global/content/bindings/remote-browser.xml#remote-browser");
-}
-
-tabbrowser {
- -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser");
-}
-
-.tabbrowser-tabs {
- -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tabs");
-}
-
-#tabbrowser-tabs:not([overflow="true"]) ~ #alltabs-button,
-#tabbrowser-tabs:not([overflow="true"]) + #new-tab-button,
-#tabbrowser-tabs[overflow="true"] > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
-#TabsToolbar[currentset]:not([currentset*="tabbrowser-tabs,new-tab-button"]) > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
-#TabsToolbar[customizing="true"] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button {
- visibility: collapse;
-}
-
-#alltabs-button { /* Pale Moon: Always show this button! (less jumpy UI) */
- visibility: visible !important;
-}
-
-#tabbrowser-tabs:not([overflow="true"])[using-closing-tabs-spacer] ~ #alltabs-button {
- visibility: hidden; /* temporary space to keep a tab's close button under the cursor */
-}
-
-.tabbrowser-tab {
- -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
-}
-
-.tabbrowser-tab:not([pinned]) {
- -moz-box-flex: 100;
- max-width: 250px;
- min-width: 100px;
- width: 0;
- transition: min-width 175ms ease-out,
- max-width 200ms ease-out,
- opacity 80ms ease-out 20ms /* hide the tab for the first 20ms of the max-width transition */;
-}
-
-.tabbrowser-tab:not([pinned]):not([fadein]) {
- max-width: 0.1px;
- min-width: 0.1px;
- opacity: 0 !important;
- transition: min-width 175ms ease-out,
- max-width 200ms ease-out,
- opacity 80ms ease-out 180ms /* hide the tab for the last 20ms of the max-width transition */;
-}
-
-.tab-throbber:not([fadein]):not([pinned]),
-.tab-label:not([fadein]):not([pinned]),
-.tab-icon-image:not([fadein]):not([pinned]),
-.tab-close-button:not([fadein]):not([pinned]) {
- display: none;
-}
-
-.tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned] {
- position: fixed !important;
- display: block; /* position:fixed already does this (bug 579776), but let's be explicit */
-}
-
-.tabbrowser-tabs[movingtab] > .tabbrowser-tab[selected] {
- position: relative;
- z-index: 2;
- pointer-events: none; /* avoid blocking dragover events on scroll buttons */
-}
-
-.tabbrowser-tabs[movingtab] > .tabbrowser-tab[fadein]:not([selected]) {
- transition: transform 200ms ease-out;
-}
-
-#alltabs-popup {
- -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-alltabs-popup");
-}
-
-toolbar[printpreview="true"] {
- -moz-binding: url("chrome://global/content/printPreviewBindings.xml#printpreviewtoolbar");
-}
-
-#toolbar-menubar {
- -moz-box-ordinal-group: 5;
-}
-
-#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
- -moz-box-ordinal-group: 50;
-}
-
-#TabsToolbar {
- -moz-box-ordinal-group: 100;
-}
-
-#TabsToolbar[tabsontop="true"] {
- -moz-box-ordinal-group: 10;
-}
-
-%ifdef CAN_DRAW_IN_TITLEBAR
-#main-window[inFullscreen] > #titlebar,
-#main-window[inFullscreen] .titlebar-placeholder,
-#main-window:not([tabsintitlebar]) .titlebar-placeholder {
- display: none;
-}
-
-#titlebar {
- -moz-binding: url("chrome://global/content/bindings/general.xml#windowdragbox");
- -moz-window-dragging: drag;
-}
-
-%ifdef XP_WIN
-#main-window[tabsontop="true"] #TabsToolbar,
-#main-window[tabsontop="true"] #toolbar-menubar,
-#main-window[tabsontop="true"] #navigator-toolbox > toolbar:-moz-lwtheme {
- -moz-window-dragging: drag;
-}
-%endif
-
-#titlebar-spacer {
- pointer-events: none;
-}
-
-#main-window[tabsintitlebar] #appmenu-button-container,
-#main-window[tabsintitlebar] #titlebar-buttonbox {
- position: relative;
-}
-%endif
-
-#main-window[inDOMFullscreen] #sidebar-box,
-#main-window[inDOMFullscreen] #sidebar-splitter {
- visibility: collapse;
-}
-
-.bookmarks-toolbar-customize,
-#wrapper-personal-bookmarks > #personal-bookmarks > #PlacesToolbar > hbox > #PlacesToolbarItems {
- display: none;
-}
-
-#wrapper-personal-bookmarks[place="toolbar"] > #personal-bookmarks > #PlacesToolbar > .bookmarks-toolbar-customize {
- display: -moz-box;
-}
-
-#main-window[disablechrome] #navigator-toolbox[tabsontop="true"] > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
- visibility: collapse;
-}
-
-#wrapper-urlbar-container #urlbar-container > #urlbar > toolbarbutton,
-#urlbar-container:not([combined]) > #urlbar > toolbarbutton,
-#urlbar-container[combined] + #reload-button + #stop-button,
-#urlbar-container[combined] + #reload-button,
-toolbar:not([mode="icons"]) > #urlbar-container > #urlbar > toolbarbutton,
-toolbar[mode="icons"] > #urlbar-container > #urlbar > #urlbar-reload-button:not([displaystop]) + #urlbar-stop-button,
-toolbar[mode="icons"] > #urlbar-container > #urlbar > #urlbar-reload-button[displaystop],
-toolbar[mode="icons"] > #reload-button:not([displaystop]) + #stop-button,
-toolbar[mode="icons"] > #reload-button[displaystop] {
- visibility: collapse;
-}
-
-#feed-button > .toolbarbutton-menu-dropmarker {
- display: none;
-}
-
-#feed-menu > .feed-menuitem:-moz-locale-dir(rtl) {
- direction: rtl;
-}
-
-#main-window:-moz-lwtheme {
- background-repeat: no-repeat;
- background-position: top right;
-}
-
-%ifdef XP_MACOSX
-#main-window[inFullscreen="true"] {
- padding-top: 0; /* override drawintitlebar="true" */
-}
-%endif
-
-#browser-bottombox[lwthemefooter="true"] {
- background-repeat: no-repeat;
- background-position: bottom left;
-}
-
-splitmenu {
- -moz-binding: url("chrome://browser/content/urlbarBindings.xml#splitmenu");
-}
-
-.splitmenu-menuitem {
- -moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem");
- list-style-image: inherit;
- -moz-image-region: inherit;
-}
-
-.splitmenu-menuitem[iconic="true"] {
- -moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
-}
-
-.splitmenu-menu > .menu-text,
-:-moz-any(.splitmenu-menu, .splitmenu-menuitem) > .menu-accel-container,
-#appmenu-editmenu > .menu-text,
-#appmenu-editmenu > .menu-accel-container {
- display: none;
-}
-
-.menuitem-tooltip {
- -moz-binding: url("chrome://browser/content/urlbarBindings.xml#menuitem-tooltip");
-}
-
-.menuitem-iconic-tooltip,
-.menuitem-tooltip[type="checkbox"],
-.menuitem-tooltip[type="radio"] {
- -moz-binding: url("chrome://browser/content/urlbarBindings.xml#menuitem-iconic-tooltip");
-}
-
-%ifdef MENUBAR_CAN_AUTOHIDE
-%ifndef CAN_DRAW_IN_TITLEBAR
-#appmenu-toolbar-button > .toolbarbutton-text {
- display: -moz-box;
-}
-%endif
-
-#appmenu_offlineModeRecovery:not([checked=true]) {
- display: none;
-}
-%endif
-
-/* Hide menu elements intended for keyboard access support */
-#main-menubar[openedwithkey=false] .show-only-for-keyboard {
- display: none;
-}
-
-/* ::::: location bar ::::: */
-#urlbar {
- -moz-binding: url(chrome://browser/content/urlbarBindings.xml#urlbar);
-}
-
-.ac-url-text:-moz-locale-dir(rtl),
-.ac-title:-moz-locale-dir(rtl) > description {
- direction: ltr !important;
-}
-
-/* For results that are actions, their description text is shown instead of
- the URL - this needs to follow the locale's direction, unlike URLs. */
-panel:not([noactions]) > richlistbox > richlistitem[type~="action"]:-moz-locale-dir(rtl) > .ac-url-box {
- direction: rtl;
-}
-
-panel[noactions] > richlistbox > richlistitem[type~="action"] > .ac-url-box > .ac-url > .ac-action-text,
-panel[noactions] > richlistbox > richlistitem[type~="action"] > .ac-url-box > .ac-action-icon {
- visibility: collapse;
-}
-
-panel[noactions] > richlistbox > richlistitem[type~="action"] > .ac-url-box > .ac-url > .ac-url-text {
- visibility: visible;
-}
-
-#urlbar:not([actiontype]) > #urlbar-display-box {
- display: none;
-}
-
-#wrapper-urlbar-container > #urlbar-container > #urlbar {
- -moz-user-input: disabled;
- cursor: -moz-grab;
-}
-
-#PopupAutoComplete {
- -moz-binding: url("chrome://browser/content/urlbarBindings.xml#browser-autocomplete-result-popup");
-}
-
-#PopupAutoCompleteRichResult {
- -moz-binding: url("chrome://browser/content/urlbarBindings.xml#urlbar-rich-result-popup");
-}
-
-#DateTimePickerPanel[active="true"] {
- -moz-binding: url("chrome://global/content/bindings/datetimepopup.xml#datetime-popup");
-}
-
-/* Pale Moon: Address bar: Feeds */
-#ub-feed-button > .button-box > .box-inherit > .button-text,
-#ub-feed-button > .button-box > .button-menu-dropmarker {
- display: none;
-}
-
-#ub-feed-menu > .feed-menuitem:-moz-locale-dir(rtl) {
- direction: rtl;
-}
-
-
-#urlbar-container[combined] > #urlbar > #urlbar-icons > #go-button,
-#urlbar[pageproxystate="invalid"] > #urlbar-icons > .urlbar-icon:not(#go-button),
-#urlbar[pageproxystate="valid"] > #urlbar-icons > #go-button,
-#urlbar[pageproxystate="invalid"][focused="true"] > #urlbar-go-button ~ toolbarbutton,
-#urlbar[pageproxystate="valid"] > #urlbar-go-button,
-#urlbar:not([focused="true"]) > #urlbar-go-button {
- visibility: collapse;
-}
-
-#urlbar[pageproxystate="invalid"] > #identity-box > #identity-icon-labels {
- visibility: collapse;
-}
-
-#urlbar[pageproxystate="invalid"] > #identity-box {
- pointer-events: none;
-}
-
-#identity-icon-labels {
- max-width: 18em;
-}
-
-#identity-icon-country-label {
- direction: ltr;
-}
-
-#identity-box.verifiedIdentity > #identity-icon-labels > #identity-icon-label {
- -moz-margin-end: 0.25em !important;
-}
-
-#wrapper-search-container > #search-container > #searchbar > .searchbar-textbox > .autocomplete-textbox-container > .textbox-input-box > html|*.textbox-input {
- visibility: hidden;
-}
-
-/* Private Autocomplete */
-textbox[type="private-autocomplete"] {
- -moz-binding: url("chrome://browser/content/autocomplete.xml#autocomplete");
-}
-
-panel[type="private-autocomplete"] {
- -moz-binding: url("chrome://browser/content/autocomplete.xml#autocomplete-result-popup");
-}
-
-panel[type="private-autocomplete-richlistbox"] {
- -moz-binding: url("chrome://browser/content/autocomplete.xml#private-autocomplete-rich-result-popup");
-}
-
-.private-autocomplete-tree {
- -moz-binding: url("chrome://browser/content/autocomplete.xml#private-autocomplete-tree");
- -moz-user-focus: ignore;
-}
-
-.private-autocomplete-treebody {
- -moz-binding: url("chrome://browser/content/autocomplete.xml#private-autocomplete-treebody");
-}
-
-.private-autocomplete-richlistbox {
- -moz-binding: url("chrome://browser/content/autocomplete.xml#private-autocomplete-richlistbox");
- -moz-user-focus: ignore;
-}
-
-.private-autocomplete-richlistbox > scrollbox {
- overflow-x: hidden !important;
-}
-
-.private-autocomplete-richlistitem {
- -moz-binding: url("chrome://browser/content/autocomplete.xml#private-autocomplete-richlistitem");
- -moz-box-orient: vertical;
- overflow: -moz-hidden-unscrollable;
-}
-
-.private-autocomplete-treerows {
- -moz-binding: url("chrome://browser/content/autocomplete.xml#private-autocomplete-treerows");
-}
-
-.private-autocomplete-history-dropmarker {
- display: none;
-}
-
-.private-autocomplete-history-dropmarker[enablehistory="true"] {
- display: -moz-box;
- -moz-binding: url("chrome://browser/content/autocomplete.xml#private-history-dropmarker");
-}
-
-.ac-ellipsis-after {
- visibility: hidden;
-}
-
-.ac-url-text[type~="action"],
-.ac-action-text:not([type~="action"]) {
- visibility: collapse;
-}
-
-
-/* ::::: Unified Back-/Forward Button ::::: */
-#back-button > .toolbarbutton-menu-dropmarker,
-#forward-button > .toolbarbutton-menu-dropmarker {
- display: none;
-}
-.unified-nav-current {
- font-weight: bold;
-}
-
-toolbarbutton.bookmark-item {
- max-width: 13em;
-}
-
-%ifdef MENUBAR_CAN_AUTOHIDE
-#toolbar-menubar:not([autohide="true"]) ~ toolbar > #bookmarks-menu-button,
-#toolbar-menubar:not([autohide="true"]) > #bookmarks-menu-button,
-#toolbar-menubar:not([autohide="true"]) ~ toolbar > #history-menu-button,
-#toolbar-menubar:not([autohide="true"]) > #history-menu-button {
- display: none;
-}
-%endif
-
-#editBMPanel_tagsSelector {
- /* override default listbox width from xul.css */
- width: auto;
-}
-
-menupopup[emptyplacesresult="true"] > .hide-if-empty-places-result {
- display: none;
-}
-
-menuitem.spell-suggestion {
- font-weight: bold;
-}
-
-#sidebar-header > .tabs-closebutton {
- -moz-user-focus: normal;
-}
-
-/* apply Fitts' law to the notification bar's close button */
-window[sizemode="maximized"] #content .notification-inner {
- border-right: 0px !important;
-}
-
-/* Hide extension toolbars that neglected to set the proper class */
-window[chromehidden~="location"][chromehidden~="toolbar"] toolbar:not(.chromeclass-menubar),
-window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(#nav-bar):not(#TabsToolbar):not(#print-preview-toolbar):not(.chromeclass-menubar) {
- display: none;
-}
-
-#navigator-toolbox ,
-#status-bar ,
-#mainPopupSet {
- min-width: 1px;
-}
-
-%ifdef MOZ_SERVICES_SYNC
-/* Sync notification UI */
-#sync-notifications {
- -moz-binding: url("chrome://browser/content/sync/notification.xml#notificationbox");
- overflow-y: visible !important;
-}
-
-#sync-notifications notification {
- -moz-binding: url("chrome://browser/content/sync/notification.xml#notification");
-}
-%endif
-
-/* History Swipe Animation */
-
-#historySwipeAnimationContainer {
- overflow: hidden;
-}
-
-#historySwipeAnimationPreviousPage,
-#historySwipeAnimationCurrentPage,
-#historySwipeAnimationNextPage {
- background: none top left no-repeat white;
-}
-
-#historySwipeAnimationPreviousPage {
- background-image: -moz-element(#historySwipeAnimationPreviousPageSnapshot);
-}
-
-#historySwipeAnimationCurrentPage {
- background-image: -moz-element(#historySwipeAnimationCurrentPageSnapshot);
-}
-
-#historySwipeAnimationNextPage {
- background-image: -moz-element(#historySwipeAnimationNextPageSnapshot);
-}
-
-/* Identity UI */
-#identity-popup-content-box.unknownIdentity > #identity-popup-connectedToLabel ,
-#identity-popup-content-box.unknownIdentity > #identity-popup-runByLabel ,
-#identity-popup-content-box.unknownIdentity > #identity-popup-content-host ,
-#identity-popup-content-box.unknownIdentity > #identity-popup-content-owner ,
-#identity-popup-content-box.verifiedIdentity > #identity-popup-connectedToLabel2 ,
-#identity-popup-content-box.verifiedDomain > #identity-popup-connectedToLabel2 {
- display: none;
-}
-
-/* Full Screen UI */
-
-#fullscr-toggler {
- height: 1px;
- background: black;
-}
-
-#full-screen-warning-container {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- z-index: 2147483647 !important;
- pointer-events: none;
-}
-
-#full-screen-warning-container[fade-warning-out] {
- transition-property: opacity !important;
- transition-duration: 500ms !important;
- opacity: 0.0;
-}
-
-#full-screen-warning-message {
- /* We must specify a max-width, otherwise word-wrap:break-word doesn't
- work in descendant <description> and <label> elements. Bug 630864. */
- max-width: 800px;
-}
-
-#full-screen-domain-text {
- word-wrap: break-word;
- /* We must specify a min-width, otherwise word-wrap:break-word doesn't work. Bug 630864. */
- min-width: 1px;
-}
-
-#nav-bar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-icon {
- display: -moz-box;
-}
-
-#nav-bar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-text {
- display: none;
-}
-
-/* ::::: Keyboard UI Panel ::::: */
-.KUI-panel-closebutton {
- -moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image");
-}
-
-:-moz-any(.ctrlTab-preview, .allTabs-preview) > html|img,
-:-moz-any(.ctrlTab-preview, .allTabs-preview) > html|canvas {
- min-width: inherit;
- max-width: inherit;
- min-height: inherit;
- max-height: inherit;
-}
-
-.ctrlTab-favicon-container,
-.allTabs-favicon-container {
- -moz-box-align: start;
-%ifdef XP_MACOSX
- -moz-box-pack: end;
-%else
- -moz-box-pack: start;
-%endif
-}
-
-.ctrlTab-favicon,
-.allTabs-favicon {
- width: 16px;
- height: 16px;
-}
-
-/* ::::: Ctrl-Tab Panel ::::: */
-.ctrlTab-preview {
- -moz-binding: url("chrome://browser/content/browser-tabPreviews.xml#ctrlTab-preview");
-}
-
-/* ::::: All Tabs Panel ::::: */
-.allTabs-preview {
- -moz-binding: url("chrome://browser/content/browser-tabPreviews.xml#allTabs-preview");
-}
-
-#allTabs-tab-close-button {
- -moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image");
- margin: 0;
-}
-
-
-/* notification anchors should only be visible when their associated
- notifications are */
-.notification-anchor-icon {
- -moz-user-focus: normal;
-}
-
-.notification-anchor-icon:not([showing]) {
- display: none;
-}
-
-/* This was added with the identity toolkit, does it have any other purpose? */
-#notification-popup .text-link.custom-link {
- -moz-binding: url("chrome://global/content/bindings/text.xml#text-label");
- text-decoration: none;
-}
-
-#invalid-form-popup > description {
- max-width: 280px;
-}
-
-.popup-anchor {
- /* should occupy space but not be visible */
- opacity: 0;
- pointer-events: none;
- -moz-stack-sizing: ignore;
-}
-
-#addon-progress-notification {
- -moz-binding: url("chrome://browser/content/urlbarBindings.xml#addon-progress-notification");
-}
-
-#click-to-play-plugins-notification {
- -moz-binding: url("chrome://browser/content/urlbarBindings.xml#click-to-play-plugins-notification");
-}
-
-.plugin-popupnotification-centeritem {
- -moz-binding: url("chrome://browser/content/urlbarBindings.xml#plugin-popupnotification-center-item");
-}
-
-/* override hidden="true" for the status bar compatibility shim
- in case it was persisted for the real status bar */
-#status-bar {
- display: -moz-box;
-}
-
-/* Remove the resizer from the statusbar compatibility shim */
-#status-bar[hideresizer] > .statusbar-resizerpanel {
- display: none;
-}
-
-browser[tabmodalPromptShowing] {
- -moz-user-focus: none !important;
-}
-
-/* Status panel */
-
-statuspanel {
- -moz-binding: url("chrome://browser/content/tabbrowser.xml#statuspanel");
- position: fixed;
- margin-top: -3em;
- left: 0;
- max-width: calc(100% - 5px);
- pointer-events: none;
-}
-
-statuspanel:-moz-locale-dir(ltr)[mirror],
-statuspanel:-moz-locale-dir(rtl):not([mirror]) {
- left: auto;
- right: 0;
-}
-
-statuspanel[sizelimit] {
- max-width: 50%;
-}
-
-statuspanel[type=status] {
- min-width: 23em;
-}
-
-@media all and (max-width: 800px) {
- statuspanel[type=status] {
- min-width: 33%;
- }
-}
-
-statuspanel[type=overLink] {
- transition: opacity 120ms ease-out;
- direction: ltr;
-}
-
-statuspanel[inactive] {
- transition: none;
- opacity: 0;
-}
-
-statuspanel[inactive][previoustype=overLink] {
- transition: opacity 200ms ease-out;
-}
-
-.statuspanel-inner {
- height: 3em;
- width: 100%;
- -moz-box-align: end;
-}
-
-/* highlighter */
-%include highlighter.css
-
-/* gcli */
-
-html|*#gcli-tooltip-frame,
-html|*#gcli-output-frame,
-#gcli-output,
-#gcli-tooltip {
- overflow-x: hidden;
-}
-
-.gclitoolbar-input-node,
-.gclitoolbar-complete-node {
- direction: ltr;
-}
-
-#developer-toolbar-toolbox-button[error-count] > .toolbarbutton-icon {
- display: none;
-}
-
-#developer-toolbar-toolbox-button[error-count]:before {
- content: attr(error-count);
- display: -moz-box;
- -moz-box-pack: center;
-}
-
-/* Responsive Mode */
-
-.browserContainer[responsivemode] {
- overflow: auto;
-}
-
-.devtools-responsiveui-toolbar:-moz-locale-dir(rtl) {
- -moz-box-pack: end;
-}
-
-.browserStack[responsivemode] {
- transition-duration: 200ms;
- transition-timing-function: linear;
-}
-
-.browserStack[responsivemode] {
- transition-property: min-width, max-width, min-height, max-height;
-}
-
-.browserStack[responsivemode][notransition] {
- transition: none;
-}
-
-.toolbarbutton-badge[badge]:not([badge=""])::after {
- content: attr(badge);
-}
-
-toolbarbutton[type="badged"] {
- -moz-binding: url("chrome://browser/content/urlbarBindings.xml#toolbarbutton-badged");
-}
-
-/* Strict icon size for PMkit 'ui/button' */
-toolbarbutton[pmkit-button="true"] > .toolbarbutton-badge-stack > .toolbarbutton-icon {
- width: 16px;
- height: 16px;
-}
-
-/* Remove white bar at the bottom of the screen when watching HTML5 video in fullscreen */
-#main-window[inFullscreen] #global-notificationbox,
-#main-window[inFullscreen] #high-priority-global-notificationbox {
- visibility: collapse;
-}
-
-#navigator-toolbox[fullscreenShouldAnimate] {
- transition: 0.7s margin-top ease-out;
- transition-delay: 0.8s;
-}
diff --git a/base/content/browser.js b/base/content/browser.js
deleted file mode 100644
index 7615bc9..0000000
--- a/base/content/browser.js
+++ /dev/null
@@ -1,7440 +0,0 @@
-# -*- 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 Ci = Components.interfaces;
-var Cu = Components.utils;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource:///modules/RecentWindow.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
- "resource://gre/modules/Task.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "CharsetMenu",
- "resource:///modules/CharsetMenu.jsm");
-
-const nsIWebNavigation = Ci.nsIWebNavigation;
-const gToolbarInfoSeparators = ["|", "-"];
-
-var gLastBrowserCharset = null;
-var gPrevCharset = null;
-var gProxyFavIcon = null;
-var gLastValidURLStr = "";
-var gInPrintPreviewMode = false;
-var gContextMenu = null; // nsContextMenu instance
-var gMultiProcessBrowser = false;
-
-#ifndef XP_MACOSX
-var gEditUIVisible = true;
-#endif
-
-[
- ["gBrowser", "content"],
- ["gNavToolbox", "navigator-toolbox"],
- ["gURLBar", "urlbar"],
- ["gNavigatorBundle", "bundle_browser"]
-].forEach(function (elementGlobal) {
- var [name, id] = elementGlobal;
- window.__defineGetter__(name, function () {
- var element = document.getElementById(id);
- if (!element)
- return null;
- delete window[name];
- return window[name] = element;
- });
- window.__defineSetter__(name, function (val) {
- delete window[name];
- return window[name] = val;
- });
-});
-
-// Smart getter for the findbar. If you don't wish to force the creation of
-// the findbar, check gFindBarInitialized first.
-var gFindBarInitialized = false;
-XPCOMUtils.defineLazyGetter(window, "gFindBar", function() {
- let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- let findbar = document.createElementNS(XULNS, "findbar");
- findbar.id = "FindToolbar";
-
- let browserBottomBox = document.getElementById("browser-bottombox");
- browserBottomBox.insertBefore(findbar, browserBottomBox.firstChild);
-
- // Force a style flush to ensure that our binding is attached.
- findbar.clientTop;
- findbar.browser = gBrowser.mCurrentBrowser;
- window.gFindBarInitialized = true;
- return findbar;
-});
-
-XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
- "resource://gre/modules/BrowserUtils.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "gPrefService", function() {
- return Services.prefs;
-});
-
-this.__defineGetter__("AddonManager", function() {
- let tmp = {};
- Cu.import("resource://gre/modules/AddonManager.jsm", tmp);
- return this.AddonManager = tmp.AddonManager;
-});
-this.__defineSetter__("AddonManager", function (val) {
- delete this.AddonManager;
- return this.AddonManager = val;
-});
-
-XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
- "resource://gre/modules/PluralForm.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "AboutHomeUtils",
- "resource:///modules/AboutHomeUtils.jsm");
-
-#ifdef MOZ_SERVICES_SYNC
-XPCOMUtils.defineLazyModuleGetter(this, "Weave",
- "resource://services-sync/main.js");
-#endif
-
-XPCOMUtils.defineLazyGetter(this, "PopupNotifications", function () {
- let tmp = {};
- Cu.import("resource:///modules/PopupNotifications.jsm", tmp);
- try {
- return new tmp.PopupNotifications(gBrowser,
- document.getElementById("notification-popup"),
- document.getElementById("notification-popup-box"));
- } catch (ex) {
- Cu.reportError(ex);
- return null;
- }
-});
-
-XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs",
- "resource://gre/modules/PageThumbs.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "gBrowserNewTabPreloader",
- "resource:///modules/BrowserNewTabPreloader.jsm", "BrowserNewTabPreloader");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
- "resource://gre/modules/PrivateBrowsingUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "FormValidationHandler",
- "resource:///modules/FormValidationHandler.jsm");
-
-var gInitialPages = [
- "about:blank",
- "about:newtab",
- "about:home",
- "about:privatebrowsing",
- "about:sessionrestore",
- "about:logopage"
-];
-
-#include browser-addons.js
-#include browser-feeds.js
-#include browser-fullScreen.js
-#include browser-fullZoom.js
-#include browser-places.js
-#include browser-plugins.js
-#include browser-tabPreviews.js
-#include browser-thumbnails.js
-#include browser-uacompat.js
-
-#ifdef MOZ_WEBRTC
-#include browser-webrtcUI.js
-#endif
-
-#include browser-gestureSupport.js
-
-#ifdef MOZ_SERVICES_SYNC
-#include browser-syncui.js
-#endif
-
-XPCOMUtils.defineLazyGetter(this, "Win7Features", function () {
-#ifdef XP_WIN
- const WINTASKBAR_CONTRACTID = "@mozilla.org/windows-taskbar;1";
- if (WINTASKBAR_CONTRACTID in Cc &&
- Cc[WINTASKBAR_CONTRACTID].getService(Ci.nsIWinTaskbar).available) {
- let AeroPeek = Cu.import("resource:///modules/WindowsPreviewPerTab.jsm", {}).AeroPeek;
- return {
- onOpenWindow: function () {
- AeroPeek.onOpenWindow(window);
- },
- onCloseWindow: function () {
- AeroPeek.onCloseWindow(window);
- }
- };
- }
-#endif
- return null;
-});
-
-XPCOMUtils.defineLazyGetter(this, "PageMenu", function() {
- let tmp = {};
- Cu.import("resource:///modules/PageMenu.jsm", tmp);
- return new tmp.PageMenu();
-});
-
-/**
-* We can avoid adding multiple load event listeners and save some time by adding
-* one listener that calls all real handlers.
-*/
-function pageShowEventHandlers(persisted) {
- charsetLoadListener();
- XULBrowserWindow.asyncUpdateUI();
-
- // The PluginClickToPlay events are not fired when navigating using the
- // BF cache. |persisted| is true when the page is loaded from the
- // BF cache, so this code reshows the notification if necessary.
- if (persisted)
- gPluginHandler.reshowClickToPlayNotification();
-}
-
-function UpdateBackForwardCommands(aWebNavigation) {
- var backBroadcaster = document.getElementById("Browser:Back");
- var forwardBroadcaster = document.getElementById("Browser:Forward");
-
- // Avoid setting attributes on broadcasters if the value hasn't changed!
- // Remember, guys, setting attributes on elements is expensive! They
- // get inherited into anonymous content, broadcast to other widgets, etc.!
- // Don't do it if the value hasn't changed! - dwh
-
- var backDisabled = backBroadcaster.hasAttribute("disabled");
- var forwardDisabled = forwardBroadcaster.hasAttribute("disabled");
- if (backDisabled == aWebNavigation.canGoBack) {
- if (backDisabled)
- backBroadcaster.removeAttribute("disabled");
- else
- backBroadcaster.setAttribute("disabled", true);
- }
-
- if (forwardDisabled == aWebNavigation.canGoForward) {
- if (forwardDisabled)
- forwardBroadcaster.removeAttribute("disabled");
- else
- forwardBroadcaster.setAttribute("disabled", true);
- }
-}
-
-/**
- * Click-and-Hold implementation for the Back and Forward buttons
- * XXXmano: should this live in toolbarbutton.xml?
- */
-function SetClickAndHoldHandlers() {
- var timer;
-
- function openMenu(aButton) {
- cancelHold(aButton);
- aButton.firstChild.hidden = false;
- aButton.open = true;
- }
-
- function mousedownHandler(aEvent) {
- if (aEvent.button != 0 ||
- aEvent.currentTarget.open ||
- aEvent.currentTarget.disabled)
- return;
-
- // Prevent the menupopup from opening immediately
- aEvent.currentTarget.firstChild.hidden = true;
-
- aEvent.currentTarget.addEventListener("mouseout", mouseoutHandler, false);
- aEvent.currentTarget.addEventListener("mouseup", mouseupHandler, false);
- timer = setTimeout(openMenu, 500, aEvent.currentTarget);
- }
-
- function mouseoutHandler(aEvent) {
- let buttonRect = aEvent.currentTarget.getBoundingClientRect();
- if (aEvent.clientX >= buttonRect.left &&
- aEvent.clientX <= buttonRect.right &&
- aEvent.clientY >= buttonRect.bottom)
- openMenu(aEvent.currentTarget);
- else
- cancelHold(aEvent.currentTarget);
- }
-
- function mouseupHandler(aEvent) {
- cancelHold(aEvent.currentTarget);
- }
-
- function cancelHold(aButton) {
- clearTimeout(timer);
- aButton.removeEventListener("mouseout", mouseoutHandler, false);
- aButton.removeEventListener("mouseup", mouseupHandler, false);
- }
-
- function clickHandler(aEvent) {
- if (aEvent.button == 0 &&
- aEvent.target == aEvent.currentTarget &&
- !aEvent.currentTarget.open &&
- !aEvent.currentTarget.disabled) {
- let cmdEvent = document.createEvent("xulcommandevent");
- cmdEvent.initCommandEvent("command", true, true, window, 0,
- aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey,
- aEvent.metaKey, null);
- aEvent.currentTarget.dispatchEvent(cmdEvent);
- }
- }
-
- function _addClickAndHoldListenersOnElement(aElm) {
- aElm.addEventListener("mousedown", mousedownHandler, true);
- aElm.addEventListener("click", clickHandler, true);
- }
-
- // Bug 414797: Clone unified-back-forward-button's context menu into both the
- // back and the forward buttons.
- var unifiedButton = document.getElementById("unified-back-forward-button");
- if (unifiedButton && !unifiedButton._clickHandlersAttached) {
- unifiedButton._clickHandlersAttached = true;
-
- let popup = document.getElementById("backForwardMenu").cloneNode(true);
- popup.removeAttribute("id");
- // Prevent the context attribute on unified-back-forward-button from being
- // inherited.
- popup.setAttribute("context", "");
-
- let backButton = document.getElementById("back-button");
- backButton.setAttribute("type", "menu");
- backButton.appendChild(popup);
- _addClickAndHoldListenersOnElement(backButton);
-
- let forwardButton = document.getElementById("forward-button");
- popup = popup.cloneNode(true);
- forwardButton.setAttribute("type", "menu");
- forwardButton.appendChild(popup);
- _addClickAndHoldListenersOnElement(forwardButton);
- }
-}
-
-const gSessionHistoryObserver = {
- observe: function(subject, topic, data)
- {
- if (topic != "browser:purge-session-history")
- return;
-
- var backCommand = document.getElementById("Browser:Back");
- backCommand.setAttribute("disabled", "true");
- var fwdCommand = document.getElementById("Browser:Forward");
- fwdCommand.setAttribute("disabled", "true");
-
- // Hide session restore button on about:home
- window.messageManager.broadcastAsyncMessage("Browser:HideSessionRestoreButton");
-
- if (gURLBar) {
- // Clear undo history of the URL bar
- gURLBar.editor.transactionManager.clear()
- }
- }
-};
-
-var gFindBarSettings = {
- messageName: "Findbar:Keypress",
- prefName: "accessibility.typeaheadfind",
- findAsYouType: null,
-
- init: function() {
- window.messageManager.addMessageListener(this.messageName, this);
-
- gPrefService.addObserver(this.prefName, this, false);
- this.writeFindAsYouType();
- },
-
- uninit: function() {
- window.messageManager.removeMessageListener(this.messageName, this);
-
- try {
- gPrefService.removeObserver(this.prefName, this);
- } catch (ex) {
- Cu.reportError(ex);
- }
- },
-
- observe: function(aSubject, aTopic, aData) {
- if (aTopic != "nsPref:changed") {
- return;
- }
-
- this.writeFindAsYouType();
- },
-
- writeFindAsYouType: function() {
- this.findAsYouType = gPrefService.getBoolPref(this.prefName);
- },
-
- receiveMessage: function(aMessage) {
- switch (aMessage.name) {
- case this.messageName:
- // If the find bar for chrome window's context is not yet alive,
- // only initialize it if there's a possibility FindAsYouType
- // will be used.
- // There's no point in doing it for most random keypresses.
- if (!gFindBarInitialized && aMessage.data.shouldFastFind) {
- let shouldFastFind = this.findAsYouType;
- if (!shouldFastFind) {
- // Please keep in sync with toolkit/content/widgets/findbar.xml
- const FAYT_LINKS_KEY = "'";
- const FAYT_TEXT_KEY = "/";
- let charCode = aMessage.data.fakeEvent.charCode;
- let key = charCode ? String.fromCharCode(charCode) : null;
- shouldFastFind = key == FAYT_LINKS_KEY || key == FAYT_TEXT_KEY;
- }
- if (shouldFastFind) {
- // Make sure we return the result.
- return gFindBar.receiveMessage(aMessage);
- }
- }
- break;
- }
- }
-};
-
-var gURLBarSettings = {
- prefSuggest: "browser.urlbar.suggest.",
- /*
- For searching in the source code:
- browser.urlbar.suggest.bookmark
- browser.urlbar.suggest.history
- browser.urlbar.suggest.openpage
- */
- prefSuggests: [
- "bookmark",
- "history",
- "openpage"
- ],
- prefKeyword: "keyword.enabled",
-
- observe: function(aSubject, aTopic, aData) {
- if (aTopic != "nsPref:changed")
- return;
-
- this.writePlaceholder();
- },
-
- writePlaceholder: function() {
- if (!gURLBar) {
- return;
- }
-
- let attribute = "placeholder";
- let prefs = this.prefSuggests.map(pref => {
- return this.prefSuggest + pref;
- });
- prefs.push(this.prefKeyword);
- let placeholderDefault = prefs.some(pref => {
- return gPrefService.getBoolPref(pref);
- });
-
- if (placeholderDefault) {
- gURLBar.setAttribute(
- attribute, gNavigatorBundle.getString("urlbar.placeholder"));
- } else {
- gURLBar.setAttribute(
- attribute, gNavigatorBundle.getString("urlbar.placeholderURLOnly"));
- }
- }
-};
-
-/**
- * Given a starting docshell and a URI to look up, find the docshell the URI
- * is loaded in.
- * @param aDocument
- * A document to find instead of using just a URI - this is more specific.
- * @param aDocShell
- * The doc shell to start at
- * @param aSoughtURI
- * The URI that we're looking for
- * @returns The doc shell that the sought URI is loaded in. Can be in
- * subframes.
- */
-function findChildShell(aDocument, aDocShell, aSoughtURI) {
- aDocShell.QueryInterface(Components.interfaces.nsIWebNavigation);
- aDocShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
- var doc = aDocShell.getInterface(Components.interfaces.nsIDOMDocument);
- if ((aDocument && doc == aDocument) ||
- (aSoughtURI && aSoughtURI.spec == aDocShell.currentURI.spec))
- return aDocShell;
-
- var node = aDocShell.QueryInterface(Components.interfaces.nsIDocShellTreeItem);
- for (var i = 0; i < node.childCount; ++i) {
- var docShell = node.getChildAt(i);
- docShell = findChildShell(aDocument, docShell, aSoughtURI);
- if (docShell)
- return docShell;
- }
- return null;
-}
-
-var gPopupBlockerObserver = {
- _reportButton: null,
-
- onReportButtonClick: function (aEvent)
- {
- if (aEvent.button != 0 || aEvent.target != this._reportButton)
- return;
-
- document.getElementById("blockedPopupOptions")
- .openPopup(this._reportButton, "after_end", 0, 2, false, false, aEvent);
- },
-
- handleEvent: function (aEvent)
- {
- if (aEvent.originalTarget != gBrowser.selectedBrowser)
- return;
-
- if (!this._reportButton && gURLBar)
- this._reportButton = document.getElementById("page-report-button");
-
- if (!gBrowser.selectedBrowser.blockedPopups ||
- !gBrowser.selectedBrowser.blockedPopups.length) {
- // Hide the icon in the location bar (if the location bar exists)
- if (gURLBar)
- this._reportButton.hidden = true;
- return;
- }
-
- if (gURLBar)
- this._reportButton.hidden = false;
-
- // Only show the notification again if we've not already shown it. Since
- // notifications are per-browser, we don't need to worry about re-adding
- // it.
- if (!gBrowser.selectedBrowser.blockedPopups.reported) {
- if (gPrefService.getBoolPref("privacy.popups.showBrowserMessage")) {
- var brandBundle = document.getElementById("bundle_brand");
- var brandShortName = brandBundle.getString("brandShortName");
- var popupCount = gBrowser.selectedBrowser.blockedPopups.length;
- var popupButtonText = gNavigatorBundle.getString("popupWarningButton");
- var popupButtonAccesskey = gNavigatorBundle.getString("popupWarningButton.accesskey");
- var messageBase = gNavigatorBundle.getString("popupWarning.message");
- var message = PluralForm.get(popupCount, messageBase)
- .replace("#1", brandShortName)
- .replace("#2", popupCount);
-
- var notificationBox = gBrowser.getNotificationBox();
- var notification = notificationBox.getNotificationWithValue("popup-blocked");
- if (notification) {
- notification.label = message;
- }
- else {
- var buttons = [{
- label: popupButtonText,
- accessKey: popupButtonAccesskey,
- popup: "blockedPopupOptions",
- callback: null
- }];
-
- const priority = notificationBox.PRIORITY_WARNING_MEDIUM;
- notificationBox.appendNotification(message, "popup-blocked",
- "chrome://browser/skin/Info.png",
- priority, buttons);
- }
- }
-
- // Record the fact that we've reported this blocked popup, so we don't
- // show it again.
- gBrowser.selectedBrowser.blockedPopups.reported = true;
- }
- },
-
- toggleAllowPopupsForSite: function (aEvent)
- {
- var pm = Services.perms;
- var shouldBlock = aEvent.target.getAttribute("block") == "true";
- var perm = shouldBlock ? pm.DENY_ACTION : pm.ALLOW_ACTION;
- pm.add(gBrowser.currentURI, "popup", perm);
-
- gBrowser.getNotificationBox().removeCurrentNotification();
- },
-
- fillPopupList: function (aEvent)
- {
- // XXXben - rather than using |currentURI| here, which breaks down on multi-framed sites
- // we should really walk the blockedPopups and create a list of "allow for <host>"
- // menuitems for the common subset of hosts present in the report, this will
- // make us frame-safe.
- //
- // XXXjst - Note that when this is fixed to work with multi-framed sites,
- // also back out the fix for bug 343772 where
- // nsGlobalWindow::CheckOpenAllow() was changed to also
- // check if the top window's location is whitelisted.
- let browser = gBrowser.selectedBrowser;
- var uri = browser.currentURI;
- var blockedPopupAllowSite = document.getElementById("blockedPopupAllowSite");
- try {
- blockedPopupAllowSite.removeAttribute("hidden");
-
- var pm = Services.perms;
- if (pm.testPermission(uri, "popup") == pm.ALLOW_ACTION) {
- // Offer an item to block popups for this site, if a whitelist entry exists
- // already for it.
- let blockString = gNavigatorBundle.getFormattedString("popupBlock", [uri.host || uri.spec]);
- blockedPopupAllowSite.setAttribute("label", blockString);
- blockedPopupAllowSite.setAttribute("block", "true");
- }
- else {
- // Offer an item to allow popups for this site
- let allowString = gNavigatorBundle.getFormattedString("popupAllow", [uri.host || uri.spec]);
- blockedPopupAllowSite.setAttribute("label", allowString);
- blockedPopupAllowSite.removeAttribute("block");
- }
- }
- catch (e) {
- blockedPopupAllowSite.setAttribute("hidden", "true");
- }
-
- if (PrivateBrowsingUtils.isWindowPrivate(window))
- blockedPopupAllowSite.setAttribute("disabled", "true");
- else
- blockedPopupAllowSite.removeAttribute("disabled");
-
- let blockedPopupDontShowMessage = document.getElementById("blockedPopupDontShowMessage");
- let showMessage = gPrefService.getBoolPref("privacy.popups.showBrowserMessage");
- blockedPopupDontShowMessage.setAttribute("checked", !showMessage);
- if (aEvent.target.anchorNode.id == "page-report-button") {
- aEvent.target.anchorNode.setAttribute("open", "true");
- blockedPopupDontShowMessage.setAttribute("label", gNavigatorBundle.getString("popupWarningDontShowFromLocationbar"));
- } else {
- blockedPopupDontShowMessage.setAttribute("label", gNavigatorBundle.getString("popupWarningDontShowFromMessage"));
- }
-
- let blockedPopupsSeparator =
- document.getElementById("blockedPopupsSeparator");
- blockedPopupsSeparator.setAttribute("hidden", true);
-
- gBrowser.selectedBrowser.retrieveListOfBlockedPopups().then(blockedPopups => {
- let foundUsablePopupURI = false;
- if (blockedPopups) {
- for (let i = 0; i < blockedPopups.length; i++) {
- let blockedPopup = blockedPopups[i];
-
- // popupWindowURI will be null if the file picker popup is blocked.
- // xxxdz this should make the option say "Show file picker" and do it (Bug 590306)
- if (!blockedPopup.popupWindowURIspec)
- continue;
-
- var popupURIspec = blockedPopup.popupWindowURIspec;
-
- // Sometimes the popup URI that we get back from the blockedPopup
- // isn't useful (for instance, netscape.com's popup URI ends up
- // being "http://www.netscape.com", which isn't really the URI of
- // the popup they're trying to show). This isn't going to be
- // useful to the user, so we won't create a menu item for it.
- if (popupURIspec == "" || popupURIspec == "about:blank" ||
- popupURIspec == "<self>" ||
- popupURIspec == uri.spec)
- continue;
-
- // Because of the short-circuit above, we may end up in a situation
- // in which we don't have any usable popup addresses to show in
- // the menu, and therefore we shouldn't show the separator. However,
- // since we got past the short-circuit, we must've found at least
- // one usable popup URI and thus we'll turn on the separator later.
- foundUsablePopupURI = true;
-
- var menuitem = document.createElement("menuitem");
- var label = gNavigatorBundle.getFormattedString("popupShowPopupPrefix",
- [popupURIspec]);
- menuitem.setAttribute("label", label);
- menuitem.setAttribute("oncommand", "gPopupBlockerObserver.showBlockedPopup(event);");
- menuitem.setAttribute("popupReportIndex", i);
- menuitem.popupReportBrowser = browser;
- aEvent.target.appendChild(menuitem);
- }
- }
-
- // Show the separator if we added any
- // showable popup addresses to the menu.
- if (foundUsablePopupURI)
- blockedPopupsSeparator.removeAttribute("hidden");
- }, null);
- },
-
- onPopupHiding: function (aEvent) {
- if (aEvent.target.anchorNode.id == "page-report-button")
- aEvent.target.anchorNode.removeAttribute("open");
-
- let item = aEvent.target.lastChild;
- while (item && item.getAttribute("observes") != "blockedPopupsSeparator") {
- let next = item.previousSibling;
- item.parentNode.removeChild(item);
- item = next;
- }
- },
-
- showBlockedPopup: function (aEvent)
- {
- var target = aEvent.target;
- var popupReportIndex = target.getAttribute("popupReportIndex");
- let browser = target.popupReportBrowser;
- browser.unblockPopup(popupReportIndex);
- },
-
- editPopupSettings: function ()
- {
- var host = "";
- try {
- host = gBrowser.currentURI.host;
- }
- catch (e) { }
-
- var bundlePreferences = document.getElementById("bundle_preferences");
- var params = { blockVisible : false,
- sessionVisible : false,
- allowVisible : true,
- prefilledHost : host,
- permissionType : "popup",
- windowTitle : bundlePreferences.getString("popuppermissionstitle"),
- introText : bundlePreferences.getString("popuppermissionstext") };
- var existingWindow = Services.wm.getMostRecentWindow("Browser:Permissions");
- if (existingWindow) {
- existingWindow.initWithParams(params);
- existingWindow.focus();
- }
- else
- window.openDialog("chrome://browser/content/preferences/permissions.xul",
- "_blank", "resizable,dialog=no,centerscreen", params);
- },
-
- dontShowMessage: function ()
- {
- var showMessage = gPrefService.getBoolPref("privacy.popups.showBrowserMessage");
- gPrefService.setBoolPref("privacy.popups.showBrowserMessage", !showMessage);
- gBrowser.getNotificationBox().removeCurrentNotification();
- }
-};
-
-const gXSSObserver = {
-
- observe: function (aSubject, aTopic, aData)
- {
-
- // Don't do anything if the notification is disabled.
- if (!gPrefService.getBoolPref("security.xssfilter.displayWarning"))
- return;
-
- // Parse incoming XSS array
- aSubject.QueryInterface(Ci.nsIArray);
- var policy = aSubject.queryElementAt(0, Ci.nsISupportsString).data;
- var content = aSubject.queryElementAt(1, Ci.nsISupportsString).data;
- var domain = aSubject.queryElementAt(2, Ci.nsISupportsString).data;
- var url = aSubject.queryElementAt(3, Ci.nsISupportsCString).data;
- var blockMode = aSubject.queryElementAt(4, Ci.nsISupportsPRBool).data;
-
- // If it is a block mode event, do not display the infobar
- if (blockMode)
- return;
-
- var nb = gBrowser.getNotificationBox();
- const priority = nb.PRIORITY_WARNING_MEDIUM;
-
- var buttons = [{
- label: 'View Unsafe Content',
- accessKey: 'V',
- popup: null,
- callback: function () {
- alert(content);
- }
- }];
-
- if (domain !== "")
- buttons.push({
- label: 'Add Domain Exception',
- accessKey: 'A',
- popup: null,
- callback: function () {
- let whitelist = gPrefService.getCharPref("security.xssfilter.whitelist");
- if (whitelist != "") {
- whitelist = whitelist + "," + domain;
- } else {
- whitelist = domain;
- }
- // Write the updated whitelist. Since this is observed by the XSS filter,
- // it will automatically sync to the back-end and update immediately.
- gPrefService.setCharPref("security.xssfilter.whitelist", whitelist);
- // After setting this, we automatically reload the page.
- BrowserReloadSkipCache();
- }
- });
-
- nb.appendNotification("The XSS Filter has detected a potential XSS attack. Type: " +
- policy, 'popup-blocked', 'chrome://browser/skin/Info.png',
- priority, buttons);
- }
-};
-
-var gBrowserInit = {
- delayedStartupFinished: false,
-
- onLoad: function() {
- gMultiProcessBrowser = gPrefService.getBoolPref("browser.tabs.remote");
-
- var mustLoadSidebar = false;
-
- Cc["@mozilla.org/eventlistenerservice;1"]
- .getService(Ci.nsIEventListenerService)
- .addSystemEventListener(gBrowser, "click", contentAreaClick, true);
-
- gBrowser.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver, false);
-
- // Note that the XBL binding is untrusted
- gBrowser.addEventListener("PluginBindingAttached", gPluginHandler, true, true);
- gBrowser.addEventListener("PluginCrashed", gPluginHandler, true);
- gBrowser.addEventListener("PluginOutdated", gPluginHandler, true);
- gBrowser.addEventListener("PluginInstantiated", gPluginHandler, true);
- gBrowser.addEventListener("PluginRemoved", gPluginHandler, true);
-
- Services.obs.addObserver(gPluginHandler.pluginCrashed, "plugin-crashed", false);
-
- window.addEventListener("AppCommand", HandleAppCommandEvent, true);
-
- // These routines add message listeners. They must run before
- // loading the frame script to ensure that we don't miss any
- // message sent between when the frame script is loaded and when
- // the listener is registered.
-#ifdef MOZ_DEVTOOLS
- DevToolsTheme.init();
-#endif
- gFindBarSettings.init();
-
- messageManager.loadFrameScript("chrome://browser/content/content.js", true);
- messageManager.loadFrameScript("chrome://browser/content/content-sessionStore.js", true);
-
- // initialize observers and listeners
- // and give C++ access to gBrowser
- XULBrowserWindow.init();
- window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIXULWindow)
- .XULBrowserWindow = window.XULBrowserWindow;
- window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow =
- new nsBrowserAccess();
-
- // set default character set if provided
- // window.arguments[1]: character set (string)
- if ("arguments" in window && window.arguments.length > 1 && window.arguments[1]) {
- if (window.arguments[1].startsWith("charset=")) {
- var arrayArgComponents = window.arguments[1].split("=");
- if (arrayArgComponents) {
- //we should "inherit" the charset menu setting in a new window
- //TFE FIXME: this is now a wrappednative and can't be set this way.
- //getMarkupDocumentViewer().defaultCharacterSet = arrayArgComponents[1];
- }
- }
- }
-
- // Manually hook up session and global history for the first browser
- // so that we don't have to load global history before bringing up a
- // window.
- // Wire up session and global history before any possible
- // progress notifications for back/forward button updating
- gBrowser.webNavigation.sessionHistory = Cc["@mozilla.org/browser/shistory;1"].
- createInstance(Ci.nsISHistory);
- Services.obs.addObserver(gBrowser.browsers[0], "browser:purge-session-history", false);
-
- // remove the disablehistory attribute so the browser cleans up, as
- // though it had done this work itself
- gBrowser.browsers[0].removeAttribute("disablehistory");
-
- // enable global history
- try {
- if (!gMultiProcessBrowser)
- gBrowser.docShell.useGlobalHistory = true;
- } catch(ex) {
- Cu.reportError("Places database may be locked: " + ex);
- }
-
- // hook up UI through progress listener
- gBrowser.addProgressListener(window.XULBrowserWindow);
- gBrowser.addTabsProgressListener(window.TabsProgressListener);
-
- // setup our common DOMLinkAdded listener
- gBrowser.addEventListener("DOMLinkAdded", DOMLinkHandler, false);
-
- // setup our MozApplicationManifest listener
- gBrowser.addEventListener("MozApplicationManifest",
- OfflineApps, false);
-
- // setup simple gestures support
- gGestureSupport.init(true);
-
- // setup history swipe animation
- gHistorySwipeAnimation.init();
-
- if (window.opener && !window.opener.closed) {
- let openerSidebarBox = window.opener.document.getElementById("sidebar-box");
- // If the opener had a sidebar, open the same sidebar in our window.
- // The opener can be the hidden window too, if we're coming from the state
- // where no windows are open, and the hidden window has no sidebar box.
- if (openerSidebarBox && !openerSidebarBox.hidden) {
- let sidebarCmd = openerSidebarBox.getAttribute("sidebarcommand");
- let sidebarCmdElem = document.getElementById(sidebarCmd);
-
- // dynamically generated sidebars will fail this check.
- if (sidebarCmdElem) {
- let sidebarBox = document.getElementById("sidebar-box");
- let sidebarTitle = document.getElementById("sidebar-title");
-
- sidebarTitle.setAttribute(
- "value", window.opener.document.getElementById("sidebar-title").getAttribute("value"));
- sidebarBox.setAttribute("width", openerSidebarBox.boxObject.width);
-
- sidebarBox.setAttribute("sidebarcommand", sidebarCmd);
- // Note: we're setting 'src' on sidebarBox, which is a <vbox>, not on
- // the <browser id="sidebar">. This lets us delay the actual load until
- // delayedStartup().
- sidebarBox.setAttribute(
- "src", window.opener.document.getElementById("sidebar").getAttribute("src"));
- mustLoadSidebar = true;
-
- sidebarBox.hidden = false;
- document.getElementById("sidebar-splitter").hidden = false;
- sidebarCmdElem.setAttribute("checked", "true");
- }
- }
- }
- else {
- let box = document.getElementById("sidebar-box");
- if (box.hasAttribute("sidebarcommand")) {
- let commandID = box.getAttribute("sidebarcommand");
- if (commandID) {
- let command = document.getElementById(commandID);
- if (command) {
- mustLoadSidebar = true;
- box.hidden = false;
- document.getElementById("sidebar-splitter").hidden = false;
- command.setAttribute("checked", "true");
- }
- else {
- // Remove the |sidebarcommand| attribute, because the element it
- // refers to no longer exists, so we should assume this sidebar
- // panel has been uninstalled. (249883)
- box.removeAttribute("sidebarcommand");
- }
- }
- }
- }
-
- // Certain kinds of automigration rely on this notification to complete their
- // tasks BEFORE the browser window is shown.
- Services.obs.notifyObservers(null, "browser-window-before-show", "");
-
- // Set a sane starting width/height for all resolutions on new profiles.
- if (!document.documentElement.hasAttribute("width")) {
- let defaultWidth;
- let defaultHeight;
-
- // Very small: maximize the window
- // Portrait : use about full width and 3/4 height, to view entire pages
- // at once (without being obnoxiously tall)
- // Widescreen: use about half width, to suggest side-by-side page view
- // Otherwise : use 3/4 height and width
- if (screen.availHeight <= 600) {
- document.documentElement.setAttribute("sizemode", "maximized");
- defaultWidth = 610;
- defaultHeight = 450;
- }
- else {
- if (screen.availWidth <= screen.availHeight) {
- defaultWidth = screen.availWidth * .9;
- defaultHeight = screen.availHeight * .75;
- }
- else if (screen.availWidth >= 2048) {
- defaultWidth = (screen.availWidth / 2) - 20;
- defaultHeight = screen.availHeight - 10;
- }
- else {
- defaultWidth = screen.availWidth * .75;
- defaultHeight = screen.availHeight * .75;
- }
-
-#ifdef MOZ_WIDGET_GTK2
- // On X, we're not currently able to account for the size of the window
- // border. Use 28px as a guess (titlebar + bottom window border)
- defaultHeight -= 28;
-#endif
- }
- document.documentElement.setAttribute("width", defaultWidth);
- document.documentElement.setAttribute("height", defaultHeight);
- }
-
- if (!gShowPageResizers)
- document.getElementById("status-bar").setAttribute("hideresizer", "true");
-
- if (!window.toolbar.visible) {
- // adjust browser UI for popups
- if (gURLBar) {
- gURLBar.setAttribute("readonly", "true");
- gURLBar.setAttribute("enablehistory", "false");
- }
- goSetCommandEnabled("cmd_newNavigatorTab", false);
- }
-
-#ifdef MENUBAR_CAN_AUTOHIDE
- updateAppButtonDisplay();
-#endif
-
- // Misc. inits.
- CombinedStopReload.init();
- allTabs.readPref();
- TabsOnTop.init();
- AudioIndicator.init();
- gPrivateBrowsingUI.init();
- TabsInTitlebar.init();
- retrieveToolbarIconsizesFromTheme();
- ToolbarIconColor.init();
- UserAgentCompatibility.init();
-
-#ifdef XP_WIN
- if (window.matchMedia("(-moz-os-version: windows-win8)").matches &&
- window.matchMedia("(-moz-windows-default-theme)").matches) {
- let windows8WindowFrameColor = Cu.import("resource:///modules/Windows8WindowFrameColor.jsm", {}).Windows8WindowFrameColor;
-
- var windowFrameColor;
- windowFrameColor = windows8WindowFrameColor.get_win8();
-
- // Formula from Microsoft's UWP guideline.
- let backgroundLuminance = (windowFrameColor[0] * 2 +
- windowFrameColor[1] * 5 +
- windowFrameColor[2]) / 8;
- if (backgroundLuminance <= 128) {
- document.documentElement.setAttribute("darkwindowframe", "true");
- }
- }
-#endif
-
- // Wait until chrome is painted before executing code not critical to making the window visible
- this._boundDelayedStartup = this._delayedStartup.bind(this, mustLoadSidebar);
- window.addEventListener("MozAfterPaint", this._boundDelayedStartup);
-
- this._loadHandled = true;
- },
-
- _cancelDelayedStartup: function () {
- window.removeEventListener("MozAfterPaint", this._boundDelayedStartup);
- this._boundDelayedStartup = null;
- },
-
- _delayedStartup: function(mustLoadSidebar) {
- let tmp = {};
-
- this._cancelDelayedStartup();
-
- let uriToLoad = this._getUriToLoad();
- var isLoadingBlank = isBlankPageURL(uriToLoad);
-
- // This pageshow listener needs to be registered before we may call
- // swapBrowsersAndCloseOther() to receive pageshow events fired by that.
- gBrowser.addEventListener("pageshow", function(event) {
- // Filter out events that are not about the document load we are interested in
- if (content && event.target == content.document)
- setTimeout(pageShowEventHandlers, 0, event.persisted);
- }, true);
-
- if (uriToLoad && uriToLoad != "about:blank") {
- if (uriToLoad instanceof Ci.nsISupportsArray) {
- let count = uriToLoad.Count();
- let specs = [];
- for (let i = 0; i < count; i++) {
- let urisstring = uriToLoad.GetElementAt(i).QueryInterface(Ci.nsISupportsString);
- specs.push(urisstring.data);
- }
-
- // This function throws for certain malformed URIs, so use exception handling
- // so that we don't disrupt startup
- try {
- gBrowser.loadTabs(specs, false, true);
- } catch (e) {}
- }
- else if (uriToLoad instanceof XULElement) {
- // swap the given tab with the default about:blank tab and then close
- // the original tab in the other window.
-
- // Stop the about:blank load
- gBrowser.stop();
- // make sure it has a docshell
- gBrowser.docShell;
-
- gBrowser.swapBrowsersAndCloseOther(gBrowser.selectedTab, uriToLoad);
- }
- // window.arguments[2]: referrer (nsIURI | string)
- // [3]: postData (nsIInputStream)
- // [4]: allowThirdPartyFixup (bool)
- // [5]: referrerPolicy (int)
- // [6]: originPrincipal (nsIPrincipal)
- // [7]: triggeringPrincipal (nsIPrincipal)
- else if (window.arguments.length >= 3) {
- let referrerURI = window.arguments[2];
- if (typeof(referrerURI) == "string") {
- try {
- referrerURI = makeURI(referrerURI);
- } catch (e) {
- referrerURI = null;
- }
- }
- let referrerPolicy = (window.arguments[5] != undefined ?
- window.arguments[5] : Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
- loadURI(uriToLoad, referrerURI, window.arguments[3] || null,
- window.arguments[4] || false, referrerPolicy,
- // pass the origin principal (if any) and force its use to create
- // an initial about:blank viewer if present:
- window.arguments[6], !!window.arguments[6], window.arguments[7]);
- window.focus();
- }
- // Note: loadOneOrMoreURIs *must not* be called if window.arguments.length >= 3.
- // Such callers expect that window.arguments[0] is handled as a single URI.
- else
- loadOneOrMoreURIs(uriToLoad);
- }
-
- Services.obs.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
- Services.obs.addObserver(gXPInstallObserver, "addon-install-disabled", false);
- Services.obs.addObserver(gXPInstallObserver, "addon-install-started", false);
- Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false);
- Services.obs.addObserver(gXPInstallObserver, "addon-install-origin-blocked", false);
- Services.obs.addObserver(gXPInstallObserver, "addon-install-failed", false);
- Services.obs.addObserver(gXPInstallObserver, "addon-install-complete", false);
- Services.obs.addObserver(gXSSObserver, "xss-on-violate-policy", false);
-
- gPrefService.addObserver(gURLBarSettings.prefSuggest, gURLBarSettings, false);
- gPrefService.addObserver(gURLBarSettings.prefKeyword, gURLBarSettings, false);
-
- gURLBarSettings.writePlaceholder();
-
- BrowserOffline.init();
- OfflineApps.init();
- IndexedDBPromptHelper.init();
- AddonManager.addAddonListener(AddonsMgrListener);
-#ifdef MOZ_WEBRTC
- WebrtcIndicator.init();
-#endif
-
- // Ensure login manager is up and running.
- Services.logins;
-
- if (mustLoadSidebar) {
- let sidebar = document.getElementById("sidebar");
- let sidebarBox = document.getElementById("sidebar-box");
- sidebar.setAttribute("src", sidebarBox.getAttribute("src"));
- }
-
- UpdateUrlbarSearchSplitterState();
-
- if (!isLoadingBlank || !focusAndSelectUrlBar())
- gBrowser.selectedBrowser.focus();
-
- gNavToolbox.customizeDone = BrowserToolboxCustomizeDone;
- gNavToolbox.customizeChange = BrowserToolboxCustomizeChange;
-
- // Set up Sanitize Item
- this._initializeSanitizer();
-
- // Enable/Disable auto-hide tabbar
- gBrowser.tabContainer.updateVisibility();
-
- gPrefService.addObserver(gHomeButton.prefDomain, gHomeButton, false);
-
- var homeButton = document.getElementById("home-button");
- gHomeButton.updateTooltip(homeButton);
- gHomeButton.updatePersonalToolbarStyle(homeButton);
-
- // BiDi UI
- gBidiUI = isBidiEnabled();
- if (gBidiUI) {
- document.getElementById("documentDirection-separator").hidden = false;
- document.getElementById("documentDirection-swap").hidden = false;
- document.getElementById("textfieldDirection-separator").hidden = false;
- document.getElementById("textfieldDirection-swap").hidden = false;
- }
-
- // Setup click-and-hold gestures access to the session history
- // menus if global click-and-hold isn't turned on
- if (!Services.prefs.getBoolPref("ui.click_hold_context_menus", false))
- SetClickAndHoldHandlers();
-
- // Initialize the full zoom setting.
- // We do this before the session restore service gets initialized so we can
- // apply full zoom settings to tabs restored by the session restore service.
- FullZoom.init();
-
- // Bug 666804 - NetworkPrioritizer support for e10s
- if (!gMultiProcessBrowser) {
- let NP = {};
- Cu.import("resource:///modules/NetworkPrioritizer.jsm", NP);
- NP.trackBrowserWindow(window);
- }
-
- // initialize the session-restore service (in case it's not already running)
- let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
- let ssPromise = ss.init(window);
-
- PlacesToolbarHelper.init();
-
- ctrlTab.readPref();
- gPrefService.addObserver(ctrlTab.prefName, ctrlTab, false);
- gPrefService.addObserver(allTabs.prefName, allTabs, false);
-
- // Initialize the download manager some time after the app starts so that
- // auto-resume downloads begin (such as after crashing or quitting with
- // active downloads) and speeds up the first-load of the download manager UI.
- // If the user manually opens the download manager before the timeout, the
- // downloads will start right away, and getting the service again won't hurt.
- setTimeout(function() {
- try {
- Cu.import("resource:///modules/DownloadsCommon.jsm", {})
- .DownloadsCommon.initializeAllDataLinks();
- Cu.import("resource:///modules/DownloadsTaskbar.jsm", {})
- .DownloadsTaskbar.registerIndicator(window);
- } catch(ex) {
- Cu.reportError(ex);
- }
- }, 10000);
-
- // Load the Login Manager data from disk off the main thread, some time
- // after startup. If the data is required before the timeout, for example
- // because a restored page contains a password field, it will be loaded on
- // the main thread, and this initialization request will be ignored.
- setTimeout(function() {
- try {
- Services.logins;
- } catch (ex) {
- Cu.reportError(ex);
- }
- }, 3000);
-
- // The object handling the downloads indicator is also initialized here in the
- // delayed startup function, but the actual indicator element is not loaded
- // unless there are downloads to be displayed.
- DownloadsButton.initializeIndicator();
-
-#ifndef XP_MACOSX
- updateEditUIVisibility();
- let placesContext = document.getElementById("placesContext");
- placesContext.addEventListener("popupshowing", updateEditUIVisibility, false);
- placesContext.addEventListener("popuphiding", updateEditUIVisibility, false);
-#endif
-
-#ifdef MOZ_PERSONAS
- gBrowser.mPanelContainer.addEventListener("InstallBrowserTheme", LightWeightThemeWebInstaller, false, true);
- gBrowser.mPanelContainer.addEventListener("PreviewBrowserTheme", LightWeightThemeWebInstaller, false, true);
- gBrowser.mPanelContainer.addEventListener("ResetBrowserThemePreview", LightWeightThemeWebInstaller, false, true);
-#endif
-
- // Bug 666808 - AeroPeek support for e10s
- if (!gMultiProcessBrowser) {
- if (Win7Features)
- Win7Features.onOpenWindow();
- }
-
- // called when we go into full screen, even if initiated by a web page script
- window.addEventListener("fullscreen", onFullScreen, true);
-
- // Called when we enter DOM full-screen mode. Note we can already be in browser
- // full-screen mode when we enter DOM full-screen mode.
- window.addEventListener("MozDOMFullscreen:NewOrigin", onMozEnteredDomFullscreen, true);
-
- if (window.fullScreen)
- onFullScreen();
- if (document.mozFullScreen)
- onMozEnteredDomFullscreen();
-
-#ifdef MOZ_SERVICES_SYNC
- // initialize the sync UI
- gSyncUI.init();
-#endif
-
- gBrowserThumbnails.init();
-
- setUrlAndSearchBarWidthForConditionalForwardButton();
- window.addEventListener("resize", function resizeHandler(event) {
- if (event.target == window)
- setUrlAndSearchBarWidthForConditionalForwardButton();
- });
-
- // Enable Error Console?
- let consoleEnabled = gPrefService.getBoolPref("devtools.errorconsole.enabled");
- if (consoleEnabled) {
- let cmd = document.getElementById("Tools:ErrorConsole");
- cmd.removeAttribute("disabled");
- cmd.removeAttribute("hidden");
- }
-
-#ifdef MENUBAR_CAN_AUTOHIDE
- // If the user (or the locale) hasn't enabled the top-level "Character
- // Encoding" menu via the "browser.menu.showCharacterEncoding" preference,
- // hide it.
- if ("true" != gPrefService.getComplexValue("browser.menu.showCharacterEncoding",
- Ci.nsIPrefLocalizedString).data)
- document.getElementById("appmenu_charsetMenu").hidden = true;
-#endif
-
- let appMenuButton = document.getElementById("appmenu-button");
- let appMenuPopup = document.getElementById("appmenu-popup");
- if (appMenuButton && appMenuPopup) {
- let appMenuOpening = null;
- appMenuButton.addEventListener("mousedown", function(event) {
- if (event.button == 0)
- appMenuOpening = new Date();
- }, false);
- appMenuPopup.addEventListener("popupshown", function(event) {
- if (event.target != appMenuPopup || !appMenuOpening)
- return;
- let duration = new Date() - appMenuOpening;
- appMenuOpening = null;
- }, false);
- }
-
- window.addEventListener("mousemove", MousePosTracker, false);
- window.addEventListener("dragover", MousePosTracker, false);
-
- // End startup crash tracking after a delay to catch crashes while restoring
- // tabs and to postpone saving the pref to disk.
- try {
- const startupCrashEndDelay = 30 * 1000;
- setTimeout(Services.startup.trackStartupCrashEnd, startupCrashEndDelay);
- } catch (ex) {
- Cu.reportError("Could not end startup crash tracking: " + ex);
- }
-
- ssPromise.then(() =>{
- // Bail out if the window has been closed in the meantime.
- if (window.closed) {
- return;
- }
- if ("TabView" in window) {
- TabView.init();
- }
- // XXX: do we still need this?...
- setTimeout(function () { BrowserChromeTest.markAsReady(); }, 0);
- });
-
- this.delayedStartupFinished = true;
-
- Services.obs.notifyObservers(window, "browser-delayed-startup-finished", "");
- },
-
- // Returns the URI(s) to load at startup.
- _getUriToLoad: function () {
- // window.arguments[0]: URI to load (string), or an nsISupportsArray of
- // nsISupportsStrings to load, or a xul:tab of
- // a tabbrowser, which will be replaced by this
- // window (for this case, all other arguments are
- // ignored).
- if (!window.arguments || !window.arguments[0])
- return null;
-
- let uri = window.arguments[0];
- let sessionStartup = Cc["@mozilla.org/browser/sessionstartup;1"]
- .getService(Ci.nsISessionStartup);
- let defaultArgs = Cc["@mozilla.org/browser/clh;1"]
- .getService(Ci.nsIBrowserHandler)
- .defaultArgs;
-
- // If the given URI matches defaultArgs (the default homepage) we want
- // to block its load if we're going to restore a session anyway.
- if (uri == defaultArgs && sessionStartup.willOverrideHomepage)
- return null;
-
- return uri;
- },
-
- onUnload: function() {
- // In certain scenarios it's possible for unload to be fired before onload,
- // (e.g. if the window is being closed after browser.js loads but before the
- // load completes). In that case, there's nothing to do here.
- if (!this._loadHandled)
- return;
-
- // First clean up services initialized in gBrowserInit.onLoad (or those whose
- // uninit methods don't depend on the services having been initialized).
-
- allTabs.uninit();
-
- CombinedStopReload.uninit();
-
- gGestureSupport.init(false);
-
- gHistorySwipeAnimation.uninit();
-
- FullScreen.cleanup();
-
- Services.obs.removeObserver(gPluginHandler.pluginCrashed, "plugin-crashed");
-
- try {
- gBrowser.removeProgressListener(window.XULBrowserWindow);
- gBrowser.removeTabsProgressListener(window.TabsProgressListener);
- } catch (ex) {
- }
-
- BookmarkingUI.uninit();
-
- TabsOnTop.uninit();
-
- AudioIndicator.uninit();
-
- TabsInTitlebar.uninit();
-
- ToolbarIconColor.uninit();
-
-#ifdef MOZ_DEVTOOLS
- DevToolsTheme.uninit();
-#endif
- gFindBarSettings.uninit();
-
- UserAgentCompatibility.uninit();
-
- var enumerator = Services.wm.getEnumerator(null);
- enumerator.getNext();
- if (!enumerator.hasMoreElements()) {
- document.persist("sidebar-box", "sidebarcommand");
- document.persist("sidebar-box", "width");
- document.persist("sidebar-box", "src");
- document.persist("sidebar-title", "value");
- }
-
- // Now either cancel delayedStartup, or clean up the services initialized from
- // it.
- if (this._boundDelayedStartup) {
- this._cancelDelayedStartup();
- } else {
- if (Win7Features)
- Win7Features.onCloseWindow();
-
- gPrefService.removeObserver(ctrlTab.prefName, ctrlTab);
- gPrefService.removeObserver(allTabs.prefName, allTabs);
- ctrlTab.uninit();
- if ("TabView" in window) {
- TabView.uninit();
- }
- gBrowserThumbnails.uninit();
- FullZoom.destroy();
-
- Services.obs.removeObserver(gSessionHistoryObserver, "browser:purge-session-history");
- Services.obs.removeObserver(gXPInstallObserver, "addon-install-disabled");
- Services.obs.removeObserver(gXPInstallObserver, "addon-install-started");
- Services.obs.removeObserver(gXPInstallObserver, "addon-install-blocked");
- Services.obs.removeObserver(gXPInstallObserver, "addon-install-origin-blocked");
- Services.obs.removeObserver(gXPInstallObserver, "addon-install-failed");
- Services.obs.removeObserver(gXPInstallObserver, "addon-install-complete");
- Services.obs.removeObserver(gXSSObserver, "xss-on-violate-policy");
-
- try {
- gPrefService.removeObserver(gURLBarSettings.prefSuggest, gURLBarSettings);
- gPrefService.removeObserver(gURLBarSettings.prefKeyword, gURLBarSettings);
- } catch (ex) {
- Cu.reportError(ex);
- }
-
- try {
- gPrefService.removeObserver(gHomeButton.prefDomain, gHomeButton);
- } catch (ex) {
- Cu.reportError(ex);
- }
-
- BrowserOffline.uninit();
- OfflineApps.uninit();
- IndexedDBPromptHelper.uninit();
- AddonManager.removeAddonListener(AddonsMgrListener);
- }
-
- // Final window teardown, do this last.
- window.XULBrowserWindow.destroy();
- window.XULBrowserWindow = null;
- window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIXULWindow)
- .XULBrowserWindow = null;
- window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow = null;
- },
-
-#ifdef XP_MACOSX
- // nonBrowserWindowStartup(), nonBrowserWindowDelayedStartup(), and
- // nonBrowserWindowShutdown() are used for non-browser windows in
- // macBrowserOverlay
- nonBrowserWindowStartup: function() {
- // Disable inappropriate commands / submenus
- var disabledItems = ['Browser:SavePage',
- 'Browser:SendLink', 'cmd_pageSetup', 'cmd_print', 'cmd_find', 'cmd_findAgain',
- 'viewToolbarsMenu', 'viewSidebarMenuMenu', 'Browser:Reload',
- 'viewFullZoomMenu', 'pageStyleMenu', 'charsetMenu', 'View:PageSource', 'View:FullScreen',
- 'viewHistorySidebar', 'Browser:AddBookmarkAs', 'Browser:BookmarkAllTabs',
- 'View:PageInfo', 'Browser:ToggleAddonBar'];
- var element;
-
- for (let disabledItem of disabledItems) {
- element = document.getElementById(disabledItem);
- if (element)
- element.setAttribute("disabled", "true");
- }
-
- // If no windows are active (i.e. we're the hidden window), disable the close, minimize
- // and zoom menu commands as well
- if (window.location.href == "chrome://browser/content/hiddenWindow.xul") {
- var hiddenWindowDisabledItems = ['cmd_close', 'minimizeWindow', 'zoomWindow'];
- for (let hiddenWindowDisabledItem of hiddenWindowDisabledItems) {
- element = document.getElementById(hiddenWindowDisabledItem);
- if (element)
- element.setAttribute("disabled", "true");
- }
-
- // also hide the window-list separator
- element = document.getElementById("sep-window-list");
- element.setAttribute("hidden", "true");
-
- // Setup the dock menu.
- let dockMenuElement = document.getElementById("menu_mac_dockmenu");
- if (dockMenuElement != null) {
- let nativeMenu = Cc["@mozilla.org/widget/standalonenativemenu;1"]
- .createInstance(Ci.nsIStandaloneNativeMenu);
-
- try {
- nativeMenu.init(dockMenuElement);
-
- let dockSupport = Cc["@mozilla.org/widget/macdocksupport;1"]
- .getService(Ci.nsIMacDockSupport);
- dockSupport.dockMenu = nativeMenu;
- }
- catch (e) {
- }
- }
- }
-
- if (PrivateBrowsingUtils.permanentPrivateBrowsing) {
- document.getElementById("macDockMenuNewWindow").hidden = true;
- }
-
- this._delayedStartupTimeoutId = setTimeout(this.nonBrowserWindowDelayedStartup.bind(this), 0);
- },
-
- nonBrowserWindowDelayedStartup: function() {
- this._delayedStartupTimeoutId = null;
-
- // initialise the offline listener
- BrowserOffline.init();
-
- // Set up Sanitize Item
- this._initializeSanitizer();
-
- // initialize the private browsing UI
- gPrivateBrowsingUI.init();
-
-#ifdef MOZ_SERVICES_SYNC
- // initialize the sync UI
- gSyncUI.init();
-#endif
- },
-
- nonBrowserWindowShutdown: function() {
- // If nonBrowserWindowDelayedStartup hasn't run yet, we have no work to do -
- // just cancel the pending timeout and return;
- if (this._delayedStartupTimeoutId) {
- clearTimeout(this._delayedStartupTimeoutId);
- return;
- }
-
- BrowserOffline.uninit();
- },
-#endif
-
- _initializeSanitizer: function() {
- const kDidSanitizeDomain = "privacy.sanitize.didShutdownSanitize";
- if (gPrefService.prefHasUserValue(kDidSanitizeDomain)) {
- gPrefService.clearUserPref(kDidSanitizeDomain);
- // We need to persist this preference change, since we want to
- // check it at next app start even if the browser exits abruptly
- gPrefService.savePrefFile(null);
- }
-
- /**
- * Migrate Firefox 3.0 privacy.item prefs under one of these conditions:
- *
- * a) User has customized any privacy.item prefs
- * b) privacy.sanitize.sanitizeOnShutdown is set
- */
- if (!gPrefService.getBoolPref("privacy.sanitize.migrateFx3Prefs")) {
- let itemBranch = gPrefService.getBranch("privacy.item.");
- let itemArray = itemBranch.getChildList("");
-
- // See if any privacy.item prefs are set
- let doMigrate = itemArray.some(function (name) itemBranch.prefHasUserValue(name));
- // Or if sanitizeOnShutdown is set
- if (!doMigrate)
- doMigrate = gPrefService.getBoolPref("privacy.sanitize.sanitizeOnShutdown");
-
- if (doMigrate) {
- let cpdBranch = gPrefService.getBranch("privacy.cpd.");
- let clearOnShutdownBranch = gPrefService.getBranch("privacy.clearOnShutdown.");
- for (let name of itemArray) {
- try {
- // don't migrate password or offlineApps clearing in the CRH dialog since
- // there's no UI for those anymore. They default to false. bug 497656
- if (name != "passwords" && name != "offlineApps")
- cpdBranch.setBoolPref(name, itemBranch.getBoolPref(name));
- clearOnShutdownBranch.setBoolPref(name, itemBranch.getBoolPref(name));
- }
- catch(e) {
- Cu.reportError("Exception thrown during privacy pref migration: " + e);
- }
- }
- }
-
- gPrefService.setBoolPref("privacy.sanitize.migrateFx3Prefs", true);
- }
- },
-}
-
-
-/* Legacy global init functions */
-var BrowserStartup = gBrowserInit.onLoad.bind(gBrowserInit);
-var BrowserShutdown = gBrowserInit.onUnload.bind(gBrowserInit);
-#ifdef XP_MACOSX
-var nonBrowserWindowStartup = gBrowserInit.nonBrowserWindowStartup.bind(gBrowserInit);
-var nonBrowserWindowDelayedStartup = gBrowserInit.nonBrowserWindowDelayedStartup.bind(gBrowserInit);
-var nonBrowserWindowShutdown = gBrowserInit.nonBrowserWindowShutdown.bind(gBrowserInit);
-#endif
-
-function HandleAppCommandEvent(evt) {
- switch (evt.command) {
- case "Back":
- BrowserBack();
- break;
- case "Forward":
- BrowserForward();
- break;
- case "Reload":
- BrowserReloadSkipCache();
- break;
- case "Stop":
- if (XULBrowserWindow.stopCommand.getAttribute("disabled") != "true")
- BrowserStop();
- break;
- case "Search":
- BrowserSearch.webSearch();
- break;
- case "Bookmarks":
- toggleSidebar('viewBookmarksSidebar');
- break;
- case "Home":
- BrowserHome();
- break;
- case "New":
- BrowserOpenTab();
- break;
- case "Close":
- BrowserCloseTabOrWindow();
- break;
- case "Find":
- gFindBar.onFindCommand();
- break;
- case "Help":
- openHelpLink('firefox-help');
- break;
- case "Open":
- BrowserOpenFileWindow();
- break;
- case "Print":
- PrintUtils.print();
- break;
- case "Save":
- saveDocument(window.content.document);
- break;
- case "SendMail":
- MailIntegration.sendLinkForWindow(window.content);
- break;
- default:
- return;
- }
- evt.stopPropagation();
- evt.preventDefault();
-}
-
-function gotoHistoryIndex(aEvent) {
- let index = aEvent.target.getAttribute("index");
- if (!index)
- return false;
-
- let where = whereToOpenLink(aEvent);
-
- if (where == "current") {
- // Normal click. Go there in the current tab and update session history.
-
- try {
- gBrowser.gotoIndex(index);
- }
- catch(ex) {
- return false;
- }
- return true;
- }
- // Modified click. Go there in a new tab/window.
-
- duplicateTabIn(gBrowser.selectedTab, where, index - gBrowser.sessionHistory.index);
- return true;
-}
-
-function BrowserForward(aEvent) {
- let where = whereToOpenLink(aEvent, false, true);
-
- if (where == "current") {
- try {
- gBrowser.goForward();
- }
- catch(ex) {
- }
- }
- else {
- duplicateTabIn(gBrowser.selectedTab, where, 1);
- }
-}
-
-function BrowserBack(aEvent) {
- let where = whereToOpenLink(aEvent, false, true);
-
- if (where == "current") {
- try {
- gBrowser.goBack();
- }
- catch(ex) {
- }
- }
- else {
- duplicateTabIn(gBrowser.selectedTab, where, -1);
- }
-}
-
-function BrowserHandleBackspace()
-{
- switch (gPrefService.getIntPref("browser.backspace_action")) {
- case 0:
- BrowserBack();
- break;
- case 1:
- goDoCommand("cmd_scrollPageUp");
- break;
- }
-}
-
-function BrowserHandleShiftBackspace()
-{
- switch (gPrefService.getIntPref("browser.backspace_action")) {
- case 0:
- BrowserForward();
- break;
- case 1:
- goDoCommand("cmd_scrollPageDown");
- break;
- }
-}
-
-function BrowserStop() {
- const stopFlags = nsIWebNavigation.STOP_ALL;
- gBrowser.webNavigation.stop(stopFlags);
-}
-
-function BrowserReloadOrDuplicate(aEvent) {
- var backgroundTabModifier = aEvent.button == 1 ||
-#ifdef XP_MACOSX
- aEvent.metaKey;
-#else
- aEvent.ctrlKey;
-#endif
- if (aEvent.shiftKey && !backgroundTabModifier) {
- BrowserReloadSkipCache();
- return;
- }
-
- let where = whereToOpenLink(aEvent, false, true);
- if (where == "current")
- BrowserReload();
- else
- duplicateTabIn(gBrowser.selectedTab, where);
-}
-
-function BrowserReload() {
- const reloadFlags = nsIWebNavigation.LOAD_FLAGS_NONE;
- BrowserReloadWithFlags(reloadFlags);
-}
-
-function BrowserReloadSkipCache() {
- // Bypass proxy and cache.
- const reloadFlags = nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY | nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
- BrowserReloadWithFlags(reloadFlags);
-}
-
-var BrowserHome = BrowserGoHome;
-function BrowserGoHome(aEvent) {
- if (aEvent && "button" in aEvent &&
- aEvent.button == 2) // right-click: do nothing
- return;
-
- var homePage = gHomeButton.getHomePage();
- var where = whereToOpenLink(aEvent, false, true);
- var urls;
-
- // Home page should open in a new tab when current tab is an app tab
- if (where == "current" &&
- gBrowser &&
- gBrowser.selectedTab.pinned)
- where = "tab";
-
- // openUILinkIn in utilityOverlay.js doesn't handle loading multiple pages
- switch (where) {
- case "current":
- loadOneOrMoreURIs(homePage);
- break;
- case "tabshifted":
- case "tab":
- urls = homePage.split("|");
- var loadInBackground = Services.prefs.getBoolPref("browser.tabs.loadBookmarksInBackground", false);
- gBrowser.loadTabs(urls, loadInBackground);
- break;
- case "window":
- OpenBrowserWindow();
- break;
- }
-}
-
-function loadOneOrMoreURIs(aURIString)
-{
-#ifdef XP_MACOSX
- // we're not a browser window, pass the URI string to a new browser window
- if (window.location.href != getBrowserURL())
- {
- window.openDialog(getBrowserURL(), "_blank", "all,dialog=no", aURIString);
- return;
- }
-#endif
- // This function throws for certain malformed URIs, so use exception handling
- // so that we don't disrupt startup
- try {
- gBrowser.loadTabs(aURIString.split("|"), false, true);
- }
- catch (e) {
- }
-}
-
-function focusAndSelectUrlBar() {
- if (gURLBar) {
- if (window.fullScreen)
- FullScreen.showNavToolbox();
-
- gURLBar.select();
- if (document.activeElement == gURLBar.inputField)
- return true;
- }
- return false;
-}
-
-function openLocation() {
- if (focusAndSelectUrlBar())
- return;
-
-#ifdef XP_MACOSX
- if (window.location.href != getBrowserURL()) {
- var win = getTopWin();
- if (win) {
- // If there's an open browser window, it should handle this command
- win.focus()
- win.openLocation();
- }
- else {
- // If there are no open browser windows, open a new one
- win = window.openDialog("chrome://browser/content/", "_blank",
- "chrome,all,dialog=no", BROWSER_NEW_TAB_URL);
- win.addEventListener("load", openLocationCallback, false);
- }
- return;
- }
-#endif
- openDialog("chrome://browser/content/openLocation.xul", "_blank",
- "chrome,modal,titlebar", window);
-}
-
-function openLocationCallback()
-{
- // make sure the DOM is ready
- setTimeout(function() { this.openLocation(); }, 0);
-}
-
-function BrowserOpenTab()
-{
- openUILinkIn(BROWSER_NEW_TAB_URL, "tab");
-}
-
-/* Called from the openLocation dialog. This allows that dialog to instruct
- its opener to open a new window and then step completely out of the way.
- Anything less byzantine is causing horrible crashes, rather believably,
- though oddly only on Linux. */
-function delayedOpenWindow(chrome, flags, href, postData)
-{
- // The other way to use setTimeout,
- // setTimeout(openDialog, 10, chrome, "_blank", flags, url),
- // doesn't work here. The extra "magic" extra argument setTimeout adds to
- // the callback function would confuse gBrowserInit.onLoad() by making
- // window.arguments[1] be an integer instead of null.
- setTimeout(function() { openDialog(chrome, "_blank", flags, href, null, null, postData); }, 10);
-}
-
-/* Required because the tab needs time to set up its content viewers and get the load of
- the URI kicked off before becoming the active content area. */
-function delayedOpenTab(aUrl, aReferrer, aCharset, aPostData, aAllowThirdPartyFixup)
-{
- gBrowser.loadOneTab(aUrl, {
- referrerURI: aReferrer,
- charset: aCharset,
- postData: aPostData,
- inBackground: false,
- allowThirdPartyFixup: aAllowThirdPartyFixup});
-}
-
-var gLastOpenDirectory = {
- _lastDir: null,
- get path() {
- if (!this._lastDir || !this._lastDir.exists()) {
- try {
- this._lastDir = gPrefService.getComplexValue("browser.open.lastDir",
- Ci.nsILocalFile);
- if (!this._lastDir.exists())
- this._lastDir = null;
- }
- catch(e) {}
- }
- return this._lastDir;
- },
- set path(val) {
- try {
- if (!val || !val.isDirectory())
- return;
- } catch(e) {
- return;
- }
- this._lastDir = val.clone();
-
- // Don't save the last open directory pref inside the Private Browsing mode
- if (!PrivateBrowsingUtils.isWindowPrivate(window))
- gPrefService.setComplexValue("browser.open.lastDir", Ci.nsILocalFile,
- this._lastDir);
- },
- reset: function() {
- this._lastDir = null;
- }
-};
-
-function BrowserOpenFileWindow()
-{
- // Get filepicker component.
- try {
- const nsIFilePicker = Ci.nsIFilePicker;
- let fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
- let fpCallback = function fpCallback_done(aResult) {
- if (aResult == nsIFilePicker.returnOK) {
- try {
- if (fp.file) {
- gLastOpenDirectory.path =
- fp.file.parent.QueryInterface(Ci.nsILocalFile);
- }
- } catch (ex) {
- }
- openUILinkIn(fp.fileURL.spec, "current");
- }
- };
-
- fp.init(window, gNavigatorBundle.getString("openFile"),
- nsIFilePicker.modeOpen);
- fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText |
- nsIFilePicker.filterImages | nsIFilePicker.filterXML |
- nsIFilePicker.filterHTML);
- fp.displayDirectory = gLastOpenDirectory.path;
- fp.open(fpCallback);
- } catch (ex) {
- }
-}
-
-function BrowserCloseTabOrWindow() {
-#ifdef XP_MACOSX
- // If we're not a browser window, just close the window
- if (window.location.href != getBrowserURL()) {
- closeWindow(true);
- return;
- }
-#endif
-
- // If the current tab is the last one, this will close the window.
- gBrowser.removeCurrentTab({animate: true});
-}
-
-function BrowserTryToCloseWindow()
-{
- if (WindowIsClosing())
- window.close(); // WindowIsClosing does all the necessary checks
-}
-
-function loadURI(uri, referrer, postData, allowThirdPartyFixup, referrerPolicy,
- originPrincipal, forceAboutBlankViewerInCurrent,
- triggeringPrincipal) {
- if (postData === undefined)
- postData = null;
-
- var flags = nsIWebNavigation.LOAD_FLAGS_NONE;
- if (allowThirdPartyFixup) {
- flags |= nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
- flags |= nsIWebNavigation.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
- }
-
- try {
- gBrowser.loadURIWithFlags(uri, {
- flags: flags,
- referrerURI: referrer,
- referrerPolicy: referrerPolicy,
- postData: postData,
- originPrincipal: originPrincipal,
- triggeringPrincipal: triggeringPrincipal,
- forceAboutBlankViewerInCurrent: forceAboutBlankViewerInCurrent,
- });
- } catch (e) {}
-}
-
-/**
- * Given a urlbar value, discerns between URIs, keywords and aliases.
- *
- * @param url
- * The urlbar value.
- * @param callback (optional, deprecated)
- * The callback function invoked when done. This parameter is
- * deprecated, please use the Promise that is returned.
- *
- * @return Promise<{ postData, url, mayInheritPrincipal }>
- */
-function getShortcutOrURIAndPostData(url, callback = null) {
- if (callback) {
- Deprecated.warning("Please use the Promise returned by " +
- "getShortcutOrURIAndPostData() instead of passing a " +
- "callback",
- "https://bugzilla.mozilla.org/show_bug.cgi?id=1100294");
- }
-
- return Task.spawn(function* () {
- let mayInheritPrincipal = false;
- let postData = null;
- let shortcutURL = null;
- let keyword = url;
- let param = "";
-
- let offset = url.indexOf(" ");
- if (offset > 0) {
- keyword = url.substr(0, offset);
- param = url.substr(offset + 1);
- }
-
- let engine = Services.search.getEngineByAlias(keyword);
- if (engine) {
- let submission = engine.getSubmission(param, null, "keyword");
- postData = submission.postData;
- return { postData: submission.postData, url: submission.uri.spec,
- mayInheritPrincipal };
- }
-
- let entry = yield PlacesUtils.keywords.fetch(keyword);
- if (entry) {
- shortcutURL = entry.url.href;
- postData = entry.postData;
- }
-
- if (!shortcutURL) {
- return { postData, url, mayInheritPrincipal };
- }
-
- let escapedPostData = "";
- if (postData)
- escapedPostData = unescape(postData);
-
- if (/%s/i.test(shortcutURL) || /%s/i.test(escapedPostData)) {
- let charset = "";
- const re = /^(.*)\&mozcharset=([a-zA-Z][_\-a-zA-Z0-9]+)\s*$/;
- let matches = shortcutURL.match(re);
-
- if (matches) {
- [, shortcutURL, charset] = matches;
- } else {
- let uri;
- try {
- // makeURI() throws if URI is invalid.
- uri = makeURI(shortcutURL);
- } catch (ex) {}
-
- if (uri) {
- // Try to get the saved character-set.
- // Will return an empty string if character-set is not found.
- charset = yield PlacesUtils.getCharsetForURI(uri);
- }
- }
-
- // encodeURIComponent produces UTF-8, and cannot be used for other charsets.
- // escape() works in those cases, but it doesn't uri-encode +, @, and /.
- // Therefore we need to manually replace these ASCII characters by their
- // encodeURIComponent result, to match the behavior of nsEscape() with
- // url_XPAlphas
- let encodedParam = "";
- if (charset && charset != "UTF-8")
- encodedParam = escape(convertFromUnicode(charset, param)).
- replace(/[+@\/]+/g, encodeURIComponent);
- else // Default charset is UTF-8
- encodedParam = encodeURIComponent(param);
-
- shortcutURL = shortcutURL.replace(/%s/g, encodedParam).replace(/%S/g, param);
-
- if (/%s/i.test(escapedPostData)) // POST keyword
- postData = getPostDataStream(escapedPostData, param, encodedParam,
- "application/x-www-form-urlencoded");
-
- // This URL came from a bookmark, so it's safe to let it inherit the current
- // document's principal.
- mayInheritPrincipal = true;
-
- return { postData, url: shortcutURL, mayInheritPrincipal };
- }
-
- if (param) {
- // This keyword doesn't take a parameter, but one was provided. Just return
- // the original URL.
- postData = null;
-
- return { postData, url, mayInheritPrincipal };
- }
-
- // This URL came from a bookmark, so it's safe to let it inherit the current
- // document's principal.
- mayInheritPrincipal = true;
-
- return { postData, url: shortcutURL, mayInheritPrincipal };
- }).then(data => {
- if (callback) {
- callback(data);
- }
-
- return data;
- });
-}
-
-function getPostDataStream(aStringData, aKeyword, aEncKeyword, aType) {
- var dataStream = Cc["@mozilla.org/io/string-input-stream;1"].
- createInstance(Ci.nsIStringInputStream);
- aStringData = aStringData.replace(/%s/g, aEncKeyword).replace(/%S/g, aKeyword);
- dataStream.data = aStringData;
-
- var mimeStream = Cc["@mozilla.org/network/mime-input-stream;1"].
- createInstance(Ci.nsIMIMEInputStream);
- mimeStream.addHeader("Content-Type", aType);
- mimeStream.addContentLength = true;
- mimeStream.setData(dataStream);
- return mimeStream.QueryInterface(Ci.nsIInputStream);
-}
-
-function getLoadContext() {
- return window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsILoadContext);
-}
-
-function readFromClipboard()
-{
- var url;
-
- try {
- // Create transferable that will transfer the text.
- var trans = Components.classes["@mozilla.org/widget/transferable;1"]
- .createInstance(Components.interfaces.nsITransferable);
- trans.init(getLoadContext());
-
- trans.addDataFlavor("text/unicode");
-
- // If available, use selection clipboard, otherwise global one
- if (Services.clipboard.supportsSelectionClipboard())
- Services.clipboard.getData(trans, Services.clipboard.kSelectionClipboard);
- else
- Services.clipboard.getData(trans, Services.clipboard.kGlobalClipboard);
-
- var data = {};
- var dataLen = {};
- trans.getTransferData("text/unicode", data, dataLen);
-
- if (data) {
- data = data.value.QueryInterface(Components.interfaces.nsISupportsString);
- url = data.data.substring(0, dataLen.value / 2);
- }
- } catch (ex) {
- }
-
- return url;
-}
-
-function BrowserViewSourceOfDocument(aArgsOrDocument)
-{
- let args;
-
- if (aArgsOrDocument instanceof Document) {
- let doc = aArgsOrDocument;
-
- let requestor = doc.defaultView
- .QueryInterface(Ci.nsIInterfaceRequestor);
- let browser = requestor.getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell)
- .chromeEventHandler;
- let outerWindowID = requestor.getInterface(Ci.nsIDOMWindowUtils)
- .outerWindowID;
- let URL = browser.currentURI.spec;
- args = { browser, outerWindowID, URL };
- } else {
- args = aArgsOrDocument;
- }
-
- let viewInternal = () => {
- top.gViewSourceUtils.viewSource(args);
- }
-
- // Check if external view source is enabled. If so, try it. If it fails,
- // fallback to internal view source.
- if (Services.prefs.getBoolPref("view_source.editor.external")) {
- top.gViewSourceUtils
- .openInExternalEditor(args, null, null, null, result => {
- if (!result) {
- viewInternal();
- }
- });
- } else {
- // Display using internal view source
- viewInternal();
- }
-}
-
-// doc - document to use for source, or null for this window's document
-// initialTab - name of the initial tab to display, or null for the first tab
-// imageElement - image to load in the Media Tab of the Page Info window; can be null/omitted
-function BrowserPageInfo(doc, initialTab, imageElement) {
- var args = {doc: doc, initialTab: initialTab, imageElement: imageElement};
- var windows = Services.wm.getEnumerator("Browser:page-info");
-
- var documentURL = doc ? doc.location : window.content.document.location;
-
- // Check for windows matching the url
- while (windows.hasMoreElements()) {
- var currentWindow = windows.getNext();
- if (currentWindow.document.documentElement.getAttribute("relatedUrl") == documentURL) {
- currentWindow.focus();
- currentWindow.resetPageInfo(args);
- return currentWindow;
- }
- }
-
- // We didn't find a matching window, so open a new one.
- return openDialog("chrome://browser/content/pageinfo/pageInfo.xul", "",
- "chrome,toolbar,dialog=no,resizable", args);
-}
-
-function URLBarSetURI(aURI) {
- var value = gBrowser.userTypedValue;
- var valid = false;
-
- if (value == null) {
- let uri = aURI || gBrowser.currentURI;
- // Strip off "wyciwyg://" and passwords for the location bar
- try {
- uri = Services.uriFixup.createExposableURI(uri);
- } catch (e) {}
-
- // Replace initial page URIs with an empty string
- // only if there's no opener (bug 370555).
- // Bug 863515 - Make content.opener checks work in electrolysis.
- if (gInitialPages.indexOf(uri.spec) != -1)
- value = !gMultiProcessBrowser && content.opener ? uri.spec : "";
- else
- value = losslessDecodeURI(uri);
-
- valid = !isBlankPageURL(uri.spec);
- }
-
- let isDifferentValidValue = valid && value != gURLBar.value;
- gURLBar.value = value;
- gURLBar.valueIsTyped = !valid;
- if (isDifferentValidValue) {
- gURLBar.selectionStart = gURLBar.selectionEnd = 0;
- }
-
- SetPageProxyState(valid ? "valid" : "invalid");
-}
-
-function losslessDecodeURI(aURI) {
- let scheme = aURI.scheme;
- let decodeASCIIOnly = !(/(https|http|file|ftp)/i.test(scheme));
-
- var value = aURI.spec;
-
- // Try to decode as UTF-8 if there's no encoding sequence that we would break.
- if (!/%25(?:3B|2F|3F|3A|40|26|3D|2B|24|2C|23)/i.test(value)) {
- if (decodeASCIIOnly) {
- // This only decodes ASCII characters (hex) 20-7e, except 25 (%).
- // This avoids both cases stipulated below (%-related issues, and \r, \n
- // and \t, which would be %0d, %0a and %09, respectively) as well as any
- // non-US-ascii characters.
- value = value.replace(/%(2[0-4]|2[6-9a-f]|[3-6][0-9a-f]|7[0-9a-e])/g, decodeURI);
- } else {
- try {
- value = decodeURI(value)
- // 1. decodeURI decodes %25 to %, which creates unintended
- // encoding sequences. Re-encode it, unless it's part of
- // a sequence that survived decodeURI, i.e. one for:
- // ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '#'
- // (RFC 3987 section 3.2)
- // 2. Re-encode whitespace so that it doesn't get eaten away
- // by the location bar (bug 410726).
- .replace(/%(?!3B|2F|3F|3A|40|26|3D|2B|24|2C|23)|[\r\n\t]/ig,
- encodeURIComponent);
- } catch (e) {}
- }
- }
-
- // Encode invisible characters (C0/C1 control characters, U+007F [DEL],
- // U+00A0 [no-break space], line and paragraph separator,
- // object replacement character) (bug 452979, bug 909264)
- value = value.replace(/[\u0000-\u001f\u007f-\u00a0\u2028\u2029\ufffc]/g,
- encodeURIComponent);
-
- // Encode default ignorable characters (bug 546013)
- // except ZWNJ (U+200C) and ZWJ (U+200D) (bug 582186).
- // This includes all bidirectional formatting characters.
- // (RFC 3987 sections 3.2 and 4.1 paragraph 6)
- value = value.replace(/[\u00ad\u034f\u115f-\u1160\u17b4-\u17b5\u180b-\u180d\u200b\u200e-\u200f\u202a-\u202e\u2060-\u206f\u3164\ufe00-\ufe0f\ufeff\uffa0\ufff0-\ufff8]|\ud834[\udd73-\udd7a]|[\udb40-\udb43][\udc00-\udfff]/g,
- encodeURIComponent);
- return value;
-}
-
-function UpdateUrlbarSearchSplitterState()
-{
- var splitter = document.getElementById("urlbar-search-splitter");
- var urlbar = document.getElementById("urlbar-container");
- var searchbar = document.getElementById("search-container");
- var stop = document.getElementById("stop-button");
-
- var ibefore = null;
- if (urlbar && searchbar) {
- if (urlbar.nextSibling == searchbar ||
- urlbar.getAttribute("combined") &&
- stop && stop.nextSibling == searchbar)
- ibefore = searchbar;
- else if (searchbar.nextSibling == urlbar)
- ibefore = urlbar;
- }
-
- if (ibefore) {
- if (!splitter) {
- splitter = document.createElement("splitter");
- splitter.id = "urlbar-search-splitter";
- splitter.setAttribute("resizebefore", "flex");
- splitter.setAttribute("resizeafter", "flex");
- splitter.setAttribute("skipintoolbarset", "true");
- splitter.className = "chromeclass-toolbar-additional";
- }
- urlbar.parentNode.insertBefore(splitter, ibefore);
- } else if (splitter)
- splitter.parentNode.removeChild(splitter);
-}
-
-function setUrlAndSearchBarWidthForConditionalForwardButton() {
- // Workaround for bug 694084: Showing/hiding the conditional forward button resizes
- // the search bar when the url/search bar splitter hasn't been used.
- var urlbarContainer = document.getElementById("urlbar-container");
- var searchbarContainer = document.getElementById("search-container");
- if (!urlbarContainer ||
- !searchbarContainer ||
- urlbarContainer.hasAttribute("width") ||
- searchbarContainer.hasAttribute("width") ||
- urlbarContainer.parentNode != searchbarContainer.parentNode)
- return;
- urlbarContainer.style.width = searchbarContainer.style.width = "";
- var urlbarWidth = urlbarContainer.clientWidth;
- var searchbarWidth = searchbarContainer.clientWidth;
- urlbarContainer.style.width = urlbarWidth + "px";
- searchbarContainer.style.width = searchbarWidth + "px";
-}
-
-function UpdatePageProxyState()
-{
- if (gURLBar && gURLBar.value != gLastValidURLStr)
- SetPageProxyState("invalid");
-}
-
-function SetPageProxyState(aState)
-{
- BookmarkingUI.onPageProxyStateChanged(aState);
-
- if (!gURLBar)
- return;
-
- if (!gProxyFavIcon)
- gProxyFavIcon = document.getElementById("page-proxy-favicon");
-
- gURLBar.setAttribute("pageproxystate", aState);
- gProxyFavIcon.setAttribute("pageproxystate", aState);
-
- // the page proxy state is set to valid via OnLocationChange, which
- // gets called when we switch tabs.
- if (aState == "valid") {
- gLastValidURLStr = gURLBar.value;
- gURLBar.addEventListener("input", UpdatePageProxyState, false);
- PageProxySetIcon(gBrowser.getIcon());
- } else if (aState == "invalid") {
- gURLBar.removeEventListener("input", UpdatePageProxyState, false);
- PageProxyClearIcon();
- }
-}
-
-function PageProxySetIcon (aURL)
-{
- if (!gProxyFavIcon)
- return;
-
- if (gBrowser.selectedBrowser.contentDocument instanceof ImageDocument) {
- // PageProxyClearIcon();
- gProxyFavIcon.setAttribute("src", "chrome://browser/skin/imagedocument.png");
- return;
- }
-
- if (!aURL)
- PageProxyClearIcon();
- else if (gProxyFavIcon.getAttribute("src") != aURL)
- gProxyFavIcon.setAttribute("src", aURL);
-}
-
-function PageProxyClearIcon ()
-{
- gProxyFavIcon.removeAttribute("src");
-}
-
-
-function PageProxyClickHandler(aEvent)
-{
- if (aEvent.button == 1 && gPrefService.getBoolPref("middlemouse.paste"))
- middleMousePaste(aEvent);
-}
-
-/**
- * Handle load of some pages (about:*) so that we can make modifications
- * to the DOM for unprivileged pages.
- */
-function BrowserOnAboutPageLoad(doc) {
-
- /* === about:home === */
-
- if (doc.documentURI.toLowerCase() == "about:home") {
- if (!PrivateBrowsingUtils.isWindowPrivate(window)) {
- let wrapper = {};
- Cu.import("resource:///modules/sessionstore/SessionStore.jsm", wrapper);
- let ss = wrapper.SessionStore;
- ss.promiseInitialized.then(function() {
- if (ss.canRestoreLastSession) {
- doc.getElementById("launcher").setAttribute("session", "true");
- }
- }).then(null, function onError(x) {
- Cu.reportError("Error in SessionStore init while processing 'about:home': " + x);
- });
- }
-
- // Inject search engine and snippets URL.
- let docElt = doc.documentElement;
- if (AboutHomeUtils.showKnowYourRights) {
- docElt.setAttribute("showKnowYourRights", "true");
- // Set pref to indicate we've shown the notification.
- let currentVersion = Services.prefs.getIntPref("browser.rights.version");
- Services.prefs.setBoolPref("browser.rights." + currentVersion + ".shown", true);
- }
-
- function updateSearchEngine() {
- let engine = AboutHomeUtils.defaultSearchEngine;
- docElt.setAttribute("searchEngineName", engine.name);
- docElt.setAttribute("searchEnginePostData", engine.postDataString || "");
- docElt.setAttribute("searchEngineURL", engine.searchURL);
- }
- Services.search.init(updateSearchEngine);
-
- // Listen for the event that's triggered when the user changes search engine.
- // At this point we simply reload about:home to reflect the change.
- Services.obs.addObserver(updateSearchEngine, "browser-search-engine-modified", false);
-
- // Remove the observer when the page is reloaded or closed.
- doc.defaultView.addEventListener("pagehide", function removeObserver() {
- doc.defaultView.removeEventListener("pagehide", removeObserver);
- Services.obs.removeObserver(updateSearchEngine, "browser-search-engine-modified");
- }, false);
- }
-
- /* === about:newtab === */
-
- if (doc.documentURI.toLowerCase() == "about:newtab") {
-
- let docElt = doc.documentElement;
-
- function updateSearchEngine() {
- let engine = AboutHomeUtils.defaultSearchEngine;
- docElt.setAttribute("searchEngineName", engine.name);
- docElt.setAttribute("searchEnginePostData", engine.postDataString || "");
- docElt.setAttribute("searchEngineURL", engine.searchURL);
- }
- Services.search.init(updateSearchEngine);
-
- // Listen for the event that's triggered when the user changes search engine.
- // At this point we simply reload about:newtab to reflect the change.
- Services.obs.addObserver(updateSearchEngine, "browser-search-engine-modified", false);
-
- // Remove the observer when the page is reloaded or closed.
- doc.defaultView.addEventListener("pagehide", function removeObserver() {
- doc.defaultView.removeEventListener("pagehide", removeObserver);
- Services.obs.removeObserver(updateSearchEngine, "browser-search-engine-modified");
- }, false);
- }
-
-}
-
-/**
- * Handle command events bubbling up from error page content
- */
-var BrowserOnClick = {
- handleEvent: function BrowserOnClick_handleEvent(aEvent) {
- if (!aEvent.isTrusted || // Don't trust synthetic events
- aEvent.button == 2 || aEvent.target.localName != "button") {
- return;
- }
-
- let originalTarget = aEvent.originalTarget;
- let ownerDoc = originalTarget.ownerDocument;
-
- // If the event came from an ssl error page, it is probably either the "Add
- // Exception…" or "Get me out of here!" button
- if (ownerDoc.documentURI.startsWith("about:certerror")) {
- this.onAboutCertError(originalTarget, ownerDoc);
- }
- else if (ownerDoc.documentURI.startsWith("about:neterror")) {
- this.onAboutNetError(originalTarget, ownerDoc);
- }
- else if (ownerDoc.documentURI.toLowerCase() == "about:home") {
- this.onAboutHome(originalTarget, ownerDoc);
- }
- },
-
- onAboutCertError: function BrowserOnClick_onAboutCertError(aTargetElm, aOwnerDoc) {
- let elmId = aTargetElm.getAttribute("id");
- let isTopFrame = (aOwnerDoc.defaultView.parent === aOwnerDoc.defaultView);
-
- switch (elmId) {
- case "exceptionDialogButton":
- let params = { exceptionAdded : false };
-
- try {
- switch (Services.prefs.getIntPref("browser.ssl_override_behavior")) {
- case 2 : // Pre-fetch & pre-populate
- params.prefetchCert = true;
- case 1 : // Pre-populate
- params.location = aOwnerDoc.location.href;
- }
- } catch (e) {
- Components.utils.reportError("Couldn't get ssl_override pref: " + e);
- }
-
- window.openDialog('chrome://pippki/content/exceptionDialog.xul',
- '','chrome,centerscreen,modal', params);
-
- // If the user added the exception cert, attempt to reload the page
- if (params.exceptionAdded) {
- aOwnerDoc.location.reload();
- }
- break;
-
- case "getMeOutOfHereButton":
- getMeOutOfHere();
- break;
-
- case "technicalContent":
- break;
-
- case "expertContent":
- break;
-
- }
- },
-
- onAboutNetError: function BrowserOnClick_onAboutNetError(aTargetElm, aOwnerDoc) {
- let elmId = aTargetElm.getAttribute("id");
- if (elmId != "errorTryAgain" || !/e=netOffline/.test(aOwnerDoc.documentURI))
- return;
- Services.io.offline = false;
- },
-
- onAboutHome: function BrowserOnClick_onAboutHome(aTargetElm, aOwnerDoc) {
- let elmId = aTargetElm.getAttribute("id");
-
- switch (elmId) {
- case "restorePreviousSession":
- let ss = Cc["@mozilla.org/browser/sessionstore;1"].
- getService(Ci.nsISessionStore);
- if (ss.canRestoreLastSession) {
- ss.restoreLastSession();
- }
- aOwnerDoc.getElementById("launcher").removeAttribute("session");
- break;
-
- case "downloads":
- BrowserDownloadsUI();
- break;
-
- case "bookmarks":
- PlacesCommandHook.showPlacesOrganizer("AllBookmarks");
- break;
-
- case "history":
- PlacesCommandHook.showPlacesOrganizer("History");
- break;
-
- case "addons":
- BrowserOpenAddonsMgr();
- break;
-
- case "sync":
- openPreferences("paneSync");
- break;
-
- case "settings":
- openPreferences();
- break;
- }
- },
-};
-
-/**
- * Re-direct the browser to a known-safe page. This function is
- * used when, for example, the user browses to a known malware page
- * and is presented with about:blocked. The "Get me out of here!"
- * button should take the user to the default start page so that even
- * when their own homepage is infected, we can get them somewhere safe.
- */
-function getMeOutOfHere() {
- try {
- let toBlank = Services.prefs.getBoolPref("browser.escape_to_blank");
- if (toBlank) {
- content.location = "about:logopage";
- return;
- }
- } catch(e) {
- Components.utils.reportError("Couldn't get escape pref: " + e);
- }
- // Get the start page from the *default* pref branch, not the user's
- var prefs = Services.prefs.getDefaultBranch(null);
- var url = BROWSER_NEW_TAB_URL;
- try {
- url = prefs.getComplexValue("browser.startup.homepage",
- Ci.nsIPrefLocalizedString).data;
- // If url is a pipe-delimited set of pages, just take the first one.
- if (url.includes("|"))
- url = url.split("|")[0];
- } catch(e) {
- Components.utils.reportError("Couldn't get homepage pref: " + e);
- }
- content.location = url;
-}
-
-function BrowserFullScreen()
-{
- window.fullScreen = !window.fullScreen;
-}
-
-function onFullScreen() {
- FullScreen.toggle();
-}
-
-function onMozEnteredDomFullscreen(event) {
- FullScreen.enterDomFullscreen(event);
-}
-
-function getWebNavigation()
-{
- return gBrowser.webNavigation;
-}
-
-function BrowserReloadWithFlags(reloadFlags) {
-
- // Reset DOS mitigation for auth prompts when user initiates a reload.
- let browser = gBrowser.selectedBrowser;
- delete browser.authPromptCounter;
-
- /* First, we'll try to use the session history object to reload so
- * that framesets are handled properly. If we're in a special
- * window (such as view-source) that has no session history, fall
- * back on using the web navigation's reload method.
- */
-
- var webNav = gBrowser.webNavigation;
- try {
- var sh = webNav.sessionHistory;
- if (sh)
- webNav = sh.QueryInterface(nsIWebNavigation);
- } catch (e) {
- }
-
- try {
- webNav.reload(reloadFlags);
- } catch (e) {
- }
-}
-
-var PrintPreviewListener = {
- _printPreviewTab: null,
- _tabBeforePrintPreview: null,
-
- getPrintPreviewBrowser: function () {
- if (!this._printPreviewTab) {
- this._tabBeforePrintPreview = gBrowser.selectedTab;
- this._printPreviewTab = gBrowser.loadOneTab("about:blank",
- { inBackground: false });
- gBrowser.selectedTab = this._printPreviewTab;
- }
- return gBrowser.getBrowserForTab(this._printPreviewTab);
- },
- getSourceBrowser: function () {
- return this._tabBeforePrintPreview ?
- this._tabBeforePrintPreview.linkedBrowser : gBrowser.selectedBrowser;
- },
- getNavToolbox: function () {
- return gNavToolbox;
- },
- onEnter: function () {
- // We might have accidentally switched tabs since the user invoked print
- // preview
- if (gBrowser.selectedTab != this._printPreviewTab) {
- gBrowser.selectedTab = this._printPreviewTab;
- }
- gInPrintPreviewMode = true;
- this._toggleAffectedChrome();
- },
- onExit: function () {
- gBrowser.selectedTab = this._tabBeforePrintPreview;
- this._tabBeforePrintPreview = null;
- gInPrintPreviewMode = false;
- this._toggleAffectedChrome();
- gBrowser.removeTab(this._printPreviewTab);
- this._printPreviewTab = null;
- },
- _toggleAffectedChrome: function () {
- gNavToolbox.collapsed = gInPrintPreviewMode;
-
- if (gInPrintPreviewMode)
- this._hideChrome();
- else
- this._showChrome();
-
- if (this._chromeState.sidebarOpen)
- toggleSidebar(this._sidebarCommand);
-
-#ifdef MENUBAR_CAN_AUTOHIDE
- updateAppButtonDisplay();
-#endif
- },
- _hideChrome: function () {
- this._chromeState = {};
-
- var sidebar = document.getElementById("sidebar-box");
- this._chromeState.sidebarOpen = !sidebar.hidden;
- this._sidebarCommand = sidebar.getAttribute("sidebarcommand");
-
- var notificationBox = gBrowser.getNotificationBox();
- this._chromeState.notificationsOpen = !notificationBox.notificationsHidden;
- notificationBox.notificationsHidden = true;
-
- document.getElementById("sidebar").setAttribute("src", "about:blank");
- var addonBar = document.getElementById("addon-bar");
- this._chromeState.addonBarOpen = !addonBar.collapsed;
- addonBar.collapsed = true;
- gBrowser.updateWindowResizers();
-
- this._chromeState.findOpen = gFindBarInitialized && !gFindBar.hidden;
- if (gFindBarInitialized)
- gFindBar.close();
-
- var globalNotificationBox = document.getElementById("global-notificationbox");
- this._chromeState.globalNotificationsOpen = !globalNotificationBox.notificationsHidden;
- globalNotificationBox.notificationsHidden = true;
-
- this._chromeState.syncNotificationsOpen = false;
- var syncNotifications = document.getElementById("sync-notifications");
- if (syncNotifications) {
- this._chromeState.syncNotificationsOpen = !syncNotifications.notificationsHidden;
- syncNotifications.notificationsHidden = true;
- }
- },
- _showChrome: function () {
- if (this._chromeState.notificationsOpen)
- gBrowser.getNotificationBox().notificationsHidden = false;
-
- if (this._chromeState.addonBarOpen) {
- document.getElementById("addon-bar").collapsed = false;
- gBrowser.updateWindowResizers();
- }
-
- if (this._chromeState.findOpen)
- gFindBar.open();
-
- if (this._chromeState.globalNotificationsOpen)
- document.getElementById("global-notificationbox").notificationsHidden = false;
-
- if (this._chromeState.syncNotificationsOpen)
- document.getElementById("sync-notifications").notificationsHidden = false;
- }
-}
-
-function getMarkupDocumentViewer()
-{
- return gBrowser.markupDocumentViewer;
-}
-
-// This function is obsolete. Newer code should use <tooltip page="true"/> instead.
-function FillInHTMLTooltip(tipElement)
-{
- document.getElementById("aHTMLTooltip").fillInPageTooltip(tipElement);
-}
-
-var browserDragAndDrop = {
- canDropLink: function (aEvent) Services.droppedLinkHandler.canDropLink(aEvent, true),
-
- dragOver: function (aEvent)
- {
- if (this.canDropLink(aEvent)) {
- aEvent.preventDefault();
- }
- },
-
- dropLinks: function (aEvent, aDisallowInherit) {
- return Services.droppedLinkHandler.dropLinks(aEvent, aDisallowInherit);
- }
-};
-
-var homeButtonObserver = {
- onDrop: function (aEvent)
- {
- // disallow setting home pages that inherit the principal
- let links = browserDragAndDrop.dropLinks(aEvent, true);
- if (links.length) {
- setTimeout(openHomeDialog, 0, links.map(link => link.url).join("|"));
- }
- },
-
- onDragOver: function (aEvent)
- {
- browserDragAndDrop.dragOver(aEvent);
- aEvent.dropEffect = "link";
- },
- onDragExit: function (aEvent)
- {
- }
-}
-
-function openHomeDialog(aURL)
-{
- var promptTitle = gNavigatorBundle.getString("droponhometitle");
- var promptMsg;
- if (aURL.includes("|")) {
- promptMsg = gNavigatorBundle.getString("droponhomemsgMultiple");
- } else {
- promptMsg = gNavigatorBundle.getString("droponhomemsg");
- }
-
- var pressedVal = Services.prompt.confirmEx(window, promptTitle, promptMsg,
- Services.prompt.STD_YES_NO_BUTTONS,
- null, null, null, null, {value:0});
-
- if (pressedVal == 0) {
- try {
- var homepageStr = Components.classes["@mozilla.org/supports-string;1"]
- .createInstance(Components.interfaces.nsISupportsString);
- homepageStr.data = aURL;
- gPrefService.setComplexValue("browser.startup.homepage",
- Components.interfaces.nsISupportsString, homepageStr);
- } catch (ex) {
- dump("Failed to set the home page.\n"+ex+"\n");
- }
- }
-}
-
-var bookmarksButtonObserver = {
- onDrop: function (aEvent)
- {
- let name = { };
- let url = browserDragAndDrop.drop(aEvent, name);
- try {
- PlacesUIUtils.showBookmarkDialog({ action: "add"
- , type: "bookmark"
- , uri: makeURI(url)
- , title: name
- , hiddenRows: [ "description"
- , "location"
- , "loadInSidebar"
- , "keyword" ]
- }, window);
- } catch(ex) { }
- },
-
- onDragOver: function (aEvent)
- {
- browserDragAndDrop.dragOver(aEvent);
- aEvent.dropEffect = "link";
- },
-
- onDragExit: function (aEvent)
- {
- }
-}
-
-var newTabButtonObserver = {
- onDragOver: function (aEvent)
- {
- browserDragAndDrop.dragOver(aEvent);
- },
-
- onDragExit: function (aEvent)
- {
- },
-
- onDrop: function (aEvent)
- {
- let links = browserDragAndDrop.dropLinks(aEvent);
- Task.spawn(function*() {
- for (let link of links) {
- let data = yield getShortcutOrURIAndPostData(link.url);
- if (data.url) {
- // allow third-party services to fixup this URL
- openNewTabWith(data.url, null, data.postData, aEvent, true);
- }
- }
- });
- }
-}
-
-var newWindowButtonObserver = {
- onDragOver: function (aEvent)
- {
- browserDragAndDrop.dragOver(aEvent);
- },
- onDragExit: function (aEvent)
- {
- },
- onDrop: function (aEvent)
- {
- let links = browserDragAndDrop.dropLinks(aEvent);
- Task.spawn(function*() {
- for (let link of links) {
- let data = yield getShortcutOrURIAndPostData(link.url);
- if (data.url) {
- // allow third-party services to fixup this URL
- openNewWindowWith(data.url, null, data.postData, true);
- }
- }
- });
- }
-}
-
-const DOMLinkHandler = {
- handleEvent: function (event) {
- switch (event.type) {
- case "DOMLinkAdded":
- this.onLinkAdded(event);
- break;
- }
- },
- getLinkIconURI: function(aLink) {
- let targetDoc = aLink.ownerDocument;
- var uri = makeURI(aLink.href, targetDoc.characterSet);
-
- // Verify that the load of this icon is legal.
- // Some error or special pages can load their favicon.
- // To be on the safe side, only allow chrome:// favicons.
- var isAllowedPage = [
- /^about:neterror\?/,
- /^about:blocked\?/,
- /^about:certerror\?/,
- /^about:home$/,
- ].some(function (re) re.test(targetDoc.documentURI));
-
- if (!isAllowedPage || !uri.schemeIs("chrome")) {
- var ssm = Services.scriptSecurityManager;
- try {
- ssm.checkLoadURIWithPrincipal(targetDoc.nodePrincipal, uri,
- Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
- } catch(e) {
- return null;
- }
- }
-
- try {
- var contentPolicy = Cc["@mozilla.org/layout/content-policy;1"].
- getService(Ci.nsIContentPolicy);
- } catch(e) {
- return null; // Refuse to load if we can't do a security check.
- }
-
- // Security says okay, now ask content policy
- if (contentPolicy.shouldLoad(Ci.nsIContentPolicy.TYPE_IMAGE,
- uri, targetDoc.documentURIObject,
- aLink, aLink.type, null)
- != Ci.nsIContentPolicy.ACCEPT)
- return null;
-
- try {
- uri.userPass = "";
- } catch(e) {
- // some URIs are immutable
- }
- return uri;
- },
- onLinkAdded: function (event) {
- var link = event.originalTarget;
- var rel = link.rel && link.rel.toLowerCase();
- if (!link || !link.ownerDocument || !rel || !link.href)
- return;
-
- var feedAdded = false;
- var iconAdded = false;
- var searchAdded = false;
- var rels = {};
- for (let relString of rel.split(/\s+/))
- rels[relString] = true;
-
- for (let relVal in rels) {
- switch (relVal) {
- case "feed":
- case "alternate":
- if (!feedAdded) {
- if (!rels.feed && rels.alternate && rels.stylesheet)
- break;
-
- if (isValidFeed(link, link.ownerDocument.nodePrincipal, "feed" in rels)) {
- FeedHandler.addFeed(link, link.ownerDocument);
- feedAdded = true;
- }
- }
- break;
- case "icon":
- if (!iconAdded) {
- if (!gPrefService.getBoolPref("browser.chrome.site_icons"))
- break;
-
- var uri = this.getLinkIconURI(link);
- if (!uri)
- break;
-
- if (gBrowser.isFailedIcon(uri))
- break;
-
- var browserIndex = gBrowser.getBrowserIndexForDocument(link.ownerDocument);
- // no browser? no favicon.
- if (browserIndex == -1)
- break;
-
- let tab = gBrowser.tabs[browserIndex];
- gBrowser.setIcon(tab, uri.spec, link.ownerDocument.nodePrincipal);
- iconAdded = true;
- }
- break;
- case "search":
- if (!searchAdded) {
- var type = link.type && link.type.toLowerCase();
- type = type.replace(/^\s+|\s*(?:;.*)?$/g, "");
-
- if (type == "application/opensearchdescription+xml" && link.title &&
- /^(?:https?|ftp):/i.test(link.href) &&
- !PrivateBrowsingUtils.isWindowPrivate(window)) {
- var engine = { title: link.title, href: link.href };
- Services.search.init(function () {
- BrowserSearch.addEngine(engine, link.ownerDocument);
- });
- searchAdded = true;
- }
- }
- break;
- }
- }
- }
-}
-
-const BrowserSearch = {
- addEngine: function(engine, targetDoc) {
- if (!this.searchBar)
- return;
-
- var browser = gBrowser.getBrowserForDocument(targetDoc);
- // ignore search engines from subframes (see bug 479408)
- if (!browser)
- return;
-
- // Check to see whether we've already added an engine with this title
- if (browser.engines) {
- if (browser.engines.some(function (e) e.title == engine.title))
- return;
- }
-
- // Append the URI and an appropriate title to the browser data.
- // Use documentURIObject in the check for shouldLoadFavIcon so that we
- // do the right thing with about:-style error pages. Bug 453442
- var iconURL = null;
- if (gBrowser.shouldLoadFavIcon(targetDoc.documentURIObject))
- iconURL = targetDoc.documentURIObject.prePath + "/favicon.ico";
-
- var hidden = false;
- // If this engine (identified by title) is already in the list, add it
- // to the list of hidden engines rather than to the main list.
- // XXX This will need to be changed when engines are identified by URL;
- // see bug 335102.
- if (Services.search.getEngineByName(engine.title))
- hidden = true;
-
- var engines = (hidden ? browser.hiddenEngines : browser.engines) || [];
-
- engines.push({ uri: engine.href,
- title: engine.title,
- icon: iconURL });
-
- if (hidden)
- browser.hiddenEngines = engines;
- else
- browser.engines = engines;
- },
-
- /**
- * Gives focus to the search bar, if it is present on the toolbar, or loads
- * the default engine's search form otherwise. For Mac, opens a new window
- * or focuses an existing window, if necessary.
- */
- webSearch: function BrowserSearch_webSearch() {
-#ifdef XP_MACOSX
- if (window.location.href != getBrowserURL()) {
- var win = getTopWin();
- if (win) {
- // If there's an open browser window, it should handle this command
- win.focus();
- win.BrowserSearch.webSearch();
- } else {
- // If there are no open browser windows, open a new one
- var observer = function observer(subject, topic, data) {
- if (subject == win) {
- BrowserSearch.webSearch();
- Services.obs.removeObserver(observer, "browser-delayed-startup-finished");
- }
- }
- win = window.openDialog(getBrowserURL(), "_blank",
- "chrome,all,dialog=no", "about:blank");
- Services.obs.addObserver(observer, "browser-delayed-startup-finished", false);
- }
- return;
- }
-#endif
- var searchBar = this.searchBar;
- if (searchBar && window.fullScreen)
- FullScreen.showNavToolbox();
- if (searchBar)
- searchBar.select();
- if (!searchBar || document.activeElement != searchBar.textbox.inputField)
- openUILinkIn(Services.search.defaultEngine.searchForm, "current");
- },
-
- /**
- * Loads a search results page, given a set of search terms. Uses the current
- * engine if the search bar is visible, or the default engine otherwise.
- *
- * @param searchText
- * The search terms to use for the search.
- *
- * @param useNewTab
- * Boolean indicating whether or not the search should load in a new
- * tab.
- *
- * @param purpose [optional]
- * A string meant to indicate the context of the search request. This
- * allows the search service to provide a different nsISearchSubmission
- * depending on e.g. where the search is triggered in the UI.
- *
- * @return string Name of the search engine used to perform a search or null
- * if a search was not performed.
- */
- loadSearch: function BrowserSearch_search(searchText, useNewTab, purpose) {
- var engine;
-
- // If the search bar is visible, use the current engine, otherwise, fall
- // back to the default engine.
- if (isElementVisible(this.searchBar))
- engine = Services.search.currentEngine;
- else
- engine = Services.search.defaultEngine;
-
- var submission = engine.getSubmission(searchText, null, purpose); // HTML response
-
- // getSubmission can return null if the engine doesn't have a URL
- // with a text/html response type. This is unlikely (since
- // SearchService._addEngineToStore() should fail for such an engine),
- // but let's be on the safe side.
- if (!submission) {
- return null;
- }
-
- let inBackground = Services.prefs.getBoolPref("browser.search.context.loadInBackground");
- openLinkIn(submission.uri.spec,
- useNewTab ? "tab" : "current",
- { postData: submission.postData,
- inBackground: inBackground,
- relatedToCurrent: true });
-
- return engine.name;
- },
-
- /**
- * Perform a search initiated from the context menu.
- *
- * This should only be called from the context menu. See
- * BrowserSearch.loadSearch for the preferred API.
- */
- loadSearchFromContext: function (terms) {
- let engine = BrowserSearch.loadSearch(terms, true, "contextmenu");
- },
-
- /**
- * Returns the search bar element if it is present in the toolbar, null otherwise.
- */
- get searchBar() {
- return document.getElementById("searchbar");
- },
-
- loadAddEngines: function BrowserSearch_loadAddEngines() {
- var newWindowPref = gPrefService.getIntPref("browser.link.open_newwindow");
- var where = newWindowPref == 3 ? "tab" : "window";
- var searchEnginesURL = formatURL("browser.search.searchEnginesURL", true);
- openUILinkIn(searchEnginesURL, where);
- },
-};
-
-XPCOMUtils.defineConstant(this, "BrowserSearch", BrowserSearch);
-
-function FillHistoryMenu(aParent) {
- // Lazily add the hover listeners on first showing and never remove them
- if (!aParent.hasStatusListener) {
- // Show history item's uri in the status bar when hovering, and clear on exit
- aParent.addEventListener("DOMMenuItemActive", function(aEvent) {
- // Only the current page should have the checked attribute, so skip it
- if (!aEvent.target.hasAttribute("checked"))
- XULBrowserWindow.setOverLink(aEvent.target.getAttribute("uri"));
- }, false);
- aParent.addEventListener("DOMMenuItemInactive", function() {
- XULBrowserWindow.setOverLink("");
- }, false);
-
- aParent.hasStatusListener = true;
- }
-
- // Remove old entries if any
- var children = aParent.childNodes;
- for (var i = children.length - 1; i >= 0; --i) {
- if (children[i].hasAttribute("index"))
- aParent.removeChild(children[i]);
- }
-
- var webNav = gBrowser.webNavigation;
- var sessionHistory = webNav.sessionHistory;
-
- var count = sessionHistory.count;
- if (count <= 1) // don't display the popup for a single item
- return false;
-
- const MAX_HISTORY_MENU_ITEMS = 15;
- var index = sessionHistory.index;
- var half_length = Math.floor(MAX_HISTORY_MENU_ITEMS / 2);
- var start = Math.max(index - half_length, 0);
- var end = Math.min(start == 0 ? MAX_HISTORY_MENU_ITEMS : index + half_length + 1, count);
- if (end == count)
- start = Math.max(count - MAX_HISTORY_MENU_ITEMS, 0);
-
- var tooltipBack = gNavigatorBundle.getString("tabHistory.goBack");
- var tooltipCurrent = gNavigatorBundle.getString("tabHistory.current");
- var tooltipForward = gNavigatorBundle.getString("tabHistory.goForward");
-
- for (var j = end - 1; j >= start; j--) {
- let item = document.createElement("menuitem");
- let entry = sessionHistory.getEntryAtIndex(j, false);
- let uri = entry.URI.spec;
-
- item.setAttribute("uri", uri);
- item.setAttribute("label", entry.title || uri);
- item.setAttribute("index", j);
-
- if (j != index) {
- PlacesUtils.favicons.getFaviconURLForPage(entry.URI, function (aURI) {
- if (aURI) {
- let iconURL = PlacesUtils.favicons.getFaviconLinkForIcon(aURI).spec;
- item.style.listStyleImage = "url(" + iconURL + ")";
- }
- });
- }
-
- if (j < index) {
- item.className = "unified-nav-back menuitem-iconic menuitem-with-favicon";
- item.setAttribute("tooltiptext", tooltipBack);
- } else if (j == index) {
- item.setAttribute("type", "radio");
- item.setAttribute("checked", "true");
- item.className = "unified-nav-current";
- item.setAttribute("tooltiptext", tooltipCurrent);
- } else {
- item.className = "unified-nav-forward menuitem-iconic menuitem-with-favicon";
- item.setAttribute("tooltiptext", tooltipForward);
- }
-
- aParent.appendChild(item);
- }
- return true;
-}
-
-function addToUrlbarHistory(aUrlToAdd) {
- if (!PrivateBrowsingUtils.isWindowPrivate(window) &&
- aUrlToAdd &&
- !aUrlToAdd.includes(" ") &&
- !/[\x00-\x1F]/.test(aUrlToAdd))
- PlacesUIUtils.markPageAsTyped(aUrlToAdd);
-}
-
-function toJavaScriptConsole()
-{
- toOpenWindowByType("global:console", "chrome://global/content/console.xul");
-}
-
-function BrowserDownloadsUI()
-{
- if (PrivateBrowsingUtils.isWindowPrivate(window)) {
- openUILinkIn("about:downloads", "tab");
- } else {
- PlacesCommandHook.showPlacesOrganizer("Downloads");
- }
-}
-
-function toOpenWindowByType(inType, uri, features)
-{
- var topWindow = Services.wm.getMostRecentWindow(inType);
-
- if (topWindow)
- topWindow.focus();
- else if (features)
- window.open(uri, "_blank", features);
- else
- window.open(uri, "_blank", "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar");
-}
-
-function OpenBrowserWindow(options)
-{
- function newDocumentShown(doc, topic, data) {
- if (topic == "document-shown" &&
- doc != document &&
- doc.defaultView == win) {
- Services.obs.removeObserver(newDocumentShown, "document-shown");
- }
- };
- Services.obs.addObserver(newDocumentShown, "document-shown", false);
-
- var charsetArg = new String();
- var handler = Components.classes["@mozilla.org/browser/clh;1"]
- .getService(Components.interfaces.nsIBrowserHandler);
- var defaultArgs = handler.defaultArgs;
- var wintype = document.documentElement.getAttribute('windowtype');
-
- var extraFeatures = "";
- if (options && options.private) {
- extraFeatures = ",private";
- if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
- // Force the new window to load about:privatebrowsing instead of the default home page
- defaultArgs = "about:privatebrowsing";
- }
- } else {
- extraFeatures = ",non-private";
- }
-
- // if and only if the current window is a browser window and it has a document with a character
- // set, then extract the current charset menu setting from the current document and use it to
- // initialize the new browser window...
- var win;
- if (window && (wintype == "navigator:browser") && window.content && window.content.document)
- {
- var DocCharset = window.content.document.characterSet;
- charsetArg = "charset="+DocCharset;
-
- //we should "inherit" the charset menu setting in a new window
- win = window.openDialog("chrome://browser/content/", "_blank", "chrome,all,dialog=no" + extraFeatures, defaultArgs, charsetArg);
- }
- else // forget about the charset information.
- {
- win = window.openDialog("chrome://browser/content/", "_blank", "chrome,all,dialog=no" + extraFeatures, defaultArgs);
- }
-
- return win;
-}
-
-var gCustomizeSheet = false;
-function BrowserCustomizeToolbar() {
- // Disable the toolbar context menu items
- var menubar = document.getElementById("main-menubar");
- for (let childNode of menubar.childNodes)
- childNode.setAttribute("disabled", true);
-
- var cmd = document.getElementById("cmd_CustomizeToolbars");
- cmd.setAttribute("disabled", "true");
-
- var splitter = document.getElementById("urlbar-search-splitter");
- if (splitter)
- splitter.parentNode.removeChild(splitter);
-
- CombinedStopReload.uninit();
-
- PlacesToolbarHelper.customizeStart();
- BookmarkingUI.customizeStart();
- DownloadsButton.customizeStart();
-
- TabsInTitlebar.allowedBy("customizing-toolbars", false);
-
- var customizeURL = "chrome://global/content/customizeToolbar.xul";
- gCustomizeSheet = Services.prefs.getBoolPref("toolbar.customization.usesheet", false);
-
- if (gCustomizeSheet) {
- let sheetFrame = document.createElement("iframe");
- let panel = document.getElementById("customizeToolbarSheetPopup");
- sheetFrame.id = "customizeToolbarSheetIFrame";
- sheetFrame.toolbox = gNavToolbox;
- sheetFrame.panel = panel;
- sheetFrame.setAttribute("style", panel.getAttribute("sheetstyle"));
- panel.appendChild(sheetFrame);
-
- // Open the panel, but make it invisible until the iframe has loaded so
- // that the user doesn't see a white flash.
- panel.style.visibility = "hidden";
- gNavToolbox.addEventListener("beforecustomization", function onBeforeCustomization() {
- gNavToolbox.removeEventListener("beforecustomization", onBeforeCustomization, false);
- panel.style.removeProperty("visibility");
- }, false);
-
- sheetFrame.setAttribute("src", customizeURL);
-
- panel.openPopup(gNavToolbox, "after_start", 0, 0);
- } else {
- window.openDialog(customizeURL,
- "CustomizeToolbar",
- "chrome,titlebar,toolbar,location,resizable,dependent",
- gNavToolbox);
- }
-}
-
-function BrowserToolboxCustomizeDone(aToolboxChanged) {
- if (gCustomizeSheet) {
- document.getElementById("customizeToolbarSheetPopup").hidePopup();
- let iframe = document.getElementById("customizeToolbarSheetIFrame");
- iframe.parentNode.removeChild(iframe);
- }
-
- // Update global UI elements that may have been added or removed
- if (aToolboxChanged) {
- gURLBar = document.getElementById("urlbar");
-
- gProxyFavIcon = document.getElementById("page-proxy-favicon");
- gHomeButton.updateTooltip();
- gIdentityHandler._cacheElements();
- window.XULBrowserWindow.init();
-
-#ifndef XP_MACOSX
- updateEditUIVisibility();
-#endif
-
- // Hacky: update the PopupNotifications' object's reference to the iconBox,
- // if it already exists, since it may have changed if the URL bar was
- // added/removed.
- if (!window.__lookupGetter__("PopupNotifications"))
- PopupNotifications.iconBox = document.getElementById("notification-popup-box");
- }
-
- PlacesToolbarHelper.customizeDone();
- BookmarkingUI.customizeDone();
- DownloadsButton.customizeDone();
-
- // The url bar splitter state is dependent on whether stop/reload
- // and the location bar are combined, so we need this ordering
- CombinedStopReload.init();
- UpdateUrlbarSearchSplitterState();
- setUrlAndSearchBarWidthForConditionalForwardButton();
-
- // Update the urlbar
- if (gURLBar) {
- gURLBarSettings.writePlaceholder();
- URLBarSetURI();
- XULBrowserWindow.asyncUpdateUI();
- BookmarkingUI.updateStarState();
- }
-
- TabsInTitlebar.allowedBy("customizing-toolbars", true);
-
- // Re-enable parts of the UI we disabled during the dialog
- var menubar = document.getElementById("main-menubar");
- for (let childNode of menubar.childNodes)
- childNode.setAttribute("disabled", false);
- var cmd = document.getElementById("cmd_CustomizeToolbars");
- cmd.removeAttribute("disabled");
-
- // make sure to re-enable click-and-hold
- if (!Services.prefs.getBoolPref("ui.click_hold_context_menus", false))
- SetClickAndHoldHandlers();
-
- gBrowser.selectedBrowser.focus();
-}
-
-function BrowserToolboxCustomizeChange(aType) {
- switch (aType) {
- case "iconsize":
- case "mode":
- retrieveToolbarIconsizesFromTheme();
- break;
- default:
- gHomeButton.updatePersonalToolbarStyle();
- BookmarkingUI.customizeChange();
- allTabs.readPref();
- }
-}
-
-/**
- * Allows themes to override the "iconsize" attribute on toolbars.
- */
-function retrieveToolbarIconsizesFromTheme() {
- function retrieveToolbarIconsize(aToolbar) {
- if (aToolbar.localName != "toolbar")
- return;
-
- // The theme indicates that it wants to override the "iconsize" attribute
- // by specifying a special value for the "counter-reset" property on the
- // toolbar. A custom property cannot be used because getComputedStyle can
- // only return the values of standard CSS properties.
- let counterReset = getComputedStyle(aToolbar).counterReset;
- if (counterReset == "smallicons 0")
- aToolbar.setAttribute("iconsize", "small");
- else if (counterReset == "largeicons 0")
- aToolbar.setAttribute("iconsize", "large");
- }
-
- Array.forEach(gNavToolbox.childNodes, retrieveToolbarIconsize);
- gNavToolbox.externalToolbars.forEach(retrieveToolbarIconsize);
-}
-
-/**
- * Update the global flag that tracks whether or not any edit UI (the Edit menu,
- * edit-related items in the context menu, and edit-related toolbar buttons
- * is visible, then update the edit commands' enabled state accordingly. We use
- * this flag to skip updating the edit commands on focus or selection changes
- * when no UI is visible to improve performance (including pageload performance,
- * since focus changes when you load a new page).
- *
- * If UI is visible, we use goUpdateGlobalEditMenuItems to set the commands'
- * enabled state so the UI will reflect it appropriately.
- *
- * If the UI isn't visible, we enable all edit commands so keyboard shortcuts
- * still work and just lazily disable them as needed when the user presses a
- * shortcut.
- *
- * This doesn't work on Mac, since Mac menus flash when users press their
- * keyboard shortcuts, so edit UI is essentially always visible on the Mac,
- * and we need to always update the edit commands. Thus on Mac this function
- * is a no op.
- */
-function updateEditUIVisibility()
-{
-#ifndef XP_MACOSX
- let editMenuPopupState = document.getElementById("menu_EditPopup").state;
- let contextMenuPopupState = document.getElementById("contentAreaContextMenu").state;
- let placesContextMenuPopupState = document.getElementById("placesContext").state;
-#ifdef MENUBAR_CAN_AUTOHIDE
- let appMenuPopupState = document.getElementById("appmenu-popup").state;
-#endif
-
- // The UI is visible if the Edit menu is opening or open, if the context menu
- // is open, or if the toolbar has been customized to include the Cut, Copy,
- // or Paste toolbar buttons.
- gEditUIVisible = editMenuPopupState == "showing" ||
- editMenuPopupState == "open" ||
- contextMenuPopupState == "showing" ||
- contextMenuPopupState == "open" ||
- placesContextMenuPopupState == "showing" ||
- placesContextMenuPopupState == "open" ||
-#ifdef MENUBAR_CAN_AUTOHIDE
- appMenuPopupState == "showing" ||
- appMenuPopupState == "open" ||
-#endif
- document.getElementById("cut-button") ||
- document.getElementById("copy-button") ||
- document.getElementById("paste-button") ? true : false;
-
- // If UI is visible, update the edit commands' enabled state to reflect
- // whether or not they are actually enabled for the current focus/selection.
- if (gEditUIVisible)
- goUpdateGlobalEditMenuItems();
-
- // Otherwise, enable all commands, so that keyboard shortcuts still work,
- // then lazily determine their actual enabled state when the user presses
- // a keyboard shortcut.
- else {
- goSetCommandEnabled("cmd_undo", true);
- goSetCommandEnabled("cmd_redo", true);
- goSetCommandEnabled("cmd_cut", true);
- goSetCommandEnabled("cmd_copy", true);
- goSetCommandEnabled("cmd_paste", true);
- goSetCommandEnabled("cmd_selectAll", true);
- goSetCommandEnabled("cmd_delete", true);
- goSetCommandEnabled("cmd_switchTextDirection", true);
- }
-#endif
-}
-
-/**
- * Makes the Character Encoding menu enabled or disabled as appropriate.
- * To be called when the View menu or the app menu is opened.
- */
-function updateCharacterEncodingMenuState()
-{
- let charsetMenu = document.getElementById("charsetMenu");
- let appCharsetMenu = document.getElementById("appmenu_charsetMenu");
- let appDevCharsetMenu =
- document.getElementById("appmenu_developer_charsetMenu");
- // gBrowser is null on Mac when the menubar shows in the context of
- // non-browser windows. The above elements may be null depending on
- // what parts of the menubar are present. E.g. no app menu on Mac.
- if (gBrowser &&
- gBrowser.docShell &&
- gBrowser.docShell.mayEnableCharacterEncodingMenu) {
- if (charsetMenu) {
- charsetMenu.removeAttribute("disabled");
- }
- if (appCharsetMenu) {
- appCharsetMenu.removeAttribute("disabled");
- }
- if (appDevCharsetMenu) {
- appDevCharsetMenu.removeAttribute("disabled");
- }
- } else {
- if (charsetMenu) {
- charsetMenu.setAttribute("disabled", "true");
- }
- if (appCharsetMenu) {
- appCharsetMenu.setAttribute("disabled", "true");
- }
- if (appDevCharsetMenu) {
- appDevCharsetMenu.setAttribute("disabled", "true");
- }
- }
-}
-
-var XULBrowserWindow = {
- // Stored Status, Link and Loading values
- status: "",
- defaultStatus: "",
- overLink: "",
- startTime: 0,
- statusText: "",
- isBusy: false,
-/* Pale Moon: Don't hide navigation controls and toolbars for "special" pages. SBaD, M!
- inContentWhitelist: ["about:addons", "about:downloads", "about:permissions",
- "about:sync-progress"],*/
- inContentWhitelist: [],
-
- QueryInterface: function (aIID) {
- if (aIID.equals(Ci.nsIWebProgressListener) ||
- aIID.equals(Ci.nsIWebProgressListener2) ||
- aIID.equals(Ci.nsISupportsWeakReference) ||
- aIID.equals(Ci.nsIXULBrowserWindow) ||
- aIID.equals(Ci.nsISupports))
- return this;
- throw Cr.NS_NOINTERFACE;
- },
-
- get stopCommand () {
- delete this.stopCommand;
- return this.stopCommand = document.getElementById("Browser:Stop");
- },
- get reloadCommand () {
- delete this.reloadCommand;
- return this.reloadCommand = document.getElementById("Browser:Reload");
- },
- get statusTextField () {
- delete this.statusTextField;
- return this.statusTextField = document.getElementById("statusbar-display");
- },
- get isImage () {
- delete this.isImage;
- return this.isImage = document.getElementById("isImage");
- },
-
- init: function () {
- this.throbberElement = document.getElementById("navigator-throbber");
-
- // Bug 666809 - SecurityUI support for e10s
- if (gMultiProcessBrowser)
- return;
-
- // Initialize the security button's state and tooltip text. Remember to reset
- // _hostChanged, otherwise onSecurityChange will short circuit.
- var securityUI = gBrowser.securityUI;
- this._hostChanged = true;
- this.onSecurityChange(null, null, securityUI.state);
- },
-
- destroy: function () {
- // XXXjag to avoid leaks :-/, see bug 60729
- delete this.throbberElement;
- delete this.stopCommand;
- delete this.reloadCommand;
- delete this.statusTextField;
- delete this.statusText;
- },
-
- setJSStatus: function () {
- // unsupported
- },
-
- setDefaultStatus: function (status) {
- this.defaultStatus = status;
- this.updateStatusField();
- },
-
- setOverLink: function (url, anchorElt) {
- // Encode bidirectional formatting characters.
- // (RFC 3987 sections 3.2 and 4.1 paragraph 6)
- url = url.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g,
- encodeURIComponent);
-
- if (gURLBar && gURLBar._mayTrimURLs /* corresponds to browser.urlbar.trimURLs */)
- url = trimURL(url);
-
- this.overLink = url;
- LinkTargetDisplay.update();
- },
-
- updateStatusField: function () {
- var text, type, types = ["overLink"];
- if (this._busyUI)
- types.push("status");
- types.push("defaultStatus");
- for (type of types) {
- text = this[type];
- if (text)
- break;
- }
-
- // check the current value so we don't trigger an attribute change
- // and cause needless (slow!) UI updates
- if (this.statusText != text) {
- let field = this.statusTextField;
- field.setAttribute("previoustype", field.getAttribute("type"));
- field.setAttribute("type", type);
- field.label = text;
- field.setAttribute("crop", type == "overLink" ? "center" : "end");
- this.statusText = text;
- }
- },
-
- // Called before links are navigated to to allow us to retarget them if needed.
- onBeforeLinkTraversal: function(originalTarget, linkURI, linkNode, isAppTab) {
- let target = this._onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab);
- return target;
- },
-
- _onBeforeLinkTraversal: function(originalTarget, linkURI, linkNode, isAppTab) {
- // Don't modify non-default targets or targets that aren't in top-level app
- // tab docshells (isAppTab will be false for app tab subframes).
- if (originalTarget != "" || !isAppTab)
- return originalTarget;
-
- // External links from within app tabs should always open in new tabs
- // instead of replacing the app tab's page (Bug 575561)
- let linkHost;
- let docHost;
- try {
- linkHost = linkURI.host;
- docHost = linkNode.ownerDocument.documentURIObject.host;
- } catch(e) {
- // nsIURI.host can throw for non-nsStandardURL nsIURIs.
- // If we fail to get either host, just return originalTarget.
- return originalTarget;
- }
-
- if (docHost == linkHost)
- return originalTarget;
-
- // Special case: ignore "www" prefix if it is part of host string
- let [longHost, shortHost] =
- linkHost.length > docHost.length ? [linkHost, docHost] : [docHost, linkHost];
- if (longHost == "www." + shortHost)
- return originalTarget;
-
- return "_blank";
- },
-
- onLinkIconAvailable: function (aIconURL) {
- if (gProxyFavIcon && gBrowser.userTypedValue === null) {
- PageProxySetIcon(aIconURL); // update the favicon in the URL bar
- }
- },
-
- onProgressChange: function (aWebProgress, aRequest,
- aCurSelfProgress, aMaxSelfProgress,
- aCurTotalProgress, aMaxTotalProgress) {
- // Do nothing.
- },
-
- onProgressChange64: function (aWebProgress, aRequest,
- aCurSelfProgress, aMaxSelfProgress,
- aCurTotalProgress, aMaxTotalProgress) {
- return this.onProgressChange(aWebProgress, aRequest,
- aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress,
- aMaxTotalProgress);
- },
-
- // This function fires only for the currently selected tab.
- onStateChange: function (aWebProgress, aRequest, aStateFlags, aStatus) {
- const nsIWebProgressListener = Ci.nsIWebProgressListener;
- const nsIChannel = Ci.nsIChannel;
-
- if (aStateFlags & nsIWebProgressListener.STATE_START &&
- aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
-
- if (aRequest && aWebProgress.isTopLevel) {
- // clear out feed data
- gBrowser.selectedBrowser.feeds = null;
-
- // clear out search-engine data
- gBrowser.selectedBrowser.engines = null;
- }
-
- this.isBusy = true;
-
- if (!(aStateFlags & nsIWebProgressListener.STATE_RESTORING)) {
- this._busyUI = true;
-
- // Turn the throbber on.
- if (this.throbberElement)
- this.throbberElement.setAttribute("busy", "true");
-
- // XXX: This needs to be based on window activity...
- this.stopCommand.removeAttribute("disabled");
- CombinedStopReload.switchToStop();
- }
- }
- else if (aStateFlags & nsIWebProgressListener.STATE_STOP) {
- // This (thanks to the filter) is a network stop or the last
- // request stop outside of loading the document, stop throbbers
- // and progress bars and such
- if (aRequest) {
- let msg = "";
- let location;
- // Get the URI either from a channel or a pseudo-object
- if (aRequest instanceof nsIChannel || "URI" in aRequest) {
- location = aRequest.URI;
-
- // For keyword URIs clear the user typed value since they will be changed into real URIs
- if (location.scheme == "keyword" && aWebProgress.isTopLevel)
- gBrowser.userTypedValue = null;
-
- if (location.spec != "about:blank") {
- switch (aStatus) {
- case Components.results.NS_ERROR_NET_TIMEOUT:
- msg = gNavigatorBundle.getString("nv_timeout");
- break;
- }
- }
- }
-
- this.status = "";
- this.setDefaultStatus(msg);
-
- // Disable menu entries for images, enable otherwise
- if (!gMultiProcessBrowser && content.document && BrowserUtils.mimeTypeIsTextBased(content.document.contentType))
- this.isImage.removeAttribute('disabled');
- else
- this.isImage.setAttribute('disabled', 'true');
- }
-
- this.isBusy = false;
-
- if (this._busyUI) {
- this._busyUI = false;
-
- // Turn the throbber off.
- if (this.throbberElement)
- this.throbberElement.removeAttribute("busy");
-
- this.stopCommand.setAttribute("disabled", "true");
- CombinedStopReload.switchToReload(aRequest instanceof Ci.nsIRequest);
- }
- }
- },
-
- onLocationChange: function (aWebProgress, aRequest, aLocationURI, aFlags) {
- var location = aLocationURI ? aLocationURI.spec : "";
- this._hostChanged = true;
-
- // If displayed, hide the form validation popup.
- FormValidationHandler.hidePopup();
-
- let pageTooltip = document.getElementById("aHTMLTooltip");
- let tooltipNode = pageTooltip.triggerNode;
- if (tooltipNode) {
- // Optimise for the common case
- if (aWebProgress.isTopLevel) {
- pageTooltip.hidePopup();
- }
- else {
- for (let tooltipWindow = tooltipNode.ownerDocument.defaultView;
- tooltipWindow != tooltipWindow.parent;
- tooltipWindow = tooltipWindow.parent) {
- if (tooltipWindow == aWebProgress.DOMWindow) {
- pageTooltip.hidePopup();
- break;
- }
- }
- }
- }
-
- // Disable menu entries for images, enable otherwise
- if (!gMultiProcessBrowser && content.document && BrowserUtils.mimeTypeIsTextBased(content.document.contentType))
- this.isImage.removeAttribute('disabled');
- else
- this.isImage.setAttribute('disabled', 'true');
-
- this.hideOverLinkImmediately = true;
- this.setOverLink("", null);
- this.hideOverLinkImmediately = false;
-
- // We should probably not do this if the value has changed since the user
- // searched
- // Update urlbar only if a new page was loaded on the primary content area
- // Do not update urlbar if there was a subframe navigation
-
- var browser = gBrowser.selectedBrowser;
- if (aWebProgress.isTopLevel) {
- if ((location == "about:blank" && (gMultiProcessBrowser || !content.opener)) ||
- location == "") { // Second condition is for new tabs, otherwise
- // reload function is enabled until tab is refreshed.
- this.reloadCommand.setAttribute("disabled", "true");
- } else {
- this.reloadCommand.removeAttribute("disabled");
- }
-
- if (gURLBar) {
- URLBarSetURI(aLocationURI);
-
- // Update starring UI
- BookmarkingUI.updateStarState();
- }
-
- // Show or hide browser chrome based on the whitelist
- if (this.hideChromeForLocation(location)) {
- document.documentElement.setAttribute("disablechrome", "true");
- } else {
- let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
- if (ss.getTabValue(gBrowser.selectedTab, "appOrigin"))
- document.documentElement.setAttribute("disablechrome", "true");
- else
- document.documentElement.removeAttribute("disablechrome");
- }
-
- // Utility functions for disabling find
- var shouldDisableFind = function shouldDisableFind(aDocument) {
- let docElt = aDocument.documentElement;
- return docElt && docElt.getAttribute("disablefastfind") == "true";
- }
-
- var disableFindCommands = function disableFindCommands(aDisable) {
- let findCommands = [document.getElementById("cmd_find"),
- document.getElementById("cmd_findAgain"),
- document.getElementById("cmd_findPrevious")];
- for (let elt of findCommands) {
- if (aDisable)
- elt.setAttribute("disabled", "true");
- else
- elt.removeAttribute("disabled");
- }
- if (gFindBarInitialized) {
- if (!gFindBar.hidden && aDisable) {
- gFindBar.hidden = true;
- this._findbarTemporarilyHidden = true;
- } else if (this._findbarTemporarilyHidden && !aDisable) {
- gFindBar.hidden = false;
- this._findbarTemporarilyHidden = false;
- }
- }
- }.bind(this);
-
- var onContentRSChange = function onContentRSChange(e) {
- if (e.target.readyState != "interactive" && e.target.readyState != "complete")
- return;
-
- e.target.removeEventListener("readystatechange", onContentRSChange);
- disableFindCommands(shouldDisableFind(e.target));
- }
-
- // Disable find commands in documents that ask for them to be disabled.
- if (!gMultiProcessBrowser && aLocationURI &&
- (aLocationURI.schemeIs("about") || aLocationURI.schemeIs("chrome"))) {
- // Don't need to re-enable/disable find commands for same-document location changes
- // (e.g. the replaceStates in about:addons)
- if (!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT)) {
- if (content.document.readyState == "interactive" || content.document.readyState == "complete")
- disableFindCommands(shouldDisableFind(content.document));
- else {
- content.document.addEventListener("readystatechange", onContentRSChange);
- }
- }
- } else
- disableFindCommands(false);
-
- if (gFindBarInitialized) {
- if (gFindBar.findMode != gFindBar.FIND_NORMAL) {
- // Close the Find toolbar if we're in old-style TAF mode
- gFindBar.close();
- }
-
- // XXX
- // See: https://github.com/MoonchildProductions/Pale-Moon/issues/364
- // An actual preference: findbar.highlightAll
- /*
- if (!(gPrefService.getBoolPref("accessibility.typeaheadfind.highlightallremember") ||
- gPrefService.getBoolPref("accessibility.typeaheadfind.highlightallbydefault"))) {
- // fix bug 253793 - turn off highlight when page changes
- gFindBar.getElement("highlight").checked = false;
- }
- */
- }
- }
- UpdateBackForwardCommands(gBrowser.webNavigation);
-
- gGestureSupport.restoreRotationState();
-
- // See bug 358202, when tabs are switched during a drag operation,
- // timers don't fire on windows (bug 203573)
- if (aRequest)
- setTimeout(function () { XULBrowserWindow.asyncUpdateUI(); }, 0);
- else
- this.asyncUpdateUI();
- },
-
- asyncUpdateUI: function () {
- FeedHandler.updateFeeds();
- },
-
- hideChromeForLocation: function(aLocation) {
- aLocation = aLocation.toLowerCase();
- return this.inContentWhitelist.some(function(aSpec) {
- return aSpec == aLocation;
- });
- },
-
- onStatusChange: function (aWebProgress, aRequest, aStatus, aMessage) {
- this.status = aMessage;
- this.updateStatusField();
- },
-
- // Properties used to cache security state used to update the UI
- _state: null,
- _hostChanged: false, // onLocationChange will flip this bit
-
- onSecurityChange: function (aWebProgress, aRequest, aState) {
- // Don't need to do anything if the data we use to update the UI hasn't
- // changed
- if (this._state == aState &&
- !this._hostChanged) {
-#ifdef DEBUG
- try {
- var contentHost = gBrowser.contentWindow.location.host;
- if (this._host !== undefined && this._host != contentHost) {
- Components.utils.reportError(
- "ASSERTION: browser.js host is inconsistent. Content window has " +
- "<" + contentHost + "> but cached host is <" + this._host + ">.\n"
- );
- }
- } catch (ex) {}
-#endif
- return;
- }
- this._state = aState;
-
-#ifdef DEBUG
- try {
- this._host = gBrowser.contentWindow.location.host;
- } catch(ex) {
- this._host = null;
- }
-#endif
-
- this._hostChanged = false;
-
- // aState is defined as a bitmask that may be extended in the future.
- // We filter out any unknown bits before testing for known values.
- const wpl = Components.interfaces.nsIWebProgressListener;
- const wpl_security_bits = wpl.STATE_IS_SECURE |
- wpl.STATE_IS_BROKEN |
- wpl.STATE_IS_INSECURE;
- var level;
-
- switch (this._state & wpl_security_bits) {
- case wpl.STATE_IS_SECURE:
- level = "high";
- break;
- case wpl.STATE_IS_BROKEN:
- level = "broken";
- break;
- }
-
- if (level) {
- // We don't style the Location Bar based on the the 'level' attribute
- // anymore, but still set it for third-party themes.
- if (gURLBar)
- gURLBar.setAttribute("level", level);
- } else {
- if (gURLBar)
- gURLBar.removeAttribute("level");
- }
-
- if (gMultiProcessBrowser)
- return;
-
- // Don't pass in the actual location object, since it can cause us to
- // hold on to the window object too long. Just pass in the fields we
- // care about. (bug 424829)
- var location = gBrowser.contentWindow.location;
- var locationObj = {};
- try {
- // about:blank can be used by webpages so pretend it is http
- locationObj.protocol = location == "about:blank" ? "http:" : location.protocol;
- locationObj.host = location.host;
- locationObj.hostname = location.hostname;
- locationObj.port = location.port;
- } catch (ex) {
- // Can sometimes throw if the URL being visited has no host/hostname,
- // e.g. about:blank. The _state for these pages means we won't need these
- // properties anyways, though.
- }
- gIdentityHandler.checkIdentity(this._state, locationObj);
- },
-
- // simulate all change notifications after switching tabs
- onUpdateCurrentBrowser: function XWB_onUpdateCurrentBrowser(aStateFlags, aStatus, aMessage, aTotalProgress) {
- if (FullZoom.updateBackgroundTabs)
- FullZoom.onLocationChange(gBrowser.currentURI, true);
- var nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
- var loadingDone = aStateFlags & nsIWebProgressListener.STATE_STOP;
- // use a pseudo-object instead of a (potentially nonexistent) channel for getting
- // a correct error message - and make sure that the UI is always either in
- // loading (STATE_START) or done (STATE_STOP) mode
- this.onStateChange(
- gBrowser.webProgress,
- { URI: gBrowser.currentURI },
- loadingDone ? nsIWebProgressListener.STATE_STOP : nsIWebProgressListener.STATE_START,
- aStatus
- );
- // status message and progress value are undefined if we're done with loading
- if (loadingDone)
- return;
- this.onStatusChange(gBrowser.webProgress, null, 0, aMessage);
- }
-};
-
-var LinkTargetDisplay = {
- get DELAY_SHOW() {
- delete this.DELAY_SHOW;
- return this.DELAY_SHOW = Services.prefs.getIntPref("browser.overlink-delay");
- },
-
- DELAY_HIDE: 250,
- _timer: 0,
-
- get _isVisible () XULBrowserWindow.statusTextField.label != "",
-
- update: function () {
- clearTimeout(this._timer);
- window.removeEventListener("mousemove", this, true);
-
- if (!XULBrowserWindow.overLink) {
- if (XULBrowserWindow.hideOverLinkImmediately)
- this._hide();
- else
- this._timer = setTimeout(this._hide.bind(this), this.DELAY_HIDE);
- return;
- }
-
- if (this._isVisible) {
- XULBrowserWindow.updateStatusField();
- } else {
- // Let the display appear when the mouse doesn't move within the delay
- this._showDelayed();
- window.addEventListener("mousemove", this, true);
- }
- },
-
- handleEvent: function (event) {
- switch (event.type) {
- case "mousemove":
- // Restart the delay since the mouse was moved
- clearTimeout(this._timer);
- this._showDelayed();
- break;
- }
- },
-
- _showDelayed: function () {
- this._timer = setTimeout(function (self) {
- XULBrowserWindow.updateStatusField();
- window.removeEventListener("mousemove", self, true);
- }, this.DELAY_SHOW, this);
- },
-
- _hide: function () {
- clearTimeout(this._timer);
-
- XULBrowserWindow.updateStatusField();
- }
-};
-
-var CombinedStopReload = {
- init: function () {
- if (this._initialized)
- return;
-
- var urlbar = document.getElementById("urlbar-container");
- var reload = document.getElementById("reload-button");
- var stop = document.getElementById("stop-button");
-
- if (urlbar) {
- if (urlbar.parentNode.getAttribute("mode") != "icons" ||
- !reload || urlbar.nextSibling != reload ||
- !stop || reload.nextSibling != stop)
- urlbar.removeAttribute("combined");
- else {
- urlbar.setAttribute("combined", "true");
- reload = document.getElementById("urlbar-reload-button");
- stop = document.getElementById("urlbar-stop-button");
- }
- }
- if (!stop || !reload || reload.nextSibling != stop)
- return;
-
- this._initialized = true;
- if (XULBrowserWindow.stopCommand.getAttribute("disabled") != "true")
- reload.setAttribute("displaystop", "true");
- stop.addEventListener("click", this, false);
- this.reload = reload;
- this.stop = stop;
- },
-
- uninit: function () {
- if (!this._initialized)
- return;
-
- this._cancelTransition();
- this._initialized = false;
- this.stop.removeEventListener("click", this, false);
- this.reload = null;
- this.stop = null;
- },
-
- handleEvent: function (event) {
- // the only event we listen to is "click" on the stop button
- if (event.button == 0 &&
- !this.stop.disabled)
- this._stopClicked = true;
- },
-
- switchToStop: function () {
- if (!this._initialized)
- return;
-
- this._cancelTransition();
- this.reload.setAttribute("displaystop", "true");
- },
-
- switchToReload: function (aDelay) {
- if (!this._initialized)
- return;
-
- this.reload.removeAttribute("displaystop");
-
- if (!aDelay || this._stopClicked) {
- this._stopClicked = false;
- this._cancelTransition();
- this.reload.disabled = XULBrowserWindow.reloadCommand
- .getAttribute("disabled") == "true";
- return;
- }
-
- if (this._timer)
- return;
-
- // Temporarily disable the reload button to prevent the user from
- // accidentally reloading the page when intending to click the stop button
- this.reload.disabled = true;
- this._timer = setTimeout(function (self) {
- self._timer = 0;
- self.reload.disabled = XULBrowserWindow.reloadCommand
- .getAttribute("disabled") == "true";
- }, 650, this);
- },
-
- _cancelTransition: function () {
- if (this._timer) {
- clearTimeout(this._timer);
- this._timer = 0;
- }
- }
-};
-
-var TabsProgressListener = {
- onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
-
- // Attach a listener to watch for "click" events bubbling up from error
- // pages and other similar page. This lets us fix bugs like 401575 which
- // require error page UI to do privileged things, without letting error
- // pages have any privilege themselves.
- // We can't look for this during onLocationChange since at that point the
- // document URI is not yet the about:-uri of the error page.
-
- let doc = gMultiProcessBrowser ? null : aWebProgress.DOMWindow.document;
- if (!gMultiProcessBrowser &&
- aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
- Components.isSuccessCode(aStatus) &&
- doc.documentURI.startsWith("about:") &&
- !doc.documentURI.toLowerCase().startsWith("about:blank") &&
- !doc.documentElement.hasAttribute("hasBrowserHandlers")) {
- // STATE_STOP may be received twice for documents, thus store an
- // attribute to ensure handling it just once.
- doc.documentElement.setAttribute("hasBrowserHandlers", "true");
- aBrowser.addEventListener("click", BrowserOnClick, true);
- aBrowser.addEventListener("pagehide", function onPageHide(event) {
- if (event.target.defaultView.frameElement)
- return;
- aBrowser.removeEventListener("click", BrowserOnClick, true);
- aBrowser.removeEventListener("pagehide", onPageHide, true);
- if (event.target.documentElement)
- event.target.documentElement.removeAttribute("hasBrowserHandlers");
- }, true);
-
- // We also want to make changes to page UI for unprivileged about pages.
- BrowserOnAboutPageLoad(doc);
- }
- },
-
- onLocationChange: function (aBrowser, aWebProgress, aRequest, aLocationURI,
- aFlags) {
- // Filter out location changes caused by anchor navigation
- // or history.push/pop/replaceState.
- if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT)
- return;
-
- // Only need to call locationChange if the PopupNotifications object
- // for this window has already been initialized (i.e. its getter no
- // longer exists)
- if (!Object.getOwnPropertyDescriptor(window, "PopupNotifications").get)
- PopupNotifications.locationChange(aBrowser);
-
- gBrowser.getNotificationBox(aBrowser).removeTransientNotifications();
-
- // Filter out location changes in sub documents.
- if (aWebProgress.isTopLevel) {
- // Initialize the click-to-play state.
- aBrowser._clickToPlayPluginsActivated = new Map();
- aBrowser._clickToPlayAllPluginsActivated = false;
- aBrowser._pluginScriptedState = gPluginHandler.PLUGIN_SCRIPTED_STATE_NONE;
-
- FullZoom.onLocationChange(aLocationURI, false, aBrowser);
- }
- },
-
- onRefreshAttempted: function (aBrowser, aWebProgress, aURI, aDelay, aSameURI) {
- if (gPrefService.getBoolPref("accessibility.blockautorefresh")) {
- let brandBundle = document.getElementById("bundle_brand");
- let brandShortName = brandBundle.getString("brandShortName");
- let refreshButtonText =
- gNavigatorBundle.getString("refreshBlocked.goButton");
- let refreshButtonAccesskey =
- gNavigatorBundle.getString("refreshBlocked.goButton.accesskey");
- let message =
- gNavigatorBundle.getFormattedString(aSameURI ? "refreshBlocked.refreshLabel"
- : "refreshBlocked.redirectLabel",
- [brandShortName]);
- let docShell = aWebProgress.DOMWindow
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell);
- let notificationBox = gBrowser.getNotificationBox(aBrowser);
- let notification = notificationBox.getNotificationWithValue("refresh-blocked");
- if (notification) {
- notification.label = message;
- notification.refreshURI = aURI;
- notification.delay = aDelay;
- notification.docShell = docShell;
- } else {
- let buttons = [{
- label: refreshButtonText,
- accessKey: refreshButtonAccesskey,
- callback: function (aNotification, aButton) {
- var refreshURI = aNotification.docShell
- .QueryInterface(Ci.nsIRefreshURI);
- refreshURI.forceRefreshURI(aNotification.refreshURI,
- aNotification.delay, true);
- }
- }];
- notification =
- notificationBox.appendNotification(message, "refresh-blocked",
- "chrome://browser/skin/Info.png",
- notificationBox.PRIORITY_INFO_MEDIUM,
- buttons);
- notification.refreshURI = aURI;
- notification.delay = aDelay;
- notification.docShell = docShell;
- }
- return false;
- }
- return true;
- }
-}
-
-function nsBrowserAccess() { }
-
-nsBrowserAccess.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserDOMWindow, Ci.nsISupports]),
-
- openURI: function (aURI, aOpener, aWhere, aContext) {
- var newWindow = null;
- var isExternal = !!(aContext & Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
-
- if (aOpener && isExternal) {
- Cu.reportError("nsBrowserAccess.openURI did not expect an opener to be " +
- "passed if the context is OPEN_EXTERNAL.");
- throw Cr.NS_ERROR_FAILURE;
- }
-
- if (isExternal && aURI && aURI.schemeIs("chrome")) {
- dump("use -chrome command-line option to load external chrome urls\n");
- return null;
- }
-
- if (aWhere == Ci.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW) {
- if (isExternal &&
- gPrefService.prefHasUserValue("browser.link.open_newwindow.override.external"))
- aWhere = gPrefService.getIntPref("browser.link.open_newwindow.override.external");
- else
- aWhere = gPrefService.getIntPref("browser.link.open_newwindow");
- }
-
- let referrer = aOpener ? makeURI(aOpener.location.href) : null;
- let triggeringPrincipal = null;
- let referrerPolicy = Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT;
- if (aOpener && aOpener.document) {
- referrerPolicy = aOpener.document.referrerPolicy;
- triggeringPrincipal = aOpener.document.nodePrincipal;
- }
-
- switch (aWhere) {
- case Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW :
- // FIXME: Bug 408379. So how come this doesn't send the
- // referrer like the other loads do?
- var url = aURI ? aURI.spec : "about:blank";
- // Pass all params to openDialog to ensure that "url" isn't passed through
- // loadOneOrMoreURIs, which splits based on "|"
- newWindow = openDialog(getBrowserURL(), "_blank", "all,dialog=no", url, null, null, null);
- break;
- case Ci.nsIBrowserDOMWindow.OPEN_NEWTAB :
- let win, needToFocusWin;
-
- // try the current window. if we're in a popup, fall back on the most recent browser window
- if (window.toolbar.visible)
- win = window;
- else {
- let isPrivate = PrivateBrowsingUtils.isWindowPrivate(aOpener || window);
- win = RecentWindow.getMostRecentBrowserWindow({private: isPrivate});
- needToFocusWin = true;
- }
-
- if (!win) {
- // we couldn't find a suitable window, a new one needs to be opened.
- return null;
- }
-
- if (isExternal && (!aURI || aURI.spec == "about:blank")) {
- win.BrowserOpenTab(); // this also focuses the location bar
- win.focus();
- newWindow = win.content;
- break;
- }
-
- let loadInBackground = gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground");
- let openerWindow = (aContext & Ci.nsIBrowserDOMWindow.OPEN_NO_OPENER) ? null : aOpener;
-
- let tab = win.gBrowser.loadOneTab(aURI ? aURI.spec : "about:blank", {
- triggeringPrincipal: triggeringPrincipal,
- referrerURI: referrer,
- referrerPolicy: referrerPolicy,
- fromExternal: isExternal,
- inBackground: loadInBackground,
- opener: openerWindow });
- let browser = win.gBrowser.getBrowserForTab(tab);
-
- if (gPrefService.getBoolPref("browser.tabs.noWindowActivationOnExternal")) {
- isExternal = false; // this is a hack, but it works
- }
-
- newWindow = browser.contentWindow;
- if (needToFocusWin || (!loadInBackground && isExternal))
- newWindow.focus();
- break;
- default : // OPEN_CURRENTWINDOW or an illegal value
- newWindow = content;
- if (aURI) {
- let loadflags = isExternal ?
- Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL :
- Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
- gBrowser.loadURIWithFlags(aURI.spec, {
- flags: loadflags,
- triggeringPrincipal: triggeringPrincipal,
- referrerURI: referrer,
- referrerPolicy: referrerPolicy,
- });
- }
- if (!gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground"))
- window.focus();
- }
- return newWindow;
- },
-
- isTabContentWindow: function (aWindow) {
- return gBrowser.browsers.some(function (browser) browser.contentWindow == aWindow);
- }
-}
-
-function onViewToolbarsPopupShowing(aEvent, aInsertPoint) {
- var popup = aEvent.target;
- if (popup != aEvent.currentTarget)
- return;
-
- // Empty the menu
- for (var i = popup.childNodes.length-1; i >= 0; --i) {
- var deadItem = popup.childNodes[i];
- if (deadItem.hasAttribute("toolbarId"))
- popup.removeChild(deadItem);
- }
-
- var firstMenuItem = aInsertPoint || popup.firstChild;
-
- let toolbarNodes = Array.slice(gNavToolbox.childNodes);
- toolbarNodes.push(document.getElementById("addon-bar"));
-
- for (let toolbar of toolbarNodes) {
- let toolbarName = toolbar.getAttribute("toolbarname");
- if (toolbarName) {
- let menuItem = document.createElement("menuitem");
- let hidingAttribute = toolbar.getAttribute("type") == "menubar" ?
- "autohide" : "collapsed";
- menuItem.setAttribute("id", "toggle_" + toolbar.id);
- menuItem.setAttribute("toolbarId", toolbar.id);
- menuItem.setAttribute("type", "checkbox");
- menuItem.setAttribute("label", toolbarName);
- menuItem.setAttribute("checked", toolbar.getAttribute(hidingAttribute) != "true");
- if (popup.id != "appmenu_customizeMenu")
- menuItem.setAttribute("accesskey", toolbar.getAttribute("accesskey"));
- if (popup.id != "toolbar-context-menu")
- menuItem.setAttribute("key", toolbar.getAttribute("key"));
-
- popup.insertBefore(menuItem, firstMenuItem);
-
- menuItem.addEventListener("command", onViewToolbarCommand, false);
- }
- }
-}
-
-function onViewToolbarCommand(aEvent) {
- var toolbarId = aEvent.originalTarget.getAttribute("toolbarId");
- var toolbar = document.getElementById(toolbarId);
- var isVisible = aEvent.originalTarget.getAttribute("checked") == "true";
- setToolbarVisibility(toolbar, isVisible);
-}
-
-function setToolbarVisibility(toolbar, isVisible) {
- var hidingAttribute = toolbar.getAttribute("type") == "menubar" ?
- "autohide" : "collapsed";
-
- toolbar.setAttribute(hidingAttribute, !isVisible);
- document.persist(toolbar.id, hidingAttribute);
-
- // Customizable toolbars - persist the hiding attribute.
- if (toolbar.hasAttribute("customindex")) {
- var toolbox = toolbar.parentNode;
- var name = toolbar.getAttribute("toolbarname");
- if (toolbox.toolbarset) {
- try {
- // Checking all attributes starting with "toolbar".
- Array.prototype.slice.call(toolbox.toolbarset.attributes, 0)
- .find(x => {
- if (x.name.startsWith("toolbar")) {
- var toolbarInfo = x.value;
- var infoSplit = toolbarInfo.split(gToolbarInfoSeparators[0]);
- if (infoSplit[0] == name) {
- infoSplit[1] = [
- infoSplit[1].split(gToolbarInfoSeparators[1], 1), !isVisible
- ].join(gToolbarInfoSeparators[1]);
- toolbox.toolbarset.setAttribute(
- x.name, infoSplit.join(gToolbarInfoSeparators[0]));
- document.persist(toolbox.toolbarset.id, x.name);
- }
- }
- });
- } catch (e) {
- Components.utils.reportError(
- "Customizable toolbars - persist the hiding attribute: " + e);
- }
- }
- }
-
- PlacesToolbarHelper.init();
- BookmarkingUI.onToolbarVisibilityChange();
- gBrowser.updateWindowResizers();
-
-#ifdef MENUBAR_CAN_AUTOHIDE
- updateAppButtonDisplay();
-#endif
-
- if (isVisible)
- ToolbarIconColor.inferFromText();
-}
-
-var AudioIndicator = {
- init: function () {
- Services.prefs.addObserver(this._prefName, this, false);
- this.syncUI();
- },
-
- uninit: function () {
- Services.prefs.removeObserver(this._prefName, this);
- },
-
- toggle: function () {
- this.enabled = !Services.prefs.getBoolPref(this._prefName);
- },
-
- syncUI: function () {
- document.getElementById("context_toggleMuteTab").setAttribute("hidden", this.enabled);
- document.getElementById("key_toggleMute").setAttribute("disabled", this.enabled);
- },
-
- get enabled () {
- return !Services.prefs.getBoolPref(this._prefName);
- },
-
- set enabled (val) {
- Services.prefs.setBoolPref(this._prefName, !!val);
- return val;
- },
-
- observe: function (subject, topic, data) {
- if (topic == "nsPref:changed")
- this.syncUI();
- },
-
- _prefName: "browser.tabs.showAudioPlayingIcon"
-}
-
-var TabsOnTop = {
- init: function TabsOnTop_init() {
- Services.prefs.addObserver(this._prefName, this, false);
-// Pale Moon: Stop Being a Derp, Mozilla (#3)
- // Only show the toggle UI if the user disabled tabs on top.
-// if (Services.prefs.getBoolPref(this._prefName)) {
-// for (let item of document.querySelectorAll("menuitem[command=cmd_ToggleTabsOnTop]"))
-// item.parentNode.removeChild(item);
-// }
- },
-
- uninit: function TabsOnTop_uninit() {
- Services.prefs.removeObserver(this._prefName, this);
- },
-
- toggle: function () {
- this.enabled = !Services.prefs.getBoolPref(this._prefName);
- },
-
- syncUI: function () {
- let userEnabled = Services.prefs.getBoolPref(this._prefName);
- let enabled = userEnabled && gBrowser.tabContainer.visible;
-
- document.getElementById("cmd_ToggleTabsOnTop")
- .setAttribute("checked", userEnabled);
-
- document.documentElement.setAttribute("tabsontop", enabled);
- document.getElementById("navigator-toolbox").setAttribute("tabsontop", enabled);
- document.getElementById("TabsToolbar").setAttribute("tabsontop", enabled);
- document.getElementById("nav-bar").setAttribute("tabsontop", enabled);
- gBrowser.tabContainer.setAttribute("tabsontop", enabled);
- TabsInTitlebar.allowedBy("tabs-on-top", enabled);
- },
-
- get enabled () {
- return gNavToolbox.getAttribute("tabsontop") == "true";
- },
-
- set enabled (val) {
- Services.prefs.setBoolPref(this._prefName, !!val);
- return val;
- },
-
- observe: function (subject, topic, data) {
- if (topic == "nsPref:changed")
- this.syncUI();
- },
-
- _prefName: "browser.tabs.onTop"
-}
-
-var TabsInTitlebar = {
- init: function () {
-#ifdef CAN_DRAW_IN_TITLEBAR
- this._readPref();
- Services.prefs.addObserver(this._prefName, this, false);
-
- // Don't trust the initial value of the sizemode attribute; wait for
- // the resize event (handled in tabbrowser.xml).
- this.allowedBy("sizemode", false);
-
- this._initialized = true;
-#endif
- },
-
- allowedBy: function (condition, allow) {
-#ifdef CAN_DRAW_IN_TITLEBAR
- if (allow) {
- if (condition in this._disallowed) {
- delete this._disallowed[condition];
- this._update();
- }
- } else {
- if (!(condition in this._disallowed)) {
- this._disallowed[condition] = null;
- this._update();
- }
- }
-#endif
- },
-
- get enabled() {
- return document.documentElement.getAttribute("tabsintitlebar") == "true";
- },
-
-#ifdef CAN_DRAW_IN_TITLEBAR
- observe: function (subject, topic, data) {
- if (topic == "nsPref:changed")
- this._readPref();
- },
-
- _initialized: false,
- _disallowed: {},
- _prefName: "browser.tabs.drawInTitlebar",
-
- _readPref: function () {
- this.allowedBy("pref",
- Services.prefs.getBoolPref(this._prefName));
- },
-
- _update: function () {
- function $(id) document.getElementById(id);
- function rect(ele) ele.getBoundingClientRect();
-
- if (!this._initialized || window.fullScreen)
- return;
-
- let allowed = true;
- for (let something in this._disallowed) {
- allowed = false;
- break;
- }
-
- if (allowed == this.enabled)
- return;
-
- let titlebar = $("titlebar");
-
- if (allowed) {
- let tabsToolbar = $("TabsToolbar");
-
-#ifdef MENUBAR_CAN_AUTOHIDE
- let appmenuButtonBox = $("appmenu-button-container");
- this._sizePlaceholder("appmenu-button", rect(appmenuButtonBox).width);
-#endif
- let captionButtonsBox = $("titlebar-buttonbox");
- this._sizePlaceholder("caption-buttons", rect(captionButtonsBox).width);
-
- let tabsToolbarRect = rect(tabsToolbar);
- let titlebarTop = rect($("titlebar-content")).top;
- titlebar.style.marginBottom = - Math.min(tabsToolbarRect.top - titlebarTop,
- tabsToolbarRect.height) + "px";
-
- document.documentElement.setAttribute("tabsintitlebar", "true");
-
- if (!this._draghandle) {
- let tmp = {};
- Components.utils.import("resource://gre/modules/WindowDraggingUtils.jsm", tmp);
- this._draghandle = new tmp.WindowDraggingElement(tabsToolbar);
- this._draghandle.mouseDownCheck = function () {
- return !this._dragBindingAlive && TabsInTitlebar.enabled;
- };
- }
- } else {
- document.documentElement.removeAttribute("tabsintitlebar");
-
- titlebar.style.marginBottom = "";
- }
-
- ToolbarIconColor.inferFromText();
- },
-
- _sizePlaceholder: function (type, width) {
- Array.forEach(document.querySelectorAll(".titlebar-placeholder[type='"+ type +"']"),
- function (node) { node.width = width; });
- },
-#endif
-
- uninit: function () {
-#ifdef CAN_DRAW_IN_TITLEBAR
- this._initialized = false;
- Services.prefs.removeObserver(this._prefName, this);
-#endif
- }
-};
-
-#ifdef MENUBAR_CAN_AUTOHIDE
-function updateAppButtonDisplay() {
- var displayAppButton =
- !gInPrintPreviewMode &&
- window.menubar.visible &&
- document.getElementById("toolbar-menubar").getAttribute("autohide") == "true";
-
-#ifdef CAN_DRAW_IN_TITLEBAR
- document.getElementById("titlebar").hidden = !displayAppButton;
-
- if (displayAppButton)
- document.documentElement.setAttribute("chromemargin", "0,2,2,2");
- else
- document.documentElement.removeAttribute("chromemargin");
-
- TabsInTitlebar.allowedBy("drawing-in-titlebar", displayAppButton);
-#else
- document.getElementById("appmenu-toolbar-button").hidden =
- !displayAppButton;
-#endif
-}
-#endif
-
-#ifdef CAN_DRAW_IN_TITLEBAR
-function onTitlebarMaxClick() {
- if (window.windowState == window.STATE_MAXIMIZED)
- window.restore();
- else
- window.maximize();
-}
-#endif
-
-function displaySecurityInfo()
-{
- BrowserPageInfo(null, "securityTab");
-}
-
-/**
- * Opens or closes the sidebar identified by commandID.
- *
- * @param commandID a string identifying the sidebar to toggle; see the
- * note below. (Optional if a sidebar is already open.)
- * @param forceOpen boolean indicating whether the sidebar should be
- * opened regardless of its current state (optional).
- * @note
- * We expect to find a xul:broadcaster element with the specified ID.
- * The following attributes on that element may be used and/or modified:
- * - id (required) the string to match commandID. The convention
- * is to use this naming scheme: 'view<sidebar-name>Sidebar'.
- * - sidebarurl (required) specifies the URL to load in this sidebar.
- * - sidebartitle or label (in that order) specify the title to
- * display on the sidebar.
- * - checked indicates whether the sidebar is currently displayed.
- * Note that toggleSidebar updates this attribute when
- * it changes the sidebar's visibility.
- * - group this attribute must be set to "sidebar".
- */
-function toggleSidebar(commandID, forceOpen) {
-
- var sidebarBox = document.getElementById("sidebar-box");
- if (!commandID)
- commandID = sidebarBox.getAttribute("sidebarcommand");
-
- var sidebarBroadcaster = document.getElementById(commandID);
- var sidebar = document.getElementById("sidebar"); // xul:browser
- var sidebarTitle = document.getElementById("sidebar-title");
- var sidebarSplitter = document.getElementById("sidebar-splitter");
-
- if (sidebarBroadcaster.getAttribute("checked") == "true") {
- if (!forceOpen) {
- // Replace the document currently displayed in the sidebar with about:blank
- // so that we can free memory by unloading the page. We need to explicitly
- // create a new content viewer because the old one doesn't get destroyed
- // until about:blank has loaded (which does not happen as long as the
- // element is hidden).
- sidebar.setAttribute("src", "about:blank");
- sidebar.docShell.createAboutBlankContentViewer(null);
-
- sidebarBroadcaster.removeAttribute("checked");
- sidebarBox.setAttribute("sidebarcommand", "");
- sidebarTitle.value = "";
- sidebarBox.hidden = true;
- sidebarSplitter.hidden = true;
- gBrowser.selectedBrowser.focus();
- } else {
- fireSidebarFocusedEvent();
- }
- return;
- }
-
- // now we need to show the specified sidebar
-
- // ..but first update the 'checked' state of all sidebar broadcasters
- var broadcasters = document.getElementsByAttribute("group", "sidebar");
- for (let broadcaster of broadcasters) {
- // skip elements that observe sidebar broadcasters and random
- // other elements
- if (broadcaster.localName != "broadcaster")
- continue;
-
- if (broadcaster != sidebarBroadcaster)
- broadcaster.removeAttribute("checked");
- else
- sidebarBroadcaster.setAttribute("checked", "true");
- }
-
- sidebarBox.hidden = false;
- sidebarSplitter.hidden = false;
-
- var url = sidebarBroadcaster.getAttribute("sidebarurl");
- var title = sidebarBroadcaster.getAttribute("sidebartitle");
- if (!title)
- title = sidebarBroadcaster.getAttribute("label");
- sidebar.setAttribute("src", url); // kick off async load
- sidebarBox.setAttribute("sidebarcommand", sidebarBroadcaster.id);
- sidebarTitle.value = title;
-
- // We set this attribute here in addition to setting it on the <browser>
- // element itself, because the code in gBrowserInit.onUnload persists this
- // attribute, not the "src" of the <browser id="sidebar">. The reason it
- // does that is that we want to delay sidebar load a bit when a browser
- // window opens. See delayedStartup().
- sidebarBox.setAttribute("src", url);
-
- if (sidebar.contentDocument.location.href != url)
- sidebar.addEventListener("load", sidebarOnLoad, true);
- else // older code handled this case, so we do it too
- fireSidebarFocusedEvent();
-}
-
-function sidebarOnLoad(event) {
- var sidebar = document.getElementById("sidebar");
- sidebar.removeEventListener("load", sidebarOnLoad, true);
- // We're handling the 'load' event before it bubbles up to the usual
- // (non-capturing) event handlers. Let it bubble up before firing the
- // SidebarFocused event.
- setTimeout(fireSidebarFocusedEvent, 0);
-}
-
-/**
- * Fire a "SidebarFocused" event on the sidebar's |window| to give the sidebar
- * a chance to adjust focus as needed. An additional event is needed, because
- * we don't want to focus the sidebar when it's opened on startup or in a new
- * window, only when the user opens the sidebar.
- */
-function fireSidebarFocusedEvent() {
- var sidebar = document.getElementById("sidebar");
- var event = document.createEvent("Events");
- event.initEvent("SidebarFocused", true, false);
- sidebar.contentWindow.dispatchEvent(event);
-}
-
-var gHomeButton = {
- prefDomain: "browser.startup.homepage",
- observe: function (aSubject, aTopic, aPrefName)
- {
- if (aTopic != "nsPref:changed" || aPrefName != this.prefDomain)
- return;
-
- this.updateTooltip();
- },
-
- updateTooltip: function (homeButton)
- {
- if (!homeButton)
- homeButton = document.getElementById("home-button");
- if (homeButton) {
- var homePage = this.getHomePage();
- homePage = homePage.replace(/\|/g,', ');
- if (homePage.toLowerCase() == "about:home")
- homeButton.setAttribute("tooltiptext", homeButton.getAttribute("aboutHomeOverrideTooltip"));
- else
- homeButton.setAttribute("tooltiptext", homePage);
- }
- },
-
- getHomePage: function ()
- {
- var url;
- try {
- url = gPrefService.getComplexValue(this.prefDomain,
- Components.interfaces.nsIPrefLocalizedString).data;
- } catch (e) {
- }
-
- // use this if we can't find the pref
- if (!url) {
- var configBundle = Services.strings
- .createBundle("chrome://branding/locale/browserconfig.properties");
- url = configBundle.GetStringFromName(this.prefDomain);
- }
-
- return url;
- },
-
- updatePersonalToolbarStyle: function (homeButton)
- {
- if (!homeButton)
- homeButton = document.getElementById("home-button");
- if (homeButton)
- homeButton.className = homeButton.parentNode.id == "PersonalToolbar"
- || homeButton.parentNode.parentNode.id == "PersonalToolbar" ?
- homeButton.className.replace("toolbarbutton-1", "bookmark-item") :
- homeButton.className.replace("bookmark-item", "toolbarbutton-1");
- }
-};
-
-/**
- * Gets the selected text in the active browser. Leading and trailing
- * whitespace is removed, and consecutive whitespace is replaced by a single
- * space. A maximum of 150 characters will be returned, regardless of the value
- * of aCharLen.
- *
- * @param aCharLen
- * The maximum number of characters to return.
- */
-function getBrowserSelection(aCharLen) {
- // selections of more than 150 characters aren't useful
- const kMaxSelectionLen = 150;
- const charLen = Math.min(aCharLen || kMaxSelectionLen, kMaxSelectionLen);
- let commandDispatcher = document.commandDispatcher;
-
- var focusedWindow = commandDispatcher.focusedWindow;
- var selection = focusedWindow.getSelection().toString();
- // try getting a selected text in text input.
- if (!selection) {
- let element = commandDispatcher.focusedElement;
- var isOnTextInput = function isOnTextInput(elem) {
- // we avoid to return a value if a selection is in password field.
- // ref. bug 565717
- return elem instanceof HTMLTextAreaElement ||
- (elem instanceof HTMLInputElement && elem.mozIsTextField(true));
- };
-
- if (isOnTextInput(element)) {
- selection = element.QueryInterface(Ci.nsIDOMNSEditableElement)
- .editor.selection.toString();
- }
- }
-
- if (selection) {
- if (selection.length > charLen) {
- // only use the first charLen important chars. see bug 221361
- var pattern = new RegExp("^(?:\\s*.){0," + charLen + "}");
- pattern.test(selection);
- selection = RegExp.lastMatch;
- }
-
- selection = selection.trim().replace(/\s+/g, " ");
-
- if (selection.length > charLen)
- selection = selection.substr(0, charLen);
- }
- return selection;
-}
-
-var gWebPanelURI;
-function openWebPanel(aTitle, aURI)
-{
- // Ensure that the web panels sidebar is open.
- toggleSidebar('viewWebPanelsSidebar', true);
-
- // Set the title of the panel.
- document.getElementById("sidebar-title").value = aTitle;
-
- // Tell the Web Panels sidebar to load the bookmark.
- var sidebar = document.getElementById("sidebar");
- if (sidebar.docShell && sidebar.contentDocument && sidebar.contentDocument.getElementById('web-panels-browser')) {
- sidebar.contentWindow.loadWebPanel(aURI);
- if (gWebPanelURI) {
- gWebPanelURI = "";
- sidebar.removeEventListener("load", asyncOpenWebPanel, true);
- }
- }
- else {
- // The panel is still being constructed. Attach an onload handler.
- if (!gWebPanelURI)
- sidebar.addEventListener("load", asyncOpenWebPanel, true);
- gWebPanelURI = aURI;
- }
-}
-
-function asyncOpenWebPanel(event)
-{
- var sidebar = document.getElementById("sidebar");
- if (gWebPanelURI && sidebar.contentDocument && sidebar.contentDocument.getElementById('web-panels-browser'))
- sidebar.contentWindow.loadWebPanel(gWebPanelURI);
- gWebPanelURI = "";
- sidebar.removeEventListener("load", asyncOpenWebPanel, true);
-}
-
-/*
- * - [ Dependencies ] ---------------------------------------------------------
- * utilityOverlay.js:
- * - gatherTextUnder
- */
-
-/**
- * Extracts linkNode and href for the current click target.
- *
- * @param event
- * The click event.
- * @return [href, linkNode].
- *
- * @note linkNode will be null if the click wasn't on an anchor
- * element (or XLink).
- */
-function hrefAndLinkNodeForClickEvent(event)
-{
- function isHTMLLink(aNode)
- {
- // Be consistent with what nsContextMenu.js does.
- return ((aNode instanceof HTMLAnchorElement && aNode.href) ||
- (aNode instanceof HTMLAreaElement && aNode.href) ||
- aNode instanceof HTMLLinkElement);
- }
-
- let node = event.target;
- while (node && !isHTMLLink(node)) {
- node = node.parentNode;
- }
-
- if (node)
- return [node.href, node];
-
- // If there is no linkNode, try simple XLink.
- let href, baseURI;
- node = event.target;
- while (node && !href) {
- if (node.nodeType == Node.ELEMENT_NODE &&
- (node.localName == "a" ||
- node.namespaceURI == "http://www.w3.org/1998/Math/MathML")) {
- href = node.getAttributeNS("http://www.w3.org/1999/xlink", "href");
- if (href) {
- baseURI = node.baseURI;
- break;
- }
- }
- node = node.parentNode;
- }
-
- // In case of XLink, we don't return the node we got href from since
- // callers expect <a>-like elements.
- return [href ? makeURLAbsolute(baseURI, href) : null, null];
-}
-
-/**
- * Called whenever the user clicks in the content area.
- *
- * @param event
- * The click event.
- * @param isPanelClick
- * Whether the event comes from a web panel.
- * @note default event is prevented if the click is handled.
- */
-function contentAreaClick(event, isPanelClick)
-{
- if (!event.isTrusted || event.defaultPrevented || event.button == 2)
- return;
-
- let [href, linkNode] = hrefAndLinkNodeForClickEvent(event);
- if (!href) {
- // Not a link, handle middle mouse navigation.
- if (event.button == 1 &&
- gPrefService.getBoolPref("middlemouse.contentLoadURL") &&
- !gPrefService.getBoolPref("general.autoScroll")) {
- middleMousePaste(event);
- event.preventDefault();
- }
- return;
- }
-
- // This code only applies if we have a linkNode (i.e. clicks on real anchor
- // elements, as opposed to XLink).
- if (linkNode && event.button == 0 &&
- !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
- // A Web panel's links should target the main content area. Do this
- // if no modifier keys are down and if there's no target or the target
- // equals _main (the IE convention) or _content (the Mozilla convention).
- let target = linkNode.target;
- let mainTarget = !target || target == "_content" || target == "_main";
- if (isPanelClick && mainTarget) {
- // javascript and data links should be executed in the current browser.
- if (linkNode.getAttribute("onclick") ||
- href.startsWith("javascript:") ||
- href.startsWith("data:"))
- return;
-
- try {
- urlSecurityCheck(href, linkNode.ownerDocument.nodePrincipal);
- }
- catch(ex) {
- // Prevent loading unsecure destinations.
- event.preventDefault();
- return;
- }
-
- loadURI(href, null, null, false);
- event.preventDefault();
- return;
- }
-
- if (linkNode.getAttribute("rel") == "sidebar") {
- // This is the Opera convention for a special link that, when clicked,
- // allows to add a sidebar panel. The link's title attribute contains
- // the title that should be used for the sidebar panel.
- PlacesUIUtils.showBookmarkDialog({ action: "add"
- , type: "bookmark"
- , uri: makeURI(href)
- , title: linkNode.getAttribute("title")
- , loadBookmarkInSidebar: true
- , hiddenRows: [ "description"
- , "location"
- , "keyword" ]
- }, window);
- event.preventDefault();
- return;
- }
- }
-
- handleLinkClick(event, href, linkNode);
-
- // Mark the page as a user followed link. This is done so that history can
- // distinguish automatic embed visits from user activated ones. For example
- // pages loaded in frames are embed visits and lost with the session, while
- // visits across frames should be preserved.
- try {
- if (!PrivateBrowsingUtils.isWindowPrivate(window))
- PlacesUIUtils.markPageAsFollowedLink(href);
- } catch (ex) { /* Skip invalid URIs. */ }
-}
-
-/**
- * Handles clicks on links.
- *
- * @return true if the click event was handled, false otherwise.
- */
-function handleLinkClick(event, href, linkNode) {
- if (event.button == 2) // right click
- return false;
-
- var where = whereToOpenLink(event);
- if (where == "current")
- return false;
-
- var doc = event.target.ownerDocument;
-
- if (where == "save") {
- saveURL(href, linkNode ? gatherTextUnder(linkNode) : "", null, true,
- true, doc.documentURIObject, doc);
- event.preventDefault();
- return true;
- }
-
- urlSecurityCheck(href, doc.nodePrincipal);
- openLinkIn(href, where, { referrerURI: doc.documentURIObject,
- charset: doc.characterSet,
- referrerPolicy: doc.referrerPolicy,
- originPrincipal: doc.nodePrincipal,
- triggeringPrincipal: doc.nodePrincipal });
- event.preventDefault();
- return true;
-}
-
-function middleMousePaste(event) {
- let clipboard = readFromClipboard();
- if (!clipboard)
- return;
-
- // Strip embedded newlines and surrounding whitespace, to match the URL
- // bar's behavior (stripsurroundingwhitespace)
- clipboard = clipboard.replace(/\s*\n\s*/g, "");
-
- // if it's not the current tab, we don't need to do anything because the
- // browser doesn't exist.
- let where = whereToOpenLink(event, true, false);
- let lastLocationChange;
- if (where == "current") {
- lastLocationChange = gBrowser.selectedBrowser.lastLocationChange;
- }
-
- getShortcutOrURIAndPostData(clipboard).then(data => {
- try {
- makeURI(data.url);
- } catch (ex) {
- // Not a valid URI.
- return;
- }
-
- try {
- addToUrlbarHistory(data.url);
- } catch (ex) {
- // Things may go wrong when adding url to session history,
- // but don't let that interfere with the loading of the url.
- Cu.reportError(ex);
- }
-
- if (where != "current" ||
- lastLocationChange == gBrowser.selectedBrowser.lastLocationChange) {
- openUILink(data.url, event,
- { ignoreButton: true,
- disallowInheritPrincipal: !data.mayInheritPrincipal,
- initiatingDoc: event ? event.target.ownerDocument : null });
- }
- });
-
- event.stopPropagation();
-}
-
-// handleDroppedLink has the following 2 overloads:
-// handleDroppedLink(event, url, name)
-// handleDroppedLink(event, links)
-function handleDroppedLink(event, urlOrLinks, name)
-{
- let links;
- if (Array.isArray(urlOrLinks)) {
- links = urlOrLinks;
- } else {
- links = [{ url: urlOrLinks, name, type: "" }];
- }
-
- let lastLocationChange = gBrowser.selectedBrowser.lastLocationChange;
-
- let inBackground = Services.prefs.getBoolPref("browser.tabs.loadInBackground");
- if (event.shiftKey)
- inBackground = !inBackground;
-
- Task.spawn(function*() {
- let urls = [];
- let postDatas = [];
- for (let link of links) {
- let data = yield getShortcutOrURIAndPostData(link.url);
- urls.push(data.url);
- postDatas.push(data.postData);
- }
- if (lastLocationChange == gBrowser.selectedBrowser.lastLocationChange) {
- gBrowser.loadTabs(urls, {
- inBackground,
- replace: true,
- allowThirdPartyFixup: false,
- postDatas,
- });
- }
- });
-
- // Keep the event from being handled by the dragDrop listeners
- // built-in to goanna if they happen to be above us.
- event.preventDefault();
-};
-
-function MultiplexHandler(event)
-{ try {
- var node = event.target;
- var name = node.getAttribute('name');
-
- if (name == 'detectorGroup') {
- BrowserCharsetReload();
- SelectDetector(event, false);
- } else if (name == 'charsetGroup') {
- var charset = node.getAttribute('id');
- charset = charset.substring(charset.indexOf('charset.') + 'charset.'.length);
- BrowserSetForcedCharacterSet(charset);
- } else if (name == 'charsetCustomize') {
- //do nothing - please remove this else statement, once the charset prefs moves to the pref window
- } else {
- BrowserSetForcedCharacterSet(node.getAttribute('id'));
- }
- } catch(ex) { alert(ex); }
-}
-
-function SelectDetector(event, doReload)
-{
- var uri = event.target.getAttribute("id");
- var prefvalue = uri.substring(uri.indexOf('chardet.') + 'chardet.'.length);
- if ("off" == prefvalue) { // "off" is special value to turn off the detectors
- prefvalue = "";
- }
-
- try {
- var str = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString);
-
- str.data = prefvalue;
- gPrefService.setComplexValue("intl.charset.detector", Ci.nsISupportsString, str);
- if (doReload)
- window.content.location.reload();
- }
- catch (ex) {
- dump("Failed to set the intl.charset.detector preference.\n");
- }
-}
-
-function BrowserSetForcedCharacterSet(aCharset)
-{
- gBrowser.docShell.charset = aCharset;
- // Save the forced character-set
- if (!PrivateBrowsingUtils.isWindowPrivate(window))
- PlacesUtils.setCharsetForURI(getWebNavigation().currentURI, aCharset);
- BrowserCharsetReload();
-}
-
-function BrowserCharsetReload()
-{
- BrowserReloadWithFlags(nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE);
-}
-
-function charsetMenuGetElement(parent, id) {
- return parent.getElementsByAttribute("id", id)[0];
-}
-
-function UpdateCurrentCharset(target) {
- // extract the charset from DOM
- var wnd = document.commandDispatcher.focusedWindow;
- if ((window == wnd) || (wnd == null)) wnd = window.content;
-
- // Uncheck previous item
- if (gPrevCharset) {
- var pref_item = charsetMenuGetElement(target, "charset." + gPrevCharset);
- if (pref_item)
- pref_item.setAttribute('checked', 'false');
- }
-
- var menuitem = charsetMenuGetElement(target, "charset." + wnd.document.characterSet);
- if (menuitem) {
- menuitem.setAttribute('checked', 'true');
- }
-}
-
-function UpdateCharsetDetector(target) {
- var prefvalue;
-
- try {
- prefvalue = gPrefService.getComplexValue("intl.charset.detector", Ci.nsIPrefLocalizedString).data;
- }
- catch (ex) {}
-
- if (!prefvalue)
- prefvalue = "off";
-
- var menuitem = charsetMenuGetElement(target, "chardet." + prefvalue);
- if (menuitem)
- menuitem.setAttribute("checked", "true");
-}
-
-function UpdateMenus(event) {
- UpdateCurrentCharset(event.target);
- UpdateCharsetDetector(event.target);
-}
-
-function charsetLoadListener() {
- var charset = window.content.document.characterSet;
-
- if (charset.length > 0 && (charset != gLastBrowserCharset)) {
- gPrevCharset = gLastBrowserCharset;
- gLastBrowserCharset = charset;
- }
-}
-
-var gPageStyleMenu = {
-
- _getAllStyleSheets: function (frameset) {
- var styleSheetsArray = Array.slice(frameset.document.styleSheets);
- for (let i = 0; i < frameset.frames.length; i++) {
- let frameSheets = this._getAllStyleSheets(frameset.frames[i]);
- styleSheetsArray = styleSheetsArray.concat(frameSheets);
- }
- return styleSheetsArray;
- },
-
- fillPopup: function (menuPopup) {
- var noStyle = menuPopup.firstChild;
- var persistentOnly = noStyle.nextSibling;
- var sep = persistentOnly.nextSibling;
- while (sep.nextSibling)
- menuPopup.removeChild(sep.nextSibling);
-
- var styleSheets = this._getAllStyleSheets(window.content);
- var currentStyleSheets = {};
- var styleDisabled = getMarkupDocumentViewer().authorStyleDisabled;
- var haveAltSheets = false;
- var altStyleSelected = false;
-
- for (let currentStyleSheet of styleSheets) {
- if (!currentStyleSheet.title)
- continue;
-
- // Skip any stylesheets whose media attribute doesn't match.
- if (currentStyleSheet.media.length > 0) {
- let mediaQueryList = currentStyleSheet.media.mediaText;
- if (!window.content.matchMedia(mediaQueryList).matches)
- continue;
- }
-
- if (!currentStyleSheet.disabled)
- altStyleSelected = true;
-
- haveAltSheets = true;
-
- let lastWithSameTitle = null;
- if (currentStyleSheet.title in currentStyleSheets)
- lastWithSameTitle = currentStyleSheets[currentStyleSheet.title];
-
- if (!lastWithSameTitle) {
- let menuItem = document.createElement("menuitem");
- menuItem.setAttribute("type", "radio");
- menuItem.setAttribute("label", currentStyleSheet.title);
- menuItem.setAttribute("data", currentStyleSheet.title);
- menuItem.setAttribute("checked", !currentStyleSheet.disabled && !styleDisabled);
- menuItem.setAttribute("oncommand", "gPageStyleMenu.switchStyleSheet(this.getAttribute('data'));");
- menuPopup.appendChild(menuItem);
- currentStyleSheets[currentStyleSheet.title] = menuItem;
- } else if (currentStyleSheet.disabled) {
- lastWithSameTitle.removeAttribute("checked");
- }
- }
-
- noStyle.setAttribute("checked", styleDisabled);
- persistentOnly.setAttribute("checked", !altStyleSelected && !styleDisabled);
- persistentOnly.hidden = (window.content.document.preferredStyleSheetSet) ? haveAltSheets : false;
- sep.hidden = (noStyle.hidden && persistentOnly.hidden) || !haveAltSheets;
- },
-
- _stylesheetInFrame: function (frame, title) {
- return Array.some(frame.document.styleSheets,
- function (stylesheet) stylesheet.title == title);
- },
-
- _stylesheetSwitchFrame: function (frame, title) {
- var docStyleSheets = frame.document.styleSheets;
-
- for (let i = 0; i < docStyleSheets.length; ++i) {
- let docStyleSheet = docStyleSheets[i];
-
- if (docStyleSheet.title)
- docStyleSheet.disabled = (docStyleSheet.title != title);
- else if (docStyleSheet.disabled)
- docStyleSheet.disabled = false;
- }
- },
-
- _stylesheetSwitchAll: function (frameset, title) {
- if (!title || this._stylesheetInFrame(frameset, title))
- this._stylesheetSwitchFrame(frameset, title);
-
- for (let i = 0; i < frameset.frames.length; i++)
- this._stylesheetSwitchAll(frameset.frames[i], title);
- },
-
- switchStyleSheet: function (title, contentWindow) {
- getMarkupDocumentViewer().authorStyleDisabled = false;
- this._stylesheetSwitchAll(contentWindow || content, title);
- },
-
- disableStyle: function () {
- getMarkupDocumentViewer().authorStyleDisabled = true;
- },
-};
-
-/* Legacy global page-style functions */
-var getAllStyleSheets = gPageStyleMenu._getAllStyleSheets.bind(gPageStyleMenu);
-var stylesheetFillPopup = gPageStyleMenu.fillPopup.bind(gPageStyleMenu);
-function stylesheetSwitchAll(contentWindow, title) {
- gPageStyleMenu.switchStyleSheet(title, contentWindow);
-}
-function setStyleDisabled(disabled) {
- if (disabled)
- gPageStyleMenu.disableStyle();
-}
-
-
-var BrowserOffline = {
- _inited: false,
-
- /////////////////////////////////////////////////////////////////////////////
- // BrowserOffline Public Methods
- init: function ()
- {
- if (!this._uiElement)
- this._uiElement = document.getElementById("workOfflineMenuitemState");
-
- Services.obs.addObserver(this, "network:offline-status-changed", false);
-
- this._updateOfflineUI(Services.io.offline);
-
- this._inited = true;
- },
-
- uninit: function ()
- {
- if (this._inited) {
- Services.obs.removeObserver(this, "network:offline-status-changed");
- }
- },
-
- toggleOfflineStatus: function ()
- {
- var ioService = Services.io;
-
- // Stop automatic management of the offline status
- try {
- ioService.manageOfflineStatus = false;
- } catch (ex) {
- }
-
- if (!ioService.offline && !this._canGoOffline()) {
- this._updateOfflineUI(false);
- return;
- }
-
- ioService.offline = !ioService.offline;
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsIObserver
- observe: function (aSubject, aTopic, aState)
- {
- if (aTopic != "network:offline-status-changed")
- return;
-
- this._updateOfflineUI(aState == "offline");
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // BrowserOffline Implementation Methods
- _canGoOffline: function ()
- {
- try {
- var cancelGoOffline = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool);
- Services.obs.notifyObservers(cancelGoOffline, "offline-requested", null);
-
- // Something aborted the quit process.
- if (cancelGoOffline.data)
- return false;
- }
- catch (ex) {
- }
-
- return true;
- },
-
- _uiElement: null,
- _updateOfflineUI: function (aOffline)
- {
- var offlineLocked = gPrefService.prefIsLocked("network.online");
- if (offlineLocked)
- this._uiElement.setAttribute("disabled", "true");
-
- this._uiElement.setAttribute("checked", aOffline);
- }
-};
-
-var OfflineApps = {
- /////////////////////////////////////////////////////////////////////////////
- // OfflineApps Public Methods
- init: function ()
- {
- Services.obs.addObserver(this, "offline-cache-update-completed", false);
- },
-
- uninit: function ()
- {
- Services.obs.removeObserver(this, "offline-cache-update-completed");
- },
-
- handleEvent: function(event) {
- if (event.type == "MozApplicationManifest") {
- this.offlineAppRequested(event.originalTarget.defaultView);
- }
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // OfflineApps Implementation Methods
-
- // XXX: _getBrowserWindowForContentWindow and _getBrowserForContentWindow
- // were taken from browser/components/feeds/src/WebContentConverter.
- _getBrowserWindowForContentWindow: function(aContentWindow) {
- return aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem)
- .rootTreeItem
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow)
- .wrappedJSObject;
- },
-
- _getBrowserForContentWindow: function(aBrowserWindow, aContentWindow) {
- // This depends on pseudo APIs of browser.js and tabbrowser.xml
- aContentWindow = aContentWindow.top;
- var browsers = aBrowserWindow.gBrowser.browsers;
- for (let browser of browsers) {
- if (browser.contentWindow == aContentWindow)
- return browser;
- }
- // handle other browser/iframe elements that may need popupnotifications
- let browser = aContentWindow
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell)
- .chromeEventHandler;
- if (browser.getAttribute("popupnotificationanchor"))
- return browser;
- return null;
- },
-
- _getManifestURI: function(aWindow) {
- if (!aWindow.document.documentElement)
- return null;
-
- var attr = aWindow.document.documentElement.getAttribute("manifest");
- if (!attr)
- return null;
-
- try {
- var contentURI = makeURI(aWindow.location.href, null, null);
- return makeURI(attr, aWindow.document.characterSet, contentURI);
- } catch (e) {
- return null;
- }
- },
-
- // A cache update isn't tied to a specific window. Try to find
- // the best browser in which to warn the user about space usage
- _getBrowserForCacheUpdate: function(aCacheUpdate) {
- // Prefer the current browser
- var uri = this._getManifestURI(content);
- if (uri && uri.equals(aCacheUpdate.manifestURI)) {
- return gBrowser.selectedBrowser;
- }
-
- var browsers = gBrowser.browsers;
- for (let browser of browsers) {
- uri = this._getManifestURI(browser.contentWindow);
- if (uri && uri.equals(aCacheUpdate.manifestURI)) {
- return browser;
- }
- }
-
- // is this from a non-tab browser/iframe?
- browsers = document.querySelectorAll("iframe[popupnotificationanchor] | browser[popupnotificationanchor]");
- for (let browser of browsers) {
- uri = this._getManifestURI(browser.contentWindow);
- if (uri && uri.equals(aCacheUpdate.manifestURI)) {
- return browser;
- }
- }
-
- return null;
- },
-
- _warnUsage: function(aBrowser, aURI) {
- if (!aBrowser)
- return;
-
- let mainAction = {
- label: gNavigatorBundle.getString("offlineApps.manageUsage"),
- accessKey: gNavigatorBundle.getString("offlineApps.manageUsageAccessKey"),
- callback: OfflineApps.manage
- };
-
- let warnQuota = gPrefService.getIntPref("offline-apps.quota.warn");
- let message = gNavigatorBundle.getFormattedString("offlineApps.usage",
- [ aURI.host,
- warnQuota / 1024 ]);
-
- let anchorID = "indexedDB-notification-icon";
- PopupNotifications.show(aBrowser, "offline-app-usage", message,
- anchorID, mainAction);
-
- // Now that we've warned once, prevent the warning from showing up
- // again.
- Services.perms.add(aURI, "offline-app",
- Ci.nsIOfflineCacheUpdateService.ALLOW_NO_WARN);
- },
-
- // XXX: duplicated in preferences/advanced.js
- _getOfflineAppUsage: function (host, groups)
- {
- var cacheService = Cc["@mozilla.org/network/application-cache-service;1"].
- getService(Ci.nsIApplicationCacheService);
- if (!groups)
- groups = cacheService.getGroups();
-
- var usage = 0;
- for (let group of groups) {
- var uri = Services.io.newURI(group, null, null);
- if (uri.asciiHost == host) {
- var cache = cacheService.getActiveCache(group);
- usage += cache.usage;
- }
- }
-
- return usage;
- },
-
- _checkUsage: function(aURI) {
- // if the user has already allowed excessive usage, don't bother checking
- if (Services.perms.testExactPermission(aURI, "offline-app") !=
- Ci.nsIOfflineCacheUpdateService.ALLOW_NO_WARN) {
- var usage = this._getOfflineAppUsage(aURI.asciiHost);
- var warnQuota = gPrefService.getIntPref("offline-apps.quota.warn");
- if (usage >= warnQuota * 1024) {
- return true;
- }
- }
-
- return false;
- },
-
- offlineAppRequested: function(aContentWindow) {
- if (!gPrefService.getBoolPref("browser.offline-apps.notify")) {
- return;
- }
-
- let browserWindow = this._getBrowserWindowForContentWindow(aContentWindow);
- let browser = this._getBrowserForContentWindow(browserWindow,
- aContentWindow);
-
- let currentURI = aContentWindow.document.documentURIObject;
-
- // don't bother showing UI if the user has already made a decision
- if (Services.perms.testExactPermission(currentURI, "offline-app") != Services.perms.UNKNOWN_ACTION)
- return;
-
- try {
- if (gPrefService.getBoolPref("offline-apps.allow_by_default")) {
- // all pages can use offline capabilities, no need to ask the user
- return;
- }
- } catch(e) {
- // this pref isn't set by default, ignore failures
- }
-
- let host = currentURI.asciiHost;
- let notificationID = "offline-app-requested-" + host;
- let notification = PopupNotifications.getNotification(notificationID, browser);
-
- if (notification) {
- notification.options.documents.push(aContentWindow.document);
- } else {
- let mainAction = {
- label: gNavigatorBundle.getString("offlineApps.allow"),
- accessKey: gNavigatorBundle.getString("offlineApps.allowAccessKey"),
- callback: function() {
- for (let document of notification.options.documents) {
- OfflineApps.allowSite(document);
- }
- }
- };
- let secondaryActions = [{
- label: gNavigatorBundle.getString("offlineApps.never"),
- accessKey: gNavigatorBundle.getString("offlineApps.neverAccessKey"),
- callback: function() {
- for (let document of notification.options.documents) {
- OfflineApps.disallowSite(document);
- }
- }
- }];
- let message = gNavigatorBundle.getFormattedString("offlineApps.available",
- [ host ]);
- let anchorID = "indexedDB-notification-icon";
- let options= {
- documents : [ aContentWindow.document ]
- };
- notification = PopupNotifications.show(browser, notificationID, message,
- anchorID, mainAction,
- secondaryActions, options);
- }
- },
-
- allowSite: function(aDocument) {
- Services.perms.add(aDocument.documentURIObject, "offline-app", Services.perms.ALLOW_ACTION);
-
- // When a site is enabled while loading, manifest resources will
- // start fetching immediately. This one time we need to do it
- // ourselves.
- this._startFetching(aDocument);
- },
-
- disallowSite: function(aDocument) {
- Services.perms.add(aDocument.documentURIObject, "offline-app", Services.perms.DENY_ACTION);
- },
-
- manage: function() {
- openAdvancedPreferences("networkTab");
- },
-
- _startFetching: function(aDocument) {
- if (!aDocument.documentElement)
- return;
-
- var manifest = aDocument.documentElement.getAttribute("manifest");
- if (!manifest)
- return;
-
- var manifestURI = makeURI(manifest, aDocument.characterSet,
- aDocument.documentURIObject);
-
- var updateService = Cc["@mozilla.org/offlinecacheupdate-service;1"].
- getService(Ci.nsIOfflineCacheUpdateService);
- updateService.scheduleUpdate(manifestURI, aDocument.documentURIObject, window);
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsIObserver
- observe: function (aSubject, aTopic, aState)
- {
- if (aTopic == "offline-cache-update-completed") {
- var cacheUpdate = aSubject.QueryInterface(Ci.nsIOfflineCacheUpdate);
-
- var uri = cacheUpdate.manifestURI;
- if (OfflineApps._checkUsage(uri)) {
- var browser = this._getBrowserForCacheUpdate(cacheUpdate);
- if (browser) {
- OfflineApps._warnUsage(browser, cacheUpdate.manifestURI);
- }
- }
- }
- }
-};
-
-var IndexedDBPromptHelper = {
- _permissionsPrompt: "indexedDB-permissions-prompt",
- _permissionsResponse: "indexedDB-permissions-response",
-
- _quotaPrompt: "indexedDB-quota-prompt",
- _quotaResponse: "indexedDB-quota-response",
- _quotaCancel: "indexedDB-quota-cancel",
-
- _notificationIcon: "indexedDB-notification-icon",
-
- init:
- function IndexedDBPromptHelper_init() {
- Services.obs.addObserver(this, this._permissionsPrompt, false);
- Services.obs.addObserver(this, this._quotaPrompt, false);
- Services.obs.addObserver(this, this._quotaCancel, false);
- },
-
- uninit:
- function IndexedDBPromptHelper_uninit() {
- Services.obs.removeObserver(this, this._permissionsPrompt);
- Services.obs.removeObserver(this, this._quotaPrompt);
- Services.obs.removeObserver(this, this._quotaCancel);
- },
-
- observe:
- function IndexedDBPromptHelper_observe(subject, topic, data) {
- if (topic != this._permissionsPrompt &&
- topic != this._quotaPrompt &&
- topic != this._quotaCancel) {
- throw new Error("Unexpected topic!");
- }
-
- var requestor = subject.QueryInterface(Ci.nsIInterfaceRequestor);
-
- var contentWindow = requestor.getInterface(Ci.nsIDOMWindow);
- var contentDocument = contentWindow.document;
- var browserWindow =
- OfflineApps._getBrowserWindowForContentWindow(contentWindow);
-
- if (browserWindow != window) {
- // Must belong to some other window.
- return;
- }
-
- var browser =
- OfflineApps._getBrowserForContentWindow(browserWindow, contentWindow);
-
- var host = contentDocument.documentURIObject.asciiHost;
-
- var message;
- var responseTopic;
- if (topic == this._permissionsPrompt) {
- message = gNavigatorBundle.getFormattedString("offlineApps.available",
- [ host ]);
- responseTopic = this._permissionsResponse;
- }
- else if (topic == this._quotaPrompt) {
- message = gNavigatorBundle.getFormattedString("indexedDB.usage",
- [ host, data ]);
- responseTopic = this._quotaResponse;
- }
- else if (topic == this._quotaCancel) {
- responseTopic = this._quotaResponse;
- }
-
- const hiddenTimeoutDuration = 30000; // 30 seconds
- const firstTimeoutDuration = 300000; // 5 minutes
-
- var timeoutId;
-
- var observer = requestor.getInterface(Ci.nsIObserver);
-
- var mainAction = {
- label: gNavigatorBundle.getString("offlineApps.allow"),
- accessKey: gNavigatorBundle.getString("offlineApps.allowAccessKey"),
- callback: function() {
- clearTimeout(timeoutId);
- observer.observe(null, responseTopic,
- Ci.nsIPermissionManager.ALLOW_ACTION);
- }
- };
-
- var secondaryActions = [
- {
- label: gNavigatorBundle.getString("offlineApps.never"),
- accessKey: gNavigatorBundle.getString("offlineApps.neverAccessKey"),
- callback: function() {
- clearTimeout(timeoutId);
- observer.observe(null, responseTopic,
- Ci.nsIPermissionManager.DENY_ACTION);
- }
- }
- ];
-
- // This will be set to the result of PopupNotifications.show() below, or to
- // the result of PopupNotifications.getNotification() if this is a
- // quotaCancel notification.
- var notification;
-
- function timeoutNotification() {
- // Remove the notification.
- if (notification) {
- notification.remove();
- }
-
- // Clear all of our timeout stuff. We may be called directly, not just
- // when the timeout actually elapses.
- clearTimeout(timeoutId);
-
- // And tell the page that the popup timed out.
- observer.observe(null, responseTopic,
- Ci.nsIPermissionManager.UNKNOWN_ACTION);
- }
-
- var options = {
- eventCallback: function(state) {
- // Don't do anything if the timeout has not been set yet.
- if (!timeoutId) {
- return;
- }
-
- // If the popup is being dismissed start the short timeout.
- if (state == "dismissed") {
- clearTimeout(timeoutId);
- timeoutId = setTimeout(timeoutNotification, hiddenTimeoutDuration);
- return;
- }
-
- // If the popup is being re-shown then clear the timeout allowing
- // unlimited waiting.
- if (state == "shown") {
- clearTimeout(timeoutId);
- }
- }
- };
-
- if (topic == this._quotaCancel) {
- notification = PopupNotifications.getNotification(this._quotaPrompt,
- browser);
- timeoutNotification();
- return;
- }
-
- notification = PopupNotifications.show(browser, topic, message,
- this._notificationIcon, mainAction,
- secondaryActions, options);
-
- // Set the timeoutId after the popup has been created, and use the long
- // timeout value. If the user doesn't notice the popup after this amount of
- // time then it is most likely not visible and we want to alert the page.
- timeoutId = setTimeout(timeoutNotification, firstTimeoutDuration);
- }
-};
-
-function WindowIsClosing()
-{
- let event = document.createEvent("Events");
- event.initEvent("WindowIsClosing", true, true);
- if (!window.dispatchEvent(event))
- return false;
-
- if (!closeWindow(false, warnAboutClosingWindow))
- return false;
-
- for (let browser of gBrowser.browsers) {
- let ds = browser.docShell;
- if (ds.contentViewer && !ds.contentViewer.permitUnload())
- return false;
- }
-
- return true;
-}
-
-/**
- * Checks if this is the last full *browser* window around. If it is, this will
- * be communicated like quitting. Otherwise, we warn about closing multiple tabs.
- * @returns true if closing can proceed, false if it got cancelled.
- */
-function warnAboutClosingWindow() {
- // Popups aren't considered full browser windows.
- let isPBWindow = PrivateBrowsingUtils.isWindowPrivate(window);
- if (!isPBWindow && !toolbar.visible)
- return gBrowser.warnAboutClosingTabs(gBrowser.closingTabsEnum.ALL);
-
- // Figure out if there's at least one other browser window around.
- let e = Services.wm.getEnumerator("navigator:browser");
- let otherPBWindowExists = false;
- let nonPopupPresent = false;
- while (e.hasMoreElements()) {
- let win = e.getNext();
- if (win != window) {
- if (isPBWindow && PrivateBrowsingUtils.isWindowPrivate(win))
- otherPBWindowExists = true;
- if (win.toolbar.visible)
- nonPopupPresent = true;
- // If the current window is not in private browsing mode we don't need to
- // look for other pb windows, we can leave the loop when finding the
- // first non-popup window. If however the current window is in private
- // browsing mode then we need at least one other pb and one non-popup
- // window to break out early.
- if ((!isPBWindow || otherPBWindowExists) && nonPopupPresent)
- break;
- }
- }
-
- if (isPBWindow && !otherPBWindowExists) {
- let exitingCanceled = Cc["@mozilla.org/supports-PRBool;1"].
- createInstance(Ci.nsISupportsPRBool);
- exitingCanceled.data = false;
- Services.obs.notifyObservers(exitingCanceled,
- "last-pb-context-exiting",
- null);
- if (exitingCanceled.data)
- return false;
- }
-
- if (nonPopupPresent) {
- return isPBWindow || gBrowser.warnAboutClosingTabs(gBrowser.closingTabsEnum.ALL);
- }
-
- let os = Services.obs;
-
- let closingCanceled = Cc["@mozilla.org/supports-PRBool;1"].
- createInstance(Ci.nsISupportsPRBool);
- os.notifyObservers(closingCanceled,
- "browser-lastwindow-close-requested", null);
- if (closingCanceled.data)
- return false;
-
- os.notifyObservers(null, "browser-lastwindow-close-granted", null);
-
-#ifdef XP_MACOSX
- // OS X doesn't quit the application when the last window is closed, but keeps
- // the session alive. Hence don't prompt users to save tabs, but warn about
- // closing multiple tabs.
- return isPBWindow || gBrowser.warnAboutClosingTabs(gBrowser.closingTabsEnum.ALL);
-#else
- return true;
-#endif
-}
-
-var MailIntegration = {
- sendLinkForWindow: function (aWindow) {
- this.sendMessage(aWindow.location.href,
- aWindow.document.title);
- },
-
- sendMessage: function (aBody, aSubject) {
- // generate a mailto url based on the url and the url's title
- var mailtoUrl = "mailto:";
- if (aBody) {
- mailtoUrl += "?body=" + encodeURIComponent(aBody);
- mailtoUrl += "&subject=" + encodeURIComponent(aSubject);
- }
-
- var uri = makeURI(mailtoUrl);
-
- // now pass this uri to the operating system
- this._launchExternalUrl(uri);
- },
-
- // a generic method which can be used to pass arbitrary urls to the operating
- // system.
- // aURL --> a nsIURI which represents the url to launch
- _launchExternalUrl: function (aURL) {
- var extProtocolSvc =
- Cc["@mozilla.org/uriloader/external-protocol-service;1"]
- .getService(Ci.nsIExternalProtocolService);
- if (extProtocolSvc)
- extProtocolSvc.loadUrl(aURL);
- }
-};
-
-function BrowserOpenAddonsMgr(aView) {
- if (aView) {
- let emWindow;
- let browserWindow;
-
- var receivePong = function receivePong(aSubject, aTopic, aData) {
- let browserWin = aSubject.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem)
- .rootTreeItem
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
- if (!emWindow || browserWin == window /* favor the current window */) {
- emWindow = aSubject;
- browserWindow = browserWin;
- }
- }
- Services.obs.addObserver(receivePong, "EM-pong", false);
- Services.obs.notifyObservers(null, "EM-ping", "");
- Services.obs.removeObserver(receivePong, "EM-pong");
-
- if (emWindow) {
- emWindow.loadView(aView);
- browserWindow.gBrowser.selectedTab =
- browserWindow.gBrowser._getTabForContentWindow(emWindow);
- emWindow.focus();
- return;
- }
- }
-
- var newLoad = !switchToTabHavingURI("about:addons", true);
-
- if (aView) {
- // This must be a new load, else the ping/pong would have
- // found the window above.
- Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
- Services.obs.removeObserver(observer, aTopic);
- aSubject.loadView(aView);
- }, "EM-loaded", false);
- }
-}
-
-function BrowserOpenPermissionsMgr() {
- switchToTabHavingURI("about:permissions", true);
-}
-
-function AddKeywordForSearchField() {
- var node = document.popupNode;
-
- var charset = node.ownerDocument.characterSet;
-
- var docURI = makeURI(node.ownerDocument.URL,
- charset);
-
- var formURI = makeURI(node.form.getAttribute("action"),
- charset,
- docURI);
-
- var spec = formURI.spec;
-
- var isURLEncoded =
- (node.form.method.toUpperCase() == "POST"
- && (node.form.enctype == "application/x-www-form-urlencoded" ||
- node.form.enctype == ""));
-
- var title = gNavigatorBundle.getFormattedString("addKeywordTitleAutoFill",
- [node.ownerDocument.title]);
- var description = PlacesUIUtils.getDescriptionFromDocument(node.ownerDocument);
-
- var formData = [];
-
- function escapeNameValuePair(aName, aValue, aIsFormUrlEncoded) {
- if (aIsFormUrlEncoded)
- return escape(aName + "=" + aValue);
- else
- return escape(aName) + "=" + escape(aValue);
- }
-
- for (let el of node.form.elements) {
- if (!el.type) // happens with fieldsets
- continue;
-
- if (el == node) {
- formData.push((isURLEncoded) ? escapeNameValuePair(el.name, "%s", true) :
- // Don't escape "%s", just append
- escapeNameValuePair(el.name, "", false) + "%s");
- continue;
- }
-
- let type = el.type.toLowerCase();
-
- if (((el instanceof HTMLInputElement && el.mozIsTextField(true)) ||
- type == "hidden" || type == "textarea") ||
- ((type == "checkbox" || type == "radio") && el.checked)) {
- formData.push(escapeNameValuePair(el.name, el.value, isURLEncoded));
- } else if (el instanceof HTMLSelectElement && el.selectedIndex >= 0) {
- for (var j=0; j < el.options.length; j++) {
- if (el.options[j].selected)
- formData.push(escapeNameValuePair(el.name, el.options[j].value,
- isURLEncoded));
- }
- }
- }
-
- var postData;
-
- if (isURLEncoded)
- postData = formData.join("&");
- else
- spec += "?" + formData.join("&");
-
- PlacesUIUtils.showBookmarkDialog({ action: "add"
- , type: "bookmark"
- , uri: makeURI(spec)
- , title: title
- , description: description
- , keyword: ""
- , postData: postData
- , charSet: charset
- , hiddenRows: [ "location"
- , "description"
- , "tags"
- , "loadInSidebar" ]
- }, window);
-}
-
-function SwitchDocumentDirection(aWindow) {
- // document.dir can also be "auto", in which case it won't change
- if (aWindow.document.dir == "ltr" || aWindow.document.dir == "") {
- aWindow.document.dir = "rtl";
- } else if (aWindow.document.dir == "rtl") {
- aWindow.document.dir = "ltr";
- }
- for (var run = 0; run < aWindow.frames.length; run++)
- SwitchDocumentDirection(aWindow.frames[run]);
-}
-
-function convertFromUnicode(charset, str)
-{
- try {
- var unicodeConverter = Components
- .classes["@mozilla.org/intl/scriptableunicodeconverter"]
- .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
- unicodeConverter.charset = charset;
- str = unicodeConverter.ConvertFromUnicode(str);
- return str + unicodeConverter.Finish();
- } catch(ex) {
- return null;
- }
-}
-
-/**
- * Re-open a closed tab.
- * @param aIndex
- * The index of the tab (via nsSessionStore.getClosedTabData)
- * @returns a reference to the reopened tab.
- */
-function undoCloseTab(aIndex) {
- // wallpaper patch to prevent an unnecessary blank tab (bug 343895)
- var blankTabToRemove = null;
- if (gBrowser.tabs.length == 1 &&
- !gPrefService.getBoolPref("browser.tabs.autoHide") &&
- isTabEmpty(gBrowser.selectedTab))
- blankTabToRemove = gBrowser.selectedTab;
-
- var tab = null;
- var ss = Cc["@mozilla.org/browser/sessionstore;1"].
- getService(Ci.nsISessionStore);
- if (ss.getClosedTabCount(window) > (aIndex || 0)) {
- tab = ss.undoCloseTab(window, aIndex || 0);
-
- if (blankTabToRemove)
- gBrowser.removeTab(blankTabToRemove);
- }
-
- return tab;
-}
-
-/**
- * Re-open a closed window.
- * @param aIndex
- * The index of the window (via nsSessionStore.getClosedWindowData)
- * @returns a reference to the reopened window.
- */
-function undoCloseWindow(aIndex) {
- let ss = Cc["@mozilla.org/browser/sessionstore;1"].
- getService(Ci.nsISessionStore);
- let window = null;
- if (ss.getClosedWindowCount() > (aIndex || 0))
- window = ss.undoCloseWindow(aIndex || 0);
-
- return window;
-}
-
-/*
- * Determines if a tab is "empty", usually used in the context of determining
- * if it's ok to close the tab.
- */
-function isTabEmpty(aTab) {
- if (aTab.hasAttribute("busy"))
- return false;
-
- let browser = aTab.linkedBrowser;
- if (!isBlankPageURL(browser.currentURI.spec))
- return false;
-
- // Bug 863515 - Make content.opener checks work in electrolysis.
- if (!gMultiProcessBrowser && browser.contentWindow.opener)
- return false;
-
- if (browser.sessionHistory && browser.sessionHistory.count >= 2)
- return false;
-
- return true;
-}
-
-#ifdef MOZ_SERVICES_SYNC
-function BrowserOpenSyncTabs() {
- switchToTabHavingURI("about:sync-tabs", true);
-}
-#endif
-
-/**
- * Format a URL
- * eg:
- * echo formatURL("https://addons.mozilla.org/%LOCALE%/%APP%/%VERSION%/");
- * > https://addons.mozilla.org/en-US/firefox/3.0a1/
- *
- * Currently supported built-ins are LOCALE, APP, and any value from nsIXULAppInfo, uppercased.
- */
-function formatURL(aFormat, aIsPref) {
- var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
- return aIsPref ? formatter.formatURLPref(aFormat) : formatter.formatURL(aFormat);
-}
-
-/**
- * Utility object to handle manipulations of the identity indicators in the UI
- */
-var gIdentityHandler = {
- // Mode strings used to control CSS display
- IDENTITY_MODE_IDENTIFIED : "verifiedIdentity", // High-quality identity information
- IDENTITY_MODE_DOMAIN_VERIFIED : "verifiedDomain", // Minimal SSL CA-signed domain verification
- IDENTITY_MODE_UNKNOWN : "unknownIdentity", // No trusted identity information
- IDENTITY_MODE_MIXED_CONTENT : "unknownIdentity mixedContent", // SSL with unauthenticated content
- IDENTITY_MODE_MIXED_ACTIVE_CONTENT : "unknownIdentity mixedContent mixedActiveContent", // SSL with unauthenticated content
- IDENTITY_MODE_CHROMEUI : "chromeUI", // Part of the product's UI
-
- // Cache the most recent SSLStatus and Location seen in checkIdentity
- _lastStatus : null,
- _lastLocation : null,
- _mode : "unknownIdentity",
-
- // smart getters
- get _encryptionLabel () {
- delete this._encryptionLabel;
- this._encryptionLabel = {};
- this._encryptionLabel[this.IDENTITY_MODE_DOMAIN_VERIFIED] =
- gNavigatorBundle.getString("identity.encrypted");
- this._encryptionLabel[this.IDENTITY_MODE_IDENTIFIED] =
- gNavigatorBundle.getString("identity.encrypted");
- this._encryptionLabel[this.IDENTITY_MODE_UNKNOWN] =
- gNavigatorBundle.getString("identity.unencrypted");
- this._encryptionLabel[this.IDENTITY_MODE_MIXED_CONTENT] =
- gNavigatorBundle.getString("identity.mixed_content");
- this._encryptionLabel[this.IDENTITY_MODE_MIXED_ACTIVE_CONTENT] =
- gNavigatorBundle.getString("identity.mixed_content");
- return this._encryptionLabel;
- },
- get _identityPopup () {
- delete this._identityPopup;
- return this._identityPopup = document.getElementById("identity-popup");
- },
- get _identityBox () {
- delete this._identityBox;
- return this._identityBox = document.getElementById("identity-box");
- },
- get _identityPopupContentBox () {
- delete this._identityPopupContentBox;
- return this._identityPopupContentBox =
- document.getElementById("identity-popup-content-box");
- },
- get _identityPopupContentHost () {
- delete this._identityPopupContentHost;
- return this._identityPopupContentHost =
- document.getElementById("identity-popup-content-host");
- },
- get _identityPopupContentOwner () {
- delete this._identityPopupContentOwner;
- return this._identityPopupContentOwner =
- document.getElementById("identity-popup-content-owner");
- },
- get _identityPopupContentSupp () {
- delete this._identityPopupContentSupp;
- return this._identityPopupContentSupp =
- document.getElementById("identity-popup-content-supplemental");
- },
- get _identityPopupContentVerif () {
- delete this._identityPopupContentVerif;
- return this._identityPopupContentVerif =
- document.getElementById("identity-popup-content-verifier");
- },
- get _identityPopupEncLabel () {
- delete this._identityPopupEncLabel;
- return this._identityPopupEncLabel =
- document.getElementById("identity-popup-encryption-label");
- },
- get _identityIconLabel () {
- delete this._identityIconLabel;
- return this._identityIconLabel = document.getElementById("identity-icon-label");
- },
- get _overrideService () {
- delete this._overrideService;
- return this._overrideService = Cc["@mozilla.org/security/certoverride;1"]
- .getService(Ci.nsICertOverrideService);
- },
- get _identityIconCountryLabel () {
- delete this._identityIconCountryLabel;
- return this._identityIconCountryLabel = document.getElementById("identity-icon-country-label");
- },
- get _identityIcon () {
- delete this._identityIcon;
- return this._identityIcon = document.getElementById("page-proxy-favicon");
- },
-
- /**
- * Rebuild cache of the elements that may or may not exist depending
- * on whether there's a location bar.
- */
- _cacheElements : function() {
- delete this._identityBox;
- delete this._identityIconLabel;
- delete this._identityIconCountryLabel;
- delete this._identityIcon;
- this._identityBox = document.getElementById("identity-box");
- this._identityIconLabel = document.getElementById("identity-icon-label");
- this._identityIconCountryLabel = document.getElementById("identity-icon-country-label");
- this._identityIcon = document.getElementById("page-proxy-favicon");
- },
-
- /**
- * Handler for mouseclicks on the "More Information" button in the
- * "identity-popup" panel.
- */
- handleMoreInfoClick : function(event) {
- displaySecurityInfo();
- event.stopPropagation();
- },
-
- /**
- * Helper to parse out the important parts of _lastStatus (of the SSL cert in
- * particular) for use in constructing identity UI strings
- */
- getIdentityData : function() {
- var result = {};
- var status = this._lastStatus.QueryInterface(Components.interfaces.nsISSLStatus);
- var cert = status.serverCert;
-
- // Human readable name of Subject
- result.subjectOrg = cert.organization;
-
- // SubjectName fields, broken up for individual access
- if (cert.subjectName) {
- result.subjectNameFields = {};
- cert.subjectName.split(",").forEach(function(v) {
- var field = v.split("=");
- this[field[0]] = field[1];
- }, result.subjectNameFields);
-
- // Call out city, state, and country specifically
- result.city = result.subjectNameFields.L;
- result.state = result.subjectNameFields.ST;
- result.country = result.subjectNameFields.C;
- }
-
- // Human readable name of Certificate Authority
- result.caOrg = cert.issuerOrganization || cert.issuerCommonName;
- result.cert = cert;
-
- return result;
- },
-
- /**
- * Determine the identity of the page being displayed by examining its SSL cert
- * (if available) and, if necessary, update the UI to reflect this. Intended to
- * be called by onSecurityChange
- *
- * @param PRUint32 state
- * @param JS Object location that mirrors an nsLocation (i.e. has .host and
- * .hostname and .port)
- */
- checkIdentity : function(state, location) {
- var currentStatus = gBrowser.securityUI
- .QueryInterface(Components.interfaces.nsISSLStatusProvider)
- .SSLStatus;
- this._lastStatus = currentStatus;
- this._lastLocation = location;
-
- let nsIWebProgressListener = Ci.nsIWebProgressListener;
- if (location.protocol == "chrome:" || location.protocol == "about:") {
- this.setMode(this.IDENTITY_MODE_CHROMEUI);
- } else if (state & nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL) {
- this.setMode(this.IDENTITY_MODE_IDENTIFIED);
- } else if (state & nsIWebProgressListener.STATE_IS_SECURE) {
- this.setMode(this.IDENTITY_MODE_DOMAIN_VERIFIED);
- } else if (state & nsIWebProgressListener.STATE_IS_BROKEN) {
- if ((state & nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT) &&
- gPrefService.getBoolPref("security.mixed_content.block_active_content")) {
- this.setMode(this.IDENTITY_MODE_MIXED_ACTIVE_CONTENT);
- } else {
- this.setMode(this.IDENTITY_MODE_MIXED_CONTENT);
- }
- } else {
- this.setMode(this.IDENTITY_MODE_UNKNOWN);
- }
-
- // Ensure the doorhanger is shown when mixed active content is blocked.
- if (state & nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT)
- this.showMixedContentDoorhanger();
- },
-
- /**
- * Display the Mixed Content Blocker doohanger, providing an option
- * to the user to override mixed content blocking
- */
- showMixedContentDoorhanger : function() {
- // If we've already got an active notification, bail out to avoid showing it repeatedly.
- if (PopupNotifications.getNotification("mixed-content-blocked", gBrowser.selectedBrowser))
- return;
-
- let brandBundle = document.getElementById("bundle_brand");
- let brandShortName = brandBundle.getString("brandShortName");
- let messageString = gNavigatorBundle.getFormattedString("mixedContentBlocked.message", [brandShortName]);
- let action = {
- label: gNavigatorBundle.getString("mixedContentBlocked.keepBlockingButton.label"),
- accessKey: gNavigatorBundle.getString("mixedContentBlocked.keepBlockingButton.accesskey"),
- callback: function() { /* NOP */ }
- };
- let secondaryActions = [
- {
- label: gNavigatorBundle.getString("mixedContentBlocked.unblock.label"),
- accessKey: gNavigatorBundle.getString("mixedContentBlocked.unblock.accesskey"),
- callback: function() {
- // Reload the page with the content unblocked
- BrowserReloadWithFlags(nsIWebNavigation.LOAD_FLAGS_ALLOW_MIXED_CONTENT);
- }
- }
- ];
- let options = {
- dismissed: true,
- learnMoreURL: Services.urlFormatter.formatURLPref("browser.mixedcontent.warning.infoURL"),
- };
- PopupNotifications.show(gBrowser.selectedBrowser, "mixed-content-blocked",
- messageString, "mixed-content-blocked-notification-icon",
- action, secondaryActions, options);
- },
-
- /**
- * Return the eTLD+1 version of the current hostname
- */
- getEffectiveHost : function() {
- try {
- let baseDomain =
- Services.eTLD.getBaseDomainFromHost(this._lastLocation.hostname);
- return this._IDNService.convertToDisplayIDN(baseDomain, {});
- } catch (e) {
- // If something goes wrong (e.g. hostname is an IP address) just fail back
- // to the full domain.
- return this._lastLocation.hostname;
- }
- },
-
- /**
- * Update the UI to reflect the specified mode, which should be one of the
- * IDENTITY_MODE_* constants.
- */
- setMode : function(newMode) {
- if (!this._identityBox) {
- // No identity box means the identity box is not visible, in which
- // case there's nothing to do.
- return;
- }
-
- this._identityBox.className = newMode;
- this.setIdentityMessages(newMode);
-
- // Update the popup too, if it's open
- if (this._identityPopup.state == "open")
- this.setPopupMessages(newMode);
-
- this._mode = newMode;
- },
-
- /**
- * Set up the messages for the primary identity UI based on the specified mode,
- * and the details of the SSL cert, where applicable
- *
- * @param newMode The newly set identity mode. Should be one of the IDENTITY_MODE_* constants.
- */
- setIdentityMessages : function(newMode) {
- let icon_label = "";
- let tooltip = "";
- let icon_country_label = "";
- let icon_labels_dir = "ltr";
-
- if (!this._IDNService)
- this._IDNService = Cc["@mozilla.org/network/idn-service;1"]
- .getService(Ci.nsIIDNService);
- let punyID = gPrefService.getIntPref("browser.identity.display_punycode", 1);
-
- switch (newMode) {
- case this.IDENTITY_MODE_DOMAIN_VERIFIED: {
- let iData = this.getIdentityData();
-
- let label_display = "";
-
- //Pale Moon: honor browser.identity.ssl_domain_display!
- switch (gPrefService.getIntPref("browser.identity.ssl_domain_display")) {
- case 2 : // Show full domain
- label_display = this._lastLocation.hostname;
- break;
- case 1 : // Show eTLD.
- label_display = this.getEffectiveHost();
- }
-
- if (punyID >= 1) {
- // Display punycode version in identity panel
- icon_label = this._IDNService.convertUTF8toACE(label_display);
- } else {
- icon_label = label_display;
- }
-
- // Verifier is either the CA Org, for a normal cert, or a special string
- // for certs that are trusted because of a security exception.
- tooltip = gNavigatorBundle.getFormattedString("identity.identified.verifier",
- [iData.caOrg]);
-
- // Check whether this site is a security exception. XPConnect does the right
- // thing here in terms of converting _lastLocation.port from string to int, but
- // the overrideService doesn't like undefined ports, so make sure we have
- // something in the default case (bug 432241).
- // .hostname can return an empty string in some exceptional cases -
- // hasMatchingOverride does not handle that, so avoid calling it.
- // Updating the tooltip value in those cases isn't critical.
- // FIXME: Fixing bug 646690 would probably makes this check unnecessary
- if (this._lastLocation.hostname &&
- this._overrideService.hasMatchingOverride(this._lastLocation.hostname,
- (this._lastLocation.port || 443),
- iData.cert, {}, {}))
- tooltip = gNavigatorBundle.getString("identity.identified.verified_by_you");
- break; }
- case this.IDENTITY_MODE_IDENTIFIED: {
- // If it's identified, then we can populate the dialog with credentials
- let iData = this.getIdentityData();
- tooltip = gNavigatorBundle.getFormattedString("identity.identified.verifier",
- [iData.caOrg]);
- icon_label = iData.subjectOrg;
- if (iData.country)
- icon_country_label = "(" + iData.country + ")";
-
- // If the organization name starts with an RTL character, then
- // swap the positions of the organization and country code labels.
- // The Unicode ranges reflect the definition of the UCS2_CHAR_IS_BIDI
- // macro in intl/unicharutil/util/nsBidiUtils.h. When bug 218823 gets
- // fixed, this test should be replaced by one adhering to the
- // Unicode Bidirectional Algorithm proper (at the paragraph level).
- icon_labels_dir = /^[\u0590-\u08ff\ufb1d-\ufdff\ufe70-\ufefc]/.test(icon_label) ?
- "rtl" : "ltr";
- break; }
- case this.IDENTITY_MODE_CHROMEUI:
- break;
- default:
- tooltip = gNavigatorBundle.getString("identity.unknown.tooltip");
- if (punyID == 2) {
- // Check for IDN and display if so...
- let rawHost = this._IDNService.convertUTF8toACE(this._lastLocation.hostname);
- if (this._IDNService.isACE(rawHost)) {
- icon_label = rawHost;
- }
- }
- }
-
- // Push the appropriate strings out to the UI
- this._identityBox.tooltipText = tooltip;
- this._identityIconLabel.value = icon_label;
- this._identityIconCountryLabel.value = icon_country_label;
- // Set cropping and direction
- this._identityIconLabel.crop = icon_country_label ? "end" : "center";
- this._identityIconLabel.parentNode.style.direction = icon_labels_dir;
- // Hide completely if the organization label is empty
- this._identityIconLabel.parentNode.collapsed = icon_label ? false : true;
- },
-
- /**
- * Set up the title and content messages for the identity message popup,
- * based on the specified mode, and the details of the SSL cert, where
- * applicable
- *
- * @param newMode The newly set identity mode. Should be one of the IDENTITY_MODE_* constants.
- */
- setPopupMessages : function(newMode) {
-
- this._identityPopup.className = newMode;
- this._identityPopupContentBox.className = newMode;
-
- // Set the static strings up front
- this._identityPopupEncLabel.textContent = this._encryptionLabel[newMode];
-
- // Initialize the optional strings to empty values
- let supplemental = "";
- let verifier = "";
- let host = "";
- let owner = "";
-
- switch (newMode) {
- case this.IDENTITY_MODE_DOMAIN_VERIFIED:
- host = this.getEffectiveHost();
- owner = gNavigatorBundle.getString("identity.ownerUnknown2");
- verifier = this._identityBox.tooltipText;
- break;
- case this.IDENTITY_MODE_IDENTIFIED: {
- // If it's identified, then we can populate the dialog with credentials
- let iData = this.getIdentityData();
- host = this.getEffectiveHost();
- owner = iData.subjectOrg;
- verifier = this._identityBox.tooltipText;
-
- // Build an appropriate supplemental block out of whatever location data we have
- if (iData.city)
- supplemental += iData.city + "\n";
- if (iData.state && iData.country)
- supplemental += gNavigatorBundle.getFormattedString("identity.identified.state_and_country",
- [iData.state, iData.country]);
- else if (iData.state) // State only
- supplemental += iData.state;
- else if (iData.country) // Country only
- supplemental += iData.country;
- break; }
- }
-
- // Push the appropriate strings out to the UI
- this._identityPopupContentHost.textContent = host;
- this._identityPopupContentOwner.textContent = owner;
- this._identityPopupContentSupp.textContent = supplemental;
- this._identityPopupContentVerif.textContent = verifier;
- },
-
- hideIdentityPopup : function() {
- this._identityPopup.hidePopup();
- },
-
- /**
- * Click handler for the identity-box element in primary chrome.
- */
- handleIdentityButtonEvent : function(event) {
- event.stopPropagation();
-
- if ((event.type == "click" && event.button != 0) ||
- (event.type == "keypress" && event.charCode != KeyEvent.DOM_VK_SPACE &&
- event.keyCode != KeyEvent.DOM_VK_RETURN)) {
- return; // Left click, space or enter only
- }
-
- // Don't allow left click, space or enter if the location
- // is chrome UI or the location has been modified.
- if (this._mode == this.IDENTITY_MODE_CHROMEUI ||
- gURLBar.getAttribute("pageproxystate") != "valid") {
- return;
- }
-
- // Make sure that the display:none style we set in xul is removed now that
- // the popup is actually needed
- this._identityPopup.hidden = false;
-
- // Update the popup strings
- this.setPopupMessages(this._identityBox.className);
-
- // Add the "open" attribute to the identity box for styling
- this._identityBox.setAttribute("open", "true");
- var self = this;
- this._identityPopup.addEventListener("popuphidden", function onPopupHidden(e) {
- e.currentTarget.removeEventListener("popuphidden", onPopupHidden, false);
- self._identityBox.removeAttribute("open");
- }, false);
-
- // Now open the popup, anchored off the primary chrome element
- this._identityPopup.openPopup(this._identityIcon, "bottomcenter topleft");
- },
-
- onPopupShown : function(event) {
- document.getElementById('identity-popup-more-info-button').focus();
- },
-
- onDragStart: function (event) {
- if (gURLBar.getAttribute("pageproxystate") != "valid")
- return;
-
- var value = content.location.href;
- var urlString = value + "\n" + content.document.title;
- var htmlString = "<a href=\"" + value + "\">" + value + "</a>";
-
- var dt = event.dataTransfer;
- dt.setData("text/x-moz-url", urlString);
- dt.setData("text/uri-list", value);
- dt.setData("text/plain", value);
- dt.setData("text/html", htmlString);
- dt.setDragImage(gProxyFavIcon, 16, 16);
- }
-};
-
-function getNotificationBox(aWindow) {
- var foundBrowser = gBrowser.getBrowserForDocument(aWindow.document);
- if (foundBrowser)
- return gBrowser.getNotificationBox(foundBrowser)
- return null;
-};
-
-function getTabModalPromptBox(aWindow) {
- var foundBrowser = gBrowser.getBrowserForDocument(aWindow.document);
- if (foundBrowser)
- return gBrowser.getTabModalPromptBox(foundBrowser);
- return null;
-};
-
-/* DEPRECATED */
-function getBrowser() gBrowser;
-function getNavToolbox() gNavToolbox;
-
-var gPrivateBrowsingUI = {
- init: function PBUI_init() {
- // Do nothing for normal windows
- if (!PrivateBrowsingUtils.isWindowPrivate(window)) {
- return;
- }
-
- // Disable the Clear Recent History... menu item when in PB mode
- // temporary fix until bug 463607 is fixed
- document.getElementById("Tools:Sanitize").setAttribute("disabled", "true");
-
- if (window.location.href == getBrowserURL()) {
-#ifdef XP_MACOSX
- if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
- document.documentElement.setAttribute("drawintitlebar", true);
- }
-#endif
-
- // Adjust the window's title
- let docElement = document.documentElement;
- if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
- docElement.setAttribute("title",
- docElement.getAttribute("title_privatebrowsing"));
- docElement.setAttribute("titlemodifier",
- docElement.getAttribute("titlemodifier_privatebrowsing"));
- }
- docElement.setAttribute("privatebrowsingmode",
- PrivateBrowsingUtils.permanentPrivateBrowsing ? "permanent" : "temporary");
- gBrowser.updateTitlebar();
-
- if (PrivateBrowsingUtils.permanentPrivateBrowsing) {
- // Adjust the New Window menu entries
- [
- { normal: "menu_newNavigator", private: "menu_newPrivateWindow" },
- { normal: "appmenu_newNavigator", private: "appmenu_newPrivateWindow" },
- ].forEach(function(menu) {
- let newWindow = document.getElementById(menu.normal);
- let newPrivateWindow = document.getElementById(menu.private);
- if (newWindow && newPrivateWindow) {
- newPrivateWindow.hidden = true;
- newWindow.label = newPrivateWindow.label;
- newWindow.accessKey = newPrivateWindow.accessKey;
- newWindow.command = newPrivateWindow.command;
- }
- });
- }
- }
-
- if (gURLBar &&
- !PrivateBrowsingUtils.permanentPrivateBrowsing) {
- // Disable switch to tab autocompletion for private windows
- // (not for "Always use private browsing" mode)
- gURLBar.setAttribute("autocompletesearchparam", "");
- }
- }
-};
-
-
-/**
- * Switch to a tab that has a given URI, and focusses its browser window.
- * If a matching tab is in this window, it will be switched to. Otherwise, other
- * windows will be searched.
- *
- * @param aURI
- * URI to search for
- * @param aOpenNew
- * True to open a new tab and switch to it, if no existing tab is found.
- * If no suitable window is found, a new one will be opened.
- * @return True if an existing tab was found, false otherwise
- */
-function switchToTabHavingURI(aURI, aOpenNew) {
- // This will switch to the tab in aWindow having aURI, if present.
- function switchIfURIInWindow(aWindow) {
- // Only switch to the tab if neither the source and desination window are
- // private and they are not in permanent private borwsing mode
- if ((PrivateBrowsingUtils.isWindowPrivate(window) ||
- PrivateBrowsingUtils.isWindowPrivate(aWindow)) &&
- !PrivateBrowsingUtils.permanentPrivateBrowsing) {
- return false;
- }
-
- let browsers = aWindow.gBrowser.browsers;
- for (let i = 0; i < browsers.length; i++) {
- let browser = browsers[i];
- if (browser.currentURI.equals(aURI)) {
- // Focus the matching window & tab
- aWindow.focus();
- aWindow.gBrowser.tabContainer.selectedIndex = i;
- return true;
- }
- }
- return false;
- }
-
- // This can be passed either nsIURI or a string.
- if (!(aURI instanceof Ci.nsIURI))
- aURI = Services.io.newURI(aURI, null, null);
-
- let isBrowserWindow = !!window.gBrowser;
-
- // Prioritise this window.
- if (isBrowserWindow && switchIfURIInWindow(window))
- return true;
-
- let winEnum = Services.wm.getEnumerator("navigator:browser");
- while (winEnum.hasMoreElements()) {
- let browserWin = winEnum.getNext();
- // Skip closed (but not yet destroyed) windows,
- // and the current window (which was checked earlier).
- if (browserWin.closed || browserWin == window)
- continue;
- if (switchIfURIInWindow(browserWin))
- return true;
- }
-
- // No opened tab has that url.
- if (aOpenNew) {
- if (isBrowserWindow && isTabEmpty(gBrowser.selectedTab))
- gBrowser.selectedBrowser.loadURI(aURI.spec);
- else
- openUILinkIn(aURI.spec, "tab");
- }
-
- return false;
-}
-
-function restoreLastSession() {
- let ss = Cc["@mozilla.org/browser/sessionstore;1"].
- getService(Ci.nsISessionStore);
- ss.restoreLastSession();
-}
-
-var TabContextMenu = {
- contextTab: null,
- _updateToggleMuteMenuItem(aTab, aConditionFn) {
- ["muted", "soundplaying"].forEach(attr => {
- if (!aConditionFn || aConditionFn(attr)) {
- if (aTab.hasAttribute(attr)) {
- aTab.toggleMuteMenuItem.setAttribute(attr, "true");
- } else {
- aTab.toggleMuteMenuItem.removeAttribute(attr);
- }
- }
- });
- },
- updateContextMenu: function updateContextMenu(aPopupMenu) {
- this.contextTab = aPopupMenu.triggerNode.localName == "tab" ?
- aPopupMenu.triggerNode : gBrowser.selectedTab;
- let disabled = gBrowser.tabs.length == 1;
-
- // Enable the "Close Tab" menuitem when the window doesn't close with the last tab.
- document.getElementById("context_closeTab").disabled =
- disabled && gBrowser.tabContainer._closeWindowWithLastTab;
-
- var menuItems = aPopupMenu.getElementsByAttribute("tbattr", "tabbrowser-multiple");
- for (let menuItem of menuItems)
- menuItem.disabled = disabled;
-
- disabled = gBrowser.visibleTabs.length == 1;
- menuItems = aPopupMenu.getElementsByAttribute("tbattr", "tabbrowser-multiple-visible");
- for (let menuItem of menuItems)
- menuItem.disabled = disabled;
-
- // Session store
- document.getElementById("context_undoCloseTab").disabled =
- Cc["@mozilla.org/browser/sessionstore;1"].
- getService(Ci.nsISessionStore).
- getClosedTabCount(window) == 0;
-
- // Only one of pin/unpin should be visible
- document.getElementById("context_pinTab").hidden = this.contextTab.pinned;
- document.getElementById("context_unpinTab").hidden = !this.contextTab.pinned;
-
- // Disable "Close Tabs to the Right" if there are no tabs
- // following it and hide it when the user rightclicked on a pinned
- // tab.
- document.getElementById("context_closeTabsToTheEnd").disabled =
- gBrowser.getTabsToTheEndFrom(this.contextTab).length == 0;
- document.getElementById("context_closeTabsToTheEnd").hidden = this.contextTab.pinned;
-
- // Disable "Close other Tabs" if there is only one unpinned tab and
- // hide it when the user rightclicked on a pinned tab.
- let unpinnedTabs = gBrowser.visibleTabs.length - gBrowser._numPinnedTabs;
- document.getElementById("context_closeOtherTabs").disabled = unpinnedTabs <= 1;
- document.getElementById("context_closeOtherTabs").hidden = this.contextTab.pinned;
-
- // Hide "Bookmark All Tabs" for a pinned tab. Update its state if visible.
- let bookmarkAllTabs = document.getElementById("context_bookmarkAllTabs");
- bookmarkAllTabs.hidden = this.contextTab.pinned;
- if (!bookmarkAllTabs.hidden)
- PlacesCommandHook.updateBookmarkAllTabsCommand();
-
- // Adjust the state of the toggle mute menu item.
- let toggleMute = document.getElementById("context_toggleMuteTab");
- if (this.contextTab.hasAttribute("muted")) {
- toggleMute.label = gNavigatorBundle.getString("unmuteTab.label");
- toggleMute.accessKey = gNavigatorBundle.getString("unmuteTab.accesskey");
- } else {
- toggleMute.label = gNavigatorBundle.getString("muteTab.label");
- toggleMute.accessKey = gNavigatorBundle.getString("muteTab.accesskey");
- }
-
- this.contextTab.toggleMuteMenuItem = toggleMute;
- this._updateToggleMuteMenuItem(this.contextTab);
-
- this.contextTab.addEventListener("TabAttrModified", this, false);
- aPopupMenu.addEventListener("popuphiding", this, false);
- },
- handleEvent(aEvent) {
- switch (aEvent.type) {
- case "popuphiding":
- gBrowser.removeEventListener("TabAttrModified", this);
- aEvent.target.removeEventListener("popuphiding", this);
- break;
- case "TabAttrModified":
- let tab = aEvent.target;
- this._updateToggleMuteMenuItem(tab,
- attr => aEvent.detail.changed.indexOf(attr) >= 0);
- break;
- }
- }
-};
-
-#ifdef MOZ_DEVTOOLS
-// Note: Do not delete! It is used for: base/content/nsContextMenu.js
-XPCOMUtils.defineLazyModuleGetter(this, "gDevTools",
- "resource://devtools/client/framework/gDevTools.jsm");
-#endif
-
-// Prompt user to restart the browser in safe mode or normally
-function restart(safeMode)
-{
- let promptTitleString = null;
- let promptMessageString = null;
- let restartTextString = null;
- if (safeMode) {
- promptTitleString = "safeModeRestartPromptTitle";
- promptMessageString = "safeModeRestartPromptMessage";
- restartTextString = "safeModeRestartButton";
- } else {
- promptTitleString = "restartPromptTitle";
- promptMessageString = "restartPromptMessage";
- restartTextString = "restartButton";
- }
-
- let flags = Ci.nsIAppStartup.eAttemptQuit;
-
- // Prompt the user to confirm
- let promptTitle = gNavigatorBundle.getString(promptTitleString);
- let brandBundle = document.getElementById("bundle_brand");
- let brandShortName = brandBundle.getString("brandShortName");
- let promptMessage =
- gNavigatorBundle.getFormattedString(promptMessageString, [brandShortName]);
- let restartText = gNavigatorBundle.getString(restartTextString);
- let buttonFlags = (Services.prompt.BUTTON_POS_0 *
- Services.prompt.BUTTON_TITLE_IS_STRING) +
- (Services.prompt.BUTTON_POS_1 *
- Services.prompt.BUTTON_TITLE_CANCEL) +
- Services.prompt.BUTTON_POS_0_DEFAULT;
-
- let rv = Services.prompt.confirmEx(window, promptTitle, promptMessage,
- buttonFlags, restartText, null, null,
- null, {});
-
- if (rv == 0) {
- // Notify all windows that an application quit has been requested.
- let cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
- .createInstance(Ci.nsISupportsPRBool);
- Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
-
- // Something aborted the quit process.
- if (cancelQuit.data) {
- return;
- }
-
- if (safeMode) {
- Services.startup.restartInSafeMode(flags);
- } else {
- Services.startup.quit(flags | Ci.nsIAppStartup.eRestart);
- }
- }
-}
-
-/* duplicateTabIn duplicates tab in a place specified by the parameter |where|.
- *
- * |where| can be:
- * "tab" new tab
- * "tabshifted" same as "tab" but in background if default is to select new
- * tabs, and vice versa
- * "window" new window
- *
- * delta is the offset to the history entry that you want to load.
- */
-function duplicateTabIn(aTab, where, delta) {
- let newTab = Cc['@mozilla.org/browser/sessionstore;1']
- .getService(Ci.nsISessionStore)
- .duplicateTab(window, aTab, delta);
-
- switch (where) {
- case "window":
- gBrowser.hideTab(newTab);
- gBrowser.replaceTabWithWindow(newTab);
- break;
- case "tabshifted":
- // A background tab has been opened, nothing else to do here.
- break;
- case "tab":
- gBrowser.selectedTab = newTab;
- break;
- }
-}
-
-function toggleAddonBar() {
- let addonBar = document.getElementById("addon-bar");
- setToolbarVisibility(addonBar, addonBar.collapsed);
-}
-
-XPCOMUtils.defineLazyGetter(window, "gShowPageResizers", function () {
-#ifdef XP_WIN
- // Only show resizers on Windows 2000 and XP
- return parseFloat(Services.sysinfo.getProperty("version")) < 6;
-#else
- return false;
-#endif
-});
-
-var MousePosTracker = {
- _listeners: [],
- _x: 0,
- _y: 0,
- get _windowUtils() {
- delete this._windowUtils;
- return this._windowUtils = window.getInterface(Ci.nsIDOMWindowUtils);
- },
-
- addListener: function (listener) {
- if (this._listeners.indexOf(listener) >= 0)
- return;
-
- listener._hover = false;
- this._listeners.push(listener);
-
- this._callListener(listener);
- },
-
- removeListener: function (listener) {
- var index = this._listeners.indexOf(listener);
- if (index < 0)
- return;
-
- this._listeners.splice(index, 1);
- },
-
- handleEvent: function (event) {
- var fullZoom = this._windowUtils.fullZoom;
- this._x = event.screenX / fullZoom - window.mozInnerScreenX;
- this._y = event.screenY / fullZoom - window.mozInnerScreenY;
-
- this._listeners.forEach(function (listener) {
- try {
- this._callListener(listener);
- } catch (e) {
- Cu.reportError(e);
- }
- }, this);
- },
-
- _callListener: function (listener) {
- let rect = listener.getMouseTargetRect();
- let hover = this._x >= rect.left &&
- this._x <= rect.right &&
- this._y >= rect.top &&
- this._y <= rect.bottom;
-
- if (hover == listener._hover)
- return;
-
- listener._hover = hover;
-
- if (hover) {
- if (listener.onMouseEnter)
- listener.onMouseEnter();
- } else {
- if (listener.onMouseLeave)
- listener.onMouseLeave();
- }
- }
-};
-
-var BrowserChromeTest = {
- _cb: null,
- _ready: false,
- markAsReady: function () {
- this._ready = true;
- if (this._cb) {
- this._cb();
- this._cb = null;
- }
- },
- runWhenReady: function (cb) {
- if (this._ready)
- cb();
- else
- this._cb = cb;
- }
-};
-
-var ToolbarIconColor = {
- init: function () {
- this._initialized = true;
-
- window.addEventListener("activate", this);
- window.addEventListener("deactivate", this);
- Services.obs.addObserver(this, "lightweight-theme-styling-update", false);
- gPrefService.addObserver("ui.colorChanged", this, false);
-
- // If the window isn't active now, we assume that it has never been active
- // before and will soon become active such that inferFromText will be
- // called from the initial activate event.
- if (Services.focus.activeWindow == window)
- this.inferFromText();
- },
-
- uninit: function () {
- this._initialized = false;
-
- window.removeEventListener("activate", this);
- window.removeEventListener("deactivate", this);
- Services.obs.removeObserver(this, "lightweight-theme-styling-update");
- gPrefService.removeObserver("ui.colorChanged", this);
- },
-
- handleEvent: function (event) {
- switch (event.type) {
- case "activate":
- case "deactivate":
- this.inferFromText();
- break;
- }
- },
-
- observe: function (aSubject, aTopic, aData) {
- switch (aTopic) {
- case "lightweight-theme-styling-update":
- // inferFromText needs to run after LightweightThemeConsumer.jsm's
- // lightweight-theme-styling-update observer.
- setTimeout(() => { this.inferFromText(); }, 0);
- break;
- case "nsPref:changed":
- // system color change
- var colorChangedPref = false;
- try {
- colorChangedPref = gPrefService.getBoolPref("ui.colorChanged");
- } catch(e) { }
- // if pref indicates change, call inferFromText() on a small delay
- if (colorChangedPref == true)
- setTimeout(() => { this.inferFromText(); }, 300);
- break;
- default:
- console.error("ToolbarIconColor: Uncaught topic " + aTopic);
- }
- },
-
- inferFromText: function () {
- if (!this._initialized)
- return;
-
- function parseRGB(aColorString) {
- let rgb = aColorString.match(/^rgba?\((\d+), (\d+), (\d+)/);
- rgb.shift();
- return rgb.map(x => parseInt(x));
- }
-
- let toolbarSelector = "toolbar:not([collapsed=true])";
-#ifdef XP_MACOSX
- toolbarSelector += ":not([type=menubar])";
-#endif
-
- // The getComputedStyle calls and setting the brighttext are separated in
- // two loops to avoid flushing layout and making it dirty repeatedly.
-
- let luminances = new Map;
- for (let toolbar of document.querySelectorAll(toolbarSelector)) {
- let [r, g, b] = parseRGB(getComputedStyle(toolbar).color);
- let luminance = (2 * r + 5 * g + b) / 8;
- luminances.set(toolbar, luminance);
- }
-
- for (let [toolbar, luminance] of luminances) {
- if (luminance <= 128)
- toolbar.removeAttribute("brighttext");
- else
- toolbar.setAttribute("brighttext", "true");
- }
-
- // Clear pref if set, since we're done applying the color changes.
- gPrefService.clearUserPref("ui.colorChanged");
- }
-}
diff --git a/base/content/browser.xul b/base/content/browser.xul
deleted file mode 100644
index 0a249af..0000000
--- a/base/content/browser.xul
+++ /dev/null
@@ -1,1046 +0,0 @@
-#filter substitution
-<?xml version="1.0"?>
-# -*- Mode: HTML -*-
-#
-# 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/.
-
-<?xml-stylesheet href="chrome://browser/content/browser.css" type="text/css"?>
-
-# Restore title to AppMenu windowed use
-<?xml-stylesheet href="chrome://browser/content/browser-title.css" type="text/css"?>
-
-<?xml-stylesheet href="chrome://browser/content/places/places.css" type="text/css"?>
-#ifdef MOZ_DEVTOOLS
-<?xml-stylesheet href="chrome://devtools/skin/devtools-browser.css" type="text/css"?>
-#endif
-<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
-
-<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
-<?xul-overlay href="chrome://browser/content/baseMenuOverlay.xul"?>
-<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-
-# Padlock feature
-<?xul-overlay href="chrome://browser/content/padlock.xul"?>
-# Improve bookmark menu dragging
-<?xul-overlay href="chrome://browser/content/browser-menudragging.xul"?>
-# Automatic browser recovery
-<?xul-overlay href="chrome://browser/content/autorecovery.xul"?>
-
-
-# All DTD information is stored in a separate file so that it can be shared by
-# hiddenWindow.xul.
-#include browser-doctype.inc
-
-<window id="main-window"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- onload="gBrowserInit.onLoad()" onunload="gBrowserInit.onUnload()" onclose="return WindowIsClosing();"
- title="&mainWindow.title;"
- title_normal="&mainWindow.title;"
-#ifdef XP_MACOSX
- title_privatebrowsing="&mainWindow.title;&mainWindow.titlemodifiermenuseparator;&mainWindow.titlePrivateBrowsingSuffix;"
- titledefault="&mainWindow.title;"
- titlemodifier=""
- titlemodifier_normal=""
- titlemodifier_privatebrowsing="&mainWindow.titlePrivateBrowsingSuffix;"
-#else
- title_privatebrowsing="&mainWindow.titlemodifier; &mainWindow.titlePrivateBrowsingSuffix;"
- titlemodifier="&mainWindow.titlemodifier;"
- titlemodifier_normal="&mainWindow.titlemodifier;"
- titlemodifier_privatebrowsing="&mainWindow.titlemodifier; &mainWindow.titlePrivateBrowsingSuffix;"
-#endif
- titlemenuseparator="&mainWindow.titlemodifiermenuseparator;"
-#ifdef MOZ_PERSONAS
- lightweightthemes="true"
- lightweightthemesfooter="browser-bottombox"
-#endif
- windowtype="navigator:browser"
- macanimationtype="document"
- screenX="4" screenY="4"
- fullscreenbutton="true"
- retargetdocumentfocus="urlbar"
- persist="screenX screenY width height sizemode">
-
-# All JS files which are not content (only) dependent that browser.xul
-# wishes to include *must* go into the global-scripts.inc file
-# so that they can be shared by macBrowserOverlay.xul.
-#include global-scripts.inc
-#ifdef MOZ_DEVTOOLS
-#include global-devtools-theme-scripts.inc
-#endif
-<script type="application/javascript" src="chrome://browser/content/nsContextMenu.js"/>
-
-<script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/>
-
-<script type="application/javascript" src="chrome://browser/content/places/editBookmarkOverlay.js"/>
-
-# All sets except for popupsets (commands, keys, stringbundles and broadcasters) *must* go into the
-# browser-sets.inc file for sharing with hiddenWindow.xul.
-#define FULL_BROWSER_WINDOW
-#include browser-sets.inc
-#undef FULL_BROWSER_WINDOW
-
- <popupset id="mainPopupSet">
- <menupopup id="tabContextMenu"
- onpopupshowing="if (event.target == this) TabContextMenu.updateContextMenu(this);"
- onpopuphidden="if (event.target == this) TabContextMenu.contextTab = null;">
- <menuitem id="context_reloadTab" label="&reloadTab.label;" accesskey="&reloadTab.accesskey;"
- oncommand="gBrowser.reloadTab(TabContextMenu.contextTab);"/>
- <menuitem id="context_toggleMuteTab" oncommand="TabContextMenu.contextTab.toggleMuteAudio();"/>
- <menuseparator/>
- <menuitem id="context_pinTab" label="&pinTab.label;"
- accesskey="&pinTab.accesskey;"
- oncommand="gBrowser.pinTab(TabContextMenu.contextTab);"/>
- <menuitem id="context_unpinTab" label="&unpinTab.label;" hidden="true"
- accesskey="&unpinTab.accesskey;"
- oncommand="gBrowser.unpinTab(TabContextMenu.contextTab);"/>
- <menuitem id="context_openTabInWindow" label="&moveToNewWindow.label;"
- accesskey="&moveToNewWindow.accesskey;"
- tbattr="tabbrowser-multiple"
- oncommand="gBrowser.replaceTabWithWindow(TabContextMenu.contextTab);"/>
- <menuseparator/>
- <menuitem id="context_reloadAllTabs" label="&reloadAllTabs.label;" accesskey="&reloadAllTabs.accesskey;"
- tbattr="tabbrowser-multiple-visible"
- oncommand="gBrowser.reloadAllTabs();"/>
- <menuitem id="context_bookmarkAllTabs"
- label="&bookmarkAllTabs.label;"
- accesskey="&bookmarkAllTabs.accesskey;"
- command="Browser:BookmarkAllTabs"/>
- <menuitem id="context_closeTabsToTheEnd" label="&closeTabsToTheEnd.label;" accesskey="&closeTabsToTheEnd.accesskey;"
- oncommand="gBrowser.removeTabsToTheEndFrom(TabContextMenu.contextTab);"/>
- <menuitem id="context_closeOtherTabs" label="&closeOtherTabs.label;" accesskey="&closeOtherTabs.accesskey;"
- oncommand="gBrowser.removeAllTabsBut(TabContextMenu.contextTab);"/>
- <menuseparator/>
- <menuitem id="context_undoCloseTab"
- label="&undoCloseTab.label;"
- accesskey="&undoCloseTab.accesskey;"
- observes="History:UndoCloseTab"/>
- <menuitem id="context_closeTab" label="&closeTab.label;" accesskey="&closeTab.accesskey;"
- oncommand="gBrowser.removeTab(TabContextMenu.contextTab, { animate: true });"/>
- </menupopup>
-
- <!-- bug 415444/582485: event.stopPropagation is here for the cloned version
- of this menupopup -->
- <menupopup id="backForwardMenu"
- onpopupshowing="return FillHistoryMenu(event.target);"
- oncommand="gotoHistoryIndex(event); event.stopPropagation();"
- onclick="checkForMiddleClick(this, event);"/>
- <tooltip id="aHTMLTooltip" page="true"/>
-
- <!-- for search and content formfill/pw manager -->
- <panel type="autocomplete" id="PopupAutoComplete" noautofocus="true" hidden="true"/>
- <panel type="private-autocomplete" id="PopupAutoComplete" noautofocus="true" hidden="true"/>
-
- <!-- for url bar autocomplete -->
- <panel type="autocomplete-richlistbox" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true"/>
- <panel type="private-autocomplete-richlistbox" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true"/>
-
- <!-- for date/time picker. consumeoutsideclicks is set to never, so that
- clicks on the anchored input box are never consumed. -->
- <panel id="DateTimePickerPanel"
- type="arrow"
- hidden="true"
- orient="vertical"
- noautofocus="true"
- norolluponanchor="true"
- consumeoutsideclicks="never"
- level="parent"
- tabspecific="true">
- <iframe id="dateTimePopupFrame"/>
- </panel>
-
- <!-- for invalid form error message -->
- <panel id="invalid-form-popup" type="arrow" orient="vertical" noautofocus="true" hidden="true" level="parent">
- <description/>
- </panel>
-
- <panel id="editBookmarkPanel"
- type="arrow"
- orient="vertical"
- ignorekeys="true"
- consumeoutsideclicks="true"
- hidden="true"
- onpopupshown="StarUI.panelShown(event);"
- aria-labelledby="editBookmarkPanelTitle">
- <row id="editBookmarkPanelHeader" align="center" hidden="true">
- <vbox align="center">
- <image id="editBookmarkPanelStarIcon"/>
- </vbox>
- <vbox>
- <label id="editBookmarkPanelTitle"/>
- <description id="editBookmarkPanelDescription"/>
- <hbox>
- <button id="editBookmarkPanelRemoveButton"
- class="editBookmarkPanelHeaderButton"
- oncommand="StarUI.removeBookmarkButtonCommand();"
- accesskey="&editBookmark.removeBookmark.accessKey;"/>
- </hbox>
- </vbox>
- </row>
- <vbox id="editBookmarkPanelContent" flex="1" hidden="true"/>
- <hbox id="editBookmarkPanelBottomButtons" pack="end">
-#ifndef XP_UNIX
- <button id="editBookmarkPanelDoneButton"
- class="editBookmarkPanelBottomButton"
- label="&editBookmark.done.label;"
- default="true"
- oncommand="StarUI.panel.hidePopup();"/>
- <button id="editBookmarkPanelDeleteButton"
- class="editBookmarkPanelBottomButton"
- label="&editBookmark.cancel.label;"
- oncommand="StarUI.cancelButtonOnCommand();"/>
-#else
- <button id="editBookmarkPanelDeleteButton"
- class="editBookmarkPanelBottomButton"
- label="&editBookmark.cancel.label;"
- oncommand="StarUI.cancelButtonOnCommand();"/>
- <button id="editBookmarkPanelDoneButton"
- class="editBookmarkPanelBottomButton"
- label="&editBookmark.done.label;"
- default="true"
- oncommand="StarUI.panel.hidePopup();"/>
-#endif
- </hbox>
- </panel>
-
- <menupopup id="toolbar-context-menu"
- onpopupshowing="onViewToolbarsPopupShowing(event);">
- <menuseparator/>
- <menuitem command="cmd_ToggleTabsOnTop"
- type="checkbox"
- label="&viewTabsOnTop.label;"
- accesskey="&viewTabsOnTop.accesskey;"/>
- <menuitem command="cmd_CustomizeToolbars"
- label="&viewCustomizeToolbar.label;"
- accesskey="&viewCustomizeToolbar.accesskey;"/>
- </menupopup>
-
- <menupopup id="blockedPopupOptions"
- onpopupshowing="gPopupBlockerObserver.fillPopupList(event);"
- onpopuphiding="gPopupBlockerObserver.onPopupHiding(event);">
- <menuitem observes="blockedPopupAllowSite"/>
- <menuitem observes="blockedPopupEditSettings"/>
- <menuitem observes="blockedPopupDontShowMessage"/>
- <menuseparator observes="blockedPopupsSeparator"/>
- </menupopup>
-
- <menupopup id="autohide-context"
- onpopupshowing="FullScreen.getAutohide(this.firstChild);">
- <menuitem type="checkbox" label="&fullScreenAutohide.label;"
- accesskey="&fullScreenAutohide.accesskey;"
- oncommand="FullScreen.setAutohide();"/>
- <menuseparator/>
- <menuitem label="&fullScreenExit.label;"
- accesskey="&fullScreenExit.accesskey;"
- oncommand="BrowserFullScreen();"/>
- </menupopup>
-
- <menupopup id="contentAreaContextMenu" pagemenu="start"
- onpopupshowing="if (event.target != this)
- return true;
- gContextMenu = new nsContextMenu(this, event.shiftKey);
- if (gContextMenu.shouldDisplay)
- updateEditUIVisibility();
- return gContextMenu.shouldDisplay;"
- onpopuphiding="if (event.target != this)
- return;
- gContextMenu.hiding();
- gContextMenu = null;
- updateEditUIVisibility();">
-#include browser-context.inc
- </menupopup>
-
- <menupopup id="placesContext"/>
-
-
- <panel id="ctrlTab-panel" class="KUI-panel" hidden="true" norestorefocus="true" level="top">
- <hbox>
- <button class="ctrlTab-preview" flex="1"/>
- <button class="ctrlTab-preview" flex="1"/>
- <button class="ctrlTab-preview" flex="1"/>
- <button class="ctrlTab-preview" flex="1"/>
- <button class="ctrlTab-preview" flex="1"/>
- <button class="ctrlTab-preview" flex="1"/>
- </hbox>
- <hbox pack="center">
- <button id="ctrlTab-showAll" class="ctrlTab-preview" noicon="true"/>
- </hbox>
- </panel>
-
- <panel id="allTabs-panel" hidden="true" norestorefocus="true" ignorekeys="true"
- onmouseover="allTabs._updateTabCloseButton(event);">
- <hbox id="allTabs-meta" align="center">
- <spacer flex="1"/>
- <textbox id="allTabs-filter"
- tooltiptext="&allTabs.filter.emptyText;"
- type="search"
- oncommand="allTabs.filter();"/>
- <spacer flex="1"/>
- <toolbarbutton class="KUI-panel-closebutton"
- oncommand="allTabs.close()"
- tooltiptext="&closeCmd.label;"/>
- </hbox>
- <stack id="allTabs-stack">
- <vbox id="allTabs-container"><hbox/></vbox>
- <toolbarbutton id="allTabs-tab-close-button"
- class="tabs-closebutton close-icon"
- oncommand="allTabs.closeTab(event);"
- tooltiptext="&closeCmd.label;"
- style="visibility:hidden"/>
- </stack>
- </panel>
-
- <!-- Bookmarks and history tooltip -->
- <tooltip id="bhTooltip"/>
-
- <panel id="customizeToolbarSheetPopup"
- noautohide="true"
- sheetstyle="&dialog.dimensions;"/>
-
- <tooltip id="tabbrowser-tab-tooltip" onpopupshowing="gBrowser.createTooltip(event);"/>
-
- <tooltip id="back-button-tooltip">
- <label class="tooltip-label" value="&backButton.tooltip;"/>
-#ifdef XP_MACOSX
- <label class="tooltip-label" value="&backForwardButtonMenuMac.tooltip;"/>
-#else
- <label class="tooltip-label" value="&backForwardButtonMenu.tooltip;"/>
-#endif
- </tooltip>
-
- <tooltip id="forward-button-tooltip">
- <label class="tooltip-label" value="&forwardButton.tooltip;"/>
-#ifdef XP_MACOSX
- <label class="tooltip-label" value="&backForwardButtonMenuMac.tooltip;"/>
-#else
- <label class="tooltip-label" value="&backForwardButtonMenu.tooltip;"/>
-#endif
- </tooltip>
-
-#include popup-notifications.inc
-
- </popupset>
-
-#ifdef CAN_DRAW_IN_TITLEBAR
-<vbox id="titlebar">
- <hbox id="titlebar-content">
-#ifdef MENUBAR_CAN_AUTOHIDE
- <hbox id="appmenu-button-container">
- <button id="appmenu-button"
- type="menu"
- label="&brandShortName;"
- tooltiptext="&appMenuButton.tooltip;"
- style="-moz-user-focus: ignore;">
-#include browser-appmenu.inc
- </button>
- </hbox>
-#endif
-#ifndef XP_MACOSX
- <spacer id="titlebar-spacer" flex="1"/>
-#endif
- <hbox id="titlebar-buttonbox-container" align="start">
- <hbox id="titlebar-buttonbox">
- <toolbarbutton class="titlebar-button" id="titlebar-min" oncommand="window.minimize();"/>
- <toolbarbutton class="titlebar-button" id="titlebar-max" oncommand="onTitlebarMaxClick();"/>
- <toolbarbutton class="titlebar-button" id="titlebar-close" command="cmd_closeWindow"/>
- </hbox>
- </hbox>
- </hbox>
-</vbox>
-#endif
-
-<deck flex="1" id="tab-view-deck">
-<vbox flex="1" id="browser-panel">
-
- <toolbox id="navigator-toolbox"
- defaultmode="icons" mode="icons"
- iconsize="large">
- <!-- Menu -->
- <toolbar type="menubar" id="toolbar-menubar" class="chromeclass-menubar" customizable="true"
- defaultset="menubar-items"
- mode="icons" iconsize="small" defaulticonsize="small"
- lockiconsize="true"
-#ifdef MENUBAR_CAN_AUTOHIDE
- toolbarname="&menubarCmd.label;"
- accesskey="&menubarCmd.accesskey;"
-#endif
- context="toolbar-context-menu">
- <toolbaritem id="menubar-items" align="center">
-# The entire main menubar is placed into browser-menubar.inc, so that it can be shared by
-# hiddenWindow.xul.
-#include browser-menubar.inc
- </toolbaritem>
-
-#ifdef CAN_DRAW_IN_TITLEBAR
- <hbox class="titlebar-placeholder" type="appmenu-button" ordinal="0"/>
- <hbox class="titlebar-placeholder" type="caption-buttons" ordinal="1000"/>
-#endif
- </toolbar>
-
- <toolbar id="nav-bar" class="toolbar-primary chromeclass-toolbar"
- toolbarname="&navbarCmd.label;" accesskey="&navbarCmd.accesskey;"
- fullscreentoolbar="true" mode="icons" customizable="true"
- iconsize="large"
- defaultset="unified-back-forward-button,reload-button,stop-button,home-button,urlbar-container,search-container,bookmarks-menu-button,history-menu-button,downloads-button,window-controls"
- context="toolbar-context-menu">
-
- <toolbaritem id="unified-back-forward-button" class="chromeclass-toolbar-additional"
- context="backForwardMenu" removable="true"
- forwarddisabled="true"
- title="&backForwardItem.title;">
- <toolbarbutton id="back-button" class="toolbarbutton-1"
- label="&backCmd.label;"
- command="Browser:BackOrBackDuplicate"
- onclick="checkForMiddleClick(this, event);"
- tooltip="back-button-tooltip"/>
- <toolbarbutton id="forward-button" class="toolbarbutton-1"
- label="&forwardCmd.label;"
- command="Browser:ForwardOrForwardDuplicate"
- onclick="checkForMiddleClick(this, event);"
- tooltip="forward-button-tooltip"/>
- <dummyobservertarget hidden="true"
- onbroadcast="if (this.getAttribute('disabled') == 'true')
- this.parentNode.setAttribute('forwarddisabled', 'true');
- else
- this.parentNode.removeAttribute('forwarddisabled');">
- <observes element="Browser:ForwardOrForwardDuplicate" attribute="disabled"/>
- </dummyobservertarget>
- </toolbaritem>
-
- <toolbarbutton id="reload-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
- label="&reloadCmd.label;" removable="true"
- command="Browser:ReloadOrDuplicate"
- onclick="checkForMiddleClick(this, event);"
- tooltiptext="&reloadButton.tooltip;"/>
-
- <toolbarbutton id="stop-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
- label="&stopCmd.label;" removable="true"
- command="Browser:Stop"
- tooltiptext="&stopButton.tooltip;"/>
-
- <toolbarbutton id="home-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
- persist="class" removable="true"
- label="&homeButton.label;"
- ondragover="homeButtonObserver.onDragOver(event)"
- ondragenter="homeButtonObserver.onDragOver(event)"
- ondrop="homeButtonObserver.onDrop(event)"
- ondragexit="homeButtonObserver.onDragExit(event)"
- onclick="BrowserGoHome(event);"
- aboutHomeOverrideTooltip="&abouthome.pageTitle;"/>
-
- <toolbaritem id="urlbar-container" align="center" flex="400" persist="width" combined="true"
- title="&locationItem.title;" class="chromeclass-location" removable="true">
- <textbox id="urlbar" flex="1"
- placeholder=""
- type="private-autocomplete"
- autocompletesearch="urlinline history"
- autocompletesearchparam="enable-actions"
- autocompletepopup="PopupAutoCompleteRichResult"
- completeselectedindex="true"
- tabscrolling="true"
- showcommentcolumn="true"
- showimagecolumn="true"
- enablehistory="true"
- maxrows="6"
- newlines="stripsurroundingwhitespace"
- oninput="gBrowser.userTypedValue = this.value;"
- ontextentered="this.handleCommand(param);"
- ontextreverted="return this.handleRevert();"
- pageproxystate="invalid"
- onfocus="document.getElementById('identity-box').style.MozUserFocus= 'normal'"
- onblur="setTimeout(function() document.getElementById('identity-box').style.MozUserFocus = '', 0);">
- <box id="notification-popup-box" hidden="true" align="center">
- <image id="default-notification-icon" class="notification-anchor-icon" role="button"/>
- <image id="geo-notification-icon" class="notification-anchor-icon" role="button"/>
- <image id="addons-notification-icon" class="notification-anchor-icon" role="button"/>
- <image id="indexedDB-notification-icon" class="notification-anchor-icon" role="button"/>
- <image id="password-notification-icon" class="notification-anchor-icon" role="button"/>
- <image id="plugins-notification-icon" class="notification-anchor-icon" role="button"/>
- <image id="web-notifications-notification-icon" class="notification-anchor-icon" role="button"/>
- <image id="alert-plugins-notification-icon" class="notification-anchor-icon" role="button"/>
- <image id="blocked-plugins-notification-icon" class="notification-anchor-icon" role="button"/>
- <image id="mixed-content-blocked-notification-icon" class="notification-anchor-icon" role="button"/>
-#ifdef MOZ_WEBRTC
- <image id="webRTC-shareDevices-notification-icon" class="notification-anchor-icon" role="button"/>
- <image id="webRTC-sharingDevices-notification-icon" class="notification-anchor-icon" role="button"/>
-#endif
- <image id="pointerLock-notification-icon" class="notification-anchor-icon" role="button"/>
- <image id="servicesInstall-notification-icon" class="notification-anchor-icon" role="button"/>
- </box>
- <!-- Use onclick instead of normal popup= syntax since the popup
- code fires onmousedown, and hence eats our favicon drag events.
- We only add the identity-box button to the tab order when the location bar
- has focus, otherwise pressing F6 focuses it instead of the location bar -->
- <box id="identity-box" role="button"
- align="center"
- onclick="gIdentityHandler.handleIdentityButtonEvent(event);"
- onkeypress="gIdentityHandler.handleIdentityButtonEvent(event);"
- ondragstart="gIdentityHandler.onDragStart(event);">
- <image id="page-proxy-favicon"
- onclick="PageProxyClickHandler(event);"
- pageproxystate="invalid"/>
- <hbox id="identity-icon-labels">
- <label id="identity-icon-label" class="plain" flex="1"/>
- <label id="identity-icon-country-label" class="plain"/>
- </hbox>
- </box>
- <box id="urlbar-display-box" align="center">
- <label id="urlbar-display" value="&urlbar.switchToTab.label;"/>
- </box>
- <hbox id="urlbar-icons">
- <image id="page-report-button"
- class="urlbar-icon"
- hidden="true"
- tooltiptext="&pageReportIcon.tooltip;"
- onclick="gPopupBlockerObserver.onReportButtonClick(event);"/>
- <button type="menu"
- style="-moz-user-focus: none"
- class="plain urlbar-icon"
- id="ub-feed-button"
- collapsed="true"
- tooltiptext="&feedButton.tooltip;"
- onclick="return FeedHandler.onFeedButtonPMClick(event);">
- <menupopup position="after_end"
- id="ub-feed-menu"
- onpopupshowing="return FeedHandler.buildFeedList(this);"
- oncommand="return FeedHandler.subscribeToFeed(null, event);"
- onclick="checkForMiddleClick(this, event);"/>
- </button>
- <image id="star-button"
- class="urlbar-icon"
- onclick="BookmarkingUI.onCommand(event);"/>
- <image id="go-button"
- class="urlbar-icon"
- tooltiptext="&goEndCap.tooltip;"
- onclick="gURLBar.handleCommand(event);"/>
- </hbox>
- <toolbarbutton id="urlbar-go-button"
- class="chromeclass-toolbar-additional"
- onclick="gURLBar.handleCommand(event);"
- tooltiptext="&goEndCap.tooltip;"/>
- <toolbarbutton id="urlbar-reload-button"
- class="chromeclass-toolbar-additional"
- command="Browser:ReloadOrDuplicate"
- onclick="checkForMiddleClick(this, event);"
- tooltiptext="&reloadButton.tooltip;"/>
- <toolbarbutton id="urlbar-stop-button"
- class="chromeclass-toolbar-additional"
- command="Browser:Stop"
- tooltiptext="&stopButton.tooltip;"/>
- </textbox>
- </toolbaritem>
-
- <toolbaritem id="search-container" title="&searchItem.title;"
- align="center" class="chromeclass-toolbar-additional"
- flex="100" persist="width" removable="true">
- <searchbar id="searchbar" flex="1"/>
- </toolbaritem>
-#ifdef MOZ_WEBRTC
- <toolbarbutton id="webrtc-status-button"
- class="toolbarbutton-1 chromeclass-toolbar-additional"
- type="menu"
- hidden="true"
- orient="horizontal"
- label="&webrtcIndicatorButton.label;"
- tooltiptext="&webrtcIndicatorButton.tooltip;">
- <menupopup onpopupshowing="WebrtcIndicator.fillPopup(this);"
- onpopuphiding="WebrtcIndicator.clearPopup(this);"
- oncommand="WebrtcIndicator.menuCommand(event.target);"/>
- </toolbarbutton>
-#endif
- <toolbarbutton id="bookmarks-menu-button"
- class="toolbarbutton-1 chromeclass-toolbar-additional"
- persist="class"
- removable="true"
- type="menu"
- label="&bookmarksMenuButton.label;"
- tooltiptext="&bookmarksMenuButton.tooltip;"
- onclick="if (event.button == 1)
- toggleSidebar('viewBookmarksSidebar');"
- ondragenter="PlacesMenuDNDHandler.onDragEnter(event);"
- ondragover="PlacesMenuDNDHandler.onDragOver(event);"
- ondragleave="PlacesMenuDNDHandler.onDragLeave(event);"
- ondrop="PlacesMenuDNDHandler.onDrop(event);">
- <menupopup id="BMB_bookmarksPopup"
- placespopup="true"
- context="placesContext"
- openInTabs="children"
- oncommand="BookmarksEventHandler.onCommand(event, this.parentNode._placesView);"
- onclick="event.stopPropagation();
- BookmarksEventHandler.onClick(event, this.parentNode._placesView);"
- onpopupshowing="BookmarkingUI.onPopupShowing(event);
- if (!this.parentNode._placesView)
- new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
- tooltip="bhTooltip" popupsinherittooltip="true">
- <menuitem id="BMB_viewBookmarksToolbar"
- placesanonid="view-toolbar"
- toolbarId="PersonalToolbar"
- type="checkbox"
- oncommand="onViewToolbarCommand(event)"
- label="&viewBookmarksToolbar.label;"/>
- <menuseparator/>
- <menuitem id="BMB_bookmarksShowAll"
-#ifndef XP_MACOSX
- class="menuitem-iconic"
-#endif
- label="&organizeBookmarks.label;"
- command="Browser:ShowAllBookmarks"
- key="manBookmarkKb"/>
- <menuseparator/>
- <menuitem id="BMB_bookmarkThisPage"
-#ifndef XP_MACOSX
- class="menuitem-iconic"
-#endif
- label="&bookmarkThisPageCmd.label;"
- command="Browser:AddBookmarkAs"
- key="addBookmarkAsKb"/>
- <menuitem id="BMB_subscribeToPageMenuitem"
-#ifndef XP_MACOSX
- class="menuitem-iconic"
-#endif
- label="&subscribeToPageMenuitem.label;"
- oncommand="return FeedHandler.subscribeToFeed(null, event);"
- onclick="checkForMiddleClick(this, event);"
- observes="singleFeedMenuitemState"/>
- <menu id="BMB_subscribeToPageMenupopup"
-#ifndef XP_MACOSX
- class="menu-iconic"
-#endif
- label="&subscribeToPageMenupopup.label;"
- observes="multipleFeedsMenuState">
- <menupopup id="BMB_subscribeToPageSubmenuMenupopup"
- onpopupshowing="return FeedHandler.buildFeedList(event.target);"
- oncommand="return FeedHandler.subscribeToFeed(null, event);"
- onclick="checkForMiddleClick(this, event);"/>
- </menu>
- <menuseparator/>
- <menu id="BMB_bookmarksToolbar"
- placesanonid="toolbar-autohide"
- class="menu-iconic bookmark-item"
- label="&personalbarCmd.label;"
- container="true">
- <menupopup id="BMB_bookmarksToolbarPopup"
- placespopup="true"
- context="placesContext"
- onpopupshowing="if (!this.parentNode._placesView)
- new PlacesMenu(event, 'place:folder=TOOLBAR');"/>
- </menu>
- <menuseparator/>
- <!-- Bookmarks menu items -->
- <menuseparator builder="end"
- class="hide-if-empty-places-result"/>
- <menuitem id="BMB_unsortedBookmarks"
- class="menuitem-iconic"
- label="&bookmarksMenuButton.unsorted.label;"
- oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"/>
- </menupopup>
- </toolbarbutton>
-
- <toolbarbutton id="history-menu-button"
- class="toolbarbutton-1 chromeclass-toolbar-additional"
- persist="class"
- removable="true"
- type="menu"
- label="&historyButton.label;"
- tooltiptext="&historyButton.tooltip;"
- onclick="if (event.button == 1)
- toggleSidebar('viewHistorySidebar');">
- <menupopup id="HMB_historyPopup"
- placespopup="true"
- context="placesContext"
- oncommand="this.parentNode._placesView._onCommand(event);"
- onclick="event.stopPropagation();
- checkForMiddleClick(this, event);"
- onpopupshowing="if (!this.parentNode._placesView)
- new HistoryMenu(event);"
- tooltip="bhTooltip"
- popupsinherittooltip="true">
- <menuitem id="HMB_showAllHistory"
- label="&showAllHistoryCmd2.label;"
-#ifndef XP_MACOSX
- class="menuitem-iconic"
- key="showAllHistoryKb"
-#endif
- command="Browser:ShowAllHistory"/>
- <menuitem id="HMB_sanitizeItem"
-#ifndef XP_MACOSX
- class="menuitem-iconic"
-#endif
- label="&clearRecentHistory.label;"
- key="key_sanitize"
- command="Tools:Sanitize"/>
- <menuseparator id="HMB_sanitizeSeparator"/>
-#ifdef MOZ_SERVICES_SYNC
- <menuitem id="HMB_sync-tabs-menuitem"
- class="syncTabsMenuItem"
- label="&syncTabsMenu2.label;"
- oncommand="BrowserOpenSyncTabs();"
- disabled="true"/>
-#endif
- <menuitem id="HMB_historyRestoreLastSession"
- label="&historyRestoreLastSession.label;"
- command="Browser:RestoreLastSession"/>
- <menu id="HMB_historyUndoMenu"
- class="recentlyClosedTabsMenu"
- label="&historyUndoMenu.label;"
- disabled="true">
- <menupopup id="HMB_historyUndoPopup"
- placespopup="true"
- onpopupshowing="document.getElementById('history-menu-button')._placesView.populateUndoSubmenu();"/>
- </menu>
- <menu id="HMB_historyUndoWindowMenu"
- class="recentlyClosedWindowsMenu"
- label="&historyUndoWindowMenu.label;"
- disabled="true">
- <menupopup id="HMB_historyUndoWindowPopup"
- placespopup="true"
- onpopupshowing="document.getElementById('history-menu-button')._placesView.populateUndoWindowSubmenu();"/>
- </menu>
- <menuseparator id="HMB_startHistorySeparator"
- class="hide-if-empty-places-result"/>
- <!-- History menu items -->
- </menupopup>
- </toolbarbutton>
-
- <hbox id="window-controls" hidden="true" pack="end">
- <toolbarbutton id="minimize-button"
- tooltiptext="&fullScreenMinimize.tooltip;"
- oncommand="window.minimize();"/>
-
- <toolbarbutton id="restore-button"
- tooltiptext="&fullScreenRestore.tooltip;"
- oncommand="BrowserFullScreen();"/>
-
- <toolbarbutton id="close-button"
- tooltiptext="&fullScreenClose.tooltip;"
- oncommand="BrowserTryToCloseWindow();"/>
- </hbox>
- </toolbar>
-
- <toolbarset id="customToolbars" context="toolbar-context-menu"/>
-
- <toolbar id="PersonalToolbar"
- mode="icons" iconsize="small" defaulticonsize="small"
- lockiconsize="true"
- class="chromeclass-directories"
- context="toolbar-context-menu"
- defaultset="personal-bookmarks"
- toolbarname="&personalbarCmd.label;" accesskey="&personalbarCmd.accesskey;"
- collapsed="false"
- customizable="true">
- <toolbaritem flex="1" id="personal-bookmarks" title="&bookmarksItem.title;"
- removable="true">
- <hbox flex="1"
- id="PlacesToolbar"
- context="placesContext"
- onclick="BookmarksEventHandler.onClick(event, this._placesView);"
- oncommand="BookmarksEventHandler.onCommand(event, this._placesView);"
- tooltip="bhTooltip"
- popupsinherittooltip="true">
- <toolbarbutton class="bookmark-item bookmarks-toolbar-customize"
- mousethrough="never"
- label="&bookmarksToolbarItem.label;"/>
- <hbox flex="1">
- <hbox align="center">
- <image id="PlacesToolbarDropIndicator"
- mousethrough="always"
- collapsed="true"/>
- </hbox>
- <scrollbox orient="horizontal"
- id="PlacesToolbarItems"
- flex="1"/>
- <toolbarbutton type="menu"
- id="PlacesChevron"
- class="chevron"
- mousethrough="never"
- collapsed="true"
- tooltiptext="&bookmarksToolbarChevron.tooltip;"
- onpopupshowing="document.getElementById('PlacesToolbar')
- ._placesView._onChevronPopupShowing(event);">
- <menupopup id="PlacesChevronPopup"
- placespopup="true"
- tooltip="bhTooltip" popupsinherittooltip="true"
- context="placesContext"/>
- </toolbarbutton>
- </hbox>
- </hbox>
- </toolbaritem>
- </toolbar>
-
-#ifdef MENUBAR_CAN_AUTOHIDE
-#ifndef CAN_DRAW_IN_TITLEBAR
-#define APPMENU_ON_TABBAR
-#endif
-#endif
-
-
- <toolbar id="TabsToolbar"
- class="toolbar-primary"
- fullscreentoolbar="true"
- customizable="true"
- mode="icons" lockmode="true"
- iconsize="small" defaulticonsize="small" lockiconsize="true"
- aria-label="&tabsToolbar.label;"
- context="toolbar-context-menu"
-#ifdef APPMENU_ON_TABBAR
- defaultset="appmenu-toolbar-button,tabbrowser-tabs,new-tab-button,alltabs-button,tabs-closebutton"
-#else
- defaultset="tabbrowser-tabs,new-tab-button,alltabs-button,tabs-closebutton"
-#endif
- collapsed="true">
-
-#ifdef APPMENU_ON_TABBAR
- <toolbarbutton id="appmenu-toolbar-button"
- class="chromeclass-toolbar-additional"
- type="menu"
- label="&brandShortName;"
- tooltiptext="&appMenuButton.tooltip;">
-#include browser-appmenu.inc
- </toolbarbutton>
-#endif
-
- <tabs id="tabbrowser-tabs"
- class="tabbrowser-tabs"
- tabbrowser="content"
- flex="1"
- setfocus="false"
- tooltip="tabbrowser-tab-tooltip">
- <tab class="tabbrowser-tab" selected="true" fadein="true"/>
- </tabs>
-
- <toolbarbutton id="new-tab-button"
- class="toolbarbutton-1 chromeclass-toolbar-additional"
- label="&tabCmd.label;"
- command="cmd_newNavigatorTab"
- onclick="checkForMiddleClick(this, event);"
- tooltiptext="&newTabButton.tooltip;"
- ondrop="newTabButtonObserver.onDrop(event)"
- ondragover="newTabButtonObserver.onDragOver(event)"
- ondragenter="newTabButtonObserver.onDragOver(event)"
- ondragexit="newTabButtonObserver.onDragExit(event)"
- removable="true"/>
-
- <toolbarbutton id="alltabs-button"
- class="toolbarbutton-1 chromeclass-toolbar-additional tabs-alltabs-button"
- type="menu"
- label="&listAllTabs.label;"
- tooltiptext="&listAllTabs.label;"
- removable="true">
- <menupopup id="alltabs-popup" position="after_end"/>
- </toolbarbutton>
-
- <toolbarbutton id="tabs-closebutton"
- class="close-button tabs-closebutton close-icon"
- command="cmd_close"
- label="&closeTab.label;"
- tooltiptext="&closeTab.label;"/>
-
-#ifdef CAN_DRAW_IN_TITLEBAR
- <hbox class="titlebar-placeholder" type="appmenu-button" ordinal="0"/>
- <hbox class="titlebar-placeholder" type="caption-buttons" ordinal="1000"/>
-#endif
- </toolbar>
-
- <toolbarpalette id="BrowserToolbarPalette">
-
-# Update primaryToolbarButtons in browser/themes/shared/browser.inc when adding
-# or removing default items with the toolbarbutton-1 class.
-
- <toolbarbutton id="print-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
- label="&printButton.label;" command="cmd_print"
- tooltiptext="&printButton.tooltip;"/>
-
- <!-- This is a placeholder for the Downloads Indicator. It is visible
- during the customization of the toolbar, in the palette, and before
- the Downloads Indicator overlay is loaded. -->
- <toolbarbutton id="downloads-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
- oncommand="DownloadsIndicatorView.onCommand(event);"
- ondrop="DownloadsIndicatorView.onDrop(event);"
- ondragover="DownloadsIndicatorView.onDragOver(event);"
- ondragenter="DownloadsIndicatorView.onDragOver(event);"
- label="&downloads.label;"
- tooltiptext="&downloads.tooltip;"/>
-
- <toolbarbutton id="history-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
- observes="viewHistorySidebar" label="&historyButton.label;"
- tooltiptext="&historyButton.tooltip;"/>
-
- <toolbarbutton id="bookmarks-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
- observes="viewBookmarksSidebar" label="&bookmarksButton.label;"
- tooltiptext="&bookmarksButton.tooltip;"
- ondrop="bookmarksButtonObserver.onDrop(event)"
- ondragover="bookmarksButtonObserver.onDragOver(event)"
- ondragenter="bookmarksButtonObserver.onDragOver(event)"
- ondragexit="bookmarksButtonObserver.onDragExit(event)"/>
-
- <toolbarbutton id="new-window-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
- label="&newNavigatorCmd.label;"
- command="key_newNavigator"
- tooltiptext="&newWindowButton.tooltip;"
- ondrop="newWindowButtonObserver.onDrop(event)"
- ondragover="newWindowButtonObserver.onDragOver(event)"
- ondragenter="newWindowButtonObserver.onDragOver(event)"
- ondragexit="newWindowButtonObserver.onDragExit(event)"/>
-
- <toolbarbutton id="fullscreen-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
- observes="View:FullScreen"
- type="checkbox"
- label="&fullScreenCmd.label;"
- tooltiptext="&fullScreenButton.tooltip;"/>
-
- <toolbaritem id="zoom-controls" class="chromeclass-toolbar-additional"
- title="&zoomControls.label;">
- <toolbarbutton id="zoom-out-button" class="toolbarbutton-1"
- label="&fullZoomReduceCmd.label;"
- command="cmd_fullZoomReduce"
- tooltiptext="&zoomOutButton.tooltip;"/>
- <toolbarbutton id="zoom-in-button" class="toolbarbutton-1"
- label="&fullZoomEnlargeCmd.label;"
- command="cmd_fullZoomEnlarge"
- tooltiptext="&zoomInButton.tooltip;"/>
- </toolbaritem>
-
- <toolbarbutton id="feed-button"
- type="menu"
- class="toolbarbutton-1 chromeclass-toolbar-additional"
- disabled="true"
- label="&feedButton.label;"
- tooltiptext="&feedButton.tooltip;"
- onclick="return FeedHandler.onFeedButtonClick(event);">
- <menupopup position="after_end"
- id="feed-menu"
- onpopupshowing="return FeedHandler.buildFeedList(this);"
- oncommand="return FeedHandler.subscribeToFeed(null, event);"
- onclick="checkForMiddleClick(this, event);"/>
- </toolbarbutton>
-
- <toolbarbutton id="cut-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
- label="&cutCmd.label;"
- command="cmd_cut"
- tooltiptext="&cutButton.tooltip;"/>
-
- <toolbarbutton id="copy-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
- label="&copyCmd.label;"
- command="cmd_copy"
- tooltiptext="&copyButton.tooltip;"/>
-
- <toolbarbutton id="paste-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
- label="&pasteCmd.label;"
- command="cmd_paste"
- tooltiptext="&pasteButton.tooltip;"/>
-
-#ifdef MOZ_SERVICES_SYNC
- <toolbarbutton id="sync-button"
- class="toolbarbutton-1 chromeclass-toolbar-additional"
- label="&syncToolbarButton.label;"
- oncommand="gSyncUI.handleToolbarButton()"/>
-#endif
-
- <toolbaritem id="navigator-throbber" title="&throbberItem.title;" align="center" pack="center"
- mousethrough="always">
- <image/>
- </toolbaritem>
- </toolbarpalette>
- </toolbox>
-
- <hbox id="fullscr-toggler" hidden="true"/>
-
- <hbox flex="1" id="browser">
- <vbox id="browser-border-start" hidden="true" layer="true"/>
- <vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">
- <sidebarheader id="sidebar-header" align="center">
- <label id="sidebar-title" persist="value" flex="1" crop="end" control="sidebar"/>
- <image id="sidebar-throbber"/>
- <toolbarbutton class="tabs-closebutton close-icon" tooltiptext="&sidebarCloseButton.tooltip;" oncommand="toggleSidebar();"/>
- </sidebarheader>
- <browser id="sidebar" flex="1" autoscroll="false" disablehistory="true"
- style="min-width: 14em; width: 18em; max-width: 36em;"/>
- </vbox>
-
- <splitter id="sidebar-splitter" class="chromeclass-extrachrome sidebar-splitter" hidden="true"/>
- <vbox id="appcontent" flex="1">
- <tabbrowser id="content" disablehistory="true"
- flex="1" contenttooltip="aHTMLTooltip"
- tabcontainer="tabbrowser-tabs"
- contentcontextmenu="contentAreaContextMenu"
- autocompletepopup="PopupAutoComplete"
- datetimepicker="DateTimePickerPanel"
- authdosprotected="true"/>
- <chatbar id="pinnedchats" layer="true" mousethrough="always" hidden="true"/>
- <statuspanel id="statusbar-display" inactive="true"/>
- </vbox>
- <vbox id="browser-border-end" hidden="true" layer="true"/>
- </hbox>
-
- <hbox id="full-screen-warning-container" hidden="true" fadeout="true">
- <hbox style="width: 100%;" pack="center"> <!-- Inner hbox needed due to bug 579776. -->
- <vbox id="full-screen-warning-message" align="center">
- <description id="full-screen-domain-text"/>
- <description class="full-screen-description" value="&fullscreenExitHint.value;"/>
- </vbox>
- </hbox>
- </hbox>
-
- <vbox id="browser-bottombox" layer="true">
- <notificationbox id="global-notificationbox"/>
- <toolbar id="addon-bar"
- toolbarname="&statusBar.label;" accesskey="&statusBar.accesskey;"
- collapsed="true"
- class="toolbar-primary chromeclass-toolbar"
- context="toolbar-context-menu" toolboxid="navigator-toolbox"
- mode="icons" iconsize="small" defaulticonsize="small"
- lockiconsize="true"
- defaultset="addonbar-closebutton,spring,status-bar"
- customizable="true"
- key="key_toggleAddonBar">
- <toolbarbutton id="addonbar-closebutton"
- class="close-icon"
- tooltiptext="&addonBarCloseButton.tooltip;"
- oncommand="setToolbarVisibility(this.parentNode, false);"/>
- <statusbar id="status-bar" ordinal="1000"/>
- </toolbar>
- </vbox>
-
-#ifndef XP_UNIX
- <svg:svg height="0">
- <svg:clipPath id="windows-keyhole-forward-clip-path" clipPathUnits="objectBoundingBox">
- <svg:path d="M 0,0 C 0.16,0.11 0.28,0.29 0.28,0.5 0.28,0.71 0.16,0.89 0,1 L 1,1 1,0 0,0 z"/>
- </svg:clipPath>
- <svg:clipPath id="windows-urlbar-back-button-clip-path" clipPathUnits="userSpaceOnUse">
- <svg:path d="M 0,0 0,7.8 C 2.5,11 4,14 4,18 4,22 2.5,25 0,28 l 0,22 10000,0 0,-50 L 0,0 z"/>
- </svg:clipPath>
- </svg:svg>
-#endif
-#ifdef XP_MACOSX
- <svg:svg height="0">
- <svg:clipPath id="osx-keyhole-forward-clip-path" clipPathUnits="objectBoundingBox">
- <svg:path d="M 0,0 C 0.15,0.12 0.25,0.3 0.25,0.5 0.25,0.7 0.15,0.88 0,1 L 1,1 1,0 0,0 z"/>
- </svg:clipPath>
- <svg:clipPath id="osx-urlbar-back-button-clip-path" clipPathUnits="userSpaceOnUse">
- <svg:path d="m 0,-5 0,4.03 C 3.6,1.8 6,6.1 6,11 6,16 3.6,20 0,23 l 0,27 10000,0 0,-55 L 0,-5 z"/>
- </svg:clipPath>
- <svg:clipPath id="osx-tab-ontop-left-curve-clip-path" clipPathUnits="userSpaceOnUse">
- <svg:path d="M 9,0 C 7.3,0 6,1.3 6,3 l 0,14 c 0,3 -2.2,5 -5,5 l -1,0 0,1 12,0 0,-1 0,-19 0,-3 -3,0 z"/>
- </svg:clipPath>
- <svg:clipPath id="osx-tab-ontop-right-curve-clip-path" clipPathUnits="userSpaceOnUse">
- <svg:path d="m 0,0 0,3 0,19 0,1 12,0 0,-1 -1,0 C 8.2,22 6,20 6,17 L 6,3 C 6,1.3 4.7,0 3,0 L 0,0 z"/>
- </svg:clipPath>
- <svg:clipPath id="osx-tab-onbottom-left-curve-clip-path" clipPathUnits="userSpaceOnUse">
- <svg:path d="m 0,0 0,1 1,0 c 2.8,0 5,2.2 5,5 l 0,14 c 0,2 1.3,3 3,3 l 3,0 0,-3 L 12,1 12,0 0,0 z"/>
- </svg:clipPath>
- <svg:clipPath id="osx-tab-onbottom-right-curve-clip-path" clipPathUnits="userSpaceOnUse">
- <svg:path d="m 0,0 0,1 0,19 0,3 3,0 c 1.7,0 3,-1 3,-3 L 6,6 C 6,3.2 8.2,1 11,1 L 12,1 12,0 0,0 z"/>
- </svg:clipPath>
- </svg:svg>
-#endif
-
-</vbox>
-# <iframe id="tab-view"> is dynamically appended as the 2nd child of #tab-view-deck.
-# Introducing the iframe dynamically, as needed, was found to be better than
-# starting with an empty iframe here in browser.xul from a Ts standpoint.
-</deck>
-
-</window>
diff --git a/base/content/browserMountPoints.inc b/base/content/browserMountPoints.inc
deleted file mode 100644
index e4315b0..0000000
--- a/base/content/browserMountPoints.inc
+++ /dev/null
@@ -1,12 +0,0 @@
-<stringbundleset id="stringbundleset"/>
-
-<commandset id="mainCommandSet"/>
-<commandset id="baseMenuCommandSet"/>
-<commandset id="placesCommands"/>
-
-<broadcasterset id="mainBroadcasterSet"/>
-
-<keyset id="mainKeyset"/>
-<keyset id="baseMenuKeyset"/>
-
-<menubar id="main-menubar"/> \ No newline at end of file
diff --git a/base/content/content.js b/base/content/content.js
deleted file mode 100644
index 211a24a..0000000
--- a/base/content/content.js
+++ /dev/null
@@ -1,177 +0,0 @@
-/* -*- 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 Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
- "resource://gre/modules/BrowserUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerContent",
- "resource://gre/modules/LoginManagerContent.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "LoginFormFactory",
- "resource://gre/modules/LoginManagerContent.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "InsecurePasswordUtils",
- "resource://gre/modules/InsecurePasswordUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "FormSubmitObserver",
- "resource:///modules/FormSubmitObserver.jsm");
-
-// Bug 671101 - directly using webNavigation in this context
-// causes docshells to leak
-this.__defineGetter__("webNavigation", function () {
- return docShell.QueryInterface(Ci.nsIWebNavigation);
-});
-
-addMessageListener("WebNavigation:LoadURI", function (message) {
- let flags = message.json.flags || webNavigation.LOAD_FLAGS_NONE;
-
- webNavigation.loadURI(message.json.uri, flags, null, null, null);
-});
-
-// TabChildGlobal
-var global = this;
-
-// Load the form validation popup handler
-var formSubmitObserver = new FormSubmitObserver(content, this);
-
-addMessageListener("Browser:HideSessionRestoreButton", function (message) {
- // Hide session restore button on about:home
- let doc = content.document;
- let container;
- if (doc.documentURI.toLowerCase() == "about:home" &&
- (container = doc.getElementById("sessionRestoreContainer"))){
- container.hidden = true;
- }
-});
-
-addEventListener("DOMFormHasPassword", function(event) {
- LoginManagerContent.onDOMFormHasPassword(event, content);
- let formLike = LoginFormFactory.createFromForm(event.target);
- InsecurePasswordUtils.reportInsecurePasswords(formLike);
-});
-addEventListener("DOMAutoComplete", function(event) {
- LoginManagerContent.onUsernameInput(event);
-});
-addEventListener("blur", function(event) {
- LoginManagerContent.onUsernameInput(event);
-});
-
-// Provide gContextMenuContentData for 'sdk/context-menu'
-var handleContentContextMenu = function (event) {
- let defaultPrevented = event.defaultPrevented;
- if (!Services.prefs.getBoolPref("dom.event.contextmenu.enabled")) {
- let plugin = null;
- try {
- plugin = event.target.QueryInterface(Ci.nsIObjectLoadingContent);
- } catch (e) {}
- if (plugin && plugin.displayedType == Ci.nsIObjectLoadingContent.TYPE_PLUGIN) {
- // Don't open a context menu for plugins.
- return;
- }
-
- defaultPrevented = false;
- }
-
- if (defaultPrevented)
- return;
-
- let addonInfo = {};
- let subject = {
- event: event,
- addonInfo: addonInfo,
- };
- subject.wrappedJSObject = subject;
- Services.obs.notifyObservers(subject, "content-contextmenu", null);
-
- let doc = event.target.ownerDocument;
- let docLocation = doc.mozDocumentURIIfNotForErrorPages;
- docLocation = docLocation && docLocation.spec;
- let charSet = doc.characterSet;
- let baseURI = doc.baseURI;
- let referrer = doc.referrer;
- let referrerPolicy = doc.referrerPolicy;
- let frameOuterWindowID = doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils)
- .outerWindowID;
- let loginFillInfo = LoginManagerContent.getFieldContext(event.target);
-
- // The same-origin check will be done in nsContextMenu.openLinkInTab.
- let parentAllowsMixedContent = !!docShell.mixedContentChannel;
-
- // get referrer attribute from clicked link and parse it
- // if per element referrer is enabled, the element referrer overrules
- // the document wide referrer
- if (Services.prefs.getBoolPref("network.http.enablePerElementReferrer")) {
- let referrerAttrValue = Services.netUtils.parseAttributePolicyString(event.target.
- getAttribute("referrerpolicy"));
- if (referrerAttrValue !== Ci.nsIHttpChannel.REFERRER_POLICY_UNSET) {
- referrerPolicy = referrerAttrValue;
- }
- }
-
- // Media related cache info parent needs for saving
- let contentType = null;
- let contentDisposition = null;
- if (event.target.nodeType == Ci.nsIDOMNode.ELEMENT_NODE &&
- event.target instanceof Ci.nsIImageLoadingContent &&
- event.target.currentURI) {
-
- try {
- let imageCache =
- Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
- .getImgCacheForDocument(doc);
- let props =
- imageCache.findEntryProperties(event.target.currentURI, doc);
- try {
- contentType = props.get("type", Ci.nsISupportsCString).data;
- } catch (e) {}
- try {
- contentDisposition =
- props.get("content-disposition", Ci.nsISupportsCString).data;
- } catch (e) {}
- } catch (e) {}
- }
-
- let selectionInfo = BrowserUtils.getSelectionDetails(content);
-
- let loadContext = docShell.QueryInterface(Ci.nsILoadContext);
-
- let browser = docShell.chromeEventHandler;
- let mainWin = browser.ownerGlobal;
-
- mainWin.gContextMenuContentData = {
- isRemote: false,
- event: event,
- popupNode: event.target,
- browser: browser,
- addonInfo: addonInfo,
- documentURIObject: doc.documentURIObject,
- docLocation: docLocation,
- charSet: charSet,
- referrer: referrer,
- referrerPolicy: referrerPolicy,
- contentType: contentType,
- contentDisposition: contentDisposition,
- selectionInfo: selectionInfo,
- loginFillInfo,
- parentAllowsMixedContent,
- };
-}
-
-Cc["@mozilla.org/eventlistenerservice;1"]
- .getService(Ci.nsIEventListenerService)
- .addSystemEventListener(global, "contextmenu", handleContentContextMenu, false);
-
-// Lazily load the finder code
-addMessageListener("Finder:Initialize", function () {
- let {RemoteFinderListener} = Cu.import("resource://gre/modules/RemoteFinder.jsm", {});
- new RemoteFinderListener(global);
-});
-
-addEventListener("DOMWebNotificationClicked", function(event) {
- sendAsyncMessage("DOMWebNotificationClicked", {});
-}, false);
diff --git a/base/content/downloadManagerOverlay.xul b/base/content/downloadManagerOverlay.xul
deleted file mode 100644
index 9987820..0000000
--- a/base/content/downloadManagerOverlay.xul
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0"?>
-# 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/.
-
-<?xul-overlay href="chrome://browser/content/macBrowserOverlay.xul"?>
-
-<overlay id="downloadManagerOverlay"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<window id="downloadManager">
-
-#include browserMountPoints.inc
-
-<script type="application/javascript"><![CDATA[
- window.addEventListener("load", function(event) {
- // Bug 405696: Map Edit -> Find command to the download manager's command
- var findMenuItem = document.getElementById("menu_find");
- findMenuItem.setAttribute("command", "cmd_findDownload");
- findMenuItem.setAttribute("key", "key_findDownload");
-
- // Bug 429614: Map Edit -> Select All command to download manager's command
- let selectAllMenuItem = document.getElementById("menu_selectAll");
- selectAllMenuItem.setAttribute("command", "cmd_selectAllDownloads");
- selectAllMenuItem.setAttribute("key", "key_selectAllDownloads");
- }, false);
-]]></script>
-
-</window>
-
-</overlay>
diff --git a/base/content/global-devtools-theme-scripts.inc b/base/content/global-devtools-theme-scripts.inc
deleted file mode 100644
index 408728e..0000000
--- a/base/content/global-devtools-theme-scripts.inc
+++ /dev/null
@@ -1,6 +0,0 @@
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# 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/.
-
-<script type="application/javascript" src="chrome://browser/content/browser-devtools-theme.js"/>
diff --git a/base/content/global-scripts.inc b/base/content/global-scripts.inc
deleted file mode 100644
index b4de574..0000000
--- a/base/content/global-scripts.inc
+++ /dev/null
@@ -1,13 +0,0 @@
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# 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/.
-
-<script type="application/javascript" src="chrome://global/content/printUtils.js"/>
-<script type="application/javascript" src="chrome://global/content/viewZoomOverlay.js"/>
-<script type="application/javascript" src="chrome://browser/content/places/browserPlacesViews.js"/>
-<script type="application/javascript" src="chrome://browser/content/browser.js"/>
-<script type="application/javascript" src="chrome://browser/content/downloads/downloads.js"/>
-<script type="application/javascript" src="chrome://browser/content/downloads/indicator.js"/>
-<script type="application/javascript" src="chrome://global/content/inlineSpellCheckUI.js"/>
-<script type="application/javascript" src="chrome://global/content/viewSourceUtils.js"/>
diff --git a/base/content/hiddenWindow.xul b/base/content/hiddenWindow.xul
deleted file mode 100644
index bf201fd..0000000
--- a/base/content/hiddenWindow.xul
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0"?>
-# -*- Mode: HTML -*-
-#
-# 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/.
-
-#ifdef XP_MACOSX
-<?xul-overlay href="chrome://browser/content/macBrowserOverlay.xul"?>
-
-<window id="main-window"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-#include browserMountPoints.inc
-
-</window>
-
-#endif
diff --git a/base/content/highlighter.css b/base/content/highlighter.css
deleted file mode 100644
index 8fb9d80..0000000
--- a/base/content/highlighter.css
+++ /dev/null
@@ -1,105 +0,0 @@
-/* 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/. */
-
-.highlighter-container {
- pointer-events: none;
-}
-
-.highlighter-controls {
- position: absolute;
- top: 0;
- left: 0;
-}
-
-.highlighter-outline-container {
- overflow: hidden;
- position: relative;
-}
-
-.highlighter-outline {
- position: absolute;
-}
-
-.highlighter-outline[hidden] {
- opacity: 0;
- pointer-events: none;
- display: -moz-box;
-}
-
-.highlighter-outline:not([disable-transitions]) {
- transition-property: opacity, top, left, width, height;
- transition-duration: 0.1s;
- transition-timing-function: linear;
-}
-
-/*
- * Node Infobar
- */
-
-.highlighter-nodeinfobar-container {
- position: absolute;
- max-width: 95%;
-}
-
-.highlighter-nodeinfobar-container[hidden] {
- opacity: 0;
- pointer-events: none;
- display: -moz-box;
-}
-
-.highlighter-nodeinfobar-container:not([disable-transitions]),
-.highlighter-nodeinfobar-container[disable-transitions][force-transitions] {
- transition-property: transform, opacity, top, left;
- transition-duration: 0.1s;
- transition-timing-function: linear;
-}
-
-.highlighter-nodeinfobar-text {
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- direction: ltr;
-}
-
-.highlighter-nodeinfobar-button > .toolbarbutton-text {
- display: none;
-}
-
-.highlighter-nodeinfobar-container:not([locked]):not(:hover) > .highlighter-nodeinfobar > .highlighter-nodeinfobar-button {
- visibility: hidden;
-}
-
-.highlighter-nodeinfobar-container[locked] > .highlighter-nodeinfobar,
-.highlighter-nodeinfobar-container:not([locked]):hover > .highlighter-nodeinfobar {
- pointer-events: auto;
-}
-
-html|*.highlighter-nodeinfobar-id,
-html|*.highlighter-nodeinfobar-classes,
-html|*.highlighter-nodeinfobar-pseudo-classes,
-html|*.highlighter-nodeinfobar-tagname {
- -moz-user-select: text;
- -moz-user-focus: normal;
- cursor: text;
-}
-
-.highlighter-nodeinfobar-arrow {
- display: none;
-}
-
-.highlighter-nodeinfobar-container[position="top"]:not([hide-arrow]) > .highlighter-nodeinfobar-arrow-bottom {
- display: block;
-}
-
-.highlighter-nodeinfobar-container[position="bottom"]:not([hide-arrow]) > .highlighter-nodeinfobar-arrow-top {
- display: block;
-}
-
-.highlighter-nodeinfobar-container[disabled] {
- visibility: hidden;
-}
-
-html|*.highlighter-nodeinfobar-tagname {
- text-transform: lowercase;
-}
diff --git a/base/content/jsConsoleOverlay.xul b/base/content/jsConsoleOverlay.xul
deleted file mode 100644
index 1bc518d..0000000
--- a/base/content/jsConsoleOverlay.xul
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0"?>
-# 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/.
-
-<?xul-overlay href="chrome://browser/content/macBrowserOverlay.xul"?>
-
-<overlay id="jsConsoleOverlay"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<window id="JSConsoleWindow">
-
-#include browserMountPoints.inc
-
-</window>
-
-</overlay>
diff --git a/base/content/macBrowserOverlay.xul b/base/content/macBrowserOverlay.xul
deleted file mode 100644
index b1ae838..0000000
--- a/base/content/macBrowserOverlay.xul
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0"?>
-# -*- Mode: HTML -*-
-#
-# 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/.
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://browser/content/places/places.css" type="text/css"?>
-
-<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
-<?xul-overlay href="chrome://browser/content/baseMenuOverlay.xul"?>
-<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-
-# All DTD information is stored in a separate file so that it can be shared by
-# hiddenWindow.xul.
-#include browser-doctype.inc
-
-<overlay id="hidden-overlay"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-# All JS files which are not content (only) dependent that browser.xul
-# wishes to include *must* go into the global-scripts.inc file
-# so that they can be shared by this overlay.
-#include global-scripts.inc
-#ifdef MOZ_DEVTOOLS
-#include global-devtools-theme-scripts.inc
-#endif
-
-<script type="application/javascript">
- function OpenBrowserWindowFromDockMenu(options) {
- let win = OpenBrowserWindow(options);
- win.addEventListener("load", function listener() {
- win.removeEventListener("load", listener);
- let dockSupport = Cc["@mozilla.org/widget/macdocksupport;1"]
- .getService(Ci.nsIMacDockSupport);
- dockSupport.activateApplication(true);
- });
-
- return win;
- }
-
- addEventListener("load", function() { gBrowserInit.nonBrowserWindowStartup() }, false);
- addEventListener("unload", function() { gBrowserInit.nonBrowserWindowShutdown() }, false);
-</script>
-
-# All sets except for popupsets (commands, keys, stringbundles and broadcasters) *must* go into the
-# browser-sets.inc file for sharing with hiddenWindow.xul.
-#include browser-sets.inc
-
-# The entire main menubar is placed into browser-menubar.inc, so that it can be shared by
-# hiddenWindow.xul.
-#include browser-menubar.inc
-
-<!-- Dock menu -->
-<popupset>
- <menupopup id="menu_mac_dockmenu">
- <!-- The command cannot be cmd_newNavigator because we need to activate
- the application. -->
- <menuitem label="&newNavigatorCmd.label;" oncommand="OpenBrowserWindowFromDockMenu();"
- id="macDockMenuNewWindow" />
- <menuitem label="&newPrivateWindow.label;" oncommand="OpenBrowserWindowFromDockMenu({private: true});" />
- </menupopup>
-</popupset>
-
-</overlay>
diff --git a/base/content/nsContextMenu.js b/base/content/nsContextMenu.js
deleted file mode 100644
index 916dd26..0000000
--- a/base/content/nsContextMenu.js
+++ /dev/null
@@ -1,1603 +0,0 @@
-# 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/.
-
-Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
-
-var gContextMenuContentData = null;
-
-function nsContextMenu(aXulMenu, aIsShift) {
- this.shouldDisplay = true;
- this.initMenu(aXulMenu, aIsShift);
-}
-
-// Prototype for nsContextMenu "class."
-nsContextMenu.prototype = {
- initMenu: function CM_initMenu(aXulMenu, aIsShift) {
- // Get contextual info.
- this.setTarget(document.popupNode, document.popupRangeParent,
- document.popupRangeOffset);
- if (!this.shouldDisplay)
- return;
-
- this.hasPageMenu = false;
- if (!aIsShift) {
- this.hasPageMenu = PageMenu.maybeBuildAndAttachMenu(this.target,
- aXulMenu);
- }
-
- this.isFrameImage = document.getElementById("isFrameImage");
- this.ellipsis = "\u2026";
- try {
- this.ellipsis = gPrefService.getComplexValue("intl.ellipsis",
- Ci.nsIPrefLocalizedString).data;
- } catch (e) { }
-
- this.isContentSelected = this.isContentSelection();
- this.onPlainTextLink = false;
-
- // Initialize (disable/remove) menu items.
- this.initItems();
- },
-
- hiding: function CM_hiding() {
- gContextMenuContentData = null;
- InlineSpellCheckerUI.clearSuggestionsFromMenu();
- InlineSpellCheckerUI.clearDictionaryListFromMenu();
- InlineSpellCheckerUI.uninit();
- },
-
- initItems: function CM_initItems() {
- this.initPageMenuSeparator();
- this.initOpenItems();
- this.initNavigationItems();
- this.initViewItems();
- this.initMiscItems();
- this.initSpellingItems();
- this.initSaveItems();
- this.initClipboardItems();
- this.initMediaPlayerItems();
- this.initLeaveDOMFullScreenItems();
- this.initClickToPlayItems();
- },
-
- initPageMenuSeparator: function CM_initPageMenuSeparator() {
- this.showItem("page-menu-separator", this.hasPageMenu);
- },
-
- initOpenItems: function CM_initOpenItems() {
- var isMailtoInternal = false;
- if (this.onMailtoLink) {
- var mailtoHandler = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
- getService(Ci.nsIExternalProtocolService).
- getProtocolHandlerInfo("mailto");
- isMailtoInternal = (!mailtoHandler.alwaysAskBeforeHandling &&
- mailtoHandler.preferredAction == Ci.nsIHandlerInfo.useHelperApp &&
- (mailtoHandler.preferredApplicationHandler instanceof Ci.nsIWebHandlerApp));
- }
-
- // Time to do some bad things and see if we've highlighted a URL that
- // isn't actually linked.
- if (this.isTextSelected && !this.onLink) {
- // Ok, we have some text, let's figure out if it looks like a URL.
- let selection = document.commandDispatcher.focusedWindow
- .getSelection();
- let linkText = selection.toString().trim();
- let uri;
- if (/^(?:https?|ftp):/i.test(linkText)) {
- try {
- uri = makeURI(linkText);
- } catch (ex) {}
- }
- // Check if this could be a valid url, just missing the protocol.
- else if (/^[-a-z\d\.]+\.[-a-z\d]{2,}[-_=~:#%&\?\w\/\.]*$/i.test(linkText)) {
- let uriFixup = Cc["@mozilla.org/docshell/urifixup;1"]
- .getService(Ci.nsIURIFixup);
- try {
- uri = uriFixup.createFixupURI(linkText, uriFixup.FIXUP_FLAG_NONE);
- } catch (ex) {}
- }
-
- if (uri && uri.host) {
- this.linkURI = uri;
- this.linkURL = this.linkURI.spec;
- this.onPlainTextLink = true;
- }
- }
-
- var shouldShow = this.onSaveableLink || isMailtoInternal || this.onPlainTextLink;
- var isWindowPrivate = PrivateBrowsingUtils.isWindowPrivate(window);
- this.showItem("context-openlink", shouldShow && !isWindowPrivate);
- this.showItem("context-openlinkprivate", shouldShow);
- this.showItem("context-openlinkintab", shouldShow);
- this.showItem("context-openlinkincurrent", shouldShow);
- this.showItem("context-sep-open", shouldShow);
- },
-
- initNavigationItems: function CM_initNavigationItems() {
- var shouldShow = !(this.isContentSelected || this.onLink || this.onImage ||
- this.onCanvas || this.onVideo || this.onAudio ||
- this.onTextInput);
- this.showItem("context-back", shouldShow);
- this.showItem("context-forward", shouldShow);
-
- let stopped = XULBrowserWindow.stopCommand.getAttribute("disabled") == "true";
-
- let stopReloadItem = "";
- if (shouldShow) {
- stopReloadItem = stopped ? "reload" : "stop";
- }
-
- this.showItem("context-reload", stopReloadItem == "reload");
- this.showItem("context-stop", stopReloadItem == "stop");
- this.showItem("context-sep-stop", !!stopReloadItem);
-
- // XXX: Stop is determined in browser.js; the canStop broadcaster is broken
- //this.setItemAttrFromNode( "context-stop", "disabled", "canStop" );
- },
-
- initLeaveDOMFullScreenItems: function CM_initLeaveFullScreenItem() {
- // only show the option if the user is in DOM fullscreen
- var shouldShow = (this.target.ownerDocument.mozFullScreenElement != null);
- this.showItem("context-leave-dom-fullscreen", shouldShow);
-
- // Explicitly show if in DOM fullscreen, but do not hide it has already been shown
- if (shouldShow)
- this.showItem("context-media-sep-commands", true);
- },
-
- initSaveItems: function CM_initSaveItems() {
- var shouldShow = !(this.onTextInput || this.onLink ||
- this.isContentSelected || this.onImage ||
- this.onCanvas || this.onVideo || this.onAudio);
- this.showItem("context-savepage", shouldShow);
- this.showItem("context-sendpage", shouldShow);
-
- // Save+Send link depends on whether we're in a link, or selected text matches valid URL pattern.
- this.showItem("context-savelink", this.onSaveableLink || this.onPlainTextLink);
- this.showItem("context-sendlink", this.onSaveableLink || this.onPlainTextLink);
-
- // Save image depends on having loaded its content, video and audio don't.
- this.showItem("context-saveimage", this.onLoadedImage || this.onCanvas);
- this.showItem("context-savevideo", this.onVideo);
- this.showItem("context-saveaudio", this.onAudio);
- this.showItem("context-video-saveimage", this.onVideo);
- this.setItemAttr("context-savevideo", "disabled", !this.mediaURL);
- this.setItemAttr("context-saveaudio", "disabled", !this.mediaURL);
- // Send media URL (but not for canvas, since it's a big data: URL)
- this.showItem("context-sendimage", this.onImage);
- this.showItem("context-sendvideo", this.onVideo);
- this.showItem("context-sendaudio", this.onAudio);
- this.setItemAttr("context-sendvideo", "disabled", !this.mediaURL);
- this.setItemAttr("context-sendaudio", "disabled", !this.mediaURL);
- },
-
- initViewItems: function CM_initViewItems() {
- // View source is always OK, unless in directory listing.
- this.showItem("context-viewpartialsource-selection",
- this.isContentSelected);
- this.showItem("context-viewpartialsource-mathml",
- this.onMathML && !this.isContentSelected);
-
- var shouldShow = !(this.isContentSelected ||
- this.onImage || this.onCanvas ||
- this.onVideo || this.onAudio ||
- this.onLink || this.onTextInput);
- this.showItem("context-viewsource", shouldShow);
- this.showItem("context-viewinfo", shouldShow);
-#ifdef MOZ_DEVTOOLS
- var showInspect = gPrefService.getBoolPref("devtools.inspector.enabled");
- this.showItem("inspect-separator", showInspect);
- this.showItem("context-inspect", showInspect);
-#endif
-
- this.showItem("context-sep-viewsource", shouldShow);
-
- // Set as Desktop background depends on whether an image was clicked on,
- // and only works if we have a shell service.
- var haveSetDesktopBackground = false;
-#ifdef HAVE_SHELL_SERVICE
- // Only enable Set as Desktop Background if we can get the shell service.
- var shell = getShellService();
- if (shell)
- haveSetDesktopBackground = shell.canSetDesktopBackground;
-#endif
- this.showItem("context-setDesktopBackground",
- haveSetDesktopBackground && this.onLoadedImage);
-
- if (haveSetDesktopBackground && this.onLoadedImage) {
- document.getElementById("context-setDesktopBackground")
- .disabled = this.disableSetDesktopBackground();
- }
-
- // Reload image depends on an image that's not fully loaded
- this.showItem("context-reloadimage", (this.onImage && !this.onCompletedImage));
-
- // View image depends on having an image that's not standalone
- // (or is in a frame), or a canvas.
- this.showItem("context-viewimage", (this.onImage &&
- (!this.inSyntheticDoc || this.inFrame)) || this.onCanvas);
-
- // View video depends on not having a standalone video.
- this.showItem("context-viewvideo", this.onVideo && (!this.inSyntheticDoc || this.inFrame));
- this.setItemAttr("context-viewvideo", "disabled", !this.mediaURL);
-
- // View background image depends on whether there is one, but don't make
- // background images of a stand-alone media document available.
- this.showItem("context-viewbgimage", shouldShow &&
- !this._hasMultipleBGImages &&
- !this.inSyntheticDoc);
- this.showItem("context-sep-viewbgimage", shouldShow &&
- !this._hasMultipleBGImages &&
- !this.inSyntheticDoc);
- document.getElementById("context-viewbgimage")
- .disabled = !this.hasBGImage;
-
- this.showItem("context-viewimageinfo", this.onImage);
- },
-
- initMiscItems: function CM_initMiscItems() {
- // Use "Bookmark This Link" if on a link.
- this.showItem("context-bookmarkpage",
- !(this.isContentSelected || this.onTextInput || this.onLink ||
- this.onImage || this.onVideo || this.onAudio));
- this.showItem("context-bookmarklink", (this.onLink && !this.onMailtoLink) ||
- this.onPlainTextLink);
- this.showItem("context-keywordfield",
- this.onTextInput && this.onKeywordField);
- this.showItem("frame", this.inFrame);
-
- let showSearchSelect = (this.isTextSelected || this.onLink) && !this.onImage;
- this.showItem("context-searchselect", showSearchSelect);
- if (showSearchSelect) {
- this.formatSearchContextItem();
- }
-
- // srcdoc cannot be opened separately due to concerns about web
- // content with about:srcdoc in location bar masquerading as trusted
- // chrome/addon content.
- // No need to also test for this.inFrame as this is checked in the parent
- // submenu.
- this.showItem("context-showonlythisframe", !this.inSrcdocFrame);
- this.showItem("context-openframeintab", !this.inSrcdocFrame);
- this.showItem("context-openframe", !this.inSrcdocFrame);
- this.showItem("context-bookmarkframe", !this.inSrcdocFrame);
- this.showItem("open-frame-sep", !this.inSrcdocFrame);
-
- this.showItem("frame-sep", this.inFrame && this.isTextSelected);
-
- // Hide menu entries for images, show otherwise
- if (this.inFrame) {
- if (BrowserUtils.mimeTypeIsTextBased(this.target.ownerDocument.contentType))
- this.isFrameImage.removeAttribute('hidden');
- else
- this.isFrameImage.setAttribute('hidden', 'true');
- }
-
- // BiDi UI
- this.showItem("context-sep-bidi", top.gBidiUI);
- this.showItem("context-bidi-text-direction-toggle",
- this.onTextInput && top.gBidiUI);
- this.showItem("context-bidi-page-direction-toggle",
- !this.onTextInput && top.gBidiUI);
- },
-
- initSpellingItems: function() {
- var canSpell = InlineSpellCheckerUI.canSpellCheck && this.canSpellCheck;
- var onMisspelling = InlineSpellCheckerUI.overMisspelling;
- var showUndo = canSpell && InlineSpellCheckerUI.canUndo();
- this.showItem("spell-check-enabled", canSpell);
- this.showItem("spell-separator", canSpell || this.onEditableArea);
- document.getElementById("spell-check-enabled")
- .setAttribute("checked", canSpell && InlineSpellCheckerUI.enabled);
-
- this.showItem("spell-add-to-dictionary", onMisspelling);
- this.showItem("spell-undo-add-to-dictionary", showUndo);
-
- // suggestion list
- this.showItem("spell-suggestions-separator", onMisspelling || showUndo);
- if (onMisspelling) {
- var suggestionsSeparator =
- document.getElementById("spell-add-to-dictionary");
- var numsug =
- InlineSpellCheckerUI.addSuggestionsToMenu(suggestionsSeparator.parentNode,
- suggestionsSeparator, 5);
- this.showItem("spell-no-suggestions", numsug == 0);
- }
- else
- this.showItem("spell-no-suggestions", false);
-
- // dictionary list
- this.showItem("spell-dictionaries", canSpell && InlineSpellCheckerUI.enabled);
- if (canSpell) {
- var dictMenu = document.getElementById("spell-dictionaries-menu");
- var dictSep = document.getElementById("spell-language-separator");
- InlineSpellCheckerUI.addDictionaryListToMenu(dictMenu, dictSep);
- this.showItem("spell-add-dictionaries-main", false);
- }
- else if (this.onEditableArea) {
- // when there is no spellchecker but we might be able to spellcheck
- // add the add to dictionaries item. This will ensure that people
- // with no dictionaries will be able to download them
- this.showItem("spell-add-dictionaries-main", true);
- }
- else
- this.showItem("spell-add-dictionaries-main", false);
- },
-
- initClipboardItems: function() {
- // Copy depends on whether there is selected text.
- // Enabling this context menu item is now done through the global
- // command updating system
- // this.setItemAttr( "context-copy", "disabled", !this.isTextSelected() );
- goUpdateGlobalEditMenuItems();
-
- this.showItem("context-undo", this.onTextInput);
- this.showItem("context-sep-undo", this.onTextInput);
- this.showItem("context-cut", this.onTextInput);
- this.showItem("context-copy",
- this.isContentSelected || this.onTextInput);
- this.showItem("context-paste", this.onTextInput);
- this.showItem("context-delete", this.onTextInput);
- this.showItem("context-sep-paste", this.onTextInput);
- this.showItem("context-selectall", !(this.onLink || this.onImage ||
- this.onVideo || this.onAudio ||
- this.inSyntheticDoc) ||
- this.isDesignMode);
- this.showItem("context-sep-selectall", this.isContentSelected );
-
- // XXX dr
- // ------
- // nsDocumentViewer.cpp has code to determine whether we're
- // on a link or an image. we really ought to be using that...
-
- // Copy email link depends on whether we're on an email link.
- this.showItem("context-copyemail", this.onMailtoLink);
-
- // Copy link location depends on whether we're on a non-mailto link.
- this.showItem("context-copylink", this.onLink && !this.onMailtoLink);
- this.showItem("context-sep-copylink", this.onLink &&
- (this.onImage || this.onVideo || this.onAudio));
-
-#ifdef CONTEXT_COPY_IMAGE_CONTENTS
- // Copy image contents depends on whether we're on an image.
- this.showItem("context-copyimage-contents", this.onImage);
-#endif
- // Copy image location depends on whether we're on an image.
- this.showItem("context-copyimage", this.onImage);
- this.showItem("context-copyvideourl", this.onVideo);
- this.showItem("context-copyaudiourl", this.onAudio);
- this.setItemAttr("context-copyvideourl", "disabled", !this.mediaURL);
- this.setItemAttr("context-copyaudiourl", "disabled", !this.mediaURL);
- this.showItem("context-sep-copyimage", this.onImage ||
- this.onVideo || this.onAudio);
- },
-
- initMediaPlayerItems: function() {
- var onMedia = (this.onVideo || this.onAudio);
- // Several mutually exclusive items... play/pause, mute/unmute, show/hide
- this.showItem("context-media-play", onMedia && (this.target.paused || this.target.ended));
- this.showItem("context-media-pause", onMedia && !this.target.paused && !this.target.ended);
- this.showItem("context-media-mute", onMedia && !this.target.muted);
- this.showItem("context-media-unmute", onMedia && this.target.muted);
- this.showItem("context-media-playbackrate", onMedia);
- this.showItem("context-media-loop", onMedia);
- this.showItem("context-media-showcontrols", onMedia && !this.target.controls);
- this.showItem("context-media-hidecontrols", onMedia && this.target.controls);
- this.showItem("context-video-fullscreen", this.onVideo && this.target.ownerDocument.mozFullScreenElement == null);
- var statsShowing = this.onVideo && XPCNativeWrapper.unwrap(this.target).mozMediaStatisticsShowing;
- this.showItem("context-video-showstats", this.onVideo && this.target.controls && !statsShowing);
- this.showItem("context-video-hidestats", this.onVideo && this.target.controls && statsShowing);
-
- // Disable them when there isn't a valid media source loaded.
- if (onMedia) {
- this.setItemAttr("context-media-playbackrate-050x", "checked", this.target.playbackRate == 0.5);
- this.setItemAttr("context-media-playbackrate-100x", "checked", this.target.playbackRate == 1.0);
- this.setItemAttr("context-media-playbackrate-150x", "checked", this.target.playbackRate == 1.5);
- this.setItemAttr("context-media-playbackrate-200x", "checked", this.target.playbackRate == 2.0);
- this.setItemAttr("context-media-loop", "checked", this.target.loop);
- var hasError = this.target.error != null ||
- this.target.networkState == this.target.NETWORK_NO_SOURCE;
- this.setItemAttr("context-media-play", "disabled", hasError);
- this.setItemAttr("context-media-pause", "disabled", hasError);
- this.setItemAttr("context-media-mute", "disabled", hasError);
- this.setItemAttr("context-media-unmute", "disabled", hasError);
- this.setItemAttr("context-media-playbackrate", "disabled", hasError);
- this.setItemAttr("context-media-playbackrate-050x", "disabled", hasError);
- this.setItemAttr("context-media-playbackrate-100x", "disabled", hasError);
- this.setItemAttr("context-media-playbackrate-150x", "disabled", hasError);
- this.setItemAttr("context-media-playbackrate-200x", "disabled", hasError);
- this.setItemAttr("context-media-showcontrols", "disabled", hasError);
- this.setItemAttr("context-media-hidecontrols", "disabled", hasError);
- if (this.onVideo) {
- let canSaveSnapshot = this.target.readyState >= this.target.HAVE_CURRENT_DATA;
- this.setItemAttr("context-video-saveimage", "disabled", !canSaveSnapshot);
- this.setItemAttr("context-video-fullscreen", "disabled", hasError);
- this.setItemAttr("context-video-showstats", "disabled", hasError);
- this.setItemAttr("context-video-hidestats", "disabled", hasError);
- }
- }
- this.showItem("context-media-sep-commands", onMedia);
- },
-
- initClickToPlayItems: function() {
- this.showItem("context-ctp-play", this.onCTPPlugin);
- this.showItem("context-ctp-hide", this.onCTPPlugin);
- this.showItem("context-sep-ctp", this.onCTPPlugin);
- },
-
- inspectNode: function CM_inspectNode() {
- let {devtools} = Cu.import("resource://devtools/shared/Loader.jsm", {});
- let gBrowser = this.browser.ownerDocument.defaultView.gBrowser;
- let target = devtools.TargetFactory.forTab(gBrowser.selectedTab);
-
- return gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
- let inspector = toolbox.getCurrentPanel();
-
- this.browser.messageManager.sendAsyncMessage("debug:inspect", {}, {node: this.target});
- inspector.walker.findInspectingNode().then(nodeFront => {
- inspector.selection.setNodeFront(nodeFront, "browser-context-menu");
- });
- }.bind(this));
- },
-
- // Set various context menu attributes based on the state of the world.
- setTarget: function (aNode, aRangeParent, aRangeOffset) {
- const xulNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- if (aNode.namespaceURI == xulNS ||
- aNode.nodeType == Node.DOCUMENT_NODE ||
- this.isDisabledForEvents(aNode)) {
- this.shouldDisplay = false;
- return;
- }
-
- // Initialize contextual info.
- this.onImage = false;
- this.onLoadedImage = false;
- this.onCompletedImage = false;
- this.onCanvas = false;
- this.onVideo = false;
- this.onAudio = false;
- this.onTextInput = false;
- this.onKeywordField = false;
- this.mediaURL = "";
- this.onLink = false;
- this.onMailtoLink = false;
- this.onSaveableLink = false;
- this.link = null;
- this.linkURL = "";
- this.linkURI = null;
- this.linkProtocol = "";
- this.linkDownload = "";
- this.onMathML = false;
- this.inFrame = false;
- this.inSrcdocFrame = false;
- this.inSyntheticDoc = false;
- this.hasBGImage = false;
- this.bgImageURL = "";
- this.onEditableArea = false;
- this.isDesignMode = false;
- this.onCTPPlugin = false;
- this.canSpellCheck = false;
- this.textSelected = getBrowserSelection();
- this.isTextSelected = this.textSelected.length != 0;
-
- // Remember the node that was clicked.
- this.target = aNode;
-
- this.browser = this.target.ownerDocument.defaultView
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell)
- .chromeEventHandler;
-
- // Check if we are in a synthetic document (stand alone image, video, etc.).
- this.inSyntheticDoc = this.target.ownerDocument.mozSyntheticDocument;
- // First, do checks for nodes that never have children.
- if (this.target.nodeType == Node.ELEMENT_NODE) {
- // See if the user clicked on an image.
- if (this.target instanceof Ci.nsIImageLoadingContent &&
- this.target.currentURI) {
- this.onImage = true;
-
- var request =
- this.target.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
- if (request && (request.imageStatus & request.STATUS_SIZE_AVAILABLE))
- this.onLoadedImage = true;
- if (request && (request.imageStatus & request.STATUS_LOAD_COMPLETE))
- this.onCompletedImage = true;
-
- this.mediaURL = this.target.currentURI.spec;
- }
- else if (this.target instanceof HTMLCanvasElement) {
- this.onCanvas = true;
- }
- else if (this.target instanceof HTMLVideoElement) {
- this.mediaURL = this.target.currentSrc || this.target.src;
- // Firefox always creates a HTMLVideoElement when loading an ogg file
- // directly. If the media is actually audio, be smarter and provide a
- // context menu with audio operations.
- if (this.target.readyState >= this.target.HAVE_METADATA &&
- (this.target.videoWidth == 0 || this.target.videoHeight == 0)) {
- this.onAudio = true;
- } else {
- this.onVideo = true;
- }
- }
- else if (this.target instanceof HTMLAudioElement) {
- this.onAudio = true;
- this.mediaURL = this.target.currentSrc || this.target.src;
- }
- else if (this.target instanceof HTMLInputElement ) {
- this.onTextInput = this.isTargetATextBox(this.target);
- // Allow spellchecking UI on all text and search inputs.
- if (this.onTextInput && ! this.target.readOnly &&
- (this.target.type == "text" || this.target.type == "search")) {
- this.onEditableArea = true;
- InlineSpellCheckerUI.init(this.target.QueryInterface(Ci.nsIDOMNSEditableElement).editor);
- InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
- }
- this.onKeywordField = this.isTargetAKeywordField(this.target);
- }
- else if (this.target instanceof HTMLTextAreaElement) {
- this.onTextInput = true;
- if (!this.target.readOnly) {
- this.onEditableArea = true;
- InlineSpellCheckerUI.init(this.target.QueryInterface(Ci.nsIDOMNSEditableElement).editor);
- InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
- }
- }
- else if (this.target instanceof HTMLHtmlElement) {
- var bodyElt = this.target.ownerDocument.body;
- if (bodyElt) {
- let computedURL;
- try {
- computedURL = this.getComputedURL(bodyElt, "background-image");
- this._hasMultipleBGImages = false;
- } catch (e) {
- this._hasMultipleBGImages = true;
- }
- if (computedURL) {
- this.hasBGImage = true;
- this.bgImageURL = makeURLAbsolute(bodyElt.baseURI,
- computedURL);
- }
- }
- }
- else if ((this.target instanceof HTMLEmbedElement ||
- this.target instanceof HTMLObjectElement ||
- this.target instanceof HTMLAppletElement) &&
- this.target.displayedType == HTMLObjectElement.TYPE_NULL &&
- this.target.pluginFallbackType == HTMLObjectElement.PLUGIN_CLICK_TO_PLAY) {
- this.onCTPPlugin = true;
- }
-
- this.canSpellCheck = this._isSpellCheckEnabled(this.target);
- }
- else if (this.target.nodeType == Node.TEXT_NODE) {
- // For text nodes, look at the parent node to determine the spellcheck attribute.
- this.canSpellCheck = this.target.parentNode &&
- this._isSpellCheckEnabled(this.target);
- }
-
- // Second, bubble out, looking for items of interest that can have childen.
- // Always pick the innermost link, background image, etc.
- const XMLNS = "http://www.w3.org/XML/1998/namespace";
- var elem = this.target;
- while (elem) {
- if (elem.nodeType == Node.ELEMENT_NODE) {
- // Link?
- if (!this.onLink &&
- // Be consistent with what hrefAndLinkNodeForClickEvent
- // does in browser.js
- ((elem instanceof HTMLAnchorElement && elem.href) ||
- (elem instanceof HTMLAreaElement && elem.href) ||
- elem instanceof HTMLLinkElement ||
- elem.getAttributeNS("http://www.w3.org/1999/xlink", "type") == "simple")) {
-
- // Target is a link or a descendant of a link.
- this.onLink = true;
-
- // Remember corresponding element.
- this.link = elem;
- this.linkURL = this.getLinkURL();
- this.linkURI = this.getLinkURI();
- this.linkProtocol = this.getLinkProtocol();
- this.onMailtoLink = (this.linkProtocol == "mailto");
- this.onSaveableLink = this.isLinkSaveable( this.link );
- try {
- if (elem.download) {
- // Ignore download attribute on cross-origin links?
- // This shoudn't be an issue because the download link presents
- // the originating URL domain and protocol to help user understand
- // from where file is downloaded and make right decision.
- // If we decide we want this restriction:
- // this.principal.checkMayLoad(this.linkURI, false, true);
- this.linkDownload = elem.download;
- }
- }
- catch (ex) {}
- }
-
- // Background image? Don't bother if we've already found a
- // background image further down the hierarchy. Otherwise,
- // we look for the computed background-image style.
- if (!this.hasBGImage &&
- !this._hasMultipleBGImages) {
- let bgImgUrl;
- try {
- bgImgUrl = this.getComputedURL(elem, "background-image");
- this._hasMultipleBGImages = false;
- } catch (e) {
- this._hasMultipleBGImages = true;
- }
- if (bgImgUrl) {
- this.hasBGImage = true;
- this.bgImageURL = makeURLAbsolute(elem.baseURI,
- bgImgUrl);
- }
- }
- }
-
- elem = elem.parentNode;
- }
-
- // See if the user clicked on MathML
- const NS_MathML = "http://www.w3.org/1998/Math/MathML";
- if ((this.target.nodeType == Node.TEXT_NODE &&
- this.target.parentNode.namespaceURI == NS_MathML)
- || (this.target.namespaceURI == NS_MathML))
- this.onMathML = true;
-
- // See if the user clicked in a frame.
- var docDefaultView = this.target.ownerDocument.defaultView;
- if (docDefaultView != docDefaultView.top) {
- this.inFrame = true;
-
- if (this.target.ownerDocument.isSrcdocDocument) {
- this.inSrcdocFrame = true;
- }
- }
-
- // if the document is editable, show context menu like in text inputs
- if (!this.onEditableArea) {
- var win = this.target.ownerDocument.defaultView;
- if (win) {
- var isEditable = false;
- try {
- var editingSession = win.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIEditingSession);
- if (editingSession.windowIsEditable(win) &&
- this.getComputedStyle(this.target, "-moz-user-modify") == "read-write") {
- isEditable = true;
- }
- }
- catch(ex) {
- // If someone built with composer disabled, we can't get an editing session.
- }
-
- if (isEditable) {
- this.onTextInput = true;
- this.onKeywordField = false;
- this.onImage = false;
- this.onLoadedImage = false;
- this.onCompletedImage = false;
- this.onMathML = false;
- this.inFrame = false;
- this.inSrcdocFrame = false;
- this.hasBGImage = false;
- this.isDesignMode = true;
- this.onEditableArea = true;
- InlineSpellCheckerUI.init(editingSession.getEditorForWindow(win));
- var canSpell = InlineSpellCheckerUI.canSpellCheck && this.canSpellCheck;
- InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
- this.showItem("spell-check-enabled", canSpell);
- this.showItem("spell-separator", canSpell);
- }
- }
- }
- },
-
- // Returns the computed style attribute for the given element.
- getComputedStyle: function(aElem, aProp) {
- return aElem.ownerDocument
- .defaultView
- .getComputedStyle(aElem, "").getPropertyValue(aProp);
- },
-
- // Returns a "url"-type computed style attribute value, with the url() stripped.
- getComputedURL: function(aElem, aProp) {
- var url = aElem.ownerDocument
- .defaultView.getComputedStyle(aElem, "")
- .getPropertyCSSValue(aProp);
- if (url instanceof CSSValueList) {
- if (url.length != 1)
- throw "found multiple URLs";
- url = url[0];
- }
- return url.primitiveType == CSSPrimitiveValue.CSS_URI ?
- url.getStringValue() : null;
- },
-
- // Returns true if clicked-on link targets a resource that can be saved.
- isLinkSaveable: function(aLink) {
- // We don't do the Right Thing for news/snews yet, so turn them off
- // until we do.
- return this.linkProtocol && !(
- this.linkProtocol == "mailto" ||
- this.linkProtocol == "javascript" ||
- this.linkProtocol == "news" ||
- this.linkProtocol == "snews" );
- },
-
- _isSpellCheckEnabled: function(aNode) {
- // We can always force-enable spellchecking on textboxes
- if (this.isTargetATextBox(aNode)) {
- return true;
- }
- // We can never spell check something which is not content editable
- var editable = aNode.isContentEditable;
- if (!editable && aNode.ownerDocument) {
- editable = aNode.ownerDocument.designMode == "on";
- }
- if (!editable) {
- return false;
- }
- // Otherwise make sure that nothing in the parent chain disables spellchecking
- return aNode.spellcheck;
- },
-
- // Open linked-to URL in a new window.
- openLink : function () {
- var doc = this.target.ownerDocument;
- urlSecurityCheck(this.linkURL, doc.nodePrincipal);
- openLinkIn(this.linkURL, "window",
- { charset: doc.characterSet,
- referrerURI: doc.documentURIObject,
- referrerPolicy: doc.referrerPolicy,
- originPrincipal: doc.nodePrincipal,
- triggeringPrincipal: doc.nodePrincipal });
- },
-
- // Open linked-to URL in a new private window.
- openLinkInPrivateWindow : function () {
- var doc = this.target.ownerDocument;
- urlSecurityCheck(this.linkURL, doc.nodePrincipal);
- openLinkIn(this.linkURL, "window",
- { charset: doc.characterSet,
- referrerURI: doc.documentURIObject,
- referrerPolicy: doc.referrerPolicy,
- originPrincipal: doc.nodePrincipal,
- triggeringPrincipal: doc.nodePrincipal,
- private: true });
- },
-
- // Open linked-to URL in a new tab.
- openLinkInTab: function() {
- var doc = this.target.ownerDocument;
- urlSecurityCheck(this.linkURL, doc.nodePrincipal);
- openLinkIn(this.linkURL, "tab",
- { charset: doc.characterSet,
- referrerURI: doc.documentURIObject,
- referrerPolicy: doc.referrerPolicy,
- originPrincipal: doc.nodePrincipal,
- triggeringPrincipal: doc.nodePrincipal });
- },
-
- // open URL in current tab
- openLinkInCurrent: function() {
- var doc = this.target.ownerDocument;
- urlSecurityCheck(this.linkURL, doc.nodePrincipal);
- openLinkIn(this.linkURL, "current",
- { charset: doc.characterSet,
- referrerURI: doc.documentURIObject,
- originPrincipal: doc.nodePrincipal,
- triggeringPrincipal: doc.nodePrincipal });
- },
-
- // Open frame in a new tab.
- openFrameInTab: function() {
- var doc = this.target.ownerDocument;
- var frameURL = doc.location.href;
- var referrer = doc.referrer;
- openLinkIn(frameURL, "tab",
- { charset: doc.characterSet,
- referrerURI: referrer ? makeURI(referrer) : null });
- },
-
- // Reload clicked-in frame.
- reloadFrame: function() {
- this.target.ownerDocument.location.reload();
- },
-
- // Open clicked-in frame in its own window.
- openFrame: function() {
- var doc = this.target.ownerDocument;
- var frameURL = doc.location.href;
- var referrer = doc.referrer;
- openLinkIn(frameURL, "window",
- { charset: doc.characterSet,
- referrerURI: referrer ? makeURI(referrer) : null });
- },
-
- // Open clicked-in frame in the same window.
- showOnlyThisFrame: function() {
- var doc = this.target.ownerDocument;
- var frameURL = doc.location.href;
-
- urlSecurityCheck(frameURL, this.browser.contentPrincipal,
- Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
- var referrer = doc.referrer;
- openUILinkIn(frameURL, "current", { disallowInheritPrincipal: true,
- referrerURI: referrer ? makeURI(referrer) : null });
- },
-
- reload: function(event) {
- BrowserReloadOrDuplicate(event);
- },
-
- // View Partial Source
- viewPartialSource: function(aContext) {
- let target = aContext == "mathml" ? this.target : null;
- top.gViewSourceUtils.viewPartialSourceInBrowser(gBrowser.selectedBrowser, target);
- },
-
- // Open new "view source" window with the frame's URL.
- viewFrameSource: function() {
- BrowserViewSourceOfDocument(this.target.ownerDocument);
- },
-
- viewInfo: function() {
- BrowserPageInfo(this.target.ownerDocument.defaultView.top.document);
- },
-
- viewImageInfo: function() {
- BrowserPageInfo(this.target.ownerDocument.defaultView.top.document,
- "mediaTab", this.target);
- },
-
- viewFrameInfo: function() {
- BrowserPageInfo(this.target.ownerDocument);
- },
-
- reloadImage: function(e) {
- urlSecurityCheck(this.mediaURL,
- this.browser.contentPrincipal,
- Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
-
- if (this.target instanceof Ci.nsIImageLoadingContent)
- this.target.forceReload();
- },
-
- // Change current window to the URL of the image, video, or audio.
- viewMedia: function(e) {
- var viewURL;
- var doc = this.target.ownerDocument;
- if (this.onCanvas) {
- var target = this.target;
- var win = doc.defaultView;
- if (!win) {
- Components.utils.reportError(
- "View Image (on the <canvas> element):\n" +
- "This feature cannot be used, because it hasn't found " +
- "an appropriate window.");
- } else {
- new Promise.resolve({then: function (resolve) {
- target.toBlob((blob) => {
- resolve(win.URL.createObjectURL(blob));
- })
- }}).then(function (blobURL) {
- openUILink(blobURL, e, { disallowInheritPrincipal: true,
- referrerURI: doc.documentURIObject });
- }, Components.utils.reportError);
- }
- } else {
- viewURL = this.mediaURL;
- urlSecurityCheck(viewURL,
- this.browser.contentPrincipal,
- Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
- let doc = this.target.ownerDocument;
- openUILink(viewURL, e, { disallowInheritPrincipal: true,
- referrerURI: doc.documentURIObject,
- forceAllowDataURI: true });
- }
- },
-
- saveVideoFrameAsImage: function () {
- let referrerURI = document.documentURIObject;
- let isPrivate = PrivateBrowsingUtils.isBrowserPrivate(this.browser);
-
- urlSecurityCheck(this.mediaURL, this.browser.contentPrincipal,
- Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
- let name = "";
- try {
- let uri = makeURI(this.mediaURL);
- let url = uri.QueryInterface(Ci.nsIURL);
- if (url.fileBaseName)
- name = decodeURI(url.fileBaseName) + ".jpg";
- } catch (e) { }
- if (!name)
- name = "snapshot.jpg";
- var video = this.target;
- var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
- canvas.width = video.videoWidth;
- canvas.height = video.videoHeight;
- var ctxDraw = canvas.getContext("2d");
- ctxDraw.drawImage(video, 0, 0);
- saveImageURL(canvas.toDataURL("image/jpeg", ""), name, "SaveImageTitle",
- true, false, referrerURI, null, null, null,
- isPrivate);
- },
-
- fullScreenVideo: function () {
- let video = this.target;
- if (document.mozFullScreenEnabled)
- video.mozRequestFullScreen();
- },
-
- leaveDOMFullScreen: function() {
- document.mozCancelFullScreen();
- },
-
- // Change current window to the URL of the background image.
- viewBGImage: function(e) {
- urlSecurityCheck(this.bgImageURL,
- this.browser.contentPrincipal,
- Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
- var doc = this.target.ownerDocument;
- openUILink(this.bgImageURL, e, { disallowInheritPrincipal: true,
- referrerURI: doc.documentURIObject });
- },
-
- disableSetDesktopBackground: function() {
- // Disable the Set as Desktop Background menu item if we're still trying
- // to load the image or the load failed.
- if (!(this.target instanceof Ci.nsIImageLoadingContent))
- return true;
-
- if (("complete" in this.target) && !this.target.complete)
- return true;
-
- if (this.target.currentURI.schemeIs("javascript"))
- return true;
-
- var request = this.target
- .QueryInterface(Ci.nsIImageLoadingContent)
- .getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
- if (!request)
- return true;
-
- return false;
- },
-
- setDesktopBackground: function() {
- // Paranoia: check disableSetDesktopBackground again, in case the
- // image changed since the context menu was initiated.
- if (this.disableSetDesktopBackground())
- return;
-
- urlSecurityCheck(this.target.currentURI.spec,
- this.target.ownerDocument.nodePrincipal);
-
- // Confirm since it's annoying if you hit this accidentally.
- const kDesktopBackgroundURL =
- "chrome://browser/content/setDesktopBackground.xul";
-#ifdef XP_MACOSX
- // On Mac, the Set Desktop Background window is not modal.
- // Don't open more than one Set Desktop Background window.
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- var dbWin = wm.getMostRecentWindow("Shell:SetDesktopBackground");
- if (dbWin) {
- dbWin.gSetBackground.init(this.target);
- dbWin.focus();
- }
- else {
- openDialog(kDesktopBackgroundURL, "",
- "centerscreen,chrome,dialog=no,dependent,resizable=no",
- this.target);
- }
-#else
- // On non-Mac platforms, the Set Wallpaper dialog is modal.
- openDialog(kDesktopBackgroundURL, "",
- "centerscreen,chrome,dialog,modal,dependent",
- this.target);
-#endif
- },
-
- // Save URL of clicked-on frame.
- saveFrame: function () {
- saveDocument(this.target.ownerDocument);
- },
-
- // Helper function to wait for appropriate MIME-type headers and
- // then prompt the user with a file picker
- saveHelper: function(linkURL, linkText, dialogTitle, bypassCache, doc,
- linkDownload) {
- // canonical def in nsURILoader.h
- const NS_ERROR_SAVE_LINK_AS_TIMEOUT = 0x805d0020;
-
- // an object to proxy the data through to
- // nsIExternalHelperAppService.doContent, which will wait for the
- // appropriate MIME-type headers and then prompt the user with a
- // file picker
- function saveAsListener() {}
- saveAsListener.prototype = {
- extListener: null,
-
- onStartRequest: function saveLinkAs_onStartRequest(aRequest, aContext) {
-
- // if the timer fired, the error status will have been caused by that,
- // and we'll be restarting in onStopRequest, so no reason to notify
- // the user
- if (aRequest.status == NS_ERROR_SAVE_LINK_AS_TIMEOUT)
- return;
-
- timer.cancel();
-
- // some other error occured; notify the user...
- if (!Components.isSuccessCode(aRequest.status)) {
- try {
- const sbs = Cc["@mozilla.org/intl/stringbundle;1"].
- getService(Ci.nsIStringBundleService);
- const bundle = sbs.createBundle(
- "chrome://mozapps/locale/downloads/downloads.properties");
-
- const title = bundle.GetStringFromName("downloadErrorAlertTitle");
- const msg = bundle.GetStringFromName("downloadErrorGeneric");
-
- const promptSvc = Cc["@mozilla.org/embedcomp/prompt-service;1"].
- getService(Ci.nsIPromptService);
- promptSvc.alert(doc.defaultView, title, msg);
- } catch (ex) {}
- return;
- }
-
- var extHelperAppSvc =
- Cc["@mozilla.org/uriloader/external-helper-app-service;1"].
- getService(Ci.nsIExternalHelperAppService);
- var channel = aRequest.QueryInterface(Ci.nsIChannel);
- this.extListener =
- extHelperAppSvc.doContent(channel.contentType, aRequest,
- doc.defaultView, true);
- this.extListener.onStartRequest(aRequest, aContext);
- },
-
- onStopRequest: function saveLinkAs_onStopRequest(aRequest, aContext,
- aStatusCode) {
- if (aStatusCode == NS_ERROR_SAVE_LINK_AS_TIMEOUT) {
- // do it the old fashioned way, which will pick the best filename
- // it can without waiting.
- saveURL(linkURL, linkText, dialogTitle, bypassCache, false, doc.documentURIObject, doc);
- }
- if (this.extListener)
- this.extListener.onStopRequest(aRequest, aContext, aStatusCode);
- },
-
- onDataAvailable: function saveLinkAs_onDataAvailable(aRequest, aContext,
- aInputStream,
- aOffset, aCount) {
- this.extListener.onDataAvailable(aRequest, aContext, aInputStream,
- aOffset, aCount);
- }
- }
-
- function callbacks() {}
- callbacks.prototype = {
- getInterface: function sLA_callbacks_getInterface(aIID) {
- if (aIID.equals(Ci.nsIAuthPrompt) || aIID.equals(Ci.nsIAuthPrompt2)) {
- // If the channel demands authentication prompt, we must cancel it
- // because the save-as-timer would expire and cancel the channel
- // before we get credentials from user. Both authentication dialog
- // and save as dialog would appear on the screen as we fall back to
- // the old fashioned way after the timeout.
- timer.cancel();
- channel.cancel(NS_ERROR_SAVE_LINK_AS_TIMEOUT);
- }
- throw Cr.NS_ERROR_NO_INTERFACE;
- }
- }
-
- // if it we don't have the headers after a short time, the user
- // won't have received any feedback from their click. that's bad. so
- // we give up waiting for the filename.
- function timerCallback() {}
- timerCallback.prototype = {
- notify: function sLA_timer_notify(aTimer) {
- channel.cancel(NS_ERROR_SAVE_LINK_AS_TIMEOUT);
- return;
- }
- }
-
- // setting up a new channel for 'right click - save link as ...'
- var channel = NetUtil.newChannel({
- uri: makeURI(linkURL),
- loadingPrincipal: this.target.ownerDocument.nodePrincipal,
- contentPolicyType: Ci.nsIContentPolicy.TYPE_SAVEAS_DOWNLOAD,
- securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS,
- });
-
- if (linkDownload)
- channel.contentDispositionFilename = linkDownload;
- if (channel instanceof Ci.nsIPrivateBrowsingChannel) {
- let docIsPrivate = PrivateBrowsingUtils.isWindowPrivate(doc.defaultView);
- channel.setPrivate(docIsPrivate);
- }
- channel.notificationCallbacks = new callbacks();
-
- let flags = Ci.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS;
-
- if (bypassCache)
- flags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
-
- if (channel instanceof Ci.nsICachingChannel)
- flags |= Ci.nsICachingChannel.LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;
-
- channel.loadFlags |= flags;
-
- if (channel instanceof Ci.nsIHttpChannel) {
- channel.referrer = doc.documentURIObject;
- if (channel instanceof Ci.nsIHttpChannelInternal)
- channel.forceAllowThirdPartyCookie = true;
- }
-
- // fallback to the old way if we don't see the headers quickly
- var timeToWait =
- gPrefService.getIntPref("browser.download.saveLinkAsFilenameTimeout");
- var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- timer.initWithCallback(new timerCallback(), timeToWait,
- timer.TYPE_ONE_SHOT);
-
- // kick off the channel with our proxy object as the listener
- channel.asyncOpen2(new saveAsListener());
- },
-
- // Save URL of clicked-on link.
- saveLink: function() {
- var doc = this.target.ownerDocument;
- var linkText;
- // If selected text is found to match valid URL pattern.
- if (this.onPlainTextLink)
- linkText = document.commandDispatcher.focusedWindow.getSelection().toString().trim();
- else
- linkText = this.linkText();
- urlSecurityCheck(this.linkURL, doc.nodePrincipal);
-
- this.saveHelper(this.linkURL, linkText, null, true, doc,
- this.linkDownload);
- },
-
- sendLink: function() {
- // we don't know the title of the link so pass in an empty string
- MailIntegration.sendMessage( this.linkURL, "" );
- },
-
- // Backwards-compatibility wrapper
- saveImage : function() {
- if (this.onCanvas || this.onImage)
- this.saveMedia();
- },
-
- // Save URL of the clicked upon image, video, or audio.
- saveMedia: function() {
- var doc = this.target.ownerDocument;
- let referrerURI = doc.documentURIObject;
- let isPrivate = PrivateBrowsingUtils.isBrowserPrivate(this.browser);
- if (this.onCanvas) {
- // Bypass cache, since it's a blob: URL.
- var target = this.target;
- var win = doc.defaultView;
- if (!win) {
- Components.utils.reportError(
- "Save Image As (on the <canvas> element):\n" +
- "This feature cannot be used, because it hasn't found " +
- "an appropriate window.");
- } else {
- new Promise.resolve({then: function (resolve) {
- target.toBlob((blob) => {
- resolve(win.URL.createObjectURL(blob));
- })
- }}).then(function (blobURL) {
- saveImageURL(blobURL, "canvas.png", "SaveImageTitle",
- true, false, referrerURI, null, null, null,
- isPrivate);
- }, Components.utils.reportError);
- }
- } else if (this.onImage) {
- urlSecurityCheck(this.mediaURL, doc.nodePrincipal);
- saveImageURL(this.mediaURL, null, "SaveImageTitle",
- false, false, referrerURI, doc, null, null,
- isPrivate);
- } else if (this.onVideo || this.onAudio) {
- urlSecurityCheck(this.mediaURL, doc.nodePrincipal);
- var dialogTitle = this.onVideo ? "SaveVideoTitle" : "SaveAudioTitle";
- this.saveHelper(this.mediaURL, null, dialogTitle, false, doc, "");
- }
- },
-
- // Backwards-compatibility wrapper
- sendImage : function() {
- if (this.onCanvas || this.onImage)
- this.sendMedia();
- },
-
- sendMedia: function() {
- MailIntegration.sendMessage(this.mediaURL, "");
- },
-
- playPlugin: function() {
- gPluginHandler._showClickToPlayNotification(this.browser, this.target);
- },
-
- hidePlugin: function() {
- gPluginHandler.hideClickToPlayOverlay(this.target);
- },
-
- // Generate email address and put it on clipboard.
- copyEmail: function() {
- // Copy the comma-separated list of email addresses only.
- // There are other ways of embedding email addresses in a mailto:
- // link, but such complex parsing is beyond us.
- var url = this.linkURL;
- var qmark = url.indexOf("?");
- var addresses;
-
- // 7 == length of "mailto:"
- addresses = qmark > 7 ? url.substring(7, qmark) : url.substr(7);
-
- // Let's try to unescape it using a character set
- // in case the address is not ASCII.
- try {
- var characterSet = this.target.ownerDocument.characterSet;
- const textToSubURI = Cc["@mozilla.org/intl/texttosuburi;1"].
- getService(Ci.nsITextToSubURI);
- addresses = textToSubURI.unEscapeURIForUI(characterSet, addresses);
- }
- catch(ex) {
- // Do nothing.
- }
-
- var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].
- getService(Ci.nsIClipboardHelper);
- clipboard.copyString(addresses, document);
- },
-
- ///////////////
- // Utilities //
- ///////////////
-
- // Show/hide one item (specified via name or the item element itself).
- showItem: function(aItemOrId, aShow) {
- var item = aItemOrId.constructor == String ?
- document.getElementById(aItemOrId) : aItemOrId;
- if (item)
- item.hidden = !aShow;
- },
-
- // Set given attribute of specified context-menu item. If the
- // value is null, then it removes the attribute (which works
- // nicely for the disabled attribute).
- setItemAttr: function(aID, aAttr, aVal ) {
- var elem = document.getElementById(aID);
- if (elem) {
- if (aVal == null) {
- // null indicates attr should be removed.
- elem.removeAttribute(aAttr);
- }
- else {
- // Set attr=val.
- elem.setAttribute(aAttr, aVal);
- }
- }
- },
-
- // Set context menu attribute according to like attribute of another node
- // (such as a broadcaster).
- setItemAttrFromNode: function(aItem_id, aAttr, aOther_id) {
- var elem = document.getElementById(aOther_id);
- if (elem && elem.getAttribute(aAttr) == "true")
- this.setItemAttr(aItem_id, aAttr, "true");
- else
- this.setItemAttr(aItem_id, aAttr, null);
- },
-
- // Temporary workaround for DOM api not yet implemented by XUL nodes.
- cloneNode: function(aItem) {
- // Create another element like the one we're cloning.
- var node = document.createElement(aItem.tagName);
-
- // Copy attributes from argument item to the new one.
- var attrs = aItem.attributes;
- for (var i = 0; i < attrs.length; i++) {
- var attr = attrs.item(i);
- node.setAttribute(attr.nodeName, attr.nodeValue);
- }
-
- // Voila!
- return node;
- },
-
- // Generate fully qualified URL for clicked-on link.
- getLinkURL: function() {
- var href = this.link.href;
- if (href)
- return href;
-
- href = this.link.getAttributeNS("http://www.w3.org/1999/xlink",
- "href");
-
- if (!href || !href.match(/\S/)) {
- // Without this we try to save as the current doc,
- // for example, HTML case also throws if empty
- throw "Empty href";
- }
-
- return makeURLAbsolute(this.link.baseURI, href);
- },
-
- getLinkURI: function() {
- try {
- return makeURI(this.linkURL);
- }
- catch (ex) {
- // e.g. empty URL string
- }
-
- return null;
- },
-
- getLinkProtocol: function() {
- if (this.linkURI)
- return this.linkURI.scheme; // can be |undefined|
-
- return null;
- },
-
- // Get text of link.
- linkText: function() {
- var text = gatherTextUnder(this.link);
- if (!text || !text.match(/\S/)) {
- text = this.link.getAttribute("title");
- if (!text || !text.match(/\S/)) {
- text = this.link.getAttribute("alt");
- if (!text || !text.match(/\S/))
- text = this.linkURL;
- }
- }
-
- return text;
- },
-
- // Returns true if anything is selected.
- isContentSelection: function() {
- return !document.commandDispatcher.focusedWindow.getSelection().isCollapsed;
- },
-
- toString: function () {
- return "contextMenu.target = " + this.target + "\n" +
- "contextMenu.onImage = " + this.onImage + "\n" +
- "contextMenu.onLink = " + this.onLink + "\n" +
- "contextMenu.link = " + this.link + "\n" +
- "contextMenu.inFrame = " + this.inFrame + "\n" +
- "contextMenu.hasBGImage = " + this.hasBGImage + "\n";
- },
-
- isDisabledForEvents: function(aNode) {
- let ownerDoc = aNode.ownerDocument;
- return ownerDoc.defaultView &&
- ownerDoc.defaultView
- .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils)
- .isNodeDisabledForEvents(aNode);
- },
-
- isTargetATextBox: function(node) {
- if (node instanceof HTMLInputElement)
- return node.mozIsTextField(false);
-
- return (node instanceof HTMLTextAreaElement);
- },
-
- isTargetAKeywordField: function(aNode) {
- if (!(aNode instanceof HTMLInputElement))
- return false;
-
- var form = aNode.form;
- if (!form || aNode.type == "password")
- return false;
-
- var method = form.method.toUpperCase();
-
- // These are the following types of forms we can create keywords for:
- //
- // method encoding type can create keyword
- // GET * YES
- // * YES
- // POST YES
- // POST application/x-www-form-urlencoded YES
- // POST text/plain NO (a little tricky to do)
- // POST multipart/form-data NO
- // POST everything else YES
- return (method == "GET" || method == "") ||
- (form.enctype != "text/plain") && (form.enctype != "multipart/form-data");
- },
-
- // Determines whether or not the separator with the specified ID should be
- // shown or not by determining if there are any non-hidden items between it
- // and the previous separator.
- shouldShowSeparator: function (aSeparatorID) {
- var separator = document.getElementById(aSeparatorID);
- if (separator) {
- var sibling = separator.previousSibling;
- while (sibling && sibling.localName != "menuseparator") {
- if (!sibling.hidden)
- return true;
- sibling = sibling.previousSibling;
- }
- }
- return false;
- },
-
- addDictionaries: function() {
- var uri = formatURL("browser.dictionaries.download.url", true);
-
- var locale = "-";
- try {
- locale = gPrefService.getComplexValue("intl.accept_languages",
- Ci.nsIPrefLocalizedString).data;
- }
- catch (e) { }
-
- var version = "-";
- try {
- version = Cc["@mozilla.org/xre/app-info;1"].
- getService(Ci.nsIXULAppInfo).version;
- }
- catch (e) { }
-
- uri = uri.replace(/%LOCALE%/, escape(locale)).replace(/%VERSION%/, version);
-
- var newWindowPref = gPrefService.getIntPref("browser.link.open_newwindow");
- var where = newWindowPref == 3 ? "tab" : "window";
-
- openUILinkIn(uri, where);
- },
-
- bookmarkThisPage: function CM_bookmarkThisPage() {
- window.top.PlacesCommandHook.bookmarkPage(this.browser, PlacesUtils.bookmarksMenuFolderId, true);
- },
-
- bookmarkLink: function CM_bookmarkLink() {
- var linkText;
- // If selected text is found to match valid URL pattern.
- if (this.onPlainTextLink)
- linkText = document.commandDispatcher.focusedWindow.getSelection().toString().trim();
- else
- linkText = this.linkText();
- window.top.PlacesCommandHook.bookmarkLink(PlacesUtils.bookmarksMenuFolderId, this.linkURL,
- linkText);
- },
-
- addBookmarkForFrame: function CM_addBookmarkForFrame() {
- var doc = this.target.ownerDocument;
- var uri = doc.documentURIObject;
-
- var itemId = PlacesUtils.getMostRecentBookmarkForURI(uri);
- if (itemId == -1) {
- var title = doc.title;
- var description = PlacesUIUtils.getDescriptionFromDocument(doc);
- PlacesUIUtils.showBookmarkDialog({ action: "add"
- , type: "bookmark"
- , uri: uri
- , title: title
- , description: description
- , hiddenRows: [ "description"
- , "location"
- , "loadInSidebar"
- , "keyword" ]
- }, window.top);
- }
- else {
- PlacesUIUtils.showBookmarkDialog({ action: "edit"
- , type: "bookmark"
- , itemId: itemId
- }, window.top);
- }
- },
-
- savePageAs: function CM_savePageAs() {
- saveDocument(this.browser.contentDocument);
- },
-
- sendPage: function CM_sendPage() {
- MailIntegration.sendLinkForWindow(this.browser.contentWindow);
- },
-
- printFrame: function CM_printFrame() {
- PrintUtils.print(this.target.ownerDocument.defaultView);
- },
-
- switchPageDirection: function CM_switchPageDirection() {
- SwitchDocumentDirection(this.browser.contentWindow);
- },
-
- mediaCommand : function CM_mediaCommand(command, data) {
- var media = this.target;
-
- switch (command) {
- case "play":
- media.play();
- break;
- case "pause":
- media.pause();
- break;
- case "loop":
- media.loop = !media.loop;
- break;
- case "mute":
- media.muted = true;
- break;
- case "unmute":
- media.muted = false;
- break;
- case "playbackRate":
- media.playbackRate = data;
- break;
- case "hidecontrols":
- media.removeAttribute("controls");
- break;
- case "showcontrols":
- media.setAttribute("controls", "true");
- break;
- case "hidestats":
- case "showstats":
- var event = media.ownerDocument.createEvent("CustomEvent");
- event.initCustomEvent("media-showStatistics", false, true, command == "showstats");
- media.dispatchEvent(event);
- break;
- }
- },
-
- copyMediaLocation : function () {
- var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].
- getService(Ci.nsIClipboardHelper);
- clipboard.copyString(this.mediaURL, document);
- },
-
- get imageURL() {
- if (this.onImage)
- return this.mediaURL;
- return "";
- },
-
- // Formats the 'Search <engine> for "<selection or link text>"' context menu.
- formatSearchContextItem: function() {
- var menuItem = document.getElementById("context-searchselect");
- var selectedText = this.isTextSelected ? this.textSelected : this.linkText();
-
- // Store searchTerms in context menu item so we know what to search onclick
- menuItem.searchTerms = selectedText;
-
- if (selectedText.length > 15)
- selectedText = selectedText.substr(0,15) + this.ellipsis;
-
- // Use the current engine if the search bar is visible, the default
- // engine otherwise.
- var engineName = "";
- var ss = Cc["@mozilla.org/browser/search-service;1"].
- getService(Ci.nsIBrowserSearchService);
- if (isElementVisible(BrowserSearch.searchBar))
- engineName = ss.currentEngine.name;
- else
- engineName = ss.defaultEngine.name;
-
- // format "Search <engine> for <selection>" string to show in menu
- var menuLabel = gNavigatorBundle.getFormattedString("contextMenuSearch",
- [engineName,
- selectedText]);
- menuItem.label = menuLabel;
- menuItem.accessKey = gNavigatorBundle.getString("contextMenuSearch.accesskey");
- }
-};
diff --git a/base/content/openLocation.js b/base/content/openLocation.js
deleted file mode 100644
index 7ad2f7c..0000000
--- a/base/content/openLocation.js
+++ /dev/null
@@ -1,150 +0,0 @@
-/* -*- Mode: C++; 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 browser;
-var dialog = {};
-var pref = null;
-var openLocationModule = {};
-try {
- pref = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
-} catch (ex) {
- // not critical, remain silent
-}
-
-Components.utils.import("resource:///modules/openLocationLastURL.jsm", openLocationModule);
-var gOpenLocationLastURL = new openLocationModule.OpenLocationLastURL(window.opener);
-
-function onLoad()
-{
- dialog.input = document.getElementById("dialog.input");
- dialog.open = document.documentElement.getButton("accept");
- dialog.openWhereList = document.getElementById("openWhereList");
- dialog.openTopWindow = document.getElementById("currentWindow");
- dialog.bundle = document.getElementById("openLocationBundle");
-
- if ("arguments" in window && window.arguments.length >= 1)
- browser = window.arguments[0];
-
- dialog.openWhereList.selectedItem = dialog.openTopWindow;
-
- if (pref) {
- try {
- var useAutoFill = pref.getBoolPref("browser.urlbar.autoFill");
- if (useAutoFill)
- dialog.input.setAttribute("completedefaultindex", "true");
- } catch (ex) {}
-
- try {
- var value = pref.getIntPref("general.open_location.last_window_choice");
- var element = dialog.openWhereList.getElementsByAttribute("value", value)[0];
- if (element)
- dialog.openWhereList.selectedItem = element;
- dialog.input.value = gOpenLocationLastURL.value;
- }
- catch(ex) {
- }
- if (dialog.input.value)
- dialog.input.select(); // XXX should probably be done automatically
- }
-
- doEnabling();
-}
-
-function doEnabling()
-{
- dialog.open.disabled = !dialog.input.value;
-}
-
-function open()
-{
- var openData = {
- "url": null,
- "postData": null,
- "mayInheritPrincipal": false
- };
- if (browser) {
- browser.getShortcutOrURIAndPostData(dialog.input.value).then(data => {
- openData.url = data.url;
- openData.postData = data.postData;
- openData.mayInheritPrincipal = data.mayInheritPrincipal;
-
- openLocation(openData);
- });
- } else {
- openData.url = dialog.input.value;
-
- openLocation(openData);
- }
-
- return false;
-}
-
-function openLocation(openData)
-{
- try {
- // Whichever target we use for the load, we allow third-party services to
- // fix up the URI
- switch (dialog.openWhereList.value) {
- case "0":
- var webNav = Components.interfaces.nsIWebNavigation;
- var flags = webNav.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
- webNav.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
- if (!openData.mayInheritPrincipal)
- flags |= webNav.LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL;
- browser.gBrowser.loadURIWithFlags(
- openData.url, flags, null, null, openData.postData);
- break;
- case "1":
- window.opener.delayedOpenWindow(getBrowserURL(), "all,dialog=no",
- openData.url, openData.postData,
- null, null, true);
- break;
- case "3":
- browser.delayedOpenTab(
- openData.url, null, null, openData.postData, true);
- break;
- }
- } catch (ex) {}
-
- if (pref) {
- gOpenLocationLastURL.value = dialog.input.value;
- pref.setIntPref(
- "general.open_location.last_window_choice", dialog.openWhereList.value);
- }
-
- window.close();
-}
-
-function createInstance(contractid, iidName)
-{
- var iid = Components.interfaces[iidName];
- return Components.classes[contractid].createInstance(iid);
-}
-
-const nsIFilePicker = Components.interfaces.nsIFilePicker;
-function onChooseFile()
-{
- try {
- let fp = Components.classes["@mozilla.org/filepicker;1"].
- createInstance(nsIFilePicker);
- let fpCallback = function fpCallback_done(aResult) {
- if (aResult == nsIFilePicker.returnOK && fp.fileURL.spec &&
- fp.fileURL.spec.length > 0) {
- dialog.input.value = fp.fileURL.spec;
- }
- doEnabling();
- };
-
- fp.init(window, dialog.bundle.getString("chooseFileDialogTitle"),
- nsIFilePicker.modeOpen);
- fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText |
- nsIFilePicker.filterImages | nsIFilePicker.filterXML |
- nsIFilePicker.filterHTML);
- fp.open(fpCallback);
- } catch (ex) {
- }
-}
diff --git a/base/content/openLocation.xul b/base/content/openLocation.xul
deleted file mode 100644
index 7bafed0..0000000
--- a/base/content/openLocation.xul
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- 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/. -->
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
-<!DOCTYPE dialog SYSTEM "chrome://browser/locale/openLocation.dtd">
-
-<dialog id="openLocation"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="&caption.label;"
- onload="onLoad()"
- buttonlabelaccept="&openBtn.label;"
- buttoniconaccept="open"
- ondialogaccept="open()"
- style="width: 40em;"
- persist="screenX screenY"
- screenX="24" screenY="24">
-
- <script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
- <script type="application/javascript" src="chrome://browser/content/openLocation.js"/>
- <script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
-
- <stringbundle id="openLocationBundle" src="chrome://browser/locale/openLocation.properties"/>
-
- <hbox>
- <separator orient="vertical" class="thin"/>
- <vbox flex="1">
- <description>&enter.label;</description>
- <separator class="thin"/>
-
- <hbox align="center">
- <textbox id="dialog.input" flex="1" type="autocomplete"
- completeselectedindex="true"
- autocompletesearch="urlinline history"
- enablehistory="true"
- class="uri-element"
- oninput="doEnabling();"/>
- <button label="&chooseFile.label;" oncommand="onChooseFile();"/>
- </hbox>
- <hbox align="center">
- <label value="&openWhere.label;"/>
- <menulist id="openWhereList">
- <menupopup>
- <menuitem value="0" id="currentWindow" label="&topTab.label;"/>
- <menuitem value="3" label="&newTab.label;"/>
- <menuitem value="1" label="&newWindow.label;"/>
- </menupopup>
- </menulist>
- <spacer flex="1"/>
- </hbox>
- </vbox>
- </hbox>
-
-</dialog>
diff --git a/base/content/overrides/app-license.html b/base/content/overrides/app-license.html
deleted file mode 100644
index 2d2e3d5..0000000
--- a/base/content/overrides/app-license.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!-- 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/. -->
- <p><b>Binaries</b> of this product have been made available to you by the
- <a href="http://www.palemoon.org/">Pale Moon Project</a> under the Pale Moon
- Binary <a href="http://www.palemoon.org/redist.shtml">redistribution license</a>.</p> \ No newline at end of file
diff --git a/base/content/padlock.css b/base/content/padlock.css
deleted file mode 100644
index 649cb27..0000000
--- a/base/content/padlock.css
+++ /dev/null
@@ -1,203 +0,0 @@
-#padlock-ib {
- -moz-appearance: none;
- min-width: 0px;
- margin-right: 1px !important;
- background-repeat: no-repeat;
- background-position: center;
- z-index: 1000 !important;
- padding: 0px;
- margin: 0px;
- border: 0px;
-}
-
-#padlock-ib[padshow="ib-trans-bg"][level="ev"] {
- list-style-image: url("chrome://browser/content/padlock_mod_ev.png");
- background-color: transparent;
-}
-
-#padlock-ib[padshow="ib-trans-bg"][level="high"] {
- list-style-image: url("chrome://browser/content/padlock_mod_https.png");
- background-color: transparent;
-}
-
-#padlock-ib[padshow="ib-trans-bg"][level="low"],
-#padlock-ib[padshow="ib-trans-bg"][level="mixed"] {
- list-style-image: url("chrome://browser/content/padlock_mod_low.png");
- background-color: transparent;
-}
-
-#padlock-ib[padshow="ib-trans-bg"][level="broken"] {
- list-style-image: url("chrome://browser/content/padlock_mod_broken.png");
- background-color: transparent;
-}
-
-#padlock-ib-left {
- -moz-appearance: none;
- min-width: 0px;
- margin-right: 1px !important;
- background-repeat: no-repeat;
- background-position: center;
- z-index: 1000 !important;
- padding: 0px;
- margin: 0px;
- border: 0px;
-}
-
-#padlock-ib-left[padshow="ib-left"][level="ev"] {
- list-style-image: url("chrome://browser/content/padlock_mod_ev.png");
- padding: 2px;
- background-color: transparent;
-}
-
-#padlock-ib-left[padshow="ib-left"][level="high"] {
- list-style-image: url("chrome://browser/content/padlock_mod_https.png");
- padding: 2px;
- background-color: transparent;
-}
-
-#padlock-ib-left[padshow="ib-left"][level="low"],
-#padlock-ib-left[padshow="ib-left"][level="mixed"] {
- list-style-image: url("chrome://browser/content/padlock_mod_low.png");
- padding: 2px;
- background-color: transparent;
-}
-
-#padlock-ib-left[padshow="ib-left"][level="broken"] {
- list-style-image: url("chrome://browser/content/padlock_mod_broken.png");
- padding: 2px;
- background-color: transparent;
-}
-
-#padlock-ub-right {
- -moz-appearance: none;
- min-width: 0px;
- margin-right: 1px !important;
- background-repeat: no-repeat;
- background-position: center;
- z-index: 1000 !important;
- padding: 0px;
- margin: 0px;
- border: 0px;
-}
-
-#padlock-ub-right[padshow="ub-right"][level="ev"] {
- list-style-image: url("chrome://browser/content/padlock_mod_ev.png");
- background-color: transparent;
-}
-
-#padlock-ub-right[padshow="ub-right"][level="high"] {
- list-style-image: url("chrome://browser/content/padlock_mod_https.png");
- background-color: transparent;
-}
-
-#padlock-ub-right[padshow="ub-right"][level="low"],
-#padlock-ub-right[padshow="ub-right"][level="mixed"] {
- list-style-image: url("chrome://browser/content/padlock_mod_low.png");
- background-color: transparent;
-}
-
-#padlock-ub-right[padshow="ub-right"][level="broken"] {
- list-style-image: url("chrome://browser/content/padlock_mod_broken.png");
- background-color: transparent;
-}
-
-#padlock-sb {
- -moz-appearance: none;
- background-repeat: no-repeat;
- background-position: center;
-}
-
-#padlock-sb[padshow="statbar"][level="ev"] {
- list-style-image: url("chrome://browser/content/padlock_mod_ev.png");
- background-color: transparent;
-}
-
-#padlock-sb[padshow="statbar"][level="high"] {
- list-style-image: url("chrome://browser/content/padlock_mod_https.png");
- background-color: transparent;
-}
-
-#padlock-sb[padshow="statbar"][level="low"],
-#padlock-sb[padshow="statbar"][level="mixed"] {
- list-style-image: url("chrome://browser/content/padlock_mod_low.png");
- background-color: transparent;
-}
-
-#padlock-sb[padshow="statbar"][level="broken"] {
- list-style-image: url("chrome://browser/content/padlock_mod_broken.png");
- background-color: transparent;
-}
-
-#padlock-tab {
- -moz-appearance: none;
- background-repeat: no-repeat;
- background-position: center;
-}
-
-#padlock-tab[padshow="tabs-bar"][level="ev"] {
- list-style-image: url("chrome://browser/content/padlock_mod_ev.png");
- background-color: transparent;
-}
-
-#padlock-tab[padshow="tabs-bar"][level="high"] {
- list-style-image: url("chrome://browser/content/padlock_mod_https.png");
- background-color: transparent;
-}
-
-#padlock-tab[padshow="tabs-bar"][level="low"],
-#padlock-tab[padshow="tabs-bar"][level="mixed"] {
- list-style-image: url("chrome://browser/content/padlock_mod_low.png");
- background-color: transparent;
-}
-
-#padlock-tab[padshow="tabs-bar"][level="broken"] {
- list-style-image: url("chrome://browser/content/padlock_mod_broken.png");
- background-color: transparent;
-}
-
-/* Classic style */
-#padlock-ib[padshow="ib-trans-bg"][padstyle="classic"][level="ev"],
-#padlock-ib-left[padshow="ib-left"][padstyle="classic"][level="ev"],
-#padlock-ub-right[padshow="ub-right"][padstyle="classic"][level="ev"],
-#padlock-sb[padshow="statbar"][padstyle="classic"][level="ev"],
-#padlock-tab[padshow="tabs-bar"][padstyle="classic"][level="ev"] {
- list-style-image: url("chrome://browser/content/padlock_classic_ev.png");
-}
-
-#padlock-ib[padshow="ib-trans-bg"][padstyle="classic"][level="high"],
-#padlock-ib-left[padshow="ib-left"][padstyle="classic"][level="high"],
-#padlock-ub-right[padshow="ub-right"][padstyle="classic"][level="high"],
-#padlock-sb[padshow="statbar"][padstyle="classic"][level="high"],
-#padlock-tab[padshow="tabs-bar"][padstyle="classic"][level="high"] {
- list-style-image: url("chrome://browser/content/padlock_classic_https.png");
-}
-
-#padlock-ib[padshow="ib-trans-bg"][padstyle="classic"][level="low"],
-#padlock-ib-left[padshow="ib-left"][padstyle="classic"][level="low"],
-#padlock-ub-right[padshow="ub-right"][padstyle="classic"][level="low"],
-#padlock-sb[padshow="statbar"][padstyle="classic"][level="low"],
-#padlock-tab[padshow="tabs-bar"][padstyle="classic"][level="low"],
-#padlock-ib[padshow="ib-trans-bg"][padstyle="classic"][level="mixed"],
-#padlock-ib-left[padshow="ib-left"][padstyle="classic"][level="mixed"],
-#padlock-ub-right[padshow="ub-right"][padstyle="classic"][level="mixed"],
-#padlock-sb[padshow="statbar"][padstyle="classic"][level="mixed"],
-#padlock-tab[padshow="tabs-bar"][padstyle="classic"][level="mixed"] {
- list-style-image: url("chrome://browser/content/padlock_classic_low.png");
-}
-
-#padlock-ib[padshow="ib-trans-bg"][padstyle="classic"][level="broken"],
-#padlock-ib-left[padshow="ib-left"][padstyle="classic"][level="broken"],
-#padlock-ub-right[padshow="ub-right"][padstyle="classic"][level="broken"],
-#padlock-sb[padshow="statbar"][padstyle="classic"][level="broken"],
-#padlock-tab[padshow="tabs-bar"][padstyle="classic"][level="broken"] {
- list-style-image: url("chrome://browser/content/padlock_classic_broken.png");
-}
-
-/* Remove a few px of dead space for disabled locations */
-#padlock-ib:not([padshow="ib-trans-bg"]),
-#padlock-ib-left:not([padshow="ib-left"]),
-#padlock-ub-right:not([padshow="ub-right"]),
-#padlock-sb:not([padshow="statbar"]),
-#padlock-tab:not([padshow="tabs-bar"]) {
- visibility: collapse;
-} \ No newline at end of file
diff --git a/base/content/padlock.js b/base/content/padlock.js
deleted file mode 100644
index 9c29524..0000000
--- a/base/content/padlock.js
+++ /dev/null
@@ -1,234 +0,0 @@
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-var padlock_PadLock =
-{
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
- Ci.nsISupportsWeakReference]),
- onButtonClick: function(event) {
- event.stopPropagation();
- gIdentityHandler.handleMoreInfoClick(event);
- },
- onStateChange: function() {},
- onProgressChange: function() {},
- onLocationChange: function() {},
- onStatusChange: function() {},
- onSecurityChange: function(aCallerWebProgress, aRequestWithState, aState) {
- // aState is defined as a bitmask that may be extended in the future.
- // We filter out any unknown bits before testing for known values.
- const wpl = Ci.nsIWebProgressListener;
- const wpl_security_bits = wpl.STATE_IS_SECURE |
- wpl.STATE_IS_BROKEN |
- wpl.STATE_IS_INSECURE |
- wpl.STATE_IDENTITY_EV_TOPLEVEL |
- wpl.STATE_SECURE_HIGH |
- wpl.STATE_SECURE_MED |
- wpl.STATE_SECURE_LOW;
- var level;
- var is_insecure;
- var highlight_urlbar = false;
-
- switch (aState & wpl_security_bits) {
- case wpl.STATE_IS_SECURE | wpl.STATE_SECURE_HIGH | wpl.STATE_IDENTITY_EV_TOPLEVEL:
- level = "ev";
- is_insecure = "";
- highlight_urlbar = true;
- break;
- case wpl.STATE_IS_SECURE | wpl.STATE_SECURE_HIGH:
- level = "high";
- is_insecure = "";
- highlight_urlbar = true;
- break;
- case wpl.STATE_IS_SECURE | wpl.STATE_SECURE_MED:
- case wpl.STATE_IS_SECURE | wpl.STATE_SECURE_LOW:
- level = "low";
- is_insecure = "insecure";
- break;
- case wpl.STATE_IS_BROKEN | wpl.STATE_SECURE_LOW:
- level = "mixed";
- is_insecure = "insecure";
- highlight_urlbar = true;
- break;
- case wpl.STATE_IS_BROKEN:
- level = "broken";
- is_insecure = "insecure";
- highlight_urlbar = true;
- break;
- default: // should not be reached
- level = null;
- is_insecure = "insecure";
- }
-
- try {
- var proto = gBrowser.contentWindow.location.protocol;
- if (proto == "about:" || proto == "chrome:" || proto == "file:" ) {
- // do not warn when using local protocols
- is_insecure = false;
- }
- }
- catch (ex) {}
-
- let ub = document.getElementById("urlbar");
- if (ub) { // Only call if URL bar is present.
- if (highlight_urlbar) {
- ub.setAttribute("security_level", level);
- } else {
- ub.removeAttribute("security_level");
- }
- }
-
- try { // URL bar may be hidden
- padlock_PadLock.setPadlockLevel("padlock-ib", level);
- padlock_PadLock.setPadlockLevel("padlock-ib-left", level);
- padlock_PadLock.setPadlockLevel("padlock-ub-right", level);
- } catch(e) {}
- padlock_PadLock.setPadlockLevel("padlock-sb", level);
- padlock_PadLock.setPadlockLevel("padlock-tab", level);
- },
- setPadlockLevel: function(item, level) {
- let secbut = document.getElementById(item);
- var sectooltip = "";
-
- if (level) {
- secbut.setAttribute("level", level);
- secbut.hidden = false;
- } else {
- secbut.hidden = true;
- secbut.removeAttribute("level");
- }
-
- switch (level) {
- case "ev":
- sectooltip = "Extended Validated";
- break;
- case "high":
- sectooltip = "Secure";
- break;
- case "low":
- sectooltip = "Weak security";
- break;
- case "mixed":
- sectooltip = "Mixed mode (partially encrypted)";
- break;
- case "broken":
- sectooltip = "Not secure";
- break;
- default:
- sectooltip = "";
- }
- secbut.setAttribute("tooltiptext", sectooltip);
- },
- prefbranch : null,
- onLoad: function() {
- gBrowser.addProgressListener(padlock_PadLock);
-
- var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
- padlock_PadLock.prefbranch = prefService.getBranch("browser.padlock.");
- padlock_PadLock.prefbranch.QueryInterface(Components.interfaces.nsIPrefBranch2);
- padlock_PadLock.usePrefs();
- padlock_PadLock.prefbranch.addObserver("", padlock_PadLock, false);
- },
- onUnLoad: function() {
- padlock_PadLock.prefbranch.removeObserver("", padlock_PadLock);
- },
- observe: function(subject, topic, data)
- {
- if (topic != "nsPref:changed")
- return;
- if (data != "style" && data != "urlbar_background" && data != "shown")
- return;
- padlock_PadLock.usePrefs();
- },
- usePrefs: function() {
- var prefval = padlock_PadLock.prefbranch.getIntPref("style");
- var position;
- var padstyle;
- if (prefval == 2) {
- position = "ib-left";
- padstyle = "modern";
- }
- else if (prefval == 3) {
- position = "ub-right";
- padstyle = "modern";
- }
- else if (prefval == 4) {
- position = "statbar";
- padstyle = "modern";
- }
- else if (prefval == 5) {
- position = "tabs-bar";
- padstyle = "modern";
- }
- else if (prefval == 6) {
- position = "ib-trans-bg";
- padstyle = "classic";
- }
- else if (prefval == 7) {
- position = "ib-left";
- padstyle = "classic";
- }
- else if (prefval == 8) {
- position = "ub-right";
- padstyle = "classic";
- }
- else if (prefval == 9) {
- position = "statbar";
- padstyle = "classic";
- }
- else if (prefval == 10) {
- position = "tabs-bar";
- padstyle = "classic";
- }
- else { // 1 or anything else_ default
- position = "ib-trans-bg";
- padstyle = "modern";
- }
-
- var colshow;
- var colprefval = padlock_PadLock.prefbranch.getIntPref("urlbar_background");
- switch (colprefval) {
- case 3:
- colshow = "all";
- break;
- case 2:
- colshow = "secure-mixed";
- break;
- case 1:
- colshow = "secure-only";
- break;
- default:
- colshow = ""; // 0 or anything else: no shading
- }
- try { // URL bar may be hidden
- document.getElementById("urlbar").setAttribute("https_color", colshow);
- } catch(e) {}
-
- var lockenabled = padlock_PadLock.prefbranch.getBoolPref("shown");
- var padshow = "";
- if (lockenabled) {
- padshow = position;
- }
-
- try { // URL bar may be hidden
- document.getElementById("padlock-ib").setAttribute("padshow", padshow);
- document.getElementById("padlock-ib-left").setAttribute("padshow", padshow);
- document.getElementById("padlock-ub-right").setAttribute("padshow", padshow);
- } catch(e) {}
- document.getElementById("padlock-sb").setAttribute("padshow", padshow);
- document.getElementById("padlock-tab").setAttribute("padshow", padshow);
-
- try { // URL bar may be hidden
- document.getElementById("padlock-ib").setAttribute("padstyle", padstyle);
- document.getElementById("padlock-ib-left").setAttribute("padstyle", padstyle);
- document.getElementById("padlock-ub-right").setAttribute("padstyle", padstyle);
- } catch(e) {}
- document.getElementById("padlock-sb").setAttribute("padstyle", padstyle);
- document.getElementById("padlock-tab").setAttribute("padstyle", padstyle);
-
- }
-};
-
-window.addEventListener("load", padlock_PadLock.onLoad, false );
-window.addEventListener("unload", padlock_PadLock.onUnLoad, false );
diff --git a/base/content/padlock.xul b/base/content/padlock.xul
deleted file mode 100644
index e820c19..0000000
--- a/base/content/padlock.xul
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://browser/content/padlock.css" type="text/css"?>
-
-<overlay
- id="padlock"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<script type="application/x-javascript" src="chrome://browser/content/padlock.js"/>
-
- <hbox id="identity-box">
- <image id="padlock-ib" insertafter="identity-icon-labels"
- class="urlbar-icon"
- style="-moz-user-focus: none;"
- hidden="false"
- tooltiptext=""
- onclick="return padlock_PadLock.onButtonClick(event);"/>
- </hbox>
-
- <hbox id="identity-box">
- <image id="padlock-ib-left" insertbefore="identity-icon-labels"
- class="urlbar-icon"
- style="-moz-user-focus: none;"
- hidden="false"
- tooltiptext=""
- onclick="return padlock_PadLock.onButtonClick(event);"/>
- </hbox>
-
- <hbox id="urlbar-icons">
- <image id="padlock-ub-right" insertbefore="star-button"
- class="urlbar-icon"
- style="-moz-user-focus: none;"
- hidden="false"
- tooltiptext=""
- onclick="return padlock_PadLock.onButtonClick(event);"/>
- </hbox>
-
- <statusbar id="status-bar">
- <statusbarpanel insertafter="security-button"
- id="padlock-sb-panel"
- class="statusbar-iconic-text">
- <image id="padlock-sb" insertbefore="star-button"
- class="urlbar-icon"
- style="-moz-user-focus: none;"
- hidden="false"
- tooltiptext=""
- onclick="return padlock_PadLock.onButtonClick(event);"/>
- </statusbarpanel>
- </statusbar>
-
- <toolbar id="TabsToolbar">
- <toolbaritem insertafter="tabs-closebutton" id="tabs-padlock-tbitem"
- align="center" pack="center">
- <image id="padlock-tab"
- class="urlbar-icon"
- style="-moz-user-focus: none;"
- hidden="false"
- tooltiptext=""
- onclick="return padlock_PadLock.onButtonClick(event);"/>
- </toolbaritem>
- </toolbar>
-
-
-</overlay>
diff --git a/base/content/padlock_classic_broken.png b/base/content/padlock_classic_broken.png
deleted file mode 100644
index 437036f..0000000
--- a/base/content/padlock_classic_broken.png
+++ /dev/null
Binary files differ
diff --git a/base/content/padlock_classic_ev.png b/base/content/padlock_classic_ev.png
deleted file mode 100644
index b3f80c0..0000000
--- a/base/content/padlock_classic_ev.png
+++ /dev/null
Binary files differ
diff --git a/base/content/padlock_classic_https.png b/base/content/padlock_classic_https.png
deleted file mode 100644
index 86026c0..0000000
--- a/base/content/padlock_classic_https.png
+++ /dev/null
Binary files differ
diff --git a/base/content/padlock_classic_low.png b/base/content/padlock_classic_low.png
deleted file mode 100644
index 652ad09..0000000
--- a/base/content/padlock_classic_low.png
+++ /dev/null
Binary files differ
diff --git a/base/content/padlock_mod_broken.png b/base/content/padlock_mod_broken.png
deleted file mode 100644
index 33a6c06..0000000
--- a/base/content/padlock_mod_broken.png
+++ /dev/null
Binary files differ
diff --git a/base/content/padlock_mod_ev.png b/base/content/padlock_mod_ev.png
deleted file mode 100644
index 3dfdcbd..0000000
--- a/base/content/padlock_mod_ev.png
+++ /dev/null
Binary files differ
diff --git a/base/content/padlock_mod_https.png b/base/content/padlock_mod_https.png
deleted file mode 100644
index d494b42..0000000
--- a/base/content/padlock_mod_https.png
+++ /dev/null
Binary files differ
diff --git a/base/content/padlock_mod_low.png b/base/content/padlock_mod_low.png
deleted file mode 100644
index 29179ef..0000000
--- a/base/content/padlock_mod_low.png
+++ /dev/null
Binary files differ
diff --git a/base/content/palemoon.xhtml b/base/content/palemoon.xhtml
deleted file mode 100644
index f145550..0000000
--- a/base/content/palemoon.xhtml
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html
-[
- <!ENTITY % mozillaDTD SYSTEM "chrome://browser/locale/palemoon.dtd" >
- %mozillaDTD;
- <!ENTITY % directionDTD SYSTEM "chrome://global/locale/global.dtd" >
- %directionDTD;
-]>
-
-<!-- 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/. -->
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta charset='utf-8' />
- <title>&chronicles.title.66.1;</title>
-
-<style type="text/css">
-html {
- background: #333399 radial-gradient( circle at 75% 25%, #6666b0 0%, #333399 40%, #111177 80%) center center / cover no-repeat;
- color: white;
- font-style: italic;
- text-rendering: optimizeLegibility;
- min-height: 100%;
-}
-
-#moztext {
- margin-top: 15%;
- font-size: 1.1em;
- font-family: serif;
- text-align: center;
- line-height: 1.5;
-}
-
-#from {
- font-size: 1.95em;
- font-family: serif;
- text-align: right;
-}
-
-em {
- font-size: 1.3em;
- line-height: 0;
-}
-
-a {
- text-decoration: none;
- color: white;
-}
-</style>
-</head>
-
-<body dir="&locale.dir;">
-
-<section>
- <p id="moztext">
- &chronicles.quote.66.1;
- </p>
-
- <p id="from">
- &chronicles.from.66.1;
- </p>
-</section>
-
-</body>
-</html>
diff --git a/base/content/popup-notifications.inc b/base/content/popup-notifications.inc
deleted file mode 100644
index 31a72b4..0000000
--- a/base/content/popup-notifications.inc
+++ /dev/null
@@ -1,104 +0,0 @@
-# to be included inside a popupset element
-
- <panel id="notification-popup"
- type="arrow"
- position="after_start"
- hidden="true"
- orient="vertical"
- role="alert"/>
-
- <!-- Popup for site identity information -->
- <panel id="identity-popup"
- type="arrow"
- hidden="true"
- noautofocus="true"
- consumeoutsideclicks="true"
- onpopupshown="gIdentityHandler.onPopupShown(event);"
- level="top">
- <hbox id="identity-popup-container" align="top">
- <image id="identity-popup-icon"/>
- <vbox id="identity-popup-content-box">
- <label id="identity-popup-connectedToLabel"
- class="identity-popup-label"
- value="&identity.connectedTo;"/>
- <label id="identity-popup-connectedToLabel2"
- class="identity-popup-label"
- value="&identity.unverifiedsite2;"/>
- <description id="identity-popup-content-host"
- class="identity-popup-description"/>
- <label id="identity-popup-runByLabel"
- class="identity-popup-label"
- value="&identity.runBy;"/>
- <description id="identity-popup-content-owner"
- class="identity-popup-description"/>
- <description id="identity-popup-content-supplemental"
- class="identity-popup-description"/>
- <description id="identity-popup-content-verifier"
- class="identity-popup-description"/>
- <hbox id="identity-popup-encryption" flex="1">
- <vbox>
- <image id="identity-popup-encryption-icon"/>
- </vbox>
- <description id="identity-popup-encryption-label" flex="1"
- class="identity-popup-description"/>
- </hbox>
- <!-- Footer button to open security page info -->
- <hbox id="identity-popup-button-container" pack="end">
- <button id="identity-popup-more-info-button"
- label="&identity.moreInfoLinkText;"
- onblur="gIdentityHandler.hideIdentityPopup();"
- oncommand="gIdentityHandler.handleMoreInfoClick(event);"/>
- </hbox>
- </vbox>
- </hbox>
- </panel>
-
-#ifdef MOZ_WEBRTC
- <popupnotification id="webRTC-shareDevices-notification" hidden="true">
- <popupnotificationcontent id="webRTC-selectCamera" orient="vertical">
- <separator class="thin"/>
- <label value="&getUserMedia.selectCamera.label;"
- accesskey="&getUserMedia.selectCamera.accesskey;"
- control="webRTC-selectCamera-menulist"/>
- <menulist id="webRTC-selectCamera-menulist">
- <menupopup id="webRTC-selectCamera-menupopup"/>
- </menulist>
- </popupnotificationcontent>
- <popupnotificationcontent id="webRTC-selectMicrophone" orient="vertical">
- <separator class="thin"/>
- <label value="&getUserMedia.selectMicrophone.label;"
- accesskey="&getUserMedia.selectMicrophone.accesskey;"
- control="webRTC-selectMicrophone-menulist"/>
- <menulist id="webRTC-selectMicrophone-menulist">
- <menupopup id="webRTC-selectMicrophone-menupopup"/>
- </menulist>
- </popupnotificationcontent>
- </popupnotification>
-#endif
- <popupnotification id="servicesInstall-notification" hidden="true">
- <popupnotificationcontent orient="vertical" align="start">
- <!-- XXX bug 974146, tests are looking for this, can't remove yet. -->
- </popupnotificationcontent>
- </popupnotification>
-
- <popupnotification id="pointerLock-notification" hidden="true">
- <popupnotificationcontent orient="vertical" align="start">
- <separator class="thin"/>
- <label id="pointerLock-cancel" value="&pointerLock.notification.message;"/>
- </popupnotificationcontent>
- </popupnotification>
-
- <popupnotification id="password-notification" hidden="true">
- <popupnotificationcontent orient="vertical">
- <textbox id="password-notification-username"/>
- <textbox id="password-notification-password" type="password" show-content=""/>
- <checkbox id="password-notification-visibilityToggle" hidden="true"/>
- </popupnotificationcontent>
- </popupnotification>
-
- <popupnotification id="mixed-content-blocked-notification" hidden="true">
- <popupnotificationcontent orient="vertical" align="start">
- <separator/>
- <description id="mixed-content-blocked-moreinfo">&mixedContentBlocked.moreinfo;</description>
- </popupnotificationcontent>
- </popupnotification>
diff --git a/base/content/safeMode.css b/base/content/safeMode.css
deleted file mode 100644
index 4f093a4..0000000
--- a/base/content/safeMode.css
+++ /dev/null
@@ -1,8 +0,0 @@
-/* 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/. */
-
-#resetProfileFooter {
- font-weight: bold;
-}
-
diff --git a/base/content/safeMode.js b/base/content/safeMode.js
deleted file mode 100644
index e1e5c72..0000000
--- a/base/content/safeMode.js
+++ /dev/null
@@ -1,128 +0,0 @@
-/* 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/. */
-
-const Cc = Components.classes,
- Ci = Components.interfaces,
- Cu = Components.utils;
-
-Cu.import("resource://gre/modules/AddonManager.jsm");
-
-function restartApp() {
- let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
- .getService(Ci.nsIAppStartup);
- appStartup.quit(Ci.nsIAppStartup.eForceQuit | Ci.nsIAppStartup.eRestart);
-}
-
-function clearAllPrefs() {
- var prefService = Cc["@mozilla.org/preferences-service;1"]
- .getService(Ci.nsIPrefService);
- prefService.resetUserPrefs();
-
- // Remove the pref-overrides dir, if it exists
- try {
- var fileLocator = Cc["@mozilla.org/file/directory_service;1"]
- .getService(Ci.nsIProperties);
- const NS_APP_PREFS_OVERRIDE_DIR = "PrefDOverride";
- var prefOverridesDir = fileLocator.get(NS_APP_PREFS_OVERRIDE_DIR,
- Ci.nsIFile);
- prefOverridesDir.remove(true);
- } catch (ex) {
- Components.utils.reportError(ex);
- }
-}
-
-function restoreDefaultBookmarks() {
- var prefBranch = Cc["@mozilla.org/preferences-service;1"]
- .getService(Ci.nsIPrefBranch);
- prefBranch.setBoolPref("browser.bookmarks.restore_default_bookmarks", true);
-}
-
-function deleteLocalstore() {
- const nsIDirectoryServiceContractID = "@mozilla.org/file/directory_service;1";
- const nsIProperties = Ci.nsIProperties;
- var directoryService = Cc[nsIDirectoryServiceContractID]
- .getService(nsIProperties);
- // Local store file
- var localstoreFile = directoryService.get("LStoreS", Components.interfaces.nsIFile);
- // XUL store file
- var xulstoreFile = directoryService.get("ProfD", Components.interfaces.nsIFile);
- xulstoreFile.append("xulstore.json");
- try {
- xulstoreFile.remove(false);
- if (localstoreFile.exists()) {
- localstoreFile.remove(false);
- }
- } catch(e) {
- Components.utils.reportError(e);
- }
-}
-
-function disableAddons() {
- AddonManager.getAllAddons(function(aAddons) {
- aAddons.forEach(function(aAddon) {
- if (aAddon.type == "theme") {
- // Setting userDisabled to false on the default theme activates it,
- // disables all other themes and deactivates the applied persona, if
- // any.
- const DEFAULT_THEME_ID = "{972ce4c6-7e08-4474-a285-3208198ce6fd}";
- if (aAddon.id == DEFAULT_THEME_ID)
- aAddon.userDisabled = false;
- }
- else {
- aAddon.userDisabled = true;
- }
- });
-
- restartApp();
- });
-}
-
-function restoreDefaultSearchEngines() {
- var searchService = Cc["@mozilla.org/browser/search-service;1"]
- .getService(Ci.nsIBrowserSearchService);
-
- searchService.restoreDefaultEngines();
-}
-
-function onOK() {
- try {
- if (document.getElementById("resetUserPrefs").checked)
- clearAllPrefs();
- if (document.getElementById("deleteBookmarks").checked)
- restoreDefaultBookmarks();
- if (document.getElementById("resetToolbars").checked)
- deleteLocalstore();
- if (document.getElementById("restoreSearch").checked)
- restoreDefaultSearchEngines();
- if (document.getElementById("disableAddons").checked) {
- disableAddons();
- // disableAddons will asynchronously restart the application
- return false;
- }
- } catch(e) {
- }
-
- restartApp();
- return false;
-}
-
-function onCancel() {
- let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
- .getService(Ci.nsIAppStartup);
- appStartup.quit(Ci.nsIAppStartup.eForceQuit);
-}
-
-function onLoad() {
- document.getElementById("tasks")
- .addEventListener("CheckboxStateChange", UpdateOKButtonState, false);
-}
-
-function UpdateOKButtonState() {
- document.documentElement.getButton("accept").disabled =
- !document.getElementById("resetUserPrefs").checked &&
- !document.getElementById("deleteBookmarks").checked &&
- !document.getElementById("resetToolbars").checked &&
- !document.getElementById("disableAddons").checked &&
- !document.getElementById("restoreSearch").checked;
-}
diff --git a/base/content/safeMode.xul b/base/content/safeMode.xul
deleted file mode 100644
index 656df6e..0000000
--- a/base/content/safeMode.xul
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-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/. -->
-
-<!DOCTYPE prefwindow [
-<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
-%brandDTD;
-<!ENTITY % safeModeDTD SYSTEM "chrome://browser/locale/safeMode.dtd" >
-%safeModeDTD;
-<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
-%browserDTD;
-]>
-
-<?xml-stylesheet href="chrome://global/skin/"?>
-
-<dialog id="safeModeDialog"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="&safeModeDialog.title;"
- buttons="accept,cancel,extra1"
- buttonlabelaccept="&changeAndRestartButton.label;"
-#ifdef XP_WIN
- buttonlabelcancel="&quitApplicationCmdWin.label;"
-#else
- buttonlabelcancel="&quitApplicationCmd.label;"
-#endif
- buttonlabelextra1="&continueButton.label;"
- width="&window.width;"
- ondialogaccept="return onOK()"
- ondialogcancel="onCancel()"
- ondialogextra1="window.close()"
- onload="onLoad();"
- buttondisabledaccept="true">
-
- <script type="application/javascript" src="chrome://browser/content/safeMode.js"/>
-
- <stringbundle id="preferencesBundle" src="chrome://browser/locale/preferences/preferences.properties"/>
-
- <description>&safeModeDescription.label;</description>
-
- <separator class="thin"/>
-
- <label value="&safeModeDescription2.label;"/>
- <vbox id="tasks">
- <checkbox id="disableAddons" label="&disableAddons.label;" accesskey="&disableAddons.accesskey;"/>
- <checkbox id="resetToolbars" label="&resetToolbars.label;" accesskey="&resetToolbars.accesskey;"/>
- <checkbox id="deleteBookmarks" label="&deleteBookmarks.label;" accesskey="&deleteBookmarks.accesskey;"/>
- <checkbox id="resetUserPrefs" label="&resetUserPrefs.label;" accesskey="&resetUserPrefs.accesskey;"/>
- <checkbox id="restoreSearch" label="&restoreSearch.label;" accesskey="&restoreSearch.accesskey;"/>
- </vbox>
-
- <separator class="thin"/>
-</dialog>
diff --git a/base/content/sanitize.js b/base/content/sanitize.js
deleted file mode 100644
index b4d13d8..0000000
--- a/base/content/sanitize.js
+++ /dev/null
@@ -1,534 +0,0 @@
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# 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/.
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "FormHistory",
- "resource://gre/modules/FormHistory.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
- "resource://gre/modules/Downloads.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
- "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
- "resource://gre/modules/Task.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "console",
- "resource://gre/modules/Console.jsm");
-
-function Sanitizer() {}
-Sanitizer.prototype = {
- // warning to the caller: this one may raise an exception (e.g. bug #265028)
- clearItem: function (aItemName)
- {
- if (this.items[aItemName].canClear)
- this.items[aItemName].clear();
- },
-
- canClearItem: function (aItemName, aCallback, aArg)
- {
- let canClear = this.items[aItemName].canClear;
- if (typeof canClear == "function") {
- canClear(aCallback, aArg);
- return false;
- }
-
- aCallback(aItemName, canClear, aArg);
- return canClear;
- },
-
- prefDomain: "",
- isShutDown: false,
-
- getNameFromPreference: function (aPreferenceName)
- {
- return aPreferenceName.substr(this.prefDomain.length);
- },
-
- /**
- * Deletes privacy sensitive data in a batch, according to user preferences.
- * Returns a promise which is resolved if no errors occurred. If an error
- * occurs, a message is reported to the console and all other items are still
- * cleared before the promise is finally rejected.
- */
- sanitize: function ()
- {
- var deferred = Promise.defer();
- var psvc = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefService);
- var branch = psvc.getBranch(this.prefDomain);
- var seenError = false;
-
- // Cache the range of times to clear
- if (this.ignoreTimespan)
- var range = null; // If we ignore timespan, clear everything
- else
- range = this.range || Sanitizer.getClearRange();
-
- let itemCount = Object.keys(this.items).length;
- let onItemComplete = function() {
- if (!--itemCount) {
- seenError ? deferred.reject() : deferred.resolve();
- }
- };
- for (var itemName in this.items) {
- let item = this.items[itemName];
- item.range = range;
- item.isShutDown = this.isShutDown;
- if ("clear" in item && branch.getBoolPref(itemName)) {
- let clearCallback = (itemName, aCanClear) => {
- // Some of these clear() may raise exceptions (see bug #265028)
- // to sanitize as much as possible, we catch and store them,
- // rather than fail fast.
- // Callers should check returned errors and give user feedback
- // about items that could not be sanitized
- let item = this.items[itemName];
- try {
- if (aCanClear)
- item.clear();
- } catch(er) {
- seenError = true;
- console.error("Error sanitizing " + itemName + ": " + er + "\n");
- }
- onItemComplete();
- };
- this.canClearItem(itemName, clearCallback);
- } else {
- onItemComplete();
- }
- }
-
- return deferred.promise;
- },
-
- // Time span only makes sense in certain cases. Consumers who want
- // to only clear some private data can opt in by setting this to false,
- // and can optionally specify a specific range. If timespan is not ignored,
- // and range is not set, sanitize() will use the value of the timespan
- // pref to determine a range
- ignoreTimespan : true,
- range : null,
-
- items: {
- cache: {
- clear: function ()
- {
- var cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"].
- getService(Ci.nsICacheStorageService);
- try {
- // Cache doesn't consult timespan, nor does it have the
- // facility for timespan-based eviction. Wipe it.
- cache.clear();
- } catch(er) {}
-
- var imageCache = Cc["@mozilla.org/image/tools;1"].
- getService(Ci.imgITools).getImgCacheForDocument(null);
- try {
- imageCache.clearCache(false); // true=chrome, false=content
- } catch(er) {}
- },
-
- get canClear()
- {
- return true;
- }
- },
-
- cookies: {
- clear: function ()
- {
- var cookieMgr = Components.classes["@mozilla.org/cookiemanager;1"]
- .getService(Ci.nsICookieManager);
- if (this.range) {
- // Iterate through the cookies and delete any created after our cutoff.
- var cookiesEnum = cookieMgr.enumerator;
- while (cookiesEnum.hasMoreElements()) {
- var cookie = cookiesEnum.getNext().QueryInterface(Ci.nsICookie2);
-
- if (cookie.creationTime > this.range[0])
- // This cookie was created after our cutoff, clear it
- cookieMgr.remove(cookie.host, cookie.name, cookie.path,
- false, cookie.originAttributes);
- }
- }
- else {
- // Remove everything
- cookieMgr.removeAll();
- }
-
- // Clear plugin data.
- const phInterface = Ci.nsIPluginHost;
- const FLAG_CLEAR_ALL = phInterface.FLAG_CLEAR_ALL;
- let ph = Cc["@mozilla.org/plugin/host;1"].getService(phInterface);
-
- // Determine age range in seconds. (-1 means clear all.) We don't know
- // that this.range[1] is actually now, so we compute age range based
- // on the lower bound. If this.range results in a negative age, do
- // nothing.
- let age = this.range ? (Date.now() / 1000 - this.range[0] / 1000000)
- : -1;
- if (!this.range || age >= 0) {
- let tags = ph.getPluginTags();
- for (let i = 0; i < tags.length; i++) {
- try {
- ph.clearSiteData(tags[i], null, FLAG_CLEAR_ALL, age);
- } catch (e) {
- // If the plugin doesn't support clearing by age, clear everything.
- if (e.result == Components.results.
- NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED) {
- try {
- ph.clearSiteData(tags[i], null, FLAG_CLEAR_ALL, -1);
- } catch (e) {
- // Ignore errors from the plugin
- }
- }
- }
- }
- }
- },
-
- get canClear()
- {
- return true;
- }
- },
-
- offlineApps: {
- clear: function ()
- {
- Components.utils.import("resource:///modules/offlineAppCache.jsm");
- OfflineAppCacheHelper.clear();
- if (!this.range || this.isShutDown) {
- Components.utils.import("resource:///modules/QuotaManager.jsm");
- QuotaManagerHelper.clear(this.isShutDown);
- }
- },
-
- get canClear()
- {
- return true;
- }
- },
-
- history: {
- clear: function ()
- {
- if (this.range) {
- PlacesUtils.history.removeVisitsByFilter({
- beginDate: new Date(this.range[0] / 1000),
- endDate: new Date(this.range[1] / 1000)
- }).catch(Components.utils.reportError);;
- } else {
- // Remove everything.
- PlacesUtils.history.clear()
- .catch(Components.utils.reportError);
- }
-
- try {
- var os = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- os.notifyObservers(null, "browser:purge-session-history", "");
- }
- catch (e) { }
-
- // Clear last URL of the Open Web Location dialog
- var prefs = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
- try {
- prefs.clearUserPref("general.open_location.last_url");
- }
- catch (e) { }
- },
-
- get canClear()
- {
- // bug 347231: Always allow clearing history due to dependencies on
- // the browser:purge-session-history notification. (like error console)
- return true;
- }
- },
-
- formdata: {
- clear: function ()
- {
- // Clear undo history of all searchBars
- var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
- .getService(Components.interfaces.nsIWindowMediator);
- var windows = windowManager.getEnumerator("navigator:browser");
- while (windows.hasMoreElements()) {
- let currentDocument = windows.getNext().document;
- let searchBar = currentDocument.getElementById("searchbar");
- if (searchBar)
- searchBar.textbox.reset();
- let findBar = currentDocument.getElementById("FindToolbar");
- if (findBar)
- findBar.clear();
- }
-
- let change = { op: "remove" };
- if (this.range) {
- [ change.firstUsedStart, change.firstUsedEnd ] = this.range;
- }
- FormHistory.update(change);
- },
-
- canClear : function(aCallback, aArg)
- {
- var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
- .getService(Components.interfaces.nsIWindowMediator);
- var windows = windowManager.getEnumerator("navigator:browser");
- while (windows.hasMoreElements()) {
- let currentDocument = windows.getNext().document;
- let searchBar = currentDocument.getElementById("searchbar");
- if (searchBar) {
- let transactionMgr = searchBar.textbox.editor.transactionManager;
- if (searchBar.value ||
- transactionMgr.numberOfUndoItems ||
- transactionMgr.numberOfRedoItems) {
- aCallback("formdata", true, aArg);
- return false;
- }
- }
- let findBar = currentDocument.getElementById("FindToolbar");
- if (findBar && findBar.canClear) {
- aCallback("formdata", true, aArg);
- return false;
- }
- }
-
- let count = 0;
- let countDone = {
- handleResult : function(aResult) count = aResult,
- handleError : function(aError) Components.utils.reportError(aError),
- handleCompletion :
- function(aReason) { aCallback("formdata", aReason == 0 && count > 0, aArg); }
- };
- FormHistory.count({}, countDone);
- return false;
- }
- },
-
- downloads: {
- clear: Task.async(function* (range) {
- let refObj = {};
- try {
- let filterByTime = null;
- if (range) {
- // Convert microseconds back to milliseconds for date comparisons.
- let rangeBeginMs = range[0] / 1000;
- let rangeEndMs = range[1] / 1000;
- filterByTime = download => download.startTime >= rangeBeginMs &&
- download.startTime <= rangeEndMs;
- }
-
- // Clear all completed/cancelled downloads
- let list = yield Downloads.getList(Downloads.ALL);
- list.removeFinished(filterByTime);
- } finally {}
- }),
-
- get canClear()
- {
- //Clearing is always possible with JSTransfers
- return true;
- }
- },
-
- passwords: {
- clear: function ()
- {
- var pwmgr = Components.classes["@mozilla.org/login-manager;1"]
- .getService(Components.interfaces.nsILoginManager);
- // Passwords are timeless, and don't respect the timeSpan setting
- pwmgr.removeAllLogins();
- },
-
- get canClear()
- {
- var pwmgr = Components.classes["@mozilla.org/login-manager;1"]
- .getService(Components.interfaces.nsILoginManager);
- var count = pwmgr.countLogins("", "", ""); // count all logins
- return (count > 0);
- }
- },
-
- sessions: {
- clear: function ()
- {
- // clear all auth tokens
- var sdr = Components.classes["@mozilla.org/security/sdr;1"]
- .getService(Components.interfaces.nsISecretDecoderRing);
- sdr.logoutAndTeardown();
-
- // clear FTP and plain HTTP auth sessions
- var os = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- os.notifyObservers(null, "net:clear-active-logins", null);
- },
-
- get canClear()
- {
- return true;
- }
- },
-
- siteSettings: {
- clear: function ()
- {
- // Clear site-specific permissions like "Allow this site to open popups"
- var pm = Components.classes["@mozilla.org/permissionmanager;1"]
- .getService(Components.interfaces.nsIPermissionManager);
- pm.removeAll();
-
- // Clear site-specific settings like page-zoom level
- var cps = Components.classes["@mozilla.org/content-pref/service;1"]
- .getService(Components.interfaces.nsIContentPrefService2);
- cps.removeAllDomains(null);
-
- // Clear "Never remember passwords for this site", which is not handled by
- // the permission manager
- var pwmgr = Components.classes["@mozilla.org/login-manager;1"]
- .getService(Components.interfaces.nsILoginManager);
- var hosts = pwmgr.getAllDisabledHosts();
- for each (var host in hosts) {
- pwmgr.setLoginSavingEnabled(host, true);
- }
- },
-
- get canClear()
- {
- return true;
- }
- },
-
- connectivityData: {
- clear: function ()
- {
- // Clear site security settings
- var sss = Components.classes["@mozilla.org/ssservice;1"]
- .getService(Components.interfaces.nsISiteSecurityService);
- sss.clearAll();
- },
-
- get canClear()
- {
- return true;
- }
- }
- }
-};
-
-
-
-// "Static" members
-Sanitizer.prefDomain = "privacy.sanitize.";
-Sanitizer.prefShutdown = "sanitizeOnShutdown";
-Sanitizer.prefDidShutdown = "didShutdownSanitize";
-
-// Time span constants corresponding to values of the privacy.sanitize.timeSpan
-// pref. Used to determine how much history to clear, for various items
-Sanitizer.TIMESPAN_EVERYTHING = 0;
-Sanitizer.TIMESPAN_HOUR = 1;
-Sanitizer.TIMESPAN_2HOURS = 2;
-Sanitizer.TIMESPAN_4HOURS = 3;
-Sanitizer.TIMESPAN_TODAY = 4;
-
-Sanitizer.IS_SHUTDOWN = true;
-
-// Return a 2 element array representing the start and end times,
-// in the uSec-since-epoch format that PRTime likes. If we should
-// clear everything, return null. Use ts if it is defined; otherwise
-// use the timeSpan pref.
-Sanitizer.getClearRange = function (ts) {
- if (ts === undefined)
- ts = Sanitizer.prefs.getIntPref("timeSpan");
- if (ts === Sanitizer.TIMESPAN_EVERYTHING)
- return null;
-
- // PRTime is microseconds while JS time is milliseconds
- var endDate = Date.now() * 1000;
- switch (ts) {
- case Sanitizer.TIMESPAN_HOUR :
- var startDate = endDate - 3600000000; // 1*60*60*1000000
- break;
- case Sanitizer.TIMESPAN_2HOURS :
- startDate = endDate - 7200000000; // 2*60*60*1000000
- break;
- case Sanitizer.TIMESPAN_4HOURS :
- startDate = endDate - 14400000000; // 4*60*60*1000000
- break;
- case Sanitizer.TIMESPAN_TODAY :
- var d = new Date(); // Start with today
- d.setHours(0); // zero us back to midnight...
- d.setMinutes(0);
- d.setSeconds(0);
- startDate = d.valueOf() * 1000; // convert to epoch usec
- break;
- default:
- throw "Invalid time span for clear private data: " + ts;
- }
- return [startDate, endDate];
-};
-
-Sanitizer._prefs = null;
-Sanitizer.__defineGetter__("prefs", function()
-{
- return Sanitizer._prefs ? Sanitizer._prefs
- : Sanitizer._prefs = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefService)
- .getBranch(Sanitizer.prefDomain);
-});
-
-// Shows sanitization UI
-Sanitizer.showUI = function(aParentWindow)
-{
- var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
- .getService(Components.interfaces.nsIWindowWatcher);
-#ifdef XP_MACOSX
- ww.openWindow(null, // make this an app-modal window on Mac
-#else
- ww.openWindow(aParentWindow,
-#endif
- "chrome://browser/content/sanitize.xul",
- "Sanitize",
- "chrome,titlebar,dialog,centerscreen,modal",
- null);
-};
-
-/**
- * Deletes privacy sensitive data in a batch, optionally showing the
- * sanitize UI, according to user preferences
- */
-Sanitizer.sanitize = function(aParentWindow)
-{
- Sanitizer.showUI(aParentWindow);
-};
-
-Sanitizer.onStartup = function()
-{
- // we check for unclean exit with pending sanitization
- Sanitizer._checkAndSanitize();
-};
-
-Sanitizer.onShutdown = function()
-{
- // we check if sanitization is needed and perform it
- Sanitizer._checkAndSanitize(Sanitizer.IS_SHUTDOWN);
-};
-
-// this is called on startup and shutdown, to perform pending sanitizations
-Sanitizer._checkAndSanitize = function(isShutDown)
-{
- const prefs = Sanitizer.prefs;
- if (prefs.getBoolPref(Sanitizer.prefShutdown) &&
- !prefs.prefHasUserValue(Sanitizer.prefDidShutdown)) {
- // this is a shutdown or a startup after an unclean exit
- var s = new Sanitizer();
- s.prefDomain = "privacy.clearOnShutdown.";
- s.isShutDown = isShutDown;
- s.sanitize().then(function() {
- prefs.setBoolPref(Sanitizer.prefDidShutdown, true);
- });
- }
-};
diff --git a/base/content/sanitize.xul b/base/content/sanitize.xul
deleted file mode 100644
index 691be92..0000000
--- a/base/content/sanitize.xul
+++ /dev/null
@@ -1,190 +0,0 @@
-<?xml version="1.0"?>
-
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# 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/.
-
-<?xml-stylesheet href="chrome://global/skin/"?>
-<?xml-stylesheet href="chrome://browser/skin/sanitizeDialog.css"?>
-
-#ifdef CRH_DIALOG_TREE_VIEW
-<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
-#endif
-
-<?xml-stylesheet href="chrome://browser/content/sanitizeDialog.css"?>
-
-<!DOCTYPE prefwindow [
- <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
- <!ENTITY % sanitizeDTD SYSTEM "chrome://browser/locale/sanitize.dtd">
- %brandDTD;
- %sanitizeDTD;
-]>
-
-<prefwindow id="SanitizeDialog" type="child"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- dlgbuttons="accept,cancel"
- title="&sanitizeDialog2.title;"
- noneverythingtitle="&sanitizeDialog2.title;"
- style="width: &dialog.width2;;"
- ondialogaccept="return gSanitizePromptDialog.sanitize();">
-
- <prefpane id="SanitizeDialogPane" onpaneload="gSanitizePromptDialog.init();">
- <stringbundle id="bundleBrowser"
- src="chrome://browser/locale/browser.properties"/>
-
- <script type="application/javascript"
- src="chrome://browser/content/sanitize.js"/>
-
-#ifdef CRH_DIALOG_TREE_VIEW
- <script type="application/javascript"
- src="chrome://global/content/globalOverlay.js"/>
- <script type="application/javascript"
- src="chrome://browser/content/places/treeView.js"/>
- <script type="application/javascript"><![CDATA[
- Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
- Components.utils.import("resource:///modules/PlacesUIUtils.jsm");
- ]]></script>
-#endif
-
- <script type="application/javascript"
- src="chrome://browser/content/sanitizeDialog.js"/>
-
- <preferences id="sanitizePreferences">
- <preference id="privacy.cpd.history" name="privacy.cpd.history" type="bool"/>
- <preference id="privacy.cpd.formdata" name="privacy.cpd.formdata" type="bool"/>
- <preference id="privacy.cpd.downloads" name="privacy.cpd.downloads" type="bool" disabled="true"/>
- <preference id="privacy.cpd.cookies" name="privacy.cpd.cookies" type="bool"/>
- <preference id="privacy.cpd.cache" name="privacy.cpd.cache" type="bool"/>
- <preference id="privacy.cpd.sessions" name="privacy.cpd.sessions" type="bool"/>
- <preference id="privacy.cpd.offlineApps" name="privacy.cpd.offlineApps" type="bool"/>
- <preference id="privacy.cpd.siteSettings" name="privacy.cpd.siteSettings" type="bool"/>
- <preference id="privacy.cpd.connectivityData" name="privacy.cpd.connectivityData" type="bool"/>
- </preferences>
-
- <preferences id="nonItemPreferences">
- <preference id="privacy.sanitize.timeSpan"
- name="privacy.sanitize.timeSpan"
- type="int"/>
- </preferences>
-
- <hbox id="SanitizeDurationBox" align="center">
- <label value="&clearTimeDuration.label;"
- accesskey="&clearTimeDuration.accesskey;"
- control="sanitizeDurationChoice"
- id="sanitizeDurationLabel"/>
- <menulist id="sanitizeDurationChoice"
- preference="privacy.sanitize.timeSpan"
- onselect="gSanitizePromptDialog.selectByTimespan();"
- flex="1">
- <menupopup id="sanitizeDurationPopup">
-#ifdef CRH_DIALOG_TREE_VIEW
- <menuitem label="" value="-1" id="sanitizeDurationCustom"/>
-#endif
- <menuitem label="&clearTimeDuration.lastHour;" value="1"/>
- <menuitem label="&clearTimeDuration.last2Hours;" value="2"/>
- <menuitem label="&clearTimeDuration.last4Hours;" value="3"/>
- <menuitem label="&clearTimeDuration.today;" value="4"/>
- <menuseparator/>
- <menuitem label="&clearTimeDuration.everything;" value="0"/>
- </menupopup>
- </menulist>
- <label id="sanitizeDurationSuffixLabel"
- value="&clearTimeDuration.suffix;"/>
- </hbox>
-
- <separator class="thin"/>
-
-#ifdef CRH_DIALOG_TREE_VIEW
- <deck id="durationDeck">
- <tree id="placesTree" flex="1" hidecolumnpicker="true" rows="10"
- disabled="true" disableKeyNavigation="true">
- <treecols>
- <treecol id="date" label="&clearTimeDuration.dateColumn;" flex="1"/>
- <splitter class="tree-splitter"/>
- <treecol id="title" label="&clearTimeDuration.nameColumn;" flex="5"/>
- </treecols>
- <treechildren id="placesTreechildren"
- ondragstart="gSanitizePromptDialog.grippyMoved('ondragstart', event);"
- ondragover="gSanitizePromptDialog.grippyMoved('ondragover', event);"
- onkeypress="gSanitizePromptDialog.grippyMoved('onkeypress', event);"
- onmousedown="gSanitizePromptDialog.grippyMoved('onmousedown', event);"/>
- </tree>
-#endif
-
- <vbox id="sanitizeEverythingWarningBox">
- <spacer flex="1"/>
- <hbox align="center">
- <image id="sanitizeEverythingWarningIcon"/>
- <vbox id="sanitizeEverythingWarningDescBox" flex="1">
- <description id="sanitizeEverythingWarning"/>
- <description id="sanitizeEverythingUndoWarning">&sanitizeEverythingUndoWarning;</description>
- </vbox>
- </hbox>
- <spacer flex="1"/>
- </vbox>
-
-#ifdef CRH_DIALOG_TREE_VIEW
- </deck>
-#endif
-
- <separator class="thin"/>
-
- <hbox id="detailsExpanderWrapper" align="center">
- <button type="image"
- id="detailsExpander"
- class="expander-down"
- persist="class"
- oncommand="gSanitizePromptDialog.toggleItemList();"/>
- <label id="detailsExpanderLabel"
- value="&detailsProgressiveDisclosure.label;"
- accesskey="&detailsProgressiveDisclosure.accesskey;"
- control="detailsExpander"/>
- </hbox>
- <listbox id="itemList" rows="8" collapsed="true" persist="collapsed">
- <listitem label="&itemHistoryAndDownloads.label;"
- type="checkbox"
- accesskey="&itemHistoryAndDownloads.accesskey;"
- preference="privacy.cpd.history"
- onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
- <listitem label="&itemFormSearchHistory.label;"
- type="checkbox"
- accesskey="&itemFormSearchHistory.accesskey;"
- preference="privacy.cpd.formdata"
- onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
- <listitem label="&itemCookies.label;"
- type="checkbox"
- accesskey="&itemCookies.accesskey;"
- preference="privacy.cpd.cookies"
- onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
- <listitem label="&itemCache.label;"
- type="checkbox"
- accesskey="&itemCache.accesskey;"
- preference="privacy.cpd.cache"
- onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
- <listitem label="&itemActiveLogins.label;"
- type="checkbox"
- accesskey="&itemActiveLogins.accesskey;"
- preference="privacy.cpd.sessions"
- onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
- <listitem label="&itemOfflineApps.label;"
- type="checkbox"
- accesskey="&itemOfflineApps.accesskey;"
- preference="privacy.cpd.offlineApps"
- onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
- <listitem label="&itemSitePreferences.label;"
- type="checkbox"
- accesskey="&itemSitePreferences.accesskey;"
- preference="privacy.cpd.siteSettings"
- noduration="true"
- onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
- <listitem label="&itemConnectivityData.label;"
- type="checkbox"
- accesskey="&itemConnectivityData.accesskey;"
- preference="privacy.cpd.connectivityData"
- noduration="true"
- onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
- </listbox>
-
- </prefpane>
-</prefwindow>
diff --git a/base/content/sanitizeDialog.css b/base/content/sanitizeDialog.css
deleted file mode 100644
index 27c3c08..0000000
--- a/base/content/sanitizeDialog.css
+++ /dev/null
@@ -1,23 +0,0 @@
-/* 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/. */
-
-/* Places tree */
-
-#placesTreechildren {
- -moz-user-focus: normal;
-}
-
-#placesTreechildren::-moz-tree-cell(grippyRow),
-#placesTreechildren::-moz-tree-cell-text(grippyRow),
-#placesTreechildren::-moz-tree-image(grippyRow) {
- cursor: -moz-grab;
-}
-
-
-/* Sanitize everything warnings */
-
-#sanitizeEverythingWarning,
-#sanitizeEverythingUndoWarning {
- white-space: pre-wrap;
-}
diff --git a/base/content/sanitizeDialog.js b/base/content/sanitizeDialog.js
deleted file mode 100644
index 7861132..0000000
--- a/base/content/sanitizeDialog.js
+++ /dev/null
@@ -1,910 +0,0 @@
-/* -*- Mode: Java; 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 Cc = Components.classes;
-var Ci = Components.interfaces;
-
-var gSanitizePromptDialog = {
-
- get bundleBrowser()
- {
- if (!this._bundleBrowser)
- this._bundleBrowser = document.getElementById("bundleBrowser");
- return this._bundleBrowser;
- },
-
- get selectedTimespan()
- {
- var durList = document.getElementById("sanitizeDurationChoice");
- return parseInt(durList.value);
- },
-
- get sanitizePreferences()
- {
- if (!this._sanitizePreferences) {
- this._sanitizePreferences =
- document.getElementById("sanitizePreferences");
- }
- return this._sanitizePreferences;
- },
-
- get warningBox()
- {
- return document.getElementById("sanitizeEverythingWarningBox");
- },
-
- init: function ()
- {
- // This is used by selectByTimespan() to determine if the window has loaded.
- this._inited = true;
-
- var s = new Sanitizer();
- s.prefDomain = "privacy.cpd.";
-
- let sanitizeItemList = document.querySelectorAll("#itemList > [preference]");
- for (let i = 0; i < sanitizeItemList.length; i++) {
- let prefItem = sanitizeItemList[i];
- let name = s.getNameFromPreference(prefItem.getAttribute("preference"));
- s.canClearItem(name, function canClearCallback(aItem, aCanClear, aPrefItem) {
- if (!aCanClear) {
- aPrefItem.preference = null;
- aPrefItem.checked = false;
- aPrefItem.disabled = true;
- }
- }, prefItem);
- }
-
- document.documentElement.getButton("accept").label =
- this.bundleBrowser.getString("sanitizeButtonOK");
-
- if (this.selectedTimespan === Sanitizer.TIMESPAN_EVERYTHING) {
- this.prepareWarning();
- this.warningBox.hidden = false;
- document.title =
- this.bundleBrowser.getString("sanitizeDialog2.everything.title");
- }
- else
- this.warningBox.hidden = true;
- },
-
- selectByTimespan: function ()
- {
- // This method is the onselect handler for the duration dropdown. As a
- // result it's called a couple of times before onload calls init().
- if (!this._inited)
- return;
-
- var warningBox = this.warningBox;
-
- // If clearing everything
- if (this.selectedTimespan === Sanitizer.TIMESPAN_EVERYTHING) {
- this.prepareWarning();
- if (warningBox.hidden) {
- warningBox.hidden = false;
- window.resizeBy(0, warningBox.boxObject.height);
- }
- window.document.title =
- this.bundleBrowser.getString("sanitizeDialog2.everything.title");
- return;
- }
-
- // If clearing a specific time range
- if (!warningBox.hidden) {
- window.resizeBy(0, -warningBox.boxObject.height);
- warningBox.hidden = true;
- }
- window.document.title =
- window.document.documentElement.getAttribute("noneverythingtitle");
- },
-
- sanitize: function ()
- {
- // Update pref values before handing off to the sanitizer (bug 453440)
- this.updatePrefs();
- var s = new Sanitizer();
- s.prefDomain = "privacy.cpd.";
-
- s.range = Sanitizer.getClearRange(this.selectedTimespan);
- s.ignoreTimespan = !s.range;
-
- // As the sanitize is async, we disable the buttons, update the label on
- // the 'accept' button to indicate things are happening and return false -
- // once the async operation completes (either with or without errors)
- // we close the window.
- let docElt = document.documentElement;
- let acceptButton = docElt.getButton("accept");
- acceptButton.disabled = true;
- acceptButton.setAttribute("label",
- this.bundleBrowser.getString("sanitizeButtonClearing"));
- docElt.getButton("cancel").disabled = true;
- try {
- s.sanitize().then(window.close, window.close);
- } catch (er) {
- Components.utils.reportError("Exception during sanitize: " + er);
- return true; // We *do* want to close immediately on error.
- }
- return false;
- },
-
- /**
- * If the panel that displays a warning when the duration is "Everything" is
- * not set up, sets it up. Otherwise does nothing.
- *
- * @param aDontShowItemList Whether only the warning message should be updated.
- * True means the item list visibility status should not
- * be changed.
- */
- prepareWarning: function (aDontShowItemList) {
- // If the date and time-aware locale warning string is ever used again,
- // initialize it here. Currently we use the no-visits warning string,
- // which does not include date and time. See bug 480169 comment 48.
-
- var warningStringID;
- if (this.hasNonSelectedItems()) {
- warningStringID = "sanitizeSelectedWarning";
- if (!aDontShowItemList)
- this.showItemList();
- }
- else {
- warningStringID = "sanitizeEverythingWarning2";
- }
-
- var warningDesc = document.getElementById("sanitizeEverythingWarning");
- warningDesc.textContent =
- this.bundleBrowser.getString(warningStringID);
- },
-
- /**
- * Called when the value of a preference element is synced from the actual
- * pref. Enables or disables the OK button appropriately.
- */
- onReadGeneric: function ()
- {
- var found = false;
-
- // Find any other pref that's checked and enabled.
- var i = 0;
- while (!found && i < this.sanitizePreferences.childNodes.length) {
- var preference = this.sanitizePreferences.childNodes[i];
-
- found = !!preference.value &&
- !preference.disabled;
- i++;
- }
-
- try {
- document.documentElement.getButton("accept").disabled = !found;
- }
- catch (e) { }
-
- // Update the warning prompt if needed
- this.prepareWarning(true);
-
- return undefined;
- },
-
- /**
- * Sanitizer.prototype.sanitize() requires the prefs to be up-to-date.
- * Because the type of this prefwindow is "child" -- and that's needed because
- * without it the dialog has no OK and Cancel buttons -- the prefs are not
- * updated on dialogaccept on platforms that don't support instant-apply
- * (i.e., Windows). We must therefore manually set the prefs from their
- * corresponding preference elements.
- */
- updatePrefs : function ()
- {
- var tsPref = document.getElementById("privacy.sanitize.timeSpan");
- Sanitizer.prefs.setIntPref("timeSpan", this.selectedTimespan);
-
- // Keep the pref for the download history in sync with the history pref.
- document.getElementById("privacy.cpd.downloads").value =
- document.getElementById("privacy.cpd.history").value;
-
- // Now manually set the prefs from their corresponding preference
- // elements.
- var prefs = this.sanitizePreferences.rootBranch;
- for (let i = 0; i < this.sanitizePreferences.childNodes.length; ++i) {
- var p = this.sanitizePreferences.childNodes[i];
- prefs.setBoolPref(p.name, p.value);
- }
- },
-
- /**
- * Check if all of the history items have been selected like the default status.
- */
- hasNonSelectedItems: function () {
- let checkboxes = document.querySelectorAll("#itemList > [preference]");
- for (let i = 0; i < checkboxes.length; ++i) {
- let pref = document.getElementById(checkboxes[i].getAttribute("preference"));
- if (!pref.value)
- return true;
- }
- return false;
- },
-
- /**
- * Show the history items list.
- */
- showItemList: function () {
- var itemList = document.getElementById("itemList");
- var expanderButton = document.getElementById("detailsExpander");
-
- if (itemList.collapsed) {
- expanderButton.className = "expander-up";
- itemList.setAttribute("collapsed", "false");
- if (document.documentElement.boxObject.height)
- window.resizeBy(0, itemList.boxObject.height);
- }
- },
-
- /**
- * Hide the history items list.
- */
- hideItemList: function () {
- var itemList = document.getElementById("itemList");
- var expanderButton = document.getElementById("detailsExpander");
-
- if (!itemList.collapsed) {
- expanderButton.className = "expander-down";
- window.resizeBy(0, -itemList.boxObject.height);
- itemList.setAttribute("collapsed", "true");
- }
- },
-
- /**
- * Called by the item list expander button to toggle the list's visibility.
- */
- toggleItemList: function ()
- {
- var itemList = document.getElementById("itemList");
-
- if (itemList.collapsed)
- this.showItemList();
- else
- this.hideItemList();
- }
-
-#ifdef CRH_DIALOG_TREE_VIEW
- // A duration value; used in the same context as Sanitizer.TIMESPAN_HOUR,
- // Sanitizer.TIMESPAN_2HOURS, et al. This should match the value attribute
- // of the sanitizeDurationCustom menuitem.
- get TIMESPAN_CUSTOM()
- {
- return -1;
- },
-
- get placesTree()
- {
- if (!this._placesTree)
- this._placesTree = document.getElementById("placesTree");
- return this._placesTree;
- },
-
- init: function ()
- {
- // This is used by selectByTimespan() to determine if the window has loaded.
- this._inited = true;
-
- var s = new Sanitizer();
- s.prefDomain = "privacy.cpd.";
-
- let sanitizeItemList = document.querySelectorAll("#itemList > [preference]");
- for (let i = 0; i < sanitizeItemList.length; i++) {
- let prefItem = sanitizeItemList[i];
- let name = s.getNameFromPreference(prefItem.getAttribute("preference"));
- s.canClearItem(name, function canClearCallback(aCanClear) {
- if (!aCanClear) {
- prefItem.preference = null;
- prefItem.checked = false;
- prefItem.disabled = true;
- }
- });
- }
-
- document.documentElement.getButton("accept").label =
- this.bundleBrowser.getString("sanitizeButtonOK");
-
- this.selectByTimespan();
- },
-
- /**
- * Sets up the hashes this.durationValsToRows, which maps duration values
- * to rows in the tree, this.durationRowsToVals, which maps rows in
- * the tree to duration values, and this.durationStartTimes, which maps
- * duration values to their corresponding start times.
- */
- initDurationDropdown: function ()
- {
- // First, calculate the start times for each duration.
- this.durationStartTimes = {};
- var durVals = [];
- var durPopup = document.getElementById("sanitizeDurationPopup");
- var durMenuitems = durPopup.childNodes;
- for (let i = 0; i < durMenuitems.length; i++) {
- let durMenuitem = durMenuitems[i];
- let durVal = parseInt(durMenuitem.value);
- if (durMenuitem.localName === "menuitem" &&
- durVal !== Sanitizer.TIMESPAN_EVERYTHING &&
- durVal !== this.TIMESPAN_CUSTOM) {
- durVals.push(durVal);
- let durTimes = Sanitizer.getClearRange(durVal);
- this.durationStartTimes[durVal] = durTimes[0];
- }
- }
-
- // Sort the duration values ascending. Because one tree index can map to
- // more than one duration, this ensures that this.durationRowsToVals maps
- // a row index to the largest duration possible in the code below.
- durVals.sort();
-
- // Now calculate the rows in the tree of the durations' start times. For
- // each duration, we are looking for the node in the tree whose time is the
- // smallest time greater than or equal to the duration's start time.
- this.durationRowsToVals = {};
- this.durationValsToRows = {};
- var view = this.placesTree.view;
- // For all rows in the tree except the grippy row...
- for (let i = 0; i < view.rowCount - 1; i++) {
- let unfoundDurVals = [];
- let nodeTime = view.QueryInterface(Ci.nsINavHistoryResultTreeViewer).
- nodeForTreeIndex(i).time;
- // For all durations whose rows have not yet been found in the tree, see
- // if index i is their index. An index may map to more than one duration,
- // in which case the final duration (the largest) wins.
- for (let j = 0; j < durVals.length; j++) {
- let durVal = durVals[j];
- let durStartTime = this.durationStartTimes[durVal];
- if (nodeTime < durStartTime) {
- this.durationValsToRows[durVal] = i - 1;
- this.durationRowsToVals[i - 1] = durVal;
- }
- else
- unfoundDurVals.push(durVal);
- }
- durVals = unfoundDurVals;
- }
-
- // If any durations were not found above, then every node in the tree has a
- // time greater than or equal to the duration. In other words, those
- // durations include the entire tree (except the grippy row).
- for (let i = 0; i < durVals.length; i++) {
- let durVal = durVals[i];
- this.durationValsToRows[durVal] = view.rowCount - 2;
- this.durationRowsToVals[view.rowCount - 2] = durVal;
- }
- },
-
- /**
- * If the Places tree is not set up, sets it up. Otherwise does nothing.
- */
- ensurePlacesTreeIsInited: function ()
- {
- if (this._placesTreeIsInited)
- return;
-
- this._placesTreeIsInited = true;
-
- // Either "Last Four Hours" or "Today" will have the most history. If
- // it's been more than 4 hours since today began, "Today" will. Otherwise
- // "Last Four Hours" will.
- var times = Sanitizer.getClearRange(Sanitizer.TIMESPAN_TODAY);
-
- // If it's been less than 4 hours since today began, use the past 4 hours.
- if (times[1] - times[0] < 14400000000) { // 4*60*60*1000000
- times = Sanitizer.getClearRange(Sanitizer.TIMESPAN_4HOURS);
- }
-
- var histServ = Cc["@mozilla.org/browser/nav-history-service;1"].
- getService(Ci.nsINavHistoryService);
- var query = histServ.getNewQuery();
- query.beginTimeReference = query.TIME_RELATIVE_EPOCH;
- query.beginTime = times[0];
- query.endTimeReference = query.TIME_RELATIVE_EPOCH;
- query.endTime = times[1];
- var opts = histServ.getNewQueryOptions();
- opts.sortingMode = opts.SORT_BY_DATE_DESCENDING;
- opts.queryType = opts.QUERY_TYPE_HISTORY;
- var result = histServ.executeQuery(query, opts);
-
- var view = gContiguousSelectionTreeHelper.setTree(this.placesTree,
- new PlacesTreeView());
- result.addObserver(view, false);
- this.initDurationDropdown();
- },
-
- /**
- * Called on select of the duration dropdown and when grippyMoved() sets a
- * duration based on the location of the grippy row. Selects all the nodes in
- * the tree that are contained in the selected duration. If clearing
- * everything, the warning panel is shown instead.
- */
- selectByTimespan: function ()
- {
- // This method is the onselect handler for the duration dropdown. As a
- // result it's called a couple of times before onload calls init().
- if (!this._inited)
- return;
-
- var durDeck = document.getElementById("durationDeck");
- var durList = document.getElementById("sanitizeDurationChoice");
- var durVal = parseInt(durList.value);
- var durCustom = document.getElementById("sanitizeDurationCustom");
-
- // If grippy row is not at a duration boundary, show the custom menuitem;
- // otherwise, hide it. Since the user cannot specify a custom duration by
- // using the dropdown, this conditional is true only when this method is
- // called onselect from grippyMoved(), so no selection need be made.
- if (durVal === this.TIMESPAN_CUSTOM) {
- durCustom.hidden = false;
- return;
- }
- durCustom.hidden = true;
-
- // If clearing everything, show the warning and change the dialog's title.
- if (durVal === Sanitizer.TIMESPAN_EVERYTHING) {
- this.prepareWarning();
- durDeck.selectedIndex = 1;
- window.document.title =
- this.bundleBrowser.getString("sanitizeDialog2.everything.title");
- document.documentElement.getButton("accept").disabled = false;
- return;
- }
-
- // Otherwise -- if clearing a specific time range -- select that time range
- // in the tree.
- this.ensurePlacesTreeIsInited();
- durDeck.selectedIndex = 0;
- window.document.title =
- window.document.documentElement.getAttribute("noneverythingtitle");
- var durRow = this.durationValsToRows[durVal];
- gContiguousSelectionTreeHelper.rangedSelect(durRow);
- gContiguousSelectionTreeHelper.scrollToGrippy();
-
- // If duration is empty (there are no selected rows), disable the dialog's
- // OK button.
- document.documentElement.getButton("accept").disabled = durRow < 0;
- },
-
- sanitize: function ()
- {
- // Update pref values before handing off to the sanitizer (bug 453440)
- this.updatePrefs();
- var s = new Sanitizer();
- s.prefDomain = "privacy.cpd.";
-
- var durList = document.getElementById("sanitizeDurationChoice");
- var durValue = parseInt(durList.value);
- s.ignoreTimespan = durValue === Sanitizer.TIMESPAN_EVERYTHING;
-
- // Set the sanitizer's time range if we're not clearing everything.
- if (!s.ignoreTimespan) {
- // If user selected a custom timespan, use that.
- if (durValue === this.TIMESPAN_CUSTOM) {
- var view = this.placesTree.view;
- var now = Date.now() * 1000;
- // We disable the dialog's OK button if there's no selection, but we'll
- // handle that case just in... case.
- if (view.selection.getRangeCount() === 0)
- s.range = [now, now];
- else {
- var startIndexRef = {};
- // Tree sorted by visit date DEscending, so start time time comes last.
- view.selection.getRangeAt(0, {}, startIndexRef);
- view.QueryInterface(Ci.nsINavHistoryResultTreeViewer);
- var startNode = view.nodeForTreeIndex(startIndexRef.value);
- s.range = [startNode.time, now];
- }
- }
- // Otherwise use the predetermined range.
- else
- s.range = [this.durationStartTimes[durValue], Date.now() * 1000];
- }
-
- try {
- s.sanitize();
- } catch (er) {
- Components.utils.reportError("Exception during sanitize: " + er);
- }
- return true;
- },
-
- /**
- * In order to mark the custom Places tree view and its nsINavHistoryResult
- * for garbage collection, we need to break the reference cycle between the
- * two.
- */
- unload: function ()
- {
- let result = this.placesTree.getResult();
- result.removeObserver(this.placesTree.view);
- this.placesTree.view = null;
- },
-
- /**
- * Called when the user moves the grippy by dragging it, clicking in the tree,
- * or on keypress. Updates the duration dropdown so that it displays the
- * appropriate specific or custom duration.
- *
- * @param aEventName
- * The name of the event whose handler called this method, e.g.,
- * "ondragstart", "onkeypress", etc.
- * @param aEvent
- * The event captured in the event handler.
- */
- grippyMoved: function (aEventName, aEvent)
- {
- gContiguousSelectionTreeHelper[aEventName](aEvent);
- var lastSelRow = gContiguousSelectionTreeHelper.getGrippyRow() - 1;
- var durList = document.getElementById("sanitizeDurationChoice");
- var durValue = parseInt(durList.value);
-
- // Multiple durations can map to the same row. Don't update the dropdown
- // if the current duration is valid for lastSelRow.
- if ((durValue !== this.TIMESPAN_CUSTOM ||
- lastSelRow in this.durationRowsToVals) &&
- (durValue === this.TIMESPAN_CUSTOM ||
- this.durationValsToRows[durValue] !== lastSelRow)) {
- // Setting durList.value causes its onselect handler to fire, which calls
- // selectByTimespan().
- if (lastSelRow in this.durationRowsToVals)
- durList.value = this.durationRowsToVals[lastSelRow];
- else
- durList.value = this.TIMESPAN_CUSTOM;
- }
-
- // If there are no selected rows, disable the dialog's OK button.
- document.documentElement.getButton("accept").disabled = lastSelRow < 0;
- }
-#endif
-
-};
-
-
-#ifdef CRH_DIALOG_TREE_VIEW
-/**
- * A helper for handling contiguous selection in the tree.
- */
-var gContiguousSelectionTreeHelper = {
-
- /**
- * Gets the tree associated with this helper.
- */
- get tree()
- {
- return this._tree;
- },
-
- /**
- * Sets the tree that this module handles. The tree is assigned a new view
- * that is equipped to handle contiguous selection. You can pass in an
- * object that will be used as the prototype of the new view. Otherwise
- * the tree's current view is used as the prototype.
- *
- * @param aTreeElement
- * The tree element
- * @param aProtoTreeView
- * If defined, this will be used as the prototype of the tree's new
- * view
- * @return The new view
- */
- setTree: function CSTH_setTree(aTreeElement, aProtoTreeView)
- {
- this._tree = aTreeElement;
- var newView = this._makeTreeView(aProtoTreeView || aTreeElement.view);
- aTreeElement.view = newView;
- return newView;
- },
-
- /**
- * The index of the row that the grippy occupies. Note that the index of the
- * last selected row is getGrippyRow() - 1. If getGrippyRow() is 0, then
- * no selection exists.
- *
- * @return The row index of the grippy
- */
- getGrippyRow: function CSTH_getGrippyRow()
- {
- var sel = this.tree.view.selection;
- var rangeCount = sel.getRangeCount();
- if (rangeCount === 0)
- return 0;
- if (rangeCount !== 1) {
- throw "contiguous selection tree helper: getGrippyRow called with " +
- "multiple selection ranges";
- }
- var max = {};
- sel.getRangeAt(0, {}, max);
- return max.value + 1;
- },
-
- /**
- * Helper function for the dragover event. Your dragover listener should
- * call this. It updates the selection in the tree under the mouse.
- *
- * @param aEvent
- * The observed dragover event
- */
- ondragover: function CSTH_ondragover(aEvent)
- {
- // Without this when dragging on Windows the mouse cursor is a "no" sign.
- // This makes it a drop symbol.
- var ds = Cc["@mozilla.org/widget/dragservice;1"].
- getService(Ci.nsIDragService).
- getCurrentSession();
- ds.canDrop = true;
- ds.dragAction = 0;
-
- var tbo = this.tree.treeBoxObject;
- aEvent.QueryInterface(Ci.nsIDOMMouseEvent);
- var hoverRow = tbo.getRowAt(aEvent.clientX, aEvent.clientY);
-
- if (hoverRow < 0)
- return;
-
- this.rangedSelect(hoverRow - 1);
- },
-
- /**
- * Helper function for the dragstart event. Your dragstart listener should
- * call this. It starts a drag session.
- *
- * @param aEvent
- * The observed dragstart event
- */
- ondragstart: function CSTH_ondragstart(aEvent)
- {
- var tbo = this.tree.treeBoxObject;
- var clickedRow = tbo.getRowAt(aEvent.clientX, aEvent.clientY);
-
- if (clickedRow !== this.getGrippyRow())
- return;
-
- // This part is a hack. What we really want is a grab and slide, not
- // drag and drop. Start a move drag session with dummy data and a
- // dummy region. Set the region's coordinates to (Infinity, Infinity)
- // so it's drawn offscreen and its size to (1, 1).
- var arr = Cc["@mozilla.org/supports-array;1"].
- createInstance(Ci.nsISupportsArray);
- var trans = Cc["@mozilla.org/widget/transferable;1"].
- createInstance(Ci.nsITransferable);
- trans.init(null);
- trans.setTransferData('dummy-flavor', null, 0);
- arr.AppendElement(trans);
- var reg = Cc["@mozilla.org/gfx/region;1"].
- createInstance(Ci.nsIScriptableRegion);
- reg.setToRect(Infinity, Infinity, 1, 1);
- var ds = Cc["@mozilla.org/widget/dragservice;1"].
- getService(Ci.nsIDragService);
- ds.invokeDragSession(aEvent.target, arr, reg, ds.DRAGDROP_ACTION_MOVE);
- },
-
- /**
- * Helper function for the keypress event. Your keypress listener should
- * call this. Users can use Up, Down, Page Up/Down, Home, and End to move
- * the bottom of the selection window.
- *
- * @param aEvent
- * The observed keypress event
- */
- onkeypress: function CSTH_onkeypress(aEvent)
- {
- var grippyRow = this.getGrippyRow();
- var tbo = this.tree.treeBoxObject;
- var rangeEnd;
- switch (aEvent.keyCode) {
- case aEvent.DOM_VK_HOME:
- rangeEnd = 0;
- break;
- case aEvent.DOM_VK_PAGE_UP:
- rangeEnd = grippyRow - tbo.getPageLength();
- break;
- case aEvent.DOM_VK_UP:
- rangeEnd = grippyRow - 2;
- break;
- case aEvent.DOM_VK_DOWN:
- rangeEnd = grippyRow;
- break;
- case aEvent.DOM_VK_PAGE_DOWN:
- rangeEnd = grippyRow + tbo.getPageLength();
- break;
- case aEvent.DOM_VK_END:
- rangeEnd = this.tree.view.rowCount - 2;
- break;
- default:
- return;
- break;
- }
-
- aEvent.stopPropagation();
-
- // First, clip rangeEnd. this.rangedSelect() doesn't clip the range if we
- // select past the ends of the tree.
- if (rangeEnd < 0)
- rangeEnd = -1;
- else if (this.tree.view.rowCount - 2 < rangeEnd)
- rangeEnd = this.tree.view.rowCount - 2;
-
- // Next, (de)select.
- this.rangedSelect(rangeEnd);
-
- // Finally, scroll the tree. We always want one row above and below the
- // grippy row to be visible if possible.
- if (rangeEnd < grippyRow) // moved up
- tbo.ensureRowIsVisible(rangeEnd < 0 ? 0 : rangeEnd);
- else { // moved down
- if (rangeEnd + 2 < this.tree.view.rowCount)
- tbo.ensureRowIsVisible(rangeEnd + 2);
- else if (rangeEnd + 1 < this.tree.view.rowCount)
- tbo.ensureRowIsVisible(rangeEnd + 1);
- }
- },
-
- /**
- * Helper function for the mousedown event. Your mousedown listener should
- * call this. Users can click on individual rows to make the selection
- * jump to them immediately.
- *
- * @param aEvent
- * The observed mousedown event
- */
- onmousedown: function CSTH_onmousedown(aEvent)
- {
- var tbo = this.tree.treeBoxObject;
- var clickedRow = tbo.getRowAt(aEvent.clientX, aEvent.clientY);
-
- if (clickedRow < 0 || clickedRow >= this.tree.view.rowCount)
- return;
-
- if (clickedRow < this.getGrippyRow())
- this.rangedSelect(clickedRow);
- else if (clickedRow > this.getGrippyRow())
- this.rangedSelect(clickedRow - 1);
- },
-
- /**
- * Selects range [0, aEndRow] in the tree. The grippy row will then be at
- * index aEndRow + 1. aEndRow may be -1, in which case the selection is
- * cleared and the grippy row will be at index 0.
- *
- * @param aEndRow
- * The range [0, aEndRow] will be selected.
- */
- rangedSelect: function CSTH_rangedSelect(aEndRow)
- {
- var tbo = this.tree.treeBoxObject;
- if (aEndRow < 0)
- this.tree.view.selection.clearSelection();
- else
- this.tree.view.selection.rangedSelect(0, aEndRow, false);
- tbo.invalidateRange(tbo.getFirstVisibleRow(), tbo.getLastVisibleRow());
- },
-
- /**
- * Scrolls the tree so that the grippy row is in the center of the view.
- */
- scrollToGrippy: function CSTH_scrollToGrippy()
- {
- var rowCount = this.tree.view.rowCount;
- var tbo = this.tree.treeBoxObject;
- var pageLen = tbo.getPageLength() ||
- parseInt(this.tree.getAttribute("rows")) ||
- 10;
-
- // All rows fit on a single page.
- if (rowCount <= pageLen)
- return;
-
- var scrollToRow = this.getGrippyRow() - Math.ceil(pageLen / 2.0);
-
- // Grippy row is in first half of first page.
- if (scrollToRow < 0)
- scrollToRow = 0;
-
- // Grippy row is in last half of last page.
- else if (rowCount < scrollToRow + pageLen)
- scrollToRow = rowCount - pageLen;
-
- tbo.scrollToRow(scrollToRow);
- },
-
- /**
- * Creates a new tree view suitable for contiguous selection. If
- * aProtoTreeView is specified, it's used as the new view's prototype.
- * Otherwise the tree's current view is used as the prototype.
- *
- * @param aProtoTreeView
- * Used as the new view's prototype if specified
- */
- _makeTreeView: function CSTH__makeTreeView(aProtoTreeView)
- {
- var view = aProtoTreeView;
- var that = this;
-
- //XXXadw: When Alex gets the grippy icon done, this may or may not change,
- // depending on how we style it.
- view.isSeparator = function CSTH_View_isSeparator(aRow)
- {
- return aRow === that.getGrippyRow();
- };
-
- // rowCount includes the grippy row.
- view.__defineGetter__("_rowCount", view.__lookupGetter__("rowCount"));
- view.__defineGetter__("rowCount",
- function CSTH_View_rowCount()
- {
- return this._rowCount + 1;
- });
-
- // This has to do with visual feedback in the view itself, e.g., drawing
- // a small line underneath the dropzone. Not what we want.
- view.canDrop = function CSTH_View_canDrop() { return false; };
-
- // No clicking headers to sort the tree or sort feedback on columns.
- view.cycleHeader = function CSTH_View_cycleHeader() {};
- view.sortingChanged = function CSTH_View_sortingChanged() {};
-
- // Override a bunch of methods to account for the grippy row.
-
- view._getCellProperties = view.getCellProperties;
- view.getCellProperties =
- function CSTH_View_getCellProperties(aRow, aCol)
- {
- var grippyRow = that.getGrippyRow();
- if (aRow === grippyRow)
- return "grippyRow";
- if (aRow < grippyRow)
- return this._getCellProperties(aRow, aCol);
-
- return this._getCellProperties(aRow - 1, aCol);
- };
-
- view._getRowProperties = view.getRowProperties;
- view.getRowProperties =
- function CSTH_View_getRowProperties(aRow)
- {
- var grippyRow = that.getGrippyRow();
- if (aRow === grippyRow)
- return "grippyRow";
-
- if (aRow < grippyRow)
- return this._getRowProperties(aRow);
-
- return this._getRowProperties(aRow - 1);
- };
-
- view._getCellText = view.getCellText;
- view.getCellText =
- function CSTH_View_getCellText(aRow, aCol)
- {
- var grippyRow = that.getGrippyRow();
- if (aRow === grippyRow)
- return "";
- aRow = aRow < grippyRow ? aRow : aRow - 1;
- return this._getCellText(aRow, aCol);
- };
-
- view._getImageSrc = view.getImageSrc;
- view.getImageSrc =
- function CSTH_View_getImageSrc(aRow, aCol)
- {
- var grippyRow = that.getGrippyRow();
- if (aRow === grippyRow)
- return "";
- aRow = aRow < grippyRow ? aRow : aRow - 1;
- return this._getImageSrc(aRow, aCol);
- };
-
- view.isContainer = function CSTH_View_isContainer(aRow) { return false; };
- view.getParentIndex = function CSTH_View_getParentIndex(aRow) { return -1; };
- view.getLevel = function CSTH_View_getLevel(aRow) { return 0; };
- view.hasNextSibling = function CSTH_View_hasNextSibling(aRow, aAfterIndex)
- {
- return aRow < this.rowCount - 1;
- };
-
- return view;
- }
-};
-#endif
diff --git a/base/content/softwareUpdateOverlay.xul b/base/content/softwareUpdateOverlay.xul
deleted file mode 100644
index 01170e4..0000000
--- a/base/content/softwareUpdateOverlay.xul
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0"?>
-# 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/.
-
-<?xul-overlay href="chrome://browser/content/macBrowserOverlay.xul"?>
-
-<overlay id="softwareUpdateOverlay"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<window id="updates">
-
-#include browserMountPoints.inc
-
-</window>
-
-</overlay>
diff --git a/base/content/tabbrowser.css b/base/content/tabbrowser.css
deleted file mode 100644
index 43536b2..0000000
--- a/base/content/tabbrowser.css
+++ /dev/null
@@ -1,77 +0,0 @@
-/* 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/. */
-
-.tabbrowser-tabbox {
- -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tabbox");
- /* Make the content area follow the system colors before load */
- background: Menu;
- color: MenuText;
-}
-
-.tabbrowser-arrowscrollbox {
- -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-arrowscrollbox");
-}
-
-.tab-close-button {
- -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-close-tab-button");
- display: none;
-}
-
-.tabbrowser-tabs[closebuttons="activetab"] > * > * > * > .tab-close-button:not([pinned])[selected="true"],
-.tabbrowser-tabs[closebuttons="alltabs"] > * > * > * > .tab-close-button:not([pinned]) {
- display: -moz-box;
-}
-
-.tab-label[pinned] {
- width: 0;
- margin-left: 0 !important;
- margin-right: 0 !important;
- padding-left: 0 !important;
- padding-right: 0 !important;
-}
-
-.tab-stack {
- vertical-align: top; /* for pinned tabs */
-}
-
-tabpanels {
- background-color: transparent;
-}
-
-.tab-drop-indicator {
- position: relative;
- z-index: 2;
-}
-
-.tab-throbber:not([busy]),
-.tab-throbber[busy] + .tab-icon-image,
-.tab-icon-sound:not([soundplaying]):not([muted]):not([blocked]),
-.tab-icon-sound[pinned],
-.tab-icon-overlay {
- display: none;
-}
-
-.tab-icon-overlay[soundplaying][pinned],
-.tab-icon-overlay[muted][pinned],
-.tab-icon-overlay[blocked][pinned] {
- display: -moz-box;
-}
-
-.closing-tabs-spacer {
- pointer-events: none;
-}
-
-.tabbrowser-tabs:not(:hover) > .tabbrowser-arrowscrollbox > .closing-tabs-spacer {
- transition: width .15s ease-out;
-}
-
-/**
- * Optimization for tabs that are restored lazily. We can save a good amount of
- * memory that to-be-restored tabs would otherwise consume simply by setting
- * their browsers to 'display: none' as that will prevent them from having to
- * create a presentation and the like.
- */
-browser[pending] {
- display: none;
-}
diff --git a/base/content/tabbrowser.xml b/base/content/tabbrowser.xml
deleted file mode 100644
index b5edd54..0000000
--- a/base/content/tabbrowser.xml
+++ /dev/null
@@ -1,5403 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- 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/. -->
-
-<!DOCTYPE bindings [
-<!ENTITY % tabBrowserDTD SYSTEM "chrome://browser/locale/tabbrowser.dtd" >
-%tabBrowserDTD;
-]>
-
-<bindings id="tabBrowserBindings"
- xmlns="http://www.mozilla.org/xbl"
- xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- xmlns:xbl="http://www.mozilla.org/xbl">
-
- <binding id="tabbrowser">
- <resources>
- <stylesheet src="chrome://browser/content/tabbrowser.css"/>
- </resources>
-
- <content>
- <xul:stringbundle anonid="tbstringbundle" src="chrome://browser/locale/tabbrowser.properties"/>
- <xul:tabbox anonid="tabbox" class="tabbrowser-tabbox"
- flex="1" eventnode="document" xbl:inherits="handleCtrlPageUpDown"
- onselect="if (event.target.localName == 'tabpanels') this.parentNode.updateCurrentBrowser();">
- <xul:tabpanels flex="1" class="plain" selectedIndex="0" anonid="panelcontainer">
- <xul:notificationbox flex="1">
- <xul:hbox flex="1" class="browserSidebarContainer">
- <xul:vbox flex="1" class="browserContainer">
- <xul:stack flex="1" class="browserStack" anonid="browserStack">
- <xul:browser anonid="initialBrowser" type="content-primary" message="true" disablehistory="true"
- xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu,autocompletepopup,datetimepicker,authdosprotected"/>
- </xul:stack>
- </xul:vbox>
- </xul:hbox>
- </xul:notificationbox>
- </xul:tabpanels>
- </xul:tabbox>
- <children/>
- </content>
- <implementation implements="nsIDOMEventListener, nsIMessageListener">
-
- <property name="tabContextMenu" readonly="true"
- onget="return this.tabContainer.contextMenu;"/>
-
- <field name="tabContainer" readonly="true">
- document.getElementById(this.getAttribute("tabcontainer"));
- </field>
- <field name="tabs" readonly="true">
- this.tabContainer.childNodes;
- </field>
-
- <property name="visibleTabs" readonly="true">
- <getter><![CDATA[
- if (!this._visibleTabs)
- this._visibleTabs = Array.filter(this.tabs,
- function (tab) !tab.hidden && !tab.closing);
- return this._visibleTabs;
- ]]></getter>
- </property>
-
- <field name="closingTabsEnum" readonly="true">({ ALL: 0, OTHER: 1, TO_END: 2 });</field>
-
- <field name="_visibleTabs">null</field>
-
- <field name="mURIFixup" readonly="true">
- Components.classes["@mozilla.org/docshell/urifixup;1"]
- .getService(Components.interfaces.nsIURIFixup);
- </field>
- <field name="mFaviconService" readonly="true">
- Components.classes["@mozilla.org/browser/favicon-service;1"]
- .getService(Components.interfaces.nsIFaviconService);
- </field>
- <field name="_placesAutocomplete" readonly="true">
- Components.classes["@mozilla.org/autocomplete/search;1?name=history"]
- .getService(Components.interfaces.mozIPlacesAutoComplete);
- </field>
- <field name="mTabBox" readonly="true">
- document.getAnonymousElementByAttribute(this, "anonid", "tabbox");
- </field>
- <field name="mPanelContainer" readonly="true">
- document.getAnonymousElementByAttribute(this, "anonid", "panelcontainer");
- </field>
- <field name="mStringBundle">
- document.getAnonymousElementByAttribute(this, "anonid", "tbstringbundle");
- </field>
- <field name="mCurrentTab">
- null
- </field>
- <field name="_lastRelatedTab">
- null
- </field>
- <field name="mCurrentBrowser">
- null
- </field>
- <field name="mProgressListeners">
- []
- </field>
- <field name="mTabsProgressListeners">
- []
- </field>
- <field name="mTabListeners">
- []
- </field>
- <field name="mTabFilters">
- []
- </field>
- <field name="mIsBusy">
- false
- </field>
- <field name="_outerWindowIDBrowserMap">
- new Map();
- </field>
- <field name="arrowKeysShouldWrap" readonly="true">
-#ifdef XP_MACOSX
- true
-#else
- false
-#endif
- </field>
-
- <field name="_autoScrollPopup">
- null
- </field>
-
- <field name="_previewMode">
- false
- </field>
-
- <property name="_numPinnedTabs" readonly="true">
- <getter><![CDATA[
- for (var i = 0; i < this.tabs.length; i++) {
- if (!this.tabs[i].pinned)
- break;
- }
- return i;
- ]]></getter>
- </property>
-
- <property name="popupAnchor" readonly="true">
- <getter><![CDATA[
- if (this.mCurrentTab._popupAnchor) {
- return this.mCurrentTab._popupAnchor;
- }
- let stack = this.mCurrentBrowser.parentNode;
- // Create an anchor for the popup
- const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- let popupAnchor = document.createElementNS(NS_XUL, "hbox");
- popupAnchor.className = "popup-anchor";
- popupAnchor.hidden = true;
- stack.appendChild(popupAnchor);
- return this.mCurrentTab._popupAnchor = popupAnchor;
- ]]></getter>
- </property>
-
- <method name="updateWindowResizers">
- <body><![CDATA[
- if (!window.gShowPageResizers)
- return;
-
- var show = document.getElementById("addon-bar").collapsed &&
- window.windowState == window.STATE_NORMAL;
- for (let i = 0; i < this.browsers.length; i++) {
- this.browsers[i].showWindowResizer = show;
- }
- ]]></body>
- </method>
-
- <method name="_setCloseKeyState">
- <parameter name="aEnabled"/>
- <body><![CDATA[
- let keyClose = document.getElementById("key_close");
- let closeKeyEnabled = keyClose.getAttribute("disabled") != "true";
- if (closeKeyEnabled == aEnabled)
- return;
-
- if (aEnabled)
- keyClose.removeAttribute("disabled");
- else
- keyClose.setAttribute("disabled", "true");
-
- // We also want to remove the keyboard shortcut from the file menu
- // when the shortcut is disabled, and bring it back when it's
- // renabled.
- //
- // Fixing bug 630826 could make that happen automatically.
- // Fixing bug 630830 could avoid the ugly hack below.
-
- let closeMenuItem = document.getElementById("menu_close");
- let parentPopup = closeMenuItem.parentNode;
- let nextItem = closeMenuItem.nextSibling;
- let clonedItem = closeMenuItem.cloneNode(true);
-
- parentPopup.removeChild(closeMenuItem);
-
- if (aEnabled)
- clonedItem.setAttribute("key", "key_close");
- else
- clonedItem.removeAttribute("key");
-
- parentPopup.insertBefore(clonedItem, nextItem);
- ]]></body>
- </method>
-
- <method name="pinTab">
- <parameter name="aTab"/>
- <body><![CDATA[
- if (aTab.pinned)
- return;
-
- if (aTab.hidden)
- this.showTab(aTab);
-
- this.moveTabTo(aTab, this._numPinnedTabs);
- aTab.setAttribute("pinned", "true");
- this.tabContainer._unlockTabSizing();
- this.tabContainer._positionPinnedTabs();
- this.tabContainer.adjustTabstrip();
-
- this.getBrowserForTab(aTab).docShell.isAppTab = true;
-
- if (aTab.selected)
- this._setCloseKeyState(false);
-
- let event = document.createEvent("Events");
- event.initEvent("TabPinned", true, false);
- aTab.dispatchEvent(event);
- ]]></body>
- </method>
-
- <method name="unpinTab">
- <parameter name="aTab"/>
- <body><![CDATA[
- if (!aTab.pinned)
- return;
-
- this.moveTabTo(aTab, this._numPinnedTabs - 1);
- aTab.setAttribute("fadein", "true");
- aTab.removeAttribute("pinned");
- aTab.style.MozMarginStart = "";
- this.tabContainer._unlockTabSizing();
- this.tabContainer._positionPinnedTabs();
- this.tabContainer.adjustTabstrip();
-
- this.getBrowserForTab(aTab).docShell.isAppTab = false;
-
- if (aTab.selected)
- this._setCloseKeyState(true);
-
- let event = document.createEvent("Events");
- event.initEvent("TabUnpinned", true, false);
- aTab.dispatchEvent(event);
- ]]></body>
- </method>
-
- <method name="previewTab">
- <parameter name="aTab"/>
- <parameter name="aCallback"/>
- <body>
- <![CDATA[
- let currentTab = this.selectedTab;
- try {
- // Suppress focus, ownership and selected tab changes
- this._previewMode = true;
- this.selectedTab = aTab;
- aCallback();
- } finally {
- this.selectedTab = currentTab;
- this._previewMode = false;
- }
- ]]>
- </body>
- </method>
-
- <method name="getBrowserAtIndex">
- <parameter name="aIndex"/>
- <body>
- <![CDATA[
- return this.browsers[aIndex];
- ]]>
- </body>
- </method>
-
- <method name="getBrowserIndexForDocument">
- <parameter name="aDocument"/>
- <body>
- <![CDATA[
- var tab = this._getTabForContentWindow(aDocument.defaultView);
- return tab ? tab._tPos : -1;
- ]]>
- </body>
- </method>
-
- <method name="getBrowserForDocument">
- <parameter name="aDocument"/>
- <body>
- <![CDATA[
- var tab = this._getTabForContentWindow(aDocument.defaultView);
- return tab ? tab.linkedBrowser : null;
- ]]>
- </body>
- </method>
-
- <method name="getBrowserForContentWindow">
- <parameter name="aWindow"/>
- <body>
- <![CDATA[
- var tab = this._getTabForContentWindow(aWindow);
- return tab ? tab.linkedBrowser : null;
- ]]>
- </body>
- </method>
-
- <method name="getBrowserForOuterWindowID">
- <parameter name="aID"/>
- <body>
- <![CDATA[
- return this._outerWindowIDBrowserMap.get(aID);
- ]]>
- </body>
- </method>
-
- <method name="_getTabForContentWindow">
- <parameter name="aWindow"/>
- <body>
- <![CDATA[
- for (let i = 0; i < this.browsers.length; i++) {
- if (this.browsers[i].contentWindow == aWindow)
- return this.tabs[i];
- }
- return null;
- ]]>
- </body>
- </method>
-
- <!-- Binding from browser to tab -->
- <field name="_tabForBrowser" readonly="true">
- <![CDATA[
- new WeakMap();
- ]]>
- </field>
-
- <method name="_getTabForBrowser">
- <parameter name="aBrowser" />
- <body>
- <![CDATA[
- let Deprecated = Components.utils.import("resource://gre/modules/Deprecated.jsm", {}).Deprecated;
- let text = "_getTabForBrowser` is now deprecated, please use `getTabForBrowser";
- let url = "https://developer.mozilla.org/docs/Mozilla/Tech/XUL/Method/getTabForBrowser";
- Deprecated.warning(text, url);
- return this.getTabForBrowser(aBrowser);
- ]]>
- </body>
- </method>
-
- <method name="getTabForBrowser">
- <parameter name="aBrowser"/>
- <body>
- <![CDATA[
- return this._tabForBrowser.get(aBrowser);
- ]]>
- </body>
- </method>
-
- <method name="getNotificationBox">
- <parameter name="aBrowser"/>
- <body>
- <![CDATA[
- return this.getSidebarContainer(aBrowser).parentNode;
- ]]>
- </body>
- </method>
-
- <method name="getSidebarContainer">
- <parameter name="aBrowser"/>
- <body>
- <![CDATA[
- return this.getBrowserContainer(aBrowser).parentNode;
- ]]>
- </body>
- </method>
-
- <method name="getBrowserContainer">
- <parameter name="aBrowser"/>
- <body>
- <![CDATA[
- return (aBrowser || this.mCurrentBrowser).parentNode.parentNode;
- ]]>
- </body>
- </method>
-
- <method name="getTabModalPromptBox">
- <parameter name="aBrowser"/>
- <body>
- <![CDATA[
- const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- let browser = (aBrowser || this.mCurrentBrowser);
- let stack = browser.parentNode;
- let self = this;
-
- let promptBox = {
- appendPrompt : function(args, onCloseCallback) {
- let newPrompt = document.createElementNS(XUL_NS, "tabmodalprompt");
- // stack.appendChild(newPrompt);
- stack.insertBefore(newPrompt, browser.nextSibling);
- browser.setAttribute("tabmodalPromptShowing", true);
-
- newPrompt.clientTop; // style flush to assure binding is attached
-
- let prompts = this.listPrompts();
- if (prompts.length > 1) {
- // Let's hide ourself behind the current prompt.
- newPrompt.hidden = true;
- }
-
- let tab = self._getTabForContentWindow(browser.contentWindow);
- newPrompt.init(args, tab, onCloseCallback);
- return newPrompt;
- },
-
- removePrompt : function(aPrompt) {
- stack.removeChild(aPrompt);
-
- let prompts = this.listPrompts();
- if (prompts.length) {
- let prompt = prompts[prompts.length - 1];
- prompt.hidden = false;
- prompt.Dialog.setDefaultFocus();
- } else {
- browser.removeAttribute("tabmodalPromptShowing");
- browser.focus();
- }
- },
-
- listPrompts : function(aPrompt) {
- let els = stack.getElementsByTagNameNS(XUL_NS, "tabmodalprompt");
- // NodeList --> real JS array
- let prompts = Array.slice(els);
- return prompts;
- },
- };
-
- return promptBox;
- ]]>
- </body>
- </method>
-
- <method name="getTabFromAudioEvent">
- <parameter name="aEvent"/>
- <body>
- <![CDATA[
- if (!Services.prefs.getBoolPref("browser.tabs.showAudioPlayingIcon") ||
- !aEvent.isTrusted) {
- return null;
- }
-
- var browser = aEvent.originalTarget;
- var tab = this.getTabForBrowser(browser);
- return tab;
- ]]>
- </body>
- </method>
-
- <method name="_callProgressListeners">
- <parameter name="aBrowser"/>
- <parameter name="aMethod"/>
- <parameter name="aArguments"/>
- <parameter name="aCallGlobalListeners"/>
- <parameter name="aCallTabsListeners"/>
- <body><![CDATA[
- var rv = true;
-
- if (!aBrowser)
- aBrowser = this.mCurrentBrowser;
-
- if (aCallGlobalListeners != false &&
- aBrowser == this.mCurrentBrowser) {
- this.mProgressListeners.forEach(function (p) {
- if (aMethod in p) {
- try {
- if (!p[aMethod].apply(p, aArguments))
- rv = false;
- } catch (e) {
- // don't inhibit other listeners
- Components.utils.reportError(e);
- }
- }
- });
- }
-
- if (aCallTabsListeners != false) {
- aArguments.unshift(aBrowser);
-
- this.mTabsProgressListeners.forEach(function (p) {
- if (aMethod in p) {
- try {
- if (!p[aMethod].apply(p, aArguments))
- rv = false;
- } catch (e) {
- // don't inhibit other listeners
- Components.utils.reportError(e);
- }
- }
- });
- }
-
- return rv;
- ]]></body>
- </method>
-
- <!-- A web progress listener object definition for a given tab. -->
- <method name="mTabProgressListener">
- <parameter name="aTab"/>
- <parameter name="aBrowser"/>
- <parameter name="aStartsBlank"/>
- <body>
- <![CDATA[
- return ({
- mTabBrowser: this,
- mTab: aTab,
- mBrowser: aBrowser,
- mBlank: aStartsBlank,
-
- // cache flags for correct status UI update after tab switching
- mStateFlags: 0,
- mStatus: 0,
- mMessage: "",
- mTotalProgress: 0,
-
- // count of open requests (should always be 0 or 1)
- mRequestCount: 0,
-
- destroy: function () {
- delete this.mTab;
- delete this.mBrowser;
- delete this.mTabBrowser;
- },
-
- _callProgressListeners: function () {
- Array.unshift(arguments, this.mBrowser);
- return this.mTabBrowser._callProgressListeners.apply(this.mTabBrowser, arguments);
- },
-
- _shouldShowProgress: function (aRequest) {
- if (this.mBlank)
- return false;
-
- if (gMultiProcessBrowser)
- return true;
-
- // Don't show progress indicators in tabs for about: URIs
- // pointing to local resources.
- try {
- let channel = aRequest.QueryInterface(Ci.nsIChannel);
- if (channel.originalURI.schemeIs("about") &&
- (channel.URI.schemeIs("jar") || channel.URI.schemeIs("file")))
- return false;
- } catch (e) {}
-
- return true;
- },
-
- onProgressChange: function (aWebProgress, aRequest,
- aCurSelfProgress, aMaxSelfProgress,
- aCurTotalProgress, aMaxTotalProgress) {
- this.mTotalProgress = aMaxTotalProgress ? aCurTotalProgress / aMaxTotalProgress : 0;
-
- if (!this._shouldShowProgress(aRequest))
- return;
-
- if (this.mTotalProgress)
- this.mTab.setAttribute("progress", "true");
-
- this._callProgressListeners("onProgressChange",
- [aWebProgress, aRequest,
- aCurSelfProgress, aMaxSelfProgress,
- aCurTotalProgress, aMaxTotalProgress]);
- },
-
- onProgressChange64: function (aWebProgress, aRequest,
- aCurSelfProgress, aMaxSelfProgress,
- aCurTotalProgress, aMaxTotalProgress) {
- return this.onProgressChange(aWebProgress, aRequest,
- aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress,
- aMaxTotalProgress);
- },
-
- onStateChange: function (aWebProgress, aRequest, aStateFlags, aStatus) {
- if (!aRequest)
- return;
-
- var oldBlank = this.mBlank;
-
- const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
- const nsIChannel = Components.interfaces.nsIChannel;
- let location, originalLocation;
- try {
- aRequest.QueryInterface(nsIChannel)
- location = aRequest.URI;
- originalLocation = aRequest.originalURI;
- } catch (ex) {}
-
- if (aStateFlags & nsIWebProgressListener.STATE_START) {
- this.mRequestCount++;
- }
- else if (aStateFlags & nsIWebProgressListener.STATE_STOP) {
- const NS_ERROR_UNKNOWN_HOST = 2152398878;
- if (--this.mRequestCount > 0 && aStatus == NS_ERROR_UNKNOWN_HOST) {
- // to prevent bug 235825: wait for the request handled
- // by the automatic keyword resolver
- return;
- }
- // since we (try to) only handle STATE_STOP of the last request,
- // the count of open requests should now be 0
- this.mRequestCount = 0;
- }
-
- if (aStateFlags & nsIWebProgressListener.STATE_START &&
- aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
- if (aWebProgress.isTopLevel)
- this.mBrowser.urlbarChangeTracker.startedLoad();
-
- if (this._shouldShowProgress(aRequest)) {
- if (!(aStateFlags & nsIWebProgressListener.STATE_RESTORING)) {
- this.mTab.setAttribute("busy", "true");
- if (!gMultiProcessBrowser) {
- if (aWebProgress.isTopLevel &&
- !(this.mBrowser.docShell.loadType & Ci.nsIDocShell.LOAD_CMD_RELOAD))
- this.mTabBrowser.setTabTitleLoading(this.mTab);
- }
- }
-
- if (this.mTab.selected)
- this.mTabBrowser.mIsBusy = true;
- }
- }
- else if (aStateFlags & nsIWebProgressListener.STATE_STOP &&
- aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
-
- if (this.mTab.hasAttribute("busy")) {
- this.mTab.removeAttribute("busy");
- this.mTabBrowser._tabAttrModified(this.mTab, ["busy"]);
- if (!this.mTab.selected)
- this.mTab.setAttribute("unread", "true");
- }
- this.mTab.removeAttribute("progress");
-
- if (aWebProgress.isTopLevel) {
- let isSuccessful = Components.isSuccessCode(aStatus);
- if (!isSuccessful && !isTabEmpty(this.mTab)) {
- // Restore the current document's location in case the
- // request was stopped (possibly from a content script)
- // before the location changed.
-
- this.mBrowser.userTypedValue = null;
-
- if (this.mTab.selected && gURLBar)
- URLBarSetURI();
- } else if (isSuccessful) {
- this.mBrowser.urlbarChangeTracker.finishedLoad();
- }
-
- if (!this.mBrowser.mIconURL)
- this.mTabBrowser.useDefaultIcon(this.mTab);
- }
-
- if (this.mBlank)
- this.mBlank = false;
-
- // For keyword URIs clear the user typed value since they will be changed into real URIs
- if (location.scheme == "keyword")
- this.mBrowser.userTypedValue = null;
-
- if (this.mTab.label == this.mTabBrowser.mStringBundle.getString("tabs.connecting"))
- this.mTabBrowser.setTabTitle(this.mTab);
-
- if (this.mTab.selected)
- this.mTabBrowser.mIsBusy = false;
- }
-
- if (oldBlank) {
- this._callProgressListeners("onUpdateCurrentBrowser",
- [aStateFlags, aStatus, "", 0],
- true, false);
- } else {
- this._callProgressListeners("onStateChange",
- [aWebProgress, aRequest, aStateFlags, aStatus],
- true, false);
- }
-
- this._callProgressListeners("onStateChange",
- [aWebProgress, aRequest, aStateFlags, aStatus],
- false);
-
- if (aStateFlags & (nsIWebProgressListener.STATE_START |
- nsIWebProgressListener.STATE_STOP)) {
- // reset cached temporary values at beginning and end
- this.mMessage = "";
- this.mTotalProgress = 0;
- }
- this.mStateFlags = aStateFlags;
- this.mStatus = aStatus;
- },
-
- onLocationChange: function (aWebProgress, aRequest, aLocation,
- aFlags) {
- // OnLocationChange is called for both the top-level content
- // and the subframes.
- let topLevel = aWebProgress.isTopLevel;
-
- if (topLevel) {
- let isSameDocument =
- !!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT);
- // We need to clear the typed value
- // if the document failed to load, to make sure the urlbar reflects the
- // failed URI (particularly for SSL errors). However, don't clear the value
- // if the error page's URI is about:blank, because that causes complete
- // loss of urlbar contents for invalid URI errors (see bug 867957).
- if (this.mBrowser.didStartLoadSinceLastUserTyping() ||
- ((aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) &&
- aLocation.spec != "about:blank"))
- this.mBrowser.userTypedValue = null;
-
- // If the browser was playing audio, we should remove the playing state.
- if (this.mTab.hasAttribute("soundplaying") && !isSameDocument) {
- clearTimeout(this.mTab._soundPlayingAttrRemovalTimer);
- this.mTab._soundPlayingAttrRemovalTimer = 0;
- this.mTab.removeAttribute("soundplaying");
- this.mTabBrowser._tabAttrModified(this.mTab, ["soundplaying"]);
- }
-
- // If the browser was previously muted, we should restore the muted state.
- if (this.mTab.hasAttribute("muted")) {
- this.mTab.linkedBrowser.mute();
- }
-
- // Don't clear the favicon if this onLocationChange was
- // triggered by a pushState or a replaceState. See bug 550565.
- if (!gMultiProcessBrowser) {
- if (aWebProgress.isLoadingDocument &&
- !(this.mBrowser.docShell.loadType & Ci.nsIDocShell.LOAD_CMD_PUSHSTATE))
- this.mBrowser.mIconURL = null;
- }
-
- let autocomplete = this.mTabBrowser._placesAutocomplete;
- if (this.mBrowser.registeredOpenURI) {
- autocomplete.unregisterOpenPage(this.mBrowser.registeredOpenURI);
- delete this.mBrowser.registeredOpenURI;
- }
- // Tabs in private windows aren't registered as "Open" so
- // that they don't appear as switch-to-tab candidates.
- if (!isBlankPageURL(aLocation.spec) &&
- (!PrivateBrowsingUtils.isWindowPrivate(window) ||
- PrivateBrowsingUtils.permanentPrivateBrowsing)) {
- autocomplete.registerOpenPage(aLocation);
- this.mBrowser.registeredOpenURI = aLocation;
- }
- }
-
- if (!this.mBlank) {
- this._callProgressListeners("onLocationChange",
- [aWebProgress, aRequest, aLocation,
- aFlags]);
- }
-
- if (topLevel) {
- this.mBrowser.lastURI = aLocation;
- this.mBrowser.lastLocationChange = Date.now();
- }
- },
-
- onStatusChange: function (aWebProgress, aRequest, aStatus, aMessage) {
- if (this.mBlank)
- return;
-
- this._callProgressListeners("onStatusChange",
- [aWebProgress, aRequest, aStatus, aMessage]);
-
- this.mMessage = aMessage;
- },
-
- onSecurityChange: function (aWebProgress, aRequest, aState) {
- this._callProgressListeners("onSecurityChange",
- [aWebProgress, aRequest, aState]);
- },
-
- onRefreshAttempted: function (aWebProgress, aURI, aDelay, aSameURI) {
- return this._callProgressListeners("onRefreshAttempted",
- [aWebProgress, aURI, aDelay, aSameURI]);
- },
-
- QueryInterface: function (aIID) {
- if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
- aIID.equals(Components.interfaces.nsIWebProgressListener2) ||
- aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
- aIID.equals(Components.interfaces.nsISupports))
- return this;
- throw Components.results.NS_NOINTERFACE;
- }
- });
- ]]>
- </body>
- </method>
-
- <method name="setIcon">
- <parameter name="aTab"/>
- <parameter name="aURI"/>
- <parameter name="aLoadingPrincipal"/>
- <body>
- <![CDATA[
- let browser = this.getBrowserForTab(aTab);
- browser.mIconURL = aURI instanceof Ci.nsIURI ? aURI.spec : aURI;
-
- if (aURI && this.mFaviconService) {
- if (!(aURI instanceof Ci.nsIURI)) {
- aURI = makeURI(aURI);
- }
- // We do not serialize the principal from within SessionStore.jsm,
- // hence if aLoadingPrincipal is null we default to the
- // systemPrincipal which will allow the favicon to load.
- let loadingPrincipal = aLoadingPrincipal
- ? aLoadingPrincipal
- : Services.scriptSecurityManager.getSystemPrincipal();
- let loadType = PrivateBrowsingUtils.isWindowPrivate(window)
- ? this.mFaviconService.FAVICON_LOAD_PRIVATE
- : this.mFaviconService.FAVICON_LOAD_NON_PRIVATE;
-
- this.mFaviconService.setAndFetchFaviconForPage(
- browser.currentURI, aURI, false, loadType, null, loadingPrincipal);
- }
-
- let sizedIconUrl = browser.mIconURL || "";
- if (sizedIconUrl != aTab.getAttribute("image")) {
- if (sizedIconUrl)
- aTab.setAttribute("image", sizedIconUrl);
- else
- aTab.removeAttribute("image");
- this._tabAttrModified(aTab, ["image"]);
- }
-
- if (Services.prefs.getBoolPref("browser.chrome.favicons.process")) {
- let favImage = new Image;
- favImage.src = browser.mIconURL;
- var tabBrowser = this;
- favImage.onload = function () {
- try {
- // Draw the icon on a hidden canvas
- var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
- var tabImg = document.getAnonymousElementByAttribute(aTab, "anonid", "tab-icon");
- var w = tabImg.boxObject.width;
- var h = tabImg.boxObject.height;
- canvas.width = w;
- canvas.height = h;
- var ctx = canvas.getContext('2d');
- ctx.drawImage(favImage, 0, 0, w, h);
- icon = canvas.toDataURL();
- browser.mIconURL = icon;
- aTab.setAttribute("image", icon);
- }
- catch (e) {
- console.warn("Processing of favicon failed.");
- // Canvas failed: icon remains as it was
- }
- tabBrowser._callProgressListeners(browser, "onLinkIconAvailable", [browser.mIconURL]);
- }
- }
-
- this._callProgressListeners(browser, "onLinkIconAvailable", [browser.mIconURL]);
- ]]>
- </body>
- </method>
-
- <method name="getIcon">
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- let browser = aTab ? this.getBrowserForTab(aTab) : this.selectedBrowser;
- return browser.mIconURL;
- ]]>
- </body>
- </method>
-
- <method name="shouldLoadFavIcon">
- <parameter name="aURI"/>
- <body>
- <![CDATA[
- return (aURI &&
- Services.prefs.getBoolPref("browser.chrome.site_icons") &&
- Services.prefs.getBoolPref("browser.chrome.favicons") &&
- ("schemeIs" in aURI) && (aURI.schemeIs("http") || aURI.schemeIs("https")));
- ]]>
- </body>
- </method>
-
- <method name="useDefaultIcon">
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- // Bug 691610 - e10s support for useDefaultIcon
- if (gMultiProcessBrowser)
- return;
-
- var browser = this.getBrowserForTab(aTab);
- var docURIObject = browser.contentDocument.documentURIObject;
- var icon = null;
- <!-- Pale Moon: new image icon method, see bug #305986 -->
- let req = browser.contentDocument.imageRequest;
- let sz = Services.prefs.getIntPref("browser.chrome.image_icons.max_size");
- if (browser.contentDocument instanceof ImageDocument &&
- req && req.image) {
- if (Services.prefs.getBoolPref("browser.chrome.site_icons") && sz) {
- try {
- <!-- Main method: draw on a hidden canvas -->
- var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
- var tabImg = document.getAnonymousElementByAttribute(aTab, "anonid", "tab-icon");
- var w = tabImg.boxObject.width;
- var h = tabImg.boxObject.height;
- canvas.width = w;
- canvas.height = h;
- var ctx = canvas.getContext('2d');
- ctx.drawImage(browser.contentDocument.body.firstChild, 0, 0, w, h);
- icon = canvas.toDataURL();
- }
- catch (e) {
- <!-- Fallback method in case canvas method fails, restricted by sz -->
- try {
-
- if (req &&
- req.image &&
- req.image.width <= sz &&
- req.image.height <= sz)
- icon = browser.currentURI;
- }
- catch (e) {
- <!-- Both methods fail (very large or corrupt image): icon remains null -->
- }
- }
- }
- }
- // Use documentURIObject in the check for shouldLoadFavIcon so that we
- // do the right thing with about:-style error pages. Bug 453442
- else if (this.shouldLoadFavIcon(docURIObject)) {
- let url = docURIObject.prePath + "/favicon.ico";
- if (!this.isFailedIcon(url))
- icon = url;
- }
- this.setIcon(aTab, icon, browser.contentPrincipal);
- ]]>
- </body>
- </method>
-
- <method name="isFailedIcon">
- <parameter name="aURI"/>
- <body>
- <![CDATA[
- if (this.mFaviconService) {
- if (!(aURI instanceof Ci.nsIURI))
- aURI = makeURI(aURI);
- return this.mFaviconService.isFailedFavicon(aURI);
- }
- return null;
- ]]>
- </body>
- </method>
-
- <method name="getWindowTitleForBrowser">
- <parameter name="aBrowser"/>
- <body>
- <![CDATA[
- var newTitle = "";
- var docElement = this.ownerDocument.documentElement;
- var sep = docElement.getAttribute("titlemenuseparator");
-
- // Strip out any null bytes in the content title, since the
- // underlying widget implementations of nsWindow::SetTitle pass
- // null-terminated strings to system APIs.
- var docTitle = aBrowser.contentTitle.replace("\0", "", "g");
-
- if (!docTitle)
- docTitle = docElement.getAttribute("titledefault");
-
- var modifier = docElement.getAttribute("titlemodifier");
- if (docTitle) {
- newTitle += docElement.getAttribute("titlepreface");
- newTitle += docTitle;
- if (modifier)
- newTitle += sep;
- }
- newTitle += modifier;
-
- // If location bar is hidden and the URL type supports a host,
- // add the scheme and host to the title to prevent spoofing.
- // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=22183#c239
- try {
- if (docElement.getAttribute("chromehidden").includes("location")) {
- var uri = this.mURIFixup.createExposableURI(
- aBrowser.currentURI);
- if (uri.scheme == "about")
- newTitle = uri.spec + sep + newTitle;
- else
- newTitle = uri.prePath + sep + newTitle;
- }
- } catch (e) {}
-
- return newTitle;
- ]]>
- </body>
- </method>
-
- <method name="freezeTitlebar">
- <parameter name="aTitle"/>
- <body>
- <![CDATA[
- this._frozenTitle = aTitle || "";
- this.updateTitlebar();
- ]]>
- </body>
- </method>
-
- <method name="unfreezeTitlebar">
- <body>
- <![CDATA[
- this._frozenTitle = "";
- this.updateTitlebar();
- ]]>
- </body>
- </method>
-
- <method name="updateTitlebar">
- <body>
- <![CDATA[
- this.ownerDocument.title = this._frozenTitle ||
- this.getWindowTitleForBrowser(this.mCurrentBrowser);
- ]]>
- </body>
- </method>
-
- <method name="updateCurrentBrowser">
- <parameter name="aForceUpdate"/>
- <body>
- <![CDATA[
- var newBrowser = this.getBrowserAtIndex(this.tabContainer.selectedIndex);
- if (this.mCurrentBrowser == newBrowser && !aForceUpdate)
- return;
-
- if (!aForceUpdate) {
- window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils)
- .beginTabSwitch();
- }
-
- var oldTab = this.mCurrentTab;
-
- // Preview mode should not reset the owner
- if (!this._previewMode && !oldTab.selected)
- oldTab.owner = null;
-
- if (this._lastRelatedTab) {
- if (!this._lastRelatedTab.selected)
- this._lastRelatedTab.owner = null;
- this._lastRelatedTab = null;
- }
-
- var oldBrowser = this.mCurrentBrowser;
- if (oldBrowser) {
- oldBrowser.setAttribute("type", "content-targetable");
- oldBrowser.docShellIsActive = false;
- this.finder.mListeners.forEach(l => oldBrowser.finder.removeResultListener(l));
- }
-
- var updateBlockedPopups = false;
- if (!oldBrowser ||
- (oldBrowser.blockedPopups && !newBrowser.blockedPopups) ||
- (!oldBrowser.blockedPopups && newBrowser.blockedPopups))
- updateBlockedPopups = true;
-
- newBrowser.setAttribute("type", "content-primary");
- newBrowser.docShellIsActive =
- (window.windowState != window.STATE_MINIMIZED);
- this.mCurrentBrowser = newBrowser;
- this.mCurrentTab = this.tabContainer.selectedItem;
- this.finder.mListeners.forEach(l => this.mCurrentBrowser.finder.addResultListener(l));
- this.showTab(this.mCurrentTab);
-
- var backForwardContainer = document.getElementById("unified-back-forward-button");
- if (backForwardContainer) {
- backForwardContainer.setAttribute("switchingtabs", "true");
- window.addEventListener("MozAfterPaint", function removeSwitchingtabsAttr() {
- window.removeEventListener("MozAfterPaint", removeSwitchingtabsAttr);
- backForwardContainer.removeAttribute("switchingtabs");
- });
- }
-
- if (updateBlockedPopups)
- this.mCurrentBrowser.updateBlockedPopups();
-
- // Update the URL bar.
- var loc = this.mCurrentBrowser.currentURI;
-
- // Bug 666809 - SecurityUI support for e10s
- var webProgress = this.mCurrentBrowser.webProgress;
- var securityUI = this.mCurrentBrowser.securityUI;
-
- // Update global findbar with new content browser
- if (gFindBarInitialized) {
- gFindBar.browser = newBrowser;
- }
-
- this._callProgressListeners(null, "onLocationChange",
- [webProgress, null, loc, 0], true,
- false);
-
- if (securityUI) {
- this._callProgressListeners(null, "onSecurityChange",
- [webProgress, null, securityUI.state], true, false);
- }
-
- var listener = this.mTabListeners[this.tabContainer.selectedIndex] || null;
- if (listener && listener.mStateFlags) {
- this._callProgressListeners(null, "onUpdateCurrentBrowser",
- [listener.mStateFlags, listener.mStatus,
- listener.mMessage, listener.mTotalProgress],
- true, false);
- }
-
- if (!this._previewMode) {
- this.mCurrentTab.removeAttribute("unread");
- this.selectedTab.lastAccessed = Date.now();
-
- // Bug 666816 - TypeAheadFind support for e10s
- if (!gMultiProcessBrowser)
- this._fastFind.setDocShell(this.mCurrentBrowser.docShell);
-
- this.updateTitlebar();
-
- this.mCurrentTab.removeAttribute("titlechanged");
- }
-
- // If the new tab is busy, and our current state is not busy, then
- // we need to fire a start to all progress listeners.
- const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
- if (this.mCurrentTab.hasAttribute("busy") && !this.mIsBusy) {
- this.mIsBusy = true;
- this._callProgressListeners(null, "onStateChange",
- [webProgress, null,
- nsIWebProgressListener.STATE_START |
- nsIWebProgressListener.STATE_IS_NETWORK, 0],
- true, false);
- }
-
- // If the new tab is not busy, and our current state is busy, then
- // we need to fire a stop to all progress listeners.
- if (!this.mCurrentTab.hasAttribute("busy") && this.mIsBusy) {
- this.mIsBusy = false;
- this._callProgressListeners(null, "onStateChange",
- [webProgress, null,
- nsIWebProgressListener.STATE_STOP |
- nsIWebProgressListener.STATE_IS_NETWORK, 0],
- true, false);
- }
-
- this._setCloseKeyState(!this.mCurrentTab.pinned);
-
- // TabSelect events are suppressed during preview mode to avoid confusing extensions and other bits of code
- // that might rely upon the other changes suppressed.
- // Focus is suppressed in the event that the main browser window is minimized - focusing a tab would restore the window
- if (!this._previewMode) {
- // We've selected the new tab, so go ahead and notify listeners.
- let event = new CustomEvent("TabSelect", {
- bubbles: true,
- cancelable: false,
- detail: {
- previousTab: oldTab
- }
- });
- this.mCurrentTab.dispatchEvent(event);
-
- this._tabAttrModified(oldTab, ["selected"]);
- this._tabAttrModified(this.mCurrentTab, ["selected"]);
-
- // Adjust focus
- oldBrowser._urlbarFocused = (gURLBar && gURLBar.focused);
- do {
- // When focus is in the tab bar, retain it there.
- if (document.activeElement == oldTab) {
- // We need to explicitly focus the new tab, because
- // tabbox.xml does this only in some cases.
- this.mCurrentTab.focus();
- break;
- }
-
- // If there's a tabmodal prompt showing, focus it.
- if (newBrowser.hasAttribute("tabmodalPromptShowing")) {
- let XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- let prompts = newBrowser.parentNode.getElementsByTagNameNS(XUL_NS, "tabmodalprompt");
- let prompt = prompts[prompts.length - 1];
- prompt.Dialog.setDefaultFocus();
- break;
- }
-
- // Focus the location bar if it was previously focused for that tab.
- // In full screen mode, only bother making the location bar visible
- // if the tab is a blank one.
- if (newBrowser._urlbarFocused && gURLBar) {
-
- // Explicitly close the popup if the URL bar retains focus
- gURLBar.closePopup();
-
- if (!window.fullScreen) {
- gURLBar.focus();
- break;
- } else if (isTabEmpty(this.mCurrentTab)) {
- focusAndSelectUrlBar();
- break;
- }
- }
-
- // If the find bar is focused, keep it focused.
- if (gFindBarInitialized &&
- !gFindBar.hidden &&
- gFindBar.getElement("findbar-textbox").getAttribute("focused") == "true")
- break;
-
- // Otherwise, focus the content area.
- let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
- let focusFlags = fm.FLAG_NOSCROLL;
-
- if (!gMultiProcessBrowser) {
- let newFocusedElement = fm.getFocusedElementForWindow(window.content, true, {});
-
- // for anchors, use FLAG_SHOWRING so that it is clear what link was
- // last clicked when switching back to that tab
- if (newFocusedElement &&
- (newFocusedElement instanceof HTMLAnchorElement ||
- newFocusedElement.getAttributeNS("http://www.w3.org/1999/xlink", "type") == "simple"))
- focusFlags |= fm.FLAG_SHOWRING;
- }
- fm.setFocus(newBrowser, focusFlags);
- } while (false);
- }
-
- this.tabContainer._setPositionalAttributes();
- ]]>
- </body>
- </method>
-
- <method name="_tabAttrModified">
- <parameter name="aTab"/>
- <parameter name="aChanged"/>
- <body><![CDATA[
- if (aTab.closing)
- return;
-
- let event = new CustomEvent("TabAttrModified", {
- bubbles: true,
- cancelable: false,
- detail: {
- changed: aChanged,
- }
- });
- aTab.dispatchEvent(event);
- ]]></body>
- </method>
-
- <method name="setTabTitleLoading">
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- aTab.label = this.mStringBundle.getString("tabs.connecting");
- aTab.crop = "end";
- this._tabAttrModified(aTab, ["label", "crop"]);
- ]]>
- </body>
- </method>
-
- <method name="setTabTitle">
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- var browser = this.getBrowserForTab(aTab);
- var crop = "end";
- var title = browser.contentTitle;
-
- if (!title) {
- if (browser.currentURI.spec) {
- try {
- title = this.mURIFixup.createExposableURI(browser.currentURI).spec;
- } catch(ex) {
- title = browser.currentURI.spec;
- }
- }
-
- if (title && !isBlankPageURL(title)) {
- // At this point, we now have a URI.
- // Let's try to unescape it using a character set
- // in case the URI is not ASCII.
- try {
- var characterSet = browser.characterSet;
- const textToSubURI = Components.classes["@mozilla.org/intl/texttosuburi;1"]
- .getService(Components.interfaces.nsITextToSubURI);
- title = textToSubURI.unEscapeNonAsciiURI(characterSet, title);
- } catch(ex) { /* Do nothing. */ }
-
- crop = "center";
-
- } else // Still no title? Fall back to our untitled string.
- title = this.mStringBundle.getString("tabs.emptyTabTitle");
- }
-
- if (aTab.label == title &&
- aTab.crop == crop)
- return false;
-
- aTab.label = title;
- aTab.crop = crop;
- this._tabAttrModified(aTab, ["label", "crop"]);
-
- if (aTab.selected)
- this.updateTitlebar();
-
- return true;
- ]]>
- </body>
- </method>
-
- <method name="loadOneTab">
- <parameter name="aURI"/>
- <parameter name="aReferrerURI"/>
- <parameter name="aCharset"/>
- <parameter name="aPostData"/>
- <parameter name="aLoadInBackground"/>
- <parameter name="aAllowThirdPartyFixup"/>
- <body>
- <![CDATA[
- var aTriggeringPrincipal;
- var aReferrerPolicy;
- var aFromExternal;
- var aRelatedToCurrent;
- var aOriginPrincipal;
- var aOpener;
- if (arguments.length == 2 &&
- typeof arguments[1] == "object" &&
- !(arguments[1] instanceof Ci.nsIURI)) {
- let params = arguments[1];
- aTriggeringPrincipal = params.triggeringPrincipal;
- aReferrerURI = params.referrerURI;
- aReferrerPolicy = params.referrerPolicy;
- aCharset = params.charset;
- aPostData = params.postData;
- aLoadInBackground = params.inBackground;
- aAllowThirdPartyFixup = params.allowThirdPartyFixup;
- aFromExternal = params.fromExternal;
- aRelatedToCurrent = params.relatedToCurrent;
- aOriginPrincipal = params.originPrincipal;
- aOpener = params.opener;
- }
-
- var bgLoad = (aLoadInBackground != null) ? aLoadInBackground :
- Services.prefs.getBoolPref("browser.tabs.loadInBackground");
- var owner = bgLoad ? null : this.selectedTab;
- var tab = this.addTab(aURI, {
- triggeringPrincipal: aTriggeringPrincipal,
- referrerURI: aReferrerURI,
- referrerPolicy: aReferrerPolicy,
- charset: aCharset,
- postData: aPostData,
- ownerTab: owner,
- allowThirdPartyFixup: aAllowThirdPartyFixup,
- fromExternal: aFromExternal,
- originPrincipal: aOriginPrincipal,
- relatedToCurrent: aRelatedToCurrent,
- opener: aOpener });
- if (!bgLoad)
- this.selectedTab = tab;
-
- return tab;
- ]]>
- </body>
- </method>
-
- <method name="loadTabs">
- <parameter name="aURIs"/>
- <parameter name="aLoadInBackground"/>
- <parameter name="aReplace"/>
- <body><![CDATA[
- let aAllowThirdPartyFixup;
- let aTargetTab;
- let aNewIndex = -1;
- let aPostDatas = [];
- if (arguments.length == 2 &&
- typeof arguments[1] == "object") {
- let params = arguments[1];
- aLoadInBackground = params.inBackground;
- aReplace = params.replace;
- aAllowThirdPartyFixup = params.allowThirdPartyFixup;
- aTargetTab = params.targetTab;
- aNewIndex = typeof params.newIndex === "number" ?
- params.newIndex : aNewIndex;
- aPostDatas = params.postDatas || aPostDatas;
- }
-
- if (!aURIs.length)
- return;
-
- // The tab selected after this new tab is closed (i.e. the new tab's
- // "owner") is the next adjacent tab (i.e. not the previously viewed tab)
- // when several urls are opened here (i.e. closing the first should select
- // the next of many URLs opened) or if the pref to have UI links opened in
- // the background is set (i.e. the link is not being opened modally)
- //
- // i.e.
- // Number of URLs Load UI Links in BG Focus Last Viewed?
- // == 1 false YES
- // == 1 true NO
- // > 1 false/true NO
- var multiple = aURIs.length > 1;
- var owner = multiple || aLoadInBackground ? null : this.selectedTab;
- var firstTabAdded = null;
- var targetTabIndex = -1;
-
- if (aReplace) {
- let browser;
- if (aTargetTab) {
- browser = this.getBrowserForTab(aTargetTab);
- targetTabIndex = aTargetTab._tPos;
- } else {
- browser = this.mCurrentBrowser;
- targetTabIndex = this.tabContainer.selectedIndex;
- }
- let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
- if (aAllowThirdPartyFixup) {
- flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
- Ci.nsIWebNavigation.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
- }
- try {
- browser.loadURIWithFlags(aURIs[0], {
- flags, postData: aPostDatas[0]
- });
- } catch (e) {
- // Ignore failure in case a URI is wrong, so we can continue
- // opening the next ones.
- }
- } else {
- firstTabAdded = this.addTab(aURIs[0], {
- ownerTab: owner,
- skipAnimation: multiple,
- allowThirdPartyFixup: aAllowThirdPartyFixup,
- postData: aPostDatas[0]
- });
- if (aNewIndex !== -1) {
- this.moveTabTo(firstTabAdded, aNewIndex);
- targetTabIndex = firstTabAdded._tPos;
- }
- }
-
- let tabNum = targetTabIndex;
- for (let i = 1; i < aURIs.length; ++i) {
- let tab = this.addTab(aURIs[i], {
- skipAnimation: true,
- allowThirdPartyFixup: aAllowThirdPartyFixup,
- postData: aPostDatas[i]
- });
- if (targetTabIndex !== -1)
- this.moveTabTo(tab, ++tabNum);
- }
-
- if (!aLoadInBackground) {
- if (firstTabAdded) {
- // .selectedTab setter focuses the content area
- this.selectedTab = firstTabAdded;
- }
- else
- this.selectedBrowser.focus();
- }
- ]]></body>
- </method>
-
- <method name="addTab">
- <parameter name="aURI"/>
- <parameter name="aReferrerURI"/>
- <parameter name="aCharset"/>
- <parameter name="aPostData"/>
- <parameter name="aOwner"/>
- <parameter name="aAllowThirdPartyFixup"/>
- <body>
- <![CDATA[
- const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- var aTriggeringPrincipal;
- var aReferrerPolicy;
- var aFromExternal;
- var aRelatedToCurrent;
- var aSkipAnimation;
- var aOriginPrincipal;
- var aSkipBackgroundNotify;
- var aOpener;
- if (arguments.length == 2 &&
- typeof arguments[1] == "object" &&
- !(arguments[1] instanceof Ci.nsIURI)) {
- let params = arguments[1];
- aTriggeringPrincipal = params.triggeringPrincipal;
- aReferrerURI = params.referrerURI;
- aReferrerPolicy = params.referrerPolicy;
- aCharset = params.charset;
- aPostData = params.postData;
- aOwner = params.ownerTab;
- aAllowThirdPartyFixup = params.allowThirdPartyFixup;
- aFromExternal = params.fromExternal;
- aRelatedToCurrent = params.relatedToCurrent;
- aSkipAnimation = params.skipAnimation;
- aOriginPrincipal = params.originPrincipal;
- aOpener = params.opener;
- aSkipBackgroundNotify = params.skipBackgroundNotify;
- }
-
- // if we're adding tabs, we're past interrupt mode, ditch the owner
- if (this.mCurrentTab.owner)
- this.mCurrentTab.owner = null;
-
- var t = document.createElementNS(NS_XUL, "tab");
-
- let aURIObject = null;
- try {
- aURIObject = Services.io.newURI(aURI || "about:blank");
- } catch (ex) { /* we'll try to fix up this URL later */ }
-
- var uriIsAboutBlank = !aURI || aURI == "about:blank";
-
- if (!aURI || isBlankPageURL(aURI))
- t.setAttribute("label", this.mStringBundle.getString("tabs.emptyTabTitle"));
- else
- t.setAttribute("label", aURI);
-
- t.setAttribute("crop", "end");
- t.setAttribute("validate", "never"); //PMed
- t.setAttribute("onerror", "this.removeAttribute('image');");
-
- if (aSkipBackgroundNotify) {
- t.setAttribute("skipbackgroundnotify", true);
- }
-
- t.className = "tabbrowser-tab";
-
- this.tabContainer._unlockTabSizing();
-
- // When overflowing, new tabs are scrolled into view smoothly, which
- // doesn't go well together with the width transition. So we skip the
- // transition in that case.
- let animate = !aSkipAnimation &&
- this.tabContainer.getAttribute("overflow") != "true" &&
- Services.prefs.getBoolPref("browser.tabs.animate");
- if (!animate) {
- t.setAttribute("fadein", "true");
- setTimeout(function (tabContainer) {
- tabContainer._handleNewTab(t);
- }, 0, this.tabContainer);
- }
-
- // invalidate caches
- this._browsers = null;
- this._visibleTabs = null;
-
- this.tabContainer.appendChild(t);
-
- // If this new tab is owned by another, assert that relationship
- if (aOwner)
- t.owner = aOwner;
-
- var b = document.createElementNS(
- "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
- "browser");
- b.setAttribute("type", "content-targetable");
- b.setAttribute("message", "true");
- b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu"));
- b.setAttribute("tooltip", this.getAttribute("contenttooltip"));
-
- if (Services.prefs.getPrefType("browser.tabs.remote") == Services.prefs.PREF_BOOL &&
- Services.prefs.getBoolPref("browser.tabs.remote")) {
- b.setAttribute("remote", "true");
- }
-
- if (window.gShowPageResizers && document.getElementById("addon-bar").collapsed &&
- window.windowState == window.STATE_NORMAL) {
- b.setAttribute("showresizer", "true");
- }
-
- if (aOpener) {
- b.QueryInterface(Ci.nsIFrameLoaderOwner).presetOpenerWindow(aOpener);
- }
-
- if (this.hasAttribute("autocompletepopup"))
- b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
- b.setAttribute("autoscrollpopup", this._autoScrollPopup.id);
-
- if (this.hasAttribute("datetimepicker")) {
- b.setAttribute("datetimepicker", this.getAttribute("datetimepicker"));
- }
-
- if (this.hasAttribute("authdosprotected")) {
- b.setAttribute("authdosprotected", this.getAttribute("authdosprotected"));
- }
-
- // Create the browserStack container
- var stack = document.createElementNS(NS_XUL, "stack");
- stack.className = "browserStack";
- stack.appendChild(b);
- stack.setAttribute("flex", "1");
-
- // Create the browserContainer
- var browserContainer = document.createElementNS(NS_XUL, "vbox");
- browserContainer.className = "browserContainer";
- browserContainer.appendChild(stack);
- browserContainer.setAttribute("flex", "1");
-
- // Create the sidebar container
- var browserSidebarContainer = document.createElementNS(NS_XUL,
- "hbox");
- browserSidebarContainer.className = "browserSidebarContainer";
- browserSidebarContainer.appendChild(browserContainer);
- browserSidebarContainer.setAttribute("flex", "1");
-
- // Add the Message and the Browser to the box
- var notificationbox = document.createElementNS(NS_XUL,
- "notificationbox");
- notificationbox.setAttribute("flex", "1");
- notificationbox.appendChild(browserSidebarContainer);
-
- var position = this.tabs.length - 1;
- var uniqueId = "panel" + Date.now() + position;
- notificationbox.id = uniqueId;
- t.linkedPanel = uniqueId;
- t.linkedBrowser = b;
- this._tabForBrowser.set(b, t);
- t._tPos = position;
- this.tabContainer._setPositionalAttributes();
-
- // Prevent the superfluous initial load of a blank document
- // if we're going to load something other than about:blank.
- if (!uriIsAboutBlank) {
- b.setAttribute("nodefaultsrc", "true");
- }
-
- // NB: this appendChild call causes us to run constructors for the
- // browser element, which fires off a bunch of notifications. Some
- // of those notifications can cause code to run that inspects our
- // state, so it is important that the tab element is fully
- // initialized by this point.
- this.mPanelContainer.appendChild(notificationbox);
-
- this.tabContainer.updateVisibility();
-
- // wire up a progress listener for the new browser object.
- var tabListener = this.mTabProgressListener(t, b, uriIsAboutBlank);
- const filter = Components.classes["@mozilla.org/appshell/component/browser-status-filter;1"]
- .createInstance(Components.interfaces.nsIWebProgress);
- filter.addProgressListener(tabListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
- b.webProgress.addProgressListener(filter, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
- this.mTabListeners[position] = tabListener;
- this.mTabFilters[position] = filter;
-
- b._fastFind = this.fastFind;
- b.droppedLinkHandler = handleDroppedLink;
-
- // If we just created a new tab that loads the default
- // newtab url, swap in a preloaded page if possible.
- // Do nothing if we're a private window.
- let docShellsSwapped = false;
- if (aURI == BROWSER_NEW_TAB_URL &&
- !PrivateBrowsingUtils.isWindowPrivate(window)) {
- docShellsSwapped = gBrowserNewTabPreloader.newTab(t);
- }
-
- // Dispatch a new tab notification. We do this once we're
- // entirely done, so that things are in a consistent state
- // even if the event listener opens or closes tabs.
- var evt = document.createEvent("Events");
- evt.initEvent("TabOpen", true, false);
- t.dispatchEvent(evt);
-
- if (aOriginPrincipal && aURI) {
- let {URI_INHERITS_SECURITY_CONTEXT} = Ci.nsIProtocolHandler;
- // Unless we know for sure we're not inheriting principals,
- // force the about:blank viewer to have the right principal:
- if (!aURIObject ||
- (Services.io.getProtocolFlags(aURIObject.scheme) & URI_INHERITS_SECURITY_CONTEXT)) {
- b.createAboutBlankContentViewer(aOriginPrincipal);
- }
- }
-
- // If we didn't swap docShells with a preloaded browser
- // then let's just continue loading the page normally.
- if (!docShellsSwapped && !uriIsAboutBlank) {
- // pretend the user typed this so it'll be available till
- // the document successfully loads
- if (aURI && gInitialPages.indexOf(aURI) == -1)
- b.userTypedValue = aURI;
-
- let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
- if (aAllowThirdPartyFixup) {
- flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
- flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
- }
- if (aFromExternal)
- flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL;
- try {
- b.loadURIWithFlags(aURI, {
- flags: flags,
- triggeringPrincipal: aTriggeringPrincipal,
- referrerURI: aReferrerURI,
- referrerPolicy: aReferrerPolicy,
- charset: aCharset,
- postData: aPostData,
- });
- } catch (ex) {
- Cu.reportError(ex);
- }
- }
-
- // We start our browsers out as inactive, and then maintain
- // activeness in the tab switcher.
- b.docShellIsActive = false;
-
- // When addTab() is called with an URL that is not "about:blank" we
- // set the "nodefaultsrc" attribute that prevents a frameLoader
- // from being created as soon as the linked <browser> is inserted
- // into the DOM. We thus have to register the new outerWindowID
- // for non-remote browsers after we have called browser.loadURI().
- //
- // Note: Only do this of we still have a docShell. The TabOpen
- // event was dispatched above and a gBrowser.removeTab() call from
- // one of its listeners could cause us to fail here.
- if (Services.prefs.getPrefType("browser.tabs.remote") == Services.prefs.PREF_BOOL &&
- !Services.prefs.getBoolPref("browser.tabs.remote")
- && b.docShell) {
- this._outerWindowIDBrowserMap.set(b.outerWindowID, b);
- }
-
- // Check if we're opening a tab related to the current tab and
- // move it to after the current tab.
- // aReferrerURI is null or undefined if the tab is opened from
- // an external application or bookmark, i.e. somewhere other
- // than the current tab.
- if ((aRelatedToCurrent == null ? aReferrerURI : aRelatedToCurrent) &&
- Services.prefs.getBoolPref("browser.tabs.insertRelatedAfterCurrent")) {
- let newTabPos = (this._lastRelatedTab ||
- this.selectedTab)._tPos + 1;
- if (this._lastRelatedTab)
- this._lastRelatedTab.owner = null;
- else
- t.owner = this.selectedTab;
- this.moveTabTo(t, newTabPos);
- this._lastRelatedTab = t;
- }
-
- if (animate) {
- requestAnimationFrame(function () {
- this.tabContainer._handleTabTelemetryStart(t, aURI);
-
- // kick the animation off
- t.setAttribute("fadein", "true");
-
- // This call to adjustTabstrip is redundant but needed so that
- // when opening a second tab, the first tab's close buttons
- // appears immediately rather than when the transition ends.
- if (this.tabs.length - this._removingTabs.length == 2)
- this.tabContainer.adjustTabstrip();
- }.bind(this));
- }
-
- return t;
- ]]>
- </body>
- </method>
-
- <method name="warnAboutClosingTabs">
- <parameter name="aCloseTabs"/>
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- var tabsToClose;
- switch (aCloseTabs) {
- case this.closingTabsEnum.ALL:
- // If there are multiple windows, pinned tabs will be closed, so
- // we warn about them, too; if there is just one window, pinned
- // tabs should come back on restart, so exclude them from warning.
- var numberOfWindows = 0;
- var browserEnum = Services.wm.getEnumerator("navigator:browser");
- while (browserEnum.hasMoreElements() && numberOfWindows < 2) {
- numberOfWindows++;
- browserEnum.getNext();
- }
- if (numberOfWindows > 1) {
- tabsToClose = this.tabs.length - this._removingTabs.length
- }
- else {
- tabsToClose = this.tabs.length - this._removingTabs.length -
- gBrowser._numPinnedTabs;
- }
- break;
- case this.closingTabsEnum.OTHER:
- tabsToClose = this.visibleTabs.length - 1 - gBrowser._numPinnedTabs;
- break;
- case this.closingTabsEnum.TO_END:
- if (!aTab)
- throw new Error("Required argument missing: aTab");
-
- tabsToClose = this.getTabsToTheEndFrom(aTab).length;
- break;
- default:
- throw new Error("Invalid argument: " + aCloseTabs);
- }
-
- if (tabsToClose <= 1)
- return true;
-
- const pref = aCloseTabs == this.closingTabsEnum.ALL ?
- "browser.tabs.warnOnClose" : "browser.tabs.warnOnCloseOtherTabs";
- var shouldPrompt = Services.prefs.getBoolPref(pref);
- if (!shouldPrompt)
- return true;
-
- var ps = Services.prompt;
-
- // default to true: if it were false, we wouldn't get this far
- var warnOnClose = { value: true };
- var bundle = this.mStringBundle;
-
- // focus the window before prompting.
- // this will raise any minimized window, which will
- // make it obvious which window the prompt is for and will
- // solve the problem of windows "obscuring" the prompt.
- // see bug #350299 for more details
- window.focus();
- var buttonPressed =
- ps.confirmEx(window,
- bundle.getString("tabs.closeWarningTitle"),
- bundle.getFormattedString("tabs.closeWarningMultipleTabs",
- [tabsToClose]),
- (ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_0)
- + (ps.BUTTON_TITLE_CANCEL * ps.BUTTON_POS_1),
- bundle.getString("tabs.closeButtonMultiple"),
- null, null,
- aCloseTabs == this.closingTabsEnum.ALL ?
- bundle.getString("tabs.closeWarningPromptMe") : null,
- warnOnClose);
- var reallyClose = (buttonPressed == 0);
-
- // don't set the prefs unless they press OK and have unchecked the box
- if (aCloseTabs == this.closingTabsEnum.ALL && reallyClose && !warnOnClose.value) {
- Services.prefs.setBoolPref("browser.tabs.warnOnClose", false);
- Services.prefs.setBoolPref("browser.tabs.warnOnCloseOtherTabs", false);
- }
- return reallyClose;
- ]]>
- </body>
- </method>
-
- <method name="getTabsToTheEndFrom">
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- var tabsToEnd = [];
- let tabs = this.visibleTabs;
- for (let i = tabs.length - 1; tabs[i] != aTab && i >= 0; --i) {
- tabsToEnd.push(tabs[i]);
- }
- return tabsToEnd.reverse();
- ]]>
- </body>
- </method>
-
- <method name="removeTabsToTheEndFrom">
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- if (this.warnAboutClosingTabs(this.closingTabsEnum.TO_END, aTab)) {
- let tabs = this.getTabsToTheEndFrom(aTab);
- for (let i = tabs.length - 1; i >= 0; --i) {
- this.removeTab(tabs[i], {animate: true});
- }
- }
- ]]>
- </body>
- </method>
-
- <method name="removeAllTabsBut">
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- if (aTab.pinned)
- return;
-
- if (this.warnAboutClosingTabs(this.closingTabsEnum.OTHER)) {
- let tabs = this.visibleTabs;
- this.selectedTab = aTab;
-
- for (let i = tabs.length - 1; i >= 0; --i) {
- if (tabs[i] != aTab && !tabs[i].pinned)
- this.removeTab(tabs[i]);
- }
- }
- ]]>
- </body>
- </method>
-
- <method name="removeCurrentTab">
- <parameter name="aParams"/>
- <body>
- <![CDATA[
- this.removeTab(this.mCurrentTab, aParams);
- ]]>
- </body>
- </method>
-
- <field name="_removingTabs">
- []
- </field>
-
- <method name="removeTab">
- <parameter name="aTab"/>
- <parameter name="aParams"/>
- <body>
- <![CDATA[
- if (aParams) {
- var animate = aParams.animate;
- var byMouse = aParams.byMouse;
- }
-
- // Handle requests for synchronously removing an already
- // asynchronously closing tab.
- if (!animate &&
- aTab.closing) {
- this._endRemoveTab(aTab);
- return;
- }
-
- var isLastTab = (this.tabs.length - this._removingTabs.length == 1);
-
- if (!this._beginRemoveTab(aTab, false, null, true))
- return;
-
- if (!aTab.pinned && !aTab.hidden && aTab._fullyOpen && byMouse)
- this.tabContainer._lockTabSizing(aTab);
- else
- this.tabContainer._unlockTabSizing();
-
- if (!animate /* the caller didn't opt in */ ||
- isLastTab ||
- aTab.pinned ||
- aTab.hidden ||
- this._removingTabs.length > 3 /* don't want lots of concurrent animations */ ||
- aTab.getAttribute("fadein") != "true" /* fade-in transition hasn't been triggered yet */ ||
- window.getComputedStyle(aTab).maxWidth == "0.1px" /* fade-in transition hasn't moved yet */ ||
- !Services.prefs.getBoolPref("browser.tabs.animate")) {
- this._endRemoveTab(aTab);
- return;
- }
-
- this.tabContainer._handleTabTelemetryStart(aTab);
-
- this._blurTab(aTab);
- aTab.style.maxWidth = ""; // ensure that fade-out transition happens
- aTab.removeAttribute("fadein");
-
- if (this.tabs.length - this._removingTabs.length == 1) {
- // The second tab just got closed and we will end up with a single
- // one. Remove the first tab's close button immediately (if needed)
- // rather than after the tabclose animation ends.
- this.tabContainer.adjustTabstrip();
- }
-
- setTimeout(function (tab, tabbrowser) {
- if (tab.parentNode &&
- window.getComputedStyle(tab).maxWidth == "0.1px") {
- NS_ASSERT(false, "Giving up waiting for the tab closing animation to finish (bug 608589)");
- tabbrowser._endRemoveTab(tab);
- }
- }, 3000, aTab, this);
- ]]>
- </body>
- </method>
-
- <!-- Tab close requests are ignored if the window is closing anyway,
- e.g. when holding Ctrl+W. -->
- <field name="_windowIsClosing">
- false
- </field>
-
- <method name="_beginRemoveTab">
- <parameter name="aTab"/>
- <parameter name="aTabWillBeMoved"/>
- <parameter name="aCloseWindowWithLastTab"/>
- <parameter name="aCloseWindowFastpath"/>
- <body>
- <![CDATA[
- if (aTab.closing ||
- aTab._pendingPermitUnload ||
- this._windowIsClosing)
- return false;
-
- var browser = this.getBrowserForTab(aTab);
-
- if (!aTabWillBeMoved) {
- let ds = browser.docShell;
- if (ds && ds.contentViewer) {
- // We need to block while calling permitUnload() because it
- // processes the event queue and may lead to another removeTab()
- // call before permitUnload() even returned.
- aTab._pendingPermitUnload = true;
- let permitUnload = ds.contentViewer.permitUnload();
- delete aTab._pendingPermitUnload;
-
- if (!permitUnload)
- return false;
- }
- }
-
- var closeWindow = false;
- var newTab = false;
- if (this.tabs.length - this._removingTabs.length == 1) {
- closeWindow = aCloseWindowWithLastTab != null ? aCloseWindowWithLastTab :
- !window.toolbar.visible ||
- this.tabContainer._closeWindowWithLastTab;
-
- // Closing the tab and replacing it with a blank one is notably slower
- // than closing the window right away. If the caller opts in, take
- // the fast path.
- if (closeWindow &&
- aCloseWindowFastpath &&
- this._removingTabs.length == 0 &&
- (this._windowIsClosing = window.closeWindow(true, window.warnAboutClosingWindow)))
- return null;
-
- newTab = true;
- }
-
- aTab.closing = true;
- this._removingTabs.push(aTab);
- this._visibleTabs = null; // invalidate cache
- if (newTab)
- this.addTab(BROWSER_NEW_TAB_URL, {skipAnimation: true});
- else
- this.tabContainer.updateVisibility();
-
- // We're committed to closing the tab now.
- // Dispatch a notification.
- // We dispatch it before any teardown so that event listeners can
- // inspect the tab that's about to close.
- var evt = document.createEvent("UIEvent");
- evt.initUIEvent("TabClose", true, false, window, aTabWillBeMoved ? 1 : 0);
- aTab.dispatchEvent(evt);
-
- if (!gMultiProcessBrowser) {
- // Prevent this tab from showing further dialogs, since we're closing it
- var windowUtils = browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIDOMWindowUtils);
- windowUtils.disableDialogs();
- }
-
- // Remove the tab's filter and progress listener.
- const filter = this.mTabFilters[aTab._tPos];
-
- browser.webProgress.removeProgressListener(filter);
-
- filter.removeProgressListener(this.mTabListeners[aTab._tPos]);
- this.mTabListeners[aTab._tPos].destroy();
-
- if (browser.registeredOpenURI && !aTabWillBeMoved) {
- this._placesAutocomplete.unregisterOpenPage(browser.registeredOpenURI);
- delete browser.registeredOpenURI;
- }
-
- // We are no longer the primary content area.
- browser.setAttribute("type", "content-targetable");
-
- // Remove this tab as the owner of any other tabs, since it's going away.
- Array.forEach(this.tabs, function (tab) {
- if ("owner" in tab && tab.owner == aTab)
- // |tab| is a child of the tab we're removing, make it an orphan
- tab.owner = null;
- });
-
- aTab._endRemoveArgs = [closeWindow, newTab];
- return true;
- ]]>
- </body>
- </method>
-
- <method name="_endRemoveTab">
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- if (!aTab || !aTab._endRemoveArgs)
- return;
-
- var [aCloseWindow, aNewTab] = aTab._endRemoveArgs;
- aTab._endRemoveArgs = null;
-
- if (this._windowIsClosing) {
- aCloseWindow = false;
- aNewTab = false;
- }
-
- this._lastRelatedTab = null;
-
- // update the UI early for responsiveness
- aTab.collapsed = true;
- this.tabContainer._fillTrailingGap();
- this._blurTab(aTab);
-
- this._removingTabs.splice(this._removingTabs.indexOf(aTab), 1);
-
- if (aCloseWindow) {
- this._windowIsClosing = true;
- while (this._removingTabs.length)
- this._endRemoveTab(this._removingTabs[0]);
- } else if (!this._windowIsClosing) {
- if (aNewTab)
- focusAndSelectUrlBar();
-
- // workaround for bug 345399
- this.tabContainer.mTabstrip._updateScrollButtonsDisabledState();
- }
-
- // We're going to remove the tab and the browser now.
- // Clean up mTabFilters and mTabListeners now rather than in
- // _beginRemoveTab, so that their size is always in sync with the
- // number of tabs and browsers (the xbl destructor depends on this).
- this.mTabFilters.splice(aTab._tPos, 1);
- this.mTabListeners.splice(aTab._tPos, 1);
-
- var browser = this.getBrowserForTab(aTab);
- this._outerWindowIDBrowserMap.delete(browser.outerWindowID);
-
- // Because of the way XBL works (fields just set JS
- // properties on the element) and the code we have in place
- // to preserve the JS objects for any elements that have
- // JS properties set on them, the browser element won't be
- // destroyed until the document goes away. So we force a
- // cleanup ourselves.
- // This has to happen before we remove the child so that the
- // XBL implementation of nsIObserver still works.
- browser.destroy();
-
- if (browser == this.mCurrentBrowser)
- this.mCurrentBrowser = null;
-
- var wasPinned = aTab.pinned;
-
- // Invalidate browsers cache, as the tab is removed from the
- // tab container.
- this._browsers = null;
-
- // Remove the tab ...
- this.tabContainer.removeChild(aTab);
-
- // ... and fix up the _tPos properties immediately.
- for (let i = aTab._tPos; i < this.tabs.length; i++)
- this.tabs[i]._tPos = i;
-
- if (!this._windowIsClosing) {
- if (wasPinned)
- this.tabContainer._positionPinnedTabs();
-
- // update tab close buttons state
- this.tabContainer.adjustTabstrip();
-
- setTimeout(function(tabs) {
- tabs._lastTabClosedByMouse = false;
- }, 0, this.tabContainer);
- }
-
- // Pale Moon: if resizing immediately, select the tab immediately to the left
- // instead of the right (if not leftmost) to prevent focus swap and
- // "selected tab not under cursor"
- // FIXME: Tabs must be sliding in from the left for this, or it'd unfocus
- // in the other direction! Disabled for now. Is there an easier way? :hover?
- // Is this even needed when resizing immediately?...
-
- //if (Services.prefs.getBoolPref("browser.tabs.resize_immediately")) {
- // if (this.selectedTab._tPos > 1) {
- // let newPos = this.selectedTab._tPos - 1;
- // this.selectedTab = this.tabs[newPos];
- // }
- //}
-
- // update tab positional properties and attributes
- this.selectedTab._selected = true;
- this.tabContainer._setPositionalAttributes();
-
- // Removing the panel requires fixing up selectedPanel immediately
- // (see below), which would be hindered by the potentially expensive
- // browser removal. So we remove the browser and the panel in two
- // steps.
-
- var panel = this.getNotificationBox(browser);
-
- // This will unload the document. An unload handler could remove
- // dependant tabs, so it's important that the tabbrowser is now in
- // a consistent state (tab removed, tab positions updated, etc.).
- browser.parentNode.removeChild(browser);
-
- // Release the browser in case something is erroneously holding a
- // reference to the tab after its removal.
- this._tabForBrowser.delete(aTab.linkedBrowser);
- aTab.linkedBrowser = null;
-
- // As the browser is removed, the removal of a dependent document can
- // cause the whole window to close. So at this point, it's possible
- // that the binding is destructed.
- if (this.mTabBox) {
- let selectedPanel = this.mTabBox.selectedPanel;
-
- this.mPanelContainer.removeChild(panel);
-
- // Under the hood, a selectedIndex attribute controls which panel
- // is displayed. Removing a panel A which precedes the selected
- // panel B makes selectedIndex point to the panel next to B. We
- // need to explicitly preserve B as the selected panel.
- this.mTabBox.selectedPanel = selectedPanel;
- }
-
- if (aCloseWindow)
- this._windowIsClosing = closeWindow(true, window.warnAboutClosingWindow);
- ]]>
- </body>
- </method>
-
- <method name="_blurTab">
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- if (!aTab.selected)
- return;
-
- if (aTab.owner &&
- !aTab.owner.hidden &&
- !aTab.owner.closing &&
- Services.prefs.getBoolPref("browser.tabs.selectOwnerOnClose")) {
- this.selectedTab = aTab.owner;
- return;
- }
-
- // Switch to a visible tab unless there aren't any others remaining
- let remainingTabs = this.visibleTabs;
- let numTabs = remainingTabs.length;
- if (numTabs == 0 || numTabs == 1 && remainingTabs[0] == aTab) {
- remainingTabs = Array.filter(this.tabs, function(tab) {
- return !tab.closing;
- }, this);
- }
-
- // Try to find a remaining tab that comes after the given tab
- var tab = aTab;
- do {
- tab = tab.nextSibling;
- } while (tab && remainingTabs.indexOf(tab) == -1);
-
- if (!tab) {
- tab = aTab;
-
- do {
- tab = tab.previousSibling;
- } while (tab && remainingTabs.indexOf(tab) == -1);
- }
-
- this.selectedTab = tab;
- ]]>
- </body>
- </method>
-
- <method name="swapNewTabWithBrowser">
- <parameter name="aNewTab"/>
- <parameter name="aBrowser"/>
- <body>
- <![CDATA[
- // The browser must be standalone.
- if (aBrowser.getTabBrowser())
- throw Cr.NS_ERROR_INVALID_ARG;
-
- // The tab is definitely not loading.
- aNewTab.removeAttribute("busy");
- if (aNewTab.selected) {
- this.mIsBusy = false;
- }
-
- this._swapBrowserDocShells(aNewTab, aBrowser);
-
- // Update the new tab's title.
- this.setTabTitle(aNewTab);
-
- if (aNewTab.selected) {
- this.updateCurrentBrowser(true);
- }
- ]]>
- </body>
- </method>
-
- <method name="swapBrowsersAndCloseOther">
- <parameter name="aOurTab"/>
- <parameter name="aOtherTab"/>
- <body>
- <![CDATA[
- // Do not allow transfering a private tab to a non-private window
- // and vice versa.
- if (PrivateBrowsingUtils.isWindowPrivate(window) !=
- PrivateBrowsingUtils.isWindowPrivate(aOtherTab.ownerDocument.defaultView))
- return;
-
- // That's gBrowser for the other window, not the tab's browser!
- var remoteBrowser = aOtherTab.ownerDocument.defaultView.gBrowser;
- var isPending = aOtherTab.hasAttribute("pending");
-
- // Expedite the removal of the icon if it was already scheduled.
- if (aOtherTab._soundPlayingAttrRemovalTimer) {
- clearTimeout(aOtherTab._soundPlayingAttrRemovalTimer);
- aOtherTab._soundPlayingAttrRemovalTimer = 0;
- aOtherTab.removeAttribute("soundplaying");
- remoteBrowser._tabAttrModified(aOtherTab, ["soundplaying"]);
- }
-
- // First, start teardown of the other browser. Make sure to not
- // fire the beforeunload event in the process. Close the other
- // window if this was its last tab.
- if (!remoteBrowser._beginRemoveTab(aOtherTab, true, true))
- return;
-
- let ourBrowser = this.getBrowserForTab(aOurTab);
- let otherBrowser = aOtherTab.linkedBrowser;
-
- let modifiedAttrs = [];
- if (aOtherTab.hasAttribute("muted")) {
- aOurTab.setAttribute("muted", "true");
- aOurTab.muteReason = aOtherTab.muteReason;
- ourBrowser.mute();
- modifiedAttrs.push("muted");
- }
- if (aOtherTab.hasAttribute("soundplaying")) {
- aOurTab.setAttribute("soundplaying", "true");
- modifiedAttrs.push("soundplaying");
- }
-
- // If the other tab is pending (i.e. has not been restored, yet)
- // then do not switch docShells but retrieve the other tab's state
- // and apply it to our tab.
- if (isPending) {
- let ss = Cc["@mozilla.org/browser/sessionstore;1"]
- .getService(Ci.nsISessionStore)
- ss.setTabState(aOurTab, ss.getTabState(aOtherTab));
-
- // Make sure to unregister any open URIs.
- this._swapRegisteredOpenURIs(ourBrowser, otherBrowser);
- } else {
- // Workarounds for bug 458697
- // Icon might have been set on DOMLinkAdded, don't override that.
- if (!ourBrowser.mIconURL && otherBrowser.mIconURL)
- this.setIcon(aOurTab, otherBrowser.mIconURL, otherBrowser.contentPrincipal);
- var isBusy = aOtherTab.hasAttribute("busy");
- if (isBusy) {
- aOurTab.setAttribute("busy", "true");
- modifiedAttrs.push("busy");
- if (aOurTab.selected)
- this.mIsBusy = true;
- }
-
- this._swapBrowserDocShells(aOurTab, otherBrowser);
- }
-
- // Finish tearing down the tab that's going away.
- remoteBrowser._endRemoveTab(aOtherTab);
-
- if (isBusy)
- this.setTabTitleLoading(aOurTab);
- else
- this.setTabTitle(aOurTab);
-
- // If the tab was already selected (this happpens in the scenario
- // of replaceTabWithWindow), notify onLocationChange, etc.
- if (aOurTab.selected)
- this.updateCurrentBrowser(true);
-
- if (modifiedAttrs.length) {
- this._tabAttrModified(aOurTab, modifiedAttrs);
- }
- ]]>
- </body>
- </method>
-
- <method name="_swapBrowserDocShells">
- <parameter name="aOurTab"/>
- <parameter name="aOtherBrowser"/>
- <body>
- <![CDATA[
- // Unhook our progress listener
- let index = aOurTab._tPos;
- const filter = this.mTabFilters[index];
- let tabListener = this.mTabListeners[index];
- let ourBrowser = this.getBrowserForTab(aOurTab);
- ourBrowser.webProgress.removeProgressListener(filter);
- filter.removeProgressListener(tabListener);
-
- // Make sure to unregister any open URIs.
- this._swapRegisteredOpenURIs(ourBrowser, aOtherBrowser);
-
- // Unmap old outerWindowIDs.
- this._outerWindowIDBrowserMap.delete(ourBrowser.outerWindowID);
- let remoteBrowser = aOtherBrowser.ownerDocument.defaultView.gBrowser;
- if (remoteBrowser) {
- remoteBrowser._outerWindowIDBrowserMap.delete(aOtherBrowser.outerWindowID);
- }
- // Swap the docshells
- ourBrowser.swapDocShells(aOtherBrowser);
-
- // Register new outerWindowIDs.
- this._outerWindowIDBrowserMap.set(ourBrowser.outerWindowID, ourBrowser);
- if (remoteBrowser) {
- remoteBrowser._outerWindowIDBrowserMap.set(aOtherBrowser.outerWindowID, aOtherBrowser);
- }
- // Restore the progress listener
- this.mTabListeners[index] = tabListener =
- this.mTabProgressListener(aOurTab, ourBrowser, false);
-
- const notifyAll = Ci.nsIWebProgress.NOTIFY_ALL;
- filter.addProgressListener(tabListener, notifyAll);
- ourBrowser.webProgress.addProgressListener(filter, notifyAll);
- ]]>
- </body>
- </method>
-
- <method name="_swapRegisteredOpenURIs">
- <parameter name="aOurBrowser"/>
- <parameter name="aOtherBrowser"/>
- <body>
- <![CDATA[
- // If the current URI is registered as open remove it from the list.
- if (aOurBrowser.registeredOpenURI) {
- this._placesAutocomplete.unregisterOpenPage(aOurBrowser.registeredOpenURI);
- delete aOurBrowser.registeredOpenURI;
- }
-
- // If the other/new URI is registered as open then copy it over.
- if (aOtherBrowser.registeredOpenURI) {
- aOurBrowser.registeredOpenURI = aOtherBrowser.registeredOpenURI;
- delete aOtherBrowser.registeredOpenURI;
- }
- ]]>
- </body>
- </method>
-
- <method name="reloadAllTabs">
- <body>
- <![CDATA[
- let tabs = this.visibleTabs;
- let l = tabs.length;
- for (var i = 0; i < l; i++) {
- try {
- this.getBrowserForTab(tabs[i]).reload();
- } catch (e) {
- // ignore failure to reload so others will be reloaded
- }
- }
- ]]>
- </body>
- </method>
-
- <method name="reloadTab">
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- let browser = this.getBrowserForTab(aTab);
- // Reset DOS mitigation for basic auth prompt
- delete browser.authPromptCounter;
- browser.reload();
- ]]>
- </body>
- </method>
-
- <method name="addProgressListener">
- <parameter name="aListener"/>
- <body>
- <![CDATA[
- if (arguments.length != 1) {
- Components.utils.reportError("gBrowser.addProgressListener was " +
- "called with a second argument, " +
- "which is not supported. See bug " +
- "608628.");
- }
-
- this.mProgressListeners.push(aListener);
- ]]>
- </body>
- </method>
-
- <method name="removeProgressListener">
- <parameter name="aListener"/>
- <body>
- <![CDATA[
- this.mProgressListeners =
- this.mProgressListeners.filter(function (l) l != aListener);
- ]]>
- </body>
- </method>
-
- <method name="addTabsProgressListener">
- <parameter name="aListener"/>
- <body>
- this.mTabsProgressListeners.push(aListener);
- </body>
- </method>
-
- <method name="removeTabsProgressListener">
- <parameter name="aListener"/>
- <body>
- <![CDATA[
- this.mTabsProgressListeners =
- this.mTabsProgressListeners.filter(function (l) l != aListener);
- ]]>
- </body>
- </method>
-
- <method name="getBrowserForTab">
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- return aTab.linkedBrowser;
- ]]>
- </body>
- </method>
-
- <method name="showOnlyTheseTabs">
- <parameter name="aTabs"/>
- <body>
- <![CDATA[
- Array.forEach(this.tabs, function(tab) {
- if (aTabs.indexOf(tab) == -1)
- this.hideTab(tab);
- else
- this.showTab(tab);
- }, this);
-
- this.tabContainer._handleTabSelect(false);
- ]]>
- </body>
- </method>
-
- <method name="showTab">
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- if (aTab.hidden) {
- aTab.removeAttribute("hidden");
- this._visibleTabs = null; // invalidate cache
-
- this.tabContainer.adjustTabstrip();
-
- this.tabContainer._setPositionalAttributes();
-
- let event = document.createEvent("Events");
- event.initEvent("TabShow", true, false);
- aTab.dispatchEvent(event);
- }
- ]]>
- </body>
- </method>
-
- <method name="hideTab">
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- if (!aTab.hidden && !aTab.pinned && !aTab.selected &&
- !aTab.closing) {
- aTab.setAttribute("hidden", "true");
- this._visibleTabs = null; // invalidate cache
-
- this.tabContainer.adjustTabstrip();
-
- this.tabContainer._setPositionalAttributes();
-
- let event = document.createEvent("Events");
- event.initEvent("TabHide", true, false);
- aTab.dispatchEvent(event);
- }
- ]]>
- </body>
- </method>
-
- <method name="selectTabAtIndex">
- <parameter name="aIndex"/>
- <parameter name="aEvent"/>
- <body>
- <![CDATA[
- let tabs = this.visibleTabs;
-
- // count backwards for aIndex < 0
- if (aIndex < 0)
- aIndex += tabs.length;
-
- if (aIndex >= 0 && aIndex < tabs.length)
- this.selectedTab = tabs[aIndex];
-
- if (aEvent) {
- aEvent.preventDefault();
- aEvent.stopPropagation();
- }
- ]]>
- </body>
- </method>
-
- <property name="selectedTab">
- <getter>
- return this.mCurrentTab;
- </getter>
- <setter>
- <![CDATA[
- if (gNavToolbox.collapsed) {
- return this.mTabBox.selectedTab;
- }
- // Update the tab
- this.mTabBox.selectedTab = val;
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="selectedBrowser"
- onget="return this.mCurrentBrowser;"
- readonly="true"/>
-
- <property name="browsers" readonly="true">
- <getter>
- <![CDATA[
- return this._browsers ||
- (this._browsers = Array.map(this.tabs, function (tab) tab.linkedBrowser));
- ]]>
- </getter>
- </property>
- <field name="_browsers">null</field>
-
- <!-- Moves a tab to a new browser window, unless it's already the only tab
- in the current window, in which case this will do nothing. -->
- <method name="replaceTabWithWindow">
- <parameter name="aTab"/>
- <parameter name="aOptions"/>
- <body>
- <![CDATA[
- if (this.tabs.length == 1)
- return null;
-
- var options = "chrome,dialog=no,all";
- for (var name in aOptions)
- options += "," + name + "=" + aOptions[name];
-
- // tell a new window to take the "dropped" tab
- return window.openDialog(getBrowserURL(), "_blank", options, aTab);
- ]]>
- </body>
- </method>
-
- <method name="moveTabTo">
- <parameter name="aTab"/>
- <parameter name="aIndex"/>
- <body>
- <![CDATA[
- var oldPosition = aTab._tPos;
- if (oldPosition == aIndex)
- return;
-
- // Don't allow mixing pinned and unpinned tabs.
- if (aTab.pinned)
- aIndex = Math.min(aIndex, this._numPinnedTabs - 1);
- else
- aIndex = Math.max(aIndex, this._numPinnedTabs);
- if (oldPosition == aIndex)
- return;
-
- this._lastRelatedTab = null;
-
- this.mTabFilters.splice(aIndex, 0, this.mTabFilters.splice(aTab._tPos, 1)[0]);
- this.mTabListeners.splice(aIndex, 0, this.mTabListeners.splice(aTab._tPos, 1)[0]);
-
- let wasFocused = (document.activeElement == this.mCurrentTab);
-
- aIndex = aIndex < aTab._tPos ? aIndex: aIndex+1;
- this.mCurrentTab._selected = false;
-
- // invalidate caches
- this._browsers = null;
- this._visibleTabs = null;
-
- // use .item() instead of [] because dragging to the end of the strip goes out of
- // bounds: .item() returns null (so it acts like appendChild), but [] throws
- this.tabContainer.insertBefore(aTab, this.tabs.item(aIndex));
-
- for (let i = 0; i < this.tabs.length; i++) {
- this.tabs[i]._tPos = i;
- this.tabs[i]._selected = false;
- }
- this.mCurrentTab._selected = true;
-
- if (wasFocused)
- this.mCurrentTab.focus();
-
- this.tabContainer._handleTabSelect(false);
-
- if (aTab.pinned)
- this.tabContainer._positionPinnedTabs();
-
- this.tabContainer._setPositionalAttributes();
-
- var evt = document.createEvent("UIEvents");
- evt.initUIEvent("TabMove", true, false, window, oldPosition);
- aTab.dispatchEvent(evt);
- ]]>
- </body>
- </method>
-
- <method name="moveTabForward">
- <body>
- <![CDATA[
- let nextTab = this.mCurrentTab.nextSibling;
- while (nextTab && nextTab.hidden)
- nextTab = nextTab.nextSibling;
-
- if (nextTab)
- this.moveTabTo(this.mCurrentTab, nextTab._tPos);
- else if (this.arrowKeysShouldWrap)
- this.moveTabToStart();
- ]]>
- </body>
- </method>
-
- <method name="moveTabBackward">
- <body>
- <![CDATA[
- let previousTab = this.mCurrentTab.previousSibling;
- while (previousTab && previousTab.hidden)
- previousTab = previousTab.previousSibling;
-
- if (previousTab)
- this.moveTabTo(this.mCurrentTab, previousTab._tPos);
- else if (this.arrowKeysShouldWrap)
- this.moveTabToEnd();
- ]]>
- </body>
- </method>
-
- <method name="moveTabToStart">
- <body>
- <![CDATA[
- var tabPos = this.mCurrentTab._tPos;
- if (tabPos > 0)
- this.moveTabTo(this.mCurrentTab, 0);
- ]]>
- </body>
- </method>
-
- <method name="moveTabToEnd">
- <body>
- <![CDATA[
- var tabPos = this.mCurrentTab._tPos;
- if (tabPos < this.browsers.length - 1)
- this.moveTabTo(this.mCurrentTab, this.browsers.length - 1);
- ]]>
- </body>
- </method>
-
- <method name="moveTabOver">
- <parameter name="aEvent"/>
- <body>
- <![CDATA[
- var direction = window.getComputedStyle(this.parentNode, null).direction;
- if ((direction == "ltr" && aEvent.keyCode == KeyEvent.DOM_VK_RIGHT) ||
- (direction == "rtl" && aEvent.keyCode == KeyEvent.DOM_VK_LEFT))
- this.moveTabForward();
- else
- this.moveTabBackward();
- ]]>
- </body>
- </method>
-
- <method name="duplicateTab">
- <parameter name="aTab"/><!-- can be from a different window as well -->
- <body>
- <![CDATA[
- return Cc["@mozilla.org/browser/sessionstore;1"]
- .getService(Ci.nsISessionStore)
- .duplicateTab(window, aTab);
- ]]>
- </body>
- </method>
-
- <!-- BEGIN FORWARDED BROWSER PROPERTIES. IF YOU ADD A PROPERTY TO THE BROWSER ELEMENT
- MAKE SURE TO ADD IT HERE AS WELL. -->
- <property name="canGoBack"
- onget="return this.mCurrentBrowser.canGoBack;"
- readonly="true"/>
-
- <property name="canGoForward"
- onget="return this.mCurrentBrowser.canGoForward;"
- readonly="true"/>
-
- <method name="goBack">
- <body>
- <![CDATA[
- return this.mCurrentBrowser.goBack();
- ]]>
- </body>
- </method>
-
- <method name="goForward">
- <body>
- <![CDATA[
- return this.mCurrentBrowser.goForward();
- ]]>
- </body>
- </method>
-
- <method name="reload">
- <body>
- <![CDATA[
- return this.mCurrentBrowser.reload();
- ]]>
- </body>
- </method>
-
- <method name="reloadWithFlags">
- <parameter name="aFlags"/>
- <body>
- <![CDATA[
- return this.mCurrentBrowser.reloadWithFlags(aFlags);
- ]]>
- </body>
- </method>
-
- <method name="stop">
- <body>
- <![CDATA[
- return this.mCurrentBrowser.stop();
- ]]>
- </body>
- </method>
-
- <!-- throws exception for unknown schemes -->
- <method name="loadURI">
- <parameter name="aURI"/>
- <parameter name="aReferrerURI"/>
- <parameter name="aCharset"/>
- <body>
- <![CDATA[
- return this.mCurrentBrowser.loadURI(aURI, aReferrerURI, aCharset);
- ]]>
- </body>
- </method>
-
- <!-- throws exception for unknown schemes -->
- <method name="loadURIWithFlags">
- <parameter name="aURI"/>
- <parameter name="aFlags"/>
- <parameter name="aReferrerURI"/>
- <parameter name="aCharset"/>
- <parameter name="aPostData"/>
- <body>
- <![CDATA[
- // Note - the callee understands both:
- // (a) loadURIWithFlags(aURI, aFlags, ...)
- // (b) loadURIWithFlags(aURI, { flags: aFlags, ... })
- // Forwarding it as (a) here actually supports both (a) and (b),
- // so you can call us either way too.
- return this.mCurrentBrowser.loadURIWithFlags(aURI, aFlags, aReferrerURI, aCharset, aPostData);
- ]]>
- </body>
- </method>
-
- <method name="goHome">
- <body>
- <![CDATA[
- return this.mCurrentBrowser.goHome();
- ]]>
- </body>
- </method>
-
- <property name="homePage">
- <getter>
- <![CDATA[
- return this.mCurrentBrowser.homePage;
- ]]>
- </getter>
- <setter>
- <![CDATA[
- this.mCurrentBrowser.homePage = val;
- return val;
- ]]>
- </setter>
- </property>
-
- <method name="gotoIndex">
- <parameter name="aIndex"/>
- <body>
- <![CDATA[
- return this.mCurrentBrowser.gotoIndex(aIndex);
- ]]>
- </body>
- </method>
-
- <method name="attachFormFill">
- <body><![CDATA[
- for (var i = 0; i < this.mPanelContainer.childNodes.length; ++i) {
- var cb = this.getBrowserAtIndex(i);
- cb.attachFormFill();
- }
- ]]></body>
- </method>
-
- <method name="detachFormFill">
- <body><![CDATA[
- for (var i = 0; i < this.mPanelContainer.childNodes.length; ++i) {
- var cb = this.getBrowserAtIndex(i);
- cb.detachFormFill();
- }
- ]]></body>
- </method>
-
- <property name="currentURI"
- onget="return this.mCurrentBrowser.currentURI;"
- readonly="true"/>
-
- <field name="_fastFind">null</field>
- <property name="fastFind"
- readonly="true">
- <getter>
- <![CDATA[
- if (!this._fastFind) {
- this._fastFind = Components.classes["@mozilla.org/typeaheadfind;1"]
- .createInstance(Components.interfaces.nsITypeAheadFind);
- this._fastFind.init(this.docShell);
- }
- return this._fastFind;
- ]]>
- </getter>
- </property>
-
- <field name="_lastSearchString">null</field>
- <field name="_lastSearchHighlight">false</field>
-
- <field name="finder"><![CDATA[
- ({
- mTabBrowser: this,
- mListeners: new Set(),
- get finder() {
- return this.mTabBrowser.mCurrentBrowser.finder;
- },
- destroy: function() {
- this.finder.destroy();
- },
- addResultListener: function(aListener) {
- this.mListeners.add(aListener);
- this.finder.addResultListener(aListener);
- },
- removeResultListener: function(aListener) {
- this.mListeners.delete(aListener);
- this.finder.removeResultListener(aListener);
- },
- get searchString() {
- return this.finder.searchString;
- },
- get clipboardSearchString() {
- return this.finder.clipboardSearchString;
- },
- set clipboardSearchString(val) {
- return this.finder.clipboardSearchString = val;
- },
- set caseSensitive(val) {
- return this.finder.caseSensitive = val;
- },
- set entireWord(val) {
- return this.finder.entireWord = val;
- },
- get highlighter() {
- return this.finder.highlighter;
- },
- get matchesCountLimit() {
- return this.finder.matchesCountLimit;
- },
- fastFind: function(...args) {
- this.finder.fastFind(...args);
- },
- findAgain: function(...args) {
- this.finder.findAgain(...args);
- },
- setSearchStringToSelection: function() {
- return this.finder.setSearchStringToSelection();
- },
- highlight: function(...args) {
- this.finder.highlight(...args);
- },
- getInitialSelection: function() {
- this.finder.getInitialSelection();
- },
- getActiveSelectionText: function() {
- return this.finder.getActiveSelectionText();
- },
- enableSelection: function() {
- this.finder.enableSelection();
- },
- removeSelection: function() {
- this.finder.removeSelection();
- },
- focusContent: function() {
- this.finder.focusContent();
- },
- onFindbarClose: function() {
- this.finder.onFindbarClose();
- },
- onFindbarOpen: function() {
- this.finder.onFindbarOpen();
- },
- onModalHighlightChange: function(...args) {
- return this.finder.onModalHighlightChange(...args);
- },
- onHighlightAllChange: function(...args) {
- return this.finder.onHighlightAllChange(...args);
- },
- keyPress: function(aEvent) {
- this.finder.keyPress(aEvent);
- },
- requestMatchesCount: function(...args) {
- this.finder.requestMatchesCount(...args);
- },
- onIteratorRangeFound: function(...args) {
- this.finder.onIteratorRangeFound(...args);
- },
- onIteratorReset: function() {
- this.finder.onIteratorReset();
- },
- onIteratorRestart: function(...args) {
- this.finder.onIteratorRestart(...args);
- },
- onIteratorStart: function(...args) {
- this.finder.onIteratorStart(...args);
- },
- onLocationChange: function(...args) {
- this.finder.onLocationChange(...args);
- }
- })
- ]]></field>
-
- <property name="docShell"
- onget="return this.mCurrentBrowser.docShell"
- readonly="true"/>
-
- <property name="webNavigation"
- onget="return this.mCurrentBrowser.webNavigation"
- readonly="true"/>
-
- <property name="webBrowserFind"
- readonly="true"
- onget="return this.mCurrentBrowser.webBrowserFind"/>
-
- <property name="webProgress"
- readonly="true"
- onget="return this.mCurrentBrowser.webProgress"/>
-
- <property name="contentWindow"
- readonly="true"
- onget="return this.mCurrentBrowser.contentWindow"/>
-
- <property name="contentWindowAsCPOW"
- readonly="true"
- onget="return this.mCurrentBrowser.contentWindow;"/>
-
- <property name="sessionHistory"
- onget="return this.mCurrentBrowser.sessionHistory;"
- readonly="true"/>
-
- <property name="markupDocumentViewer"
- onget="return this.mCurrentBrowser.markupDocumentViewer;"
- readonly="true"/>
-
- <property name="contentViewerEdit"
- onget="return this.mCurrentBrowser.contentViewerEdit;"
- readonly="true"/>
-
- <property name="contentViewerFile"
- onget="return this.mCurrentBrowser.contentViewerFile;"
- readonly="true"/>
-
- <property name="contentDocument"
- onget="return this.mCurrentBrowser.contentDocument;"
- readonly="true"/>
-
- <property name="contentDocumentAsCPOW"
- onget="return this.mCurrentBrowser.contentDocument;"
- readonly="true"/>
-
- <property name="contentTitle"
- onget="return this.mCurrentBrowser.contentTitle;"
- readonly="true"/>
-
- <property name="contentPrincipal"
- onget="return this.mCurrentBrowser.contentPrincipal;"
- readonly="true"/>
-
- <property name="securityUI"
- onget="return this.mCurrentBrowser.securityUI;"
- readonly="true"/>
-
- <property name="fullZoom"
- onget="return this.mCurrentBrowser.fullZoom;"
- onset="this.mCurrentBrowser.fullZoom = val;"/>
-
- <property name="textZoom"
- onget="return this.mCurrentBrowser.textZoom;"
- onset="this.mCurrentBrowser.textZoom = val;"/>
-
- <property name="isSyntheticDocument"
- onget="return this.mCurrentBrowser.isSyntheticDocument;"
- readonly="true"/>
-
- <method name="_handleKeyEvent">
- <parameter name="aEvent"/>
- <body><![CDATA[
- if (!aEvent.isTrusted) {
- // Don't let untrusted events mess with tabs.
- return;
- }
-
- if (aEvent.altKey)
- return;
-
- if (aEvent.ctrlKey && aEvent.shiftKey && !aEvent.metaKey) {
- switch (aEvent.keyCode) {
- case aEvent.DOM_VK_PAGE_UP:
- this.moveTabBackward();
- aEvent.stopPropagation();
- aEvent.preventDefault();
- return;
- case aEvent.DOM_VK_PAGE_DOWN:
- this.moveTabForward();
- aEvent.stopPropagation();
- aEvent.preventDefault();
- return;
- }
- }
-
-#ifdef XP_MACOSX
- if (!aEvent.metaKey)
- return;
-
- var offset = 1;
- switch (aEvent.charCode) {
- case '}'.charCodeAt(0):
- offset = -1;
- case '{'.charCodeAt(0):
- if (window.getComputedStyle(this, null).direction == "ltr")
- offset *= -1;
- this.tabContainer.advanceSelectedTab(offset, true);
- aEvent.stopPropagation();
- aEvent.preventDefault();
- }
-#else
- if (aEvent.ctrlKey && !aEvent.shiftKey && !aEvent.metaKey &&
- aEvent.keyCode == KeyEvent.DOM_VK_F4 &&
- !this.mCurrentTab.pinned) {
- this.removeCurrentTab({animate: true});
- aEvent.stopPropagation();
- aEvent.preventDefault();
- }
-#endif
- ]]></body>
- </method>
-
- <property name="userTypedValue"
- onget="return this.mCurrentBrowser.userTypedValue;"
- onset="return this.mCurrentBrowser.userTypedValue = val;"/>
-
- <method name="createTooltip">
- <parameter name="event"/>
- <body><![CDATA[
- event.stopPropagation();
- var tab = document.tooltipNode;
- if (tab.localName != "tab") {
- event.preventDefault();
- return;
- }
-
- var stringID, label;
- if (tab.mOverCloseButton) {
- stringID = "tabs.closeTab";
- } else if (tab._overPlayingIcon) {
- if (tab.linkedBrowser.audioBlocked) {
- stringID = "tabs.unblockAudio.tooltip";
- } else {
- stringID = tab.linkedBrowser.audioMuted ?
- "tabs.unmuteAudio.tooltip" :
- "tabs.muteAudio.tooltip";
- }
- } else {
- label = tab.getAttribute("label");
- }
- if (stringID && !label) {
- label = this.mStringBundle.getString(stringID);
- }
- event.target.setAttribute("label", label);
- ]]></body>
- </method>
-
- <method name="handleEvent">
- <parameter name="aEvent"/>
- <body><![CDATA[
- switch (aEvent.type) {
- case "keypress":
- this._handleKeyEvent(aEvent);
- break;
- case "sizemodechange":
- if (aEvent.target == window) {
- this.mCurrentBrowser.docShellIsActive =
- (window.windowState != window.STATE_MINIMIZED);
- }
- break;
- }
- ]]></body>
- </method>
-
- <method name="receiveMessage">
- <parameter name="aMessage"/>
- <body><![CDATA[
- let json = aMessage.json;
- let browser = aMessage.target;
-
- switch (aMessage.name) {
- case "DOMTitleChanged": {
- let tab = this.getTabForBrowser(browser);
- if (!tab)
- return;
- let titleChanged = this.setTabTitle(tab);
- if (titleChanged && !tab.selected && !tab.hasAttribute("busy"))
- tab.setAttribute("titlechanged", "true");
- break;
- }
- case "DOMWebNotificationClicked": {
- let tab = this.getTabForBrowser(browser);
- if (!tab)
- return;
- this.selectedTab = tab;
- window.focus();
- break;
- }
- }
- ]]></body>
- </method>
-
- <constructor>
- <![CDATA[
- let browserStack = document.getAnonymousElementByAttribute(this, "anonid", "browserStack");
- this.mCurrentBrowser = document.getAnonymousElementByAttribute(this, "anonid", "initialBrowser");
- if (Services.prefs.getBoolPref("browser.tabs.remote")) {
- browserStack.removeChild(this.mCurrentBrowser);
- this.mCurrentBrowser.setAttribute("remote", true);
- browserStack.appendChild(this.mCurrentBrowser);
- }
-
- this.mCurrentTab = this.tabContainer.firstChild;
- document.addEventListener("keypress", this, false);
- window.addEventListener("sizemodechange", this, false);
-
- var uniqueId = "panel" + Date.now();
- this.mPanelContainer.childNodes[0].id = uniqueId;
- this.mCurrentTab.linkedPanel = uniqueId;
- this.mCurrentTab._tPos = 0;
- this.mCurrentTab._fullyOpen = true;
- this.mCurrentTab.linkedBrowser = this.mCurrentBrowser;
- this._tabForBrowser.set(this.mCurrentBrowser, this.mCurrentTab);
-
- // set up the shared autoscroll popup
- this._autoScrollPopup = this.mCurrentBrowser._createAutoScrollPopup();
- this._autoScrollPopup.id = "autoscroller";
- this.appendChild(this._autoScrollPopup);
- this.mCurrentBrowser.setAttribute("autoscrollpopup", this._autoScrollPopup.id);
- this.mCurrentBrowser.droppedLinkHandler = handleDroppedLink;
- this.updateWindowResizers();
-
- // Hook up the event listeners to the first browser
- var tabListener = this.mTabProgressListener(this.mCurrentTab, this.mCurrentBrowser, true);
- const nsIWebProgress = Components.interfaces.nsIWebProgress;
- const filter = Components.classes["@mozilla.org/appshell/component/browser-status-filter;1"]
- .createInstance(nsIWebProgress);
- filter.addProgressListener(tabListener, nsIWebProgress.NOTIFY_ALL);
- this.mTabListeners[0] = tabListener;
- this.mTabFilters[0] = filter;
-
- try {
- // We assume this can only fail because mCurrentBrowser's docShell
- // hasn't been created, yet. This may be caused by code accessing
- // gBrowser before the window has finished loading.
- this._addProgressListenerForInitialTab();
- } catch (e) {
- // The binding was constructed too early, wait until the initial
- // tab's document is ready, then add the progress listener.
- this._waitForInitialContentDocument();
- }
-
- this.style.backgroundColor =
- Services.prefs.getBoolPref("browser.display.use_system_colors") ?
- "-moz-default-background-color" :
- Services.prefs.getCharPref("browser.display.background_color");
-
- if (Services.prefs.getBoolPref("browser.tabs.remote")) {
- messageManager.addMessageListener("DOMTitleChanged", this);
- } else {
- this._outerWindowIDBrowserMap.set(this.mCurrentBrowser.outerWindowID,
- this.mCurrentBrowser);
- }
- messageManager.addMessageListener("DOMWebNotificationClicked", this);
- ]]>
- </constructor>
-
- <method name="_addProgressListenerForInitialTab">
- <body><![CDATA[
- this.webProgress.addProgressListener(this.mTabFilters[0], Ci.nsIWebProgress.NOTIFY_ALL);
- ]]></body>
- </method>
-
- <method name="_waitForInitialContentDocument">
- <body><![CDATA[
- let obs = (subject, topic) => {
- if (this.browsers[0].contentWindow == subject) {
- Services.obs.removeObserver(obs, topic);
- this._addProgressListenerForInitialTab();
- }
- };
-
- // We use content-document-global-created as an approximation for
- // "docShell is initialized". We can do this because in the
- // mTabProgressListener we care most about the STATE_STOP notification
- // that will reset mBlank. That means it's important to at least add
- // the progress listener before the initial about:blank load stops
- // if we can't do it before the load starts.
- Services.obs.addObserver(obs, "content-document-global-created", false);
- ]]></body>
- </method>
-
- <destructor>
- <![CDATA[
- for (var i = 0; i < this.mTabListeners.length; ++i) {
- let browser = this.getBrowserAtIndex(i);
- if (browser.registeredOpenURI) {
- this._placesAutocomplete.unregisterOpenPage(browser.registeredOpenURI);
- delete browser.registeredOpenURI;
- }
- browser.webProgress.removeProgressListener(this.mTabFilters[i]);
- this.mTabFilters[i].removeProgressListener(this.mTabListeners[i]);
- this.mTabFilters[i] = null;
- this.mTabListeners[i].destroy();
- this.mTabListeners[i] = null;
- }
- document.removeEventListener("keypress", this, false);
- window.removeEventListener("sizemodechange", this, false);
-
- if (Services.prefs.getBoolPref("browser.tabs.remote"))
- messageManager.removeMessageListener("DOMTitleChanged", this);
- ]]>
- </destructor>
-
- <!-- Deprecated stuff, implemented for backwards compatibility. -->
- <method name="enterTabbedMode">
- <body>
- Application.console.log("enterTabbedMode is an obsolete method and " +
- "will be removed in a future release.");
- </body>
- </method>
- <field name="mTabbedMode" readonly="true">true</field>
- <method name="setStripVisibilityTo">
- <parameter name="aShow"/>
- <body>
- this.tabContainer.visible = aShow;
- </body>
- </method>
- <method name="getStripVisibility">
- <body>
- return this.tabContainer.visible;
- </body>
- </method>
- <property name="mContextTab" readonly="true"
- onget="return TabContextMenu.contextTab;"/>
- <property name="mPrefs" readonly="true"
- onget="return Services.prefs;"/>
- <property name="mTabContainer" readonly="true"
- onget="return this.tabContainer;"/>
- <property name="mTabs" readonly="true"
- onget="return this.tabs;"/>
- <!--
- - Compatibility hack: several extensions depend on this property to
- - access the tab context menu or tab container, so keep that working for
- - now. Ideally we can remove this once extensions are using
- - tabbrowser.tabContextMenu and tabbrowser.tabContainer directly.
- -->
- <property name="mStrip" readonly="true">
- <getter>
- <![CDATA[
- return ({
- self: this,
- childNodes: [null, this.tabContextMenu, this.tabContainer],
- firstChild: { nextSibling: this.tabContextMenu },
- getElementsByAttribute: function (attr, attrValue) {
- if (attr == "anonid" && attrValue == "tabContextMenu")
- return [this.self.tabContextMenu];
- return [];
- },
- // Also support adding event listeners (forward to the tab container)
- addEventListener: function (a,b,c) { this.self.tabContainer.addEventListener(a,b,c); },
- removeEventListener: function (a,b,c) { this.self.tabContainer.removeEventListener(a,b,c); }
- });
- ]]>
- </getter>
- </property>
- <field name="_soundPlayingAttrRemovalTimer">0</field>
- </implementation>
-
- <handlers>
- <handler event="DOMWindowClose" phase="capturing">
- <![CDATA[
- if (!event.isTrusted)
- return;
-
- if (this.tabs.length == 1)
- return;
-
- var tab = this._getTabForContentWindow(event.target);
- if (tab) {
- this.removeTab(tab);
- event.preventDefault();
- }
- ]]>
- </handler>
- <handler event="DOMWillOpenModalDialog" phase="capturing">
- <![CDATA[
- if (!event.isTrusted)
- return;
-
- // We're about to open a modal dialog, make sure the opening
- // tab is brought to the front.
- this.selectedTab = this._getTabForContentWindow(event.target.top);
- ]]>
- </handler>
- <handler event="DOMTitleChanged">
- <![CDATA[
- if (!event.isTrusted)
- return;
-
- var contentWin = event.target.defaultView;
- if (contentWin != contentWin.top)
- return;
-
- var tab = this._getTabForContentWindow(contentWin);
- if (!tab) {
- return;
- }
-
- var titleChanged = this.setTabTitle(tab);
- if (titleChanged && !tab.selected && !tab.hasAttribute("busy"))
- tab.setAttribute("titlechanged", "true");
- ]]>
- </handler>
- <handler event="DOMAudioPlaybackStarted">
- <![CDATA[
- var tab = getTabFromAudioEvent(event)
- if (!tab) {
- return;
- }
-
- clearTimeout(tab._soundPlayingAttrRemovalTimer);
- tab._soundPlayingAttrRemovalTimer = 0;
-
- let modifiedAttrs = [];
- if (tab.hasAttribute("soundplaying-scheduledremoval")) {
- tab.removeAttribute("soundplaying-scheduledremoval");
- modifiedAttrs.push("soundplaying-scheduledremoval");
- }
-
- if (!tab.hasAttribute("soundplaying")) {
- tab.setAttribute("soundplaying", true);
- modifiedAttrs.push("soundplaying");
- }
-
- this._tabAttrModified(tab, modifiedAttrs);
- ]]>
- </handler>
- <handler event="DOMAudioPlaybackStopped">
- <![CDATA[
- var tab = getTabFromAudioEvent(event)
- if (!tab) {
- return;
- }
-
- if (tab.hasAttribute("soundplaying")) {
- let removalDelay = Services.prefs.getIntPref("browser.tabs.delayHidingAudioPlayingIconMS");
-
- tab.style.setProperty("--soundplaying-removal-delay", `${removalDelay - 300}ms`);
- tab.setAttribute("soundplaying-scheduledremoval", "true");
- this._tabAttrModified(tab, ["soundplaying-scheduledremoval"]);
-
- tab._soundPlayingAttrRemovalTimer = setTimeout(() => {
- tab.removeAttribute("soundplaying-scheduledremoval");
- tab.removeAttribute("soundplaying");
- this._tabAttrModified(tab, ["soundplaying", "soundplaying-scheduledremoval"]);
- }, removalDelay);
- }
- ]]>
- </handler>
- <handler event="DOMAudioPlaybackBlockStarted">
- <![CDATA[
- var tab = getTabFromAudioEvent(event)
- if (!tab) {
- return;
- }
-
- if (!tab.hasAttribute("blocked")) {
- tab.setAttribute("blocked", true);
- this._tabAttrModified(tab, ["blocked"]);
- }
- ]]>
- </handler>
- <handler event="DOMAudioPlaybackBlockStopped">
- <![CDATA[
- var tab = getTabFromAudioEvent(event)
- if (!tab) {
- return;
- }
-
- if (tab.hasAttribute("blocked")) {
- tab.removeAttribute("blocked");
- this._tabAttrModified(tab, ["blocked"]);
- }
- ]]>
- </handler>
- </handlers>
- </binding>
-
- <binding id="tabbrowser-tabbox"
- extends="chrome://global/content/bindings/tabbox.xml#tabbox">
- <implementation>
- <property name="tabs" readonly="true"
- onget="return document.getBindingParent(this).tabContainer;"/>
- </implementation>
- </binding>
-
- <binding id="tabbrowser-arrowscrollbox" extends="chrome://global/content/bindings/scrollbox.xml#arrowscrollbox-clicktoscroll">
- <implementation>
- <!-- Override scrollbox.xml method, since our scrollbox's children are
- inherited from the binding parent -->
- <method name="_getScrollableElements">
- <body><![CDATA[
- return Array.filter(document.getBindingParent(this).childNodes,
- this._canScrollToElement, this);
- ]]></body>
- </method>
- <method name="_canScrollToElement">
- <parameter name="tab"/>
- <body><![CDATA[
- return !tab.pinned && !tab.hidden;
- ]]></body>
- </method>
- </implementation>
-
- <handlers>
- <handler event="underflow" phase="capturing"><![CDATA[
- if (event.detail == 0)
- return; // Ignore vertical events
-
- var tabs = document.getBindingParent(this);
- tabs.removeAttribute("overflow");
-
- if (tabs._lastTabClosedByMouse)
- tabs._expandSpacerBy(this._scrollButtonDown.clientWidth);
-
- tabs.tabbrowser._removingTabs.forEach(tabs.tabbrowser.removeTab,
- tabs.tabbrowser);
-
- tabs._positionPinnedTabs();
- ]]></handler>
- <handler event="overflow"><![CDATA[
- if (event.detail == 0)
- return; // Ignore vertical events
-
- var tabs = document.getBindingParent(this);
- tabs.setAttribute("overflow", "true");
- tabs._positionPinnedTabs();
- tabs._handleTabSelect(false);
- ]]></handler>
- </handlers>
- </binding>
-
- <binding id="tabbrowser-tabs"
- extends="chrome://global/content/bindings/tabbox.xml#tabs">
- <resources>
- <stylesheet src="chrome://browser/content/tabbrowser.css"/>
- </resources>
-
- <content>
- <xul:hbox align="end">
- <xul:image class="tab-drop-indicator" anonid="tab-drop-indicator" collapsed="true"/>
- </xul:hbox>
- <xul:arrowscrollbox anonid="arrowscrollbox" orient="horizontal" flex="1"
- style="min-width: 1px;"
-#ifndef XP_MACOSX
- clicktoscroll="true"
-#endif
- class="tabbrowser-arrowscrollbox">
-# This is a hack to circumvent bug 472020, otherwise the tabs show up on the
-# right of the newtab button.
- <children includes="tab"/>
-# This is to ensure anything extensions put here will go before the newtab
-# button, necessary due to the previous hack.
- <children/>
- <xul:toolbarbutton class="tabs-newtab-button"
- command="cmd_newNavigatorTab"
- onclick="checkForMiddleClick(this, event);"
- onmouseover="document.getBindingParent(this)._enterNewTab();"
- onmouseout="document.getBindingParent(this)._leaveNewTab();"
- tooltiptext="&newTabButton.tooltip;"/>
- <xul:spacer class="closing-tabs-spacer" anonid="closing-tabs-spacer"
- style="width: 0;"/>
- </xul:arrowscrollbox>
- </content>
-
- <implementation implements="nsIDOMEventListener">
- <constructor>
- <![CDATA[
- this.mTabClipWidth = Services.prefs.getIntPref("browser.tabs.tabClipWidth");
- this.mCloseButtons = Services.prefs.getIntPref("browser.tabs.closeButtons");
- this._closeWindowWithLastTab = Services.prefs.getBoolPref("browser.tabs.closeWindowWithLastTab");
-
- var tab = this.firstChild;
- tab.setAttribute("label",
- this.tabbrowser.mStringBundle.getString("tabs.emptyTabTitle"));
- tab.setAttribute("crop", "end");
- tab.setAttribute("onerror", "this.removeAttribute('image');");
- this.adjustTabstrip();
-
- Services.prefs.addObserver("browser.tabs.", this._prefObserver, false);
- window.addEventListener("resize", this, false);
- window.addEventListener("load", this, false);
-
- this._tabAnimationLoggingEnabled = Services.prefs.getBoolPref("browser.tabs.animationLogging.enabled", false);
- this._browserNewtabpageEnabled = Services.prefs.getBoolPref("browser.newtabpage.enabled");
- ]]>
- </constructor>
-
- <destructor>
- <![CDATA[
- Services.prefs.removeObserver("browser.tabs.", this._prefObserver);
- ]]>
- </destructor>
-
- <field name="tabbrowser" readonly="true">
- document.getElementById(this.getAttribute("tabbrowser"));
- </field>
-
- <field name="tabbox" readonly="true">
- this.tabbrowser.mTabBox;
- </field>
-
- <field name="contextMenu" readonly="true">
- document.getElementById("tabContextMenu");
- </field>
-
- <field name="mTabstripWidth">0</field>
-
- <field name="mTabstrip">
- document.getAnonymousElementByAttribute(this, "anonid", "arrowscrollbox");
- </field>
-
- <field name="_firstTab">null</field>
- <field name="_lastTab">null</field>
- <field name="_afterSelectedTab">null</field>
- <field name="_beforeHoveredTab">null</field>
- <field name="_afterHoveredTab">null</field>
-
- <method name="_setPositionalAttributes">
- <body><![CDATA[
- let visibleTabs = this.tabbrowser.visibleTabs;
-
- if (!visibleTabs.length)
- return;
-
- let selectedIndex = visibleTabs.indexOf(this.selectedItem);
-
- let lastVisible = visibleTabs.length - 1;
-
- if (this._afterSelectedTab)
- this._afterSelectedTab.removeAttribute("afterselected-visible");
- if (this.selectedItem.closing || selectedIndex == lastVisible) {
- this._afterSelectedTab = null;
- } else {
- this._afterSelectedTab = visibleTabs[selectedIndex + 1];
- this._afterSelectedTab.setAttribute("afterselected-visible",
- "true");
- }
-
- if (this._firstTab)
- this._firstTab.removeAttribute("first-visible-tab");
- this._firstTab = visibleTabs[0];
- this._firstTab.setAttribute("first-visible-tab", "true");
- if (this._lastTab)
- this._lastTab.removeAttribute("last-visible-tab");
- this._lastTab = visibleTabs[lastVisible];
- this._lastTab.setAttribute("last-visible-tab", "true");
- ]]></body>
- </method>
-
- <field name="_prefObserver"><![CDATA[({
- tabContainer: this,
-
- observe: function (subject, topic, data) {
- switch (data) {
- case "browser.tabs.closeButtons":
- this.tabContainer.mCloseButtons = Services.prefs.getIntPref(data);
- this.tabContainer.adjustTabstrip();
- break;
- case "browser.tabs.autoHide":
- this.tabContainer.updateVisibility();
- break;
- case "browser.tabs.closeWindowWithLastTab":
- this.tabContainer._closeWindowWithLastTab = Services.prefs.getBoolPref(data);
- this.tabContainer.adjustTabstrip();
- break;
- }
- }
- });]]></field>
- <field name="_blockDblClick">false</field>
-
- <field name="_tabDropIndicator">
- document.getAnonymousElementByAttribute(this, "anonid", "tab-drop-indicator");
- </field>
-
- <field name="_dragOverDelay">350</field>
- <field name="_dragTime">0</field>
-
- <field name="_container" readonly="true"><![CDATA[
- this.parentNode && this.parentNode.localName == "toolbar" ? this.parentNode : this;
- ]]></field>
-
- <field name="_propagatedVisibilityOnce">false</field>
-
- <property name="visible"
- onget="return !this._container.collapsed;">
- <setter><![CDATA[
- if (val == this.visible &&
- this._propagatedVisibilityOnce)
- return val;
-
- this._container.collapsed = !val;
-
- this._propagateVisibility();
- this._propagatedVisibilityOnce = true;
-
- return val;
- ]]></setter>
- </property>
-
- <method name="_enterNewTab">
- <body><![CDATA[
- let visibleTabs = this.tabbrowser.visibleTabs;
- let candidate = visibleTabs[visibleTabs.length - 1];
- if (!candidate.selected) {
- this._beforeHoveredTab = candidate;
- candidate.setAttribute("beforehovered", "true");
- }
- ]]></body>
- </method>
-
- <method name="_leaveNewTab">
- <body><![CDATA[
- if (this._beforeHoveredTab) {
- this._beforeHoveredTab.removeAttribute("beforehovered");
- this._beforeHoveredTab = null;
- }
- ]]></body>
- </method>
-
- <method name="_propagateVisibility">
- <body><![CDATA[
- let visible = this.visible;
-
- document.getElementById("menu_closeWindow").hidden = !visible;
- document.getElementById("menu_close").setAttribute("label",
- this.tabbrowser.mStringBundle.getString(visible ? "tabs.closeTab" : "tabs.close"));
-
- goSetCommandEnabled("cmd_ToggleTabsOnTop", visible);
-
- TabsOnTop.syncUI();
-
- TabsInTitlebar.allowedBy("tabs-visible", visible);
- ]]></body>
- </method>
-
- <method name="updateVisibility">
- <body><![CDATA[
- if (this.childNodes.length - this.tabbrowser._removingTabs.length == 1)
- this.visible = window.toolbar.visible &&
- !Services.prefs.getBoolPref("browser.tabs.autoHide");
- else
- this.visible = true;
- ]]></body>
- </method>
-
- <method name="adjustTabstrip">
- <body><![CDATA[
- let numTabs = this.childNodes.length -
- this.tabbrowser._removingTabs.length;
- // modes for tabstrip
- // 0 - button on active tab only
- // 1 - close buttons on all tabs, if available space allows
- // 2 - no close buttons at all
- // 3 - close button at the end of the tabstrip
- switch (this.mCloseButtons) {
- case 0:
- // If we decide we want to hide the close tab button on the last tab
- // when closing the window with the last tab, then we should check
- // if (numTabs == 1 && this._closeWindowWithLastTab) here and set
- // this.setAttribute("closebuttons", "hidden") appropriately
- this.setAttribute("closebuttons", "activetab");
- break;
- case 1:
- if (numTabs == 1) {
- // See remark about potentially hiding the close tab button, above.
- this.setAttribute("closebuttons", "alltabs");
- } else if (numTabs == 2) {
- // This is an optimization to avoid layout flushes by calling
- // getBoundingClientRect() when we just opened a second tab. In
- // this case it's highly unlikely that the tab width is smaller
- // than mTabClipWidth and the tab close button obscures too much
- // of the tab's label. In the edge case of the window being too
- // narrow (or if tabClipWidth has been set to a way higher value),
- // we'll correct the 'closebuttons' attribute after the tabopen
- // animation has finished.
- this.setAttribute("closebuttons", "alltabs");
- } else {
- let tab = this.tabbrowser.visibleTabs[this.tabbrowser._numPinnedTabs];
- if (tab && tab.getBoundingClientRect().width > this.mTabClipWidth)
- this.setAttribute("closebuttons", "alltabs");
- else
- this.setAttribute("closebuttons", "activetab");
- }
- break;
- case 2:
- case 3:
- this.setAttribute("closebuttons", "never");
- break;
- }
- var tabstripClosebutton = document.getElementById("tabs-closebutton");
- if (tabstripClosebutton && tabstripClosebutton.parentNode == this._container)
- tabstripClosebutton.collapsed = this.mCloseButtons != 3;
- ]]></body>
- </method>
-
- <method name="_handleTabSelect">
- <parameter name="aSmoothScroll"/>
- <body><![CDATA[
- if (this.getAttribute("overflow") == "true")
- this.mTabstrip.ensureElementIsVisible(this.selectedItem, aSmoothScroll);
- ]]></body>
- </method>
-
- <method name="_fillTrailingGap">
- <body><![CDATA[
- try {
- // if we're at the right side (and not the logical end,
- // which is why this works for both LTR and RTL)
- // of the tabstrip, we need to ensure that we stay
- // completely scrolled to the right side
- var tabStrip = this.mTabstrip;
- if (tabStrip.scrollPosition + tabStrip.scrollClientSize >
- tabStrip.scrollSize)
- tabStrip.scrollByPixels(-1);
- } catch (e) {}
- ]]></body>
- </method>
-
- <field name="_closingTabsSpacer">
- document.getAnonymousElementByAttribute(this, "anonid", "closing-tabs-spacer");
- </field>
-
- <field name="_tabDefaultMaxWidth">NaN</field>
- <field name="_lastTabClosedByMouse">false</field>
- <field name="_hasTabTempMaxWidth">false</field>
-
- <!-- Try to keep the active tab's close button under the mouse cursor -->
- <method name="_lockTabSizing">
- <parameter name="aTab"/>
- <body><![CDATA[
- var tabs = this.tabbrowser.visibleTabs;
- if (!tabs.length)
- return;
-
- var isEndTab = (aTab._tPos > tabs[tabs.length-1]._tPos);
- var tabWidth = aTab.getBoundingClientRect().width;
-
- if (!this._tabDefaultMaxWidth)
- this._tabDefaultMaxWidth =
- parseFloat(window.getComputedStyle(aTab).maxWidth);
- this._lastTabClosedByMouse = true;
-
- if (this.getAttribute("overflow") == "true") {
-#ifdef XP_WIN
- // Don't need to do anything if we're in overflow mode and we're closing
- // the last tab.
- if (isEndTab)
-#else
- // Don't need to do anything if we're in overflow mode and aren't scrolled
- // all the way to the right, or if we're closing the last tab.
- if (isEndTab || !this.mTabstrip._scrollButtonDown.disabled)
-#endif
- return;
-
- // If the tab has an owner that will become the active tab, the owner will
- // be to the left of it, so we actually want the left tab to slide over.
- // This can't be done as easily in non-overflow mode, so we don't bother.
- if (aTab.owner)
- return;
-
- // Resize immediately if preffed
- // XXX: we may want to make this a three-state pref to disable this early
- // exit if people prefer a mix of behavior (don't resize in overflow,
- // but resize if not overflowing)
- if (Services.prefs.getBoolPref("browser.tabs.resize_immediately"))
- return;
-
- this._expandSpacerBy(tabWidth);
- } else { // non-overflow mode
- // Locking is neither in effect nor needed, so let tabs expand normally.
- if (isEndTab && !this._hasTabTempMaxWidth)
- return;
-
- // Resize immediately if preffed
- // XXX: we may want to make this a three-state pref to disable this early
- // exit if people prefer a mix of behavior (don't resize in overflow,
- // but resize if not overflowing)
- if (Services.prefs.getBoolPref("browser.tabs.resize_immediately"))
- return;
-
- let numPinned = this.tabbrowser._numPinnedTabs;
- // Force tabs to stay the same width, unless we're closing the last tab,
- // which case we need to let them expand just enough so that the overall
- // tabbar width is the same.
- if (isEndTab) {
- let numNormalTabs = tabs.length - numPinned;
- tabWidth = tabWidth * (numNormalTabs + 1) / numNormalTabs;
- if (tabWidth > this._tabDefaultMaxWidth)
- tabWidth = this._tabDefaultMaxWidth;
- }
- tabWidth += "px";
- for (let i = numPinned; i < tabs.length; i++) {
- let tab = tabs[i];
- tab.style.setProperty("max-width", tabWidth, "important");
- if (!isEndTab) { // keep tabs the same width
- tab.style.transition = "none";
- tab.clientTop; // flush styles to skip animation; see bug 649247
- tab.style.transition = "";
- }
- }
- this._hasTabTempMaxWidth = true;
- this.tabbrowser.addEventListener("mousemove", this, false);
- window.addEventListener("mouseout", this, false);
- }
- ]]></body>
- </method>
-
- <method name="_expandSpacerBy">
- <parameter name="pixels"/>
- <body><![CDATA[
- let spacer = this._closingTabsSpacer;
- spacer.style.width = parseFloat(spacer.style.width) + pixels + "px";
- this.setAttribute("using-closing-tabs-spacer", "true");
- this.tabbrowser.addEventListener("mousemove", this, false);
- window.addEventListener("mouseout", this, false);
- ]]></body>
- </method>
-
- <method name="_unlockTabSizing">
- <body><![CDATA[
- this.tabbrowser.removeEventListener("mousemove", this, false);
- window.removeEventListener("mouseout", this, false);
-
- if (this._hasTabTempMaxWidth) {
- this._hasTabTempMaxWidth = false;
- let tabs = this.tabbrowser.visibleTabs;
- for (let i = 0; i < tabs.length; i++)
- tabs[i].style.maxWidth = "";
- }
-
- if (this.hasAttribute("using-closing-tabs-spacer")) {
- this.removeAttribute("using-closing-tabs-spacer");
- this._closingTabsSpacer.style.width = 0;
- }
- ]]></body>
- </method>
-
- <field name="_lastNumPinned">0</field>
- <method name="_positionPinnedTabs">
- <body><![CDATA[
- var numPinned = this.tabbrowser._numPinnedTabs;
- var doPosition = this.getAttribute("overflow") == "true" &&
- numPinned > 0;
-
- if (doPosition) {
- this.setAttribute("positionpinnedtabs", "true");
-
- let scrollButtonWidth = this.mTabstrip._scrollButtonDown.getBoundingClientRect().width;
- let paddingStart = this.mTabstrip.scrollboxPaddingStart;
- let width = 0;
-
- for (let i = numPinned - 1; i >= 0; i--) {
- let tab = this.childNodes[i];
- width += tab.getBoundingClientRect().width;
- tab.style.MozMarginStart = - (width + scrollButtonWidth + paddingStart) + "px";
- }
-
- this.style.MozPaddingStart = width + paddingStart + "px";
-
- } else {
- this.removeAttribute("positionpinnedtabs");
-
- for (let i = 0; i < numPinned; i++) {
- let tab = this.childNodes[i];
- tab.style.MozMarginStart = "";
- }
-
- this.style.MozPaddingStart = "";
- }
-
- if (this._lastNumPinned != numPinned) {
- this._lastNumPinned = numPinned;
- this._handleTabSelect(false);
- }
- ]]></body>
- </method>
-
- <method name="_animateTabMove">
- <parameter name="event"/>
- <body><![CDATA[
- let draggedTab = event.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
-
- if (this.getAttribute("movingtab") != "true") {
- this.setAttribute("movingtab", "true");
- this.selectedItem = draggedTab;
- }
-
- if (!("animLastScreenX" in draggedTab._dragData))
- draggedTab._dragData.animLastScreenX = draggedTab._dragData.screenX;
-
- let screenX = event.screenX;
- if (screenX == draggedTab._dragData.animLastScreenX)
- return;
-
- let draggingRight = screenX > draggedTab._dragData.animLastScreenX;
- draggedTab._dragData.animLastScreenX = screenX;
-
- let rtl = (window.getComputedStyle(this).direction == "rtl");
- let pinned = draggedTab.pinned;
- let numPinned = this.tabbrowser._numPinnedTabs;
- let tabs = this.tabbrowser.visibleTabs
- .slice(pinned ? 0 : numPinned,
- pinned ? numPinned : undefined);
- if (rtl)
- tabs.reverse();
- let tabWidth = draggedTab.getBoundingClientRect().width;
-
- // Move the dragged tab based on the mouse position.
-
- let leftTab = tabs[0];
- let rightTab = tabs[tabs.length - 1];
- let tabScreenX = draggedTab.boxObject.screenX;
- let translateX = screenX - draggedTab._dragData.screenX;
- if (!pinned)
- translateX += this.mTabstrip.scrollPosition - draggedTab._dragData.scrollX;
- let leftBound = leftTab.boxObject.screenX - tabScreenX;
- let rightBound = (rightTab.boxObject.screenX + rightTab.boxObject.width) -
- (tabScreenX + tabWidth);
- translateX = Math.max(translateX, leftBound);
- translateX = Math.min(translateX, rightBound);
- draggedTab.style.transform = "translateX(" + translateX + "px)";
-
- // Determine what tab we're dragging over.
- // * Point of reference is the center of the dragged tab. If that
- // point touches a background tab, the dragged tab would take that
- // tab's position when dropped.
- // * We're doing a binary search in order to reduce the amount of
- // tabs we need to check.
-
- let tabCenter = tabScreenX + translateX + tabWidth / 2;
- let newIndex = -1;
- let oldIndex = "animDropIndex" in draggedTab._dragData ?
- draggedTab._dragData.animDropIndex : draggedTab._tPos;
- let low = 0;
- let high = tabs.length - 1;
- while (low <= high) {
- let mid = Math.floor((low + high) / 2);
- if (tabs[mid] == draggedTab &&
- ++mid > high)
- break;
- let boxObject = tabs[mid].boxObject;
- let screenX = boxObject.screenX + getTabShift(tabs[mid], oldIndex);
- if (screenX > tabCenter) {
- high = mid - 1;
- } else if (screenX + boxObject.width < tabCenter) {
- low = mid + 1;
- } else {
- newIndex = tabs[mid]._tPos;
- break;
- }
- }
- if (newIndex >= oldIndex)
- newIndex++;
- if (newIndex < 0 || newIndex == oldIndex)
- return;
- draggedTab._dragData.animDropIndex = newIndex;
-
- // Shift background tabs to leave a gap where the dragged tab
- // would currently be dropped.
-
- for (let tab of tabs) {
- if (tab != draggedTab) {
- let shift = getTabShift(tab, newIndex);
- tab.style.transform = shift ? "translateX(" + shift + "px)" : "";
- }
- }
-
- function getTabShift(tab, dropIndex) {
- if (tab._tPos < draggedTab._tPos && tab._tPos >= dropIndex)
- return rtl ? -tabWidth : tabWidth;
- if (tab._tPos > draggedTab._tPos && tab._tPos < dropIndex)
- return rtl ? tabWidth : -tabWidth;
- return 0;
- }
- ]]></body>
- </method>
-
- <method name="_finishAnimateTabMove">
- <body><![CDATA[
- if (this.getAttribute("movingtab") != "true")
- return;
-
- for (let tab of this.tabbrowser.visibleTabs)
- tab.style.transform = "";
-
- this.removeAttribute("movingtab");
-
- this._handleTabSelect();
- ]]></body>
- </method>
-
- <method name="handleEvent">
- <parameter name="aEvent"/>
- <body><![CDATA[
- switch (aEvent.type) {
- case "load":
- this.updateVisibility();
- break;
- case "resize":
- if (aEvent.target != window)
- break;
-
- let sizemode = document.documentElement.getAttribute("sizemode");
- TabsInTitlebar.allowedBy("sizemode",
- sizemode == "maximized" || sizemode == "fullscreen");
-
- var width = this.mTabstrip.boxObject.width;
- if (width != this.mTabstripWidth) {
- this.adjustTabstrip();
- this._fillTrailingGap();
- this._handleTabSelect();
- this.mTabstripWidth = width;
- }
-
- this.tabbrowser.updateWindowResizers();
- break;
- case "mouseout":
- // If the "related target" (the node to which the pointer went) is not
- // a child of the current document, the mouse just left the window.
- let relatedTarget = aEvent.relatedTarget;
- if (relatedTarget && relatedTarget.ownerDocument == document)
- break;
- case "mousemove":
- if (document.getElementById("tabContextMenu").state != "open")
- this._unlockTabSizing();
- break;
- }
- ]]></body>
- </method>
-
- <field name="_animateElement">
- this.mTabstrip._scrollButtonDown;
- </field>
-
- <method name="_notifyBackgroundTab">
- <parameter name="aTab"/>
- <body><![CDATA[
- if (aTab.pinned)
- return;
-
- var scrollRect = this.mTabstrip.scrollClientRect;
- var tab = aTab.getBoundingClientRect();
-
- // Is the new tab already completely visible?
- if (scrollRect.left <= tab.left && tab.right <= scrollRect.right)
- return;
-
- if (this.mTabstrip.smoothScroll) {
- let selected = !this.selectedItem.pinned &&
- this.selectedItem.getBoundingClientRect();
-
- // Can we make both the new tab and the selected tab completely visible?
- if (!selected ||
- Math.max(tab.right - selected.left, selected.right - tab.left) <=
- scrollRect.width) {
- this.mTabstrip.ensureElementIsVisible(aTab);
- return;
- }
-
- this.mTabstrip._smoothScrollByPixels(this.mTabstrip._isRTLScrollbox ?
- selected.right - scrollRect.right :
- selected.left - scrollRect.left);
- }
-
- if (!this._animateElement.hasAttribute("notifybgtab")) {
- this._animateElement.setAttribute("notifybgtab", "true");
- setTimeout(function (ele) {
- ele.removeAttribute("notifybgtab");
- }, 150, this._animateElement);
- }
- ]]></body>
- </method>
-
- <method name="_getDragTargetTab">
- <parameter name="event"/>
- <body><![CDATA[
- let tab = event.target.localName == "tab" ? event.target : null;
- if (tab &&
- (event.type == "drop" || event.type == "dragover") &&
- event.dataTransfer.dropEffect == "link") {
- let boxObject = tab.boxObject;
- if (event.screenX < boxObject.screenX + boxObject.width * .25 ||
- event.screenX > boxObject.screenX + boxObject.width * .75)
- return null;
- }
- return tab;
- ]]></body>
- </method>
-
- <method name="_getDropIndex">
- <parameter name="event"/>
- <body><![CDATA[
- var tabs = this.childNodes;
- var tab = this._getDragTargetTab(event);
- if (window.getComputedStyle(this, null).direction == "ltr") {
- for (let i = tab ? tab._tPos : 0; i < tabs.length; i++)
- if (event.screenX < tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2)
- return i;
- } else {
- for (let i = tab ? tab._tPos : 0; i < tabs.length; i++)
- if (event.screenX > tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2)
- return i;
- }
- return tabs.length;
- ]]></body>
- </method>
-
- <method name="_setEffectAllowedForDataTransfer">
- <parameter name="event"/>
- <body><![CDATA[
- var dt = event.dataTransfer;
- // Disallow dropping multiple items
- if (dt.mozItemCount > 1)
- return dt.effectAllowed = "none";
-
- var types = dt.mozTypesAt(0);
- var sourceNode = null;
- // tabs are always added as the first type
- if (types[0] == TAB_DROP_TYPE) {
- var sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
- if (sourceNode instanceof XULElement &&
- sourceNode.localName == "tab" &&
- sourceNode.ownerDocument.defaultView instanceof ChromeWindow &&
- sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser" &&
- sourceNode.ownerDocument.defaultView.gBrowser.tabContainer == sourceNode.parentNode) {
- // Do not allow transfering a private tab to a non-private window
- // and vice versa.
- if (PrivateBrowsingUtils.isWindowPrivate(window) !=
- PrivateBrowsingUtils.isWindowPrivate(sourceNode.ownerDocument.defaultView))
- return dt.effectAllowed = "none";
-
-#ifdef XP_MACOSX
- return dt.effectAllowed = event.altKey ? "copy" : "move";
-#else
- return dt.effectAllowed = event.ctrlKey ? "copy" : "move";
-#endif
- }
- }
-
- if (browserDragAndDrop.canDropLink(event)) {
- // Here we need to do this manually
- return dt.effectAllowed = dt.dropEffect = "link";
- }
- return dt.effectAllowed = "none";
- ]]></body>
- </method>
-
- <method name="_handleNewTab">
- <parameter name="tab"/>
- <body><![CDATA[
- if (tab.parentNode != this)
- return;
- tab._fullyOpen = true;
-
- this.adjustTabstrip();
-
- if (tab.getAttribute("selected") == "true") {
- this._fillTrailingGap();
- this._handleTabSelect();
- } else {
- if (tab.hasAttribute("skipbackgroundnotify")) {
- tab.removeAttribute("skipbackgroundnotify");
- } else {
- this._notifyBackgroundTab(tab);
- }
- }
-
- // XXXmano: this is a temporary workaround for bug 345399
- // We need to manually update the scroll buttons disabled state
- // if a tab was inserted to the overflow area or removed from it
- // without any scrolling and when the tabbar has already
- // overflowed.
- this.mTabstrip._updateScrollButtonsDisabledState();
- ]]></body>
- </method>
-
- <method name="_canAdvanceToTab">
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- return !aTab.closing;
- ]]>
- </body>
- </method>
-
- <method name="_handleTabTelemetryStart">
- <parameter name="aTab"/>
- <parameter name="aURI"/>
- <body>
- <![CDATA[
- // Animation-smoothness telemetry/logging
- if (this._tabAnimationLoggingEnabled) {
- if (aURI == "about:newtab" && (aTab._tPos == 1 || aTab._tPos == 2)) {
- // Indicate newtab page animation where other tabs are unaffected
- // (for which case, the 2nd or 3rd tabs are good representatives, even if not absolute)
- aTab._recordingTabOpenPlain = true;
- }
- aTab._recordingHandle = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils)
- .startFrameTimeRecording();
- }
-
- // Overall animation duration
- aTab._animStartTime = Date.now();
- ]]>
- </body>
- </method>
-
- <method name="_handleTabTelemetryEnd">
- <parameter name="aTab"/>
- <body>
- <![CDATA[
- if (!aTab._animStartTime) {
- return;
- }
-
- aTab._animStartTime = 0;
-
- // Handle tab animation smoothness telemetry/logging of frame intervals and paint times
- if (!("_recordingHandle" in aTab)) {
- return;
- }
-
- let paints = {};
- let intervals = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils)
- .stopFrameTimeRecording(aTab._recordingHandle, paints);
- delete aTab._recordingHandle;
- paints = paints.value; // The result array itself.
- let frameCount = intervals.length;
-
- if (this._tabAnimationLoggingEnabled) {
- let msg = "Tab " + (aTab.closing ? "close" : "open") + " (Frame-interval / paint-processing):\n";
- for (let i = 0; i < frameCount; i++) {
- msg += Math.round(intervals[i]) + " / " + Math.round(paints[i]) + "\n";
- }
- Services.console.logStringMessage(msg);
- }
-
- // For telemetry, the first frame interval is not useful since it may represent an interval
- // to a relatively old frame (prior to recording start). So we'll ignore it for the average.
- // But if we recorded only 1 frame (very rare), then the first paint duration is a good
- // representative of the first frame interval for our cause (indicates very bad animation).
- // First paint duration is always useful for us.
- if (frameCount > 0) {
- let averageInterval = 0;
- let averagePaint = paints[0];
- for (let i = 1; i < frameCount; i++) {
- averageInterval += intervals[i];
- averagePaint += paints[i];
- };
- averagePaint /= frameCount;
- averageInterval = (frameCount == 1)
- ? averagePaint
- : averageInterval / (frameCount - 1);
-
- if (aTab._recordingTabOpenPlain) {
- delete aTab._recordingTabOpenPlain;
- }
- }
- ]]>
- </body>
- </method>
-
- <!-- Deprecated stuff, implemented for backwards compatibility. -->
- <property name="mTabstripClosebutton" readonly="true"
- onget="return document.getElementById('tabs-closebutton');"/>
- <property name="mAllTabsPopup" readonly="true"
- onget="return document.getElementById('alltabs-popup');"/>
- </implementation>
-
- <handlers>
- <handler event="TabSelect" action="this._handleTabSelect();"/>
-
- <handler event="transitionend"><![CDATA[
- if (event.propertyName != "max-width")
- return;
-
- var tab = event.target;
-
- this._handleTabTelemetryEnd(tab);
-
- if (tab.getAttribute("fadein") == "true") {
- if (tab._fullyOpen)
- this.adjustTabstrip();
- else
- this._handleNewTab(tab);
- } else if (tab.closing) {
- this.tabbrowser._endRemoveTab(tab);
- }
- ]]></handler>
-
- <handler event="dblclick"><![CDATA[
-#ifndef XP_MACOSX
- // When the tabbar has an unified appearance with the titlebar
- // and menubar, a double-click in it should have the same behavior
- // as double-clicking the titlebar
- if (TabsInTitlebar.enabled ||
- (TabsOnTop.enabled && this.parentNode._dragBindingAlive))
- return;
-#endif
-
- if (event.button != 0 ||
- event.originalTarget.localName != "box")
- return;
-
- // See comments in the "mousedown" and "click" event handlers of the
- // tabbrowser-tabs binding.
- if (!this._blockDblClick)
- BrowserOpenTab();
-
- event.preventDefault();
- ]]></handler>
-
- <!-- Consider that the in-tab close button is only shown on the active
- tab. When clicking on an inactive tab at the position where the
- close button will appear during the click, no "click" event will be
- dispatched, because the mousedown and mouseup events don't have the
- same event target. For that reason use "mousedown" instead of "click"
- to implement in-tab close button behavior. (Pale Moon UXP issue #775)
- -->
- <handler event="mousedown" button="0" phase="capturing"><![CDATA[
- /* The only sequence in which a second click event (i.e. dblclik)
- * can be dispatched on an in-tab close button is when it is shown
- * after the first click (i.e. the first click event was dispatched
- * on the tab). This happens when we show the close button only on
- * the active tab. (bug 352021)
- * The only sequence in which a third click event can be dispatched
- * on an in-tab close button is when the tab was opened with a
- * double click on the tabbar. (bug 378344)
- * In both cases, it is most likely that the close button area has
- * been accidentally clicked, therefore we do not close the tab.
- *
- * We don't want to ignore processing of more than one click event,
- * though, since the user might actually be repeatedly clicking to
- * close many tabs at once.
- *
- * Also prevent errant doubleclick on the close button from opening
- * a new tab (bug 343628):
- * Since we're removing the event target, if the user double-clicks
- * the button, the dblclick event will be dispatched with the tabbar
- * as its event target (and explicit/originalTarget), which treats
- * that as a mouse gesture for opening a new tab.
- * In this context, we're manually blocking the dblclick event.
- */
-
- // Reset flags at the beginning of a series of clicks:
- if (event.detail == 1) {
- this.flagClickOnCloseButton = false;
- this.flagActivateTabOrClickOnTabbar = false;
- }
-
- this.blockCloseButtonOnDblclick = this.flagActivateTabOrClickOnTabbar;
- this._blockDblClick = this.flagClickOnCloseButton;
-
- // Set flags:
- let eventTargetIsCloseButton =
- event.originalTarget.classList.contains("tab-close-button");
- this.flagClickOnCloseButton = eventTargetIsCloseButton;
- this.flagActivateTabOrClickOnTabbar =
- ((!eventTargetIsCloseButton && event.detail == 1) ||
- event.originalTarget.localName == "box");
- ]]></handler>
-
- <handler event="click" button="0"><![CDATA[
- // See comment in the "mousedown" event handler of the
- // tabbrowser-tabs binding.
- if (event.originalTarget.classList.contains("tab-close-button") &&
- !this.blockCloseButtonOnDblclick) {
- gBrowser.removeTab(document.getBindingParent(event.originalTarget),
- {animate: true, byMouse: true,});
- this._blockDblClick = true;
- }
- ]]></handler>
-
- <handler event="click" button="1"><![CDATA[
- if (event.target.localName == "tab") {
- if (this.childNodes.length > 1 || !this._closeWindowWithLastTab)
- this.tabbrowser.removeTab(event.target, {animate: true, byMouse: true});
- } else if (event.originalTarget.localName == "box") {
- BrowserOpenTab();
- } else {
- return;
- }
-
- event.stopPropagation();
- ]]></handler>
-
- <handler event="keypress"><![CDATA[
- if (event.altKey || event.shiftKey ||
-#ifdef XP_MACOSX
- !event.metaKey)
-#else
- !event.ctrlKey || event.metaKey)
-#endif
- return;
-
- switch (event.keyCode) {
- case KeyEvent.DOM_VK_UP:
- this.tabbrowser.moveTabBackward();
- break;
- case KeyEvent.DOM_VK_DOWN:
- this.tabbrowser.moveTabForward();
- break;
- case KeyEvent.DOM_VK_RIGHT:
- case KeyEvent.DOM_VK_LEFT:
- this.tabbrowser.moveTabOver(event);
- break;
- case KeyEvent.DOM_VK_HOME:
- this.tabbrowser.moveTabToStart();
- break;
- case KeyEvent.DOM_VK_END:
- this.tabbrowser.moveTabToEnd();
- break;
- default:
- // Stop the keypress event for the above keyboard
- // shortcuts only.
- return;
- }
- event.stopPropagation();
- event.preventDefault();
- ]]></handler>
-
- <handler event="dragstart"><![CDATA[
- var tab = this._getDragTargetTab(event);
- if (!tab)
- return;
-
- let dt = event.dataTransfer;
- dt.mozSetDataAt(TAB_DROP_TYPE, tab, 0);
- let browser = tab.linkedBrowser;
-
- // We must not set text/x-moz-url or text/plain data here,
- // otherwise trying to deatch the tab by dropping it on the desktop
- // may result in an "internet shortcut"
- dt.mozSetDataAt("text/x-moz-text-internal", browser.currentURI.spec, 0);
-
- // Set the cursor to an arrow during tab drags.
- dt.mozCursor = "default";
-
- // Create a canvas to which we capture the current tab.
- // Until canvas is HiDPI-aware (bug 780362), we need to scale the desired
- // canvas size (in CSS pixels) to the window's backing resolution in order
- // to get a full-resolution drag image for use on HiDPI displays.
- let windowUtils = window.getInterface(Ci.nsIDOMWindowUtils);
- let scale = windowUtils.screenPixelsPerCSSPixel / windowUtils.fullZoom;
- let canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
- canvas.mozOpaque = true;
- canvas.width = 160 * scale;
- canvas.height = 90 * scale;
- PageThumbs.captureToCanvas(browser, canvas);
- dt.setDragImage(canvas, -16 * scale, -16 * scale);
-
- // _dragData.offsetX/Y give the coordinates that the mouse should be
- // positioned relative to the corner of the new window created upon
- // dragend such that the mouse appears to have the same position
- // relative to the corner of the dragged tab.
- function clientX(ele) ele.getBoundingClientRect().left;
- let tabOffsetX = clientX(tab) - clientX(this);
- tab._dragData = {
- offsetX: event.screenX - window.screenX - tabOffsetX,
- offsetY: event.screenY - window.screenY,
- scrollX: this.mTabstrip.scrollPosition,
- screenX: event.screenX
- };
-
- event.stopPropagation();
- ]]></handler>
-
- <handler event="dragover"><![CDATA[
- var effects = this._setEffectAllowedForDataTransfer(event);
-
- var ind = this._tabDropIndicator;
- if (effects == "" || effects == "none") {
- ind.collapsed = true;
- return;
- }
- event.preventDefault();
- event.stopPropagation();
-
- var tabStrip = this.mTabstrip;
- var ltr = (window.getComputedStyle(this, null).direction == "ltr");
-
- // autoscroll the tab strip if we drag over the scroll
- // buttons, even if we aren't dragging a tab, but then
- // return to avoid drawing the drop indicator
- var pixelsToScroll = 0;
- if (this.getAttribute("overflow") == "true") {
- var targetAnonid = event.originalTarget.getAttribute("anonid");
- switch (targetAnonid) {
- case "scrollbutton-up":
- pixelsToScroll = tabStrip.scrollIncrement * -1;
- break;
- case "scrollbutton-down":
- pixelsToScroll = tabStrip.scrollIncrement;
- break;
- }
- if (pixelsToScroll)
- tabStrip.scrollByPixels((ltr ? 1 : -1) * pixelsToScroll);
- }
-
- if (effects == "move" &&
- this == event.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0).parentNode) {
- ind.collapsed = true;
- this._animateTabMove(event);
- return;
- }
-
- this._finishAnimateTabMove();
-
- if (effects == "link") {
- let tab = this._getDragTargetTab(event);
- if (tab) {
- if (!this._dragTime)
- this._dragTime = Date.now();
- if (Date.now() >= this._dragTime + this._dragOverDelay)
- this.selectedItem = tab;
- ind.collapsed = true;
- return;
- }
- }
-
- var rect = tabStrip.getBoundingClientRect();
- var newMargin;
- if (pixelsToScroll) {
- // if we are scrolling, put the drop indicator at the edge
- // so that it doesn't jump while scrolling
- let scrollRect = tabStrip.scrollClientRect;
- let minMargin = scrollRect.left - rect.left;
- let maxMargin = Math.min(minMargin + scrollRect.width,
- scrollRect.right);
- if (!ltr)
- [minMargin, maxMargin] = [this.clientWidth - maxMargin,
- this.clientWidth - minMargin];
- newMargin = (pixelsToScroll > 0) ? maxMargin : minMargin;
- }
- else {
- let newIndex = this._getDropIndex(event);
- if (newIndex == this.childNodes.length) {
- let tabRect = this.childNodes[newIndex-1].getBoundingClientRect();
- if (ltr)
- newMargin = tabRect.right - rect.left;
- else
- newMargin = rect.right - tabRect.left;
- }
- else {
- let tabRect = this.childNodes[newIndex].getBoundingClientRect();
- if (ltr)
- newMargin = tabRect.left - rect.left;
- else
- newMargin = rect.right - tabRect.right;
- }
- }
-
- ind.collapsed = false;
-
- newMargin += ind.clientWidth / 2;
- if (!ltr)
- newMargin *= -1;
-
- ind.style.transform = "translate(" + Math.round(newMargin) + "px)";
- ind.style.MozMarginStart = (-ind.clientWidth) + "px";
- ]]></handler>
-
- <handler event="drop"><![CDATA[
- var dt = event.dataTransfer;
- var dropEffect = dt.dropEffect;
- var draggedTab;
- if (dropEffect != "link") { // copy or move
- draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
- // not our drop then
- if (!draggedTab)
- return;
- }
-
- this._tabDropIndicator.collapsed = true;
- event.stopPropagation();
- if (draggedTab && dropEffect == "copy") {
- // copy the dropped tab (wherever it's from)
- let newIndex = this._getDropIndex(event);
- let newTab = this.tabbrowser.duplicateTab(draggedTab);
- this.tabbrowser.moveTabTo(newTab, newIndex);
- if (draggedTab.parentNode != this || event.shiftKey)
- this.selectedItem = newTab;
- } else if (draggedTab && draggedTab.parentNode == this) {
- this._finishAnimateTabMove();
-
- // actually move the dragged tab
- if ("animDropIndex" in draggedTab._dragData) {
- let newIndex = draggedTab._dragData.animDropIndex;
- if (newIndex > draggedTab._tPos)
- newIndex--;
- this.tabbrowser.moveTabTo(draggedTab, newIndex);
- }
- } else if (draggedTab) {
- // swap the dropped tab with a new one we create and then close
- // it in the other window (making it seem to have moved between
- // windows)
- let newIndex = this._getDropIndex(event);
- let newTab = this.tabbrowser.addTab("about:blank");
- let newBrowser = this.tabbrowser.getBrowserForTab(newTab);
- // Stop the about:blank load
- newBrowser.stop();
- // make sure it has a docshell
- newBrowser.docShell;
-
- let numPinned = this.tabbrowser._numPinnedTabs;
- if (newIndex < numPinned || draggedTab.pinned && newIndex == numPinned)
- this.tabbrowser.pinTab(newTab);
- this.tabbrowser.moveTabTo(newTab, newIndex);
-
- // We need to select the tab before calling swapBrowsersAndCloseOther
- // so that window.content in chrome windows points to the right tab
- // when pagehide/show events are fired.
- this.tabbrowser.selectedTab = newTab;
-
- draggedTab.parentNode._finishAnimateTabMove();
- this.tabbrowser.swapBrowsersAndCloseOther(newTab, draggedTab);
-
- // Call updateCurrentBrowser to make sure the URL bar is up to date
- // for our new tab after we've done swapBrowsersAndCloseOther.
- this.tabbrowser.updateCurrentBrowser(true);
- } else {
- // Pass true to disallow dropping javascript: or data: urls
- let links;
- try {
- links = browserDragAndDrop.dropLinks(event, true);
- } catch (ex) {}
-
-// // valid urls don't contain spaces ' '; if we have a space it isn't a valid url.
-// if (!url || url.includes(" ")) //PMed
- if (!links || links.length === 0) //FF
- return;
-
- let inBackground = Services.prefs.getBoolPref("browser.tabs.loadInBackground");
-
- if (event.shiftKey)
- inBackground = !inBackground;
-
- let targetTab = this._getDragTargetTab(event);
- let replace = !(!targetTab || dropEffect == "copy");
- let newIndex = this._getDropIndex(event);
- let urls = links.map(link => link.url);
- this.tabbrowser.loadTabs(urls, {
- inBackground,
- replace,
- allowThirdPartyFixup: true,
- targetTab,
- newIndex,
- });
- }
-
- if (draggedTab) {
- delete draggedTab._dragData;
- }
- ]]></handler>
-
- <handler event="dragend"><![CDATA[
- // Note: while this case is correctly handled here, this event
- // isn't dispatched when the tab is moved within the tabstrip,
- // see bug 460801.
-
- this._finishAnimateTabMove();
-
- var dt = event.dataTransfer;
- var draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
- if (dt.mozUserCancelled || dt.dropEffect != "none") {
- delete draggedTab._dragData;
- return;
- }
-
- // Disable detach within the browser toolbox
- var eX = event.screenX;
- var eY = event.screenY;
- var wX = window.screenX;
- // check if the drop point is horizontally within the window
- if (eX > wX && eX < (wX + window.outerWidth)) {
- let bo = this.mTabstrip.boxObject;
- // also avoid detaching if the the tab was dropped too close to
- // the tabbar (half a tab)
- let endScreenY = bo.screenY + 1.5 * bo.height;
- if (eY < endScreenY && eY > window.screenY)
- return;
- }
-
- // screen.availLeft et. al. only check the screen that this window is on,
- // but we want to look at the screen the tab is being dropped onto.
- var sX = {}, sY = {}, sWidth = {}, sHeight = {};
- Cc["@mozilla.org/gfx/screenmanager;1"]
- .getService(Ci.nsIScreenManager)
- .screenForRect(eX, eY, 1, 1)
- .GetAvailRect(sX, sY, sWidth, sHeight);
- // ensure new window entirely within screen
- var winWidth = Math.min(window.outerWidth, sWidth.value);
- var winHeight = Math.min(window.outerHeight, sHeight.value);
- var left = Math.min(Math.max(eX - draggedTab._dragData.offsetX, sX.value),
- sX.value + sWidth.value - winWidth);
- var top = Math.min(Math.max(eY - draggedTab._dragData.offsetY, sY.value),
- sY.value + sHeight.value - winHeight);
-
- delete draggedTab._dragData;
-
- if (this.tabbrowser.tabs.length == 1) {
- // resize _before_ move to ensure the window fits the new screen. if
- // the window is too large for its screen, the window manager may do
- // automatic repositioning.
- window.resizeTo(winWidth, winHeight);
- window.moveTo(left, top);
- window.focus();
- } else {
- this.tabbrowser.replaceTabWithWindow(draggedTab, { screenX: left,
- screenY: top,
-#ifndef XP_WIN
- outerWidth: winWidth,
- outerHeight: winHeight
-#endif
- });
- }
- event.stopPropagation();
- ]]></handler>
-
- <handler event="dragexit"><![CDATA[
- this._dragTime = 0;
-
- // This does not work at all (see bug 458613)
- var target = event.relatedTarget;
- while (target && target != this)
- target = target.parentNode;
- if (target)
- return;
-
- this._tabDropIndicator.collapsed = true;
- event.stopPropagation();
- ]]></handler>
- </handlers>
- </binding>
-
- <!-- close-tab-button binding
- This binding relies on the structure of the tabbrowser binding.
- Therefore it should only be used as a child of the tab or the tabs
- element (in both cases, when they are anonymous nodes of <tabbrowser>).
- -->
- <binding id="tabbrowser-close-tab-button"
- extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image">
- <handlers>
- <handler event="dragstart">
- event.stopPropagation();
- </handler>
- </handlers>
- </binding>
-
- <binding id="tabbrowser-tab" display="xul:hbox"
- extends="chrome://global/content/bindings/tabbox.xml#tab">
- <resources>
- <stylesheet src="chrome://browser/content/tabbrowser.css"/>
- </resources>
-
- <content context="tabContextMenu" closetabtext="&closeTab.label;">
- <xul:stack class="tab-stack" flex="1">
- <xul:hbox xbl:inherits="pinned,selected,titlechanged"
- class="tab-background">
- <xul:hbox xbl:inherits="pinned,selected,titlechanged"
- class="tab-background-start"/>
- <xul:hbox xbl:inherits="pinned,selected,titlechanged"
- class="tab-background-middle"/>
- <xul:hbox xbl:inherits="pinned,selected,titlechanged"
- class="tab-background-end"/>
- </xul:hbox>
- <xul:hbox xbl:inherits="pinned,selected,titlechanged"
- class="tab-content" align="center">
- <xul:image xbl:inherits="fadein,pinned,busy,progress,selected"
- class="tab-throbber"
- role="presentation"
- layer="true" />
- <xul:image xbl:inherits="validate,src=image,fadein,pinned,selected"
- class="tab-icon-image"
- role="presentation"
- anonid="tab-icon"/>
- <xul:image xbl:inherits="busy,soundplaying,soundplaying-scheduledremoval,pinned,muted,blocked,selected"
- anonid="overlay-icon"
- class="tab-icon-overlay"
- role="presentation"/>
- <xul:label flex="1"
- xbl:inherits="value=label,crop,accesskey,fadein,pinned,selected"
- class="tab-text tab-label"
- role="presentation"/>
- <xul:image xbl:inherits="soundplaying,soundplaying-scheduledremoval,pinned,muted,blocked,selected"
- anonid="soundplaying-icon"
- class="tab-icon-sound"
- role="presentation"/>
- <xul:toolbarbutton anonid="close-button"
- xbl:inherits="fadein,pinned,selected"
- class="tab-close-button close-icon"/>
- </xul:hbox>
- </xul:stack>
- </content>
-
- <implementation>
- <property name="pinned" readonly="true">
- <getter>
- return this.getAttribute("pinned") == "true";
- </getter>
- </property>
- <property name="hidden" readonly="true">
- <getter>
- return this.getAttribute("hidden") == "true";
- </getter>
- </property>
-
- <field name="mOverCloseButton">false</field>
- <property name="_overPlayingIcon" readonly="true">
- <getter><![CDATA[
- let iconVisible = this.hasAttribute("soundplaying") ||
- this.hasAttribute("muted") ||
- this.hasAttribute("blocked");
- let soundPlayingIcon =
- document.getAnonymousElementByAttribute(this, "anonid", "soundplaying-icon");
- let overlayIcon =
- document.getAnonymousElementByAttribute(this, "anonid", "overlay-icon");
-
- return soundPlayingIcon && soundPlayingIcon.matches(":hover") ||
- (overlayIcon && overlayIcon.matches(":hover") && iconVisible);
- ]]></getter>
- </property>
- <field name="mCorrespondingMenuitem">null</field>
- <field name="closing">false</field>
- <field name="lastAccessed">0</field>
-
- <method name="toggleMuteAudio">
- <parameter name="aMuteReason"/>
- <body>
- <![CDATA[
- let tabContainer = this.parentNode;
- let browser = this.linkedBrowser;
- let modifiedAttrs = [];
- if (browser.audioBlocked) {
- this.removeAttribute("blocked");
- modifiedAttrs.push("blocked");
-
- // We don't want sound icon flickering between "blocked", "none" and
- // "sound-playing", here adding the "soundplaying" is to keep the
- // transition smoothly.
- if (!this.hasAttribute("soundplaying")) {
- this.setAttribute("soundplaying", true);
- modifiedAttrs.push("soundplaying");
- }
-
- browser.resumeMedia();
- } else {
- if (browser.audioMuted) {
- browser.unmute();
- this.removeAttribute("muted");
- } else {
- browser.mute();
- this.setAttribute("muted", "true");
- }
- this.muteReason = aMuteReason || null;
- modifiedAttrs.push("muted");
- }
- tabContainer.tabbrowser._tabAttrModified(this, modifiedAttrs);
- ]]>
- </body>
- </method>
- </implementation>
-
- <handlers>
- <handler event="mouseover"><![CDATA[
- let anonid = event.originalTarget.getAttribute("anonid");
- if (anonid == "close-button")
- this.mOverCloseButton = true;
-
- let tab = event.target;
- if (tab.closing)
- return;
-
- let tabContainer = this.parentNode;
- let visibleTabs = tabContainer.tabbrowser.visibleTabs;
- let tabIndex = visibleTabs.indexOf(tab);
- if (tabIndex == 0) {
- tabContainer._beforeHoveredTab = null;
- } else {
- let candidate = visibleTabs[tabIndex - 1];
- if (!candidate.selected) {
- tabContainer._beforeHoveredTab = candidate;
- candidate.setAttribute("beforehovered", "true");
- }
- }
-
- if (tabIndex == visibleTabs.length - 1) {
- tabContainer._afterHoveredTab = null;
- } else {
- let candidate = visibleTabs[tabIndex + 1];
- if (!candidate.selected) {
- tabContainer._afterHoveredTab = candidate;
- candidate.setAttribute("afterhovered", "true");
- }
- }
- ]]></handler>
- <handler event="mouseout"><![CDATA[
- let anonid = event.originalTarget.getAttribute("anonid");
- if (anonid == "close-button")
- this.mOverCloseButton = false;
-
- let tabContainer = this.parentNode;
- if (tabContainer._beforeHoveredTab) {
- tabContainer._beforeHoveredTab.removeAttribute("beforehovered");
- tabContainer._beforeHoveredTab = null;
- }
- if (tabContainer._afterHoveredTab) {
- tabContainer._afterHoveredTab.removeAttribute("afterhovered");
- tabContainer._afterHoveredTab = null;
- }
- ]]></handler>
- <handler event="dragstart" phase="capturing">
- this.style.MozUserFocus = '';
- </handler>
- <handler event="mousedown" phase="capturing">
- <![CDATA[
- if (this.selected) {
- this.style.MozUserFocus = 'ignore';
- this.clientTop; // just using this to flush style updates
- } else if (this.mOverCloseButton ||
- this._overPlayingIcon) {
- // Prevent tabbox.xml from selecting the tab.
- event.stopPropagation();
- }
- ]]>
- </handler>
- <handler event="mouseup">
- this.style.MozUserFocus = '';
- </handler>
- <handler event="click">
- <![CDATA[
- if (event.button != 0) {
- return;
- }
-
- if (this._overPlayingIcon) {
- this.toggleMuteAudio();
- }
- ]]>
- </handler>
- </handlers>
- </binding>
-
- <binding id="tabbrowser-alltabs-popup"
- extends="chrome://global/content/bindings/popup.xml#popup">
- <implementation implements="nsIDOMEventListener">
- <method name="_tabOnAttrModified">
- <parameter name="aEvent"/>
- <body><![CDATA[
- var tab = aEvent.target;
- if (tab.mCorrespondingMenuitem)
- this._setMenuitemAttributes(tab.mCorrespondingMenuitem, tab);
- ]]></body>
- </method>
-
- <method name="_tabOnTabClose">
- <parameter name="aEvent"/>
- <body><![CDATA[
- var tab = aEvent.target;
- if (tab.mCorrespondingMenuitem)
- this.removeChild(tab.mCorrespondingMenuitem);
- ]]></body>
- </method>
-
- <method name="handleEvent">
- <parameter name="aEvent"/>
- <body><![CDATA[
- switch (aEvent.type) {
- case "TabAttrModified":
- this._tabOnAttrModified(aEvent);
- break;
- case "TabClose":
- this._tabOnTabClose(aEvent);
- break;
- case "scroll":
- this._updateTabsVisibilityStatus();
- break;
- }
- ]]></body>
- </method>
-
- <method name="_updateTabsVisibilityStatus">
- <body><![CDATA[
- var tabContainer = gBrowser.tabContainer;
- // We don't want menu item decoration unless there is overflow.
- if (tabContainer.getAttribute("overflow") != "true")
- return;
-
- var tabstripBO = tabContainer.mTabstrip.scrollBoxObject;
- for (var i = 0; i < this.childNodes.length; i++) {
- let curTab = this.childNodes[i].tab;
- let curTabBO = curTab.boxObject;
- if (curTabBO.screenX >= tabstripBO.screenX &&
- curTabBO.screenX + curTabBO.width <= tabstripBO.screenX + tabstripBO.width)
- this.childNodes[i].setAttribute("tabIsVisible", "true");
- else
- this.childNodes[i].removeAttribute("tabIsVisible");
- }
- ]]></body>
- </method>
-
- <method name="_createTabMenuItem">
- <parameter name="aTab"/>
- <body><![CDATA[
- var menuItem = document.createElementNS(
- "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
- "menuitem");
-
- menuItem.setAttribute("class", "menuitem-iconic alltabs-item menuitem-with-favicon");
-
- this._setMenuitemAttributes(menuItem, aTab);
-
- if (!aTab.mCorrespondingMenuitem) {
- aTab.mCorrespondingMenuitem = menuItem;
- menuItem.tab = aTab;
-
- this.appendChild(menuItem);
- }
- ]]></body>
- </method>
-
- <method name="_setMenuitemAttributes">
- <parameter name="aMenuitem"/>
- <parameter name="aTab"/>
- <body><![CDATA[
- aMenuitem.setAttribute("label", aTab.label);
- aMenuitem.setAttribute("crop", aTab.getAttribute("crop"));
-
- if (aTab.hasAttribute("busy")) {
- aMenuitem.setAttribute("busy", aTab.getAttribute("busy"));
- aMenuitem.removeAttribute("image");
- } else {
- aMenuitem.setAttribute("image", aTab.getAttribute("image"));
- aMenuitem.removeAttribute("busy");
- }
-
- if (aTab.hasAttribute("pending"))
- aMenuitem.setAttribute("pending", aTab.getAttribute("pending"));
- else
- aMenuitem.removeAttribute("pending");
-
- if (aTab.selected)
- aMenuitem.setAttribute("selected", "true");
- else
- aMenuitem.removeAttribute("selected");
-
- function addEndImage() {
- let endImage = document.createElement("image");
- endImage.setAttribute("class", "allTabs-endimage");
- let endImageContainer = document.createElement("hbox");
- endImageContainer.setAttribute("align", "center");
- endImageContainer.setAttribute("pack", "center");
- endImageContainer.appendChild(endImage);
- aMenuitem.appendChild(endImageContainer);
- return endImage;
- }
-
- if (aMenuitem.firstChild)
- aMenuitem.firstChild.remove();
- if (aTab.hasAttribute("muted"))
- addEndImage().setAttribute("muted", "true");
- else if (aTab.hasAttribute("soundplaying"))
- addEndImage().setAttribute("soundplaying", "true");
- ]]></body>
- </method>
- </implementation>
-
- <handlers>
- <handler event="popupshowing">
- <![CDATA[
- var tabcontainer = gBrowser.tabContainer;
-
- // Listen for changes in the tab bar.
- tabcontainer.addEventListener("TabAttrModified", this, false);
- tabcontainer.addEventListener("TabClose", this, false);
- tabcontainer.mTabstrip.addEventListener("scroll", this, false);
-
- let tabs = gBrowser.visibleTabs;
- for (var i = 0; i < tabs.length; i++) {
- if (!tabs[i].pinned)
- this._createTabMenuItem(tabs[i]);
- }
- this._updateTabsVisibilityStatus();
- ]]></handler>
-
- <handler event="popuphidden">
- <![CDATA[
- // clear out the menu popup and remove the listeners
- for (let i = this.childNodes.length - 1; i >= 0; i--) {
- let menuItem = this.childNodes[i];
- if (menuItem.tab) {
- menuItem.tab.mCorrespondingMenuitem = null;
- this.removeChild(menuItem);
- }
- }
- var tabcontainer = gBrowser.tabContainer;
- tabcontainer.mTabstrip.removeEventListener("scroll", this, false);
- tabcontainer.removeEventListener("TabAttrModified", this, false);
- tabcontainer.removeEventListener("TabClose", this, false);
- ]]></handler>
-
- <handler event="DOMMenuItemActive">
- <![CDATA[
- var tab = event.target.tab;
- if (tab) {
- let overLink = tab.linkedBrowser.currentURI.spec;
- if (overLink == "about:blank")
- overLink = "";
- XULBrowserWindow.setOverLink(overLink, null);
- }
- ]]></handler>
-
- <handler event="DOMMenuItemInactive">
- <![CDATA[
- XULBrowserWindow.setOverLink("", null);
- ]]></handler>
-
- <handler event="command"><![CDATA[
- if (event.target.tab)
- gBrowser.selectedTab = event.target.tab;
- ]]></handler>
-
- </handlers>
- </binding>
-
- <binding id="statuspanel" display="xul:hbox">
- <content>
- <xul:hbox class="statuspanel-inner">
- <xul:label class="statuspanel-label"
- role="status"
- aria-live="off"
- xbl:inherits="value=label,crop,mirror"
- flex="1"
- crop="end"/>
- </xul:hbox>
- </content>
-
- <implementation implements="nsIDOMEventListener">
- <constructor><![CDATA[
- window.addEventListener("resize", this, false);
- ]]></constructor>
-
- <destructor><![CDATA[
- window.removeEventListener("resize", this, false);
- MousePosTracker.removeListener(this);
- ]]></destructor>
-
- <property name="label">
- <setter><![CDATA[
- if (!this.label) {
- this.removeAttribute("mirror");
- this.removeAttribute("sizelimit");
- }
-
- this.style.minWidth = this.getAttribute("type") == "status" &&
- this.getAttribute("previoustype") == "status"
- ? getComputedStyle(this).width : "";
-
- if (val) {
- this.setAttribute("label", val);
- this.removeAttribute("inactive");
- this._calcMouseTargetRect();
- MousePosTracker.addListener(this);
- } else {
- this.setAttribute("inactive", "true");
- MousePosTracker.removeListener(this);
- }
-
- return val;
- ]]></setter>
- <getter>
- return this.hasAttribute("inactive") ? "" : this.getAttribute("label");
- </getter>
- </property>
-
- <method name="getMouseTargetRect">
- <body><![CDATA[
- return this._mouseTargetRect;
- ]]></body>
- </method>
-
- <method name="onMouseEnter">
- <body>
- this._mirror();
- </body>
- </method>
-
- <method name="onMouseLeave">
- <body>
- this._mirror();
- </body>
- </method>
-
- <method name="handleEvent">
- <parameter name="event"/>
- <body><![CDATA[
- if (!this.label)
- return;
-
- switch (event.type) {
- case "resize":
- this._calcMouseTargetRect();
- break;
- }
- ]]></body>
- </method>
-
- <method name="_calcMouseTargetRect">
- <body><![CDATA[
- let alignRight = false;
-
- if (getComputedStyle(document.documentElement).direction == "rtl")
- alignRight = !alignRight;
-
- let rect = this.getBoundingClientRect();
- this._mouseTargetRect = {
- top: rect.top,
- bottom: rect.bottom,
- left: alignRight ? window.innerWidth - rect.width : 0,
- right: alignRight ? window.innerWidth : rect.width
- };
- ]]></body>
- </method>
-
- <method name="_mirror">
- <body>
- if (this.hasAttribute("mirror"))
- this.removeAttribute("mirror");
- else
- this.setAttribute("mirror", "true");
-
- if (!this.hasAttribute("sizelimit")) {
- this.setAttribute("sizelimit", "true");
- this._calcMouseTargetRect();
- }
- </body>
- </method>
- </implementation>
- </binding>
-
-</bindings>
diff --git a/base/content/test/general/audio.ogg b/base/content/test/general/audio.ogg
deleted file mode 100644
index 7e6ef77..0000000
--- a/base/content/test/general/audio.ogg
+++ /dev/null
Binary files differ
diff --git a/base/content/urlbarBindings.xml b/base/content/urlbarBindings.xml
deleted file mode 100644
index d2d9cc7..0000000
--- a/base/content/urlbarBindings.xml
+++ /dev/null
@@ -1,1800 +0,0 @@
-<?xml version="1.0"?>
-
-# -*- Mode: HTML -*-
-# 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/.
-
-<!DOCTYPE bindings [
-<!ENTITY % notificationDTD SYSTEM "chrome://global/locale/notification.dtd">
-%notificationDTD;
-<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
-%browserDTD;
-]>
-
-<bindings id="urlbarBindings" xmlns="http://www.mozilla.org/xbl"
- xmlns:html="http://www.w3.org/1999/xhtml"
- xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- xmlns:xbl="http://www.mozilla.org/xbl">
-
- <binding id="urlbar" extends="chrome://browser/content/autocomplete.xml#private-autocomplete">
-
- <content sizetopopup="pref">
- <xul:hbox anonid="textbox-container"
- class="private-autocomplete-textbox-container urlbar-textbox-container"
- flex="1" xbl:inherits="focused">
- <children includes="image|deck|stack|box">
- <xul:image class="private-autocomplete-icon" allowevents="true"/>
- </children>
- <xul:hbox anonid="textbox-input-box"
- class="textbox-input-box urlbar-input-box"
- flex="1" xbl:inherits="tooltiptext=inputtooltiptext">
- <children/>
- <html:input anonid="input"
- class="private-autocomplete-textbox urlbar-input textbox-input uri-element-right-align"
- allowevents="true"
- xbl:inherits="tooltiptext=inputtooltiptext,value,type,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey"/>
- </xul:hbox>
- <children includes="hbox"/>
- </xul:hbox>
- <xul:dropmarker anonid="historydropmarker"
- class="private-autocomplete-history-dropmarker urlbar-history-dropmarker"
- allowevents="true"
- xbl:inherits="open,enablehistory,parentfocused=focused"/>
- <xul:popupset anonid="popupset"
- class="private-autocomplete-result-popupset"/>
- <children includes="toolbarbutton"/>
- </content>
-
- <implementation implements="nsIObserver, nsIDOMEventListener">
- <constructor><![CDATA[
- this._prefs = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefService)
- .getBranch("browser.urlbar.");
-
- this._prefs.addObserver("", this, false);
- this.clickSelectsAll = this._prefs.getBoolPref("clickSelectsAll");
- this.doubleClickSelectsAll = this._prefs.getBoolPref("doubleClickSelectsAll");
- this.completeDefaultIndex = this._prefs.getBoolPref("autoFill");
- this.timeout = this._prefs.getIntPref("delay");
- this._formattingEnabled = this._prefs.getBoolPref("formatting.enabled");
- this._mayTrimURLs = this._prefs.getBoolPref("trimURLs");
-
- this.inputField.controllers.insertControllerAt(0, this._copyCutController);
- this.inputField.addEventListener("mousedown", this, false);
- this.inputField.addEventListener("mousemove", this, false);
- this.inputField.addEventListener("mouseout", this, false);
- this.inputField.addEventListener("overflow", this, false);
- this.inputField.addEventListener("underflow", this, false);
-
- const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- var textBox = document.getAnonymousElementByAttribute(this,
- "anonid", "textbox-input-box");
- var cxmenu = document.getAnonymousElementByAttribute(textBox,
- "anonid", "input-box-contextmenu");
- var pasteAndGo;
- cxmenu.addEventListener("popupshowing", function() {
- if (!pasteAndGo)
- return;
- var controller = document.commandDispatcher.getControllerForCommand("cmd_paste");
- var enabled = controller.isCommandEnabled("cmd_paste");
- if (enabled)
- pasteAndGo.removeAttribute("disabled");
- else
- pasteAndGo.setAttribute("disabled", "true");
- }, false);
-
- var insertLocation = cxmenu.firstChild;
- while (insertLocation.nextSibling &&
- insertLocation.getAttribute("cmd") != "cmd_paste")
- insertLocation = insertLocation.nextSibling;
- if (insertLocation) {
- pasteAndGo = document.createElement("menuitem");
- let label = Services.strings.createBundle("chrome://browser/locale/browser.properties").
- GetStringFromName("pasteAndGo.label");
- pasteAndGo.setAttribute("label", label);
- pasteAndGo.setAttribute("anonid", "paste-and-go");
- pasteAndGo.setAttribute("oncommand",
- "gURLBar.select(); goDoCommand('cmd_paste'); gURLBar.handleCommand();");
- cxmenu.insertBefore(pasteAndGo, insertLocation.nextSibling);
- }
- ]]></constructor>
-
- <destructor><![CDATA[
- this._prefs.removeObserver("", this);
- this._prefs = null;
- this.inputField.controllers.removeController(this._copyCutController);
- this.inputField.removeEventListener("mousedown", this, false);
- this.inputField.removeEventListener("mousemove", this, false);
- this.inputField.removeEventListener("mouseout", this, false);
- this.inputField.removeEventListener("overflow", this, false);
- this.inputField.removeEventListener("underflow", this, false);
- ]]></destructor>
-
- <field name="_value">""</field>
-
- <!--
- onBeforeValueGet is called by the base-binding's .value getter.
- It can return an object with a "value" property, to override the
- return value of the getter.
- -->
- <method name="onBeforeValueGet">
- <body><![CDATA[
- if (this.hasAttribute("actiontype"))
- return {value: this._value};
- return null;
- ]]></body>
- </method>
-
- <!--
- onBeforeValueSet is called by the base-binding's .value setter.
- It should return the value that the setter should use.
- -->
- <method name="onBeforeValueSet">
- <parameter name="aValue"/>
- <body><![CDATA[
- this._value = aValue;
- var returnValue = aValue;
- var action = this._parseActionUrl(aValue);
-
- if (action) {
- returnValue = action.param;
- }
-
- // Set the actiontype only if the user is not overriding actions.
- if (action && this._noActionsKeys.size == 0) {
- this.setAttribute("actiontype", action.type);
- } else {
- this.removeAttribute("actiontype");
- }
- return returnValue;
- ]]></body>
- </method>
-
- <field name="_mayTrimURLs">true</field>
- <method name="trimValue">
- <parameter name="aURL"/>
- <body><![CDATA[
- // This method must not modify the given URL such that calling
- // nsIURIFixup::createFixupURI with the result will produce a different URI.
- return this._mayTrimURLs ? trimURL(aURL) : aURL;
- ]]></body>
- </method>
-
- <field name="_formattingEnabled">true</field>
- <method name="formatValue">
- <body><![CDATA[
- if (!this._formattingEnabled || this.focused)
- return;
-
- let controller = this.editor.selectionController;
- let selection = controller.getSelection(controller.SELECTION_URLSECONDARY);
- selection.removeAllRanges();
-
- let textNode = this.editor.rootElement.firstChild;
- let value = textNode.textContent;
-
- let protocol = value.match(/^[a-z\d.+\-]+:(?=[^\d])/);
- if (protocol &&
- ["http:", "https:", "ftp:"].indexOf(protocol[0]) == -1)
- return;
- let matchedURL = value.match(/^((?:[a-z]+:\/\/)?(?:[^\/]+@)?)(.+?)(?::\d+)?(?:\/|$)/);
- if (!matchedURL)
- return;
-
- let [, preDomain, domain] = matchedURL;
- let baseDomain = domain;
- let subDomain = "";
- // getBaseDomainFromHost doesn't recognize IPv6 literals in brackets as IPs (bug 667159)
- if (domain[0] != "[") {
- try {
- baseDomain = Services.eTLD.getBaseDomainFromHost(domain);
- if (!domain.endsWith(baseDomain)) {
- // getBaseDomainFromHost converts its resultant to ACE.
- let IDNService = Cc["@mozilla.org/network/idn-service;1"]
- .getService(Ci.nsIIDNService);
- baseDomain = IDNService.convertACEtoUTF8(baseDomain);
- }
- } catch (e) {}
- }
- if (baseDomain != domain) {
- subDomain = domain.slice(0, -baseDomain.length);
- }
-
- let rangeLength = preDomain.length + subDomain.length;
- if (rangeLength) {
- let range = document.createRange();
- range.setStart(textNode, 0);
- range.setEnd(textNode, rangeLength);
- selection.addRange(range);
- }
-
- let startRest = preDomain.length + domain.length;
- if (startRest < value.length) {
- let range = document.createRange();
- range.setStart(textNode, startRest);
- range.setEnd(textNode, value.length);
- selection.addRange(range);
- }
- ]]></body>
- </method>
-
- <method name="_clearFormatting">
- <body><![CDATA[
- if (!this._formattingEnabled)
- return;
-
- let controller = this.editor.selectionController;
- let selection = controller.getSelection(controller.SELECTION_URLSECONDARY);
- selection.removeAllRanges();
- ]]></body>
- </method>
-
- <method name="handleRevert">
- <body><![CDATA[
- var isScrolling = this.popupOpen;
-
- gBrowser.userTypedValue = null;
-
- // don't revert to last valid url unless page is NOT loading
- // and user is NOT key-scrolling through autocomplete list
- if (!XULBrowserWindow.isBusy && !isScrolling) {
- URLBarSetURI();
-
- // If the value isn't empty and the urlbar has focus, select the value.
- if (this.value && this.hasAttribute("focused"))
- this.select();
- }
-
- // tell widget to revert to last typed text only if the user
- // was scrolling when they hit escape
- return !isScrolling;
- ]]></body>
- </method>
-
- <method name="handleCommand">
- <parameter name="aTriggeringEvent"/>
- <body><![CDATA[
- if (aTriggeringEvent instanceof MouseEvent && aTriggeringEvent.button == 2)
- return; // Do nothing for right clicks
-
- var url = this.value;
- var mayInheritPrincipal = false;
- var postData = null;
-
- var action = this._parseActionUrl(url);
- let lastLocationChange = gBrowser.selectedBrowser.lastLocationChange;
-
- let matchLastLocationChange = true;
- if (action) {
- url = action.param;
- if (this.hasAttribute("actiontype")) {
- if (action.type == "switchtab") {
- this.handleRevert();
- let prevTab = gBrowser.selectedTab;
- if (switchToTabHavingURI(url) &&
- isTabEmpty(prevTab))
- gBrowser.removeTab(prevTab);
- }
- return;
- }
- continueOperation.call(this);
- }
- else {
- this._canonizeURL(aTriggeringEvent, response => {
- [url, postData, mayInheritPrincipal] = response;
- if (url) {
- matchLastLocationChange = (lastLocationChange ==
- gBrowser.selectedBrowser.lastLocationChange);
- continueOperation.call(this);
- }
- });
- }
-
- function continueOperation()
- {
- this.value = url;
- gBrowser.userTypedValue = url;
- try {
- addToUrlbarHistory(url);
- } catch (ex) {
- // Things may go wrong when adding url to session history,
- // but don't let that interfere with the loading of the url.
- Cu.reportError(ex);
- }
-
- // Reset DOS mitigations for the basic auth prompt.
- let browser = gBrowser.selectedBrowser;
- delete browser.authPromptCounter;
-
- function loadCurrent() {
- let flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
- // Pass LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL to prevent any loads from
- // inheriting the currently loaded document's principal, unless this
- // URL is marked as safe to inherit (e.g. came from a bookmark
- // keyword).
- if (!mayInheritPrincipal)
- flags |= Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL;
- // If the value wasn't typed, we know that we decoded the value as
- // UTF-8 (see losslessDecodeURI)
- if (!this.valueIsTyped)
- flags |= Ci.nsIWebNavigation.LOAD_FLAGS_URI_IS_UTF8;
- gBrowser.loadURIWithFlags(url, flags, null, null, postData);
- }
-
- // Focus the content area before triggering loads, since if the load
- // occurs in a new tab, we want focus to be restored to the content
- // area when the current tab is re-selected.
- gBrowser.selectedBrowser.focus();
-
- let isMouseEvent = aTriggeringEvent instanceof MouseEvent;
-
- // If the current tab is empty, ignore Alt+Enter (just reuse this tab)
- let altEnter = !isMouseEvent && aTriggeringEvent &&
- aTriggeringEvent.altKey && !isTabEmpty(gBrowser.selectedTab);
-
- if (isMouseEvent || altEnter) {
- // Use the standard UI link behaviors for clicks or Alt+Enter
- let where = "tab";
- if (isMouseEvent)
- where = whereToOpenLink(aTriggeringEvent, false, false);
-
- if (where == "current") {
- if (matchLastLocationChange) {
- loadCurrent();
- }
- } else {
- this.handleRevert();
- let params = { allowThirdPartyFixup: true,
- postData: postData,
- initiatingDoc: document };
- if (!this.valueIsTyped)
- params.isUTF8 = true;
- openUILinkIn(url, where, params);
- }
- } else {
- if (matchLastLocationChange) {
- loadCurrent();
- }
- }
- }
- ]]></body>
- </method>
-
- <method name="_canonizeURL">
- <parameter name="aTriggeringEvent"/>
- <parameter name="aCallback"/>
- <body><![CDATA[
- var url = this.value;
- if (!url) {
- aCallback(["", null, false]);
- return;
- }
-
- // Only add the suffix when the URL bar value isn't already "URL-like",
- // and only if we get a keyboard event, to match user expectations.
- if (/^\s*[^.:\/\s]+(?:\/.*|\s*)$/i.test(url) &&
- (aTriggeringEvent instanceof KeyEvent)) {
-#ifdef XP_MACOSX
- let accel = aTriggeringEvent.metaKey;
-#else
- let accel = aTriggeringEvent.ctrlKey;
-#endif
- let shift = aTriggeringEvent.shiftKey;
-
- let suffix = "";
-
- switch (true) {
- case (accel && shift):
- suffix = ".org/";
- break;
- case (shift):
- suffix = ".net/";
- break;
- case (accel):
- try {
- suffix = gPrefService.getCharPref("browser.fixup.alternate.suffix");
- if (suffix.charAt(suffix.length - 1) != "/")
- suffix += "/";
- } catch(e) {
- suffix = ".com/";
- }
- break;
- }
-
- if (suffix) {
- // trim leading/trailing spaces (bug 233205)
- url = url.trim();
-
- // Tack www. and suffix on. If user has appended directories, insert
- // suffix before them (bug 279035). Be careful not to get two slashes.
-
- let firstSlash = url.indexOf("/");
-
- if (firstSlash >= 0) {
- url = url.substring(0, firstSlash) + suffix +
- url.substring(firstSlash + 1);
- } else {
- url = url + suffix;
- }
-
- url = "http://www." + url;
- }
- }
-
- getShortcutOrURIAndPostData(url).then(data => {
- aCallback([data.url, data.postData, data.mayInheritPrincipal]);
- });
- ]]></body>
- </method>
-
- <field name="_contentIsCropped">false</field>
-
- <method name="_initURLTooltip">
- <body><![CDATA[
- if (this.focused || !this._contentIsCropped)
- return;
- this.inputField.setAttribute("tooltiptext", this.value);
- ]]></body>
- </method>
-
- <method name="_hideURLTooltip">
- <body><![CDATA[
- this.inputField.removeAttribute("tooltiptext");
- ]]></body>
- </method>
-
- <method name="onDragOver">
- <parameter name="aEvent"/>
- <body>
- var types = aEvent.dataTransfer.types;
- if (types.contains("application/x-moz-file") ||
- types.contains("text/x-moz-url") ||
- types.contains("text/uri-list") ||
- types.contains("text/unicode"))
- aEvent.preventDefault();
- </body>
- </method>
-
- <method name="onDrop">
- <parameter name="aEvent"/>
- <body><![CDATA[
- let links = browserDragAndDrop.dropLinks(aEvent);
-
- // The URL bar automatically handles inputs with newline characters,
- // so we can get away with treating text/x-moz-url flavours as text/plain.
- if (links.length > 0 && links[0].url) {
- let url = links[0].url;
- aEvent.preventDefault();
- this.value = url;
- SetPageProxyState("invalid");
- this.focus();
- try {
- urlSecurityCheck(url,
- gBrowser.contentPrincipal,
- Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
- } catch (ex) {
- return;
- }
- this.handleCommand();
- // Force not showing the dropped URI immediately.
- gBrowser.userTypedValue = null;
- URLBarSetURI();
- }
- ]]></body>
- </method>
-
- <method name="_getSelectedValueForClipboard">
- <body><![CDATA[
- // Grab the actual input field's value, not our value, which could include moz-action:
- var inputVal = this.inputField.value;
- var selectedVal = inputVal.substring(this.selectionStart, this.selectionEnd);
-
- // If the selection doesn't start at the beginning or doesn't span the full domain or
- // the URL bar is modified, nothing else to do here.
- if (this.selectionStart > 0 || this.valueIsTyped)
- return selectedVal;
- // The selection doesn't span the full domain if it doesn't contain a slash and is
- // followed by some character other than a slash.
- if (!selectedVal.includes("/")) {
- let remainder = inputVal.replace(selectedVal, "");
- if (remainder != "" && remainder[0] != "/")
- return selectedVal;
- }
-
- let uriFixup = Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci.nsIURIFixup);
-
- let uri;
- try {
- uri = uriFixup.createFixupURI(inputVal, Ci.nsIURIFixup.FIXUP_FLAG_NONE);
- } catch (e) {}
- if (!uri)
- return selectedVal;
-
- // Only copy exposable URIs
- try {
- uri = uriFixup.createExposableURI(uri);
- } catch (ex) {}
-
- // If the entire URL is selected, just use the actual loaded URI.
- if (inputVal == selectedVal) {
- // ... but only if isn't a javascript: or data: URI, since those
- // are hard to read when encoded
- if (!uri.schemeIs("javascript") && !uri.schemeIs("data")) {
- // Parentheses are known to confuse third-party applications (bug 458565).
- selectedVal = uri.spec.replace(/[()]/g, function (c) escape(c));
- }
-
- return selectedVal;
- }
-
- // Just the beginning of the URL is selected, check for a trimmed
- // value
- let spec = uri.spec;
- let trimmedSpec = this.trimValue(spec);
- if (spec != trimmedSpec) {
- // Prepend the portion that trimValue removed from the beginning.
- // This assumes trimValue will only truncate the URL at
- // the beginning or end (or both).
- let trimmedSegments = spec.split(trimmedSpec);
- selectedVal = trimmedSegments[0] + selectedVal;
- }
-
- return selectedVal;
- ]]></body>
- </method>
-
- <field name="_copyCutController"><![CDATA[
- ({
- urlbar: this,
- doCommand: function(aCommand) {
- var urlbar = this.urlbar;
- var val = urlbar._getSelectedValueForClipboard();
- if (!val)
- return;
-
- if (aCommand == "cmd_cut" && this.isCommandEnabled(aCommand)) {
- let start = urlbar.selectionStart;
- let end = urlbar.selectionEnd;
- urlbar.inputField.value = urlbar.inputField.value.substring(0, start) +
- urlbar.inputField.value.substring(end);
- urlbar.selectionStart = urlbar.selectionEnd = start;
- urlbar.removeAttribute("actiontype");
- SetPageProxyState("invalid");
- }
-
- Cc["@mozilla.org/widget/clipboardhelper;1"]
- .getService(Ci.nsIClipboardHelper)
- .copyString(val, document);
- },
- supportsCommand: function(aCommand) {
- switch (aCommand) {
- case "cmd_copy":
- case "cmd_cut":
- return true;
- }
- return false;
- },
- isCommandEnabled: function(aCommand) {
- return this.supportsCommand(aCommand) &&
- (aCommand != "cmd_cut" || !this.urlbar.readOnly) &&
- this.urlbar.selectionStart < this.urlbar.selectionEnd;
- },
- onEvent: function(aEventName) {}
- })
- ]]></field>
-
- <method name="observe">
- <parameter name="aSubject"/>
- <parameter name="aTopic"/>
- <parameter name="aData"/>
- <body><![CDATA[
- if (aTopic == "nsPref:changed") {
- switch (aData) {
- case "clickSelectsAll":
- case "doubleClickSelectsAll":
- this[aData] = this._prefs.getBoolPref(aData);
- break;
- case "autoFill":
- this.completeDefaultIndex = this._prefs.getBoolPref(aData);
- break;
- case "delay":
- this.timeout = this._prefs.getIntPref(aData);
- break;
- case "formatting.enabled":
- this._formattingEnabled = this._prefs.getBoolPref(aData);
- break;
- case "trimURLs":
- this._mayTrimURLs = this._prefs.getBoolPref(aData);
- break;
- }
- }
- ]]></body>
- </method>
-
- <method name="handleEvent">
- <parameter name="aEvent"/>
- <body><![CDATA[
- switch (aEvent.type) {
- case "mousedown":
- if (this.doubleClickSelectsAll &&
- aEvent.button == 0 && aEvent.detail == 2) {
- this.editor.selectAll();
- aEvent.preventDefault();
- }
- break;
- case "mousemove":
- this._initURLTooltip();
- break;
- case "mouseout":
- this._hideURLTooltip();
- break;
- case "overflow":
- this._contentIsCropped = true;
- break;
- case "underflow":
- this._contentIsCropped = false;
- this._hideURLTooltip();
- break;
- }
- ]]></body>
- </method>
-
- <property name="textValue"
- onget="return this.value;">
- <setter>
- <![CDATA[
- try {
- val = losslessDecodeURI(makeURI(val));
- } catch (ex) { }
-
- // Trim popup selected values, but never trim results coming from
- // autofill.
- if (this.popup.selectedIndex == -1)
- this._disableTrim = true;
- this.value = val;
- this._disableTrim = false;
-
- // Completing a result should simulate the user typing the result, so
- // fire an input event.
- let evt = document.createEvent("UIEvents");
- evt.initUIEvent("input", true, false, window, 0);
- this.mIgnoreInput = true;
- this.dispatchEvent(evt);
- this.mIgnoreInput = false;
-
- return this.value;
- ]]>
- </setter>
- </property>
-
- <method name="_parseActionUrl">
- <parameter name="aUrl"/>
- <body><![CDATA[
- if (!aUrl.startsWith("moz-action:"))
- return null;
-
- // url is in the format moz-action:ACTION,PARAM
- let [, action, param] = aUrl.match(/^moz-action:([^,]+),(.*)$/);
- return {type: action, param: param};
- ]]></body>
- </method>
-
- <field name="_noActionsKeys"><![CDATA[
- new Set();
- ]]></field>
-
- <method name="_clearNoActions">
- <parameter name="aURL"/>
- <body><![CDATA[
- this._noActionsKeys.clear();
- this.popup.removeAttribute("noactions");
- let action = this._parseActionUrl(this._value);
- if (action)
- this.setAttribute("actiontype", action.type);
- ]]></body>
- </method>
- </implementation>
-
- <handlers>
- <handler event="keydown"><![CDATA[
- if ((event.keyCode === KeyEvent.DOM_VK_ALT ||
- event.keyCode === KeyEvent.DOM_VK_SHIFT) &&
- this.popup.selectedIndex >= 0 &&
- !this._noActionsKeys.has(event.keyCode)) {
- if (this._noActionsKeys.size == 0) {
- this.popup.setAttribute("noactions", "true");
- this.removeAttribute("actiontype");
- }
- this._noActionsKeys.add(event.keyCode);
- }
- ]]></handler>
-
- <handler event="keyup"><![CDATA[
- if ((event.keyCode === KeyEvent.DOM_VK_ALT ||
- event.keyCode === KeyEvent.DOM_VK_SHIFT) &&
- this._noActionsKeys.has(event.keyCode)) {
- this._noActionsKeys.delete(event.keyCode);
- if (this._noActionsKeys.size == 0)
- this._clearNoActions();
- }
- ]]></handler>
-
- <handler event="blur"><![CDATA[
- if (event.originalTarget != this.inputField)
- return;
- this._clearNoActions();
- this.formatValue();
- ]]></handler>
-
- <handler event="dragstart" phase="capturing"><![CDATA[
- // Drag only if the gesture starts from the input field.
- if (event.originalTarget != this.inputField)
- return;
-
- // Drag only if the entire value is selected and it's a valid URI.
- var isFullSelection = this.selectionStart == 0 &&
- this.selectionEnd == this.textLength;
- if (!isFullSelection ||
- this.getAttribute("pageproxystate") != "valid")
- return;
-
- var urlString = content.location.href;
- var title = content.document.title || urlString;
- var htmlString = "<a href=\"" + urlString + "\">" + urlString + "</a>";
-
- var dt = event.dataTransfer;
- dt.setData("text/x-moz-url", urlString + "\n" + title);
- dt.setData("text/unicode", urlString);
- dt.setData("text/html", htmlString);
-
- dt.effectAllowed = "copyLink";
- event.stopPropagation();
- ]]></handler>
-
- <handler event="focus" phase="capturing"><![CDATA[
- if (event.originalTarget != this.inputField)
- return;
- this._hideURLTooltip();
- this._clearFormatting();
- ]]></handler>
-
- <handler event="dragover" phase="capturing" action="this.onDragOver(event, this);"/>
- <handler event="drop" phase="capturing" action="this.onDrop(event, this);"/>
- <handler event="select"><![CDATA[
- if (!Cc["@mozilla.org/widget/clipboard;1"]
- .getService(Ci.nsIClipboard)
- .supportsSelectionClipboard())
- return;
-
- // Check if this selection was actually user-generated, and exit if not
- // to prevent copying the selection (e.g autofill) to clipboard/primary
- if (!window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils)
- .isHandlingUserInput)
- return;
-
- var val = this._getSelectedValueForClipboard();
- if (!val)
- return;
-
- Cc["@mozilla.org/widget/clipboardhelper;1"]
- .getService(Ci.nsIClipboardHelper)
- .copyStringToClipboard(val, Ci.nsIClipboard.kSelectionClipboard, document);
- ]]></handler>
- </handlers>
-
- </binding>
-
- <!-- Note: this binding is applied to the autocomplete popup used in the Search bar and in web page content -->
- <binding id="browser-autocomplete-result-popup" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-result-popup">
- <implementation>
- <method name="openAutocompletePopup">
- <parameter name="aInput"/>
- <parameter name="aElement"/>
- <body>
- <![CDATA[
- // initially the panel is hidden
- // to avoid impacting startup / new window performance
- aInput.popup.hidden = false;
-
- // this method is defined on the base binding
- this._openAutocompletePopup(aInput, aElement);
- ]]></body>
- </method>
-
- <method name="onPopupClick">
- <parameter name="aEvent"/>
- <body><![CDATA[
- // Ignore all right-clicks
- if (aEvent.button == 2)
- return;
-
- var controller = this.view.QueryInterface(Components.interfaces.nsIAutoCompleteController);
-
- // Check for unmodified left-click, and use default behavior
- if (aEvent.button == 0 && !aEvent.shiftKey && !aEvent.ctrlKey &&
- !aEvent.altKey && !aEvent.metaKey) {
- controller.handleEnter(true);
- return;
- }
-
- // Check for middle-click or modified clicks on the search bar
- var searchBar = BrowserSearch.searchBar;
- if (searchBar && searchBar.textbox == this.mInput) {
- // Handle search bar popup clicks
- var search = controller.getValueAt(this.selectedIndex);
-
- // close the autocomplete popup and revert the entered search term
- this.closePopup();
- controller.handleEscape();
-
- // Fill in the search bar's value
- searchBar.value = search;
-
- // open the search results according to the clicking subtlety
- var where = whereToOpenLink(aEvent, false, true);
- searchBar.doSearch(search, where);
- }
- ]]></body>
- </method>
- </implementation>
- </binding>
-
- <binding id="urlbar-rich-result-popup" extends="chrome://browser/content/autocomplete.xml#private-autocomplete-rich-result-popup">
- <implementation>
- <field name="_maxResults">0</field>
-
- <field name="_bundle" readonly="true">
- Cc["@mozilla.org/intl/stringbundle;1"].
- getService(Ci.nsIStringBundleService).
- createBundle("chrome://browser/locale/places/places.properties");
- </field>
-
- <property name="maxResults" readonly="true">
- <getter>
- <![CDATA[
- if (!this._maxResults) {
- var prefService =
- Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
- this._maxResults = prefService.getIntPref("browser.urlbar.maxRichResults");
- }
- return this._maxResults;
- ]]>
- </getter>
- </property>
-
- <method name="openAutocompletePopup">
- <parameter name="aInput"/>
- <parameter name="aElement"/>
- <body>
- <![CDATA[
- // initially the panel is hidden
- // to avoid impacting startup / new window performance
- aInput.popup.hidden = false;
-
- // this method is defined on the base binding
- this._openAutocompletePopup(aInput, aElement);
- ]]></body>
- </method>
-
- <method name="onPopupClick">
- <parameter name="aEvent"/>
- <body>
- <![CDATA[
- // Ignore right-clicks
- if (aEvent.button == 2)
- return;
-
- var controller = this.view.QueryInterface(Components.interfaces.nsIAutoCompleteController);
-
- // Check for unmodified left-click, and use default behavior
- if (aEvent.button == 0 && !aEvent.shiftKey && !aEvent.ctrlKey &&
- !aEvent.altKey && !aEvent.metaKey) {
- controller.handleEnter(true);
- return;
- }
-
- // Check for middle-click or modified clicks on the URL bar
- if (gURLBar && this.mInput == gURLBar) {
- var url = controller.getValueAt(this.selectedIndex);
-
- // close the autocomplete popup and revert the entered address
- this.closePopup();
- controller.handleEscape();
-
- // Check if this is meant to be an action
- let action = this.mInput._parseActionUrl(url);
- if (action) {
- if (action.type == "switchtab")
- url = action.param;
- else
- return;
- }
-
- // respect the usual clicking subtleties
- openUILink(url, aEvent);
- }
- ]]>
- </body>
- </method>
-
- <method name="createResultLabel">
- <parameter name="aTitle"/>
- <parameter name="aUrl"/>
- <parameter name="aType"/>
- <body>
- <![CDATA[
- var label = aTitle + " " + aUrl;
- // convert aType (ex: "ac-result-type-<aType>") to text to be spoke aloud
- // by screen readers. convert "tag" and "bookmark" to the localized versions,
- // but don't do anything for "favicon" (the default)
- if (aType != "favicon") {
- label += " " + this._bundle.GetStringFromName(aType + "ResultLabel");
- }
- return label;
- ]]>
- </body>
- </method>
-
- </implementation>
- </binding>
-
- <binding id="addon-progress-notification" extends="chrome://global/content/bindings/notification.xml#popup-notification">
- <content align="start">
- <xul:image class="popup-notification-icon"
- xbl:inherits="popupid,src=icon"/>
- <xul:vbox flex="1">
- <xul:description class="popup-notification-description addon-progress-description"
- xbl:inherits="xbl:text=label"/>
- <xul:spacer flex="1"/>
- <xul:hbox align="center">
- <xul:progressmeter anonid="progressmeter" flex="1" mode="undetermined" class="popup-progress-meter"/>
- <xul:button anonid="cancel" class="popup-progress-cancel" oncommand="document.getBindingParent(this).cancel()"/>
- </xul:hbox>
- <xul:label anonid="progresstext" class="popup-progress-label"/>
- <xul:hbox class="popup-notification-button-container"
- pack="end" align="center">
- <xul:button anonid="button"
- class="popup-notification-menubutton"
- type="menu-button"
- xbl:inherits="oncommand=buttoncommand,label=buttonlabel,accesskey=buttonaccesskey">
- <xul:menupopup anonid="menupopup"
- xbl:inherits="oncommand=menucommand">
- <children/>
- <xul:menuitem class="menuitem-iconic popup-notification-closeitem close-icon"
- label="&closeNotificationItem.label;"
- xbl:inherits="oncommand=closeitemcommand"/>
- </xul:menupopup>
- </xul:button>
- </xul:hbox>
- </xul:vbox>
- <xul:vbox pack="start">
- <xul:toolbarbutton anonid="closebutton"
- class="messageCloseButton close-icon popup-notification-closebutton tabbable"
- xbl:inherits="oncommand=closebuttoncommand"
- tooltiptext="&closeNotification.tooltip;"/>
- </xul:vbox>
- </content>
- <implementation>
- <constructor><![CDATA[
- this.cancelbtn.setAttribute("tooltiptext", gNavigatorBundle.getString("addonDownloadCancelTooltip"));
-
- this.notification.options.installs.forEach(function(aInstall) {
- aInstall.addListener(this);
- }, this);
-
- // Calling updateProgress can sometimes cause this notification to be
- // removed in the middle of refreshing the notification panel which
- // makes the panel get refreshed again. Just initialise to the
- // undetermined state and then schedule a proper check at the next
- // opportunity
- this.setProgress(0, -1);
- this._updateProgressTimeout = setTimeout(this.updateProgress.bind(this), 0);
- ]]></constructor>
-
- <destructor><![CDATA[
- this.destroy();
- ]]></destructor>
-
- <field name="progressmeter" readonly="true">
- document.getAnonymousElementByAttribute(this, "anonid", "progressmeter");
- </field>
- <field name="progresstext" readonly="true">
- document.getAnonymousElementByAttribute(this, "anonid", "progresstext");
- </field>
- <field name="cancelbtn" readonly="true">
- document.getAnonymousElementByAttribute(this, "anonid", "cancel");
- </field>
- <field name="DownloadUtils" readonly="true">
- {
- let utils = {};
- Components.utils.import("resource://gre/modules/DownloadUtils.jsm", utils);
- utils.DownloadUtils;
- }
- </field>
-
- <method name="destroy">
- <body><![CDATA[
- this.notification.options.installs.forEach(function(aInstall) {
- aInstall.removeListener(this);
- }, this);
- clearTimeout(this._updateProgressTimeout);
- ]]></body>
- </method>
-
- <method name="setProgress">
- <parameter name="aProgress"/>
- <parameter name="aMaxProgress"/>
- <body><![CDATA[
- if (aMaxProgress == -1) {
- this.progressmeter.mode = "undetermined";
- }
- else {
- this.progressmeter.mode = "determined";
- this.progressmeter.value = (aProgress * 100) / aMaxProgress;
- }
-
- let now = Date.now();
-
- if (!this.notification.lastUpdate) {
- this.notification.lastUpdate = now;
- this.notification.lastProgress = aProgress;
- return;
- }
-
- let delta = now - this.notification.lastUpdate;
- if ((delta < 400) && (aProgress < aMaxProgress))
- return;
-
- delta /= 1000;
-
- // This code is taken from nsDownloadManager.cpp
- let speed = (aProgress - this.notification.lastProgress) / delta;
- if (this.notification.speed)
- speed = speed * 0.9 + this.notification.speed * 0.1;
-
- this.notification.lastUpdate = now;
- this.notification.lastProgress = aProgress;
- this.notification.speed = speed;
-
- let status = null;
- [status, this.notification.last] = this.DownloadUtils.getDownloadStatus(aProgress, aMaxProgress, speed, this.notification.last);
- this.progresstext.value = status;
- ]]></body>
- </method>
-
- <method name="cancel">
- <body><![CDATA[
- // Cache these as cancelling the installs will remove this
- // notification which will drop these references
- let browser = this.notification.browser;
- let contentWindow = this.notification.options.contentWindow;
- let sourceURI = this.notification.options.sourceURI;
-
- let installs = this.notification.options.installs;
- installs.forEach(function(aInstall) {
- try {
- aInstall.cancel();
- }
- catch (e) {
- // Cancel will throw if the download has already failed
- }
- }, this);
-
- let anchorID = "addons-notification-icon";
- let notificationID = "addon-install-cancelled";
- let messageString = gNavigatorBundle.getString("addonDownloadCancelled");
- messageString = PluralForm.get(installs.length, messageString);
- let buttonText = gNavigatorBundle.getString("addonDownloadRestart");
- buttonText = PluralForm.get(installs.length, buttonText);
-
- let action = {
- label: buttonText,
- accessKey: gNavigatorBundle.getString("addonDownloadRestart.accessKey"),
- callback: function() {
- let weblistener = Cc["@mozilla.org/addons/web-install-listener;1"].
- getService(Ci.amIWebInstallListener);
- if (weblistener.onWebInstallRequested(contentWindow, sourceURI,
- installs, installs.length)) {
- installs.forEach(function(aInstall) {
- aInstall.install();
- });
- }
- }
- };
-
- PopupNotifications.show(browser, notificationID, messageString,
- anchorID, action);
- ]]></body>
- </method>
-
- <method name="updateProgress">
- <body><![CDATA[
- let downloadingCount = 0;
- let progress = 0;
- let maxProgress = 0;
-
- this.notification.options.installs.forEach(function(aInstall) {
- if (aInstall.maxProgress == -1)
- maxProgress = -1;
- progress += aInstall.progress;
- if (maxProgress >= 0)
- maxProgress += aInstall.maxProgress;
- if (aInstall.state < AddonManager.STATE_DOWNLOADED)
- downloadingCount++;
- });
-
- if (downloadingCount == 0) {
- this.destroy();
- PopupNotifications.remove(this.notification);
- }
- else {
- this.setProgress(progress, maxProgress);
- }
- ]]></body>
- </method>
-
- <method name="onDownloadProgress">
- <body><![CDATA[
- this.updateProgress();
- ]]></body>
- </method>
-
- <method name="onDownloadFailed">
- <body><![CDATA[
- this.updateProgress();
- ]]></body>
- </method>
-
- <method name="onDownloadCancelled">
- <body><![CDATA[
- this.updateProgress();
- ]]></body>
- </method>
-
- <method name="onDownloadEnded">
- <body><![CDATA[
- this.updateProgress();
- ]]></body>
- </method>
- </implementation>
- </binding>
-
- <binding id="plugin-popupnotification-center-item">
- <content align="center">
- <xul:vbox pack="center" anonid="itemBox" class="itemBox">
- <xul:description anonid="center-item-label" class="center-item-label" />
- <xul:hbox flex="1" pack="start" align="center" anonid="center-item-warning">
- <xul:image anonid="center-item-warning-icon" class="center-item-warning-icon"/>
- <xul:label anonid="center-item-warning-label"/>
- <xul:label anonid="center-item-link" value="&checkForUpdates;" class="text-link"/>
- </xul:hbox>
- </xul:vbox>
- <xul:vbox pack="center">
- <xul:menulist class="center-item-menulist"
- anonid="center-item-menulist">
- <xul:menupopup>
- <xul:menuitem anonid="allownow" value="allownow"
- label="&pluginActivateNow.label;" />
- <xul:menuitem anonid="allowalways" value="allowalways"
- label="&pluginActivateAlways.label;" />
- <xul:menuitem anonid="block" value="block"
- label="&pluginBlockNow.label;" />
- </xul:menupopup>
- </xul:menulist>
- </xul:vbox>
- </content>
- <resources>
- <stylesheet src="chrome://global/skin/notification.css"/>
- </resources>
- <implementation>
- <constructor><![CDATA[
- document.getAnonymousElementByAttribute(this, "anonid", "center-item-label").value = this.action.pluginName;
-
- let curState = "block";
- if (this.action.fallbackType == Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE) {
- if (this.action.pluginPermissionType == Ci.nsIPermissionManager.EXPIRE_SESSION) {
- curState = "allownow";
- }
- else {
- curState = "allowalways";
- }
- }
- document.getAnonymousElementByAttribute(this, "anonid", "center-item-menulist").value = curState;
-
- let warningString = "";
- let linkString = "";
-
- let link = document.getAnonymousElementByAttribute(this, "anonid", "center-item-link");
-
- let url;
- let linkHandler;
-
- if (this.action.pluginTag.enabledState == Ci.nsIPluginTag.STATE_DISABLED) {
- document.getAnonymousElementByAttribute(this, "anonid", "center-item-menulist").hidden = true;
- warningString = gNavigatorBundle.getString("pluginActivateDisabled.label");
- linkString = gNavigatorBundle.getString("pluginActivateDisabled.manage");
- linkHandler = function(event) {
- event.preventDefault();
- gPluginHandler.managePlugins();
- };
- document.getAnonymousElementByAttribute(this, "anonid", "center-item-warning-icon").hidden = true;
- }
- else {
- url = this.action.detailsLink;
-
- switch (this.action.blocklistState) {
- case Ci.nsIBlocklistService.STATE_NOT_BLOCKED:
- document.getAnonymousElementByAttribute(this, "anonid", "center-item-warning").hidden = true;
- break;
- case Ci.nsIBlocklistService.STATE_BLOCKED:
- document.getAnonymousElementByAttribute(this, "anonid", "center-item-menulist").hidden = true;
- warningString = gNavigatorBundle.getString("pluginActivateBlocked.label");
- linkString = gNavigatorBundle.getString("pluginActivate.learnMore");
- break;
- case Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE:
- warningString = gNavigatorBundle.getString("pluginActivateOutdated.label");
- linkString = gNavigatorBundle.getString("pluginActivate.updateLabel");
- break;
- case Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE:
- warningString = gNavigatorBundle.getString("pluginActivateVulnerable.label");
- linkString = gNavigatorBundle.getString("pluginActivate.riskLabel");
- break;
- }
- }
- document.getAnonymousElementByAttribute(this, "anonid", "center-item-warning-label").value = warningString;
-
- if (url || linkHandler) {
- link.value = linkString;
- if (url) {
- link.href = url;
- }
- if (linkHandler) {
- link.addEventListener("click", linkHandler, false);
- }
- }
- else {
- link.hidden = true;
- }
- ]]></constructor>
- <property name="value">
- <getter>
- return document.getAnonymousElementByAttribute(this, "anonid",
- "center-item-menulist").value;
- </getter>
- <setter><!-- This should be used only in automated tests -->
- document.getAnonymousElementByAttribute(this, "anonid",
- "center-item-menulist").value = val;
- </setter>
- </property>
- </implementation>
- </binding>
-
- <binding id="click-to-play-plugins-notification" extends="chrome://global/content/bindings/notification.xml#popup-notification">
- <content align="start" class="click-to-play-plugins-notification-content">
- <xul:vbox flex="1" align="stretch" class="popup-notification-main-box"
- xbl:inherits="popupid">
- <xul:hbox class="click-to-play-plugins-notification-description-box" flex="1" align="start">
- <xul:description class="click-to-play-plugins-outer-description" flex="1">
- <html:span anonid="click-to-play-plugins-notification-description" />
- <xul:label class="text-link click-to-play-plugins-notification-link" anonid="click-to-play-plugins-notification-link" />
- </xul:description>
- <xul:toolbarbutton anonid="closebutton"
- class="messageCloseButton close-icon popup-notification-closebutton tabbable"
- xbl:inherits="oncommand=closebuttoncommand"
- tooltiptext="&closeNotification.tooltip;"/>
- </xul:hbox>
- <xul:grid anonid="click-to-play-plugins-notification-center-box"
- class="click-to-play-plugins-notification-center-box">
- <xul:columns>
- <xul:column flex="1"/>
- <xul:column/>
- </xul:columns>
- <xul:rows>
- <children includes="row"/>
- <xul:hbox pack="start" anonid="plugin-notification-showbox">
- <xul:button label="&pluginNotification.showAll.label;"
- accesskey="&pluginNotification.showAll.accesskey;"
- class="plugin-notification-showbutton"
- oncommand="document.getBindingParent(this)._setState(2)"/>
- </xul:hbox>
- </xul:rows>
- </xul:grid>
- <xul:hbox anonid="button-container"
- class="click-to-play-plugins-notification-button-container"
- pack="center" align="center">
- <xul:button anonid="primarybutton"
- class="click-to-play-popup-button primary-button"
- oncommand="document.getBindingParent(this)._onButton(this)"
- flex="1"/>
- <xul:button anonid="secondarybutton"
- class="click-to-play-popup-button"
- oncommand="document.getBindingParent(this)._onButton(this);"
- flex="1"/>
- </xul:hbox>
- <xul:box hidden="true">
- <children/>
- </xul:box>
- </xul:vbox>
- </content>
- <resources>
- <stylesheet src="chrome://global/skin/notification.css"/>
- </resources>
- <implementation>
- <field name="_states">
- ({SINGLE: 0, MULTI_COLLAPSED: 1, MULTI_EXPANDED: 2})
- </field>
- <field name="_primaryButton">
- document.getAnonymousElementByAttribute(this, "anonid", "primarybutton");
- </field>
- <field name="_secondaryButton">
- document.getAnonymousElementByAttribute(this, "anonid", "secondarybutton")
- </field>
- <field name="_buttonContainer">
- document.getAnonymousElementByAttribute(this, "anonid", "button-container")
- </field>
- <field name="_brandShortName">
- document.getElementById("bundle_brand").getString("brandShortName")
- </field>
- <field name="_items">[]</field>
- <constructor><![CDATA[
- const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- for (let action of this.notification.options.centerActions) {
- let item = document.createElementNS(XUL_NS, "row");
- item.setAttribute("class", "plugin-popupnotification-centeritem");
- item.action = action;
- this.appendChild(item);
- this._items.push(item);
- }
- switch (this.notification.options.centerActions.length) {
- case 0:
- PopupNotifications._dismiss();
- break;
- case 1:
- this._setState(this._states.SINGLE);
- break;
- default:
- if (this.notification.options.primaryPlugin) {
- this._setState(this._states.MULTI_COLLAPSED);
- } else {
- this._setState(this._states.MULTI_EXPANDED);
- }
- }
- ]]></constructor>
- <method name="_setState">
- <parameter name="state" />
- <body><![CDATA[
- var grid = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-center-box");
-
- if (this._states.SINGLE == state) {
- grid.hidden = true;
- this._setupSingleState();
- return;
- }
-
- let prePath = this.notification.browser.contentWindow.document.nodePrincipal.URI.prePath;
- this._setupDescription("pluginActivateMultiple.message", null, prePath);
-
- var showBox = document.getAnonymousElementByAttribute(this, "anonid", "plugin-notification-showbox");
-
- var dialogStrings = Services.strings.createBundle("chrome://global/locale/dialog.properties");
- this._primaryButton.label = dialogStrings.GetStringFromName("button-accept");
- this._primaryButton.setAttribute("default", "true");
-
- this._secondaryButton.label = dialogStrings.GetStringFromName("button-cancel");
- this._primaryButton.setAttribute("action", "_multiAccept");
- this._secondaryButton.setAttribute("action", "_cancel");
-
- grid.hidden = false;
-
- if (this._states.MULTI_COLLAPSED == state) {
- for (let child of this.childNodes) {
- if (child.tagName != "row") {
- continue;
- }
- child.hidden = this.notification.options.primaryPlugin !=
- child.action.permissionString;
- }
- showBox.hidden = false;
- }
- else {
- for (let child of this.childNodes) {
- if (child.tagName != "row") {
- continue;
- }
- child.hidden = false;
- }
- showBox.hidden = true;
- }
- this._setupLink(null);
- ]]></body>
- </method>
- <method name="_setupSingleState">
- <body><![CDATA[
- var action = this.notification.options.centerActions[0];
- var prePath = action.pluginPermissionPrePath;
-
- let label, linkLabel, linkUrl, button1, button2;
-
- if (action.fallbackType == Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE) {
- button1 = {
- label: "pluginBlockNow.label",
- accesskey: "pluginBlockNow.accesskey",
- action: "_singleBlock"
- };
- button2 = {
- label: "pluginContinue.label",
- accesskey: "pluginContinue.accesskey",
- action: "_singleContinue",
- default: true
- };
- switch (action.blocklistState) {
- case Ci.nsIBlocklistService.STATE_NOT_BLOCKED:
- label = "pluginEnabled.message";
- linkLabel = "pluginActivate.learnMore";
- break;
-
- case Ci.nsIBlocklistService.STATE_BLOCKED:
- Cu.reportError(Error("Cannot happen!"));
- break;
-
- case Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE:
- label = "pluginEnabledOutdated.message";
- linkLabel = "pluginActivate.updateLabel";
- break;
-
- case Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE:
- label = "pluginEnabledVulnerable.message";
- linkLabel = "pluginActivate.riskLabel"
- break;
-
- default:
- Cu.reportError(Error("Unexpected blocklist state"));
- }
- }
- else if (action.pluginTag.enabledState == Ci.nsIPluginTag.STATE_DISABLED) {
- let linkElement =
- document.getAnonymousElementByAttribute(
- this, "anonid", "click-to-play-plugins-notification-link");
- linkElement.textContent = gNavigatorBundle.getString("pluginActivateDisabled.manage");
- linkElement.setAttribute("onclick", "gPluginHandler.managePlugins()");
-
- let descElement = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-description");
- descElement.textContent = gNavigatorBundle.getFormattedString(
- "pluginActivateDisabled.message", [action.pluginName, this._brandShortName]) + " ";
- this._buttonContainer.hidden = true;
- return;
- }
- else if (action.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) {
- let descElement = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-description");
- descElement.textContent = gNavigatorBundle.getFormattedString(
- "pluginActivateBlocked.message", [action.pluginName, this._brandShortName]) + " ";
- this._setupLink("pluginActivate.learnMore", action.detailsLink);
- this._buttonContainer.hidden = true;
- return;
- }
- else {
- button1 = {
- label: "pluginActivateNow.label",
- accesskey: "pluginActivateNow.accesskey",
- action: "_singleActivateNow"
- };
- button2 = {
- label: "pluginActivateAlways.label",
- accesskey: "pluginActivateAlways.accesskey",
- action: "_singleActivateAlways"
- };
- switch (action.blocklistState) {
- case Ci.nsIBlocklistService.STATE_NOT_BLOCKED:
- label = "pluginActivateNew.message";
- linkLabel = "pluginActivate.learnMore";
- button2.default = true;
- break;
-
- case Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE:
- label = "pluginActivateOutdated.message";
- linkLabel = "pluginActivate.updateLabel";
- button1.default = true;
- break;
-
- case Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE:
- label = "pluginActivateVulnerable.message";
- linkLabel = "pluginActivate.riskLabel"
- button1.default = true;
- break;
-
- default:
- Cu.reportError(Error("Unexpected blocklist state"));
- }
- }
- this._setupDescription(label, action.pluginName, prePath);
- this._setupLink(linkLabel, action.detailsLink);
-
- this._primaryButton.label = gNavigatorBundle.getString(button1.label);
- this._primaryButton.accesskey = gNavigatorBundle.getString(button1.accesskey);
- this._primaryButton.setAttribute("action", button1.action);
-
- this._secondaryButton.label = gNavigatorBundle.getString(button2.label);
- this._secondaryButton.accesskey = gNavigatorBundle.getString(button2.accesskey);
- this._secondaryButton.setAttribute("action", button2.action);
- if (button1.default) {
- this._primaryButton.setAttribute("default", "true");
- }
- else if (button2.default) {
- this._secondaryButton.setAttribute("default", "true");
- }
- ]]></body>
- </method>
- <method name="_setupDescription">
- <parameter name="baseString" />
- <parameter name="pluginName" /> <!-- null for the multiple-plugin case -->
- <parameter name="prePath" />
- <body><![CDATA[
- var bsn = this._brandShortName;
- var span = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-description");
- while (span.lastChild) {
- span.removeChild(span.lastChild);
- }
-
- var args = ["__prepath__", this._brandShortName];
- if (pluginName) {
- args.unshift(pluginName);
- }
- var bases = gNavigatorBundle.getFormattedString(baseString, args).
- split("__prepath__", 2);
-
- span.appendChild(document.createTextNode(bases[0]));
- var prePathSpan = document.createElementNS("http://www.w3.org/1999/xhtml", "em");
- prePathSpan.appendChild(document.createTextNode(prePath));
- span.appendChild(prePathSpan);
- span.appendChild(document.createTextNode(bases[1] + " "));
- ]]></body>
- </method>
- <method name="_setupLink">
- <parameter name="linkString"/>
- <parameter name="linkUrl" />
- <body><![CDATA[
- var link = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-link");
- if (!linkString || !linkUrl) {
- link.hidden = true;
- return;
- }
-
- link.hidden = false;
- link.textContent = gNavigatorBundle.getString(linkString);
- link.href = linkUrl;
- ]]></body>
- </method>
- <method name="_onButton">
- <parameter name="aButton" />
- <body><![CDATA[
- let methodName = aButton.getAttribute("action");
- this[methodName]();
- ]]></body>
- </method>
- <method name="_singleActivateNow">
- <body><![CDATA[
- gPluginHandler._updatePluginPermission(this.notification,
- this.notification.options.centerActions[0],
- "allownow");
- this._cancel();
- ]]></body>
- </method>
- <method name="_singleBlock">
- <body><![CDATA[
- gPluginHandler._updatePluginPermission(this.notification,
- this.notification.options.centerActions[0],
- "block");
- this._cancel();
- ]]></body>
- </method>
- <method name="_singleActivateAlways">
- <body><![CDATA[
- gPluginHandler._updatePluginPermission(this.notification,
- this.notification.options.centerActions[0],
- "allowalways");
- this._cancel();
- ]]></body>
- </method>
- <method name="_singleContinue">
- <body><![CDATA[
- gPluginHandler._updatePluginPermission(this.notification,
- this.notification.options.centerActions[0],
- "continue");
- this._cancel();
- ]]></body>
- </method>
- <method name="_multiAccept">
- <body><![CDATA[
- for (let item of this._items) {
- let action = item.action;
- if (action.pluginTag.enabledState == Ci.nsIPluginTag.STATE_DISABLED ||
- action.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) {
- continue;
- }
- gPluginHandler._updatePluginPermission(this.notification,
- item.action, item.value);
- }
- this._cancel();
- ]]></body>
- </method>
- <method name="_cancel">
- <body><![CDATA[
- PopupNotifications._dismiss();
- ]]></body>
- </method>
- <method name="_accept">
- <parameter name="aEvent" />
- <body><![CDATA[
- if (aEvent.defaultPrevented)
- return;
- aEvent.preventDefault();
- if (this._primaryButton.getAttribute("default") == "true") {
- this._primaryButton.click();
- }
- else if (this._secondaryButton.getAttribute("default") == "true") {
- this._secondaryButton.click();
- }
- ]]></body>
- </method>
- </implementation>
- <handlers>
- <!-- The _accept method checks for .defaultPrevented so that if focus is in a button,
- enter activates the button and not this default action -->
- <handler event="keypress" keycode="VK_ENTER" group="system" action="this._accept(event);"/>
- <handler event="keypress" keycode="VK_RETURN" group="system" action="this._accept(event);"/>
- </handlers>
- </binding>
-
- <binding id="splitmenu">
- <content>
- <xul:hbox anonid="menuitem" flex="1"
- class="splitmenu-menuitem"
- xbl:inherits="iconic,label,disabled,onclick=oncommand,_moz-menuactive=active"/>
- <xul:menu anonid="menu" class="splitmenu-menu"
- xbl:inherits="disabled,_moz-menuactive=active"
- oncommand="event.stopPropagation();">
- <children includes="menupopup"/>
- </xul:menu>
- </content>
-
- <implementation implements="nsIDOMEventListener">
- <constructor><![CDATA[
- this._parentMenupopup.addEventListener("DOMMenuItemActive", this, false);
- this._parentMenupopup.addEventListener("popuphidden", this, false);
- ]]></constructor>
-
- <destructor><![CDATA[
- this._parentMenupopup.removeEventListener("DOMMenuItemActive", this, false);
- this._parentMenupopup.removeEventListener("popuphidden", this, false);
- ]]></destructor>
-
- <field name="menuitem" readonly="true">
- document.getAnonymousElementByAttribute(this, "anonid", "menuitem");
- </field>
- <field name="menu" readonly="true">
- document.getAnonymousElementByAttribute(this, "anonid", "menu");
- </field>
-
- <field name="_menuDelay">600</field>
-
- <field name="_parentMenupopup"><![CDATA[
- this._getParentMenupopup(this);
- ]]></field>
-
- <method name="_getParentMenupopup">
- <parameter name="aNode"/>
- <body><![CDATA[
- let node = aNode.parentNode;
- while (node) {
- if (node.localName == "menupopup")
- break;
- node = node.parentNode;
- }
- return node;
- ]]></body>
- </method>
-
- <method name="handleEvent">
- <parameter name="event"/>
- <body><![CDATA[
- switch (event.type) {
- case "DOMMenuItemActive":
- if (this.getAttribute("active") == "true" &&
- event.target != this &&
- this._getParentMenupopup(event.target) == this._parentMenupopup)
- this.removeAttribute("active");
- break;
- case "popuphidden":
- if (event.target == this._parentMenupopup)
- this.removeAttribute("active");
- break;
- }
- ]]></body>
- </method>
- </implementation>
-
- <handlers>
- <handler event="mouseover"><![CDATA[
- if (this.getAttribute("active") != "true") {
- this.setAttribute("active", "true");
-
- let event = document.createEvent("Events");
- event.initEvent("DOMMenuItemActive", true, false);
- this.dispatchEvent(event);
-
- if (this.getAttribute("disabled") != "true") {
- let self = this;
- setTimeout(function () {
- if (self.getAttribute("active") == "true")
- self.menu.open = true;
- }, this._menuDelay);
- }
- }
- ]]></handler>
-
- <handler event="popupshowing"><![CDATA[
- if (event.target == this.firstChild &&
- this._parentMenupopup._currentPopup)
- this._parentMenupopup._currentPopup.hidePopup();
- ]]></handler>
-
- <handler event="click" phase="capturing"><![CDATA[
- if (this.getAttribute("disabled") == "true") {
- // Prevent the command from being carried out
- event.stopPropagation();
- return;
- }
-
- let node = event.originalTarget;
- while (true) {
- if (node == this.menuitem)
- break;
- if (node == this)
- return;
- node = node.parentNode;
- }
-
- this._parentMenupopup.hidePopup();
- ]]></handler>
- </handlers>
- </binding>
-
- <binding id="menuitem-tooltip" extends="chrome://global/content/bindings/menu.xml#menuitem">
- <implementation>
- <constructor><![CDATA[
- this.setAttribute("tooltiptext", this.getAttribute("acceltext"));
- // TODO: Simplify this to this.setAttribute("acceltext", "") once bug
- // 592424 is fixed
- document.getAnonymousElementByAttribute(this, "anonid", "accel").firstChild.setAttribute("value", "");
- ]]></constructor>
- </implementation>
- </binding>
-
- <binding id="menuitem-iconic-tooltip" extends="chrome://global/content/bindings/menu.xml#menuitem-iconic">
- <implementation>
- <constructor><![CDATA[
- this.setAttribute("tooltiptext", this.getAttribute("acceltext"));
- // TODO: Simplify this to this.setAttribute("acceltext", "") once bug
- // 592424 is fixed
- document.getAnonymousElementByAttribute(this, "anonid", "accel").firstChild.setAttribute("value", "");
- ]]></constructor>
- </implementation>
- </binding>
-
- <binding id="toolbarbutton-badged" display="xul:button"
- extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton">
- <content>
- <children includes="observes|template|menupopup|panel|tooltip"/>
- <xul:stack class="toolbarbutton-badge-stack">
- <xul:image class="toolbarbutton-icon" xbl:inherits="validate,src=image,label"/>
- <xul:label class="toolbarbutton-badge" xbl:inherits="value=badge" top="0" end="0"/>
- </xul:stack>
- <xul:label class="toolbarbutton-text" crop="right" flex="1"
- xbl:inherits="value=label,accesskey,crop"/>
- </content>
- </binding>
-
-</bindings>
diff --git a/base/content/utilityOverlay.js b/base/content/utilityOverlay.js
deleted file mode 100644
index 1d284ba..0000000
--- a/base/content/utilityOverlay.js
+++ /dev/null
@@ -1,901 +0,0 @@
-# -*- Mode: javascript; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# 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/.
-
-// Services = object with smart getters for common XPCOM services
-Components.utils.import("resource://gre/modules/Services.jsm");
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
-Components.utils.import("resource:///modules/RecentWindow.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "ShellService",
- "resource:///modules/ShellService.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Deprecated",
- "resource://gre/modules/Deprecated.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "BROWSER_NEW_TAB_URL", function () {
- const PREF = "browser.newtab.url";
-
- function getNewTabPageURL() {
- if (!Services.prefs.prefHasUserValue(PREF)) {
- if (PrivateBrowsingUtils.isWindowPrivate(window) &&
- !PrivateBrowsingUtils.permanentPrivateBrowsing)
- return "about:privatebrowsing";
- }
- return Services.prefs.getCharPref(PREF) || "about:blank";
- }
-
- function update() {
- BROWSER_NEW_TAB_URL = getNewTabPageURL();
- }
-
- Services.prefs.addObserver(PREF, update, false);
-
- addEventListener("unload", function onUnload() {
- removeEventListener("unload", onUnload);
- Services.prefs.removeObserver(PREF, update);
- });
-
- return getNewTabPageURL();
-});
-
-var TAB_DROP_TYPE = "application/x-moz-tabbrowser-tab";
-
-var gBidiUI = false;
-
-/**
- * Determines whether the given url is considered a special URL for new tabs.
- */
-function isBlankPageURL(aURL) {
- // Pale Moon: Only make "about:blank", the logopage, or "about:newtab" be
- // a "blank page" to fix focus issues.
- // Original code: return aURL == "about:blank" || aURL == BROWSER_NEW_TAB_URL;
- return aURL == "about:blank" || aURL == "about:newtab" || aURL == "about:logopage";
-}
-
-function getBrowserURL()
-{
- return "chrome://browser/content/browser.xul";
-}
-
-function getBoolPref(pref, defaultValue) {
- Deprecated.warning("getBoolPref is deprecated and will be removed in a future release. " +
- "You should use Services.pref.getBoolPref (Services.jsm).",
- "https://github.com/MoonchildProductions/UXP/issues/989");
- return Services.prefs.getBoolPref(pref, defaultValue);
-}
-
-
-function getTopWin(skipPopups) {
- // If this is called in a browser window, use that window regardless of
- // whether it's the frontmost window, since commands can be executed in
- // background windows (bug 626148).
- if (top.document.documentElement.getAttribute("windowtype") == "navigator:browser" &&
- (!skipPopups || top.toolbar.visible))
- return top;
-
- let isPrivate = PrivateBrowsingUtils.isWindowPrivate(window);
- return RecentWindow.getMostRecentBrowserWindow({private: isPrivate,
- allowPopups: !skipPopups});
-}
-
-function openTopWin(url) {
- /* deprecated */
- openUILinkIn(url, "current");
-}
-
-/* openUILink handles clicks on UI elements that cause URLs to load.
- *
- * As the third argument, you may pass an object with the same properties as
- * accepted by openUILinkIn, plus "ignoreButton" and "ignoreAlt".
- */
-function openUILink(url, event, aIgnoreButton, aIgnoreAlt, aAllowThirdPartyFixup,
- aPostData, aReferrerURI) {
- let params;
-
- if (aIgnoreButton && typeof aIgnoreButton == "object") {
- params = aIgnoreButton;
-
- // don't forward "ignoreButton" and "ignoreAlt" to openUILinkIn
- aIgnoreButton = params.ignoreButton;
- aIgnoreAlt = params.ignoreAlt;
- delete params.ignoreButton;
- delete params.ignoreAlt;
- } else {
- params = {
- allowThirdPartyFixup: aAllowThirdPartyFixup,
- postData: aPostData,
- referrerURI: aReferrerURI,
- referrerPolicy: Components.interfaces.nsIHttpChannel.REFERRER_POLICY_DEFAULT,
- initiatingDoc: event ? event.target.ownerDocument : null,
- };
- }
-
- let where = whereToOpenLink(event, aIgnoreButton, aIgnoreAlt);
- openUILinkIn(url, where, params);
-}
-
-
-/* whereToOpenLink() looks at an event to decide where to open a link.
- *
- * The event may be a mouse event (click, double-click, middle-click) or keypress event (enter).
- *
- * On Windows, the modifiers are:
- * Ctrl new tab, selected
- * Shift new window
- * Ctrl+Shift new tab, in background
- * Alt save
- *
- * Middle-clicking is the same as Ctrl+clicking (it opens a new tab).
- *
- * Exceptions:
- * - Alt is ignored for menu items selected using the keyboard so you don't accidentally save stuff.
- * (Currently, the Alt isn't sent here at all for menu items, but that will change in bug 126189.)
- * - Alt is hard to use in context menus, because pressing Alt closes the menu.
- * - Alt can't be used on the bookmarks toolbar because Alt is used for "treat this as something draggable".
- * - The button is ignored for the middle-click-paste-URL feature, since it's always a middle-click.
- */
-function whereToOpenLink( e, ignoreButton, ignoreAlt )
-{
- // This method must treat a null event like a left click without modifier keys (i.e.
- // e = { shiftKey:false, ctrlKey:false, metaKey:false, altKey:false, button:0 })
- // for compatibility purposes.
- if (!e)
- return "current";
-
- var shift = e.shiftKey;
- var ctrl = e.ctrlKey;
- var meta = e.metaKey;
- var alt = e.altKey && !ignoreAlt;
-
- // ignoreButton allows "middle-click paste" to use function without always opening in a new window.
- var middle = !ignoreButton && e.button == 1;
- var middleUsesTabs = Services.prefs.getBoolPref("browser.tabs.opentabfor.middleclick", true);
-
- // Don't do anything special with right-mouse clicks. They're probably clicks on context menu items.
-
-#ifdef XP_MACOSX
- if (meta || (middle && middleUsesTabs))
-#else
- if (ctrl || (middle && middleUsesTabs))
-#endif
- return shift ? "tabshifted" : "tab";
-
- if (alt && Services.prefs.getBoolPref("browser.altClickSave", false))
- return "save";
-
- if (shift || (middle && !middleUsesTabs))
- return "window";
-
- return "current";
-}
-
-/* openUILinkIn opens a URL in a place specified by the parameter |where|.
- *
- * |where| can be:
- * "current" current tab (if there aren't any browser windows, then in a new window instead)
- * "tab" new tab (if there aren't any browser windows, then in a new window instead)
- * "tabshifted" same as "tab" but in background if default is to select new tabs, and vice versa
- * "window" new window
- * "save" save to disk (with no filename hint!)
- *
- * aAllowThirdPartyFixup controls whether third party services such as Google's
- * I Feel Lucky are allowed to interpret this URL. This parameter may be
- * undefined, which is treated as false.
- *
- * Instead of aAllowThirdPartyFixup, you may also pass an object with any of
- * these properties:
- * allowThirdPartyFixup (boolean)
- * postData (nsIInputStream)
- * referrerURI (nsIURI)
- * relatedToCurrent (boolean)
- */
-function openUILinkIn(url, where, aAllowThirdPartyFixup, aPostData, aReferrerURI) {
- var params;
-
- if (arguments.length == 3 && typeof arguments[2] == "object") {
- params = aAllowThirdPartyFixup;
- } else {
- params = {
- allowThirdPartyFixup: aAllowThirdPartyFixup,
- postData: aPostData,
- referrerURI: aReferrerURI,
- referrerPolicy: Components.interfaces.nsIHttpChannel.REFERRER_POLICY_DEFAULT,
- };
- }
-
- params.fromChrome = true;
-
- openLinkIn(url, where, params);
-}
-
-/* eslint-disable complexity */
-function openLinkIn(url, where, params) {
- if (!where || !url)
- return;
- const Cc = Components.classes;
- const Ci = Components.interfaces;
-
- var aFromChrome = params.fromChrome;
- var aAllowThirdPartyFixup = params.allowThirdPartyFixup;
- var aPostData = params.postData;
- var aCharset = params.charset;
- var aReferrerURI = params.referrerURI;
- var aReferrerPolicy = ('referrerPolicy' in params ?
- params.referrerPolicy : Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
- var aRelatedToCurrent = params.relatedToCurrent;
- var aForceAllowDataURI = params.forceAllowDataURI;
- var aInBackground = params.inBackground;
- var aDisallowInheritPrincipal = params.disallowInheritPrincipal;
- var aInitiatingDoc = params.initiatingDoc;
- var aIsPrivate = params.private;
- var aPrincipal = params.originPrincipal;
- var aTriggeringPrincipal = params.triggeringPrincipal;
- var aForceAboutBlankViewerInCurrent =
- params.forceAboutBlankViewerInCurrent;
- var sendReferrerURI = true;
-
- if (where == "save") {
- if (!aInitiatingDoc) {
- Components.utils.reportError("openUILink/openLinkIn was called with " +
- "where == 'save' but without initiatingDoc. See bug 814264.");
- return;
- }
- // TODO(1073187): propagate referrerPolicy.
- saveURL(url, null, null, true, null, aReferrerURI, aInitiatingDoc);
- return;
- }
-
- var w = getTopWin();
- if ((where == "tab" || where == "tabshifted") &&
- w && !w.toolbar.visible) {
- w = getTopWin(true);
- aRelatedToCurrent = false;
- }
-
- // We can only do this after we're sure of what |w| will be the rest of this function.
- // Note that if |w| is null we might have no current browser (we'll open a new window).
- var aCurrentBrowser = params.currentBrowser || (w && w.gBrowser.selectedBrowser);
-
- // Teach the principal about the right OA to use, e.g. in case when
- // opening a link in a new private window.
- // Please note we do not have to do that for SystemPrincipals and we
- // can not do it for NullPrincipals since NullPrincipals are only
- // identical if they actually are the same object (See Bug: 1346759)
- function useOAForPrincipal(principal) {
- if (principal && principal.isCodebasePrincipal) {
- let attrs = {
- privateBrowsingId: aIsPrivate || (w && PrivateBrowsingUtils.isWindowPrivate(w)),
- };
- return Services.scriptSecurityManager.createCodebasePrincipal(principal.URI, attrs);
- }
- return principal;
- }
- aPrincipal = useOAForPrincipal(aPrincipal);
- aTriggeringPrincipal = useOAForPrincipal(aTriggeringPrincipal);
-
- if (!w || where == "window") {
- // This propagates to window.arguments.
- // Strip referrer data when opening a new private window, to prevent
- // regular browsing data from leaking into it.
- if (aIsPrivate) {
- sendReferrerURI = false;
- }
-
- var sa = Cc["@mozilla.org/supports-array;1"].
- createInstance(Ci.nsISupportsArray);
-
- var wuri = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString);
- wuri.data = url;
-
- let charset = null;
- if (aCharset) {
- charset = Cc["@mozilla.org/supports-string;1"]
- .createInstance(Ci.nsISupportsString);
- charset.data = "charset=" + aCharset;
- }
-
- var allowThirdPartyFixupSupports = Cc["@mozilla.org/supports-PRBool;1"].
- createInstance(Ci.nsISupportsPRBool);
- allowThirdPartyFixupSupports.data = aAllowThirdPartyFixup;
-
- var referrerURISupports = null;
- if (aReferrerURI && sendReferrerURI) {
- referrerURISupports = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString);
- referrerURISupports.data = aReferrerURI.spec;
- }
-
- var referrerPolicySupports = Cc["@mozilla.org/supports-PRUint32;1"].
- createInstance(Ci.nsISupportsPRUint32);
- referrerPolicySupports.data = aReferrerPolicy;
-
- sa.AppendElement(wuri);
- sa.AppendElement(charset);
- sa.AppendElement(referrerURISupports);
- sa.AppendElement(aPostData);
- sa.AppendElement(allowThirdPartyFixupSupports);
- sa.AppendElement(referrerPolicySupports);
- sa.AppendElement(aPrincipal);
- sa.AppendElement(aTriggeringPrincipal);
-
- let features = "chrome,dialog=no,all";
- if (aIsPrivate) {
- features += ",private";
- }
-
- Services.ww.openWindow(w || window, getBrowserURL(), null, features, sa);
- return;
- }
-
- let loadInBackground = where == "current" ? false : aInBackground;
- if (loadInBackground == null) {
- loadInBackground = aFromChrome ?
- false :
- Services.prefs.getBoolPref("browser.tabs.loadInBackground");
- }
-
- let uriObj;
- if (where == "current") {
- try {
- uriObj = Services.io.newURI(url, null, null);
- } catch (e) {}
- }
-
- if (where == "current" && w.gBrowser.selectedTab.pinned) {
- try {
- // nsIURI.host can throw for non-nsStandardURL nsIURIs.
- if (!uriObj || !uriObj.schemeIs("javascript") &&
- w.gBrowser.currentURI.host != uriObj.host) {
- where = "tab";
- loadInBackground = false;
- }
- } catch (err) {
- where = "tab";
- loadInBackground = false;
- }
- }
-
- // Raise the target window before loading the URI, since loading it may
- // result in a new frontmost window (e.g. "javascript:window.open('');").
- w.focus();
-
- let browserUsedForLoad = null;
- switch (where) {
- case "current":
- let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
- if (aAllowThirdPartyFixup) {
- flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
- flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
- }
- if (aDisallowInheritPrincipal)
- flags |= Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL;
- if (aForceAllowDataURI) {
- flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
- }
- let {URI_INHERITS_SECURITY_CONTEXT} = Ci.nsIProtocolHandler;
- if (aForceAboutBlankViewerInCurrent &&
- (!uriObj ||
- (Services.io.getProtocolFlags(uriObj.scheme) & URI_INHERITS_SECURITY_CONTEXT))) {
- // Unless we know for sure we're not inheriting principals,
- // force the about:blank viewer to have the right principal:
- w.gBrowser.selectedBrowser.createAboutBlankContentViewer(aPrincipal);
- }
-
- w.gBrowser.loadURIWithFlags(url, {
- flags: flags,
- triggeringPrincipal: aTriggeringPrincipal,
- referrerURI: aReferrerURI,
- referrerPolicy: aReferrerPolicy,
- postData: aPostData,
- originPrincipal: aPrincipal,
- });
- browserUsedForLoad = aCurrentBrowser;
- break;
- case "tabshifted":
- loadInBackground = !loadInBackground;
- // fall through
- case "tab":
- let browser = w.gBrowser;
- let tabUsedForLoad = browser.loadOneTab(url, {
- referrerURI: aReferrerURI,
- referrerPolicy: aReferrerPolicy,
- charset: aCharset,
- postData: aPostData,
- inBackground: loadInBackground,
- allowThirdPartyFixup: aAllowThirdPartyFixup,
- relatedToCurrent: aRelatedToCurrent,
- originPrincipal: aPrincipal,
- triggeringPrincipal: aTriggeringPrincipal });
- browserUsedForLoad = tabUsedForLoad.linkedBrowser;
- break;
- }
-
- // Focus the content, but only if the browser used for the load is selected.
- if (browserUsedForLoad &&
- browserUsedForLoad == browserUsedForLoad.getTabBrowser().selectedBrowser) {
- browserUsedForLoad.focus();
- }
-
- if (!loadInBackground && w.isBlankPageURL(url))
- if (!w.focusAndSelectUrlBar()) {
- console.error("Unable to focus and select address bar.")
- }
-}
-
-// Used as an onclick handler for UI elements with link-like behavior.
-// e.g. onclick="checkForMiddleClick(this, event);"
-function checkForMiddleClick(node, event) {
- // We should be using the disabled property here instead of the attribute,
- // but some elements that this function is used with don't support it (e.g.
- // menuitem).
- if (node.getAttribute("disabled") == "true")
- return; // Do nothing
-
- if (event.button == 1) {
- /* Execute the node's oncommand or command.
- *
- * XXX: we should use node.oncommand(event) once bug 246720 is fixed.
- */
- var target = node.hasAttribute("oncommand") ? node :
- node.ownerDocument.getElementById(node.getAttribute("command"));
- var fn = new Function("event", target.getAttribute("oncommand"));
- fn.call(target, event);
-
- // If the middle-click was on part of a menu, close the menu.
- // (Menus close automatically with left-click but not with middle-click.)
- closeMenus(event.target);
- }
-}
-
-// Closes all popups that are ancestors of the node.
-function closeMenus(node)
-{
- if ("tagName" in node) {
- if (node.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- && (node.tagName == "menupopup" || node.tagName == "popup"))
- node.hidePopup();
-
- closeMenus(node.parentNode);
- }
-}
-
-// Gather all descendent text under given document node.
-function gatherTextUnder ( root )
-{
- var text = "";
- var node = root.firstChild;
- var depth = 1;
- while ( node && depth > 0 ) {
- // See if this node is text.
- if ( node.nodeType == Node.TEXT_NODE ) {
- // Add this text to our collection.
- text += " " + node.data;
- } else if ( node instanceof HTMLImageElement) {
- // If it has an alt= attribute, use that.
- var altText = node.getAttribute( "alt" );
- if ( altText && altText != "" ) {
- text = altText;
- break;
- }
- }
- // Find next node to test.
- // First, see if this node has children.
- if ( node.hasChildNodes() ) {
- // Go to first child.
- node = node.firstChild;
- depth++;
- } else {
- // No children, try next sibling (or parent next sibling).
- while ( depth > 0 && !node.nextSibling ) {
- node = node.parentNode;
- depth--;
- }
- if ( node.nextSibling ) {
- node = node.nextSibling;
- }
- }
- }
- // Strip leading whitespace.
- text = text.replace( /^\s+/, "" );
- // Strip trailing whitespace.
- text = text.replace( /\s+$/, "" );
- // Compress remaining whitespace.
- text = text.replace( /\s+/g, " " );
- return text;
-}
-
-// This function exists for legacy reasons.
-function getShellService()
-{
- return ShellService;
-}
-
-function isBidiEnabled() {
- // first check the pref.
- if (Services.prefs.getBoolPref("bidi.browser.ui", false))
- return true;
-
- // if the pref isn't set, check for an RTL locale and force the pref to true
- // if we find one.
- var rv = false;
-
- try {
- var localeService = Components.classes["@mozilla.org/intl/nslocaleservice;1"]
- .getService(Components.interfaces.nsILocaleService);
- var systemLocale = localeService.getSystemLocale().getCategory("NSILOCALE_CTYPE").substr(0,3);
-
- switch (systemLocale) {
- case "ar-":
- case "he-":
- case "fa-":
- case "ur-":
- case "syr":
- rv = true;
- Services.prefs.setBoolPref("bidi.browser.ui", true);
- }
- } catch (e) {}
-
- return rv;
-}
-
-#ifdef MOZ_UPDATER
-/**
- * Opens the update manager and checks for updates to the application.
- */
-function checkForUpdates()
-{
- var um =
- Components.classes["@mozilla.org/updates/update-manager;1"].
- getService(Components.interfaces.nsIUpdateManager);
- var prompter =
- Components.classes["@mozilla.org/updates/update-prompt;1"].
- createInstance(Components.interfaces.nsIUpdatePrompt);
-
- // If there's an update ready to be applied, show the "Update Downloaded"
- // UI instead and let the user know they have to restart the application for
- // the changes to be applied.
- if (um.activeUpdate && ["pending", "pending-elevate", "applied"].includes(um.activeUpdate.state))
- prompter.showUpdateDownloaded(um.activeUpdate);
- else
- prompter.checkForUpdates();
-}
-#endif
-
-/**
- * Set up the help menu software update items to show proper status,
- * also disabling the items if update is disabled.
- */
-function buildHelpMenu()
-{
-#ifdef MOZ_UPDATER
- var updates =
- Components.classes["@mozilla.org/updates/update-service;1"].
- getService(Components.interfaces.nsIApplicationUpdateService);
- var um =
- Components.classes["@mozilla.org/updates/update-manager;1"].
- getService(Components.interfaces.nsIUpdateManager);
-
- // Disable the UI if the update enabled pref has been locked by the
- // administrator or if we cannot update for some other reason.
- var checkForUpdates = document.getElementById("checkForUpdates");
- var appMenuCheckForUpdates = document.getElementById("appmenu_checkForUpdates");
- var canCheckForUpdates = updates.canCheckForUpdates;
-
- checkForUpdates.setAttribute("disabled", !canCheckForUpdates);
-
- if (appMenuCheckForUpdates) {
- appMenuCheckForUpdates.setAttribute("disabled", !canCheckForUpdates);
- }
-
- if (!canCheckForUpdates) {
- return;
- }
-
- var strings = document.getElementById("bundle_browser");
- var activeUpdate = um.activeUpdate;
-
- // If there's an active update, substitute its name into the label
- // we show for this item, otherwise display a generic label.
- function getStringWithUpdateName(key) {
- if (activeUpdate && activeUpdate.name)
- return strings.getFormattedString(key, [activeUpdate.name]);
- return strings.getString(key + "Fallback");
- }
-
- // By default, show "Check for Updates..." from updatesItem_default or
- // updatesItem_defaultFallback
- var key = "default";
- if (activeUpdate) {
- switch (activeUpdate.state) {
- case "downloading":
- // If we're downloading an update at present, show the text:
- // "Downloading Thunderbird x.x..." from updatesItem_downloading or
- // updatesItem_downloadingFallback, otherwise we're paused, and show
- // "Resume Downloading Thunderbird x.x..." from updatesItem_resume or
- // updatesItem_resumeFallback
- key = updates.isDownloading ? "downloading" : "resume";
- break;
- case "pending":
- // If we're waiting for the user to restart, show: "Apply Downloaded
- // Updates Now..." from updatesItem_pending or
- // updatesItem_pendingFallback
- key = "pending";
- break;
- }
- }
-
- checkForUpdates.label = getStringWithUpdateName("updatesItem_" + key);
-
- if (appMenuCheckForUpdates) {
- appMenuCheckForUpdates.label = getStringWithUpdateName("updatesItem_" + key);
- }
-
- // updatesItem_default.accesskey, updatesItem_downloading.accesskey,
- // updatesItem_resume.accesskey or updatesItem_pending.accesskey
- checkForUpdates.accessKey = strings.getString("updatesItem_" + key +
- ".accesskey");
-
- if (appMenuCheckForUpdates) {
- appMenuCheckForUpdates.accessKey = strings.getString("updatesItem_" + key +
- ".accesskey");
- }
-
- if (um.activeUpdate && updates.isDownloading) {
- checkForUpdates.setAttribute("loading", "true");
- if (appMenuCheckForUpdates) {
- appMenuCheckForUpdates.setAttribute("loading", "true");
- }
- } else {
- checkForUpdates.removeAttribute("loading");
- if (appMenuCheckForUpdates) {
- appMenuCheckForUpdates.removeAttribute("loading");
- }
- }
-#else
-#ifndef XP_MACOSX
- // Some extensions may rely on these being present so only hide the about
- // separator when there are no elements besides the check for updates menuitem
- // in between the about separator and the updates separator.
- var updatesSeparator = document.getElementById("updatesSeparator");
- var aboutSeparator = document.getElementById("aboutSeparator");
- var checkForUpdates = document.getElementById("checkForUpdates");
- if (updatesSeparator.nextSibling === checkForUpdates &&
- checkForUpdates.nextSibling === aboutSeparator)
- updatesSeparator.hidden = true;
-#endif
-#endif
-}
-
-
-function openAboutDialog() {
- var enumerator = Services.wm.getEnumerator("Browser:About");
- while (enumerator.hasMoreElements()) {
- // Only open one about window (Bug 599573)
- let win = enumerator.getNext();
- win.focus();
- return;
- }
-
-#ifdef XP_WIN
- var features = "chrome,centerscreen,dependent";
-#elifdef XP_MACOSX
- var features = "chrome,resizable=no,minimizable=no";
-#else
- var features = "chrome,centerscreen,dependent,dialog=no";
-#endif
- window.openDialog("chrome://browser/content/aboutDialog.xul", "", features);
-}
-
-function openPreferences(paneID, extraArgs)
-{
- var instantApply = Services.prefs.getBoolPref("browser.preferences.instantApply", false);
- var features = "chrome,titlebar,toolbar,centerscreen" + (instantApply ? ",dialog=no" : ",modal");
-
- var win = Services.wm.getMostRecentWindow("Browser:Preferences");
- if (win) {
- win.focus();
- if (paneID) {
- var pane = win.document.getElementById(paneID);
- win.document.documentElement.showPane(pane);
- }
-
- if (extraArgs && extraArgs["advancedTab"]) {
- var advancedPaneTabs = win.document.getElementById("advancedPrefs");
- advancedPaneTabs.selectedTab = win.document.getElementById(extraArgs["advancedTab"]);
- }
-
- return win;
- }
-
- return openDialog("chrome://browser/content/preferences/preferences.xul",
- "Preferences", features, paneID, extraArgs);
-}
-
-function openAdvancedPreferences(tabID)
-{
- openPreferences("paneAdvanced", { "advancedTab" : tabID });
-}
-
-/**
- * Opens the release notes page for this version of the application.
- */
-function openReleaseNotes()
-{
- var relnotesURL = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
- .getService(Components.interfaces.nsIURLFormatter)
- .formatURLPref("app.releaseNotesURL");
-
- openUILinkIn(relnotesURL, "tab");
-}
-
-/**
- * Opens the troubleshooting information (about:support) page for this version
- * of the application.
- */
-function openTroubleshootingPage()
-{
- openUILinkIn("about:support", "tab");
-}
-
-/**
- * Opens the feedback page for this version of the application.
- */
-function openFeedbackPage()
-{
- openUILinkIn(Services.prefs.getCharPref("browser.feedback.url"), "tab");
-}
-
-function isElementVisible(aElement)
-{
- if (!aElement)
- return false;
-
- // If aElement or a direct or indirect parent is hidden or collapsed,
- // height, width or both will be 0.
- var bo = aElement.boxObject;
- return (bo.height > 0 && bo.width > 0);
-}
-
-function makeURLAbsolute(aBase, aUrl)
-{
- // Note: makeURI() will throw if aUri is not a valid URI
- return makeURI(aUrl, null, makeURI(aBase)).spec;
-}
-
-
-/**
- * openNewTabWith: opens a new tab with the given URL.
- *
- * @param aURL
- * The URL to open (as a string).
- * @param aDocument
- * The document from which the URL came, or null. This is used to set the
- * referrer header and to do a security check of whether the document is
- * allowed to reference the URL. If null, there will be no referrer
- * header and no security check.
- * @param aPostData
- * Form POST data, or null.
- * @param aEvent
- * The triggering event (for the purpose of determining whether to open
- * in the background), or null.
- * @param aAllowThirdPartyFixup
- * If true, then we allow the URL text to be sent to third party services
- * (e.g., Google's I Feel Lucky) for interpretation. This parameter may
- * be undefined in which case it is treated as false.
- * @param [optional] aReferrer
- * If aDocument is null, then this will be used as the referrer.
- * There will be no security check.
- * @param [optional] aReferrerPolicy
- * Referrer policy - Ci.nsIHttpChannel.REFERRER_POLICY_*.
- */
-function openNewTabWith(aURL, aDocument, aPostData, aEvent,
- aAllowThirdPartyFixup, aReferrer, aReferrerPolicy) {
- if (aDocument)
- urlSecurityCheck(aURL, aDocument.nodePrincipal);
-
- // As in openNewWindowWith(), we want to pass the charset of the
- // current document over to a new tab.
- var originCharset = aDocument && aDocument.characterSet;
- if (!originCharset &&
- document.documentElement.getAttribute("windowtype") == "navigator:browser")
- originCharset = window.content.document.characterSet;
-
- openLinkIn(aURL, aEvent && aEvent.shiftKey ? "tabshifted" : "tab",
- { charset: originCharset,
- postData: aPostData,
- allowThirdPartyFixup: aAllowThirdPartyFixup,
- referrerURI: aDocument ? aDocument.documentURIObject : aReferrer,
- referrerPolicy: aReferrerPolicy,
- });
-}
-
-function openNewWindowWith(aURL, aDocument, aPostData, aAllowThirdPartyFixup,
- aReferrer, aReferrerPolicy) {
- if (aDocument)
- urlSecurityCheck(aURL, aDocument.nodePrincipal);
-
- // if and only if the current window is a browser window and it has a
- // document with a character set, then extract the current charset menu
- // setting from the current document and use it to initialize the new browser
- // window...
- var originCharset = aDocument && aDocument.characterSet;
- if (!originCharset &&
- document.documentElement.getAttribute("windowtype") == "navigator:browser")
- originCharset = window.content.document.characterSet;
-
- openLinkIn(aURL, "window",
- { charset: originCharset,
- postData: aPostData,
- allowThirdPartyFixup: aAllowThirdPartyFixup,
- referrerURI: aDocument ? aDocument.documentURIObject : aReferrer,
- referrerPolicy: aReferrerPolicy,
- });
-}
-
-/**
- * isValidFeed: checks whether the given data represents a valid feed.
- *
- * @param aLink
- * An object representing a feed with title, href and type.
- * @param aPrincipal
- * The principal of the document, used for security check.
- * @param aIsFeed
- * Whether this is already a known feed or not, if true only a security
- * check will be performed.
- */
-function isValidFeed(aLink, aPrincipal, aIsFeed)
-{
- if (!aLink || !aPrincipal)
- return false;
-
- var type = aLink.type.toLowerCase().replace(/^\s+|\s*(?:;.*)?$/g, "");
- if (!aIsFeed) {
- aIsFeed = (type == "application/rss+xml" ||
- type == "application/atom+xml");
- }
-
- if (aIsFeed) {
- try {
- urlSecurityCheck(aLink.href, aPrincipal,
- Components.interfaces.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
- return type || "application/rss+xml";
- }
- catch(ex) {
- }
- }
-
- return null;
-}
-
-// aCalledFromModal is optional
-function openHelpLink(aHelpTopic, aCalledFromModal) {
- var url = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
- .getService(Components.interfaces.nsIURLFormatter)
- .formatURLPref("app.support.baseURL");
- url += aHelpTopic;
-
- var where = aCalledFromModal ? "window" : "tab";
- openUILinkIn(url, where);
-}
-
-function openPrefsHelp() {
- // non-instant apply prefwindows are usually modal, so we can't open in the topmost window,
- // since its probably behind the window.
- var instantApply = Services.prefs.getBoolPref("browser.preferences.instantApply");
-
- var helpTopic = document.getElementsByTagName("prefwindow")[0].currentPane.helpTopic;
- openHelpLink(helpTopic, !instantApply);
-}
-
-function trimURL(aURL) {
- // This function must not modify the given URL such that calling
- // nsIURIFixup::createFixupURI with the result will produce a different URI.
- return aURL /* remove single trailing slash for http/https/ftp URLs */
- .replace(/^((?:http|https|ftp):\/\/[^/]+)\/$/, "$1")
- /* remove http:// unless the host starts with "ftp\d*\." or contains "@" */
- .replace(/^http:\/\/((?!ftp\d*\.)[^\/@]+(?:\/|$))/, "$1");
-}
diff --git a/base/content/viewSourceOverlay.xul b/base/content/viewSourceOverlay.xul
deleted file mode 100644
index 8b40ddf..0000000
--- a/base/content/viewSourceOverlay.xul
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0"?>
-# 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/.
-
-<?xul-overlay href="chrome://browser/content/baseMenuOverlay.xul"?>
-
-<overlay id="viewSourceOverlay"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<window id="viewSource">
- <commandset id="baseMenuCommandSet"/>
- <keyset id="baseMenuKeyset"/>
- <stringbundleset id="stringbundleset"/>
-</window>
-
-<menubar id="viewSource-main-menubar">
-#ifdef XP_MACOSX
- <menu id="windowMenu"/>
- <menupopup id="menu_ToolsPopup"/>
-#endif
- <menu id="helpMenu"/>
-</menubar>
-
-</overlay>
diff --git a/base/content/web-panels.js b/base/content/web-panels.js
deleted file mode 100644
index 6e2bf5b..0000000
--- a/base/content/web-panels.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* 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/. */
-
-const NS_ERROR_MODULE_NETWORK = 2152398848;
-const NS_NET_STATUS_READ_FROM = NS_ERROR_MODULE_NETWORK + 8;
-const NS_NET_STATUS_WROTE_TO = NS_ERROR_MODULE_NETWORK + 9;
-
-function getPanelBrowser()
-{
- return document.getElementById("web-panels-browser");
-}
-
-var panelProgressListener = {
- onProgressChange : function (aWebProgress, aRequest,
- aCurSelfProgress, aMaxSelfProgress,
- aCurTotalProgress, aMaxTotalProgress) {
- },
-
- onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
- {
- if (!aRequest)
- return;
-
- //ignore local/resource:/chrome: files
- if (aStatus == NS_NET_STATUS_READ_FROM || aStatus == NS_NET_STATUS_WROTE_TO)
- return;
-
- if (aStateFlags & Ci.nsIWebProgressListener.STATE_START &&
- aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) {
- window.parent.document.getElementById('sidebar-throbber').setAttribute("loading", "true");
- }
- else if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
- aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) {
- window.parent.document.getElementById('sidebar-throbber').removeAttribute("loading");
- }
- },
-
- onLocationChange : function(aWebProgress, aRequest, aLocation, aFlags) {
- UpdateBackForwardCommands(getPanelBrowser().webNavigation);
- },
-
- onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage) {
- },
-
- onSecurityChange : function(aWebProgress, aRequest, aState) {
- },
-
- QueryInterface : function(aIID)
- {
- if (aIID.equals(Ci.nsIWebProgressListener) ||
- aIID.equals(Ci.nsISupportsWeakReference) ||
- aIID.equals(Ci.nsISupports))
- return this;
- throw Cr.NS_NOINTERFACE;
- }
-};
-
-var gLoadFired = false;
-function loadWebPanel(aURI) {
- var panelBrowser = getPanelBrowser();
- if (gLoadFired) {
- panelBrowser.webNavigation
- .loadURI(aURI, nsIWebNavigation.LOAD_FLAGS_NONE,
- null, null, null);
- }
- panelBrowser.setAttribute("cachedurl", aURI);
-}
-
-function load()
-{
- var panelBrowser = getPanelBrowser();
- panelBrowser.webProgress.addProgressListener(panelProgressListener,
- Ci.nsIWebProgress.NOTIFY_ALL);
- var cachedurl = panelBrowser.getAttribute("cachedurl")
- if (cachedurl) {
- panelBrowser.webNavigation
- .loadURI(cachedurl, nsIWebNavigation.LOAD_FLAGS_NONE, null,
- null, null);
- }
-
- gLoadFired = true;
-}
-
-function unload()
-{
- getPanelBrowser().webProgress.removeProgressListener(panelProgressListener);
-}
-
-function PanelBrowserStop()
-{
- getPanelBrowser().webNavigation.stop(nsIWebNavigation.STOP_ALL)
-}
-
-function PanelBrowserReload()
-{
- getPanelBrowser().webNavigation
- .sessionHistory
- .QueryInterface(nsIWebNavigation)
- .reload(nsIWebNavigation.LOAD_FLAGS_NONE);
-}
diff --git a/base/content/web-panels.xul b/base/content/web-panels.xul
deleted file mode 100644
index ea1e2eb..0000000
--- a/base/content/web-panels.xul
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0"?>
-
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# 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/.
-
-<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
-<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
-<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
-
-<!DOCTYPE page [
-<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
-%browserDTD;
-<!ENTITY % textcontextDTD SYSTEM "chrome://global/locale/textcontext.dtd">
-%textcontextDTD;
-]>
-
-<page id="webpanels-window"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- onload="load()" onunload="unload()">
- <script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/>
- <script type="application/javascript" src="chrome://browser/content/browser.js"/>
- <script type="application/javascript" src="chrome://global/content/inlineSpellCheckUI.js"/>
- <script type="application/javascript" src="chrome://browser/content/nsContextMenu.js"/>
- <script type="application/javascript" src="chrome://browser/content/web-panels.js"/>
-
- <stringbundleset id="stringbundleset">
- <stringbundle id="bundle_browser" src="chrome://browser/locale/browser.properties"/>
- </stringbundleset>
-
- <broadcasterset id="mainBroadcasterSet">
- <broadcaster id="isFrameImage"/>
- </broadcasterset>
-
- <commandset id="mainCommandset">
- <command id="Browser:Back"
- oncommand="getPanelBrowser().webNavigation.goBack();"
- disabled="true"/>
- <command id="Browser:Forward"
- oncommand="getPanelBrowser().webNavigation.goForward();"
- disabled="true"/>
- <command id="Browser:Stop" oncommand="PanelBrowserStop();"/>
- <command id="Browser:Reload" oncommand="PanelBrowserReload();"/>
- <command id="Browser:BackOrBackDuplicate"
- oncommand="getPanelBrowser().webNavigation.goBack(event);"
- disabled="true">
- <observes element="Browser:Back" attribute="disabled"/>
- </command>
- <command id="Browser:ForwardOrForwardDuplicate"
- oncommand="getPanelBrowser().webNavigation.goForward(event);"
- disabled="true">
- <observes element="Browser:Forward" attribute="disabled"/>
- </command>
- <command id="Browser:ReloadOrDuplicate"
- oncommand="PanelBrowserReload(event)"
- disabled="true">
- <observes element="Browser:Reload" attribute="disabled"/>
- </command>
- </commandset>
-
- <popupset id="mainPopupSet">
- <tooltip id="aHTMLTooltip" page="true"/>
- <menupopup id="contentAreaContextMenu" pagemenu="start"
- onpopupshowing="if (event.target != this)
- return true;
- gContextMenu = new nsContextMenu(this, event.shiftKey);
- if (gContextMenu.shouldDisplay)
- document.popupNode = this.triggerNode;
- return gContextMenu.shouldDisplay;"
- onpopuphiding="if (event.target != this)
- return;
- gContextMenu.hiding();
- gContextMenu = null;">
-#include browser-context.inc
- </menupopup>
- </popupset>
-
- <commandset id="editMenuCommands"/>
- <browser id="web-panels-browser" persist="cachedurl" type="content" flex="1"
- context="contentAreaContextMenu" tooltip="aHTMLTooltip"
- onclick="window.parent.contentAreaClick(event, true);"/>
-</page>
diff --git a/base/content/win6BrowserOverlay.xul b/base/content/win6BrowserOverlay.xul
deleted file mode 100644
index a69e3f6..0000000
--- a/base/content/win6BrowserOverlay.xul
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- -*- Mode: HTML -*- -->
-<!-- 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/. -->
-
-<overlay id="win6-browser-overlay"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <toolbar id="toolbar-menubar"
- autohide="true"/>
-</overlay>