Files
roytam1 5f6d4971d0 import changes from `dev' branch of rmottola/Arctic-Fox:
- caps part only: Bug 1178533 - Add nsIInstallPackagedWebapp for registering permissions when navigating to signed packages r=bholley,fabrice,valentin (8174625aab)
- Bug 1299615 - Part 2: Skip ICU source directory in Clang build plugin when searching for implicit conversion constructors. r=Waldo, r=mystor (30a51b6602)
- Bug 1264827 - Part 1: Rename the existing code to make it clear it's checking for template args; r=mystor (2710d7e318)
- Bug 1264827 - Part 2: Add a static analysis to help check Rust wrapped C++ classes for members which are unsafe to memmove; r=mystor (8f053f59cf)
- Bug 1264827 - Part 3: Add the MOZ_NEEDS_MEMMOVABLE_MEMBERS annotation to MFBT; r=froydnj (937622926a)
- Bug 1229769 - We should be able to use DOM promises in the worker debugger;r=khuey (b3b32e9b94)
- Bug 1265035 - Make ~WorkerJSRuntime() handle Initialize() failure better. r=khuey. (67e67fab06)
- Bug 1256428 P1 Add ServiceWorkerJob2 base class. r=jdm (0bedbfa070)
- Bug 1256428 P2 Add ServiceWorkerJobQueue2 class. r=jdm (806e9b242e)
- Bug 1260933 - Part 1: For invalid easing values, print the invalid value. r=birtles (482541cfcb)
- Bug 1260933 - Part 2: For invalid duration values, print the invalid value. r=birtles (5b20918f77)
- Bug 1256428 P3 Add ServiceWorkerUpdateJob2. r=jdm (135e9bf05d)
- Bug 1256428 P4 Add ServiceWorkerRegisterJob2. r=jdm (e790f95b1d)
- Bug 1256428 P5 Add ServiceWorkerUnregisterJob2 class. r=jdm (cf63826b57)
- Bug 1220757 - Add report to console when service worker register fails due to mismatching scope path.r=bkelly (dbbf1a8515)
- Bug 1255621 - Ignore service workers previously registered in non-private windows. r=bkelly (593ebfc612)
- Bug 1241531 - Part 1: Only pop jobs from the queue when the correct job completes. r=ehsan (f8a1ea2fda)
- Bug 1241531 - Part 2: Move Cancel() to ServiceWorkerJob base class. r=ehsan (33ffccb8a4)
- Bug 1241531 - Part 3: Call Cancel() on all service worker jobs. r=ehsan (4cce06ab41)
- Bug 1241531 - Part 4: Make service worker unregister job respect cancelation. r=ehsan (1877cb3919)
- Bug 1261776 Use SafeElementAt() in service worker job queue. r=ehsan (c7a883a087)
- Bug 1238990 P1 ServiceWorkerManager should trigger automatic updates in current process. r=ehsan (c65bded060)
- Bug 1238990 P2 Try to ensure service worker jobs do not run during shutdown. r=ehsan (f816a012f2)
- Bug 1256428 P6 Use ServiceWorkerJobQueue2 and new job classes in ServiceWorkerManager. r=jdm (641af03802)
- Bug 1256428 P0 Fix unified build failures in dom/workers. r=jdm (33aaafd188)
- Bug 1261814: Use the presence of the content global, and not any random global, to determine whether to run the close handler. r=bz (8f182bf345)
- Bug 1256428 P7 Fix wpt update.https.html to expect TypeError per current spec. r=jdm (4c6cad6e0f)
- Bug 1256428 P8 Fix wpt unregister-then-register-new-script.https.html to new spec expectations matching blink's tests. r=jdm (d9191f7002)
- Bug 1226443 P5 Always use first scheduled update timer instead of rescheduling on new events. r=ehsan (7b1b31dcc0)
- Bug 1230341 Hold a strong ref in service worker NS_NewRunnableMethodWithArg uses. r=ehsan a=abillings (2b1d942ae4)
- Bug 1256428 P9 Remove now unused code from ServiceWorkerManager.cpp. r=jdm (7f97035007)
- Bug 1256428 P10 Remove ServiceWorkerRegistrationInfo::mUpdating flag. r=jdm (31fc686d5d)
- Bug 1256428 P11 Don't coalesce SW jobs after the existing job has already resolved its promise. r=jdm (1ce373f98b)
- Bug 1256428 P12 ServiceWorkerUnregisterJob2 should not use ServiceWorkerManager internals. r=jdm (1abe304c3c)
- Bug 1256428 P13 Remove unnecessary ServiceWorkerUnregsterJob2 stop. r=jdm (05d0717b7c)
- Bug 1256428 P14 Remove dead code in SeviceWorkerUpdateJob.cpp. r=jdm (7d1ac1112a)
- Bug 1256428 P15 Perform byte-for-byte comparison check after validating script URL. r=jdm (dc30ec75a9)
- Bug 1256428 P16 Fix some issues calling purgeCache() in ServiceWorkerUpdateJob.cpp. r=jdm (cffe93613a)
- Bug 1256428 P17 Rename service worker job classes to remove "2" suffix. r=jdm (f1d7a6aadf)
- Bug 1256428 P18 Add spec annotations and tweak asserts in ServiceWorkerUpdateJob. r=jdm (1a9c95a5bb)
- Bug 1256428 P19 Address ServiceWorkerUnregisterJob review feedback. r=jdm (2b8775a9ad)
- Bug 1260591 Move ServiceWorkerInfo and ServiceWorkerRegistrationInfo into separate files. r=jdm (2e31a3c002)
- Bug 1266857 Make Clients.claim() use observer document list instead of secondary hashtable. r=bz (2b318072f5)
- Bug 1261428: Migrate the useless setTimeout error message to the bindings infrastructure. r=bz (80d2503978)
- Bug 1263307 P1 Make ServiceWorkerRegistrationInfo::mScope const. r=jdm (b8b03bc594)
- Bug 1263307 P2 Make ServiceWorkerRegistrationInfo worker members private. r=jdm (16773a9134)
- Bug 1263307 P3 Move ServiceWorker update logic into central place in ServiceWorkerRegistrationInfo methods. r=jdm (68b288cbfb)
- Bug 1265761 Clients.matchAll() should treat http windows as secure if devtools are open and http testing is enabled. r=ehsan (100e16ca08)
- Bug 1265795 P1 Uncontrolled service workers when global is removed from document. r=bz (db069b0756)
- Bug 1265795 P2 Add a web-platform-test for the window navigation case. r=bz (6571257e5b)
- Bug 1265795 P3 Assert that controlled documents have an outer window. r=bz (fdc14dbf66)
- Bug 1265795 P4 Always call nsDocument::SetScriptGlobalObject(nullptr) from nsDocument::Destroy(). r=bz (8825c3dbd5)
- Bug 1254194: Add a validator for custom add-on content security policies. r=billm f=aswan (c557dd47ef)
- Bug 1254194: Allow iterating over and inspecting sources of parsed CSP directives. r=ckerschb (2d93cdda56)
- Bug 1142332 - Prevent calling CSP_EnumToKeyword with CSP_HASH. r=ckerschb (15a80ed62f)
- Bug 1236416 - Remove some misc toolkit content UI from Fennec r=margaret (01f7f81c93)
- Bug 1234403 - Part 1: Implement CSSPseudoElement.getAnimations. r=birtles (91ce2e1cae)
- Bug 1234403 - Part 2: Implement document.getAnimations. r=birtles (49afbacadb)
- Bug 1234403 - Part 3: Test for the CSSPseudoElement objects returned by effect.target. r=birtles (bf34dda38f)
- Bug 1234403 - Part 4: Test for the animation order returned by document.getAnimations(). r=birtles (fa8ec8e01f)
- Bug 1234403 - Part 5: Test for CSSPseudoElement.getAnimations. r=birtles (3ef598f2ba)
- Bug 1254418 - Part 1: Support generated-content element for Element.getAnimations. r=birtles (7ae806859a)
- Bug 1254418 - Part 2: Test getAnimations for generated-content elements. r=birtles (b562ec7478)
- Bug 1254761 - Part 1: Implement getAnimations({ subtree: true }). r=smaug (c5419ffec0)
- Bug 1254761 - Part 2: Removes extra whitespaces. r=birtles (2a98381928)
- Bug 1254761 - Part 3: Add tests for AnimationFilter. r=birtles (bdd9b39849)
- Bug 1254194: Apply a content security policy to all WebExtension documents. r=gabor (c3a9f32be8)
- Bug 1257246: Update the version of eslint that mach installs. r=gps (da0481d7e4)
- Bug 1229588: Add a taskcluster test for eslint. r=dustin (e6eff5caf2)
- Bug 1257246: Update lint test image to newer packages of eslint. r=ahal (bcfaf3b5d8)
- Bug 1263637 - Fix eslint 2 warnings for WebExtensions code. r=kmag (16537b22dc)
- Bug 1238177 - fix extension content needs to use the correct user context id origin attribute. r=sicking (834faa0f62)
2024-05-02 16:55:13 +08:00

1273 lines
44 KiB
XML

<?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="browserBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="browser" extends="xul:browser" role="outerdoc">
<content clickthrough="never">
<children/>
</content>
<implementation type="application/javascript" implements="nsIObserver, nsIDOMEventListener, nsIMessageListener">
<property name="autoscrollEnabled">
<getter>
<![CDATA[
if (this.getAttribute("autoscroll") == "false")
return false;
var enabled = true;
try {
enabled = this.mPrefs.getBoolPref("general.autoScroll");
}
catch(ex) {
}
return enabled;
]]>
</getter>
</property>
<property name="canGoBack"
onget="return this.webNavigation.canGoBack;"
readonly="true"/>
<property name="canGoForward"
onget="return this.webNavigation.canGoForward;"
readonly="true"/>
<method name="goBack">
<body>
<![CDATA[
var webNavigation = this.webNavigation;
if (webNavigation.canGoBack) {
try {
this.userTypedClear++;
webNavigation.goBack();
} finally {
if (this.userTypedClear)
this.userTypedClear--;
}
}
]]>
</body>
</method>
<method name="goForward">
<body>
<![CDATA[
var webNavigation = this.webNavigation;
if (webNavigation.canGoForward) {
try {
this.userTypedClear++;
webNavigation.goForward();
} finally {
if (this.userTypedClear)
this.userTypedClear--;
}
}
]]>
</body>
</method>
<method name="reload">
<body>
<![CDATA[
const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
const flags = nsIWebNavigation.LOAD_FLAGS_NONE;
this.reloadWithFlags(flags);
]]>
</body>
</method>
<method name="reloadWithFlags">
<parameter name="aFlags"/>
<body>
<![CDATA[
this.webNavigation.reload(aFlags);
]]>
</body>
</method>
<method name="stop">
<body>
<![CDATA[
const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
const flags = nsIWebNavigation.STOP_ALL;
this.webNavigation.stop(flags);
]]>
</body>
</method>
<!-- throws exception for unknown schemes -->
<method name="loadURI">
<parameter name="aURI"/>
<parameter name="aReferrerURI"/>
<parameter name="aCharset"/>
<body>
<![CDATA[
const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
const flags = nsIWebNavigation.LOAD_FLAGS_NONE;
this.loadURIWithFlags(aURI, flags, 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[
if (!aURI)
aURI = "about:blank";
var aReferrerPolicy = Components.interfaces.nsIHttpChannel.REFERRER_POLICY_DEFAULT;
// Check for loadURIWithFlags(uri, { ... });
var params = arguments[1];
if (params && typeof(params) == "object") {
aFlags = params.flags;
aReferrerURI = params.referrerURI;
if ('referrerPolicy' in params) {
aReferrerPolicy = params.referrerPolicy;
}
aCharset = params.charset;
aPostData = params.postData;
}
if (!(aFlags & this.webNavigation.LOAD_FLAGS_FROM_EXTERNAL))
this.userTypedClear++;
try {
this.webNavigation.loadURIWithOptions(
aURI, aFlags, aReferrerURI, aReferrerPolicy,
aPostData, null, null);
} finally {
if (this.userTypedClear)
this.userTypedClear--;
}
]]>
</body>
</method>
<method name="goHome">
<body>
<![CDATA[
try {
this.loadURI(this.homePage);
}
catch (e) {
}
]]>
</body>
</method>
<property name="homePage">
<getter>
<![CDATA[
var uri;
if (this.hasAttribute("homepage"))
uri = this.getAttribute("homepage");
else
uri = "http://www.mozilla.org/"; // widget pride
return uri;
]]>
</getter>
<setter>
<![CDATA[
this.setAttribute("homepage", val);
return val;
]]>
</setter>
</property>
<method name="gotoIndex">
<parameter name="aIndex"/>
<body>
<![CDATA[
try {
this.userTypedClear++;
this.webNavigation.gotoIndex(aIndex);
} finally {
if (this.userTypedClear)
this.userTypedClear--;
}
]]>
</body>
</method>
<property name="currentURI" readonly="true">
<getter><![CDATA[
if (this.webNavigation) {
return this.webNavigation.currentURI;
}
return null;
]]>
</getter>
</property>
<!--
Used by session restore to ensure that currentURI is set so
that switch-to-tab works before the tab is fully
restored. This function also invokes onLocationChanged
listeners in tabbrowser.xml.
-->
<method name="_setCurrentURI">
<parameter name="aURI"/>
<body><![CDATA[
this.docShell.setCurrentURI(aURI);
]]></body>
</method>
<property name="documentURI"
onget="return this.contentDocument.documentURIObject;"
readonly="true"/>
<property name="documentContentType"
onget="return this.contentDocument ? this.contentDocument.contentType : null;"
readonly="true"/>
<property name="preferences"
onget="return this.mPrefs.QueryInterface(Components.interfaces.nsIPrefService);"
readonly="true"/>
<field name="_docShell">null</field>
<property name="docShell" readonly="true">
<getter><![CDATA[
if (this._docShell)
return this._docShell;
let frameLoader = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
if (!frameLoader)
return null;
this._docShell = frameLoader.docShell;
return this._docShell;
]]></getter>
</property>
<field name="_loadContext">null</field>
<property name="loadContext" readonly="true">
<getter><![CDATA[
if (this._loadContext)
return this._loadContext;
let frameLoader = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
if (!frameLoader)
return null;
this._loadContext = frameLoader.loadContext;
return this._loadContext;
]]></getter>
</property>
<property name="docShellIsActive">
<getter>
<![CDATA[
return this.docShell && this.docShell.isActive;
]]>
</getter>
<setter>
<![CDATA[
if (this.docShell)
return this.docShell.isActive = val;
return false;
]]>
</setter>
</property>
<method name="setDocShellIsActiveAndForeground">
<parameter name="isActive"/>
<body>
<![CDATA[
this.docShell && this.docShell.setIsActiveAndForeground(isActive);
]]>
</body>
</method>
<property name="imageDocument"
readonly="true">
<getter>
<![CDATA[
var document = this.contentDocument;
if (!document || !(document instanceof Ci.nsIImageDocument))
return null;
try {
return {width: document.imageRequest.image.width, height: document.imageRequest.image.height };
} catch (e) {}
return null;
]]>
</getter>
</property>
<property name="isRemoteBrowser"
onget="return (this.getAttribute('remote') == 'true');"
readonly="true"/>
<property name="messageManager"
readonly="true">
<getter>
<![CDATA[
var owner = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner);
if (!owner.frameLoader) {
return null;
}
return owner.frameLoader.messageManager;
]]>
</getter>
</property>
<field name="_webNavigation">null</field>
<property name="webNavigation"
readonly="true">
<getter>
<![CDATA[
if (!this._webNavigation) {
if (!this.docShell) {
return null;
}
this._webNavigation = this.docShell.QueryInterface(Components.interfaces.nsIWebNavigation);
}
return this._webNavigation;
]]>
</getter>
</property>
<field name="_webBrowserFind">null</field>
<property name="webBrowserFind"
readonly="true">
<getter>
<![CDATA[
if (!this._webBrowserFind)
this._webBrowserFind = this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebBrowserFind);
return this._webBrowserFind;
]]>
</getter>
</property>
<method name="getTabBrowser">
<body>
<![CDATA[
var tabBrowser = this.parentNode;
while (tabBrowser && tabBrowser.localName != "tabbrowser")
tabBrowser = tabBrowser.parentNode;
return tabBrowser;
]]>
</body>
</method>
<field name="_finder">null</field>
<property name="finder" readonly="true">
<getter><![CDATA[
if (!this._finder) {
if (!this.docShell)
return null;
let Finder = Components.utils.import("resource://gre/modules/Finder.jsm", {}).Finder;
this._finder = new Finder(this.docShell);
}
return this._finder;
]]></getter>
</property>
<field name="_fastFind">null</field>
<property name="fastFind" readonly="true">
<getter><![CDATA[
if (!this._fastFind) {
if (!("@mozilla.org/typeaheadfind;1" in Components.classes))
return null;
var tabBrowser = this.getTabBrowser();
if (tabBrowser && "fastFind" in tabBrowser)
return this._fastFind = tabBrowser.fastFind;
if (!this.docShell)
return null;
this._fastFind = Components.classes["@mozilla.org/typeaheadfind;1"]
.createInstance(Components.interfaces.nsITypeAheadFind);
this._fastFind.init(this.docShell);
}
return this._fastFind;
]]></getter>
</property>
<field name="_permanentKey">({})</field>
<property name="permanentKey"
onget="return this._permanentKey;"
onset="this._permanentKey = val;"/>
<property name="outerWindowID" readonly="true">
<getter><![CDATA[
return this.contentWindow
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils)
.outerWindowID;
]]></getter>
</property>
<property name="innerWindowID" readonly="true">
<getter><![CDATA[
try {
return this.contentWindow
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils)
.currentInnerWindowID;
} catch (e) {
if (e.result != Cr.NS_ERROR_NOT_AVAILABLE) {
throw e;
}
return null;
}
]]></getter>
</property>
<field name="_lastSearchString">null</field>
<field name="_lastSearchHighlight">false</field>
<property name="webProgress"
readonly="true"
onget="return this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);"/>
<field name="_contentWindow">null</field>
<property name="contentWindow"
readonly="true"
onget="return this._contentWindow || (this._contentWindow = this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindow));"/>
<property name="contentWindowAsCPOW"
readonly="true"
onget="return this.contentWindow;"/>
<property name="sessionHistory"
onget="return this.webNavigation.sessionHistory;"
readonly="true"/>
<property name="markupDocumentViewer"
onget="return this.docShell.contentViewer;"
readonly="true"/>
<property name="contentViewerEdit"
onget="return this.docShell.contentViewer.QueryInterface(Components.interfaces.nsIContentViewerEdit);"
readonly="true"/>
<property name="contentViewerFile"
onget="return this.docShell.contentViewer.QueryInterface(Components.interfaces.nsIContentViewerFile);"
readonly="true"/>
<property name="contentDocument"
onget="return this.webNavigation.document;"
readonly="true"/>
<property name="contentDocumentAsCPOW"
onget="return this.contentDocument;"
readonly="true"/>
<property name="contentTitle"
onget="return this.contentDocument.title;"
readonly="true"/>
<property name="characterSet"
onget="return this.docShell.charset;">
<setter><![CDATA[
this.docShell.charset = val;
this.docShell.gatherCharsetMenuTelemetry();
]]></setter>
</property>
<property name="mayEnableCharacterEncodingMenu"
onget="return this.docShell.mayEnableCharacterEncodingMenu;"
readonly="true"/>
<property name="contentPrincipal"
onget="return this.contentDocument.nodePrincipal;"
readonly="true"/>
<property name="showWindowResizer"
onset="if (val) this.setAttribute('showresizer', 'true');
else this.removeAttribute('showresizer');
return val;"
onget="return this.getAttribute('showresizer') == 'true';"/>
<property name="fullZoom">
<getter><![CDATA[
return this.markupDocumentViewer.fullZoom;
]]></getter>
<setter><![CDATA[
this.markupDocumentViewer.fullZoom = val;
]]></setter>
</property>
<property name="textZoom">
<getter><![CDATA[
return this.markupDocumentViewer.textZoom;
]]></getter>
<setter><![CDATA[
this.markupDocumentViewer.textZoom = val;
]]></setter>
</property>
<property name="isSyntheticDocument">
<getter><![CDATA[
return this.contentDocument.mozSyntheticDocument;
]]></getter>
</property>
<field name="mPrefs" readonly="true">
Components.classes['@mozilla.org/preferences-service;1']
.getService(Components.interfaces.nsIPrefBranch);
</field>
<field name="_mStrBundle">null</field>
<property name="mStrBundle">
<getter>
<![CDATA[
if (!this._mStrBundle) {
// need to create string bundle manually instead of using <xul:stringbundle/>
// see bug 63370 for details
this._mStrBundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
.getService(Components.interfaces.nsIStringBundleService)
.createBundle("chrome://global/locale/browser.properties");
}
return this._mStrBundle;
]]></getter>
</property>
<method name="addProgressListener">
<parameter name="aListener"/>
<parameter name="aNotifyMask"/>
<body>
<![CDATA[
if (!aNotifyMask) {
aNotifyMask = Components.interfaces.nsIWebProgress.NOTIFY_ALL;
}
this.webProgress.addProgressListener(aListener, aNotifyMask);
]]>
</body>
</method>
<method name="removeProgressListener">
<parameter name="aListener"/>
<body>
<![CDATA[
this.webProgress.removeProgressListener(aListener);
]]>
</body>
</method>
<method name="attachFormFill">
<body>
<![CDATA[
if (!this.mFormFillAttached && this.hasAttribute("autocompletepopup")) {
// hoop up the form fill autocomplete controller
var controller = Components.classes["@mozilla.org/satchel/form-fill-controller;1"].
getService(Components.interfaces.nsIFormFillController);
var popup = document.getElementById(this.getAttribute("autocompletepopup"));
if (popup) {
controller.attachToBrowser(this.docShell, popup.QueryInterface(Components.interfaces.nsIAutoCompletePopup));
this.mFormFillAttached = true;
}
}
]]>
</body>
</method>
<method name="detachFormFill">
<body>
<![CDATA[
if (this.mFormFillAttached) {
// hoop up the form fill autocomplete controller
var controller = Components.classes["@mozilla.org/satchel/form-fill-controller;1"].
getService(Components.interfaces.nsIFormFillController);
controller.detachFromBrowser(this.docShell);
this.mFormFillAttached = false;
}
]]>
</body>
</method>
<method name="findChildShell">
<parameter name="aDocShell"/>
<parameter name="aSoughtURI"/>
<body>
<![CDATA[
if (aDocShell.QueryInterface(Components.interfaces.nsIWebNavigation)
.currentURI.spec == aSoughtURI.spec)
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, aSoughtURI);
if (docShell)
return docShell;
}
return null;
]]>
</body>
</method>
<method name="onPageShow">
<parameter name="aEvent"/>
<body>
<![CDATA[
this.attachFormFill();
]]>
</body>
</method>
<method name="onPageHide">
<parameter name="aEvent"/>
<body>
<![CDATA[
// Delete the feeds cache if we're hiding the topmost page
// (as opposed to one of its iframes).
if (this.feeds && aEvent.target == this.contentDocument)
this.feeds = null;
if (!this.docShell || !this.fastFind)
return;
var tabBrowser = this.getTabBrowser();
if (!tabBrowser || !("fastFind" in tabBrowser) ||
tabBrowser.selectedBrowser == this)
this.fastFind.setDocShell(this.docShell);
]]>
</body>
</method>
<method name="updateBlockedPopups">
<body>
<![CDATA[
var event = document.createEvent("Events");
event.initEvent("DOMUpdatePageReport", true, true);
this.dispatchEvent(event);
]]>
</body>
</method>
<method name="unblockPopup">
<parameter name="aPopupIndex"/>
<body><![CDATA[
this.messageManager.sendAsyncMessage("PopupBlocking:UnblockPopup",
{index: aPopupIndex});
]]></body>
</method>
<field name="blockedPopups">null</field>
<!-- Obsolete name for blockedPopups. Used by android. -->
<property name="pageReport"
onget="return this.blockedPopups;"
readonly="true"/>
<property name="securityUI">
<getter>
<![CDATA[
if (!this.docShell.securityUI) {
const SECUREBROWSERUI_CONTRACTID = "@mozilla.org/secure_browser_ui;1";
if (!this.hasAttribute("disablesecurity") &&
SECUREBROWSERUI_CONTRACTID in Components.classes) {
var securityUI = Components.classes[SECUREBROWSERUI_CONTRACTID]
.createInstance(Components.interfaces.nsISecureBrowserUI);
securityUI.init(this.contentWindow);
}
}
return this.docShell.securityUI;
]]>
</getter>
<setter>
<![CDATA[
this.docShell.securityUI = val;
]]>
</setter>
</property>
<method name="adjustPriority">
<parameter name="adjustment"/>
<body><![CDATA[
let loadGroup = this.webNavigation.QueryInterface(Ci.nsIDocumentLoader)
.loadGroup.QueryInterface(Ci.nsISupportsPriority);
loadGroup.adjustPriority(adjustment);
]]></body>
</method>
<!--
This field tracks the location bar state. The value that the user typed
in to the location bar may not be changed while this field is zero.
However invoking a load will temporarily increase this field to allow
the location bar to be updated to the new URL.
Case 1: Anchor scroll
The user appends the anchor to the URL. This sets the location bar
into typed state, and disables changes to the location bar. The user
then requests the scroll. loadURIWithFlags temporarily increases the
flag by 1 so that the anchor scroll's location change resets the
location bar state.
Case 2: Interrupted load
The user types in and submits the URL. This triggers an asynchronous
network load which increases the flag by 2. (The temporary increase
from loadURIWithFlags is not noticeable in this case.) When the load
is interrupted the flag returns to zero, and the location bar stays
in typed state.
Case 3: New load
This works like case 2, but as the load is not interrupted the
location changes while the flag is still 2 thus resetting the
location bar state.
Case 4: Corrected load
This is a combination of case 2 and case 3, except that the original
load is interrupted by the new load. Normally cancelling and starting
a new load would reset the flag to 0 and then increase it to 2 again.
However both actions occur as a consequence of the loadURIWithFlags
invocation, which adds its temporary increase in to the mix. Since
the new URL would have been typed in the flag would have been reset
before loadURIWithFlags incremented it. The interruption resets the
flag to 0 and increases it to 2. Although loadURIWithFlags will
decrement the flag it remains at 1 thus allowing the location bar
state to be reset when the new load changes the location.
This case also applies when loading into a new browser, as this
interrupts the default load of about:blank.
-->
<field name="userTypedClear">
1
</field>
<field name="_userTypedValue">
null
</field>
<property name="userTypedValue"
onget="return this._userTypedValue;">
<setter><![CDATA[
this.userTypedClear = 0;
this._userTypedValue = val;
return val;
]]></setter>
</property>
<field name="mFormFillAttached">
false
</field>
<field name="isShowingMessage">
false
</field>
<field name="droppedLinkHandler">
null
</field>
<field name="mIconURL">null</field>
<!-- This is managed by the tabbrowser -->
<field name="lastURI">null</field>
<field name="mDestroyed">false</field>
<constructor>
<![CDATA[
try {
// |webNavigation.sessionHistory| will have been set by the frame
// loader when creating the docShell as long as this xul:browser
// doesn't have the 'disablehistory' attribute set.
if (this.docShell && this.webNavigation.sessionHistory) {
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
os.addObserver(this, "browser:purge-session-history", false);
// enable global history if we weren't told otherwise
if (!this.hasAttribute("disableglobalhistory") && !this.isRemoteBrowser) {
try {
this.docShell.useGlobalHistory = true;
} catch(ex) {
// This can occur if the Places database is locked
Components.utils.reportError("Error enabling browser global history: " + ex);
}
}
}
}
catch (e) {
Components.utils.reportError(e);
}
try {
var securityUI = this.securityUI;
}
catch (e) {
}
// Listen for first load for lazy attachment to form fill controller
// (But we don't want to do this for remote browsers - the test infra
// might fire these events when they normally wouldn't.)
if (!this.isRemoteBrowser) {
this.addEventListener("pageshow", this.onPageShow, true);
this.addEventListener("pagehide", this.onPageHide, true);
}
if (this.messageManager) {
this.messageManager.addMessageListener("PopupBlocking:UpdateBlockedPopups", this);
this.messageManager.addMessageListener("Autoscroll:Start", this);
this.messageManager.addMessageListener("Autoscroll:Cancel", this);
}
]]>
</constructor>
<destructor>
<![CDATA[
this.destroy();
]]>
</destructor>
<!-- This is necessary because the destructor doesn't always get called when
we are removed from a tabbrowser. This will be explicitly called by tabbrowser -->
<method name="destroy">
<body>
<![CDATA[
if (this.mDestroyed)
return;
this.mDestroyed = true;
if (this.docShell && this.webNavigation.sessionHistory) {
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
try {
os.removeObserver(this, "browser:purge-session-history");
} catch (ex) {
// It's not clear why this sometimes throws an exception.
}
}
this.detachFormFill();
this._fastFind = null;
this._webBrowserFind = null;
// The feeds cache can keep the document inside this browser alive.
this.feeds = null;
this.lastURI = null;
if (!this.isRemoteBrowser) {
this.removeEventListener("pageshow", this.onPageShow, true);
this.removeEventListener("pagehide", this.onPageHide, true);
}
if (this._autoScrollNeedsCleanup) {
// we polluted the global scope, so clean it up
this._autoScrollPopup.parentNode.removeChild(this._autoScrollPopup);
}
]]>
</body>
</method>
<!--
We call this _receiveMessage (and alias receiveMessage to it) so that
bindings that inherit from this one can delegate to it.
-->
<method name="_receiveMessage">
<parameter name="aMessage"/>
<body><![CDATA[
let data = aMessage.data;
switch (aMessage.name) {
case "PopupBlocking:UpdateBlockedPopups": {
this.blockedPopups = data.blockedPopups;
if (this.blockedPopups) {
for (let i = 0; i < this.blockedPopups.length; i++) {
let scope = Components.utils.import("resource://gre/modules/BrowserUtils.jsm", {});
let uri = scope.BrowserUtils.makeURI(this.blockedPopups[i].popupWindowURI);
this.blockedPopups[i].popupWindowURI = uri;
}
if (data.freshPopup) {
this.blockedPopups.reported = false;
}
}
this.updateBlockedPopups();
break;
}
case "Autoscroll:Start": {
if (!this.autoscrollEnabled) {
return false;
}
this.startScroll(data.scrolldir, data.screenX, data.screenY);
return true;
}
case "Autoscroll:Cancel":
this._autoScrollPopup.hidePopup();
break;
}
]]></body>
</method>
<method name="receiveMessage">
<parameter name="aMessage"/>
<body><![CDATA[
return this._receiveMessage(aMessage);
]]></body>
</method>
<method name="observe">
<parameter name="aSubject"/>
<parameter name="aTopic"/>
<parameter name="aState"/>
<body>
<![CDATA[
if (aTopic != "browser:purge-session-history" || !this.sessionHistory)
return;
// place the entry at current index at the end of the history list, so it won't get removed
if (this.sessionHistory.index < this.sessionHistory.count - 1) {
var indexEntry = this.sessionHistory.getEntryAtIndex(this.sessionHistory.index, false);
this.sessionHistory.QueryInterface(Components.interfaces.nsISHistoryInternal);
indexEntry.QueryInterface(Components.interfaces.nsISHEntry);
this.sessionHistory.addEntry(indexEntry, true);
}
var purge = this.sessionHistory.count;
if (this.currentURI != "about:blank")
--purge; // Don't remove the page the user's staring at from shistory
if (purge > 0)
this.sessionHistory.PurgeHistory(purge);
]]>
</body>
</method>
<field name="_AUTOSCROLL_SNAP">10</field>
<field name="_scrolling">false</field>
<field name="_startX">null</field>
<field name="_startY">null</field>
<field name="_autoScrollPopup">null</field>
<field name="_autoScrollNeedsCleanup">false</field>
<method name="stopScroll">
<body>
<![CDATA[
if (this._scrolling) {
this._scrolling = false;
window.removeEventListener("mousemove", this, true);
window.removeEventListener("mousedown", this, true);
window.removeEventListener("mouseup", this, true);
window.removeEventListener("contextmenu", this, true);
window.removeEventListener("keydown", this, true);
window.removeEventListener("keypress", this, true);
window.removeEventListener("keyup", this, true);
this.messageManager.sendAsyncMessage("Autoscroll:Stop");
}
]]>
</body>
</method>
<method name="_createAutoScrollPopup">
<body>
<![CDATA[
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var popup = document.createElementNS(XUL_NS, "panel");
popup.className = "autoscroller";
// We set this attribute on the element so that mousemove
// events can be handled by browser-content.js.
popup.setAttribute("mousethrough", "always");
return popup;
]]>
</body>
</method>
<method name="startScroll">
<parameter name="scrolldir"/>
<parameter name="screenX"/>
<parameter name="screenY"/>
<body><![CDATA[
if (!this._autoScrollPopup) {
if (this.hasAttribute("autoscrollpopup")) {
// our creator provided a popup to share
this._autoScrollPopup = document.getElementById(this.getAttribute("autoscrollpopup"));
}
else {
// we weren't provided a popup; we have to use the global scope
this._autoScrollPopup = this._createAutoScrollPopup();
document.documentElement.appendChild(this._autoScrollPopup);
this._autoScrollNeedsCleanup = true;
}
}
// we need these attributes so themers don't need to create per-platform packages
if (screen.colorDepth > 8) { // need high color for transparency
// Exclude second-rate platforms
this._autoScrollPopup.setAttribute("transparent", !/BeOS|OS\/2/.test(navigator.appVersion));
// Enable translucency on Windows and Mac
this._autoScrollPopup.setAttribute("translucent", /Win|Mac/.test(navigator.platform));
}
this._autoScrollPopup.setAttribute("scrolldir", scrolldir);
this._autoScrollPopup.addEventListener("popuphidden", this, true);
this._autoScrollPopup.showPopup(document.documentElement,
screenX,
screenY,
"popup", null, null);
this._ignoreMouseEvents = true;
this._scrolling = true;
this._startX = screenX;
this._startY = screenY;
window.addEventListener("mousemove", this, true);
window.addEventListener("mousedown", this, true);
window.addEventListener("mouseup", this, true);
window.addEventListener("contextmenu", this, true);
window.addEventListener("keydown", this, true);
window.addEventListener("keypress", this, true);
window.addEventListener("keyup", this, true);
]]>
</body>
</method>
<method name="handleEvent">
<parameter name="aEvent"/>
<body>
<![CDATA[
if (this._scrolling) {
switch(aEvent.type) {
case "mousemove": {
var x = aEvent.screenX - this._startX;
var y = aEvent.screenY - this._startY;
if ((x > this._AUTOSCROLL_SNAP || x < -this._AUTOSCROLL_SNAP) ||
(y > this._AUTOSCROLL_SNAP || y < -this._AUTOSCROLL_SNAP))
this._ignoreMouseEvents = false;
break;
}
case "mouseup":
case "mousedown":
case "contextmenu": {
if (!this._ignoreMouseEvents) {
// Use a timeout to prevent the mousedown from opening the popup again.
// Ideally, we could use preventDefault here, but contenteditable
// and middlemouse paste don't interact well. See bug 1188536.
setTimeout(() => this._autoScrollPopup.hidePopup(), 0);
}
this._ignoreMouseEvents = false;
break;
}
case "popuphidden": {
this._autoScrollPopup.removeEventListener("popuphidden", this, true);
this.stopScroll();
break;
}
case "keydown": {
if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
// the escape key will be processed by
// nsXULPopupManager::KeyDown and the panel will be closed.
// So, don't consume the key event here.
break;
}
// don't break here. we need to eat keydown events.
}
case "keypress":
case "keyup": {
// All keyevents should be eaten here during autoscrolling.
aEvent.stopPropagation();
aEvent.preventDefault();
break;
}
}
}
]]>
</body>
</method>
<method name="swapDocShells">
<parameter name="aOtherBrowser"/>
<body>
<![CDATA[
if (this.isRemoteBrowser != aOtherBrowser.isRemoteBrowser)
throw new Error("Can only swap docshells between browsers in the same process.");
// Give others a chance to swap state.
let event = new CustomEvent("SwapDocShells", {"detail": aOtherBrowser});
this.dispatchEvent(event);
event = new CustomEvent("SwapDocShells", {"detail": this});
aOtherBrowser.dispatchEvent(event);
// We need to swap fields that are tied to our docshell or related to
// the loaded page
// Fields which are built as a result of notifactions (pageshow/hide,
// DOMLinkAdded/Removed, onStateChange) should not be swapped here,
// because these notifications are dispatched again once the docshells
// are swapped.
var fieldsToSwap = [
"_docShell",
"_webBrowserFind",
"_contentWindow",
"_webNavigation",
"_permanentKey",
"_innerWindowID",
];
var ourFieldValues = {};
var otherFieldValues = {};
for (let field of fieldsToSwap) {
ourFieldValues[field] = this[field];
otherFieldValues[field] = aOtherBrowser[field];
}
this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner)
.swapFrameLoaders(aOtherBrowser);
// Before we swap the actual docShell property we need to detach the
// form fill controller from those docShells.
this.detachFormFill();
aOtherBrowser.detachFormFill();
for (let field of fieldsToSwap) {
this[field] = otherFieldValues[field];
aOtherBrowser[field] = ourFieldValues[field];
}
// Re-attach the docShells to the form fill controller.
if (!this.isRemoteBrowser) {
this.attachFormFill();
}
if (!aOtherBrowser.isRemoteBrowser) {
aOtherBrowser.attachFormFill();
}
// Null the current nsITypeAheadFind instances so that they're
// lazily re-created on access. We need to do this because they
// might have attached the wrong docShell.
this._fastFind = aOtherBrowser._fastFind = null;
]]>
</body>
</method>
</implementation>
<handlers>
<handler event="keypress" keycode="VK_F7" group="system">
<![CDATA[
if (event.defaultPrevented || !event.isTrusted)
return;
const kPrefShortcutEnabled = "accessibility.browsewithcaret_shortcut.enabled";
const kPrefWarnOnEnable = "accessibility.warn_on_browsewithcaret";
const kPrefCaretBrowsingOn = "accessibility.browsewithcaret";
var isEnabled = this.mPrefs.getBoolPref(kPrefShortcutEnabled);
if (!isEnabled)
return;
// Toggle browse with caret mode
var browseWithCaretOn = false;
var warn = true;
try {
warn = this.mPrefs.getBoolPref(kPrefWarnOnEnable);
} catch (ex) {
}
try {
browseWithCaretOn = this.mPrefs.getBoolPref(kPrefCaretBrowsingOn);
} catch (ex) {
}
if (warn && !browseWithCaretOn) {
var checkValue = {value:false};
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService);
var buttonPressed = promptService.confirmEx(window,
this.mStrBundle.GetStringFromName('browsewithcaret.checkWindowTitle'),
this.mStrBundle.GetStringFromName('browsewithcaret.checkLabel'),
// Make "No" the default:
promptService.STD_YES_NO_BUTTONS | promptService.BUTTON_POS_1_DEFAULT,
null, null, null, this.mStrBundle.GetStringFromName('browsewithcaret.checkMsg'),
checkValue);
if (buttonPressed != 0) {
if (checkValue.value) {
try {
this.mPrefs.setBoolPref(kPrefShortcutEnabled, false);
} catch (ex) {
}
}
return;
}
if (checkValue.value) {
try {
this.mPrefs.setBoolPref(kPrefWarnOnEnable, false);
}
catch (ex) {
}
}
}
// Toggle the pref
try {
this.mPrefs.setBoolPref(kPrefCaretBrowsingOn, !browseWithCaretOn);
} catch (ex) {
}
]]>
</handler>
<handler event="dragover" group="system">
<![CDATA[
if (!this.droppedLinkHandler || event.defaultPrevented)
return;
// For drags that appear to be internal text (for example, tab drags),
// set the dropEffect to 'none'. This prevents the drop even if some
// other listener cancelled the event.
var types = event.dataTransfer.types;
if (types.contains("text/x-moz-text-internal") && !types.contains("text/plain")) {
event.dataTransfer.dropEffect = "none";
event.stopPropagation();
event.preventDefault();
}
let linkHandler = Components.classes["@mozilla.org/content/dropped-link-handler;1"].
getService(Components.interfaces.nsIDroppedLinkHandler);
if (linkHandler.canDropLink(event, false))
event.preventDefault();
]]>
</handler>
<handler event="drop" group="system">
<![CDATA[
// No need to handle "drop" in e10s, since nsDocShellTreeOwner.cpp in the child process
// handles that case using "@mozilla.org/content/dropped-link-handler;1" service.
if (!this.droppedLinkHandler || event.defaultPrevented || this.isRemoteBrowser)
return;
let name = { };
let linkHandler = Components.classes["@mozilla.org/content/dropped-link-handler;1"].
getService(Components.interfaces.nsIDroppedLinkHandler);
try {
// Pass true to prevent the dropping of javascript:/data: URIs
var uri = linkHandler.dropLink(event, name, true);
} catch (ex) {
return;
}
if (uri) {
this.droppedLinkHandler(event, uri, name.value);
}
]]>
</handler>
</handlers>
</binding>
</bindings>