home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / xulrunner-1.9.0.14 / chrome / toolkit.jar / content / global / bindings / findbar.xml < prev    next >
Encoding:
Extensible Markup Language  |  2008-04-09  |  49.1 KB  |  1,339 lines

  1. <?xml version="1.0"?>
  2.  
  3. <!-- ***** BEGIN LICENSE BLOCK *****
  4.    - Version: MPL 1.1/GPL 2.0/LGPL 2.1
  5.    -
  6.    - The contents of this file are subject to the Mozilla Public License Version
  7.    - 1.1 (the "License"); you may not use this file except in compliance with
  8.    - the License. You may obtain a copy of the License at
  9.    - http://www.mozilla.org/MPL/
  10.    -
  11.    - Software distributed under the License is distributed on an "AS IS" basis,
  12.    - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13.    - for the specific language governing rights and limitations under the
  14.    - License.
  15.    -
  16.    - The Original Code is mozilla.org viewsource frontend.
  17.    -
  18.    - The Initial Developer of the Original Code is
  19.    - Netscape Communications Corporation.
  20.    - Portions created by the Initial Developer are Copyright (C) 2003
  21.    - the Initial Developer. All Rights Reserved.
  22.    -
  23.    - Contributor(s):
  24.    -     Blake Ross <blake@cs.stanford.edu> (Original Author)
  25.    -     Masayuki Nakano <masayuki@d-toybox.com>
  26.    -     Ben Basson <contact@cusser.net>
  27.    -     Jason Barnabe <jason_barnabe@fastmail.fm>
  28.    -     Asaf Romano <mano@mozilla.com>
  29.    -     Ehsan Akhgari <ehsan.akhgari@gmail.com>
  30.    -
  31.    - Alternatively, the contents of this file may be used under the terms of
  32.    - either the GNU General Public License Version 2 or later (the "GPL"), or
  33.    - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  34.    - in which case the provisions of the GPL or the LGPL are applicable instead
  35.    - of those above. If you wish to allow use of your version of this file only
  36.    - under the terms of either the GPL or the LGPL, and not to allow others to
  37.    - use your version of this file under the terms of the MPL, indicate your
  38.    - decision by deleting the provisions above and replace them with the notice
  39.    - and other provisions required by the GPL or the LGPL. If you do not delete
  40.    - the provisions above, a recipient may use your version of this file under
  41.    - the terms of any one of the MPL, the GPL or the LGPL.
  42.    -
  43.    - ***** END LICENSE BLOCK ***** -->
  44.  
  45. <!DOCTYPE bindings [
  46. <!ENTITY % findBarDTD SYSTEM "chrome://global/locale/findbar.dtd" >
  47. %findBarDTD;
  48. <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
  49. %globalDTD;
  50. ]>
  51.  
  52. <bindings id="findbarBindings"
  53.    xmlns="http://www.mozilla.org/xbl"
  54.    xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  55.    xmlns:xbl="http://www.mozilla.org/xbl">
  56.  
  57.   <!-- Private binding -->
  58.   <binding id="findbar-textbox"
  59.            extends="chrome://global/content/bindings/textbox.xml#textbox">
  60.     <implementation>
  61.  
  62.       <field name="_findbar">null</field>
  63.       <property name="findbar" readonly="true">
  64.         <getter>
  65.           return this._findbar ?
  66.                  this._findbar : this._findbar = document.getBindingParent(this);
  67.         </getter>
  68.       </property>
  69.  
  70.       <method name="getSupportedFlavours">
  71.         <body><![CDATA[
  72.           var flavourSet = new FlavourSet();
  73.           flavourSet.appendFlavour("text/unicode");
  74.           return flavourSet;
  75.         ]]></body>
  76.       </method>
  77.  
  78.       <method name="onDrop">
  79.         <parameter name="aEvent"/>
  80.         <parameter name="aXferData"/>
  81.         <parameter name="aDragSession"/>
  82.         <body><![CDATA[
  83.           this.value = aXferData.data;
  84.           this.findbar._find(aXferData.data);
  85.         ]]></body>
  86.       </method>
  87.  
  88.       <method name="_handleEnter">
  89.         <parameter name="aEvent"/>
  90.         <body><![CDATA[
  91.           if (this.findbar._findMode == this.findbar.FIND_NORMAL) {
  92.             var findString = this.findbar._findField;
  93.             if (!findString.value)
  94.               return;
  95.             if (aEvent.ctrlKey) {
  96.               this.findbar.getElement("highlight").click();
  97.               return;
  98.             }
  99.  
  100.             this.findbar.onFindAgainCommand(aEvent.shiftKey);
  101.           }
  102.           else {
  103.             // We need to keep a reference to _foundLink because
  104.             // _finishFAYT resets it to null.
  105.             var tmpLink = this._findbar._foundLink;
  106.             if (tmpLink && this.findbar._finishFAYT(aEvent))
  107.               this.findbar._dispatchKeypressEvent(tmpLink, aEvent);
  108.           }
  109.         ]]></body>
  110.       </method>
  111.  
  112.       <method name="_handleTab">
  113.         <parameter name="aEvent"/>
  114.         <body><![CDATA[
  115.           var shouldHandle = !aEvent.altKey && !aEvent.ctrlKey &&
  116.                              !aEvent.metaKey;
  117.           if (shouldHandle &&
  118.               this.findbar._findMode != this.findbar.FIND_NORMAL &&
  119.               this.findbar._finishFAYT(aEvent)) {
  120.             if (aEvent.shiftKey)
  121.               document.commandDispatcher.rewindFocus();
  122.             else
  123.               document.commandDispatcher.advanceFocus();
  124.           }
  125.         ]]></body>
  126.       </method>
  127.     </implementation>
  128.  
  129.     <handlers>
  130.       <handler event="input"><![CDATA[
  131.         this.findbar._find(this.value);
  132.       ]]></handler>
  133.  
  134.       <handler event="keypress"><![CDATA[
  135.         var win = this.findbar._currentWindow ||
  136.                   this.findbar.browser.contentWindow;
  137.  
  138.         switch (event.keyCode) {
  139.           case KeyEvent.DOM_VK_RETURN:
  140.             this._handleEnter(event);
  141.             break;
  142.           case KeyEvent.DOM_VK_TAB:
  143.             this._handleTab(event);
  144.             break;
  145.           case KeyEvent.DOM_VK_PAGE_UP:
  146.             win.scrollByPages(-1);
  147.             event.preventDefault();
  148.             break;
  149.           case KeyEvent.DOM_VK_PAGE_DOWN:
  150.             win.scrollByPages(1);
  151.             event.preventDefault();
  152.             break;
  153.           case KeyEvent.DOM_VK_UP:
  154.             win.scrollByLines(-1);
  155.             event.preventDefault();
  156.             break;
  157.           case KeyEvent.DOM_VK_DOWN:
  158.             win.scrollByLines(1);
  159.             event.preventDefault();
  160.             break;
  161.         }
  162.       ]]></handler>
  163.  
  164.       <handler event="blur"><![CDATA[
  165.         var findbar = this.findbar;
  166.         var fastFind = findbar.browser.fastFind;
  167.         if (findbar._foundEditable)
  168.           fastFind.collapseSelection();
  169.         else {
  170.           fastFind.setSelectionModeAndRepaint
  171.             (findbar.nsISelectionController.SELECTION_ON);
  172.         }
  173.         findbar._setFoundLink(null);
  174.         findbar._foundEditable = null;
  175.         findbar._currentWindow = null;
  176.       ]]></handler>
  177.  
  178.       <handler event="compositionstart"><![CDATA[
  179.         // Don't close the find toolbar while IME is composing.
  180.         var findbar = this.findbar;
  181.         findbar._isIMEComposing = true;
  182.         if (findbar._quickFindTimeout) {
  183.           clearTimeout(findbar._quickFindTimeout);
  184.           findbar._quickFindTimeout = null;
  185.         }
  186.       ]]></handler>
  187.  
  188.       <handler event="compositionend"><![CDATA[
  189.         var findbar = this.findbar;
  190.         findbar._isIMEComposing = false;
  191.         if (findbar._findMode != findbar.FIND_NORMAL &&
  192.             !findbar.hidden)
  193.           findbar._setFindCloseTimeout();
  194.       ]]></handler>
  195.  
  196.       <handler event="dragdrop" phase="capturing"><![CDATA[
  197.         nsDragAndDrop.drop(event, this);
  198.       ]]></handler>
  199.     </handlers>
  200.   </binding>
  201.  
  202.   <binding id="findbar"
  203.            extends="chrome://global/content/bindings/toolbar.xml#toolbar">
  204.     <resources>
  205.       <stylesheet src="chrome://global/skin/findBar.css"/>
  206.     </resources>
  207.  
  208.     <content hidden="true">
  209.     <xul:hbox anonid="findbar-container" class="findbar-container" flex="1" align="center">
  210.       <xul:toolbarbutton anonid="find-closebutton"
  211.                          class="findbar-closebutton"
  212.                          tooltiptext="&findCloseButton.tooltip;"
  213.                          oncommand="close();"/>
  214.       <xul:label anonid="find-label" class="findbar-find-fast" control="findbar-textbox"/>
  215.       <xul:hbox anonid="find-field-container"
  216.                 class="find-field-container findbar-find-fast">
  217.         <xul:textbox class="findbar-textbox" anonid="findbar-textbox"/>
  218.       </xul:hbox>
  219.       <xul:hbox anonid="find-buttons-container" class="find-buttons-container">
  220.         <xul:toolbarbutton anonid="find-next"
  221.                            class="findbar-find-next tabbable"
  222.                            label="&next.label;"
  223.                            accesskey="&next.accesskey;"
  224.                            tooltiptext="&next.tooltip;"
  225.                            oncommand="onFindAgainCommand(false);"
  226.                            disabled="true"
  227.                            chromedir="&locale.dir;"
  228.                            xbl:inherits="accesskey=findnextaccesskey"/>
  229.         <xul:toolbarbutton anonid="find-previous"
  230.                            class="findbar-find-previous tabbable"
  231.                            label="&previous.label;"
  232.                            accesskey="&previous.accesskey;"
  233.                            tooltiptext="&previous.tooltip;"
  234.                            oncommand="onFindAgainCommand(true);"
  235.                            disabled="true"
  236.                            chromedir="&locale.dir;"
  237.                            xbl:inherits="accesskey=findpreviousaccesskey"/>
  238.       </xul:hbox>
  239.       <xul:toolbarbutton anonid="highlight"
  240.                          class="findbar-highlight tabbable"
  241.                          label="&highlight.label;"
  242.                          accesskey="&highlight.accesskey;"
  243.                          tooltiptext="&highlight.tooltiptext;"
  244.                          oncommand="toggleHighlight(this.checked);"
  245.                          type="checkbox"
  246.                          disabled="true"
  247.                          xbl:inherits="accesskey=highlightaccesskey"/>
  248.       <xul:checkbox anonid="find-case-sensitive"
  249.                     oncommand="_setCaseSensitivity(this.checked);"
  250.                     label="&caseSensitiveCheckbox.label;"
  251.                     accesskey="&caseSensitiveCheckbox.accesskey;"
  252.                     xbl:inherits="accesskey=matchcaseaccesskey"/>
  253.       <xul:label anonid="match-case-status" class="findbar-find-fast"/>
  254.       <xul:image anonid="find-status-icon" class="findbar-find-fast find-status-icon"/>
  255.       <xul:description anonid="find-status" class="findbar-find-fast findbar-find-status"
  256.                        control="findbar-textbox">
  257.       <!-- Do not use value, first child is used because it provides a11y with text change events -->
  258.       </xul:description>
  259.     </xul:hbox>
  260.     </content>
  261.  
  262.     <implementation implements="nsIDOMEventListener">
  263.       <field name="FIND_NORMAL">0</field>
  264.       <field name="FIND_TYPEAHEAD">1</field>
  265.       <field name="FIND_LINKS">2</field>
  266.  
  267.       <field name="_findMode">0</field>
  268.       <field name="_tmpOutline">null</field>
  269.       <field name="_tmpOutlineOffset">"0"</field>
  270.       <field name="_drawOutline">false</field>
  271.       <field name="_foundLink">null</field>
  272.  
  273.       <field name="_flashFindBar">0</field>
  274.       <field name="_initialFlashFindBarCount">6</field>
  275.  
  276.       <property name="prefillWithSelection"
  277.                 onget="return this.getAttribute('prefillwithselection') != 'false'"
  278.                 onset="this.setAttribute('prefillwithselection', val); return val;"/>
  279.       <field name="_selectionMaxLen">150</field>
  280.  
  281.       <method name="getElement">
  282.         <parameter name="aAnonymousID"/>
  283.         <body><![CDATA[
  284.           return document.getAnonymousElementByAttribute(this,
  285.                                                          "anonid",
  286.                                                          aAnonymousID)
  287.         ]]></body>
  288.       </method>
  289.  
  290.       <property name="findMode"
  291.                 readonly="true"
  292.                 onget="return this._findMode;"/>
  293.  
  294.       <field name="_browser">null</field>
  295.       <property name="browser">
  296.         <getter><![CDATA[
  297.           if (!this._browser) {
  298.             this._browser =
  299.               document.getElementById(this.getAttribute("browserid"));
  300.           }
  301.           return this._browser;
  302.         ]]></getter>
  303.         <setter><![CDATA[
  304.           if (this._browser) {
  305.             this._browser.removeEventListener("keypress", this, false);
  306.             this._browser.removeEventListener("mouseup", this, false);
  307.             this._foundLink = null;
  308.             this._foundEditable = null;
  309.             this._currentWindow = null;
  310.           }
  311.  
  312.           this._browser = val;
  313.           if (this._browser) {
  314.             this._browser.addEventListener("keypress", this, false);
  315.             this._browser.addEventListener("mouseup", this, false);
  316.             this._findField.value = this._browser.fastFind.searchString;
  317.           }
  318.           return val;
  319.         ]]></setter>
  320.       </property>
  321.  
  322.       <field name="_observer"><![CDATA[({
  323.         _self: this,
  324.  
  325.         QueryInterface: function(aIID) {
  326.           if (aIID.equals(Components.interfaces.nsIObserver) ||
  327.               aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
  328.               aIID.equals(Components.interfaces.nsISupports))
  329.             return this;
  330.  
  331.           throw Components.results.NS_ERROR_NO_INTERFACE;
  332.         },
  333.  
  334.         observe: function(aSubject, aTopic, aPrefName) {
  335.           if (aTopic != "nsPref:changed")
  336.             return;
  337.  
  338.           var prefsvc =
  339.             aSubject.QueryInterface(Components.interfaces.nsIPrefBranch2);
  340.  
  341.           switch (aPrefName) {
  342.             case "accessibility.typeaheadfind":
  343.               this._self._useTypeAheadFind = prefsvc.getBoolPref(aPrefName);
  344.               break;
  345.             case "accessibility.typeaheadfind.linksonly":
  346.               this._self._typeAheadLinksOnly = prefsvc.getBoolPref(aPrefName);
  347.               break;
  348.             case "accessibility.typeaheadfind.casesensitive":
  349.               this._self._typeAheadCaseSensitive = prefsvc.getIntPref(aPrefName);
  350.               this._self._updateCaseSensitivity();
  351.               if (this._self.getElement("highlight").checked)
  352.                 this._self._setHighlightTimeout();
  353.               break;
  354.           }
  355.         }
  356.       })]]></field>
  357.  
  358.       <constructor><![CDATA[
  359.         // These elements are accessed frequently and are therefore cached
  360.         this._findField = this.getElement("findbar-textbox");
  361.         this._findStatusIcon = this.getElement("find-status-icon");
  362.         this._findStatusDesc = this.getElement("find-status");
  363.  
  364.         var prefsvc =
  365.           Components.classes["@mozilla.org/preferences-service;1"]
  366.                     .getService(Components.interfaces.nsIPrefBranch2);
  367.  
  368.         this._quickFindTimeoutLength =
  369.           prefsvc.getIntPref("accessibility.typeaheadfind.timeout");
  370.         this._flashFindBar =
  371.           prefsvc.getIntPref("accessibility.typeaheadfind.flashBar");
  372.  
  373.         prefsvc.addObserver("accessibility.typeaheadfind",
  374.                             this._observer, false);
  375.         prefsvc.addObserver("accessibility.typeaheadfind.linksonly",
  376.                             this._observer, false);
  377.         prefsvc.addObserver("accessibility.typeaheadfind.casesensitive",
  378.                             this._observer, false);
  379.  
  380.         this._useTypeAheadFind =
  381.           prefsvc.getBoolPref("accessibility.typeaheadfind");
  382.         this._typeAheadLinksOnly =
  383.           prefsvc.getBoolPref("accessibility.typeaheadfind.linksonly");
  384.         this._typeAheadCaseSensitive =
  385.           prefsvc.getIntPref("accessibility.typeaheadfind.casesensitive");
  386.  
  387.         // Convenience
  388.         this.nsITypeAheadFind = Components.interfaces.nsITypeAheadFind;
  389.         this.nsISelectionController = Components.interfaces.nsISelectionController;
  390.  
  391.         // Make sure the FAYT keypress listener is attached by initializing the
  392.         // browser property
  393.         setTimeout(function(aSelf) { aSelf.browser = aSelf.browser; }, 0, this);
  394.       ]]></constructor>
  395.  
  396.       <destructor><![CDATA[
  397.         this.browser = null;
  398.  
  399.         var prefsvc =
  400.           Components.classes["@mozilla.org/preferences-service;1"]
  401.                     .getService(Components.interfaces.nsIPrefBranch2);
  402.         prefsvc.removeObserver("accessibility.typeaheadfind",
  403.                                this._observer);
  404.         prefsvc.removeObserver("accessibility.typeaheadfind.linksonly",
  405.                                this._observer);
  406.         prefsvc.removeObserver("accessibility.typeaheadfind.casesensitive",
  407.                                this._observer);
  408.       ]]></destructor>
  409.  
  410.       <method name="_setFindCloseTimeout">
  411.         <body><![CDATA[
  412.           if (this._quickFindTimeout)
  413.             clearTimeout(this._quickFindTimeout);
  414.  
  415.           // Don't close the find toolbar while IME is composing.
  416.           if (this._isIMEComposing) {
  417.             this._quickFindTimeout = null;
  418.             return;
  419.           }
  420.  
  421.           this._quickFindTimeout =
  422.             setTimeout(function(aSelf) {
  423.                          if (aSelf._findMode != aSelf.FIND_NORMAL)
  424.                            aSelf.close();
  425.                        }, this._quickFindTimeoutLength, this);
  426.         ]]></body>
  427.       </method>
  428.  
  429.       <!--
  430.         - Turns highlight on or off.
  431.         - @param aHighlight (boolean)
  432.         -        Whether to turn on highlight
  433.         -->
  434.       <method name="toggleHighlight">
  435.         <parameter name="aHighlight"/>
  436.         <body><![CDATA[
  437.           var word = this._findField.value;
  438.           if (aHighlight) {
  439.             // We have to update the status because we might still have the status
  440.             // of another tab
  441.             if (this._highlightDoc("yellow", "black", word))
  442.               this._updateStatusUI(this.nsITypeAheadFind.FIND_FOUND);
  443.             else
  444.               this._updateStatusUI(this.nsITypeAheadFind.FIND_NOTFOUND);
  445.           }
  446.           else {
  447.             this._highlightDoc(null, null, null);
  448.             this._lastHighlightString = null;
  449.           }
  450.         ]]></body>
  451.       </method>
  452.  
  453.       <!--
  454.         - (Un)highlights each instance of the searched word in the passed
  455.         - window's content.
  456.         - @param aHighBackColor
  457.         -        the background color for the highlight
  458.         - @param aHighTextColor
  459.         -        the text color for the highlight, or null to make it
  460.         -        unhighlight
  461.         - @param aWord
  462.         -        the word to search for
  463.         - @param aWindow
  464.         -        the window to search in. Passing undefined will search the
  465.         -        current content window.
  466.         - @returns true if aWord was found
  467.         -->
  468.       <method name="_highlightDoc">
  469.         <parameter name="aHighBackColor"/>
  470.         <parameter name="aHighTextColor"/>
  471.         <parameter name="aWord"/>
  472.         <parameter name="aWindow"/>
  473.         <body><![CDATA[
  474.           var win = aWindow || this.browser.contentWindow;
  475.  
  476.           var textFound = false;
  477.           for (var i = 0; win.frames && i < win.frames.length; i++) {
  478.             if (this._highlightDoc(aHighBackColor, aHighTextColor, aWord, win.frames[i]))
  479.               textFound = true;
  480.           }
  481.  
  482.           var doc = win.document;
  483.           if (!doc || !(doc instanceof HTMLDocument))
  484.             return textFound;
  485.  
  486.           var body = doc.body;
  487.  
  488.           var count = body.childNodes.length;
  489.           this._searchRange = doc.createRange();
  490.           this._startPt = doc.createRange();
  491.           this._endPt = doc.createRange();
  492.  
  493.           this._searchRange.setStart(body, 0);
  494.           this._searchRange.setEnd(body, count);
  495.  
  496.           this._startPt.setStart(body, 0);
  497.           this._startPt.setEnd(body, 0);
  498.           this._endPt.setStart(body, count);
  499.           this._endPt.setEnd(body, count);
  500.  
  501.           if (!aHighBackColor) {
  502.             // Remove highlighting.  We use the find API again rather than
  503.             // searching for our span elements so that we gain access to the
  504.             // anonymous content that nsIFind searches.
  505.  
  506.             if (!this._lastHighlightString)
  507.               return textFound;
  508.  
  509.             var retRange = null;
  510.             var finder = Components.classes["@mozilla.org/embedcomp/rangefind;1"]
  511.                                    .createInstance(Components.interfaces.nsIFind);
  512.  
  513.             while ((retRange = finder.Find(this._lastHighlightString,
  514.                                            this._searchRange, this._startPt,
  515.                                            this._endPt))) {
  516.               var startContainer = retRange.startContainer;
  517.               var elem = null;
  518.               try {
  519.                 elem = startContainer.parentNode;
  520.               }
  521.               catch (ex) { }
  522.  
  523.               if (elem && elem.className == "__mozilla-findbar-search") {
  524.                 var child = null;
  525.                 var docfrag = doc.createDocumentFragment();
  526.                 var next = elem.nextSibling;
  527.                 var parent = elem.parentNode;
  528.  
  529.                 while ((child = elem.firstChild)) {
  530.                   docfrag.appendChild(child);
  531.                 }
  532.  
  533.                 this._startPt = doc.createRange();
  534.                 this._startPt.setStartAfter(elem);
  535.  
  536.                 parent.removeChild(elem);
  537.                 parent.insertBefore(docfrag, next);
  538.                 parent.normalize();
  539.               }
  540.               else {
  541.                 // Somehow we didn't highlight this instance; just skip it.
  542.                 this._startPt = doc.createRange();
  543.                 this._startPt.setStart(retRange.endContainer,
  544.                                        retRange.endOffset);
  545.               }
  546.  
  547.               this._startPt.collapse(true);
  548.  
  549.               textFound = true;
  550.             }
  551.             return textFound;
  552.           }
  553.  
  554.           var baseNode = doc.createElementNS("http://www.w3.org/1999/xhtml", "span");
  555.           baseNode.style.backgroundColor = aHighBackColor;
  556.           baseNode.style.color = aHighTextColor;
  557.           baseNode.style.display = "inline";
  558.           baseNode.style.fontSize = "inherit";
  559.           baseNode.style.padding = "0";
  560.           baseNode.className = "__mozilla-findbar-search";
  561.  
  562.           return this._highlightText(aWord, baseNode) || textFound;
  563.         ]]></body>
  564.       </method>
  565.  
  566.       <!--
  567.         - Highlights each instance of the searched word in the current range.
  568.         -
  569.         - @param aWord
  570.         -        the word to search for.
  571.         - @param aBaseNode
  572.         -        a node to use as a template for what will replace the searched
  573.         -        word.
  574.         - @returns true if aWord was found
  575.         -->
  576.       <method name="_highlightText">
  577.         <parameter name="aWord"/>
  578.         <parameter name="aBaseNode"/>
  579.         <body><![CDATA[
  580.           var retRange = null;
  581.           var finder = Components.classes["@mozilla.org/embedcomp/rangefind;1"]
  582.                                  .createInstance()
  583.                                  .QueryInterface(Components.interfaces.nsIFind);
  584.  
  585.           finder.caseSensitive = this._shouldBeCaseSensitive(aWord);
  586.  
  587.           var textFound = false;
  588.           while((retRange = finder.Find(aWord, this._searchRange,
  589.                                         this._startPt, this._endPt))) {
  590.             // Highlight
  591.             var nodeSurround = aBaseNode.cloneNode(true);
  592.             var node = this._highlight(retRange, nodeSurround);
  593.             this._startPt = node.ownerDocument.createRange();
  594.             this._startPt.setStart(node, node.childNodes.length);
  595.             this._startPt.setEnd(node, node.childNodes.length);
  596.  
  597.             textFound = true;
  598.           }
  599.  
  600.           this._lastHighlightString = aWord;
  601.  
  602.           return textFound;
  603.         ]]></body>
  604.       </method>
  605.  
  606.      <!--
  607.        - Highlights the word in the passed range.
  608.        -
  609.        - @param aRange
  610.        -        the range that contains the word to highlight
  611.        - @param aNode
  612.        -        the node replace the searched word with
  613.        - @returns the node that replaced the searched word
  614.        -->
  615.       <method name="_highlight">
  616.         <parameter name="aRange"/>
  617.         <parameter name="aNode"/>
  618.         <body><![CDATA[
  619.           var startContainer = aRange.startContainer;
  620.           var startOffset = aRange.startOffset;
  621.           var endOffset = aRange.endOffset;
  622.           var docfrag = aRange.extractContents();
  623.           var before = startContainer.splitText(startOffset);
  624.           var parent = before.parentNode;
  625.           aNode.appendChild(docfrag);
  626.           parent.insertBefore(aNode, before);
  627.           return aNode;
  628.         ]]></body>
  629.       </method>
  630.  
  631.       <!--
  632.         - Updates the case-sensitivity mode of the findbar and its UI.
  633.         - @param [optional] aString
  634.         -        The string for which case sensitivity might be turned on.
  635.         -        This only used when case-sensitivity is in auto mode,
  636.         -        @see _shouldBeCaseSensitive. The default value for this
  637.         -        parameter is the find-field value.
  638.         -->
  639.       <method name="_updateCaseSensitivity">
  640.         <parameter name="aString"/>
  641.         <body><![CDATA[
  642.           var val = aString || this._findField.value;
  643.  
  644.           var caseSensitive = this._shouldBeCaseSensitive(val);
  645.           var checkbox = this.getElement("find-case-sensitive");
  646.           var statusLabel = this.getElement("match-case-status");
  647.           checkbox.checked = caseSensitive;
  648.  
  649.           statusLabel.value = caseSensitive ? this._caseSensitiveStr : "";
  650.  
  651.           // Show the checkbox on the full Find bar in non-auto mode.
  652.           // Show the label in all other cases.
  653.           var hideCheckbox = this._findMode != this.FIND_NORMAL ||
  654.             (this._typeAheadCaseSensitive != 0 &&
  655.              this._typeAheadCaseSensitive != 1);
  656.           checkbox.hidden = hideCheckbox;
  657.           statusLabel.hidden = !hideCheckbox;
  658.  
  659.           var fastFind = this.browser.fastFind;
  660.           fastFind.caseSensitive = caseSensitive;
  661.         ]]></body>
  662.       </method>
  663.  
  664.       <!--
  665.         - Sets the findbar case-sensitivity mode
  666.         - @param aCaseSensitive (boolean)
  667.         -        Whether or not case-sensitivity should be turned on.
  668.         -->
  669.       <method name="_setCaseSensitivity">
  670.         <parameter name="aCaseSensitive"/>
  671.         <body><![CDATA[
  672.           var prefsvc =
  673.             Components.classes["@mozilla.org/preferences-service;1"]
  674.                       .getService(Components.interfaces.nsIPrefBranch2);
  675.  
  676.           // Just set the pref; our observer will change the find bar behavior
  677.           prefsvc.setIntPref("accessibility.typeaheadfind.casesensitive",
  678.                              aCaseSensitive ? 1 : 0);
  679.         ]]></body>
  680.       </method>
  681.  
  682.       <!--
  683.         - Opens and displays the find bar.
  684.         -
  685.         - @param aMode
  686.         -        the find mode to be used, which is either FIND_NORMAL,
  687.         -        FIND_TYPEAHEAD or FIND_LINKS. If not passed, the last
  688.         -        find mode if any or FIND_NORMAL.
  689.         - @returns true if the find bar wasn't previously open, false otherwise.
  690.         -->
  691.       <method name="open">
  692.         <parameter name="aMode"/>
  693.         <body><![CDATA[
  694.           if (aMode != undefined)
  695.             this._findMode = aMode;
  696.  
  697.           if (!this._notFoundStr) {
  698.             var stringsBundle =
  699.               Components.classes["@mozilla.org/intl/stringbundle;1"]
  700.                         .getService(Components.interfaces.nsIStringBundleService)
  701.                         .createBundle("chrome://global/locale/findbar.properties");
  702.             this._notFoundStr = stringsBundle.GetStringFromName("NotFound");
  703.             this._wrappedToTopStr =
  704.               stringsBundle.GetStringFromName("WrappedToTop");
  705.             this._wrappedToBottomStr =
  706.               stringsBundle.GetStringFromName("WrappedToBottom");
  707.             this._normalFindStr =
  708.               stringsBundle.GetStringFromName("NormalFindLabel");
  709.             this._fastFindStr =
  710.               stringsBundle.GetStringFromName("FastFindLabel");
  711.             this._fastFindLinksStr =
  712.               stringsBundle.GetStringFromName("FastFindLinksLabel");
  713.             this._caseSensitiveStr =
  714.               stringsBundle.GetStringFromName("CaseSensitive");
  715.           }
  716.  
  717.           this._updateFindUI();
  718.           if (this.hidden) {
  719.             this.hidden = false;
  720.  
  721.             this._updateStatusUI(this.nsITypeAheadFind.FIND_FOUND);
  722.             return true;
  723.           }
  724.           return false;
  725.         ]]></body>
  726.       </method>
  727.  
  728.       <!--
  729.         - Closes the findbar.
  730.         -->
  731.       <method name="close">
  732.         <body><![CDATA[
  733.           var ww =
  734.             Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
  735.                       .getService(Components.interfaces.nsIWindowWatcher);
  736.           if (window == ww.activeWindow) {
  737.             var focusedElement = document.commandDispatcher.focusedElement;
  738.             if (focusedElement) {
  739.               var bindingParent = document.getBindingParent(focusedElement);
  740.               if (bindingParent == this || bindingParent == this._findField) {
  741.                 // block scrolling on focus since find already scrolls, further
  742.                 // scrolling is due to user action, so don't override this
  743.                 var suppressedScroll = document.commandDispatcher.suppressFocusScroll;
  744.                 document.commandDispatcher.suppressFocusScroll = true;
  745.                 // We MUST reset suppressFocusScroll.
  746.                 try {
  747.                   if (this._foundLink)
  748.                     this._foundLink.focus();
  749.                   else if (this._foundEditable)
  750.                     this._foundEditable.focus();
  751.                   else if (this._currentWindow)
  752.                     this._currentWindow.focus();
  753.                   else
  754.                     this.browser.contentWindow.focus();
  755.                 }
  756.                 catch(ex) {
  757.                   // Retry to set focus.
  758.                   try {
  759.                     this.browser.contentWindow.focus();
  760.                   }
  761.                   catch(e) { /* We lose focused element! */ }
  762.                 }
  763.                 document.commandDispatcher.suppressFocusScroll = suppressedScroll;
  764.               }
  765.             }
  766.           }
  767.  
  768.           this.hidden = true;
  769.           var fastFind = this.browser.fastFind;
  770.           fastFind.setSelectionModeAndRepaint
  771.             (this.nsISelectionController.SELECTION_ON);
  772.           this._setFoundLink(null);
  773.           this._foundEditable = null;
  774.           this._currentWindow = null;
  775.           if (this._quickFindTimeout) {
  776.             clearTimeout(this._quickFindTimeout);
  777.             this._quickFindTimeout = null;
  778.           }
  779.         ]]></body>
  780.       </method>
  781.  
  782.       <method name="_dispatchKeypressEvent">
  783.         <parameter name="aTarget"/>
  784.         <parameter name="aEvent"/>
  785.         <body><![CDATA[
  786.           if (!aTarget)
  787.             return;
  788.  
  789.           var event = document.createEvent("KeyEvents");
  790.           event.initKeyEvent(aEvent.type, aEvent.bubbles, aEvent.cancelable,
  791.                              aEvent.view, aEvent.ctrlKey, aEvent.altKey,
  792.                              aEvent.shiftKey, aEvent.metaKey, aEvent.keyCode,
  793.                              aEvent.charCode);
  794.           aTarget.dispatchEvent(event);
  795.         ]]></body>
  796.       </method>
  797.  
  798.       <field name="_xulBrowserWindow">null</field>
  799.       <method name="_updateStatusUIBar">
  800.         <body><![CDATA[
  801.           if (!this._xulBrowserWindow) {
  802.             try {
  803.               this._xulBrowserWindow =
  804.                 window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  805.                       .getInterface(Components.interfaces.nsIWebNavigation)
  806.                       .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
  807.                       .treeOwner
  808.                       .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  809.                       .getInterface(Components.interfaces.nsIXULWindow)
  810.                       .XULBrowserWindow;
  811.             }
  812.             catch(ex) { }
  813.             if (!this._xulBrowserWindow)
  814.               return false;
  815.           }
  816.  
  817.           if (!this._foundLink || !this._foundLink.href ||
  818.               this._foundLink.href == "") {
  819.             this._xulBrowserWindow.setOverLink("", null);
  820.             return true;
  821.           }
  822.  
  823.           var docCharset = "";
  824.           var ownerDoc = this._foundLink.ownerDocument;
  825.           if (ownerDoc)
  826.             docCharset = ownerDoc.characterSet;
  827.  
  828.           if (!this._textToSubURIService) {
  829.             this._textToSubURIService =
  830.               Components.classes["@mozilla.org/intl/texttosuburi;1"]
  831.                         .getService(Components.interfaces.nsITextToSubURI);
  832.           }
  833.           var url =
  834.             this._textToSubURIService.unEscapeURIForUI(docCharset,
  835.                                                        this._foundLink.href);
  836.           this._xulBrowserWindow.setOverLink(url, null);
  837.  
  838.           return true;
  839.         ]]></body>
  840.       </method>
  841.  
  842.       <method name="_setFoundLink">
  843.         <parameter name="aFoundLink"/>
  844.         <body><![CDATA[
  845.           if (this._foundLink == aFoundLink)
  846.             return;
  847.  
  848.           if (this._foundLink && this._drawOutline) {
  849.             // restore original outline
  850.             this._foundLink.style.outline = this._tmpOutline;
  851.             this._foundLink.style.outlineOffset = this._tmpOutlineOffset;
  852.           }
  853.           this._drawOutline = (aFoundLink && this._findMode != this.FIND_NORMAL);
  854.           if (this._drawOutline) {
  855.             // backup original outline
  856.             this._tmpOutline = aFoundLink.style.outline;
  857.             this._tmpOutlineOffset = aFoundLink.style.outlineOffset;
  858.  
  859.             // draw pseudo focus rect
  860.             // XXX Should we change the following style for FAYT pseudo focus?
  861.             // XXX Shouldn't we change default design if outline is visible
  862.             //     already?
  863.             // Don't set the outline-color, we should always use initial value.
  864.             aFoundLink.style.outline = "1px dotted";
  865.             aFoundLink.style.outlineOffset = "0";
  866.           }
  867.  
  868.           this._foundLink = aFoundLink;
  869.  
  870.           // If the mouse cursor is on the document, the status bar text is
  871.           // changed by a mouse event which is dispatched by a scroll event.
  872.           // Thus we should change it only after the mouse event is dispatched.
  873.           if (this._findMode != this.FIND_NORMAL)
  874.             setTimeout(function(aSelf) { aSelf._updateStatusUIBar(); }, 0, this);
  875.         ]]></body>
  876.       </method>
  877.  
  878.       <method name="_finishFAYT">
  879.         <parameter name="aKeypressEvent"/>
  880.         <body><![CDATA[
  881.           try {
  882.             if (this._foundLink)
  883.               this._foundLink.focus();
  884.             else if (this._foundEditable) {
  885.               this._foundEditable.focus();
  886.               var fastFind = this.browser.fastFind;
  887.               fastFind.collapseSelection();
  888.             }
  889.             else if (this._currentWindow)
  890.               this._currentWindow.focus();
  891.             else
  892.               return false;
  893.           }
  894.           catch(e) {
  895.             return false;
  896.           }
  897.  
  898.           if (aKeypressEvent)
  899.             aKeypressEvent.preventDefault();
  900.  
  901.           this.close();
  902.           return true;
  903.         ]]></body>
  904.       </method>
  905.  
  906.       <!--
  907.         - Returns true if |aMimeType| is text-based, or false otherwise.
  908.         -
  909.         - @param aMimeType
  910.         -        The MIME type to check.
  911.         -
  912.         - if adding types to this function, please see the similar function
  913.         - in browser/base/content/browser.js
  914.         -->
  915.       <method name="_mimeTypeIsTextBased">
  916.         <parameter name="aMimeType"/>
  917.         <body><![CDATA[
  918.           return /^text\/|\+xml$/.test(aMimeType) ||
  919.                  aMimeType == "application/x-javascript" ||
  920.                  aMimeType == "application/javascript" ||
  921.                  aMimeType == "application/xml";
  922.         ]]></body>
  923.       </method>
  924.  
  925.       <!--
  926.         - Returns whether FAYT can be used for the given event in
  927.         - the current content state.
  928.         -->
  929.       <method name="_shouldFastFind">
  930.         <parameter name="aEvent"/>
  931.         <body><![CDATA[
  932.           if (aEvent.ctrlKey || aEvent.altKey || aEvent.metaKey ||
  933.               aEvent.getPreventDefault())
  934.             return false;
  935.  
  936.           var win = document.commandDispatcher.focusedWindow;
  937.           if (win)
  938.             if (!this._mimeTypeIsTextBased(win.document.contentType))
  939.               return false;
  940.  
  941.           var elt = document.commandDispatcher.focusedElement;
  942.           if (elt) {
  943.             if (elt instanceof HTMLInputElement) {
  944.               // block FAYT when an <input> textfield element is focused
  945.               var inputType = elt.type;
  946.               switch (inputType) {
  947.                 case "text":
  948.                 case "password":
  949.                 case "file":
  950.                   return false;
  951.               }
  952.             }
  953.             else if (elt instanceof HTMLTextAreaElement ||
  954.                      elt instanceof HTMLSelectElement ||
  955.                      elt instanceof HTMLIsIndexElement ||
  956.                      elt instanceof HTMLObjectElement ||
  957.                      elt instanceof HTMLEmbedElement)
  958.               return false;
  959.           }
  960.  
  961.           // disable FAYT in about:config and about:blank to prevent FAYT
  962.           // opening unexpectedly - to fix bugs 264562, 267150, 269712
  963.           var url = this.browser.currentURI.spec;
  964.           if (url == "about:blank" || url == "about:config")
  965.             return false;
  966.  
  967.           if (win) {
  968.             try {
  969.               var editingSession = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  970.                                    .getInterface(Components.interfaces.nsIWebNavigation)
  971.                                    .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  972.                                    .getInterface(Components.interfaces.nsIEditingSession);
  973.               if (editingSession.windowIsEditable(win))
  974.                 return false;
  975.             }
  976.             catch (e) {
  977.               // If someone built with composer disabled, we can't get an editing session.
  978.             }
  979.           }  
  980.  
  981.           return true;
  982.         ]]></body>
  983.       </method>
  984.  
  985.       <method name="_shouldBeCaseSensitive">
  986.         <parameter name="aString"/>
  987.         <body><![CDATA[
  988.           if (this._typeAheadCaseSensitive == 0)
  989.             return false;
  990.           if (this._typeAheadCaseSensitive == 1)
  991.             return true;
  992.  
  993.           return aString != aString.toLowerCase();
  994.         ]]></body>
  995.       </method>
  996.  
  997.       <method name="_onBrowserKeypress">
  998.         <parameter name="aEvent"/>
  999.         <body><![CDATA[
  1000.           const TAF_LINKS_KEY = "'";
  1001.           const TAF_TEXT_KEY = "/";
  1002.  
  1003.           if (!this._shouldFastFind(aEvent))
  1004.             return;
  1005.  
  1006.           if (this._findMode != this.FIND_NORMAL && this._quickFindTimeout) {
  1007.             if (!aEvent.charCode)
  1008.               return;
  1009.  
  1010.             this._findField.select();
  1011.             this._findField.focus();
  1012.             this._dispatchKeypressEvent(this._findField.inputField, aEvent);
  1013.             aEvent.preventDefault();
  1014.             return;
  1015.           }
  1016.  
  1017.           var key = aEvent.charCode ? String.fromCharCode(aEvent.charCode) : null;
  1018.           var manualstartFAYT = (key == TAF_LINKS_KEY || key == TAF_TEXT_KEY);
  1019.           var autostartFAYT = !manualstartFAYT && this._useTypeAheadFind &&
  1020.                               key && key != " ";
  1021.           if (manualstartFAYT || autostartFAYT) {
  1022.             var mode = (key == TAF_LINKS_KEY ||
  1023.                         (autostartFAYT && this._typeAheadLinksOnly)) ?
  1024.               this.FIND_LINKS : this.FIND_TYPEAHEAD;
  1025.  
  1026.             // Clear bar first, so that when openFindBar() calls setCaseSensitivity()
  1027.             // it doesn't get confused by a lingering value
  1028.             this._findField.value = "";
  1029.  
  1030.             this.open(mode);
  1031.             this._setFindCloseTimeout();
  1032.             this._findField.select();
  1033.             this._findField.focus();
  1034.  
  1035.             if (autostartFAYT)
  1036.               this._dispatchKeypressEvent(this._findField.inputField, aEvent);
  1037.             else
  1038.               this._updateStatusUI(this.nsITypeAheadFind.FIND_FOUND);
  1039.  
  1040.             aEvent.preventDefault();
  1041.           }
  1042.         ]]></body>
  1043.       </method>
  1044.  
  1045.       <!-- See nsIDOMEventListener -->
  1046.       <method name="handleEvent">
  1047.         <parameter name="aEvent"/>
  1048.         <body><![CDATA[
  1049.           switch (aEvent.type) {
  1050.             case "mouseup":
  1051.               if (!this.hidden && this._findMode != this.FIND_NORMAL)
  1052.                 this.close();
  1053.  
  1054.               break;
  1055.             case "keypress":
  1056.               this._onBrowserKeypress(aEvent);
  1057.               break;
  1058.           }
  1059.         ]]></body>
  1060.       </method>
  1061.  
  1062.       <method name="_enableFindButtons">
  1063.         <parameter name="aEnable"/>
  1064.         <body><![CDATA[
  1065.           this.getElement("find-next").disabled =
  1066.             this.getElement("find-previous").disabled =
  1067.             this.getElement("highlight").disabled = !aEnable;
  1068.         ]]></body>
  1069.       </method>
  1070.  
  1071.       <!--
  1072.         - Determines whether minimalist or general-purpose search UI is to be
  1073.         - displayed when the find bar is activated.
  1074.         -->
  1075.       <method name="_updateFindUI">
  1076.         <body><![CDATA[
  1077.           var showMinimalUI = this._findMode != this.FIND_NORMAL;
  1078.  
  1079.           var nodes = this.getElement("findbar-container").childNodes;
  1080.           for (var i = 0; i < nodes.length; i++) {
  1081.             if (nodes[i].className.indexOf("findbar-find-fast") != -1)
  1082.                continue;
  1083.  
  1084.             nodes[i].hidden = showMinimalUI;
  1085.           }
  1086.           this._updateCaseSensitivity();
  1087.  
  1088.           if (this._findMode == this.FIND_TYPEAHEAD)
  1089.             this.getElement("find-label").value = this._fastFindStr;
  1090.           else if (this._findMode == this.FIND_LINKS)
  1091.             this.getElement("find-label").value = this._fastFindLinksStr;
  1092.           else
  1093.             this.getElement("find-label").value = this._normalFindStr;
  1094.         ]]></body>
  1095.       </method>
  1096.  
  1097.       <method name="_updateFoundLink">
  1098.         <parameter name="res"/>
  1099.         <body><![CDATA[
  1100.           var val = this._findField.value;
  1101.           if (res == this.nsITypeAheadFind.FIND_NOTFOUND || !val) {
  1102.             this._setFoundLink(null);
  1103.             this._foundEditable = null;
  1104.             this._currentWindow = null;
  1105.           }
  1106.           else {
  1107.             this._setFoundLink(this.browser.fastFind.foundLink);
  1108.             this._foundEditable = this.browser.fastFind.foundEditable;
  1109.             this._currentWindow = this.browser.fastFind.currentWindow;
  1110.           }
  1111.         ]]></body>
  1112.       </method>
  1113.  
  1114.       <method name="_find">
  1115.         <parameter name="aValue"/>
  1116.         <body><![CDATA[
  1117.           var val = aValue || this._findField.value
  1118.  
  1119.           this._enableFindButtons(val);
  1120.           if (this.getElement("highlight").checked)
  1121.             this._setHighlightTimeout();
  1122.  
  1123.           this._updateCaseSensitivity(val);
  1124.  
  1125.           var fastFind = this.browser.fastFind;
  1126.           var res = fastFind.find(val, this._findMode == this.FIND_LINKS);
  1127.           this._updateFoundLink(res);
  1128.           this._updateStatusUI(res, false);
  1129.  
  1130.           if (this._findMode != this.FIND_NORMAL)
  1131.             this._setFindCloseTimeout();
  1132.  
  1133.           return res;
  1134.         ]]></body>
  1135.       </method>
  1136.  
  1137.       <method name="_flash">
  1138.         <body><![CDATA[
  1139.           if (this._flashFindBarCount === undefined)
  1140.             this._flashFindBarCount = this._initialFlashFindBarCount;
  1141.  
  1142.           if (this._flashFindBarCount-- == 0) {
  1143.             clearInterval(this._flashFindBarTimeout);
  1144.             this.removeAttribute("flash");
  1145.             this._flashFindBarCount = 6;
  1146.             return;
  1147.           }
  1148.  
  1149.           this.setAttribute("flash",
  1150.                             (this._flashFindBarCount % 2 == 0) ?
  1151.                             "false" : "true");
  1152.         ]]></body>
  1153.       </method>
  1154.  
  1155.       <method name="_setHighlightTimeout">
  1156.         <body><![CDATA[
  1157.           if (this._highlightTimeout)
  1158.             clearTimeout(this._highlightTimeout);
  1159.           this._highlightTimeout =
  1160.             setTimeout(function(aSelf) {
  1161.                          aSelf.toggleHighlight(false);
  1162.                          aSelf.toggleHighlight(true);
  1163.                        }, 500, this);
  1164.         ]]></body>
  1165.       </method>
  1166.  
  1167.       <method name="_findAgain">
  1168.         <parameter name="aFindPrevious"/>
  1169.         <body><![CDATA[
  1170.           var fastFind = this.browser.fastFind;
  1171.           var res = fastFind.findAgain(aFindPrevious,
  1172.                                        this._findMode == this.FIND_LINKS);
  1173.           this._updateFoundLink(res);
  1174.           this._updateStatusUI(res, aFindPrevious);
  1175.  
  1176.           if (this._findMode != this.FIND_NORMAL && !this.hidden)
  1177.             this._setFindCloseTimeout();
  1178.  
  1179.           return res;
  1180.         ]]></body>
  1181.       </method>
  1182.  
  1183.       <method name="_updateStatusUI">
  1184.         <parameter name="res"/>
  1185.         <parameter name="aFindPrevious"/>
  1186.         <body><![CDATA[
  1187.           switch (res) {
  1188.             case this.nsITypeAheadFind.FIND_WRAPPED:
  1189.               this._findStatusIcon.setAttribute("status", "wrapped");
  1190.               this._findStatusDesc.textContent =
  1191.                 aFindPrevious ? this._wrappedToBottomStr : this._wrappedToTopStr;
  1192.               this._findField.removeAttribute("status");
  1193.               break;
  1194.             case this.nsITypeAheadFind.FIND_NOTFOUND:
  1195.               this._findStatusIcon.setAttribute("status", "notfound");
  1196.               this._findStatusDesc.textContent = this._notFoundStr;
  1197.               this._findField.setAttribute("status", "notfound");
  1198.               break;
  1199.             case this.nsITypeAheadFind.FIND_FOUND:
  1200.             default:
  1201.               this._findStatusIcon.removeAttribute("status");
  1202.               this._findStatusDesc.textContent = "";
  1203.               this._findField.removeAttribute("status");
  1204.               break;
  1205.           }
  1206.         ]]></body>
  1207.       </method>
  1208.  
  1209.       <method name="_getInitialSelection">
  1210.         <body><![CDATA[
  1211.           var focusedElement = document.commandDispatcher.focusedElement;
  1212.           var selText;
  1213.  
  1214.           if (focusedElement instanceof Components.interfaces.nsIDOMNSEditableElement &&
  1215.             focusedElement.ownerDocument.defaultView.top == this._browser.contentWindow)
  1216.           {
  1217.             // The user may have a selection in an input or textarea
  1218.             selText = focusedElement.editor.selectionController
  1219.               .getSelection(Components.interfaces.nsISelectionController.SELECTION_NORMAL)
  1220.               .toString();
  1221.           }
  1222.           else {
  1223.             // Look for any selected text on the actual page
  1224.             var focusedWindow = document.commandDispatcher.focusedWindow;
  1225.             if (focusedWindow.top == this._browser.contentWindow)
  1226.               selText = focusedWindow.getSelection().toString();
  1227.           }
  1228.  
  1229.           if (!selText)
  1230.             return "";
  1231.  
  1232.           // Process our text to get rid of unwanted characters
  1233.           if (selText.length > this._selectionMaxLen) {
  1234.             var pattern = new RegExp("^(?:\\s*.){0," + this._selectionMaxLen + "}");
  1235.             pattern.test(selText);
  1236.             selText = RegExp.lastMatch;
  1237.           }
  1238.           return selText.replace(/^\s+/, "")
  1239.                         .replace(/\s+$/, "")
  1240.                         .replace(/\s+/g, " ")
  1241.                         .substr(0, this._selectionMaxLen);
  1242.         ]]></body>
  1243.       </method>
  1244.  
  1245.       <!--
  1246.         - Opens the findbar, focuses the findfield and selects its contents.
  1247.         - Also flashes the findbar the first time it's used.
  1248.         - @param aMode
  1249.         -        the find mode to be used, which is either FIND_NORMAL,
  1250.         -        FIND_TYPEAHEAD or FIND_LINKS. If not passed, the last
  1251.         -        find mode if any or FIND_NORMAL.
  1252.         -->
  1253.       <method name="startFind">
  1254.         <parameter name="aMode"/>
  1255.         <body><![CDATA[
  1256.           var prefsvc =
  1257.             Components.classes["@mozilla.org/preferences-service;1"]
  1258.                       .getService(Components.interfaces.nsIPrefBranch2);
  1259.           var userWantsPrefill = true;
  1260.           this.open(aMode);
  1261.  
  1262.           if (this._flashFindBar) {
  1263.             this._flashFindBarTimeout =
  1264.               setInterval(function(aSelf) { aSelf._flash(); }, 500, this);
  1265.             prefsvc.setIntPref("accessibility.typeaheadfind.flashBar",
  1266.                                --this._flashFindBar);
  1267.           }
  1268.  
  1269.           if (this.prefillWithSelection)
  1270.             userWantsPrefill = 
  1271.               prefsvc.getBoolPref("accessibility.typeaheadfind.prefillwithselection");
  1272.  
  1273.           var initialString = (this.prefillWithSelection && userWantsPrefill) ?
  1274.                               this._getInitialSelection() : null;
  1275.           if (initialString) {
  1276.             this._findField.value = initialString;
  1277.             this._enableFindButtons(true);
  1278.           }
  1279.           else if (!this._findField.value)
  1280.             this._enableFindButtons(false);
  1281.  
  1282.           this._findField.select();
  1283.           this._findField.focus();
  1284.         ]]></body>
  1285.       </method>
  1286.  
  1287.       <!--
  1288.         - Convenient alias to startFind(gFindBar.FIND_NORMAL);
  1289.         -
  1290.         - You should generally map the window's find command to this method.
  1291.         -   e.g. <command name="cmd_find" oncommand="gFindBar.onFindCommand();"/>
  1292.         -->
  1293.       <method name="onFindCommand">
  1294.         <body><![CDATA[
  1295.           this.startFind(this.FIND_NORMAL);
  1296.         ]]></body>
  1297.       </method>
  1298.  
  1299.       <!--
  1300.         - Stub for find-next and find-previous commands
  1301.         - @param aFindPrevious
  1302.         -        true for find-previous, false otherwise.
  1303.         -->
  1304.       <method name="onFindAgainCommand">
  1305.         <parameter name="aFindPrevious"/>
  1306.         <body><![CDATA[
  1307.           var findString = this._browser.fastFind.searchString || this._findField.value;
  1308.           if (!findString) {
  1309.             this.startFind();
  1310.             return;
  1311.           }
  1312.  
  1313.           var res;
  1314.           // Ensure the stored SearchString is in sync with what we want to find
  1315.           if (this._findField.value != this._browser.fastFind.searchString &&
  1316.               !this.hidden)
  1317.             res = this._find(this._findField.value);
  1318.           else
  1319.             res = this._findAgain(aFindPrevious);
  1320.  
  1321.           if (res == this.nsITypeAheadFind.FIND_NOTFOUND) {
  1322.             if (this.open()) {
  1323.               if (this._findMode != this.FIND_NORMAL)
  1324.                 this._setFindCloseTimeout();
  1325.               this._findField.focus();
  1326.               this._findField.focus();
  1327.               this._updateStatusUI(res, aFindPrevious);
  1328.             }
  1329.           }
  1330.         ]]></body>
  1331.       </method>
  1332.     </implementation>
  1333.  
  1334.     <handlers>
  1335.       <handler event="keypress" keycode="VK_ESCAPE" phase="capturing" action="this.close();" preventdefault="true"/>
  1336.     </handlers>
  1337.   </binding>
  1338. </bindings>
  1339.