toolkit/content/widgets/browser.xml

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 <?xml version="1.0"?>
     3 <!-- This Source Code Form is subject to the terms of the Mozilla Public
     4    - License, v. 2.0. If a copy of the MPL was not distributed with this
     5    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
     7 <!DOCTYPE bindings [
     8   <!ENTITY % findBarDTD SYSTEM "chrome://global/locale/findbar.dtd" >
     9   %findBarDTD;
    10 ]>
    12 <bindings id="browserBindings"
    13           xmlns="http://www.mozilla.org/xbl"
    14           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    16   <binding id="browser" extends="xul:browser" role="outerdoc">
    17     <content clickthrough="never">
    18       <children/>
    19     </content>
    20     <implementation type="application/javascript" implements="nsIObserver, nsIDOMEventListener, nsIFrameRequestCallback, nsIMessageListener">
    21       <property name="autoscrollEnabled">
    22         <getter>
    23           <![CDATA[
    24             if (this.getAttribute("autoscroll") == "false")
    25               return false;
    27             var enabled = true;
    28             try {
    29               enabled = this.mPrefs.getBoolPref("general.autoScroll");
    30             }
    31             catch(ex) {
    32             }
    34             return enabled;
    35           ]]>
    36         </getter>
    37       </property>
    39       <property name="canGoBack"
    40                 onget="return this.webNavigation.canGoBack;"
    41                 readonly="true"/>
    43       <property name="canGoForward"
    44                 onget="return this.webNavigation.canGoForward;"
    45                 readonly="true"/>
    47       <method name="goBack">
    48         <body>
    49           <![CDATA[
    50             var webNavigation = this.webNavigation;
    51             if (webNavigation.canGoBack) {
    52               try {
    53                 this.userTypedClear++;
    54                 webNavigation.goBack();
    55               } finally {
    56                 if (this.userTypedClear)
    57                   this.userTypedClear--;
    58               }
    59             }
    60           ]]>
    61         </body>
    62       </method>
    64       <method name="goForward">
    65         <body>
    66           <![CDATA[
    67             var webNavigation = this.webNavigation;
    68             if (webNavigation.canGoForward) {
    69               try {
    70                 this.userTypedClear++;
    71                 webNavigation.goForward();
    72               } finally {
    73                 if (this.userTypedClear)
    74                   this.userTypedClear--;
    75               }
    76             }
    77           ]]>
    78         </body>
    79       </method>
    81       <method name="reload">
    82         <body>
    83           <![CDATA[
    84             const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
    85             const flags = nsIWebNavigation.LOAD_FLAGS_NONE;
    86             this.reloadWithFlags(flags);
    87           ]]>
    88         </body>
    89       </method>
    91       <method name="reloadWithFlags">
    92         <parameter name="aFlags"/>
    93         <body>
    94           <![CDATA[
    95             this.webNavigation.reload(aFlags);
    96           ]]>
    97         </body>
    98       </method>
   100       <method name="stop">
   101         <body>
   102           <![CDATA[
   103             const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
   104             const flags = nsIWebNavigation.STOP_ALL;
   105             this.webNavigation.stop(flags);
   106           ]]>
   107         </body>
   108       </method>
   110       <!-- throws exception for unknown schemes -->
   111       <method name="loadURI">
   112         <parameter name="aURI"/>
   113         <parameter name="aReferrerURI"/>
   114         <parameter name="aCharset"/>
   115         <body>
   116           <![CDATA[
   117             const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
   118             const flags = nsIWebNavigation.LOAD_FLAGS_NONE;
   119             this.loadURIWithFlags(aURI, flags, aReferrerURI, aCharset);
   120           ]]>
   121         </body>
   122       </method>
   124       <!-- throws exception for unknown schemes -->
   125       <method name="loadURIWithFlags">
   126         <parameter name="aURI"/>
   127         <parameter name="aFlags"/>
   128         <parameter name="aReferrerURI"/>
   129         <parameter name="aCharset"/>
   130         <parameter name="aPostData"/>
   131         <body>
   132           <![CDATA[
   133             if (!aURI)
   134               aURI = "about:blank";
   136             if (aCharset) {
   137               try {
   138                 this.docShell.parentCharset = aCharset;
   139               }
   140               catch (e) {
   141               }
   142             }
   144             if (!(aFlags & this.webNavigation.LOAD_FLAGS_FROM_EXTERNAL))
   145               this.userTypedClear++;
   147             try {
   148               this.webNavigation.loadURI(aURI, aFlags, aReferrerURI, aPostData, null);
   149             } finally {
   150               if (this.userTypedClear)
   151                 this.userTypedClear--;
   152             }
   153           ]]>
   154         </body>
   155       </method>
   157       <method name="goHome">
   158         <body>
   159           <![CDATA[
   160             try {
   161               this.loadURI(this.homePage);
   162             }
   163             catch (e) {
   164             }
   165           ]]>
   166         </body>
   167       </method>
   169       <property name="homePage">
   170         <getter>
   171           <![CDATA[
   172             var uri;
   174             if (this.hasAttribute("homepage"))
   175               uri = this.getAttribute("homepage");
   176             else
   177               uri = "http://www.mozilla.org/"; // widget pride
   179             return uri;
   180           ]]>
   181         </getter>
   182         <setter>
   183           <![CDATA[
   184             this.setAttribute("homepage", val);
   185             return val;
   186           ]]>
   187         </setter>
   188       </property>
   190       <method name="gotoIndex">
   191         <parameter name="aIndex"/>
   192         <body>
   193           <![CDATA[
   194             try {
   195               this.userTypedClear++;
   196               this.webNavigation.gotoIndex(aIndex);
   197             } finally {
   198               if (this.userTypedClear)
   199                 this.userTypedClear--;
   200             }
   201           ]]>
   202         </body>
   203       </method>
   205       <property name="currentURI"
   206                 onget="return this.webNavigation.currentURI;"
   207                 readonly="true"/>
   209       <!--
   210         Used by session restore to ensure that currentURI is set so
   211         that switch-to-tab works before the tab is fully
   212         restored. This function also invokes onLocationChanged
   213         listeners in tabbrowser.xml.
   214       -->
   215       <method name="_setCurrentURI">
   216         <parameter name="aURI"/>
   217         <body><![CDATA[
   218           this.docShell.setCurrentURI(aURI);
   219         ]]></body>
   220       </method>
   222       <property name="documentURI"
   223                 onget="return this.contentDocument.documentURIObject;"
   224                 readonly="true"/>
   226       <property name="documentContentType"
   227                 onget="return this.contentDocument ? this.contentDocument.contentType : null;"
   228                 readonly="true"/>
   230       <property name="preferences"
   231                 onget="return this.mPrefs.QueryInterface(Components.interfaces.nsIPrefService);"
   232                 readonly="true"/>
   234       <field name="_docShell">null</field>
   236       <property name="docShell" readonly="true">
   237         <getter><![CDATA[
   238           if (this._docShell)
   239             return this._docShell;
   241           let frameLoader = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
   242           if (!frameLoader)
   243             return null;
   244           this._docShell = frameLoader.docShell;
   245           return this._docShell;
   246         ]]></getter>
   247       </property>
   249       <field name="_loadContext">null</field>
   251       <property name="loadContext" readonly="true">
   252         <getter><![CDATA[
   253           if (this._loadContext)
   254             return this._loadContext;
   256           let frameLoader = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
   257           if (!frameLoader)
   258             return null;
   259           this._loadContext = frameLoader.loadContext;
   260           return this._loadContext;
   261         ]]></getter>
   262       </property>
   264       <property name="docShellIsActive">
   265         <getter>
   266           <![CDATA[
   267             return this.docShell && this.docShell.isActive;
   268           ]]>
   269         </getter>
   270         <setter>
   271           <![CDATA[
   272             if (this.docShell)
   273               return this.docShell.isActive = val;
   274             return false;
   275           ]]>
   276         </setter>
   277       </property>
   279       <property name="imageDocument"
   280                 readonly="true">
   281         <getter>
   282           <![CDATA[
   283             var document = this.contentDocument;
   284             if (!document || !(document instanceof Ci.nsIImageDocument))
   285               return null;
   287             try {
   288                 return {width: document.imageRequest.image.width, height: document.imageRequest.image.height };
   289             } catch (e) {}
   290             return null;
   291           ]]>
   292         </getter>
   293       </property>
   295       <property name="isRemoteBrowser"
   296                 onget="return (this.getAttribute('remote') == 'true');"
   297                 readonly="true"/>
   299       <property name="messageManager"
   300                 onget="return this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.messageManager;"
   301                 readonly="true"/>
   303       <field name="_webNavigation">null</field>
   305       <property name="webNavigation"
   306                 readonly="true">
   307         <getter>
   308         <![CDATA[
   309           if (!this._webNavigation)
   310             this._webNavigation = this.docShell.QueryInterface(Components.interfaces.nsIWebNavigation);
   311           return this._webNavigation;
   312         ]]>
   313         </getter>
   314       </property>
   316       <field name="_webBrowserFind">null</field>
   318       <property name="webBrowserFind"
   319                 readonly="true">
   320         <getter>
   321         <![CDATA[
   322           if (!this._webBrowserFind)
   323             this._webBrowserFind = this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebBrowserFind);
   324           return this._webBrowserFind;
   325         ]]>
   326         </getter>
   327       </property>
   329       <method name="getTabBrowser">
   330         <body>
   331           <![CDATA[
   332             var tabBrowser = this.parentNode;
   333             while (tabBrowser && tabBrowser.localName != "tabbrowser")
   334               tabBrowser = tabBrowser.parentNode;
   335             return tabBrowser;
   336           ]]>
   337         </body>
   338       </method>
   340       <field name="_finder">null</field>
   342       <property name="finder" readonly="true">
   343         <getter><![CDATA[
   344           if (!this._finder) {
   345             if (!this.docShell)
   346               return null;
   348             let Finder = Components.utils.import("resource://gre/modules/Finder.jsm", {}).Finder;
   349             this._finder = new Finder(this.docShell);
   350           }
   351           return this._finder;
   352         ]]></getter>
   353       </property>
   355       <field name="_fastFind">null</field>
   356       <property name="fastFind" readonly="true">
   357         <getter><![CDATA[
   358           if (!this._fastFind) {
   359             if (!("@mozilla.org/typeaheadfind;1" in Components.classes))
   360               return null;
   362             var tabBrowser = this.getTabBrowser();
   363             if (tabBrowser && "fastFind" in tabBrowser)
   364               return this._fastFind = tabBrowser.fastFind;
   366             if (!this.docShell)
   367               return null;
   369             this._fastFind = Components.classes["@mozilla.org/typeaheadfind;1"]
   370                                        .createInstance(Components.interfaces.nsITypeAheadFind);
   371             this._fastFind.init(this.docShell);
   372           }
   373           return this._fastFind;
   374         ]]></getter>
   375       </property>
   377       <field name="_permanentKey">({})</field>
   379       <property name="permanentKey" readonly="true"
   380                 onget="return this._permanentKey;"/>
   382       <field name="_lastSearchString">null</field>
   383       <field name="_lastSearchHighlight">false</field>
   385       <property name="webProgress"
   386                 readonly="true"
   387                 onget="return this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);"/>
   389       <field name="_contentWindow">null</field>
   391       <property name="contentWindow"
   392                 readonly="true"
   393                 onget="return this._contentWindow || (this._contentWindow = this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindow));"/>
   395       <property name="sessionHistory"
   396                 onget="return this.webNavigation.sessionHistory;"
   397                 readonly="true"/>
   399       <property name="markupDocumentViewer"
   400                 onget="return this.docShell.contentViewer.QueryInterface(Components.interfaces.nsIMarkupDocumentViewer);"
   401                 readonly="true"/>
   403       <property name="contentViewerEdit"
   404                 onget="return this.docShell.contentViewer.QueryInterface(Components.interfaces.nsIContentViewerEdit);"
   405                 readonly="true"/>
   407       <property name="contentViewerFile"
   408                 onget="return this.docShell.contentViewer.QueryInterface(Components.interfaces.nsIContentViewerFile);"
   409                 readonly="true"/>
   411       <property name="contentDocument"
   412                 onget="return this.webNavigation.document;"
   413                 readonly="true"/>
   415       <property name="contentTitle"
   416                 onget="return this.contentDocument.title;"
   417                 readonly="true"/>
   419       <property name="characterSet"
   420                 onget="return this.contentDocument.characterSet;"
   421                 readonly="true"/>
   423       <property name="contentPrincipal"
   424                 onget="return this.contentDocument.nodePrincipal;"
   425                 readonly="true"/>
   427       <property name="showWindowResizer"
   428                 onset="if (val) this.setAttribute('showresizer', 'true');
   429                        else this.removeAttribute('showresizer');
   430                        return val;"
   431                 onget="return this.getAttribute('showresizer') == 'true';"/>
   434       <property name="fullZoom">
   435         <getter><![CDATA[
   436           return this.markupDocumentViewer.fullZoom;
   437         ]]></getter>
   438         <setter><![CDATA[
   439           this.markupDocumentViewer.fullZoom = val;
   440         ]]></setter>
   441       </property>
   443       <property name="textZoom">
   444         <getter><![CDATA[
   445           return this.markupDocumentViewer.textZoom;
   446         ]]></getter>
   447         <setter><![CDATA[
   448           this.markupDocumentViewer.textZoom = val;
   449         ]]></setter>
   450       </property>
   452       <property name="isSyntheticDocument">
   453         <getter><![CDATA[
   454           return this.contentDocument.mozSyntheticDocument;
   455         ]]></getter>
   456       </property>
   458       <field name="mPrefs" readonly="true">
   459         Components.classes['@mozilla.org/preferences-service;1']
   460                   .getService(Components.interfaces.nsIPrefBranch);
   461       </field>
   463       <field name="mAtomService" readonly="true">
   464         Components.classes['@mozilla.org/atom-service;1']
   465                   .getService(Components.interfaces.nsIAtomService);
   466       </field>
   468       <field name="_mStrBundle">null</field>
   470       <property name="mStrBundle">
   471         <getter>
   472         <![CDATA[
   473           if (!this._mStrBundle) {
   474             // need to create string bundle manually instead of using <xul:stringbundle/>
   475             // see bug 63370 for details
   476             this._mStrBundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
   477                                          .getService(Components.interfaces.nsIStringBundleService)
   478                                          .createBundle("chrome://global/locale/browser.properties");
   479           }
   480           return this._mStrBundle;
   481         ]]></getter>
   482       </property>
   484       <method name="addProgressListener">
   485         <parameter name="aListener"/>
   486         <parameter name="aNotifyMask"/>
   487         <body>
   488           <![CDATA[
   489             if (!aNotifyMask) {
   490               aNotifyMask = Components.interfaces.nsIWebProgress.NOTIFY_ALL;
   491             }
   492             this.webProgress.addProgressListener(aListener, aNotifyMask);
   493           ]]>
   494         </body>
   495       </method>
   497       <method name="removeProgressListener">
   498         <parameter name="aListener"/>
   499         <body>
   500           <![CDATA[
   501             this.webProgress.removeProgressListener(aListener);
   502          ]]>
   503         </body>
   504       </method>
   506       <method name="attachFormFill">
   507         <body>
   508           <![CDATA[
   509           if (!this.mFormFillAttached && this.hasAttribute("autocompletepopup")) {
   510             // hoop up the form fill autocomplete controller
   511             var controller = Components.classes["@mozilla.org/satchel/form-fill-controller;1"].
   512                                getService(Components.interfaces.nsIFormFillController);
   514             var popup = document.getElementById(this.getAttribute("autocompletepopup"));
   515             if (popup) {
   516               controller.attachToBrowser(this.docShell, popup.QueryInterface(Components.interfaces.nsIAutoCompletePopup));
   517               this.mFormFillAttached = true;
   518             }
   519           }
   520           ]]>
   521         </body>
   522       </method>
   524       <method name="detachFormFill">
   525         <body>
   526           <![CDATA[
   527           if (this.mFormFillAttached) {
   528             // hoop up the form fill autocomplete controller
   529             var controller = Components.classes["@mozilla.org/satchel/form-fill-controller;1"].
   530                                getService(Components.interfaces.nsIFormFillController);
   531             controller.detachFromBrowser(this.docShell);
   533             this.mFormFillAttached = false;
   534           }
   535           ]]>
   536         </body>
   537       </method>
   539       <method name="findChildShell">
   540         <parameter name="aDocShell"/>
   541         <parameter name="aSoughtURI"/>
   542         <body>
   543           <![CDATA[
   544             if (aDocShell.QueryInterface(Components.interfaces.nsIWebNavigation)
   545                          .currentURI.spec == aSoughtURI.spec)
   546               return aDocShell;
   547             var node = aDocShell.QueryInterface(
   548                                    Components.interfaces.nsIDocShellTreeItem);
   549             for (var i = 0; i < node.childCount; ++i) {
   550               var docShell = node.getChildAt(i);
   551               docShell = this.findChildShell(docShell, aSoughtURI);
   552               if (docShell)
   553                 return docShell;
   554             }
   555             return null;
   556           ]]>
   557         </body>
   558       </method>
   560       <method name="onPageShow">
   561         <parameter name="aEvent"/>
   562         <body>
   563           <![CDATA[
   564             this.attachFormFill();
   565          ]]>
   566         </body>
   567       </method>
   569       <method name="onPageHide">
   570         <parameter name="aEvent"/>
   571         <body>
   572           <![CDATA[
   573             // Delete the feeds cache if we're hiding the topmost page
   574             // (as opposed to one of its iframes).
   575             if (this.feeds && aEvent.target == this.contentDocument)
   576               this.feeds = null;
   577             if (!this.docShell || !this.fastFind)
   578               return;
   579             var tabBrowser = this.getTabBrowser();
   580             if (!tabBrowser || !("fastFind" in tabBrowser) ||
   581                 tabBrowser.selectedBrowser == this)
   582               this.fastFind.setDocShell(this.docShell);
   583          ]]>
   584         </body>
   585       </method>
   587       <method name="updateBlockedPopups">
   588         <parameter name="aBlockedPopups"/>
   589         <parameter name="aFreshPopup"/>
   590         <body>
   591           <![CDATA[
   592             this.blockedPopups = aBlockedPopups;
   593             if (aFreshPopup) {
   594               this.blockedPopups.reported = false;
   595             }
   597             var event = document.createEvent("Events");
   598             event.initEvent("DOMUpdatePageReport", true, true);
   599             this.dispatchEvent(event);
   600           ]]>
   601         </body>
   602       </method>
   604       <method name="unblockPopup">
   605         <parameter name="aPopupIndex"/>
   606         <body><![CDATA[
   607           this.messageManager.sendAsyncMessage("PopupBlocking:UnblockPopup",
   608                                                {index: aPopupIndex});
   609         ]]></body>
   610       </method>
   612       <field name="blockedPopups">null</field>
   614       <!-- Obsolete name for blockedPopups. Used by metro and android. -->
   615       <property name="pageReport"
   616          onget="return this.blockedPopups;"
   617          readonly="true"/>
   619       <property name="securityUI">
   620         <getter>
   621           <![CDATA[
   622             // Bug 666809 - SecurityUI support for e10s
   623             if (!this.docShell)
   624               return null;
   626             if (!this.docShell.securityUI) {
   627               const SECUREBROWSERUI_CONTRACTID = "@mozilla.org/secure_browser_ui;1";
   628               if (!this.hasAttribute("disablesecurity") &&
   629                   SECUREBROWSERUI_CONTRACTID in Components.classes) {
   630                 var securityUI = Components.classes[SECUREBROWSERUI_CONTRACTID]
   631                                            .createInstance(Components.interfaces.nsISecureBrowserUI);
   632                 securityUI.init(this.contentWindow);
   633               }
   634             }
   636             return this.docShell.securityUI;
   637           ]]>
   638         </getter>
   639         <setter>
   640           <![CDATA[
   641             this.docShell.securityUI = val;
   642           ]]>
   643         </setter>
   644       </property>
   646       <method name="adjustPriority">
   647         <parameter name="adjustment"/>
   648         <body><![CDATA[
   649           let loadGroup = this.webNavigation.QueryInterface(Ci.nsIDocumentLoader)
   650                               .loadGroup.QueryInterface(Ci.nsISupportsPriority);
   651           loadGroup.adjustPriority(adjustment);
   652         ]]></body>
   653       </method>
   655       <!--
   656         This field tracks the location bar state. The value that the user typed
   657         in to the location bar may not be changed while this field is zero.
   658         However invoking a load will temporarily increase this field to allow
   659         the location bar to be updated to the new URL.
   661         Case 1: Anchor scroll
   662           The user appends the anchor to the URL. This sets the location bar
   663           into typed state, and disables changes to the location bar. The user
   664           then requests the scroll. loadURIWithFlags temporarily increases the
   665           flag by 1 so that the anchor scroll's location change resets the
   666           location bar state.
   668         Case 2: Interrupted load
   669           The user types in and submits the URL. This triggers an asynchronous
   670           network load which increases the flag by 2. (The temporary increase
   671           from loadURIWithFlags is not noticeable in this case.) When the load
   672           is interrupted the flag returns to zero, and the location bar stays
   673           in typed state.
   675         Case 3: New load
   676           This works like case 2, but as the load is not interrupted the
   677           location changes while the flag is still 2 thus resetting the
   678           location bar state.
   680         Case 4: Corrected load
   681           This is a combination of case 2 and case 3, except that the original
   682           load is interrupted by the new load. Normally cancelling and starting
   683           a new load would reset the flag to 0 and then increase it to 2 again.
   684           However both actions occur as a consequence of the loadURIWithFlags
   685           invocation, which adds its temporary increase in to the mix. Since
   686           the new URL would have been typed in the flag would have been reset
   687           before loadURIWithFlags incremented it. The interruption resets the
   688           flag to 0 and increases it to 2. Although loadURIWithFlags will
   689           decrement the flag it remains at 1 thus allowing the location bar
   690           state to be reset when the new load changes the location.
   691           This case also applies when loading into a new browser, as this
   692           interrupts the default load of about:blank.
   693       -->
   694       <field name="userTypedClear">
   695         1
   696       </field>
   698       <field name="_userTypedValue">
   699         null
   700       </field>
   702       <property name="userTypedValue"
   703                 onget="return this._userTypedValue;">
   704         <setter><![CDATA[
   705           this.userTypedClear = 0;
   706           this._userTypedValue = val;
   707           return val;
   708         ]]></setter>
   709       </property>
   711       <field name="mFormFillAttached">
   712         false
   713       </field>
   715       <field name="isShowingMessage">
   716         false
   717       </field>
   719       <field name="droppedLinkHandler">
   720         null
   721       </field>
   723       <field name="mIconURL">null</field>
   725       <!-- This is managed by the tabbrowser -->
   726       <field name="lastURI">null</field>
   728       <field name="mDestroyed">false</field>
   730       <constructor>
   731         <![CDATA[
   732           try {
   733             // |webNavigation.sessionHistory| will have been set by the frame
   734             // loader when creating the docShell as long as this xul:browser
   735             // doesn't have the 'disablehistory' attribute set.
   736             if (this.docShell && this.webNavigation.sessionHistory) {
   737               var os = Components.classes["@mozilla.org/observer-service;1"]
   738                                  .getService(Components.interfaces.nsIObserverService);
   739               os.addObserver(this, "browser:purge-session-history", false);
   741               // enable global history if we weren't told otherwise
   742               if (!this.hasAttribute("disableglobalhistory") && !this.isRemoteBrowser) {
   743                 try {
   744                   this.docShell.useGlobalHistory = true;
   745                 } catch(ex) {
   746                   // This can occur if the Places database is locked
   747                   Components.utils.reportError("Error enabling browser global history: " + ex);
   748                 }
   749               }
   750             }
   751           }
   752           catch (e) {
   753             Components.utils.reportError(e);
   754           }
   755           try {
   756             var securityUI = this.securityUI;
   757           }
   758           catch (e) {
   759           }
   761           // Listen for first load for lazy attachment to form fill controller
   762           // (But we don't want to do this for remote browsers - the test infra
   763           // might fire these events when they normally wouldn't.)
   764           if (!this.isRemoteBrowser) {
   765             this.addEventListener("pageshow", this.onPageShow, true);
   766             this.addEventListener("pagehide", this.onPageHide, true);
   767           }
   769           if (this.messageManager) {
   770             this.messageManager.addMessageListener("PopupBlocking:UpdateBlockedPopups", this);
   771             this.messageManager.addMessageListener("Autoscroll:Start", this);
   772             this.messageManager.addMessageListener("Autoscroll:Cancel", this);
   773             this.messageManager.loadFrameScript("chrome://global/content/browser-content.js", true);
   774           }
   775         ]]>
   776       </constructor>
   778       <destructor>
   779         <![CDATA[
   780           this.destroy();
   781         ]]>
   782       </destructor>
   784       <!-- This is necessary because the destructor doesn't always get called when
   785            we are removed from a tabbrowser. This will be explicitly called by tabbrowser -->
   786       <method name="destroy">
   787         <body>
   788           <![CDATA[
   789           if (this.mDestroyed)
   790             return;
   791           this.mDestroyed = true;
   793           if (this.docShell && this.webNavigation.sessionHistory) {
   794             var os = Components.classes["@mozilla.org/observer-service;1"]
   795                                .getService(Components.interfaces.nsIObserverService);
   796             try {
   797               os.removeObserver(this, "browser:purge-session-history");
   798             } catch (ex) {
   799               // It's not clear why this sometimes throws an exception.
   800             }
   801           }
   803           this.detachFormFill();
   805           this._fastFind = null;
   806           this._webBrowserFind = null;
   808           // The feeds cache can keep the document inside this browser alive.
   809           this.feeds = null;
   811           this.lastURI = null;
   813           if (!this.isRemoteBrowser) {
   814             this.removeEventListener("pageshow", this.onPageShow, true);
   815             this.removeEventListener("pagehide", this.onPageHide, true);
   816           }
   818           if (this._autoScrollNeedsCleanup) {
   819             // we polluted the global scope, so clean it up
   820             this._autoScrollPopup.parentNode.removeChild(this._autoScrollPopup);
   821           }
   822           ]]>
   823         </body>
   824       </method>
   826       <!--
   827         We call this _receiveMessage (and alias receiveMessage to it) so that
   828         bindings that inherit from this one can delegate to it.
   829       -->
   830       <method name="_receiveMessage">
   831         <parameter name="aMessage"/>
   832         <body><![CDATA[
   833           let data = aMessage.data;
   834           switch (aMessage.name) {
   835 	    case "PopupBlocking:UpdateBlockedPopups":
   836               this.updateBlockedPopups(data.blockedPopups, data.freshPopup);
   837               break;
   838             case "Autoscroll:Start": {
   839               if (!this.autoscrollEnabled) {
   840                 return false;
   841               }
   842               let pos = this.mapScreenCoordinatesFromContent(data.screenX, data.screenY);
   843               this.startScroll(data.scrolldir, pos.x, pos.y);
   844               return true;
   845             }
   846             case "Autoscroll:Cancel":
   847               this._autoScrollPopup.hidePopup();
   848               break;
   849           }
   850         ]]></body>
   851       </method>
   853       <method name="receiveMessage">
   854         <parameter name="aMessage"/>
   855         <body><![CDATA[
   856           return this._receiveMessage(aMessage);
   857         ]]></body>
   858       </method>
   860       <method name="observe">
   861         <parameter name="aSubject"/>
   862         <parameter name="aTopic"/>
   863         <parameter name="aState"/>
   864         <body>
   865           <![CDATA[
   866             if (aTopic != "browser:purge-session-history" || !this.sessionHistory)
   867               return;
   869             // place the entry at current index at the end of the history list, so it won't get removed
   870             if (this.sessionHistory.index < this.sessionHistory.count - 1) {
   871               var indexEntry = this.sessionHistory.getEntryAtIndex(this.sessionHistory.index, false);
   872               this.sessionHistory.QueryInterface(Components.interfaces.nsISHistoryInternal);
   873               indexEntry.QueryInterface(Components.interfaces.nsISHEntry);
   874               this.sessionHistory.addEntry(indexEntry, true);
   875             }
   877             var purge = this.sessionHistory.count;
   878             if (this.currentURI != "about:blank")
   879               --purge; // Don't remove the page the user's staring at from shistory
   881             if (purge > 0)
   882               this.sessionHistory.PurgeHistory(purge);
   883           ]]>
   884         </body>
   885       </method>
   887       <field name="_AUTOSCROLL_SNAP">10</field>
   888       <field name="_scrolling">false</field>
   889       <field name="_startX">null</field>
   890       <field name="_startY">null</field>
   891       <field name="_autoScrollPopup">null</field>
   892       <field name="_autoScrollNeedsCleanup">false</field>
   894       <method name="stopScroll">
   895         <body>
   896           <![CDATA[
   897             if (this._scrolling) {
   898               this._scrolling = false;
   899               window.removeEventListener("mousemove", this, true);
   900               window.removeEventListener("mousedown", this, true);
   901               window.removeEventListener("mouseup", this, true);
   902               window.removeEventListener("contextmenu", this, true);
   903               window.removeEventListener("keydown", this, true);
   904               window.removeEventListener("keypress", this, true);
   905               window.removeEventListener("keyup", this, true);
   906               this.messageManager.sendAsyncMessage("Autoscroll:Stop");
   907             }
   908          ]]>
   909        </body>
   910      </method>
   912       <method name="_createAutoScrollPopup">
   913         <body>
   914           <![CDATA[
   915             const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
   916             var popup = document.createElementNS(XUL_NS, "panel");
   917             popup.className = "autoscroller";
   918             // We set this attribute on the element so that mousemove
   919             // events can be handled by browser-content.js.
   920             popup.setAttribute("mousethrough", "always");
   921             return popup;
   922           ]]>
   923         </body>
   924       </method>
   926       <method name="startScroll">
   927         <parameter name="scrolldir"/>
   928         <parameter name="screenX"/>
   929         <parameter name="screenY"/>
   930         <body><![CDATA[
   931             if (!this._autoScrollPopup) {
   932               if (this.hasAttribute("autoscrollpopup")) {
   933                 // our creator provided a popup to share
   934                 this._autoScrollPopup = document.getElementById(this.getAttribute("autoscrollpopup"));
   935               }
   936               else {
   937                 // we weren't provided a popup; we have to use the global scope
   938                 this._autoScrollPopup = this._createAutoScrollPopup();
   939                 document.documentElement.appendChild(this._autoScrollPopup);
   940                 this._autoScrollNeedsCleanup = true;
   941               }
   942             }
   944             // we need these attributes so themers don't need to create per-platform packages
   945             if (screen.colorDepth > 8) { // need high color for transparency
   946               // Exclude second-rate platforms
   947               this._autoScrollPopup.setAttribute("transparent", !/BeOS|OS\/2/.test(navigator.appVersion));
   948               // Enable translucency on Windows and Mac
   949               this._autoScrollPopup.setAttribute("translucent", /Win|Mac/.test(navigator.platform));
   950             }
   952             this._autoScrollPopup.setAttribute("scrolldir", scrolldir);
   953             this._autoScrollPopup.addEventListener("popuphidden", this, true);
   954             this._autoScrollPopup.showPopup(document.documentElement,
   955                                             screenX,
   956                                             screenY,
   957                                             "popup", null, null);
   958             this._ignoreMouseEvents = true;
   959             this._scrolling = true;
   960             this._startX = screenX;
   961             this._startY = screenY;
   963             window.addEventListener("mousemove", this, true);
   964             window.addEventListener("mousedown", this, true);
   965             window.addEventListener("mouseup", this, true);
   966             window.addEventListener("contextmenu", this, true);
   967             window.addEventListener("keydown", this, true);
   968             window.addEventListener("keypress", this, true);
   969             window.addEventListener("keyup", this, true);
   970          ]]>
   971        </body>
   972      </method>
   974       <method name="handleEvent">
   975         <parameter name="aEvent"/>
   976         <body>
   977         <![CDATA[
   978           if (this._scrolling) {
   979             switch(aEvent.type) {
   980               case "mousemove": {
   981                 var x = aEvent.screenX - this._startX;
   982                 var y = aEvent.screenY - this._startY;
   984                 if ((x > this._AUTOSCROLL_SNAP || x < -this._AUTOSCROLL_SNAP) ||
   985                     (y > this._AUTOSCROLL_SNAP || y < -this._AUTOSCROLL_SNAP))
   986                   this._ignoreMouseEvents = false;
   987                 break;
   988               }
   989               case "mouseup":
   990               case "mousedown":
   991               case "contextmenu": {
   992                 if (!this._ignoreMouseEvents)
   993                   this._autoScrollPopup.hidePopup();
   994                 this._ignoreMouseEvents = false;
   995                 break;
   996               }
   997               case "popuphidden": {
   998                 this._autoScrollPopup.removeEventListener("popuphidden", this, true);
   999                 this.stopScroll();
  1000                 break;
  1002               case "keydown": {
  1003                 if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
  1004                   // the escape key will be processed by
  1005                   // nsXULPopupManager::KeyDown and the panel will be closed.
  1006                   // So, don't consume the key event here.
  1007                   break;
  1009                 // don't break here. we need to eat keydown events.
  1011               case "keypress":
  1012               case "keyup": {
  1013                 // All keyevents should be eaten here during autoscrolling.
  1014                 aEvent.stopPropagation();
  1015                 aEvent.preventDefault();
  1016                 break;
  1020         ]]>
  1021         </body>
  1022       </method>
  1024       <!--
  1025         For out-of-process code, event.screen[XY] is relative to the
  1026         left/top of the content view. For in-process code,
  1027         event.screen[XY] is relative to the left/top of the screen. We
  1028         use this method to map screen coordinates received from a
  1029         (possibly out-of-process) <browser> element to coordinates
  1030         that are relative to the screen. This code handles the
  1031         in-process case, where we return the coordinates unchanged.
  1032       -->
  1033       <method name="mapScreenCoordinatesFromContent">
  1034         <parameter name="aScreenX"/>
  1035         <parameter name="aScreenY"/>
  1036         <body>
  1037         <![CDATA[
  1038           return { x: aScreenX, y: aScreenY };
  1039         ]]>
  1040         </body>
  1041       </method>
  1043       <method name="swapDocShells">
  1044         <parameter name="aOtherBrowser"/>
  1045         <body>
  1046         <![CDATA[
  1047           // We need to swap fields that are tied to our docshell or related to
  1048           // the loaded page
  1049           // Fields which are built as a result of notifactions (pageshow/hide,
  1050           // DOMLinkAdded/Removed, onStateChange) should not be swapped here,
  1051           // because these notifications are dispatched again once the docshells
  1052           // are swapped.
  1053           var fieldsToSwap = [
  1054             "_docShell",
  1055             "_webBrowserFind",
  1056             "_contentWindow",
  1057             "_webNavigation",
  1058             "_permanentKey"
  1059           ];
  1061           var ourFieldValues = {};
  1062           var otherFieldValues = {};
  1063           for each (var field in fieldsToSwap) {
  1064             ourFieldValues[field] = this[field];
  1065             otherFieldValues[field] = aOtherBrowser[field];
  1068           if (window.PopupNotifications)
  1069             PopupNotifications._swapBrowserNotifications(aOtherBrowser, this);
  1071           this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner)
  1072               .swapFrameLoaders(aOtherBrowser);
  1074           // Before we swap the actual docShell property we need to detach the
  1075           // form fill controller from those docShells.
  1076           this.detachFormFill();
  1077           aOtherBrowser.detachFormFill();
  1079           for each (var field in fieldsToSwap) {
  1080             this[field] = otherFieldValues[field];
  1081             aOtherBrowser[field] = ourFieldValues[field];
  1084           // Re-attach the docShells to the form fill controller.
  1085           this.attachFormFill();
  1086           aOtherBrowser.attachFormFill();
  1088           // Null the current nsITypeAheadFind instances so that they're
  1089           // lazily re-created on access. We need to do this because they
  1090           // might have attached the wrong docShell.
  1091           this._fastFind = aOtherBrowser._fastFind = null;
  1092         ]]>
  1093         </body>
  1094       </method>
  1095     </implementation>
  1097     <handlers>
  1098       <handler event="keypress" keycode="VK_F7" group="system">
  1099         <![CDATA[
  1100           if (event.defaultPrevented || !event.isTrusted)
  1101             return;
  1103           var isEnabled = this.mPrefs.getBoolPref("accessibility.browsewithcaret_shortcut.enabled");
  1104           if (!isEnabled)
  1105             return;
  1107           // Toggle browse with caret mode
  1108           var browseWithCaretOn = false;
  1109           var warn = true;
  1111           try {
  1112             warn = this.mPrefs.getBoolPref("accessibility.warn_on_browsewithcaret");
  1113           } catch (ex) {
  1116           try {
  1117             browseWithCaretOn = this.mPrefs.getBoolPref("accessibility.browsewithcaret");
  1118           } catch (ex) {
  1120           if (warn && !browseWithCaretOn) {
  1121             var checkValue = {value:false};
  1122             var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
  1123                                           .getService(Components.interfaces.nsIPromptService);
  1125             var buttonPressed = promptService.confirmEx(window,
  1126               this.mStrBundle.GetStringFromName('browsewithcaret.checkWindowTitle'),
  1127               this.mStrBundle.GetStringFromName('browsewithcaret.checkLabel'),
  1128               promptService.STD_YES_NO_BUTTONS,
  1129               null, null, null, this.mStrBundle.GetStringFromName('browsewithcaret.checkMsg'),
  1130               checkValue);
  1131             if (buttonPressed != 0)
  1132               return;
  1133             if (checkValue.value) {
  1134               try {
  1135                 this.mPrefs.setBoolPref("accessibility.warn_on_browsewithcaret", false);
  1137               catch (ex) {
  1142           // Toggle the pref
  1143           try {
  1144             this.mPrefs.setBoolPref("accessibility.browsewithcaret",!browseWithCaretOn);
  1145           } catch (ex) {
  1147         ]]>
  1148       </handler>
  1149       <handler event="dragover" group="system">
  1150       <![CDATA[
  1151         if (!this.droppedLinkHandler || event.defaultPrevented)
  1152           return;
  1154         // For drags that appear to be internal text (for example, tab drags),
  1155         // set the dropEffect to 'none'. This prevents the drop even if some
  1156         // other listener cancelled the event.
  1157         var types = event.dataTransfer.types;
  1158         if (types.contains("text/x-moz-text-internal") && !types.contains("text/plain")) {
  1159           event.dataTransfer.dropEffect = "none";
  1160           event.stopPropagation();
  1161           event.preventDefault();
  1164         let linkHandler = Components.classes["@mozilla.org/content/dropped-link-handler;1"].
  1165                             getService(Components.interfaces.nsIDroppedLinkHandler);
  1166         if (linkHandler.canDropLink(event, false))
  1167           event.preventDefault();
  1168       ]]>
  1169       </handler>
  1170       <handler event="drop" group="system">
  1171       <![CDATA[
  1172         if (!this.droppedLinkHandler || event.defaultPrevented)
  1173           return;
  1175         let name = { };
  1176         let linkHandler = Components.classes["@mozilla.org/content/dropped-link-handler;1"].
  1177                             getService(Components.interfaces.nsIDroppedLinkHandler);
  1178         try {
  1179           // Pass true to prevent the dropping of javascript:/data: URIs
  1180           var uri = linkHandler.dropLink(event, name, true);
  1181         } catch (ex) {
  1182           return;
  1185         if (uri) {
  1186           this.droppedLinkHandler(event, uri, name.value);
  1188       ]]>
  1189       </handler>
  1190     </handlers>
  1192   </binding>
  1194 </bindings>

mercurial