1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/content/widgets/findbar.xml Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1213 @@ 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="findbarBindings" 1.16 + xmlns="http://www.mozilla.org/xbl" 1.17 + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 1.18 + xmlns:xbl="http://www.mozilla.org/xbl"> 1.19 + 1.20 + <!-- Private binding --> 1.21 + <binding id="findbar-textbox" 1.22 + extends="chrome://global/content/bindings/textbox.xml#textbox"> 1.23 + <implementation> 1.24 + 1.25 + <field name="_findbar">null</field> 1.26 + <property name="findbar" readonly="true"> 1.27 + <getter> 1.28 + return this._findbar ? 1.29 + this._findbar : this._findbar = document.getBindingParent(this); 1.30 + </getter> 1.31 + </property> 1.32 + 1.33 + <method name="_handleEnter"> 1.34 + <parameter name="aEvent"/> 1.35 + <body><![CDATA[ 1.36 + if (this.findbar._findMode == this.findbar.FIND_NORMAL) { 1.37 + let findString = this.findbar._findField; 1.38 + if (!findString.value) 1.39 + return; 1.40 +#ifdef XP_MACOSX 1.41 + if (aEvent.metaKey) { 1.42 +#else 1.43 + if (aEvent.ctrlKey) { 1.44 +#endif 1.45 + this.findbar.getElement("highlight").click(); 1.46 + return; 1.47 + } 1.48 + 1.49 + this.findbar.onFindAgainCommand(aEvent.shiftKey); 1.50 + } else { 1.51 + this.findbar._finishFAYT(aEvent); 1.52 + } 1.53 + ]]></body> 1.54 + </method> 1.55 + 1.56 + <method name="_handleTab"> 1.57 + <parameter name="aEvent"/> 1.58 + <body><![CDATA[ 1.59 + let shouldHandle = !aEvent.altKey && !aEvent.ctrlKey && 1.60 + !aEvent.metaKey; 1.61 + if (shouldHandle && 1.62 + this.findbar._findMode != this.findbar.FIND_NORMAL) { 1.63 + 1.64 + this.findbar._finishFAYT(aEvent); 1.65 + } 1.66 + ]]></body> 1.67 + </method> 1.68 + </implementation> 1.69 + 1.70 + <handlers> 1.71 + <handler event="input"><![CDATA[ 1.72 + // We should do nothing during composition. E.g., composing string 1.73 + // before converting may matches a forward word of expected word. 1.74 + // After that, even if user converts the composition string to the 1.75 + // expected word, it may find second or later searching word in the 1.76 + // document. 1.77 + if (this.findbar._isIMEComposing) { 1.78 + return; 1.79 + } 1.80 + this.findbar._find(this.value); 1.81 + ]]></handler> 1.82 + 1.83 + <handler event="keypress"><![CDATA[ 1.84 + let shouldHandle = !event.altKey && !event.ctrlKey && 1.85 + !event.metaKey && !event.shiftKey; 1.86 + 1.87 + switch (event.keyCode) { 1.88 + case KeyEvent.DOM_VK_RETURN: 1.89 + this._handleEnter(event); 1.90 + break; 1.91 + case KeyEvent.DOM_VK_TAB: 1.92 + this._handleTab(event); 1.93 + break; 1.94 + case KeyEvent.DOM_VK_PAGE_UP: 1.95 + case KeyEvent.DOM_VK_PAGE_DOWN: 1.96 + if (shouldHandle) { 1.97 + this.findbar.browser.finder.keyPress(event); 1.98 + event.preventDefault(); 1.99 + } 1.100 + break; 1.101 + case KeyEvent.DOM_VK_UP: 1.102 + case KeyEvent.DOM_VK_DOWN: 1.103 + this.findbar.browser.finder.keyPress(event); 1.104 + event.preventDefault(); 1.105 + break; 1.106 + } 1.107 + ]]></handler> 1.108 + 1.109 + <handler event="blur"><![CDATA[ 1.110 + let findbar = this.findbar; 1.111 + // Note: This code used to remove the selection 1.112 + // if it matched an editable. 1.113 + findbar.browser.finder.enableSelection(); 1.114 + ]]></handler> 1.115 + 1.116 +#ifdef XP_MACOSX 1.117 + <handler event="focus"><![CDATA[ 1.118 + let findbar = this.findbar; 1.119 + findbar._onFindFieldFocus(); 1.120 + ]]></handler> 1.121 +#endif 1.122 + 1.123 + <handler event="compositionstart"><![CDATA[ 1.124 + // Don't close the find toolbar while IME is composing. 1.125 + let findbar = this.findbar; 1.126 + findbar._isIMEComposing = true; 1.127 + if (findbar._quickFindTimeout) { 1.128 + clearTimeout(findbar._quickFindTimeout); 1.129 + findbar._quickFindTimeout = null; 1.130 + } 1.131 + ]]></handler> 1.132 + 1.133 + <handler event="compositionend"><![CDATA[ 1.134 + let findbar = this.findbar; 1.135 + findbar._isIMEComposing = false; 1.136 + if (findbar._findMode != findbar.FIND_NORMAL) 1.137 + findbar._setFindCloseTimeout(); 1.138 + ]]></handler> 1.139 + 1.140 + <handler event="dragover"><![CDATA[ 1.141 + if (event.dataTransfer.types.contains("text/plain")) 1.142 + event.preventDefault(); 1.143 + ]]></handler> 1.144 + 1.145 + <handler event="drop"><![CDATA[ 1.146 + let value = event.dataTransfer.getData("text/plain"); 1.147 + this.value = value; 1.148 + this.findbar._find(value); 1.149 + event.stopPropagation(); 1.150 + event.preventDefault(); 1.151 + ]]></handler> 1.152 + </handlers> 1.153 + </binding> 1.154 + 1.155 + <binding id="findbar" 1.156 + extends="chrome://global/content/bindings/toolbar.xml#toolbar"> 1.157 + <resources> 1.158 + <stylesheet src="chrome://global/skin/findBar.css"/> 1.159 + </resources> 1.160 + 1.161 + <content hidden="true"> 1.162 + <xul:hbox anonid="findbar-container" class="findbar-container" flex="1" align="center"> 1.163 + <xul:hbox anonid="findbar-textbox-wrapper" align="stretch"> 1.164 + <xul:textbox anonid="findbar-textbox" 1.165 + class="findbar-textbox findbar-find-fast" 1.166 + xbl:inherits="flash"/> 1.167 + <xul:toolbarbutton anonid="find-previous" 1.168 + class="findbar-find-previous tabbable" 1.169 + tooltiptext="&previous.tooltip;" 1.170 + oncommand="onFindAgainCommand(true);" 1.171 + disabled="true" 1.172 + xbl:inherits="accesskey=findpreviousaccesskey"/> 1.173 + <xul:toolbarbutton anonid="find-next" 1.174 + class="findbar-find-next tabbable" 1.175 + tooltiptext="&next.tooltip;" 1.176 + oncommand="onFindAgainCommand(false);" 1.177 + disabled="true" 1.178 + xbl:inherits="accesskey=findnextaccesskey"/> 1.179 + </xul:hbox> 1.180 + <xul:toolbarbutton anonid="highlight" 1.181 + class="findbar-highlight tabbable" 1.182 + label="&highlightAll.label;" 1.183 + accesskey="&highlightAll.accesskey;" 1.184 + tooltiptext="&highlightAll.tooltiptext;" 1.185 + oncommand="toggleHighlight(this.checked);" 1.186 + type="checkbox" 1.187 + xbl:inherits="accesskey=highlightaccesskey"/> 1.188 + <xul:toolbarbutton anonid="find-case-sensitive" 1.189 + class="findbar-case-sensitive tabbable" 1.190 + label="&caseSensitive.label;" 1.191 + accesskey="&caseSensitive.accesskey;" 1.192 + tooltiptext="&caseSensitive.tooltiptext;" 1.193 + oncommand="_setCaseSensitivity(this.checked);" 1.194 + type="checkbox" 1.195 + xbl:inherits="accesskey=matchcaseaccesskey"/> 1.196 + <xul:label anonid="match-case-status" class="findbar-find-fast"/> 1.197 + <xul:image anonid="find-status-icon" class="findbar-find-fast find-status-icon"/> 1.198 + <xul:description anonid="find-status" 1.199 + control="findbar-textbox" 1.200 + class="findbar-find-fast findbar-find-status"> 1.201 + <!-- Do not use value, first child is used because it provides a11y with text change events --> 1.202 + </xul:description> 1.203 + </xul:hbox> 1.204 + <xul:toolbarbutton anonid="find-closebutton" 1.205 + class="findbar-closebutton close-icon" 1.206 + tooltiptext="&findCloseButton.tooltip;" 1.207 + oncommand="close();"/> 1.208 + </content> 1.209 + 1.210 + <implementation implements="nsIDOMEventListener, nsIEditActionListener"> 1.211 + <field name="FIND_NORMAL">0</field> 1.212 + <field name="FIND_TYPEAHEAD">1</field> 1.213 + <field name="FIND_LINKS">2</field> 1.214 + 1.215 + <field name="_findMode">0</field> 1.216 + 1.217 + <field name="_flashFindBar">0</field> 1.218 + <field name="_initialFlashFindBarCount">6</field> 1.219 + 1.220 + <property name="prefillWithSelection" 1.221 + onget="return this.getAttribute('prefillwithselection') != 'false'" 1.222 + onset="this.setAttribute('prefillwithselection', val); return val;"/> 1.223 + <field name="_selectionMaxLen">150</field> 1.224 + 1.225 + <method name="getElement"> 1.226 + <parameter name="aAnonymousID"/> 1.227 + <body><![CDATA[ 1.228 + return document.getAnonymousElementByAttribute(this, 1.229 + "anonid", 1.230 + aAnonymousID) 1.231 + ]]></body> 1.232 + </method> 1.233 + 1.234 + <property name="findMode" 1.235 + readonly="true" 1.236 + onget="return this._findMode;"/> 1.237 + 1.238 + <property name="canClear" readonly="true"> 1.239 + <getter><![CDATA[ 1.240 + if (this._findField.value) 1.241 + return true; 1.242 + 1.243 + // Watch out for lazy editor init 1.244 + if (this._findField.editor) { 1.245 + let tm = this._findField.editor.transactionManager; 1.246 + return !!(tm.numberOfUndoItems || tm.numberOfRedoItems); 1.247 + } 1.248 + return false; 1.249 + ]]></getter> 1.250 + </property> 1.251 + 1.252 + <field name="_browser">null</field> 1.253 + <property name="browser"> 1.254 + <getter><![CDATA[ 1.255 + if (!this._browser) { 1.256 + this._browser = 1.257 + document.getElementById(this.getAttribute("browserid")); 1.258 + } 1.259 + return this._browser; 1.260 + ]]></getter> 1.261 + <setter><![CDATA[ 1.262 + if (this._browser) { 1.263 + this._browser.removeEventListener("keypress", this, false); 1.264 + this._browser.removeEventListener("mouseup", this, false); 1.265 + let finder = this._browser.finder; 1.266 + if (finder) 1.267 + finder.removeResultListener(this); 1.268 + } 1.269 + 1.270 + this._browser = val; 1.271 + if (this._browser) { 1.272 + this._browser.addEventListener("keypress", this, false); 1.273 + this._browser.addEventListener("mouseup", this, false); 1.274 + this._browser.finder.addResultListener(this); 1.275 + 1.276 + this._findField.value = this._browser._lastSearchString; 1.277 + this.toggleHighlight(this.browser._lastSearchHighlight); 1.278 + } 1.279 + return val; 1.280 + ]]></setter> 1.281 + </property> 1.282 + 1.283 + <field name="_observer"><![CDATA[({ 1.284 + _self: this, 1.285 + 1.286 + QueryInterface: function(aIID) { 1.287 + if (aIID.equals(Components.interfaces.nsIObserver) || 1.288 + aIID.equals(Components.interfaces.nsISupportsWeakReference) || 1.289 + aIID.equals(Components.interfaces.nsISupports)) 1.290 + return this; 1.291 + 1.292 + throw Components.results.NS_ERROR_NO_INTERFACE; 1.293 + }, 1.294 + 1.295 + observe: function(aSubject, aTopic, aPrefName) { 1.296 + if (aTopic != "nsPref:changed") 1.297 + return; 1.298 + 1.299 + let prefsvc = 1.300 + aSubject.QueryInterface(Components.interfaces.nsIPrefBranch); 1.301 + 1.302 + switch (aPrefName) { 1.303 + case "accessibility.typeaheadfind": 1.304 + this._self._useTypeAheadFind = prefsvc.getBoolPref(aPrefName); 1.305 + break; 1.306 + case "accessibility.typeaheadfind.linksonly": 1.307 + this._self._typeAheadLinksOnly = prefsvc.getBoolPref(aPrefName); 1.308 + break; 1.309 + case "accessibility.typeaheadfind.casesensitive": 1.310 + this._self._typeAheadCaseSensitive = prefsvc.getIntPref(aPrefName); 1.311 + this._self._updateCaseSensitivity(); 1.312 + if (this._self.getElement("highlight").checked) 1.313 + this._self._setHighlightTimeout(); 1.314 + break; 1.315 + } 1.316 + } 1.317 + })]]></field> 1.318 + 1.319 + <field name="_destroyed">false</field> 1.320 + 1.321 + <constructor><![CDATA[ 1.322 + // These elements are accessed frequently and are therefore cached 1.323 + this._findField = this.getElement("findbar-textbox"); 1.324 + this._findStatusIcon = this.getElement("find-status-icon"); 1.325 + this._findStatusDesc = this.getElement("find-status"); 1.326 + 1.327 + this._foundURL = null; 1.328 + 1.329 + let prefsvc = 1.330 + Components.classes["@mozilla.org/preferences-service;1"] 1.331 + .getService(Components.interfaces.nsIPrefBranch); 1.332 + 1.333 + this._quickFindTimeoutLength = 1.334 + prefsvc.getIntPref("accessibility.typeaheadfind.timeout"); 1.335 + this._flashFindBar = 1.336 + prefsvc.getIntPref("accessibility.typeaheadfind.flashBar"); 1.337 + 1.338 + prefsvc.addObserver("accessibility.typeaheadfind", 1.339 + this._observer, false); 1.340 + prefsvc.addObserver("accessibility.typeaheadfind.linksonly", 1.341 + this._observer, false); 1.342 + prefsvc.addObserver("accessibility.typeaheadfind.casesensitive", 1.343 + this._observer, false); 1.344 + 1.345 + this._useTypeAheadFind = 1.346 + prefsvc.getBoolPref("accessibility.typeaheadfind"); 1.347 + this._typeAheadLinksOnly = 1.348 + prefsvc.getBoolPref("accessibility.typeaheadfind.linksonly"); 1.349 + this._typeAheadCaseSensitive = 1.350 + prefsvc.getIntPref("accessibility.typeaheadfind.casesensitive"); 1.351 + 1.352 + // Convenience 1.353 + this.nsITypeAheadFind = Components.interfaces.nsITypeAheadFind; 1.354 + this.nsISelectionController = Components.interfaces.nsISelectionController; 1.355 + this._findSelection = this.nsISelectionController.SELECTION_FIND; 1.356 + 1.357 + this._findResetTimeout = -1; 1.358 + 1.359 + // Make sure the FAYT keypress listener is attached by initializing the 1.360 + // browser property 1.361 + if (this.getAttribute("browserid")) 1.362 + setTimeout(function(aSelf) { aSelf.browser = aSelf.browser; }, 0, this); 1.363 + ]]></constructor> 1.364 + 1.365 + <destructor><![CDATA[ 1.366 + this.destroy(); 1.367 + ]]></destructor> 1.368 + 1.369 + <!-- This is necessary because the destructor isn't called when 1.370 + we are removed from a document that is not destroyed. This 1.371 + needs to be explicitly called in this case --> 1.372 + <method name="destroy"> 1.373 + <body><![CDATA[ 1.374 + if (this._destroyed) 1.375 + return; 1.376 + this._destroyed = true; 1.377 + 1.378 + this.browser = null; 1.379 + 1.380 + let prefsvc = 1.381 + Components.classes["@mozilla.org/preferences-service;1"] 1.382 + .getService(Components.interfaces.nsIPrefBranch); 1.383 + prefsvc.removeObserver("accessibility.typeaheadfind", 1.384 + this._observer); 1.385 + prefsvc.removeObserver("accessibility.typeaheadfind.linksonly", 1.386 + this._observer); 1.387 + prefsvc.removeObserver("accessibility.typeaheadfind.casesensitive", 1.388 + this._observer); 1.389 + 1.390 + // Clear all timers that might still be running. 1.391 + this._cancelTimers(); 1.392 + ]]></body> 1.393 + </method> 1.394 + 1.395 + <method name="_cancelTimers"> 1.396 + <body><![CDATA[ 1.397 + if (this._flashFindBarTimeout) { 1.398 + clearInterval(this._flashFindBarTimeout); 1.399 + this._flashFindBarTimeout = null; 1.400 + } 1.401 + if (this._quickFindTimeout) { 1.402 + clearTimeout(this._quickFindTimeout); 1.403 + this._quickFindTimeout = null; 1.404 + } 1.405 + if (this._highlightTimeout) { 1.406 + clearTimeout(this._highlightTimeout); 1.407 + this._highlightTimeout = null; 1.408 + } 1.409 + if (this._findResetTimeout) { 1.410 + clearTimeout(this._findResetTimeout); 1.411 + this._findResetTimeout = null; 1.412 + } 1.413 + ]]></body> 1.414 + </method> 1.415 + 1.416 + <method name="_setFindCloseTimeout"> 1.417 + <body><![CDATA[ 1.418 + if (this._quickFindTimeout) 1.419 + clearTimeout(this._quickFindTimeout); 1.420 + 1.421 + // Don't close the find toolbar while IME is composing OR when the 1.422 + // findbar is already hidden. 1.423 + if (this._isIMEComposing || this.hidden) { 1.424 + this._quickFindTimeout = null; 1.425 + return; 1.426 + } 1.427 + 1.428 + this._quickFindTimeout = setTimeout(() => { 1.429 + if (this._findMode != this.FIND_NORMAL) 1.430 + this.close(); 1.431 + this._quickFindTimeout = null; 1.432 + }, this._quickFindTimeoutLength); 1.433 + ]]></body> 1.434 + </method> 1.435 + 1.436 + <!-- 1.437 + - Turns highlight on or off. 1.438 + - @param aHighlight (boolean) 1.439 + - Whether to turn the highlight on or off 1.440 + --> 1.441 + <method name="toggleHighlight"> 1.442 + <parameter name="aHighlight"/> 1.443 + <body><![CDATA[ 1.444 + if (!this._dispatchFindEvent("highlightallchange")) 1.445 + return; 1.446 + 1.447 + let word = this._findField.value; 1.448 + // Bug 429723. Don't attempt to highlight "" 1.449 + if (aHighlight && !word) 1.450 + return; 1.451 + 1.452 + this.browser._lastSearchHighlight = aHighlight; 1.453 + this.browser.finder.highlight(aHighlight, word); 1.454 + ]]></body> 1.455 + </method> 1.456 + 1.457 + <!-- 1.458 + - Updates the case-sensitivity mode of the findbar and its UI. 1.459 + - @param [optional] aString 1.460 + - The string for which case sensitivity might be turned on. 1.461 + - This only used when case-sensitivity is in auto mode, 1.462 + - @see _shouldBeCaseSensitive. The default value for this 1.463 + - parameter is the find-field value. 1.464 + --> 1.465 + <method name="_updateCaseSensitivity"> 1.466 + <parameter name="aString"/> 1.467 + <body><![CDATA[ 1.468 + let val = aString || this._findField.value; 1.469 + 1.470 + let caseSensitive = this._shouldBeCaseSensitive(val); 1.471 + let checkbox = this.getElement("find-case-sensitive"); 1.472 + let statusLabel = this.getElement("match-case-status"); 1.473 + checkbox.checked = caseSensitive; 1.474 + 1.475 + statusLabel.value = caseSensitive ? this._caseSensitiveStr : ""; 1.476 + 1.477 + // Show the checkbox on the full Find bar in non-auto mode. 1.478 + // Show the label in all other cases. 1.479 + let hideCheckbox = this._findMode != this.FIND_NORMAL || 1.480 + (this._typeAheadCaseSensitive != 0 && 1.481 + this._typeAheadCaseSensitive != 1); 1.482 + checkbox.hidden = hideCheckbox; 1.483 + statusLabel.hidden = !hideCheckbox; 1.484 + 1.485 + this.browser.finder.caseSensitive = caseSensitive; 1.486 + ]]></body> 1.487 + </method> 1.488 + 1.489 + <!-- 1.490 + - Sets the findbar case-sensitivity mode 1.491 + - @param aCaseSensitive (boolean) 1.492 + - Whether or not case-sensitivity should be turned on. 1.493 + --> 1.494 + <method name="_setCaseSensitivity"> 1.495 + <parameter name="aCaseSensitive"/> 1.496 + <body><![CDATA[ 1.497 + let prefsvc = 1.498 + Components.classes["@mozilla.org/preferences-service;1"] 1.499 + .getService(Components.interfaces.nsIPrefBranch); 1.500 + 1.501 + // Just set the pref; our observer will change the find bar behavior 1.502 + prefsvc.setIntPref("accessibility.typeaheadfind.casesensitive", 1.503 + aCaseSensitive ? 1 : 0); 1.504 + 1.505 + this._dispatchFindEvent("casesensitivitychange"); 1.506 + ]]></body> 1.507 + </method> 1.508 + 1.509 + <!-- 1.510 + - Opens and displays the find bar. 1.511 + - 1.512 + - @param aMode 1.513 + - the find mode to be used, which is either FIND_NORMAL, 1.514 + - FIND_TYPEAHEAD or FIND_LINKS. If not passed, the last 1.515 + - find mode if any or FIND_NORMAL. 1.516 + - @returns true if the find bar wasn't previously open, false otherwise. 1.517 + --> 1.518 + <method name="open"> 1.519 + <parameter name="aMode"/> 1.520 + <body><![CDATA[ 1.521 + if (aMode != undefined) 1.522 + this._findMode = aMode; 1.523 + 1.524 + if (!this._notFoundStr) { 1.525 + let stringsBundle = 1.526 + Components.classes["@mozilla.org/intl/stringbundle;1"] 1.527 + .getService(Components.interfaces.nsIStringBundleService) 1.528 + .createBundle("chrome://global/locale/findbar.properties"); 1.529 + this._notFoundStr = stringsBundle.GetStringFromName("NotFound"); 1.530 + this._wrappedToTopStr = 1.531 + stringsBundle.GetStringFromName("WrappedToTop"); 1.532 + this._wrappedToBottomStr = 1.533 + stringsBundle.GetStringFromName("WrappedToBottom"); 1.534 + this._normalFindStr = 1.535 + stringsBundle.GetStringFromName("NormalFind"); 1.536 + this._fastFindStr = 1.537 + stringsBundle.GetStringFromName("FastFind"); 1.538 + this._fastFindLinksStr = 1.539 + stringsBundle.GetStringFromName("FastFindLinks"); 1.540 + this._caseSensitiveStr = 1.541 + stringsBundle.GetStringFromName("CaseSensitive"); 1.542 + } 1.543 + 1.544 + this._findFailedString = null; 1.545 + 1.546 + this._updateFindUI(); 1.547 + if (this.hidden) { 1.548 + this.hidden = false; 1.549 + 1.550 + this._updateStatusUI(this.nsITypeAheadFind.FIND_FOUND); 1.551 + 1.552 + let event = document.createEvent("Events"); 1.553 + event.initEvent("findbaropen", true, false); 1.554 + this.dispatchEvent(event); 1.555 + 1.556 + return true; 1.557 + } 1.558 + return false; 1.559 + ]]></body> 1.560 + </method> 1.561 + 1.562 + <!-- 1.563 + - Closes the findbar. 1.564 + --> 1.565 + <method name="close"> 1.566 + <body><![CDATA[ 1.567 + if (this.hidden) 1.568 + return; 1.569 + 1.570 + this.hidden = true; 1.571 + 1.572 + this.browser.finder.focusContent(); 1.573 + this.browser.finder.enableSelection(); 1.574 + this._findField.blur(); 1.575 + 1.576 + this._cancelTimers(); 1.577 + 1.578 + this._findFailedString = null; 1.579 + ]]></body> 1.580 + </method> 1.581 + 1.582 + <method name="clear"> 1.583 + <body><![CDATA[ 1.584 + this.browser.finder.removeSelection(); 1.585 + this._findField.reset(); 1.586 + this.toggleHighlight(false); 1.587 + this._updateStatusUI(); 1.588 + this._enableFindButtons(false); 1.589 + ]]></body> 1.590 + </method> 1.591 + 1.592 + <method name="_dispatchKeypressEvent"> 1.593 + <parameter name="aTarget"/> 1.594 + <parameter name="aEvent"/> 1.595 + <body><![CDATA[ 1.596 + if (!aTarget) 1.597 + return; 1.598 + 1.599 + let event = document.createEvent("KeyEvents"); 1.600 + event.initKeyEvent(aEvent.type, aEvent.bubbles, aEvent.cancelable, 1.601 + aEvent.view, aEvent.ctrlKey, aEvent.altKey, 1.602 + aEvent.shiftKey, aEvent.metaKey, aEvent.keyCode, 1.603 + aEvent.charCode); 1.604 + aTarget.dispatchEvent(event); 1.605 + ]]></body> 1.606 + </method> 1.607 + 1.608 + <field name="_xulBrowserWindow">null</field> 1.609 + <method name="_updateStatusUIBar"> 1.610 + <parameter name="aFoundURL"/> 1.611 + <body><![CDATA[ 1.612 + if (!this._xulBrowserWindow) { 1.613 + try { 1.614 + this._xulBrowserWindow = 1.615 + window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) 1.616 + .getInterface(Components.interfaces.nsIWebNavigation) 1.617 + .QueryInterface(Components.interfaces.nsIDocShellTreeItem) 1.618 + .treeOwner 1.619 + .QueryInterface(Components.interfaces.nsIInterfaceRequestor) 1.620 + .getInterface(Components.interfaces.nsIXULWindow) 1.621 + .XULBrowserWindow; 1.622 + } 1.623 + catch(ex) { } 1.624 + if (!this._xulBrowserWindow) 1.625 + return false; 1.626 + } 1.627 + 1.628 + // Call this has the same effect like hovering over link, 1.629 + // the browser shows the URL as a tooltip. 1.630 + this._xulBrowserWindow.setOverLink(aFoundURL || "", null); 1.631 + return true; 1.632 + ]]></body> 1.633 + </method> 1.634 + 1.635 + <method name="_finishFAYT"> 1.636 + <parameter name="aKeypressEvent"/> 1.637 + <body><![CDATA[ 1.638 + this.browser.finder.focusContent(); 1.639 + 1.640 + if (aKeypressEvent) 1.641 + aKeypressEvent.preventDefault(); 1.642 + 1.643 + this.browser.finder.keyPress(aKeypressEvent); 1.644 + 1.645 + this.close(); 1.646 + return true; 1.647 + ]]></body> 1.648 + </method> 1.649 + 1.650 + <!-- 1.651 + - Returns true if |aMimeType| is text-based, or false otherwise. 1.652 + - 1.653 + - @param aMimeType 1.654 + - The MIME type to check. 1.655 + - 1.656 + - if adding types to this function, please see the similar function 1.657 + - in browser/base/content/browser.js 1.658 + --> 1.659 + <method name="_mimeTypeIsTextBased"> 1.660 + <parameter name="aMimeType"/> 1.661 + <body><![CDATA[ 1.662 + return /^text\/|\+xml$/.test(aMimeType) || 1.663 + aMimeType == "application/x-javascript" || 1.664 + aMimeType == "application/javascript" || 1.665 + aMimeType == "application/json" || 1.666 + aMimeType == "application/xml"; 1.667 + ]]></body> 1.668 + </method> 1.669 + 1.670 + <!-- 1.671 + - Returns whether FAYT can be used for the given event in 1.672 + - the current content state. 1.673 + --> 1.674 + <method name="_shouldFastFind"> 1.675 + <parameter name="aEvent"/> 1.676 + <body><![CDATA[ 1.677 + if (aEvent.ctrlKey || aEvent.altKey || aEvent.metaKey || 1.678 + aEvent.defaultPrevented) 1.679 + return false; 1.680 + 1.681 + let {BrowserUtils} = Components.utils.import("resource://gre/modules/BrowserUtils.jsm", {}); 1.682 + let [elt, win] = BrowserUtils.getFocusSync(document); 1.683 + 1.684 + if (elt) { 1.685 + if (elt instanceof HTMLInputElement && elt.mozIsTextField(false)) 1.686 + return false; 1.687 + 1.688 + if (elt.isContentEditable) 1.689 + return false; 1.690 + 1.691 + if (elt instanceof HTMLTextAreaElement || 1.692 + elt instanceof HTMLSelectElement || 1.693 + elt instanceof HTMLObjectElement || 1.694 + elt instanceof HTMLEmbedElement) 1.695 + return false; 1.696 + } 1.697 + 1.698 + if (win && !this._mimeTypeIsTextBased(win.document.contentType)) 1.699 + return false; 1.700 + 1.701 + // disable FAYT in about:blank to prevent FAYT opening unexpectedly. 1.702 + let url = this.browser.currentURI; 1.703 + if (url.spec == "about:blank") 1.704 + return false; 1.705 + 1.706 + // disable FAYT in documents that ask for it to be disabled. 1.707 + if ((url.schemeIs("about") || url.schemeIs("chrome")) && 1.708 + (win.document.documentElement && 1.709 + win.document.documentElement.getAttribute("disablefastfind") == "true")) 1.710 + return false; 1.711 + 1.712 + if (win) { 1.713 + try { 1.714 + let editingSession = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor) 1.715 + .getInterface(Components.interfaces.nsIWebNavigation) 1.716 + .QueryInterface(Components.interfaces.nsIInterfaceRequestor) 1.717 + .getInterface(Components.interfaces.nsIEditingSession); 1.718 + if (editingSession.windowIsEditable(win)) 1.719 + return false; 1.720 + } 1.721 + catch (e) { 1.722 + // If someone built with composer disabled, we can't get an editing session. 1.723 + } 1.724 + } 1.725 + 1.726 + return true; 1.727 + ]]></body> 1.728 + </method> 1.729 + 1.730 + <method name="_shouldBeCaseSensitive"> 1.731 + <parameter name="aString"/> 1.732 + <body><![CDATA[ 1.733 + if (this._typeAheadCaseSensitive == 0) 1.734 + return false; 1.735 + if (this._typeAheadCaseSensitive == 1) 1.736 + return true; 1.737 + 1.738 + return aString != aString.toLowerCase(); 1.739 + ]]></body> 1.740 + </method> 1.741 + 1.742 + <method name="_onBrowserKeypress"> 1.743 + <parameter name="aEvent"/> 1.744 + <body><![CDATA[ 1.745 + const TAF_LINKS_KEY = "'"; 1.746 + const TAF_TEXT_KEY = "/"; 1.747 + 1.748 + if (!this._shouldFastFind(aEvent)) 1.749 + return; 1.750 + 1.751 + if (this._findMode != this.FIND_NORMAL && this._quickFindTimeout) { 1.752 + if (!aEvent.charCode) 1.753 + return; 1.754 + 1.755 + this._findField.select(); 1.756 + this._findField.focus(); 1.757 + this._dispatchKeypressEvent(this._findField.inputField, aEvent); 1.758 + aEvent.preventDefault(); 1.759 + return; 1.760 + } 1.761 + 1.762 + let key = aEvent.charCode ? String.fromCharCode(aEvent.charCode) : null; 1.763 + let manualstartFAYT = (key == TAF_LINKS_KEY || key == TAF_TEXT_KEY); 1.764 + let autostartFAYT = !manualstartFAYT && this._useTypeAheadFind && 1.765 + key && key != " "; 1.766 + if (manualstartFAYT || autostartFAYT) { 1.767 + let mode = (key == TAF_LINKS_KEY || 1.768 + (autostartFAYT && this._typeAheadLinksOnly)) ? 1.769 + this.FIND_LINKS : this.FIND_TYPEAHEAD; 1.770 + 1.771 + // Clear bar first, so that when openFindBar() calls setCaseSensitivity() 1.772 + // it doesn't get confused by a lingering value 1.773 + this._findField.value = ""; 1.774 + 1.775 + this.open(mode); 1.776 + this._setFindCloseTimeout(); 1.777 + this._findField.select(); 1.778 + this._findField.focus(); 1.779 + 1.780 + if (autostartFAYT) 1.781 + this._dispatchKeypressEvent(this._findField.inputField, aEvent); 1.782 + else 1.783 + this._updateStatusUI(this.nsITypeAheadFind.FIND_FOUND); 1.784 + 1.785 + aEvent.preventDefault(); 1.786 + } 1.787 + ]]></body> 1.788 + </method> 1.789 + 1.790 + <!-- See nsIDOMEventListener --> 1.791 + <method name="handleEvent"> 1.792 + <parameter name="aEvent"/> 1.793 + <body><![CDATA[ 1.794 + switch (aEvent.type) { 1.795 + case "mouseup": 1.796 + if (!this.hidden && this._findMode != this.FIND_NORMAL) 1.797 + this.close(); 1.798 + 1.799 + break; 1.800 + case "keypress": 1.801 + this._onBrowserKeypress(aEvent); 1.802 + break; 1.803 + } 1.804 + ]]></body> 1.805 + </method> 1.806 + 1.807 + <method name="_enableFindButtons"> 1.808 + <parameter name="aEnable"/> 1.809 + <body><![CDATA[ 1.810 + this.getElement("find-next").disabled = 1.811 + this.getElement("find-previous").disabled = !aEnable; 1.812 + ]]></body> 1.813 + </method> 1.814 + 1.815 + <!-- 1.816 + - Determines whether minimalist or general-purpose search UI is to be 1.817 + - displayed when the find bar is activated. 1.818 + --> 1.819 + <method name="_updateFindUI"> 1.820 + <body><![CDATA[ 1.821 + let showMinimalUI = this._findMode != this.FIND_NORMAL; 1.822 + 1.823 + let nodes = this.getElement("findbar-container").childNodes; 1.824 + let wrapper = this.getElement("findbar-textbox-wrapper"); 1.825 + for (let node of nodes) { 1.826 + if (node == wrapper) 1.827 + continue; 1.828 + node.hidden = showMinimalUI; 1.829 + } 1.830 + this.getElement("find-next").hidden = 1.831 + this.getElement("find-previous").hidden = showMinimalUI; 1.832 + this._updateCaseSensitivity(); 1.833 + 1.834 + if (showMinimalUI) 1.835 + this._findField.classList.add("minimal"); 1.836 + else 1.837 + this._findField.classList.remove("minimal"); 1.838 + 1.839 + if (this._findMode == this.FIND_TYPEAHEAD) 1.840 + this._findField.placeholder = this._fastFindStr; 1.841 + else if (this._findMode == this.FIND_LINKS) 1.842 + this._findField.placeholder = this._fastFindLinksStr; 1.843 + else 1.844 + this._findField.placeholder = this._normalFindStr; 1.845 + ]]></body> 1.846 + </method> 1.847 + 1.848 + <method name="_find"> 1.849 + <parameter name="aValue"/> 1.850 + <body><![CDATA[ 1.851 + if (!this._dispatchFindEvent("")) 1.852 + return; 1.853 + 1.854 + let val = aValue || this._findField.value; 1.855 + 1.856 + // We have to carry around an explicit version of this, 1.857 + // because finder.searchString doesn't update on failed 1.858 + // searches. 1.859 + this.browser._lastSearchString = val; 1.860 + 1.861 + // Only search on input if we don't have a last-failed string, 1.862 + // or if the current search string doesn't start with it. 1.863 + if (!this._findFailedString || 1.864 + !val.startsWith(this._findFailedString)) 1.865 + { 1.866 + this._enableFindButtons(val); 1.867 + if (this.getElement("highlight").checked) 1.868 + this._setHighlightTimeout(); 1.869 + 1.870 + this._updateCaseSensitivity(val); 1.871 + 1.872 + this.browser.finder.fastFind(val, this._findMode == this.FIND_LINKS, 1.873 + this._findMode != this.FIND_NORMAL); 1.874 + } 1.875 + 1.876 + if (this._findMode != this.FIND_NORMAL) 1.877 + this._setFindCloseTimeout(); 1.878 + 1.879 + if (this._findResetTimeout != -1) 1.880 + clearTimeout(this._findResetTimeout); 1.881 + 1.882 + // allow a search to happen on input again after a second has 1.883 + // expired since the previous input, to allow for dynamic 1.884 + // content and/or page loading 1.885 + this._findResetTimeout = setTimeout(() => { 1.886 + this._findFailedString = null; 1.887 + this._findResetTimeout = -1; 1.888 + }, 1000); 1.889 + ]]></body> 1.890 + </method> 1.891 + 1.892 + <method name="_flash"> 1.893 + <body><![CDATA[ 1.894 + if (this._flashFindBarCount === undefined) 1.895 + this._flashFindBarCount = this._initialFlashFindBarCount; 1.896 + 1.897 + if (this._flashFindBarCount-- == 0) { 1.898 + clearInterval(this._flashFindBarTimeout); 1.899 + this.removeAttribute("flash"); 1.900 + this._flashFindBarCount = 6; 1.901 + return; 1.902 + } 1.903 + 1.904 + this.setAttribute("flash", 1.905 + (this._flashFindBarCount % 2 == 0) ? 1.906 + "false" : "true"); 1.907 + ]]></body> 1.908 + </method> 1.909 + 1.910 + <method name="_setHighlightTimeout"> 1.911 + <body><![CDATA[ 1.912 + if (this._highlightTimeout) 1.913 + clearTimeout(this._highlightTimeout); 1.914 + this._highlightTimeout = 1.915 + setTimeout(function(aSelf) { 1.916 + aSelf.toggleHighlight(false); 1.917 + aSelf.toggleHighlight(true); 1.918 + }, 500, this); 1.919 + ]]></body> 1.920 + </method> 1.921 + 1.922 + <method name="_findAgain"> 1.923 + <parameter name="aFindPrevious"/> 1.924 + <body><![CDATA[ 1.925 + this.browser.finder.findAgain(aFindPrevious, 1.926 + this._findMode == this.FIND_LINKS, 1.927 + this._findMode != this.FIND_NORMAL); 1.928 + ]]></body> 1.929 + </method> 1.930 + 1.931 + <method name="_updateStatusUI"> 1.932 + <parameter name="res"/> 1.933 + <parameter name="aFindPrevious"/> 1.934 + <body><![CDATA[ 1.935 + switch (res) { 1.936 + case this.nsITypeAheadFind.FIND_WRAPPED: 1.937 + this._findStatusIcon.setAttribute("status", "wrapped"); 1.938 + this._findStatusDesc.textContent = 1.939 + aFindPrevious ? this._wrappedToBottomStr : this._wrappedToTopStr; 1.940 + this._findField.removeAttribute("status"); 1.941 + break; 1.942 + case this.nsITypeAheadFind.FIND_NOTFOUND: 1.943 + this._findStatusIcon.setAttribute("status", "notfound"); 1.944 + this._findStatusDesc.textContent = this._notFoundStr; 1.945 + this._findField.setAttribute("status", "notfound"); 1.946 + break; 1.947 + case this.nsITypeAheadFind.FIND_PENDING: 1.948 + this._findStatusIcon.setAttribute("status", "pending"); 1.949 + this._findStatusDesc.textContent = ""; 1.950 + this._findField.removeAttribute("status"); 1.951 + break; 1.952 + case this.nsITypeAheadFind.FIND_FOUND: 1.953 + default: 1.954 + this._findStatusIcon.removeAttribute("status"); 1.955 + this._findStatusDesc.textContent = ""; 1.956 + this._findField.removeAttribute("status"); 1.957 + break; 1.958 + } 1.959 + ]]></body> 1.960 + </method> 1.961 + 1.962 + <method name="updateControlState"> 1.963 + <parameter name="aResult"/> 1.964 + <parameter name="aFindPrevious"/> 1.965 + <body><![CDATA[ 1.966 + this._updateStatusUI(aResult, aFindPrevious); 1.967 + this._enableFindButtons(aResult !== this.nsITypeAheadFind.FIND_NOTFOUND); 1.968 + ]]></body> 1.969 + </method> 1.970 + 1.971 + <method name="_getInitialSelection"> 1.972 + <body><![CDATA[ 1.973 + let focusedElement = document.commandDispatcher.focusedElement; 1.974 + let selText; 1.975 + 1.976 + if (focusedElement instanceof Components.interfaces.nsIDOMNSEditableElement && 1.977 + focusedElement.editor && 1.978 + focusedElement.ownerDocument.defaultView.top == this._browser.contentWindow) 1.979 + { 1.980 + // The user may have a selection in an input or textarea 1.981 + selText = focusedElement.editor.selectionController 1.982 + .getSelection(Components.interfaces.nsISelectionController.SELECTION_NORMAL) 1.983 + .toString(); 1.984 + } 1.985 + else { 1.986 + // Look for any selected text on the actual page 1.987 + let focusedWindow = document.commandDispatcher.focusedWindow; 1.988 + if (focusedWindow.top == this._browser.contentWindow) 1.989 + selText = focusedWindow.getSelection().toString(); 1.990 + } 1.991 + 1.992 + if (!selText) 1.993 + return ""; 1.994 + 1.995 + // Process our text to get rid of unwanted characters 1.996 + if (selText.length > this._selectionMaxLen) { 1.997 + let pattern = new RegExp("^(?:\\s*.){0," + this._selectionMaxLen + "}"); 1.998 + pattern.test(selText); 1.999 + selText = RegExp.lastMatch; 1.1000 + } 1.1001 + return selText.replace(/^\s+/, "") 1.1002 + .replace(/\s+$/, "") 1.1003 + .replace(/\s+/g, " ") 1.1004 + .substr(0, this._selectionMaxLen); 1.1005 + ]]></body> 1.1006 + </method> 1.1007 + 1.1008 + <method name="_dispatchFindEvent"> 1.1009 + <parameter name="aType"/> 1.1010 + <parameter name="aFindPrevious"/> 1.1011 + <body><![CDATA[ 1.1012 + let event = document.createEvent("CustomEvent"); 1.1013 + event.initCustomEvent("find" + aType, true, true, { 1.1014 + query: this._findField.value, 1.1015 + caseSensitive: !!this._typeAheadCaseSensitive, 1.1016 + highlightAll: this.getElement("highlight").checked, 1.1017 + findPrevious: aFindPrevious 1.1018 + }); 1.1019 + return this.dispatchEvent(event); 1.1020 + ]]></body> 1.1021 + </method> 1.1022 + 1.1023 + 1.1024 + <!-- 1.1025 + - Opens the findbar, focuses the findfield and selects its contents. 1.1026 + - Also flashes the findbar the first time it's used. 1.1027 + - @param aMode 1.1028 + - the find mode to be used, which is either FIND_NORMAL, 1.1029 + - FIND_TYPEAHEAD or FIND_LINKS. If not passed, the last 1.1030 + - find mode if any or FIND_NORMAL. 1.1031 + --> 1.1032 + <method name="startFind"> 1.1033 + <parameter name="aMode"/> 1.1034 + <body><![CDATA[ 1.1035 + let prefsvc = 1.1036 + Components.classes["@mozilla.org/preferences-service;1"] 1.1037 + .getService(Components.interfaces.nsIPrefBranch); 1.1038 + let userWantsPrefill = true; 1.1039 + this.open(aMode); 1.1040 + 1.1041 + if (this._flashFindBar) { 1.1042 + this._flashFindBarTimeout = setInterval(() => this._flash(), 500); 1.1043 + prefsvc.setIntPref("accessibility.typeaheadfind.flashBar", 1.1044 + --this._flashFindBar); 1.1045 + } 1.1046 + 1.1047 + if (this.prefillWithSelection) 1.1048 + userWantsPrefill = 1.1049 + prefsvc.getBoolPref("accessibility.typeaheadfind.prefillwithselection"); 1.1050 + 1.1051 + let initialString = null; 1.1052 + if (this.prefillWithSelection && userWantsPrefill) 1.1053 + initialString = this._getInitialSelection(); 1.1054 +#ifdef XP_MACOSX 1.1055 + if (!initialString) { 1.1056 + let clipboardSearchString = this.browser.finder.clipboardSearchString; 1.1057 + if (clipboardSearchString) 1.1058 + initialString = clipboardSearchString; 1.1059 + } 1.1060 +#endif 1.1061 + 1.1062 + if (initialString) 1.1063 + this._findField.value = initialString; 1.1064 + 1.1065 + this._enableFindButtons(!!this._findField.value); 1.1066 + 1.1067 + this._findField.select(); 1.1068 + this._findField.focus(); 1.1069 + ]]></body> 1.1070 + </method> 1.1071 + 1.1072 + <!-- 1.1073 + - Convenient alias to startFind(gFindBar.FIND_NORMAL); 1.1074 + - 1.1075 + - You should generally map the window's find command to this method. 1.1076 + - e.g. <command name="cmd_find" oncommand="gFindBar.onFindCommand();"/> 1.1077 + --> 1.1078 + <method name="onFindCommand"> 1.1079 + <body><![CDATA[ 1.1080 + this.startFind(this.FIND_NORMAL); 1.1081 + ]]></body> 1.1082 + </method> 1.1083 + 1.1084 + <!-- 1.1085 + - Stub for find-next and find-previous commands 1.1086 + - @param aFindPrevious 1.1087 + - true for find-previous, false otherwise. 1.1088 + --> 1.1089 + <method name="onFindAgainCommand"> 1.1090 + <parameter name="aFindPrevious"/> 1.1091 + <body><![CDATA[ 1.1092 + let findString = this._browser.finder.searchString || this._findField.value; 1.1093 + if (!findString) { 1.1094 + this.startFind(); 1.1095 + return; 1.1096 + } 1.1097 + 1.1098 + // We dispatch the findAgain event here instead of in _findAgain since 1.1099 + // if there is a find event handler that prevents the default then 1.1100 + // finder.searchString will never get updated which in turn means 1.1101 + // there would never be findAgain events because of the logic below. 1.1102 + if (!this._dispatchFindEvent("again", aFindPrevious)) 1.1103 + return; 1.1104 + 1.1105 + // user explicitly requested another search, so do it even if we think it'll fail 1.1106 + this._findFailedString = null; 1.1107 + 1.1108 + // Ensure the stored SearchString is in sync with what we want to find 1.1109 + if (this._findField.value != this._browser.finder.searchString) 1.1110 + this._find(this._findField.value); 1.1111 + else 1.1112 + this._findAgain(aFindPrevious); 1.1113 + 1.1114 + ]]></body> 1.1115 + </method> 1.1116 + 1.1117 +#ifdef XP_MACOSX 1.1118 + <!-- 1.1119 + - Fetches the currently selected text and sets that as the text to search 1.1120 + - next. This is a MacOS specific feature. 1.1121 + --> 1.1122 + <method name="onFindSelectionCommand"> 1.1123 + <body><![CDATA[ 1.1124 + let searchString = this.browser.finder.setSearchStringToSelection(); 1.1125 + if (searchString) 1.1126 + this._findField.value = searchString; 1.1127 + ]]></body> 1.1128 + </method> 1.1129 + 1.1130 + <method name="_onFindFieldFocus"> 1.1131 + <body><![CDATA[ 1.1132 + let prefsvc = 1.1133 + Components.classes["@mozilla.org/preferences-service;1"] 1.1134 + .getService(Components.interfaces.nsIPrefBranch); 1.1135 + const kPref = "accessibility.typeaheadfind.prefillwithselection"; 1.1136 + if (this.prefillWithSelection && prefsvc.getBoolPref(kPref)) 1.1137 + return; 1.1138 + 1.1139 + let clipboardSearchString = this._browser.finder.clipboardSearchString; 1.1140 + if (clipboardSearchString && this._findField.value != clipboardSearchString) { 1.1141 + this._findField.value = clipboardSearchString; 1.1142 + // Changing the search string makes the previous status invalid, so 1.1143 + // we better clear it here. 1.1144 + this._updateStatusUI(); 1.1145 + } 1.1146 + ]]></body> 1.1147 + </method> 1.1148 +#endif 1.1149 + 1.1150 + <!-- 1.1151 + - This handles all the result changes for both 1.1152 + - type-ahead-find and highlighting. 1.1153 + - @param aResult 1.1154 + - One of the nsITypeAheadFind.FIND_* constants 1.1155 + - indicating the result of a search operation. 1.1156 + - @param aFindBackwards 1.1157 + - If the search was done from the bottom to 1.1158 + - the top. This is used for right error messages 1.1159 + - when reaching "the end of the page". 1.1160 + - @param aLinkURL 1.1161 + - When a link matched then its URK. Always null 1.1162 + - when not in FIND_LINKS mode. 1.1163 + --> 1.1164 + <method name="onFindResult"> 1.1165 + <parameter name="aData"/> 1.1166 + <body><![CDATA[ 1.1167 + if (aData.storeResult && this._findField.value != this.browser.finder.searchString) 1.1168 + this._findField.value = this.browser.finder.searchString; 1.1169 + this._updateStatusUI(aData.result, aData.findBackwards); 1.1170 + this._updateStatusUIBar(aData.linkURL); 1.1171 + 1.1172 + if (aData.result == this.nsITypeAheadFind.FIND_NOTFOUND) 1.1173 + this._findFailedString = aData.searchString; 1.1174 + else 1.1175 + this._findFailedString = null; 1.1176 + 1.1177 + if (this._findMode != this.FIND_NORMAL) 1.1178 + this._setFindCloseTimeout(); 1.1179 + ]]></body> 1.1180 + </method> 1.1181 + 1.1182 + <!-- 1.1183 + - This handler may cancel a request to focus content by returning |false| 1.1184 + - explicitly. 1.1185 + --> 1.1186 + <method name="shouldFocusContent"> 1.1187 + <body><![CDATA[ 1.1188 + const fm = Components.classes["@mozilla.org/focus-manager;1"] 1.1189 + .getService(Components.interfaces.nsIFocusManager); 1.1190 + if (fm.focusedWindow != window) 1.1191 + return false; 1.1192 + 1.1193 + let focusedElement = fm.focusedElement; 1.1194 + if (!focusedElement) 1.1195 + return false; 1.1196 + 1.1197 + let bindingParent = document.getBindingParent(focusedElement); 1.1198 + if (bindingParent != this && bindingParent != this._findField) 1.1199 + return false; 1.1200 + 1.1201 + return true; 1.1202 + ]]></body> 1.1203 + </method> 1.1204 + 1.1205 + </implementation> 1.1206 + 1.1207 + <handlers> 1.1208 + <!-- 1.1209 + - We have to guard against `this.close` being |null| due to an unknown 1.1210 + - issue, which is tracked in bug 957999. 1.1211 + --> 1.1212 + <handler event="keypress" keycode="VK_ESCAPE" phase="capturing" 1.1213 + action="if (this.close) this.close();" preventdefault="true"/> 1.1214 + </handlers> 1.1215 + </binding> 1.1216 +</bindings>