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>