toolkit/content/widgets/browser.xml

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/content/widgets/browser.xml	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1194 @@
     1.4 +<?xml version="1.0"?>
     1.5 +
     1.6 +<!-- This Source Code Form is subject to the terms of the Mozilla Public
     1.7 +   - License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 +   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
     1.9 +
    1.10 +<!DOCTYPE bindings [
    1.11 +  <!ENTITY % findBarDTD SYSTEM "chrome://global/locale/findbar.dtd" >
    1.12 +  %findBarDTD;
    1.13 +]>
    1.14 +
    1.15 +<bindings id="browserBindings"
    1.16 +          xmlns="http://www.mozilla.org/xbl"
    1.17 +          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    1.18 +
    1.19 +  <binding id="browser" extends="xul:browser" role="outerdoc">
    1.20 +    <content clickthrough="never">
    1.21 +      <children/>
    1.22 +    </content>
    1.23 +    <implementation type="application/javascript" implements="nsIObserver, nsIDOMEventListener, nsIFrameRequestCallback, nsIMessageListener">
    1.24 +      <property name="autoscrollEnabled">
    1.25 +        <getter>
    1.26 +          <![CDATA[
    1.27 +            if (this.getAttribute("autoscroll") == "false")
    1.28 +              return false;
    1.29 +
    1.30 +            var enabled = true;
    1.31 +            try {
    1.32 +              enabled = this.mPrefs.getBoolPref("general.autoScroll");
    1.33 +            }
    1.34 +            catch(ex) {
    1.35 +            }
    1.36 +
    1.37 +            return enabled;
    1.38 +          ]]>
    1.39 +        </getter>
    1.40 +      </property>
    1.41 +
    1.42 +      <property name="canGoBack"
    1.43 +                onget="return this.webNavigation.canGoBack;"
    1.44 +                readonly="true"/>
    1.45 +
    1.46 +      <property name="canGoForward"
    1.47 +                onget="return this.webNavigation.canGoForward;"
    1.48 +                readonly="true"/>
    1.49 +
    1.50 +      <method name="goBack">
    1.51 +        <body>
    1.52 +          <![CDATA[
    1.53 +            var webNavigation = this.webNavigation;
    1.54 +            if (webNavigation.canGoBack) {
    1.55 +              try {
    1.56 +                this.userTypedClear++;
    1.57 +                webNavigation.goBack();
    1.58 +              } finally {
    1.59 +                if (this.userTypedClear)
    1.60 +                  this.userTypedClear--;
    1.61 +              }
    1.62 +            }
    1.63 +          ]]>
    1.64 +        </body>
    1.65 +      </method>
    1.66 +
    1.67 +      <method name="goForward">
    1.68 +        <body>
    1.69 +          <![CDATA[
    1.70 +            var webNavigation = this.webNavigation;
    1.71 +            if (webNavigation.canGoForward) {
    1.72 +              try {
    1.73 +                this.userTypedClear++;
    1.74 +                webNavigation.goForward();
    1.75 +              } finally {
    1.76 +                if (this.userTypedClear)
    1.77 +                  this.userTypedClear--;
    1.78 +              }
    1.79 +            }
    1.80 +          ]]>
    1.81 +        </body>
    1.82 +      </method>
    1.83 +
    1.84 +      <method name="reload">
    1.85 +        <body>
    1.86 +          <![CDATA[
    1.87 +            const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
    1.88 +            const flags = nsIWebNavigation.LOAD_FLAGS_NONE;
    1.89 +            this.reloadWithFlags(flags);
    1.90 +          ]]>
    1.91 +        </body>
    1.92 +      </method>
    1.93 +
    1.94 +      <method name="reloadWithFlags">
    1.95 +        <parameter name="aFlags"/>
    1.96 +        <body>
    1.97 +          <![CDATA[
    1.98 +            this.webNavigation.reload(aFlags);
    1.99 +          ]]>
   1.100 +        </body>
   1.101 +      </method>
   1.102 +
   1.103 +      <method name="stop">
   1.104 +        <body>
   1.105 +          <![CDATA[
   1.106 +            const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
   1.107 +            const flags = nsIWebNavigation.STOP_ALL;
   1.108 +            this.webNavigation.stop(flags);
   1.109 +          ]]>
   1.110 +        </body>
   1.111 +      </method>
   1.112 +
   1.113 +      <!-- throws exception for unknown schemes -->
   1.114 +      <method name="loadURI">
   1.115 +        <parameter name="aURI"/>
   1.116 +        <parameter name="aReferrerURI"/>
   1.117 +        <parameter name="aCharset"/>
   1.118 +        <body>
   1.119 +          <![CDATA[
   1.120 +            const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
   1.121 +            const flags = nsIWebNavigation.LOAD_FLAGS_NONE;
   1.122 +            this.loadURIWithFlags(aURI, flags, aReferrerURI, aCharset);
   1.123 +          ]]>
   1.124 +        </body>
   1.125 +      </method>
   1.126 +
   1.127 +      <!-- throws exception for unknown schemes -->
   1.128 +      <method name="loadURIWithFlags">
   1.129 +        <parameter name="aURI"/>
   1.130 +        <parameter name="aFlags"/>
   1.131 +        <parameter name="aReferrerURI"/>
   1.132 +        <parameter name="aCharset"/>
   1.133 +        <parameter name="aPostData"/>
   1.134 +        <body>
   1.135 +          <![CDATA[
   1.136 +            if (!aURI)
   1.137 +              aURI = "about:blank";
   1.138 +
   1.139 +            if (aCharset) {
   1.140 +              try {
   1.141 +                this.docShell.parentCharset = aCharset;
   1.142 +              }
   1.143 +              catch (e) {
   1.144 +              }
   1.145 +            }
   1.146 +
   1.147 +            if (!(aFlags & this.webNavigation.LOAD_FLAGS_FROM_EXTERNAL))
   1.148 +              this.userTypedClear++;
   1.149 +
   1.150 +            try {
   1.151 +              this.webNavigation.loadURI(aURI, aFlags, aReferrerURI, aPostData, null);
   1.152 +            } finally {
   1.153 +              if (this.userTypedClear)
   1.154 +                this.userTypedClear--;
   1.155 +            }
   1.156 +          ]]>
   1.157 +        </body>
   1.158 +      </method>
   1.159 +
   1.160 +      <method name="goHome">
   1.161 +        <body>
   1.162 +          <![CDATA[
   1.163 +            try {
   1.164 +              this.loadURI(this.homePage);
   1.165 +            }
   1.166 +            catch (e) {
   1.167 +            }
   1.168 +          ]]>
   1.169 +        </body>
   1.170 +      </method>
   1.171 +
   1.172 +      <property name="homePage">
   1.173 +        <getter>
   1.174 +          <![CDATA[
   1.175 +            var uri;
   1.176 +
   1.177 +            if (this.hasAttribute("homepage"))
   1.178 +              uri = this.getAttribute("homepage");
   1.179 +            else
   1.180 +              uri = "http://www.mozilla.org/"; // widget pride
   1.181 +
   1.182 +            return uri;
   1.183 +          ]]>
   1.184 +        </getter>
   1.185 +        <setter>
   1.186 +          <![CDATA[
   1.187 +            this.setAttribute("homepage", val);
   1.188 +            return val;
   1.189 +          ]]>
   1.190 +        </setter>
   1.191 +      </property>
   1.192 +
   1.193 +      <method name="gotoIndex">
   1.194 +        <parameter name="aIndex"/>
   1.195 +        <body>
   1.196 +          <![CDATA[
   1.197 +            try {
   1.198 +              this.userTypedClear++;
   1.199 +              this.webNavigation.gotoIndex(aIndex);
   1.200 +            } finally {
   1.201 +              if (this.userTypedClear)
   1.202 +                this.userTypedClear--;
   1.203 +            }
   1.204 +          ]]>
   1.205 +        </body>
   1.206 +      </method>
   1.207 +
   1.208 +      <property name="currentURI"
   1.209 +                onget="return this.webNavigation.currentURI;"
   1.210 +                readonly="true"/>
   1.211 +
   1.212 +      <!--
   1.213 +        Used by session restore to ensure that currentURI is set so
   1.214 +        that switch-to-tab works before the tab is fully
   1.215 +        restored. This function also invokes onLocationChanged
   1.216 +        listeners in tabbrowser.xml.
   1.217 +      -->
   1.218 +      <method name="_setCurrentURI">
   1.219 +        <parameter name="aURI"/>
   1.220 +        <body><![CDATA[
   1.221 +          this.docShell.setCurrentURI(aURI);
   1.222 +        ]]></body>
   1.223 +      </method>
   1.224 +
   1.225 +      <property name="documentURI"
   1.226 +                onget="return this.contentDocument.documentURIObject;"
   1.227 +                readonly="true"/>
   1.228 +
   1.229 +      <property name="documentContentType"
   1.230 +                onget="return this.contentDocument ? this.contentDocument.contentType : null;"
   1.231 +                readonly="true"/>
   1.232 +
   1.233 +      <property name="preferences"
   1.234 +                onget="return this.mPrefs.QueryInterface(Components.interfaces.nsIPrefService);"
   1.235 +                readonly="true"/>
   1.236 +
   1.237 +      <field name="_docShell">null</field>
   1.238 +
   1.239 +      <property name="docShell" readonly="true">
   1.240 +        <getter><![CDATA[
   1.241 +          if (this._docShell)
   1.242 +            return this._docShell;
   1.243 +
   1.244 +          let frameLoader = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
   1.245 +          if (!frameLoader)
   1.246 +            return null;
   1.247 +          this._docShell = frameLoader.docShell;
   1.248 +          return this._docShell;
   1.249 +        ]]></getter>
   1.250 +      </property>
   1.251 +
   1.252 +      <field name="_loadContext">null</field>
   1.253 +
   1.254 +      <property name="loadContext" readonly="true">
   1.255 +        <getter><![CDATA[
   1.256 +          if (this._loadContext)
   1.257 +            return this._loadContext;
   1.258 +
   1.259 +          let frameLoader = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
   1.260 +          if (!frameLoader)
   1.261 +            return null;
   1.262 +          this._loadContext = frameLoader.loadContext;
   1.263 +          return this._loadContext;
   1.264 +        ]]></getter>
   1.265 +      </property>
   1.266 +
   1.267 +      <property name="docShellIsActive">
   1.268 +        <getter>
   1.269 +          <![CDATA[
   1.270 +            return this.docShell && this.docShell.isActive;
   1.271 +          ]]>
   1.272 +        </getter>
   1.273 +        <setter>
   1.274 +          <![CDATA[
   1.275 +            if (this.docShell)
   1.276 +              return this.docShell.isActive = val;
   1.277 +            return false;
   1.278 +          ]]>
   1.279 +        </setter>
   1.280 +      </property>
   1.281 +
   1.282 +      <property name="imageDocument"
   1.283 +                readonly="true">
   1.284 +        <getter>
   1.285 +          <![CDATA[
   1.286 +            var document = this.contentDocument;
   1.287 +            if (!document || !(document instanceof Ci.nsIImageDocument))
   1.288 +              return null;
   1.289 +
   1.290 +            try {
   1.291 +                return {width: document.imageRequest.image.width, height: document.imageRequest.image.height };
   1.292 +            } catch (e) {}
   1.293 +            return null;
   1.294 +          ]]>
   1.295 +        </getter>
   1.296 +      </property>
   1.297 +
   1.298 +      <property name="isRemoteBrowser"
   1.299 +                onget="return (this.getAttribute('remote') == 'true');"
   1.300 +                readonly="true"/>
   1.301 +
   1.302 +      <property name="messageManager"
   1.303 +                onget="return this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.messageManager;"
   1.304 +                readonly="true"/>
   1.305 +
   1.306 +      <field name="_webNavigation">null</field>
   1.307 +
   1.308 +      <property name="webNavigation"
   1.309 +                readonly="true">
   1.310 +        <getter>
   1.311 +        <![CDATA[
   1.312 +          if (!this._webNavigation)
   1.313 +            this._webNavigation = this.docShell.QueryInterface(Components.interfaces.nsIWebNavigation);
   1.314 +          return this._webNavigation;
   1.315 +        ]]>
   1.316 +        </getter>
   1.317 +      </property>
   1.318 +
   1.319 +      <field name="_webBrowserFind">null</field>
   1.320 +
   1.321 +      <property name="webBrowserFind"
   1.322 +                readonly="true">
   1.323 +        <getter>
   1.324 +        <![CDATA[
   1.325 +          if (!this._webBrowserFind)
   1.326 +            this._webBrowserFind = this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebBrowserFind);
   1.327 +          return this._webBrowserFind;
   1.328 +        ]]>
   1.329 +        </getter>
   1.330 +      </property>
   1.331 +
   1.332 +      <method name="getTabBrowser">
   1.333 +        <body>
   1.334 +          <![CDATA[
   1.335 +            var tabBrowser = this.parentNode;
   1.336 +            while (tabBrowser && tabBrowser.localName != "tabbrowser")
   1.337 +              tabBrowser = tabBrowser.parentNode;
   1.338 +            return tabBrowser;
   1.339 +          ]]>
   1.340 +        </body>
   1.341 +      </method>
   1.342 +
   1.343 +      <field name="_finder">null</field>
   1.344 +
   1.345 +      <property name="finder" readonly="true">
   1.346 +        <getter><![CDATA[
   1.347 +          if (!this._finder) {
   1.348 +            if (!this.docShell)
   1.349 +              return null;
   1.350 +
   1.351 +            let Finder = Components.utils.import("resource://gre/modules/Finder.jsm", {}).Finder;
   1.352 +            this._finder = new Finder(this.docShell);
   1.353 +          }
   1.354 +          return this._finder;
   1.355 +        ]]></getter>
   1.356 +      </property>
   1.357 +
   1.358 +      <field name="_fastFind">null</field>
   1.359 +      <property name="fastFind" readonly="true">
   1.360 +        <getter><![CDATA[
   1.361 +          if (!this._fastFind) {
   1.362 +            if (!("@mozilla.org/typeaheadfind;1" in Components.classes))
   1.363 +              return null;
   1.364 +
   1.365 +            var tabBrowser = this.getTabBrowser();
   1.366 +            if (tabBrowser && "fastFind" in tabBrowser)
   1.367 +              return this._fastFind = tabBrowser.fastFind;
   1.368 +
   1.369 +            if (!this.docShell)
   1.370 +              return null;
   1.371 +
   1.372 +            this._fastFind = Components.classes["@mozilla.org/typeaheadfind;1"]
   1.373 +                                       .createInstance(Components.interfaces.nsITypeAheadFind);
   1.374 +            this._fastFind.init(this.docShell);
   1.375 +          }
   1.376 +          return this._fastFind;
   1.377 +        ]]></getter>
   1.378 +      </property>
   1.379 +
   1.380 +      <field name="_permanentKey">({})</field>
   1.381 +
   1.382 +      <property name="permanentKey" readonly="true"
   1.383 +                onget="return this._permanentKey;"/>
   1.384 +
   1.385 +      <field name="_lastSearchString">null</field>
   1.386 +      <field name="_lastSearchHighlight">false</field>
   1.387 +
   1.388 +      <property name="webProgress"
   1.389 +                readonly="true"
   1.390 +                onget="return this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);"/>
   1.391 +
   1.392 +      <field name="_contentWindow">null</field>
   1.393 +
   1.394 +      <property name="contentWindow"
   1.395 +                readonly="true"
   1.396 +                onget="return this._contentWindow || (this._contentWindow = this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindow));"/>
   1.397 +
   1.398 +      <property name="sessionHistory"
   1.399 +                onget="return this.webNavigation.sessionHistory;"
   1.400 +                readonly="true"/>
   1.401 +
   1.402 +      <property name="markupDocumentViewer"
   1.403 +                onget="return this.docShell.contentViewer.QueryInterface(Components.interfaces.nsIMarkupDocumentViewer);"
   1.404 +                readonly="true"/>
   1.405 +
   1.406 +      <property name="contentViewerEdit"
   1.407 +                onget="return this.docShell.contentViewer.QueryInterface(Components.interfaces.nsIContentViewerEdit);"
   1.408 +                readonly="true"/>
   1.409 +
   1.410 +      <property name="contentViewerFile"
   1.411 +                onget="return this.docShell.contentViewer.QueryInterface(Components.interfaces.nsIContentViewerFile);"
   1.412 +                readonly="true"/>
   1.413 +
   1.414 +      <property name="contentDocument"
   1.415 +                onget="return this.webNavigation.document;"
   1.416 +                readonly="true"/>
   1.417 +
   1.418 +      <property name="contentTitle"
   1.419 +                onget="return this.contentDocument.title;"
   1.420 +                readonly="true"/>
   1.421 +
   1.422 +      <property name="characterSet"
   1.423 +                onget="return this.contentDocument.characterSet;"
   1.424 +                readonly="true"/>
   1.425 +
   1.426 +      <property name="contentPrincipal"
   1.427 +                onget="return this.contentDocument.nodePrincipal;"
   1.428 +                readonly="true"/>
   1.429 +
   1.430 +      <property name="showWindowResizer"
   1.431 +                onset="if (val) this.setAttribute('showresizer', 'true');
   1.432 +                       else this.removeAttribute('showresizer');
   1.433 +                       return val;"
   1.434 +                onget="return this.getAttribute('showresizer') == 'true';"/>
   1.435 +
   1.436 +
   1.437 +      <property name="fullZoom">
   1.438 +        <getter><![CDATA[
   1.439 +          return this.markupDocumentViewer.fullZoom;
   1.440 +        ]]></getter>
   1.441 +        <setter><![CDATA[
   1.442 +          this.markupDocumentViewer.fullZoom = val;
   1.443 +        ]]></setter>
   1.444 +      </property>
   1.445 +
   1.446 +      <property name="textZoom">
   1.447 +        <getter><![CDATA[
   1.448 +          return this.markupDocumentViewer.textZoom;
   1.449 +        ]]></getter>
   1.450 +        <setter><![CDATA[
   1.451 +          this.markupDocumentViewer.textZoom = val;
   1.452 +        ]]></setter>
   1.453 +      </property>
   1.454 +
   1.455 +      <property name="isSyntheticDocument">
   1.456 +        <getter><![CDATA[
   1.457 +          return this.contentDocument.mozSyntheticDocument;
   1.458 +        ]]></getter>
   1.459 +      </property>
   1.460 +
   1.461 +      <field name="mPrefs" readonly="true">
   1.462 +        Components.classes['@mozilla.org/preferences-service;1']
   1.463 +                  .getService(Components.interfaces.nsIPrefBranch);
   1.464 +      </field>
   1.465 +
   1.466 +      <field name="mAtomService" readonly="true">
   1.467 +        Components.classes['@mozilla.org/atom-service;1']
   1.468 +                  .getService(Components.interfaces.nsIAtomService);
   1.469 +      </field>
   1.470 +
   1.471 +      <field name="_mStrBundle">null</field>
   1.472 +
   1.473 +      <property name="mStrBundle">
   1.474 +        <getter>
   1.475 +        <![CDATA[
   1.476 +          if (!this._mStrBundle) {
   1.477 +            // need to create string bundle manually instead of using <xul:stringbundle/>
   1.478 +            // see bug 63370 for details
   1.479 +            this._mStrBundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
   1.480 +                                         .getService(Components.interfaces.nsIStringBundleService)
   1.481 +                                         .createBundle("chrome://global/locale/browser.properties");
   1.482 +          }
   1.483 +          return this._mStrBundle;
   1.484 +        ]]></getter>
   1.485 +      </property>
   1.486 +
   1.487 +      <method name="addProgressListener">
   1.488 +        <parameter name="aListener"/>
   1.489 +        <parameter name="aNotifyMask"/>
   1.490 +        <body>
   1.491 +          <![CDATA[
   1.492 +            if (!aNotifyMask) {
   1.493 +              aNotifyMask = Components.interfaces.nsIWebProgress.NOTIFY_ALL;
   1.494 +            }
   1.495 +            this.webProgress.addProgressListener(aListener, aNotifyMask);
   1.496 +          ]]>
   1.497 +        </body>
   1.498 +      </method>
   1.499 +
   1.500 +      <method name="removeProgressListener">
   1.501 +        <parameter name="aListener"/>
   1.502 +        <body>
   1.503 +          <![CDATA[
   1.504 +            this.webProgress.removeProgressListener(aListener);
   1.505 +         ]]>
   1.506 +        </body>
   1.507 +      </method>
   1.508 +
   1.509 +      <method name="attachFormFill">
   1.510 +        <body>
   1.511 +          <![CDATA[
   1.512 +          if (!this.mFormFillAttached && this.hasAttribute("autocompletepopup")) {
   1.513 +            // hoop up the form fill autocomplete controller
   1.514 +            var controller = Components.classes["@mozilla.org/satchel/form-fill-controller;1"].
   1.515 +                               getService(Components.interfaces.nsIFormFillController);
   1.516 +
   1.517 +            var popup = document.getElementById(this.getAttribute("autocompletepopup"));
   1.518 +            if (popup) {
   1.519 +              controller.attachToBrowser(this.docShell, popup.QueryInterface(Components.interfaces.nsIAutoCompletePopup));
   1.520 +              this.mFormFillAttached = true;
   1.521 +            }
   1.522 +          }
   1.523 +          ]]>
   1.524 +        </body>
   1.525 +      </method>
   1.526 +
   1.527 +      <method name="detachFormFill">
   1.528 +        <body>
   1.529 +          <![CDATA[
   1.530 +          if (this.mFormFillAttached) {
   1.531 +            // hoop up the form fill autocomplete controller
   1.532 +            var controller = Components.classes["@mozilla.org/satchel/form-fill-controller;1"].
   1.533 +                               getService(Components.interfaces.nsIFormFillController);
   1.534 +            controller.detachFromBrowser(this.docShell);
   1.535 +
   1.536 +            this.mFormFillAttached = false;
   1.537 +          }
   1.538 +          ]]>
   1.539 +        </body>
   1.540 +      </method>
   1.541 +
   1.542 +      <method name="findChildShell">
   1.543 +        <parameter name="aDocShell"/>
   1.544 +        <parameter name="aSoughtURI"/>
   1.545 +        <body>
   1.546 +          <![CDATA[
   1.547 +            if (aDocShell.QueryInterface(Components.interfaces.nsIWebNavigation)
   1.548 +                         .currentURI.spec == aSoughtURI.spec)
   1.549 +              return aDocShell;
   1.550 +            var node = aDocShell.QueryInterface(
   1.551 +                                   Components.interfaces.nsIDocShellTreeItem);
   1.552 +            for (var i = 0; i < node.childCount; ++i) {
   1.553 +              var docShell = node.getChildAt(i);
   1.554 +              docShell = this.findChildShell(docShell, aSoughtURI);
   1.555 +              if (docShell)
   1.556 +                return docShell;
   1.557 +            }
   1.558 +            return null;
   1.559 +          ]]>
   1.560 +        </body>
   1.561 +      </method>
   1.562 +
   1.563 +      <method name="onPageShow">
   1.564 +        <parameter name="aEvent"/>
   1.565 +        <body>
   1.566 +          <![CDATA[
   1.567 +            this.attachFormFill();
   1.568 +         ]]>
   1.569 +        </body>
   1.570 +      </method>
   1.571 +
   1.572 +      <method name="onPageHide">
   1.573 +        <parameter name="aEvent"/>
   1.574 +        <body>
   1.575 +          <![CDATA[
   1.576 +            // Delete the feeds cache if we're hiding the topmost page
   1.577 +            // (as opposed to one of its iframes).
   1.578 +            if (this.feeds && aEvent.target == this.contentDocument)
   1.579 +              this.feeds = null;
   1.580 +            if (!this.docShell || !this.fastFind)
   1.581 +              return;
   1.582 +            var tabBrowser = this.getTabBrowser();
   1.583 +            if (!tabBrowser || !("fastFind" in tabBrowser) ||
   1.584 +                tabBrowser.selectedBrowser == this)
   1.585 +              this.fastFind.setDocShell(this.docShell);
   1.586 +         ]]>
   1.587 +        </body>
   1.588 +      </method>
   1.589 +
   1.590 +      <method name="updateBlockedPopups">
   1.591 +        <parameter name="aBlockedPopups"/>
   1.592 +        <parameter name="aFreshPopup"/>
   1.593 +        <body>
   1.594 +          <![CDATA[
   1.595 +            this.blockedPopups = aBlockedPopups;
   1.596 +            if (aFreshPopup) {
   1.597 +              this.blockedPopups.reported = false;
   1.598 +            }
   1.599 +
   1.600 +            var event = document.createEvent("Events");
   1.601 +            event.initEvent("DOMUpdatePageReport", true, true);
   1.602 +            this.dispatchEvent(event);
   1.603 +          ]]>
   1.604 +        </body>
   1.605 +      </method>
   1.606 +
   1.607 +      <method name="unblockPopup">
   1.608 +        <parameter name="aPopupIndex"/>
   1.609 +        <body><![CDATA[
   1.610 +          this.messageManager.sendAsyncMessage("PopupBlocking:UnblockPopup",
   1.611 +                                               {index: aPopupIndex});
   1.612 +        ]]></body>
   1.613 +      </method>
   1.614 +
   1.615 +      <field name="blockedPopups">null</field>
   1.616 +
   1.617 +      <!-- Obsolete name for blockedPopups. Used by metro and android. -->
   1.618 +      <property name="pageReport"
   1.619 +         onget="return this.blockedPopups;"
   1.620 +         readonly="true"/>
   1.621 +
   1.622 +      <property name="securityUI">
   1.623 +        <getter>
   1.624 +          <![CDATA[
   1.625 +            // Bug 666809 - SecurityUI support for e10s
   1.626 +            if (!this.docShell)
   1.627 +              return null;
   1.628 +
   1.629 +            if (!this.docShell.securityUI) {
   1.630 +              const SECUREBROWSERUI_CONTRACTID = "@mozilla.org/secure_browser_ui;1";
   1.631 +              if (!this.hasAttribute("disablesecurity") &&
   1.632 +                  SECUREBROWSERUI_CONTRACTID in Components.classes) {
   1.633 +                var securityUI = Components.classes[SECUREBROWSERUI_CONTRACTID]
   1.634 +                                           .createInstance(Components.interfaces.nsISecureBrowserUI);
   1.635 +                securityUI.init(this.contentWindow);
   1.636 +              }
   1.637 +            }
   1.638 +
   1.639 +            return this.docShell.securityUI;
   1.640 +          ]]>
   1.641 +        </getter>
   1.642 +        <setter>
   1.643 +          <![CDATA[
   1.644 +            this.docShell.securityUI = val;
   1.645 +          ]]>
   1.646 +        </setter>
   1.647 +      </property>
   1.648 +
   1.649 +      <method name="adjustPriority">
   1.650 +        <parameter name="adjustment"/>
   1.651 +        <body><![CDATA[
   1.652 +          let loadGroup = this.webNavigation.QueryInterface(Ci.nsIDocumentLoader)
   1.653 +                              .loadGroup.QueryInterface(Ci.nsISupportsPriority);
   1.654 +          loadGroup.adjustPriority(adjustment);
   1.655 +        ]]></body>
   1.656 +      </method>
   1.657 +
   1.658 +      <!--
   1.659 +        This field tracks the location bar state. The value that the user typed
   1.660 +        in to the location bar may not be changed while this field is zero.
   1.661 +        However invoking a load will temporarily increase this field to allow
   1.662 +        the location bar to be updated to the new URL.
   1.663 +
   1.664 +        Case 1: Anchor scroll
   1.665 +          The user appends the anchor to the URL. This sets the location bar
   1.666 +          into typed state, and disables changes to the location bar. The user
   1.667 +          then requests the scroll. loadURIWithFlags temporarily increases the
   1.668 +          flag by 1 so that the anchor scroll's location change resets the
   1.669 +          location bar state.
   1.670 +
   1.671 +        Case 2: Interrupted load
   1.672 +          The user types in and submits the URL. This triggers an asynchronous
   1.673 +          network load which increases the flag by 2. (The temporary increase
   1.674 +          from loadURIWithFlags is not noticeable in this case.) When the load
   1.675 +          is interrupted the flag returns to zero, and the location bar stays
   1.676 +          in typed state.
   1.677 +
   1.678 +        Case 3: New load
   1.679 +          This works like case 2, but as the load is not interrupted the
   1.680 +          location changes while the flag is still 2 thus resetting the
   1.681 +          location bar state.
   1.682 +
   1.683 +        Case 4: Corrected load
   1.684 +          This is a combination of case 2 and case 3, except that the original
   1.685 +          load is interrupted by the new load. Normally cancelling and starting
   1.686 +          a new load would reset the flag to 0 and then increase it to 2 again.
   1.687 +          However both actions occur as a consequence of the loadURIWithFlags
   1.688 +          invocation, which adds its temporary increase in to the mix. Since
   1.689 +          the new URL would have been typed in the flag would have been reset
   1.690 +          before loadURIWithFlags incremented it. The interruption resets the
   1.691 +          flag to 0 and increases it to 2. Although loadURIWithFlags will
   1.692 +          decrement the flag it remains at 1 thus allowing the location bar
   1.693 +          state to be reset when the new load changes the location.
   1.694 +          This case also applies when loading into a new browser, as this
   1.695 +          interrupts the default load of about:blank.
   1.696 +      -->
   1.697 +      <field name="userTypedClear">
   1.698 +        1
   1.699 +      </field>
   1.700 +
   1.701 +      <field name="_userTypedValue">
   1.702 +        null
   1.703 +      </field>
   1.704 +
   1.705 +      <property name="userTypedValue"
   1.706 +                onget="return this._userTypedValue;">
   1.707 +        <setter><![CDATA[
   1.708 +          this.userTypedClear = 0;
   1.709 +          this._userTypedValue = val;
   1.710 +          return val;
   1.711 +        ]]></setter>
   1.712 +      </property>
   1.713 +
   1.714 +      <field name="mFormFillAttached">
   1.715 +        false
   1.716 +      </field>
   1.717 +
   1.718 +      <field name="isShowingMessage">
   1.719 +        false
   1.720 +      </field>
   1.721 +
   1.722 +      <field name="droppedLinkHandler">
   1.723 +        null
   1.724 +      </field>
   1.725 +
   1.726 +      <field name="mIconURL">null</field>
   1.727 +
   1.728 +      <!-- This is managed by the tabbrowser -->
   1.729 +      <field name="lastURI">null</field>
   1.730 +
   1.731 +      <field name="mDestroyed">false</field>
   1.732 +
   1.733 +      <constructor>
   1.734 +        <![CDATA[
   1.735 +          try {
   1.736 +            // |webNavigation.sessionHistory| will have been set by the frame
   1.737 +            // loader when creating the docShell as long as this xul:browser
   1.738 +            // doesn't have the 'disablehistory' attribute set.
   1.739 +            if (this.docShell && this.webNavigation.sessionHistory) {
   1.740 +              var os = Components.classes["@mozilla.org/observer-service;1"]
   1.741 +                                 .getService(Components.interfaces.nsIObserverService);
   1.742 +              os.addObserver(this, "browser:purge-session-history", false);
   1.743 +
   1.744 +              // enable global history if we weren't told otherwise
   1.745 +              if (!this.hasAttribute("disableglobalhistory") && !this.isRemoteBrowser) {
   1.746 +                try {
   1.747 +                  this.docShell.useGlobalHistory = true;
   1.748 +                } catch(ex) {
   1.749 +                  // This can occur if the Places database is locked
   1.750 +                  Components.utils.reportError("Error enabling browser global history: " + ex);
   1.751 +                }
   1.752 +              }
   1.753 +            }
   1.754 +          }
   1.755 +          catch (e) {
   1.756 +            Components.utils.reportError(e);
   1.757 +          }
   1.758 +          try {
   1.759 +            var securityUI = this.securityUI;
   1.760 +          }
   1.761 +          catch (e) {
   1.762 +          }
   1.763 +
   1.764 +          // Listen for first load for lazy attachment to form fill controller
   1.765 +          // (But we don't want to do this for remote browsers - the test infra
   1.766 +          // might fire these events when they normally wouldn't.)
   1.767 +          if (!this.isRemoteBrowser) {
   1.768 +            this.addEventListener("pageshow", this.onPageShow, true);
   1.769 +            this.addEventListener("pagehide", this.onPageHide, true);
   1.770 +          }
   1.771 +
   1.772 +          if (this.messageManager) {
   1.773 +            this.messageManager.addMessageListener("PopupBlocking:UpdateBlockedPopups", this);
   1.774 +            this.messageManager.addMessageListener("Autoscroll:Start", this);
   1.775 +            this.messageManager.addMessageListener("Autoscroll:Cancel", this);
   1.776 +            this.messageManager.loadFrameScript("chrome://global/content/browser-content.js", true);
   1.777 +          }
   1.778 +        ]]>
   1.779 +      </constructor>
   1.780 +
   1.781 +      <destructor>
   1.782 +        <![CDATA[
   1.783 +          this.destroy();
   1.784 +        ]]>
   1.785 +      </destructor>
   1.786 +
   1.787 +      <!-- This is necessary because the destructor doesn't always get called when
   1.788 +           we are removed from a tabbrowser. This will be explicitly called by tabbrowser -->
   1.789 +      <method name="destroy">
   1.790 +        <body>
   1.791 +          <![CDATA[
   1.792 +          if (this.mDestroyed)
   1.793 +            return;
   1.794 +          this.mDestroyed = true;
   1.795 +
   1.796 +          if (this.docShell && this.webNavigation.sessionHistory) {
   1.797 +            var os = Components.classes["@mozilla.org/observer-service;1"]
   1.798 +                               .getService(Components.interfaces.nsIObserverService);
   1.799 +            try {
   1.800 +              os.removeObserver(this, "browser:purge-session-history");
   1.801 +            } catch (ex) {
   1.802 +              // It's not clear why this sometimes throws an exception.
   1.803 +            }
   1.804 +          }
   1.805 +
   1.806 +          this.detachFormFill();
   1.807 +
   1.808 +          this._fastFind = null;
   1.809 +          this._webBrowserFind = null;
   1.810 +
   1.811 +          // The feeds cache can keep the document inside this browser alive.
   1.812 +          this.feeds = null;
   1.813 +
   1.814 +          this.lastURI = null;
   1.815 +
   1.816 +          if (!this.isRemoteBrowser) {
   1.817 +            this.removeEventListener("pageshow", this.onPageShow, true);
   1.818 +            this.removeEventListener("pagehide", this.onPageHide, true);
   1.819 +          }
   1.820 +
   1.821 +          if (this._autoScrollNeedsCleanup) {
   1.822 +            // we polluted the global scope, so clean it up
   1.823 +            this._autoScrollPopup.parentNode.removeChild(this._autoScrollPopup);
   1.824 +          }
   1.825 +          ]]>
   1.826 +        </body>
   1.827 +      </method>
   1.828 +
   1.829 +      <!--
   1.830 +        We call this _receiveMessage (and alias receiveMessage to it) so that
   1.831 +        bindings that inherit from this one can delegate to it.
   1.832 +      -->
   1.833 +      <method name="_receiveMessage">
   1.834 +        <parameter name="aMessage"/>
   1.835 +        <body><![CDATA[
   1.836 +          let data = aMessage.data;
   1.837 +          switch (aMessage.name) {
   1.838 +	    case "PopupBlocking:UpdateBlockedPopups":
   1.839 +              this.updateBlockedPopups(data.blockedPopups, data.freshPopup);
   1.840 +              break;
   1.841 +            case "Autoscroll:Start": {
   1.842 +              if (!this.autoscrollEnabled) {
   1.843 +                return false;
   1.844 +              }
   1.845 +              let pos = this.mapScreenCoordinatesFromContent(data.screenX, data.screenY);
   1.846 +              this.startScroll(data.scrolldir, pos.x, pos.y);
   1.847 +              return true;
   1.848 +            }
   1.849 +            case "Autoscroll:Cancel":
   1.850 +              this._autoScrollPopup.hidePopup();
   1.851 +              break;
   1.852 +          }
   1.853 +        ]]></body>
   1.854 +      </method>
   1.855 +
   1.856 +      <method name="receiveMessage">
   1.857 +        <parameter name="aMessage"/>
   1.858 +        <body><![CDATA[
   1.859 +          return this._receiveMessage(aMessage);
   1.860 +        ]]></body>
   1.861 +      </method>
   1.862 +
   1.863 +      <method name="observe">
   1.864 +        <parameter name="aSubject"/>
   1.865 +        <parameter name="aTopic"/>
   1.866 +        <parameter name="aState"/>
   1.867 +        <body>
   1.868 +          <![CDATA[
   1.869 +            if (aTopic != "browser:purge-session-history" || !this.sessionHistory)
   1.870 +              return;
   1.871 +
   1.872 +            // place the entry at current index at the end of the history list, so it won't get removed
   1.873 +            if (this.sessionHistory.index < this.sessionHistory.count - 1) {
   1.874 +              var indexEntry = this.sessionHistory.getEntryAtIndex(this.sessionHistory.index, false);
   1.875 +              this.sessionHistory.QueryInterface(Components.interfaces.nsISHistoryInternal);
   1.876 +              indexEntry.QueryInterface(Components.interfaces.nsISHEntry);
   1.877 +              this.sessionHistory.addEntry(indexEntry, true);
   1.878 +            }
   1.879 +
   1.880 +            var purge = this.sessionHistory.count;
   1.881 +            if (this.currentURI != "about:blank")
   1.882 +              --purge; // Don't remove the page the user's staring at from shistory
   1.883 +
   1.884 +            if (purge > 0)
   1.885 +              this.sessionHistory.PurgeHistory(purge);
   1.886 +          ]]>
   1.887 +        </body>
   1.888 +      </method>
   1.889 +
   1.890 +      <field name="_AUTOSCROLL_SNAP">10</field>
   1.891 +      <field name="_scrolling">false</field>
   1.892 +      <field name="_startX">null</field>
   1.893 +      <field name="_startY">null</field>
   1.894 +      <field name="_autoScrollPopup">null</field>
   1.895 +      <field name="_autoScrollNeedsCleanup">false</field>
   1.896 +
   1.897 +      <method name="stopScroll">
   1.898 +        <body>
   1.899 +          <![CDATA[
   1.900 +            if (this._scrolling) {
   1.901 +              this._scrolling = false;
   1.902 +              window.removeEventListener("mousemove", this, true);
   1.903 +              window.removeEventListener("mousedown", this, true);
   1.904 +              window.removeEventListener("mouseup", this, true);
   1.905 +              window.removeEventListener("contextmenu", this, true);
   1.906 +              window.removeEventListener("keydown", this, true);
   1.907 +              window.removeEventListener("keypress", this, true);
   1.908 +              window.removeEventListener("keyup", this, true);
   1.909 +              this.messageManager.sendAsyncMessage("Autoscroll:Stop");
   1.910 +            }
   1.911 +         ]]>
   1.912 +       </body>
   1.913 +     </method>
   1.914 +
   1.915 +      <method name="_createAutoScrollPopup">
   1.916 +        <body>
   1.917 +          <![CDATA[
   1.918 +            const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
   1.919 +            var popup = document.createElementNS(XUL_NS, "panel");
   1.920 +            popup.className = "autoscroller";
   1.921 +            // We set this attribute on the element so that mousemove
   1.922 +            // events can be handled by browser-content.js.
   1.923 +            popup.setAttribute("mousethrough", "always");
   1.924 +            return popup;
   1.925 +          ]]>
   1.926 +        </body>
   1.927 +      </method>
   1.928 +
   1.929 +      <method name="startScroll">
   1.930 +        <parameter name="scrolldir"/>
   1.931 +        <parameter name="screenX"/>
   1.932 +        <parameter name="screenY"/>
   1.933 +        <body><![CDATA[
   1.934 +            if (!this._autoScrollPopup) {
   1.935 +              if (this.hasAttribute("autoscrollpopup")) {
   1.936 +                // our creator provided a popup to share
   1.937 +                this._autoScrollPopup = document.getElementById(this.getAttribute("autoscrollpopup"));
   1.938 +              }
   1.939 +              else {
   1.940 +                // we weren't provided a popup; we have to use the global scope
   1.941 +                this._autoScrollPopup = this._createAutoScrollPopup();
   1.942 +                document.documentElement.appendChild(this._autoScrollPopup);
   1.943 +                this._autoScrollNeedsCleanup = true;
   1.944 +              }
   1.945 +            }
   1.946 +
   1.947 +            // we need these attributes so themers don't need to create per-platform packages
   1.948 +            if (screen.colorDepth > 8) { // need high color for transparency
   1.949 +              // Exclude second-rate platforms
   1.950 +              this._autoScrollPopup.setAttribute("transparent", !/BeOS|OS\/2/.test(navigator.appVersion));
   1.951 +              // Enable translucency on Windows and Mac
   1.952 +              this._autoScrollPopup.setAttribute("translucent", /Win|Mac/.test(navigator.platform));
   1.953 +            }
   1.954 +
   1.955 +            this._autoScrollPopup.setAttribute("scrolldir", scrolldir);
   1.956 +            this._autoScrollPopup.addEventListener("popuphidden", this, true);
   1.957 +            this._autoScrollPopup.showPopup(document.documentElement,
   1.958 +                                            screenX,
   1.959 +                                            screenY,
   1.960 +                                            "popup", null, null);
   1.961 +            this._ignoreMouseEvents = true;
   1.962 +            this._scrolling = true;
   1.963 +            this._startX = screenX;
   1.964 +            this._startY = screenY;
   1.965 +
   1.966 +            window.addEventListener("mousemove", this, true);
   1.967 +            window.addEventListener("mousedown", this, true);
   1.968 +            window.addEventListener("mouseup", this, true);
   1.969 +            window.addEventListener("contextmenu", this, true);
   1.970 +            window.addEventListener("keydown", this, true);
   1.971 +            window.addEventListener("keypress", this, true);
   1.972 +            window.addEventListener("keyup", this, true);
   1.973 +         ]]>
   1.974 +       </body>
   1.975 +     </method>
   1.976 +
   1.977 +      <method name="handleEvent">
   1.978 +        <parameter name="aEvent"/>
   1.979 +        <body>
   1.980 +        <![CDATA[
   1.981 +          if (this._scrolling) {
   1.982 +            switch(aEvent.type) {
   1.983 +              case "mousemove": {
   1.984 +                var x = aEvent.screenX - this._startX;
   1.985 +                var y = aEvent.screenY - this._startY;
   1.986 +
   1.987 +                if ((x > this._AUTOSCROLL_SNAP || x < -this._AUTOSCROLL_SNAP) ||
   1.988 +                    (y > this._AUTOSCROLL_SNAP || y < -this._AUTOSCROLL_SNAP))
   1.989 +                  this._ignoreMouseEvents = false;
   1.990 +                break;
   1.991 +              }
   1.992 +              case "mouseup":
   1.993 +              case "mousedown":
   1.994 +              case "contextmenu": {
   1.995 +                if (!this._ignoreMouseEvents)
   1.996 +                  this._autoScrollPopup.hidePopup();
   1.997 +                this._ignoreMouseEvents = false;
   1.998 +                break;
   1.999 +              }
  1.1000 +              case "popuphidden": {
  1.1001 +                this._autoScrollPopup.removeEventListener("popuphidden", this, true);
  1.1002 +                this.stopScroll();
  1.1003 +                break;
  1.1004 +              }
  1.1005 +              case "keydown": {
  1.1006 +                if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
  1.1007 +                  // the escape key will be processed by
  1.1008 +                  // nsXULPopupManager::KeyDown and the panel will be closed.
  1.1009 +                  // So, don't consume the key event here.
  1.1010 +                  break;
  1.1011 +                }
  1.1012 +                // don't break here. we need to eat keydown events.
  1.1013 +              }
  1.1014 +              case "keypress":
  1.1015 +              case "keyup": {
  1.1016 +                // All keyevents should be eaten here during autoscrolling.
  1.1017 +                aEvent.stopPropagation();
  1.1018 +                aEvent.preventDefault();
  1.1019 +                break;
  1.1020 +              }
  1.1021 +            }
  1.1022 +          }
  1.1023 +        ]]>
  1.1024 +        </body>
  1.1025 +      </method>
  1.1026 +
  1.1027 +      <!--
  1.1028 +        For out-of-process code, event.screen[XY] is relative to the
  1.1029 +        left/top of the content view. For in-process code,
  1.1030 +        event.screen[XY] is relative to the left/top of the screen. We
  1.1031 +        use this method to map screen coordinates received from a
  1.1032 +        (possibly out-of-process) <browser> element to coordinates
  1.1033 +        that are relative to the screen. This code handles the
  1.1034 +        in-process case, where we return the coordinates unchanged.
  1.1035 +      -->
  1.1036 +      <method name="mapScreenCoordinatesFromContent">
  1.1037 +        <parameter name="aScreenX"/>
  1.1038 +        <parameter name="aScreenY"/>
  1.1039 +        <body>
  1.1040 +        <![CDATA[
  1.1041 +          return { x: aScreenX, y: aScreenY };
  1.1042 +        ]]>
  1.1043 +        </body>
  1.1044 +      </method>
  1.1045 +
  1.1046 +      <method name="swapDocShells">
  1.1047 +        <parameter name="aOtherBrowser"/>
  1.1048 +        <body>
  1.1049 +        <![CDATA[
  1.1050 +          // We need to swap fields that are tied to our docshell or related to
  1.1051 +          // the loaded page
  1.1052 +          // Fields which are built as a result of notifactions (pageshow/hide,
  1.1053 +          // DOMLinkAdded/Removed, onStateChange) should not be swapped here,
  1.1054 +          // because these notifications are dispatched again once the docshells
  1.1055 +          // are swapped.
  1.1056 +          var fieldsToSwap = [
  1.1057 +            "_docShell",
  1.1058 +            "_webBrowserFind",
  1.1059 +            "_contentWindow",
  1.1060 +            "_webNavigation",
  1.1061 +            "_permanentKey"
  1.1062 +          ];
  1.1063 +
  1.1064 +          var ourFieldValues = {};
  1.1065 +          var otherFieldValues = {};
  1.1066 +          for each (var field in fieldsToSwap) {
  1.1067 +            ourFieldValues[field] = this[field];
  1.1068 +            otherFieldValues[field] = aOtherBrowser[field];
  1.1069 +          }
  1.1070 +
  1.1071 +          if (window.PopupNotifications)
  1.1072 +            PopupNotifications._swapBrowserNotifications(aOtherBrowser, this);
  1.1073 +
  1.1074 +          this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner)
  1.1075 +              .swapFrameLoaders(aOtherBrowser);
  1.1076 +
  1.1077 +          // Before we swap the actual docShell property we need to detach the
  1.1078 +          // form fill controller from those docShells.
  1.1079 +          this.detachFormFill();
  1.1080 +          aOtherBrowser.detachFormFill();
  1.1081 +
  1.1082 +          for each (var field in fieldsToSwap) {
  1.1083 +            this[field] = otherFieldValues[field];
  1.1084 +            aOtherBrowser[field] = ourFieldValues[field];
  1.1085 +          }
  1.1086 +
  1.1087 +          // Re-attach the docShells to the form fill controller.
  1.1088 +          this.attachFormFill();
  1.1089 +          aOtherBrowser.attachFormFill();
  1.1090 +
  1.1091 +          // Null the current nsITypeAheadFind instances so that they're
  1.1092 +          // lazily re-created on access. We need to do this because they
  1.1093 +          // might have attached the wrong docShell.
  1.1094 +          this._fastFind = aOtherBrowser._fastFind = null;
  1.1095 +        ]]>
  1.1096 +        </body>
  1.1097 +      </method>
  1.1098 +    </implementation>
  1.1099 +
  1.1100 +    <handlers>
  1.1101 +      <handler event="keypress" keycode="VK_F7" group="system">
  1.1102 +        <![CDATA[
  1.1103 +          if (event.defaultPrevented || !event.isTrusted)
  1.1104 +            return;
  1.1105 +
  1.1106 +          var isEnabled = this.mPrefs.getBoolPref("accessibility.browsewithcaret_shortcut.enabled");
  1.1107 +          if (!isEnabled)
  1.1108 +            return;
  1.1109 +
  1.1110 +          // Toggle browse with caret mode
  1.1111 +          var browseWithCaretOn = false;
  1.1112 +          var warn = true;
  1.1113 +
  1.1114 +          try {
  1.1115 +            warn = this.mPrefs.getBoolPref("accessibility.warn_on_browsewithcaret");
  1.1116 +          } catch (ex) {
  1.1117 +          }
  1.1118 +
  1.1119 +          try {
  1.1120 +            browseWithCaretOn = this.mPrefs.getBoolPref("accessibility.browsewithcaret");
  1.1121 +          } catch (ex) {
  1.1122 +          }
  1.1123 +          if (warn && !browseWithCaretOn) {
  1.1124 +            var checkValue = {value:false};
  1.1125 +            var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
  1.1126 +                                          .getService(Components.interfaces.nsIPromptService);
  1.1127 +
  1.1128 +            var buttonPressed = promptService.confirmEx(window,
  1.1129 +              this.mStrBundle.GetStringFromName('browsewithcaret.checkWindowTitle'),
  1.1130 +              this.mStrBundle.GetStringFromName('browsewithcaret.checkLabel'),
  1.1131 +              promptService.STD_YES_NO_BUTTONS,
  1.1132 +              null, null, null, this.mStrBundle.GetStringFromName('browsewithcaret.checkMsg'),
  1.1133 +              checkValue);
  1.1134 +            if (buttonPressed != 0)
  1.1135 +              return;
  1.1136 +            if (checkValue.value) {
  1.1137 +              try {
  1.1138 +                this.mPrefs.setBoolPref("accessibility.warn_on_browsewithcaret", false);
  1.1139 +              }
  1.1140 +              catch (ex) {
  1.1141 +              }
  1.1142 +            }
  1.1143 +          }
  1.1144 +
  1.1145 +          // Toggle the pref
  1.1146 +          try {
  1.1147 +            this.mPrefs.setBoolPref("accessibility.browsewithcaret",!browseWithCaretOn);
  1.1148 +          } catch (ex) {
  1.1149 +          }
  1.1150 +        ]]>
  1.1151 +      </handler>
  1.1152 +      <handler event="dragover" group="system">
  1.1153 +      <![CDATA[
  1.1154 +        if (!this.droppedLinkHandler || event.defaultPrevented)
  1.1155 +          return;
  1.1156 +
  1.1157 +        // For drags that appear to be internal text (for example, tab drags),
  1.1158 +        // set the dropEffect to 'none'. This prevents the drop even if some
  1.1159 +        // other listener cancelled the event.
  1.1160 +        var types = event.dataTransfer.types;
  1.1161 +        if (types.contains("text/x-moz-text-internal") && !types.contains("text/plain")) {
  1.1162 +          event.dataTransfer.dropEffect = "none";
  1.1163 +          event.stopPropagation();
  1.1164 +          event.preventDefault();
  1.1165 +        }
  1.1166 +
  1.1167 +        let linkHandler = Components.classes["@mozilla.org/content/dropped-link-handler;1"].
  1.1168 +                            getService(Components.interfaces.nsIDroppedLinkHandler);
  1.1169 +        if (linkHandler.canDropLink(event, false))
  1.1170 +          event.preventDefault();
  1.1171 +      ]]>
  1.1172 +      </handler>
  1.1173 +      <handler event="drop" group="system">
  1.1174 +      <![CDATA[
  1.1175 +        if (!this.droppedLinkHandler || event.defaultPrevented)
  1.1176 +          return;
  1.1177 +
  1.1178 +        let name = { };
  1.1179 +        let linkHandler = Components.classes["@mozilla.org/content/dropped-link-handler;1"].
  1.1180 +                            getService(Components.interfaces.nsIDroppedLinkHandler);
  1.1181 +        try {
  1.1182 +          // Pass true to prevent the dropping of javascript:/data: URIs
  1.1183 +          var uri = linkHandler.dropLink(event, name, true);
  1.1184 +        } catch (ex) {
  1.1185 +          return;
  1.1186 +        }
  1.1187 +
  1.1188 +        if (uri) {
  1.1189 +          this.droppedLinkHandler(event, uri, name.value);
  1.1190 +        }
  1.1191 +      ]]>
  1.1192 +      </handler>
  1.1193 +    </handlers>
  1.1194 +
  1.1195 +  </binding>
  1.1196 +
  1.1197 +</bindings>

mercurial