Find To Center(Firefox 3.6 - 9)
Автор: Alice0775
Описание: код при поиске на странице, отображает найденные слова, в центре экрана, это очень удобно. Аналог расширению Find To Center https://addons.mozilla.org/en-US/firefo … to-center/
Использование: положите код в любую Custom Buttons кнопку, в инициализацию. Не обязательно создавать новую CB кнопку, можно использовать уже существующую.

скрытый текст
Инициализация:

Выделить код

Код:

// find center....................
var findcenter = {
// -- config --
  SCROLL_SMOOTH: true,      
  SCROLL_PADDING:10,         
  SCROLL_PARENT_BLOCK: false, 
  // -- config --
  kSCROLL_WRAPPED      :'extensions.findcenter.alert.find.wrapped',
  kSCROLL_SMOOTH_FIND  :'extensions.findcenter.scroll_smooth.find',
  kSCROLL_SMOOTH_STEPS :'extensions.findcenter.scroll_smooth.steps',
  kSCROLL_SMOOTH_LIMITS :'extensions.findcenter.scroll_smooth.limits',
  kSCROLL_PADDING      :'extensions.findcenter.scroll.padding',
  _timer: null,
  get browser() {
    return document.getElementById('content') || // Firefox
      document.getElementById('messagepane') || // Thunderbird
      document.getElementById('help-content'); // Help
  },

  get activeBrowser() {
    return ('SplitBrowser' in window && SplitBrowser.activeBrowser) || this.browser;
  },

  getVer: function(){
    const Cc = Components.classes;
    const Ci = Components.interfaces;
    var info = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
    var ver = parseInt(info.version.substr(0,3) * 10,10) / 10;
    return ver;
  },

  debug: function(aMsg){
    const Cc = Components.classes;
    const Ci = Components.interfaces;
    Cc["@mozilla.org/consoleservice;1"]
      .getService(Ci.nsIConsoleService)
      .logStringMessage(aMsg);
  },

  init: function(){

    if (!document.getElementById("FindToolbar") &&
        typeof gFindBarInitialized != 'undefined' &&
        !gFindBarInitialized) {
      window.watch('gFindBarInitialized', function() { findcenter.init(); });
      return;
    }

    if (!("gFindBar" in window)) {
      window.gFindBar = document.getElementById("FindToolbar");
    }

    if ('XMigemoFind' in window) {
      this.setPrefValue('xulmigemo.scrollSelectionToCenter', 'bool', false)

      if (this.getVer() >= 3.0) { //Fx3.0 3.5
        this.debug('Firefox 3 W/ XUL/Migemo');

        try {
          eval('gFindBar._updateStatusUI = gFindBar.updateStatus = '+gFindBar._updateStatusUI.toString()
            .replace('{', '$&findcenter._dispSelectionCenter(res);')
          );
        } catch(ex) {
        }

      }

    } else { // without XUL/Migemo

      if (this.getVer() >= 3.0) { //Fx3.0 3.5
        this.debug('Firefox 3');
        try {
          eval('gFindBar._updateStatusUI = '+gFindBar._updateStatusUI.toSource()
            .replace('{', '$&findcenter._dispSelectionCenter(res);')
          );
        } catch(ex) {
        }
      }

    }

    //searchWp 1.0
    if (typeof gSearchWPTermsToolbar != 'undefined') {
      this.debug('SearchWP');
      try{
        var func = gSearchWPTermsToolbar._doSearch.toString();
        //var exp = new RegExp(/}$/);
        func = func.replace('if (result && prevRange) {', 'findcenter._dispSelectionCenter();if (result && prevRange) {');
        eval("gSearchWPTermsToolbar._doSearch = " + func);
        //this.debug(func);
      }catch(ex){
      }
      //alert if find wrapped.
      document.getElementById("statusbar-display").addEventListener("DOMAttrModified", function(e) {
        if (!e.newValue) return;
          if(findcenter.getPrefValue(findcenter.kSCROLL_WRAPPED, 'bool', false)){
            var bundle = document.getElementById("bundle_searchwp");
            var status = e.target;
            if(findcenter._timer) clearTimeout(findcenter._timer);
            findcenter._timer = setTimeout(function(){
              if( status.getAttribute('label') == bundle.getString("wrappedToTop")
                 || status.getAttribute('label') == bundle.getString("wrappedToBottom") ){
                alert(status.getAttribute('label'));
              }
            },200);
          }
      }, false);
    }
    if (typeof searchwp != 'undefined'){
      //alert if find wrapped.
      document.getElementById("statusbar-display").addEventListener("DOMAttrModified", function(e) {
        if (!e.newValue) return;
          var status = e.target;
          if(findcenter._timer) clearTimeout(findcenter._timer);
            findcenter._timer = setTimeout(function(){
            if(findcenter.getPrefValue(findcenter.kSCROLL_WRAPPED, 'bool', false)){
              var textboxWP = document.getAnonymousElementByAttribute(document.getElementById("searchbar"),
                      "anonid", "searchbar-textbox");
              var bundleWP = document.getAnonymousElementByAttribute(textboxWP, "anonid", "searchwp-stringbundle");

              if( status.getAttribute('label') == bundleWP.getString("wrappedToTop")
                 || status.getAttribute('label') == bundleWP.getString("wrappedToBottom") ){
                alert(status.getAttribute('label'));
              }
            }
          },200);
      }, false);
      this.debug('SearchWP 2.0');
    }
    //all in one search button 1.67
    if (typeof ObjAllinonesearch != 'undefined'){
      dump('Allinonesearch');
      try{
        var func = ObjAllinonesearch.doselection.toString();
        var exp = new RegExp(/}$/);
        func = func.replace('selection.addRange(allinonesearch_range);', 'selection.addRange(allinonesearch_range);findcenter._dispSelectionCenter();return;');
        eval("ObjAllinonesearch.doselection = " + func);
      }catch(ex){
      }
    }

    //Googlebar Lite 4.6.9
    if ('GBL_FindInPage' in window) {
      try{
        var func = GBL_FindInPage.toString();
        func = func.replace('found = findInst.findNext();', '$&findcenter._dispSelectionCenter();');
        eval("GBL_FindInPage = " + func);
      }catch(ex){
      }
    }

    //Google Toolbar for Firefox 3.1.20090119W
    if ('GTB_getToolbar' in window && typeof GTB_getToolbar().highlighter == 'object') {
      try{
        var func = GTB_getToolbar().highlighter.findTermText.toString();
        func = func.replace(/findBar\.findNext\(\);/g, '$&findcenter._dispSelectionCenter();');
        func = func.replace(/findBar\.findPrevious\(\);/g, '$&findcenter._dispSelectionCenter();');
        eval("GTB_getToolbar().highlighter.findTermText = " + func);
      }catch(ex){
      }
      try{
        var func = GTB_getToolbar().highlighter._unhighlightWindow.toString();
        func = func.replace(/return result/g, 'doc.body.normalize();$&');
        eval("GTB_getToolbar().highlighter._unhighlightWindow = " + func);
      }catch(ex){
      }
      //Google Toolbar for Firefox 5.0.20090324W
      try{
        var func = GTB_getToolbar().highlighter.findTermText.toString();
        func = func.replace(/c\.gFindBar\._findAgain\(false\);/g, '$&findcenter._dispSelectionCenter();');
        func = func.replace(/c\.gFindBar\._findAgain\(true\);/g, '$&findcenter._dispSelectionCenter();');
        eval("GTB_getToolbar().highlighter.findTermText = " + func);
      }catch(ex){
      }
    }



    if (this.getVer() >= 3.0) { //Fx3.0 3.5
     //alert if find wrapped.
      gFindBar.addEventListener("DOMAttrModified", function(e) {
        if(e.newValue != 'wrapped') return;
          var MigemoON =  false;
          if(document.getElementById("find-migemo-mode")){
            MigemoON =  document.getElementById("find-migemo-mode").checked;
          }else if(document.getElementById("find-mode-selector")){
            MigemoON =  document.getElementById("find-mode-selector").value == 1;
          }
        if(findcenter.getPrefValue(findcenter.kSCROLL_WRAPPED, 'bool', false) &&
           !MigemoON )
        {
          var bundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
                      .getService(Components.interfaces.nsIStringBundleService)
                      .createBundle("chrome://global/locale/findbar.properties");
          if(findcenter._timer) clearTimeout(findcenter._timer);
          findcenter._timer = setTimeout(function(){
            var status = document.getAnonymousElementByAttribute(gFindBar, "anonid", "find-status");
            if( status.textContent == bundle.GetStringFromName("WrappedToTop")
               || status.textContent == bundle.GetStringFromName("WrappedToBottom") ){
              alert(status.textContent);
            }
          },100);
        }
      }, false);
    }
    window.addEventListener('unload', this, false);
    //Findbar
    gFindBar.addEventListener("DOMAttrModified", this, false);
    if ("gBrowser" in window && "tabContainer" in gBrowser)
      gBrowser.tabContainer.addEventListener('TabSelect', this, false);
    var findcenter_init = true;
  },


  setPrefValue: function(aPrefString, aPrefType, aValue) {
    var xpPref = Components.classes['@mozilla.org/preferences-service;1']
                  .getService(Components.interfaces.nsIPrefBranch2);
    try {
      switch (aPrefType) {
        case 'complex':
          return xpPref.setComplexValue(aPrefString, Components.interfaces.nsILocalFile, aValue); break;
        case 'str':
          return xpPref.setCharPref(aPrefString, aValue); break;
        case 'int':
          aValue = parseInt(aValue);
          return xpPref.setIntPref(aPrefString, aValue);  break;
        case 'bool':
        default:
          return xpPref.setBoolPref(aPrefString, aValue); break;
      }
    } catch(e) { }
    return null;
  },

  getPrefValue: function(aPrefString, aPrefType, aDefault) {
    var xpPref = Components.classes['@mozilla.org/preferences-service;1']
                  .getService(Components.interfaces.nsIPrefBranch2);
    if (xpPref.getPrefType(aPrefString) == xpPref.PREF_INVALID) {
      return aDefault;
    }
    try {
      switch (aPrefType) {
        case "str":
          return xpPref.getCharPref(aPrefString).toString(); break;
        case "int":
          return xpPref.getIntPref(aPrefString); break;
        case "bool":
        default:
          return xpPref.getBoolPref(aPrefString); break;
      }
    } catch(e) { }
    return aDefault;
  },

  //-------------------------------------------------------------------
  // overflow hiddenу
  // SCROLL_PARENT_BLOCK
  prevelement: null,
  prevelementScrollTop:0,
  prevelementScrollLeft:0,
  ensureVisibleElement: function ensureVisibleElement(aNode){
    if (aNode instanceof Range) {
      var selCon = this._getSelectionController(aNode.startContainer.ownerDocument.defaultView);
      if (selCon) {
        // 
        selCon.scrollSelectionIntoView(selCon.SELECTION_NORMAL,
                                             selCon.SELECTION_ANCHOR_REGION,
                                             true);
      }
      return
    }

    try {
      var mShell = Components.classes["@mozilla.org/inspector/flasher;1"]
               .createInstance(Components.interfaces.inIFlasher);
    } catch(e) {
      return;
    }

    var target0 = null;
    var target0ScrollTop = 0;
    var target0ScrollLeft = 0;
    var target = aNode;
    while(target) {
      var style = this._getComputedStyle(target);
      if (style &&
          style.getPropertyValue("display") == "block" &&
          target.clientHeight < target.scrollHeight ||
          target.clientWidth < target.scrollWidth) {
        if (style.getPropertyValue("overflow-y") == "hidden") {
          target0 = target;
          target0ScrolllTop = target.scrollTop;
          target0ScrollLeft = target.scrollLeft;
        }
        break;
      }
      target = target.parentNode;
    }

    if (target0 != this.prevelement) {
      var target = this.prevelement;
      if (target) {
         target.scrollTop = this.prevelementScrollTop;
         target.scrollLeft = this.prevelementScrollLeft;
      }
      this.prevelement = target0;
      this.prevelementScrollTop = target0ScrollTop;
      this.prevelementScrollLeft = target0ScrollLeft;

    }

    mShell.scrollElementIntoView(aNode);
  },

  //
  _dispSelectionCenter : function(res){

    var frame = this._getSelectionFramePrefFocused( window.content );
    if (!frame) return;

    var selection = Components.lookupMethod(frame, 'getSelection').call(frame);
    var elem = null;
    // Fx3.5
    // хp
    this.SCROLL_PARENT_BLOCK2 = this.SCROLL_PARENT_BLOCK
                              || (this.getVer() == 3.5 &&
                              gFindBar.getElement("highlight").checked);


    if (!this.SCROLL_PARENT_BLOCK2) {
      if (this.getVer() <= 3.6) {
        var range = frame.document.createRange( );
        range.setStart( selection.focusNode, selection.focusOffset );
        range.setEnd  ( selection.focusNode, selection.focusOffset );
        elem = frame.document.createElement( "span" )
        range.insertNode( elem );
      } else {
        elem = frame.document.createRange( );
        elem.setStart( selection.anchorNode, selection.anchorOffset );
        elem.setEnd  ( selection.focusNode, selection.focusOffset );
      }

    }

    if (typeof res != 'undefined' && res != 0)
      this.prevFrame = null;

    this.doCenter( frame, elem, selection);

    // ф¬АцЩВчЪДуБкшжБч+ауВТхЙКщЩд
    if (!!elem && !(elem instanceof Range)) {
      var p = elem.parentNode;
      p.removeChild( elem );
      range.deleteContents( );
      range.detach( );
      p.normalize();
    } else if (!!elem && (elem instanceof Range)) {
      elem.detach( );
    }

    var selCon = this._getSelectionController(frame);
    if (selCon) {
      // 
      selCon.scrollSelectionIntoView(selCon.SELECTION_NORMAL,
                                           selCon.SELECTION_ANCHOR_REGION,
                                           true);
    }

  },

  
  //This Code based on Piro's XUL/Migemo
  doCenter : function(aFrame, aElem, aSelection) {
    if (!aFrame) return;
    if (!aElem && !(aElem instanceof Range)) { 
      var range = aFrame.document.createRange( );
      range.setStart( aSelection.focusNode, aSelection.focusOffset );
      range.setEnd  ( aSelection.focusNode, aSelection.focusOffset );

      aElem = range.startContainer.parentNode;
      range.deleteContents( );
      range.detach( );
    }
    this.doCenter_sub(aFrame, aElem, aSelection);
    // ensureVisibleElement
    // TabSelect
    this.ensureVisibleElement( aElem );

  },

  prevFrame: null,
  prevElem: null,
  prevScrollView: [],

  doCenter_sub: function(aFrame, aElem, aSelection) {
      if (/*true ||*/this.prevFrame != aFrame) {
      this.scrollFrameifAny(aFrame);
      this.prevFrame = aFrame;

    }

    var padding = findcenter.getPrefValue(findcenter.kSCROLL_PADDING,
                                          "int", findcenter.SCROLL_PADDING);
    var view = null,
        box,
        box2,
        targetX,
        targetY,
        targetW,
        targetH;

    box = window['piro.sakura.ne.jp.Alice0775'].boxObject.getBoxObjectFor(aElem);
    if (!box.x && !box.y) {
      if ((aElem instanceof Range))
        box = window['piro.sakura.ne.jp.Alice0775'].boxObject.getBoxObjectFor(aElem.startContainer);
      else
        box = window['piro.sakura.ne.jp.Alice0775'].boxObject.getBoxObjectFor(aElem.parentNode);
    }
    targetX = box.x;
    targetY = box.y;
    targetW = Math.max(box.width, 20);
    targetH = Math.max(box.height, 20);

    var scrollView;
    if (aElem instanceof Range) {
      if (aElem.startContainer.parentNode && this.prevElem == aElem.startContainer.parentNode) {
        scrollView = this.prevScrollView;
      } else {
        scrollView = this.getScrollView(aElem.startContainer);
        this.prevScrollView = scrollView;
        this.prevElem = aElem.startContainer.parentNode;
      }
    } else {
      if (aElem.parentNode && this.prevElem == aElem.parentNode) {
        scrollView = this.prevScrollView;
      } else {
        scrollView = this.getScrollView(aElem);
        this.prevScrollView = scrollView;
        this.prevElem = aElem.parentNode;
      }
    }

    var viewX, targetX_x, targetX_y, viewY, targetY_x, targetY_y;
    viewX = viewY = null;

    if (scrollView[1] && scrollView[1] instanceof Window) {
      view = scrollView[1];

      var viewW = view.innerWidth;
      var xUnit = Math.max(viewW * (padding / 100), targetW);

      var sx = view.scrollX;
      var sy = view.scrollY;
      var xa = targetX - sx;
      var xb = xa + targetW;
//this.debug(" " + (targetX <= viewW - xUnit) +   (xa <= viewW - xUnit)  +  (xb >= viewW - xUnit));
      var x = (targetX <= viewW - xUnit) ? 0 :
                      (xa <= viewW - xUnit) ? sx :
                             (xb >= viewW - xUnit) ? +targetX - viewW / 2:
                                                    sx;
      viewX = view;
      targetX_x = x;
      targetX_y = sy;
    } else if (scrollView[1]) {
      view = scrollView[1];

      var viewbox = window['piro.sakura.ne.jp.Alice0775'].boxObject.getBoxObjectFor(view);
      var style = this._getComputedStyle(aFrame);
      var overfllowx = style.getPropertyValue("overflow-x")
      var overfllowy = style.getPropertyValue("overflow-y")
      var xx = aFrame.scrollX;
      if (overfllowx != "visible" && overfllowx != "hidden")
        xx = (viewbox.x + viewbox.width / 2) - aFrame.innerWidth / 2;
      var yy = aFrame.scrollY;
      if (overfllowy != "visible" && overfllowy != "hidden")
        yy = (viewbox.y + viewbox.height / 2) - aFrame.innerHeight / 2;
      this._scrollTo(aFrame, xx ,yy);


      var viewW = view.clientWidth;
      var xUnit = Math.max(viewW * (padding / 100), targetW);

      var sx = view.scrollLeft;
      var sy = view.scrollTop;
      targetX =  targetX - viewbox.x;
      var xa = targetX;
      var xb = xa + targetW;
      var x = (targetX + sx <= viewW - xUnit) ? 0 :
                      (xa <= viewW - xUnit) ? sx :
                             (xb >= viewW - xUnit) ? +targetX + sx - viewW / 2 :
                                                    sx;
      viewX = view;
      targetX_x = x;
      targetX_y = sy;
    }

    if (scrollView[0] && scrollView[0] instanceof Window) {
      view = scrollView[0];

      var viewH = view.innerHeight;
      var yUnit = Math.max(viewH * (padding / 100), targetH);

      var sx = view.scrollX;
      var sy = view.scrollY;
      var ya = targetY - sy;
      var yb = ya + targetH;
      var pos = 0.5;
      if (this.SCROLL_PARENT_BLOCK2) {
        if (targetH < viewH)
          pos = (viewH - targetH) / viewH /2;
        else
          return
      }
      var y = (ya <= yUnit ) ? targetY - viewH * pos  :
                              (yb >= viewH - yUnit ) ? +targetY - viewH * pos  :
                                                      sy;
      viewY = view;
      targetY_x = x;//sx;
      targetY_y = y;
    } else if (scrollView[0]) {
      view = scrollView[0];

      var viewbox = window['piro.sakura.ne.jp.Alice0775'].boxObject.getBoxObjectFor(view);
      var style = this._getComputedStyle(aFrame);
      var overfllowx = style.getPropertyValue("overflow-x");
      var overfllowy = style.getPropertyValue("overflow-y");
      var xx = aFrame.scrollX;
      if (overfllowx != "visible" && overfllowx != "hidden");
        xx = (viewbox.x + viewbox.width / 2) - aFrame.innerWidth / 2;
      var yy = aFrame.scrollY;
      if (overfllowy != "visible" && overfllowy != "hidden");
        yy = (viewbox.y + viewbox.height / 2) - aFrame.innerHeight / 2;
      this._scrollTo(aFrame, xx ,yy);

      var viewH = view.clientHeight;
      var yUnit = Math.max(viewH * (padding / 100), targetH);
      var sx = view.scrollLeft;
      var sy = view.scrollTop;
      targetY =  targetY - viewbox.y;
      var ya = targetY;
      var yb = ya + targetH;
      var pos = 0.5;
      if (this.SCROLL_PARENT_BLOCK2) {
        if (targetH < viewH)
          pos = (viewH - targetH) / viewH /2;
        else
          return
      }
      var y = (ya <= yUnit ) ? targetY + sy - viewH * pos  :
                              (yb >= viewH - yUnit ) ? +targetY + sy - viewH * pos  :
                                                      sy;
      viewY = view;
      targetY_x = x;//sx;
      targetY_y = y;
    }

    if (viewX == viewY) {
      targetY_x = targetX_x;
      viewX = null;
    }
    this.smoothScrollTo(viewX, targetX_x, targetX_y, viewY, targetY_x, targetY_y);

    // hack for Google Reader
    if (/^http:\/\/www\.google\.[.a-z]+\/reader\/view/.test(content.location.href)) {
      this.viewY.style.visibility = "collapse";
      this.viewY.clientTop;
      this.viewY.style.visibility = "visible";
    }

  },


  timerid: null,
  timerSmoothScroll: null,
  stopSmoothScroll: false,

  smoothScrollTo: function(viewX, targetX_x, targetX_y, viewY, targetY_x, targetY_y) {
    if (this.timerid)
      clearInterval(this.timerid);
    var interval = 20;//
    this.n = this.getPrefValue(this.kSCROLL_SMOOTH_FIND, 'bool', this.SCROLL_SMOOTH)
               ? this.getPrefValue(this.kSCROLL_SMOOTH_STEPS, 'int', 6) : 1; 
    this.limits = this.getPrefValue(this.kSCROLL_SMOOTH_LIMITS, 'int', 100);

    if (viewX){
      this.viewX = viewX;
      this.targetX_x = targetX_x;
      this.targetX_y = targetX_y;
      if (this.viewX instanceof Window) {
        this.currentX_x = viewX.scrollX;
        this.currentX_y = viewX.scrollY;
      } else {
        this.currentX_x = viewX.scrollLeft;
        this.currentX_y = viewX.scrollTop;
      }

      this.diffX_x = targetX_x - this.currentX_x;
      this.diffX_y = targetX_y - this.currentX_y;
    }
    if (viewY){
      this.viewY = viewY;
      this.targetY_x = targetY_x;
      this.targetY_y = targetY_y;
      if (this.viewY instanceof Window) {
        this.currentY_x = viewY.scrollX;
        this.currentY_y = viewY.scrollY;
      } else {
        this.currentY_x = viewY.scrollLeft;
        this.currentY_y = viewY.scrollTop;
      }

      this.diffY_x = targetY_x - this.currentY_x;
      this.diffY_y = targetY_y - this.currentY_y;
    }


    this.count = 1;

      if (this.timerSmoothScroll)
      clearTimeout(this.timerSmoothScroll);
    this.stopSmoothScroll = false;

    this.timerSmoothScroll = setTimeout(function(self){self.stopSmoothScroll = true;}, this.limits, this);

    this.timerid = setInterval( function(self) {
      var dx,dy;
      if ( self.count >= self.n || self.stopSmoothScroll) {
        if (self.timerSmoothScroll)
          clearInterval(self.timerSmoothScroll);
        clearInterval(self.timerid);
        if (self.viewX)
          self._scrollTo(self.viewX, self.targetX_x, self.targetX_y);
        if (self.viewY)
          self._scrollTo(self.viewY, self.targetY_x, self.targetY_y);
        return;
      } else {
        if (self.viewX){
          if (self.viewX instanceof Window) {
            dx = (self.currentX_x + self.diffX_x / self.n * self.count) - self.viewX.scrollX;
            dy = (self.currentX_y + self.diffX_y / self.n * self.count) - self.viewX.scrollY;
          } else {
            dx = (self.currentX_x + self.diffX_x / self.n * self.count) - self.viewX.scrollLeft;
            dy = (self.currentX_y + self.diffX_y / self.n * self.count) - self.viewX.scrollTop;
          }
          self._scrollBy(self.viewX, dx, dy);
        }
        if (self.viewY){
          if (self.viewY instanceof Window) {
            dx = (self.currentY_x + self.diffY_x / self.n * self.count) - self.viewY.scrollX;
            dy = (self.currentY_y + self.diffY_y / self.n * self.count) - self.viewY.scrollY;
          } else {
            dx = (self.currentY_x + self.diffY_x / self.n * self.count) - self.viewY.scrollLeft;
            dy = (self.currentY_y + self.diffY_y / self.n * self.count) - self.viewY.scrollTop;
          }
          self._scrollBy(self.viewY, dx, dy);
        }

        self.count++;
        if (2 < self.count && self.count < self.n - 2)
          self.count++;
        if (4 < self.count && self.count < self.n - 4)
          self.count++;
        if (6 < self.count && self.count < self.n - 6)
          self.count++;
        if (8 < self.count && self.count < self.n - 8)
          self.count++;
        if (10 < self.count && self.count < self.n -10)
          self.count++;
      }
    }, interval, this);
    return;
  },

  _scrollTo: function(aElem, x, y){
    var self = this;
    if (aElem instanceof Window) {
      aElem.scrollTo(x, y);
    } else {
      aElem.scrollLeft = x;
      aElem.scrollTop = y;
    }
  },

  _scrollBy: function(aElem, x, y){
    if (aElem instanceof Window) {
      aElem.scrollBy(x, y);
    } else {
      aElem.scrollLeft += x;
      aElem.scrollTop += y;
    }
  },

  _getSelectionController : function(aWindow) {
    // Yuck. See bug 138068.
    var Ci = Components.interfaces;
    var docShell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                          .getInterface(Ci.nsIWebNavigation)
                          .QueryInterface(Ci.nsIDocShell);
    try{
      var controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                               .getInterface(Ci.nsISelectionDisplay)
                               .QueryInterface(Ci.nsISelectionController);
    }catch(e){
      return null;
    }
    return controller;
  },

  getScrollView: function (aTarget) {
    var NS, EW, NSEW;
    NS = EW = NSEW = null;
    var _scrollingView = null;
    for (_scrollingView = aTarget; _scrollingView; _scrollingView = _scrollingView.parentNode) {
      if (_scrollingView instanceof NSHTMLElement) {
        if (_scrollingView.localName.toLowerCase() == "select") {
          _scrollingView.parentNode.focus();
          return [NS, EW, NSEW];
        }
        var doc, style;
        var overflowx = "";
        var overflowy = "";
        try {
          doc = _scrollingView.ownerDocument;
          style = doc.defaultView.getComputedStyle(_scrollingView, "");
          overflowx = style.getPropertyValue("overflow-x");
          overflowy = style.getPropertyValue("overflow-y");
        } catch (ex) {
        }
        var borderTop    = 0;
        var borderBottom = 0;
        var borderLeft   = 0;
        var borderRight  = 0;
        if (/^(td|th)$/i.test(_scrollingView.localName)) {
          try {
            doc = _scrollingView.ownerDocument;
            style = doc.defaultView.getComputedStyle(_scrollingView, "");
            borderTop    = style.getPropertyValue("border-top-width").replace('px', '');
            borderBottom = style.getPropertyValue("border-bottom-width").replace('px', '');
            borderLeft   = style.getPropertyValue("border-left-width").replace('px', '');
            borderRight   = style.getPropertyValue("border-right-width").replace('px', '');
          } catch (ex) {
          }
        }
        var horz = _scrollingView.clientWidth !== 0 &&
                   _scrollingView.clientWidth + borderLeft + borderRight < _scrollingView.scrollWidth;
        var vert = _scrollingView.clientHeight !== 0 &&
                   _scrollingView.clientHeight + borderTop + borderBottom < _scrollingView.scrollHeight;
        if (horz &&
            overflowx != "hidden" &&
            overflowx != "visible" &&
            vert && overflowy != "hidden" && overflowy != "visible") {
          NSEW = !NSEW ? _scrollingView : NSEW;
        }
        if (horz && overflowx != "hidden" && overflowx != "visible") {
          EW = !EW ? _scrollingView : EW;
        }
        if (vert && overflowy != "hidden" && overflowy != "visible") {
          NS = !NS ? _scrollingView : NS;
        }
        if (_scrollingView.localName.toUpperCase() == "HTML" ||
            _scrollingView.localName.toUpperCase() == "BODY") {
          _scrollingView = _scrollingView.ownerDocument.defaultView;
          if (_scrollingView.scrollMaxX > 0 &&
              _scrollingView.scrollMaxY > 0) {
            NSEW = !NSEW ? _scrollingView : NSEW;
          }
          if (_scrollingView.scrollMaxX > 0) {
            EW = !EW ? _scrollingView : EW;
          }
          if (_scrollingView.scrollMaxY > 0) {
            NS = !NS ? _scrollingView : NS;
            break;
          }
        }
      }
    }
    return [NS, EW, NSEW];
  },

  getSelectionFrame : function(aFrame) {
    var selection = Components.lookupMethod(aFrame, 'getSelection').call(aFrame);
    if (selection && selection.toString()) {
      return aFrame;
    }
    var frame;
    for (var i = 0, maxi = aFrame.frames.length; i < maxi; i++) {
      frame = arguments.callee(aFrame.frames[i]);
      if (frame)
        return frame;
    }
    return null;
  },

  _getComputedStyle : function(aNode) {
    if (aNode instanceof Window)
      return aNode.getComputedStyle(aNode.document.documentElement, null);
      if (!aNode.ownerDocument)
        return null;
    return aNode.ownerDocument.defaultView.getComputedStyle(aNode, null);
  },

  _getPropertyPixelValue : function(aStyle, aProperty) {
    return parseInt(aStyle.getPropertyValue(aProperty).replace('px', ''));
  },

  // TOP уБЛуВЙуБоч¦¦хп-х¦зциЩуВТхПЦх-Ч
  getPageOffsetTop : function(aNode) {
    if (!aNode) return 0;
    var top = aNode.offsetTop;
    while (aNode.offsetParent != null)
    {
      aNode = aNode.offsetParent;
      top += aNode.offsetTop;
    }
    return top;
  },

    scrollFrameifAny: function scrollFrameifAny(win) {
    var pelem = this.getIFrameByWindow(win);
    if (pelem) {
      var pwin = pelem.ownerDocument.defaultView; 
      var PageOffsetTop;
      try {
        PageOffsetTop = pelem.ownerDocument.getBoxObjectFor(pelem).y;
      } catch(e) {
        PageOffsetTop = window['piro.sakura.ne.jp.Alice0775'].boxObject.getBoxObjectFor(pelem).y;
      }
      if (PageOffsetTop) {
        pwin.scroll( pwin.pageXOffset, PageOffsetTop - pwin.innerHeight / 2 + win.innerHeight / 2);
        //this.scrollFrameifAny(pwin);
      }
    }
  },

  getIFrameByWindow: function getIFrameByWindow(awin,win) {
    if(!win) win = this.activeBrowser.contentDocument.defaultView; 
    for (var i=0; win.frames && i<win.frames.length; i++){
      var iframe = this.getIFrameByWindow(awin,win.frames[i]);
      if (iframe)
        return iframe;
    }
    var doc = win.document;
    if (!doc)
      return false;
    var iframes = doc.getElementsByTagName("iframe");
    for (var i=0; i<iframes.length; i++) {
      var w = null;
      if (iframes[i].contentWindow)
        w = iframes[i].contentWindow;
      if (w == awin )
        return iframes[i];
    }
    return false;
  },

   _getSelectionFramePrefFocused: function( parent_frame ) {

    //this.debug
    var focued_frame = document.commandDispatcher.focusedWindow;
    if ( focued_frame ){
      var selection = Components.lookupMethod(focued_frame, 'getSelection').call(focued_frame);
      if ( selection && selection.toString() ) {
        return focued_frame;
      }
    }

    return this.getSelectionFrame( parent_frame );
  },


  handleEvent: function(aEvent) {
    switch (aEvent.type) {
      case 'DOMAttrModified':
        this._DOMAttrModified(aEvent);
        break;
      case 'TabSelect':
        this._TabSelect(aEvent);
        break;
      case 'load':
        this.onload();
        break;
      case 'unload':
        this.onunload();
        break;
    }
  },

  _DOMAttrModified: function(aEvent) {
    var attrName = aEvent.attrName;
    //this.debug(attrName);
    //this.debug(aEvent.newValue);
    switch (attrName) {
      case "checked":
        var target = this.prevelement;
        if (target) {
          target.scrollTop = this.prevelementScrollTop;
          target.scrollLeft = this.prevelementScrollLeft;
          this.prevelement = null;
        }
        break;
      case "hidden":
        //FindbarуБощЭЮшбичд¦уБлхРМцЬЯуБЧуБжуВ¦уВпуГнуГ-уГлуГкуВ¬уГГуГИ
        if (aEvent.newValue) {
          var target = this.prevelement;
          if (target) {
            target.scrollTop = this.prevelementScrollTop;
            target.scrollLeft = this.prevelementScrollLeft;
          }
        }
        this.prevelement = null;
        break;
    }
  },

  _TabSelect: function(aEvent) {
    try {
      var target = this.prevelement;
      if (target) {
        target.scrollTop = this.prevelementScrollTop;
        target.scrollLeft = this.prevelementScrollLeft;
        this.prevelement = null;
      }
    } catch(e) {}
  },

  delayedStartUpTimer: null,
  delayedStartUpTimer2: null,

  onload: function() {
    window.addEventListener('unload', this, false);
    window.removeEventListener('load', this, false);
    //delayed start up
    this.delayedStartUpTimer = setTimeout(function(self) {
      var nTab = 1;
      try {
        if(gBrowser && gBrowser.mTabs)
          nTab = gBrowser.mTabs.length;
      } catch(ex) {}
        self.delayedStartUpTimer2 = setTimeout(function(self) {
        self.init();
      }, nTab*100, self);
    }, 1000, this);
  },

  onunload: function() {
    window.removeEventListener('unload', this, false);
    window.unwatch('gFindBarInitialized');
    gFindBar.removeEventListener("DOMAttrModified", this, false);
    if ("gBrowser" in window && "tabContainer" in gBrowser)
      gBrowser.tabContainer.removeEventListener('TabSelect', this, false);

    if (this.delayedStartUpTimer)
      clearTimeout(this.delayedStartUpTimer);
    if (this.delayedStartUpTimer2)
      clearTimeout(this.delayedStartUpTimer2);
    if(this._timer)
      clearTimeout(this._timer);

    if(this.timerid)
      clearTimeout(this.timerid);
    if (this.timerSmoothScroll)
      clearTimeout(this.timerSmoothScroll);
  }
};
findcenter.onload();
var ucjsFind = findcenter;



(function() {
  const currentRevision = 3.3;

  if (!('piro.sakura.ne.jp.Alice0775' in window)) window['piro.sakura.ne.jp.Alice0775'] = {};

  var loadedRevision = 'boxObject' in window['piro.sakura.ne.jp.Alice0775'] ?
      window['piro.sakura.ne.jp.Alice0775'].boxObject.revision :
      0 ;
  if (loadedRevision && loadedRevision > currentRevision) {
    return;
  }

  var Cc = Components.classes;
  var Ci = Components.interfaces;

  window['piro.sakura.ne.jp.Alice0775'].boxObject = {
    revision : currentRevision,

    getBoxObjectFor : function(aNode, aUnify)
    {
      if (aNode instanceof Range){
        return this.getBoxObjectFromClientRectFor(aNode, aUnify) ;
      }
      return (aNode.ownerDocument.body &&
              !('getBoundingClientRect' in aNode.ownerDocument.body)) ? /*aaaaaaaaaaaa*/
          this.getBoxObjectFromBoxObjectFor(aNode, aUnify) :
          this.getBoxObjectFromClientRectFor(aNode, aUnify) ;
    },

    getBoxObjectFromBoxObjectFor : function(aNode, aUnify)
    {
      var boxObject = aNode.ownerDocument.getBoxObjectFor(aNode);
      var box = {
          x       : boxObject.x,
          y       : boxObject.y,
          width   : boxObject.width,
          height  : boxObject.height,
          screenX : boxObject.screenX,
          screenY : boxObject.screenY
        };
      if (!aUnify) return box;

      var style = this._getComputedStyle(aNode);
      box.left = box.x - this._getPropertyPixelValue(style, 'border-left-width');
      box.top = box.y - this._getPropertyPixelValue(style, 'border-top-width');
      if (style.getPropertyValue('position') == 'fixed') {
        box.left -= frame.scrollX;
        box.top  -= frame.scrollY;
      }
      box.right  = box.left + box.width;
      box.bottom = box.top + box.height;

      return box;
    },

    getBoxObjectFromClientRectFor : function(aNode, aUnify)
    {
      var box = {
          x       : 0,
          y       : 0,
          width   : 0,
          height  : 0,
          screenX : 0,
          screenY : 0
        };
      try {
        if (aNode instanceof Range){
          var zoom = this.getZoom(aNode.startContainer.ownerDocument.defaultView);
        } else {
          var zoom = this.getZoom(aNode.ownerDocument.defaultView);
        }

        var rect = aNode.getBoundingClientRect();
        if (aUnify) {
          box.left   = rect.left;
          box.top    = rect.top;
          box.right  = rect.right;
          box.bottom = rect.bottom;
          return box;
        }

        if (aNode instanceof Range){
          var style = this._getComputedStyle(aNode.startContainer.parentNode);
          var frame = aNode.startContainer.parentNode.ownerDocument.defaultView;
        } else {
          var style = this._getComputedStyle(aNode);
          var frame = aNode.ownerDocument.defaultView;
        }

        // "x" and "y" are offset positions of the "padding-box" from the document top-left edge.
        box.x = rect.left + this._getPropertyPixelValue(style, 'border-left-width');
        box.y = rect.top + this._getPropertyPixelValue(style, 'border-top-width');
        if (style.getPropertyValue('position') != 'fixed') {
          box.x += frame.scrollX;
          box.y += frame.scrollY;
        }

        // "width" and "height" are sizes of the "border-box".
        box.width  = rect.right-rect.left;
        box.height = rect.bottom-rect.top;

        // "screenX" and "screenY" are absolute positions of the "border-box".
        box.screenX = rect.left * zoom;
        box.screenY = rect.top * zoom;

        if ('mozInnerScreenX' in frame && 'mozInnerScreenY' in frame) {
          box.screenX += frame.mozInnerScreenX * zoom;
          box.screenY += frame.mozInnerScreenY * zoom;
        }
        else {
          if (aNode instanceof Range){
            var owner = aNode.startContainer.parentNode;
          } else {
            var owner = aNode;
          }
          while (true)
          {
            owner = this._getFrameOwnerFromFrame(frame);
            frame = owner.ownerDocument.defaultView;
            zoom  = this.getZoom(frame);

            let style = this._getComputedStyle(owner);
            box.screenX += this._getPropertyPixelValue(style, 'border-left-width') * zoom;
            box.screenY += this._getPropertyPixelValue(style, 'border-top-width') * zoom;

            if (!owner) {
              box.screenX += frame.screenX;
              box.screenY += frame.screenY;
              break;
            }
            if (owner.ownerDocument instanceof Ci.nsIDOMXULDocument) {
              let ownerBox = owner.ownerDocument.getBoxObjectFor(owner);
              box.screenX += ownerBox.screenX;
              box.screenY += ownerBox.screenY;
              break;
            }

            let ownerRect = owner.getBoundingClientRect();
            box.screenX += ownerRect.left * zoom;
            box.screenY += ownerRect.top * zoom;
          }
        }
      }
      catch(e) {
        ucjsFind.debug(e);
      }

      for (let i in box)
      {
        box[i] = Math.round(box[i]);
      }

      return box;
    },

    _getComputedStyle : function(aNode)
    {
      return aNode.ownerDocument.defaultView.getComputedStyle(aNode, null);
    },

    _getPropertyPixelValue : function(aStyle, aProperty)
    {
      return parseInt(aStyle.getPropertyValue(aProperty).replace('px', ''));
    },

    _getFrameOwnerFromFrame : function(aFrame)
    {
      var parentItem = aFrame
          .QueryInterface(Ci.nsIInterfaceRequestor)
          .getInterface(Ci.nsIWebNavigation)
          .QueryInterface(Ci.nsIDocShell)
          .QueryInterface(Ci.nsIDocShellTreeNode)
          .QueryInterface(Ci.nsIDocShellTreeItem)
          .parent;
      var isChrome = parentItem.itemType == parentItem.typeChrome;
      var parentDocument = parentItem
          .QueryInterface(Ci.nsIWebNavigation)
          .document;
      var nodes = parentDocument.evaluate(
          '/descendant::*[contains(" frame FRAME iframe IFRAME browser tabbrowser ", concat(" ", local-name(), " "))]',
          parentDocument,
          null,
          Ci.nsIDOMXPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
          null
        );
      for (let i = 0, maxi = nodes.snapshotLength; i < maxi; i++)
      {
        let owner = nodes.snapshotItem(i);
        if (isChrome && owner.wrappedJSObject) owner = owner.wrappedJSObject;
        if (owner.localName == 'tabbrowser') {
          let tabs = owner.mTabContainer.childNodes;
          for (let i = 0, maxi = tabs.length; i < maxi; i++)
          {
            let browser = tabs[i].linkedBrowser;
            if (browser.contentWindow == aFrame)
              return browser;
          }
        }
        else if (owner.contentWindow == aFrame) {
          return owner;
        }
      }
      return null;
    },

    Prefs : Cc['@mozilla.org/preferences-service;1']
      .getService(Ci.nsIPrefBranch)
      .QueryInterface(Ci.nsIPrefBranch2),

    getZoom : function(aFrame)
    {
      try {
        if (!this.Prefs.getBoolPref('browser.zoom.full'))
          return 1;
      }
      catch(e) {
        return 1;
      }
      var markupDocumentViewer = aFrame.top
          .QueryInterface(Ci.nsIInterfaceRequestor)
          .getInterface(Ci.nsIWebNavigation)
          .QueryInterface(Ci.nsIDocShell)
          .contentViewer
          .QueryInterface(Ci.nsIMarkupDocumentViewer);
      return markupDocumentViewer.fullZoom;
    }

  };
})();

Не работает на [aurora] 11 :( что можно сделать?

Kamui пишет

Не работает на [aurora] 11 :( что можно сделать?

да не работает, в консоли
Error: NSHTMLElement is not defined

В аналогичном расширении Find To Center это исправлено и даже написано что связано с багом 684821

https://developer.mozilla.org/en/Firefo … interfaces

hydrolizer
Спасибо, ты очень помог!



Find To Center(Firefox 10+)

скрытый текст

Выделить код

Код:

// find center....................
var findcenter = {
// -- config --
  SCROLL_SMOOTH: true,      
  SCROLL_PADDING:10,         
  SCROLL_PARENT_BLOCK: false, 
  // -- config --
  kSCROLL_WRAPPED      :'extensions.findcenter.alert.find.wrapped',
  kSCROLL_SMOOTH_FIND  :'extensions.findcenter.scroll_smooth.find',
  kSCROLL_SMOOTH_STEPS :'extensions.findcenter.scroll_smooth.steps',
  kSCROLL_SMOOTH_LIMITS :'extensions.findcenter.scroll_smooth.limits',
  kSCROLL_PADDING      :'extensions.findcenter.scroll.padding',
  _timer: null,
  get browser() {
    return document.getElementById('content') || // Firefox
      document.getElementById('messagepane') || // Thunderbird
      document.getElementById('help-content'); // Help
  },

  get activeBrowser() {
    return ('SplitBrowser' in window && SplitBrowser.activeBrowser) || this.browser;
  },

  getVer: function(){
    const Cc = Components.classes;
    const Ci = Components.interfaces;
    var info = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
    var ver = parseInt(info.version.substr(0,3) * 10,10) / 10;
    return ver;
  },

  debug: function(aMsg){
    const Cc = Components.classes;
    const Ci = Components.interfaces;
    Cc["@mozilla.org/consoleservice;1"]
      .getService(Ci.nsIConsoleService)
      .logStringMessage(aMsg);
  },

  init: function(){

    if (!document.getElementById("FindToolbar") &&
        typeof gFindBarInitialized != 'undefined' &&
        !gFindBarInitialized) {
      window.watch('gFindBarInitialized', function() { findcenter.init(); });
      return;
    }

    if (!("gFindBar" in window)) {
      window.gFindBar = document.getElementById("FindToolbar");
    }

    if ('XMigemoFind' in window) {
      this.setPrefValue('xulmigemo.scrollSelectionToCenter', 'bool', false)

      if (this.getVer() >= 3.0) { //Fx3.0 3.5
        this.debug('Firefox 3 W/ XUL/Migemo');

        try {
          eval('gFindBar._updateStatusUI = gFindBar.updateStatus = '+gFindBar._updateStatusUI.toString()
            .replace('{', '$&findcenter._dispSelectionCenter(res);')
          );
        } catch(ex) {
        }

      }

    } else { // without XUL/Migemo

      if (this.getVer() >= 3.0) { //Fx3.0 3.5
        this.debug('Firefox 3');
        try {
          eval('gFindBar._updateStatusUI = '+gFindBar._updateStatusUI.toSource()
            .replace('{', '$&findcenter._dispSelectionCenter(res);')
          );
        } catch(ex) {
        }
      }

    }

    //searchWp 1.0
    if (typeof gSearchWPTermsToolbar != 'undefined') {
      this.debug('SearchWP');
      try{
        var func = gSearchWPTermsToolbar._doSearch.toString();
        //var exp = new RegExp(/}$/);
        func = func.replace('if (result && prevRange) {', 'findcenter._dispSelectionCenter();if (result && prevRange) {');
        eval("gSearchWPTermsToolbar._doSearch = " + func);
        //this.debug(func);
      }catch(ex){
      }
      //alert if find wrapped.
      document.getElementById("statusbar-display").addEventListener("DOMAttrModified", function(e) {
        if (!e.newValue) return;
          if(findcenter.getPrefValue(findcenter.kSCROLL_WRAPPED, 'bool', false)){
            var bundle = document.getElementById("bundle_searchwp");
            var status = e.target;
            if(findcenter._timer) clearTimeout(findcenter._timer);
            findcenter._timer = setTimeout(function(){
              if( status.getAttribute('label') == bundle.getString("wrappedToTop")
                 || status.getAttribute('label') == bundle.getString("wrappedToBottom") ){
                alert(status.getAttribute('label'));
              }
            },200);
          }
      }, false);
    }
    if (typeof searchwp != 'undefined'){
      //alert if find wrapped.
      document.getElementById("statusbar-display").addEventListener("DOMAttrModified", function(e) {
        if (!e.newValue) return;
          var status = e.target;
          if(findcenter._timer) clearTimeout(findcenter._timer);
            findcenter._timer = setTimeout(function(){
            if(findcenter.getPrefValue(findcenter.kSCROLL_WRAPPED, 'bool', false)){
              var textboxWP = document.getAnonymousElementByAttribute(document.getElementById("searchbar"),
                      "anonid", "searchbar-textbox");
              var bundleWP = document.getAnonymousElementByAttribute(textboxWP, "anonid", "searchwp-stringbundle");

              if( status.getAttribute('label') == bundleWP.getString("wrappedToTop")
                 || status.getAttribute('label') == bundleWP.getString("wrappedToBottom") ){
                alert(status.getAttribute('label'));
              }
            }
          },200);
      }, false);
      this.debug('SearchWP 2.0');
    }
    //all in one search button 1.67
    if (typeof ObjAllinonesearch != 'undefined'){
      dump('Allinonesearch');
      try{
        var func = ObjAllinonesearch.doselection.toString();
        var exp = new RegExp(/}$/);
        func = func.replace('selection.addRange(allinonesearch_range);', 'selection.addRange(allinonesearch_range);findcenter._dispSelectionCenter();return;');
        eval("ObjAllinonesearch.doselection = " + func);
      }catch(ex){
      }
    }

    //Googlebar Lite 4.6.9
    if ('GBL_FindInPage' in window) {
      try{
        var func = GBL_FindInPage.toString();
        func = func.replace('found = findInst.findNext();', '$&findcenter._dispSelectionCenter();');
        eval("GBL_FindInPage = " + func);
      }catch(ex){
      }
    }

    //Google Toolbar for Firefox 3.1.20090119W
    if ('GTB_getToolbar' in window && typeof GTB_getToolbar().highlighter == 'object') {
      try{
        var func = GTB_getToolbar().highlighter.findTermText.toString();
        func = func.replace(/findBar\.findNext\(\);/g, '$&findcenter._dispSelectionCenter();');
        func = func.replace(/findBar\.findPrevious\(\);/g, '$&findcenter._dispSelectionCenter();');
        eval("GTB_getToolbar().highlighter.findTermText = " + func);
      }catch(ex){
      }
      try{
        var func = GTB_getToolbar().highlighter._unhighlightWindow.toString();
        func = func.replace(/return result/g, 'doc.body.normalize();$&');
        eval("GTB_getToolbar().highlighter._unhighlightWindow = " + func);
      }catch(ex){
      }
      //Google Toolbar for Firefox 5.0.20090324W
      try{
        var func = GTB_getToolbar().highlighter.findTermText.toString();
        func = func.replace(/c\.gFindBar\._findAgain\(false\);/g, '$&findcenter._dispSelectionCenter();');
        func = func.replace(/c\.gFindBar\._findAgain\(true\);/g, '$&findcenter._dispSelectionCenter();');
        eval("GTB_getToolbar().highlighter.findTermText = " + func);
      }catch(ex){
      }
    }



    if (this.getVer() >= 3.0) { //Fx3.0 3.5
     //alert if find wrapped.
      gFindBar.addEventListener("DOMAttrModified", function(e) {
        if(e.newValue != 'wrapped') return;
          var MigemoON =  false;
          if(document.getElementById("find-migemo-mode")){
            MigemoON =  document.getElementById("find-migemo-mode").checked;
          }else if(document.getElementById("find-mode-selector")){
            MigemoON =  document.getElementById("find-mode-selector").value == 1;
          }
        if(findcenter.getPrefValue(findcenter.kSCROLL_WRAPPED, 'bool', false) &&
           !MigemoON )
        {
          var bundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
                      .getService(Components.interfaces.nsIStringBundleService)
                      .createBundle("chrome://global/locale/findbar.properties");
          if(findcenter._timer) clearTimeout(findcenter._timer);
          findcenter._timer = setTimeout(function(){
            var status = document.getAnonymousElementByAttribute(gFindBar, "anonid", "find-status");
            if( status.textContent == bundle.GetStringFromName("WrappedToTop")
               || status.textContent == bundle.GetStringFromName("WrappedToBottom") ){
              alert(status.textContent);
            }
          },100);
        }
      }, false);
    }
    window.addEventListener('unload', this, false);
    //Findbar
    gFindBar.addEventListener("DOMAttrModified", this, false);
    if ("gBrowser" in window && "tabContainer" in gBrowser)
      gBrowser.tabContainer.addEventListener('TabSelect', this, false);
    var findcenter_init = true;
  },


  setPrefValue: function(aPrefString, aPrefType, aValue) {
    var xpPref = Components.classes['@mozilla.org/preferences-service;1']
                  .getService(Components.interfaces.nsIPrefBranch2);
    try {
      switch (aPrefType) {
        case 'complex':
          return xpPref.setComplexValue(aPrefString, Components.interfaces.nsILocalFile, aValue); break;
        case 'str':
          return xpPref.setCharPref(aPrefString, aValue); break;
        case 'int':
          aValue = parseInt(aValue);
          return xpPref.setIntPref(aPrefString, aValue);  break;
        case 'bool':
        default:
          return xpPref.setBoolPref(aPrefString, aValue); break;
      }
    } catch(e) { }
    return null;
  },

  getPrefValue: function(aPrefString, aPrefType, aDefault) {
    var xpPref = Components.classes['@mozilla.org/preferences-service;1']
                  .getService(Components.interfaces.nsIPrefBranch2);
    if (xpPref.getPrefType(aPrefString) == xpPref.PREF_INVALID) {
      return aDefault;
    }
    try {
      switch (aPrefType) {
        case "str":
          return xpPref.getCharPref(aPrefString).toString(); break;
        case "int":
          return xpPref.getIntPref(aPrefString); break;
        case "bool":
        default:
          return xpPref.getBoolPref(aPrefString); break;
      }
    } catch(e) { }
    return aDefault;
  },

  //-------------------------------------------------------------------
  // overflow hiddenу
  // SCROLL_PARENT_BLOCK
  prevelement: null,
  prevelementScrollTop:0,
  prevelementScrollLeft:0,
  ensureVisibleElement: function ensureVisibleElement(aNode){
    if (aNode instanceof Range) {
      var selCon = this._getSelectionController(aNode.startContainer.ownerDocument.defaultView);
      if (selCon) {
        // 
        selCon.scrollSelectionIntoView(selCon.SELECTION_NORMAL,
                                             selCon.SELECTION_ANCHOR_REGION,
                                             true);
      }
      return
    }

    try {
      var mShell = Components.classes["@mozilla.org/inspector/flasher;1"]
               .createInstance(Components.interfaces.inIFlasher);
    } catch(e) {
      return;
    }

    var target0 = null;
    var target0ScrollTop = 0;
    var target0ScrollLeft = 0;
    var target = aNode;
    while(target) {
      var style = this._getComputedStyle(target);
      if (style &&
          style.getPropertyValue("display") == "block" &&
          target.clientHeight < target.scrollHeight ||
          target.clientWidth < target.scrollWidth) {
        if (style.getPropertyValue("overflow-y") == "hidden") {
          target0 = target;
          target0ScrolllTop = target.scrollTop;
          target0ScrollLeft = target.scrollLeft;
        }
        break;
      }
      target = target.parentNode;
    }

    if (target0 != this.prevelement) {
      var target = this.prevelement;
      if (target) {
         target.scrollTop = this.prevelementScrollTop;
         target.scrollLeft = this.prevelementScrollLeft;
      }
      this.prevelement = target0;
      this.prevelementScrollTop = target0ScrollTop;
      this.prevelementScrollLeft = target0ScrollLeft;

    }

    mShell.scrollElementIntoView(aNode);
  },

  //
  _dispSelectionCenter : function(res){

    var frame = this._getSelectionFramePrefFocused( window.content );
    if (!frame) return;

    var selection = Components.lookupMethod(frame, 'getSelection').call(frame);
    var elem = null;
    // Fx3.5
    // хp
    this.SCROLL_PARENT_BLOCK2 = this.SCROLL_PARENT_BLOCK
                              || (this.getVer() == 3.5 &&
                              gFindBar.getElement("highlight").checked);


    if (!this.SCROLL_PARENT_BLOCK2) {
      if (this.getVer() <= 3.6) {
        var range = frame.document.createRange( );
        range.setStart( selection.focusNode, selection.focusOffset );
        range.setEnd  ( selection.focusNode, selection.focusOffset );
        elem = frame.document.createElement( "span" )
        range.insertNode( elem );
      } else {
        elem = frame.document.createRange( );
        elem.setStart( selection.anchorNode, selection.anchorOffset );
        elem.setEnd  ( selection.focusNode, selection.focusOffset );
      }

    }

    if (typeof res != 'undefined' && res != 0)
      this.prevFrame = null;

    this.doCenter( frame, elem, selection);

    // ф¬АцЩВчЪДуБкшжБч+ауВТхЙКщЩд
    if (!!elem && !(elem instanceof Range)) {
      var p = elem.parentNode;
      p.removeChild( elem );
      range.deleteContents( );
      range.detach( );
      p.normalize();
    } else if (!!elem && (elem instanceof Range)) {
      elem.detach( );
    }

    var selCon = this._getSelectionController(frame);
    if (selCon) {
      // 
      selCon.scrollSelectionIntoView(selCon.SELECTION_NORMAL,
                                           selCon.SELECTION_ANCHOR_REGION,
                                           true);
    }

  },

  
  //This Code based on Piro's XUL/Migemo
  doCenter : function(aFrame, aElem, aSelection) {
    if (!aFrame) return;
    if (!aElem && !(aElem instanceof Range)) { 
      var range = aFrame.document.createRange( );
      range.setStart( aSelection.focusNode, aSelection.focusOffset );
      range.setEnd  ( aSelection.focusNode, aSelection.focusOffset );

      aElem = range.startContainer.parentNode;
      range.deleteContents( );
      range.detach( );
    }
    this.doCenter_sub(aFrame, aElem, aSelection);
    // ensureVisibleElement
    // TabSelect
    this.ensureVisibleElement( aElem );

  },

  prevFrame: null,
  prevElem: null,
  prevScrollView: [],

  doCenter_sub: function(aFrame, aElem, aSelection) {
      if (/*true ||*/this.prevFrame != aFrame) {
      this.scrollFrameifAny(aFrame);
      this.prevFrame = aFrame;

    }

    var padding = findcenter.getPrefValue(findcenter.kSCROLL_PADDING,
                                          "int", findcenter.SCROLL_PADDING);
    var view = null,
        box,
        box2,
        targetX,
        targetY,
        targetW,
        targetH;

    box = window['piro.sakura.ne.jp.Alice0775'].boxObject.getBoxObjectFor(aElem);
    if (!box.x && !box.y) {
      if ((aElem instanceof Range))
        box = window['piro.sakura.ne.jp.Alice0775'].boxObject.getBoxObjectFor(aElem.startContainer);
      else
        box = window['piro.sakura.ne.jp.Alice0775'].boxObject.getBoxObjectFor(aElem.parentNode);
    }
    targetX = box.x;
    targetY = box.y;
    targetW = Math.max(box.width, 20);
    targetH = Math.max(box.height, 20);

    var scrollView;
    if (aElem instanceof Range) {
      if (aElem.startContainer.parentNode && this.prevElem == aElem.startContainer.parentNode) {
        scrollView = this.prevScrollView;
      } else {
        scrollView = this.getScrollView(aElem.startContainer);
        this.prevScrollView = scrollView;
        this.prevElem = aElem.startContainer.parentNode;
      }
    } else {
      if (aElem.parentNode && this.prevElem == aElem.parentNode) {
        scrollView = this.prevScrollView;
      } else {
        scrollView = this.getScrollView(aElem);
        this.prevScrollView = scrollView;
        this.prevElem = aElem.parentNode;
      }
    }

    var viewX, targetX_x, targetX_y, viewY, targetY_x, targetY_y;
    viewX = viewY = null;

    if (scrollView[1] && scrollView[1] instanceof Window) {
      view = scrollView[1];

      var viewW = view.innerWidth;
      var xUnit = Math.max(viewW * (padding / 100), targetW);

      var sx = view.scrollX;
      var sy = view.scrollY;
      var xa = targetX - sx;
      var xb = xa + targetW;
//this.debug(" " + (targetX <= viewW - xUnit) +   (xa <= viewW - xUnit)  +  (xb >= viewW - xUnit));
      var x = (targetX <= viewW - xUnit) ? 0 :
                      (xa <= viewW - xUnit) ? sx :
                             (xb >= viewW - xUnit) ? +targetX - viewW / 2:
                                                    sx;
      viewX = view;
      targetX_x = x;
      targetX_y = sy;
    } else if (scrollView[1]) {
      view = scrollView[1];

      var viewbox = window['piro.sakura.ne.jp.Alice0775'].boxObject.getBoxObjectFor(view);
      var style = this._getComputedStyle(aFrame);
      var overfllowx = style.getPropertyValue("overflow-x")
      var overfllowy = style.getPropertyValue("overflow-y")
      var xx = aFrame.scrollX;
      if (overfllowx != "visible" && overfllowx != "hidden")
        xx = (viewbox.x + viewbox.width / 2) - aFrame.innerWidth / 2;
      var yy = aFrame.scrollY;
      if (overfllowy != "visible" && overfllowy != "hidden")
        yy = (viewbox.y + viewbox.height / 2) - aFrame.innerHeight / 2;
      this._scrollTo(aFrame, xx ,yy);


      var viewW = view.clientWidth;
      var xUnit = Math.max(viewW * (padding / 100), targetW);

      var sx = view.scrollLeft;
      var sy = view.scrollTop;
      targetX =  targetX - viewbox.x;
      var xa = targetX;
      var xb = xa + targetW;
      var x = (targetX + sx <= viewW - xUnit) ? 0 :
                      (xa <= viewW - xUnit) ? sx :
                             (xb >= viewW - xUnit) ? +targetX + sx - viewW / 2 :
                                                    sx;
      viewX = view;
      targetX_x = x;
      targetX_y = sy;
    }

    if (scrollView[0] && scrollView[0] instanceof Window) {
      view = scrollView[0];

      var viewH = view.innerHeight;
      var yUnit = Math.max(viewH * (padding / 100), targetH);

      var sx = view.scrollX;
      var sy = view.scrollY;
      var ya = targetY - sy;
      var yb = ya + targetH;
      var pos = 0.5;
      if (this.SCROLL_PARENT_BLOCK2) {
        if (targetH < viewH)
          pos = (viewH - targetH) / viewH /2;
        else
          return
      }
      var y = (ya <= yUnit ) ? targetY - viewH * pos  :
                              (yb >= viewH - yUnit ) ? +targetY - viewH * pos  :
                                                      sy;
      viewY = view;
      targetY_x = x;//sx;
      targetY_y = y;
    } else if (scrollView[0]) {
      view = scrollView[0];

      var viewbox = window['piro.sakura.ne.jp.Alice0775'].boxObject.getBoxObjectFor(view);
      var style = this._getComputedStyle(aFrame);
      var overfllowx = style.getPropertyValue("overflow-x");
      var overfllowy = style.getPropertyValue("overflow-y");
      var xx = aFrame.scrollX;
      if (overfllowx != "visible" && overfllowx != "hidden");
        xx = (viewbox.x + viewbox.width / 2) - aFrame.innerWidth / 2;
      var yy = aFrame.scrollY;
      if (overfllowy != "visible" && overfllowy != "hidden");
        yy = (viewbox.y + viewbox.height / 2) - aFrame.innerHeight / 2;
      this._scrollTo(aFrame, xx ,yy);

      var viewH = view.clientHeight;
      var yUnit = Math.max(viewH * (padding / 100), targetH);
      var sx = view.scrollLeft;
      var sy = view.scrollTop;
      targetY =  targetY - viewbox.y;
      var ya = targetY;
      var yb = ya + targetH;
      var pos = 0.5;
      if (this.SCROLL_PARENT_BLOCK2) {
        if (targetH < viewH)
          pos = (viewH - targetH) / viewH /2;
        else
          return
      }
      var y = (ya <= yUnit ) ? targetY + sy - viewH * pos  :
                              (yb >= viewH - yUnit ) ? +targetY + sy - viewH * pos  :
                                                      sy;
      viewY = view;
      targetY_x = x;//sx;
      targetY_y = y;
    }

    if (viewX == viewY) {
      targetY_x = targetX_x;
      viewX = null;
    }
    this.smoothScrollTo(viewX, targetX_x, targetX_y, viewY, targetY_x, targetY_y);

    // hack for Google Reader
    if (/^http:\/\/www\.google\.[.a-z]+\/reader\/view/.test(content.location.href)) {
      this.viewY.style.visibility = "collapse";
      this.viewY.clientTop;
      this.viewY.style.visibility = "visible";
    }

  },


  timerid: null,
  timerSmoothScroll: null,
  stopSmoothScroll: false,

  smoothScrollTo: function(viewX, targetX_x, targetX_y, viewY, targetY_x, targetY_y) {
    if (this.timerid)
      clearInterval(this.timerid);
    var interval = 20;//
    this.n = this.getPrefValue(this.kSCROLL_SMOOTH_FIND, 'bool', this.SCROLL_SMOOTH)
               ? this.getPrefValue(this.kSCROLL_SMOOTH_STEPS, 'int', 6) : 1; 
    this.limits = this.getPrefValue(this.kSCROLL_SMOOTH_LIMITS, 'int', 100);

    if (viewX){
      this.viewX = viewX;
      this.targetX_x = targetX_x;
      this.targetX_y = targetX_y;
      if (this.viewX instanceof Window) {
        this.currentX_x = viewX.scrollX;
        this.currentX_y = viewX.scrollY;
      } else {
        this.currentX_x = viewX.scrollLeft;
        this.currentX_y = viewX.scrollTop;
      }

      this.diffX_x = targetX_x - this.currentX_x;
      this.diffX_y = targetX_y - this.currentX_y;
    }
    if (viewY){
      this.viewY = viewY;
      this.targetY_x = targetY_x;
      this.targetY_y = targetY_y;
      if (this.viewY instanceof Window) {
        this.currentY_x = viewY.scrollX;
        this.currentY_y = viewY.scrollY;
      } else {
        this.currentY_x = viewY.scrollLeft;
        this.currentY_y = viewY.scrollTop;
      }

      this.diffY_x = targetY_x - this.currentY_x;
      this.diffY_y = targetY_y - this.currentY_y;
    }


    this.count = 1;

      if (this.timerSmoothScroll)
      clearTimeout(this.timerSmoothScroll);
    this.stopSmoothScroll = false;

    this.timerSmoothScroll = setTimeout(function(self){self.stopSmoothScroll = true;}, this.limits, this);

    this.timerid = setInterval( function(self) {
      var dx,dy;
      if ( self.count >= self.n || self.stopSmoothScroll) {
        if (self.timerSmoothScroll)
          clearInterval(self.timerSmoothScroll);
        clearInterval(self.timerid);
        if (self.viewX)
          self._scrollTo(self.viewX, self.targetX_x, self.targetX_y);
        if (self.viewY)
          self._scrollTo(self.viewY, self.targetY_x, self.targetY_y);
        return;
      } else {
        if (self.viewX){
          if (self.viewX instanceof Window) {
            dx = (self.currentX_x + self.diffX_x / self.n * self.count) - self.viewX.scrollX;
            dy = (self.currentX_y + self.diffX_y / self.n * self.count) - self.viewX.scrollY;
          } else {
            dx = (self.currentX_x + self.diffX_x / self.n * self.count) - self.viewX.scrollLeft;
            dy = (self.currentX_y + self.diffX_y / self.n * self.count) - self.viewX.scrollTop;
          }
          self._scrollBy(self.viewX, dx, dy);
        }
        if (self.viewY){
          if (self.viewY instanceof Window) {
            dx = (self.currentY_x + self.diffY_x / self.n * self.count) - self.viewY.scrollX;
            dy = (self.currentY_y + self.diffY_y / self.n * self.count) - self.viewY.scrollY;
          } else {
            dx = (self.currentY_x + self.diffY_x / self.n * self.count) - self.viewY.scrollLeft;
            dy = (self.currentY_y + self.diffY_y / self.n * self.count) - self.viewY.scrollTop;
          }
          self._scrollBy(self.viewY, dx, dy);
        }

        self.count++;
        if (2 < self.count && self.count < self.n - 2)
          self.count++;
        if (4 < self.count && self.count < self.n - 4)
          self.count++;
        if (6 < self.count && self.count < self.n - 6)
          self.count++;
        if (8 < self.count && self.count < self.n - 8)
          self.count++;
        if (10 < self.count && self.count < self.n -10)
          self.count++;
      }
    }, interval, this);
    return;
  },

  _scrollTo: function(aElem, x, y){
    var self = this;
    if (aElem instanceof Window) {
      aElem.scrollTo(x, y);
    } else {
      aElem.scrollLeft = x;
      aElem.scrollTop = y;
    }
  },

  _scrollBy: function(aElem, x, y){
    if (aElem instanceof Window) {
      aElem.scrollBy(x, y);
    } else {
      aElem.scrollLeft += x;
      aElem.scrollTop += y;
    }
  },

  _getSelectionController : function(aWindow) {
    // Yuck. See bug 138068.
    var Ci = Components.interfaces;
    var docShell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                          .getInterface(Ci.nsIWebNavigation)
                          .QueryInterface(Ci.nsIDocShell);
    try{
      var controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                               .getInterface(Ci.nsISelectionDisplay)
                               .QueryInterface(Ci.nsISelectionController);
    }catch(e){
      return null;
    }
    return controller;
  },

  getScrollView: function (aTarget) {
    var NS, EW, NSEW;
    NS = EW = NSEW = null;
    var _scrollingView = null;
    for (_scrollingView = aTarget; _scrollingView; _scrollingView = _scrollingView.parentNode) {
      if (_scrollingView instanceof HTMLElement) {
        if (_scrollingView.localName.toLowerCase() == "select") {
          _scrollingView.parentNode.focus();
          return [NS, EW, NSEW];
        }
        var doc, style;
        var overflowx = "";
        var overflowy = "";
        try {
          doc = _scrollingView.ownerDocument;
          style = doc.defaultView.getComputedStyle(_scrollingView, "");
          overflowx = style.getPropertyValue("overflow-x");
          overflowy = style.getPropertyValue("overflow-y");
        } catch (ex) {
        }
        var borderTop    = 0;
        var borderBottom = 0;
        var borderLeft   = 0;
        var borderRight  = 0;
        if (/^(td|th)$/i.test(_scrollingView.localName)) {
          try {
            doc = _scrollingView.ownerDocument;
            style = doc.defaultView.getComputedStyle(_scrollingView, "");
            borderTop    = style.getPropertyValue("border-top-width").replace('px', '');
            borderBottom = style.getPropertyValue("border-bottom-width").replace('px', '');
            borderLeft   = style.getPropertyValue("border-left-width").replace('px', '');
            borderRight   = style.getPropertyValue("border-right-width").replace('px', '');
          } catch (ex) {
          }
        }
        var horz = _scrollingView.clientWidth !== 0 &&
                   _scrollingView.clientWidth + borderLeft + borderRight < _scrollingView.scrollWidth;
        var vert = _scrollingView.clientHeight !== 0 &&
                   _scrollingView.clientHeight + borderTop + borderBottom < _scrollingView.scrollHeight;
        if (horz &&
            overflowx != "hidden" &&
            overflowx != "visible" &&
            vert && overflowy != "hidden" && overflowy != "visible") {
          NSEW = !NSEW ? _scrollingView : NSEW;
        }
        if (horz && overflowx != "hidden" && overflowx != "visible") {
          EW = !EW ? _scrollingView : EW;
        }
        if (vert && overflowy != "hidden" && overflowy != "visible") {
          NS = !NS ? _scrollingView : NS;
        }
        if (_scrollingView.localName.toUpperCase() == "HTML" ||
            _scrollingView.localName.toUpperCase() == "BODY") {
          _scrollingView = _scrollingView.ownerDocument.defaultView;
          if (_scrollingView.scrollMaxX > 0 &&
              _scrollingView.scrollMaxY > 0) {
            NSEW = !NSEW ? _scrollingView : NSEW;
          }
          if (_scrollingView.scrollMaxX > 0) {
            EW = !EW ? _scrollingView : EW;
          }
          if (_scrollingView.scrollMaxY > 0) {
            NS = !NS ? _scrollingView : NS;
            break;
          }
        }
      }
    }
    return [NS, EW, NSEW];
  },

  getSelectionFrame : function(aFrame) {
    var selection = Components.lookupMethod(aFrame, 'getSelection').call(aFrame);
    if (selection && selection.toString()) {
      return aFrame;
    }
    var frame;
    for (var i = 0, maxi = aFrame.frames.length; i < maxi; i++) {
      frame = arguments.callee(aFrame.frames[i]);
      if (frame)
        return frame;
    }
    return null;
  },

  _getComputedStyle : function(aNode) {
    if (aNode instanceof Window)
      return aNode.getComputedStyle(aNode.document.documentElement, null);
      if (!aNode.ownerDocument)
        return null;
    return aNode.ownerDocument.defaultView.getComputedStyle(aNode, null);
  },

  _getPropertyPixelValue : function(aStyle, aProperty) {
    return parseInt(aStyle.getPropertyValue(aProperty).replace('px', ''));
  },

  // TOP уБЛуВЙуБоч¦¦хп-х¦зциЩуВТхПЦх-Ч
  getPageOffsetTop : function(aNode) {
    if (!aNode) return 0;
    var top = aNode.offsetTop;
    while (aNode.offsetParent != null)
    {
      aNode = aNode.offsetParent;
      top += aNode.offsetTop;
    }
    return top;
  },

    scrollFrameifAny: function scrollFrameifAny(win) {
    var pelem = this.getIFrameByWindow(win);
    if (pelem) {
      var pwin = pelem.ownerDocument.defaultView; 
      var PageOffsetTop;
      try {
        PageOffsetTop = pelem.ownerDocument.getBoxObjectFor(pelem).y;
      } catch(e) {
        PageOffsetTop = window['piro.sakura.ne.jp.Alice0775'].boxObject.getBoxObjectFor(pelem).y;
      }
      if (PageOffsetTop) {
        pwin.scroll( pwin.pageXOffset, PageOffsetTop - pwin.innerHeight / 2 + win.innerHeight / 2);
        //this.scrollFrameifAny(pwin);
      }
    }
  },

  getIFrameByWindow: function getIFrameByWindow(awin,win) {
    if(!win) win = this.activeBrowser.contentDocument.defaultView; 
    for (var i=0; win.frames && i<win.frames.length; i++){
      var iframe = this.getIFrameByWindow(awin,win.frames[i]);
      if (iframe)
        return iframe;
    }
    var doc = win.document;
    if (!doc)
      return false;
    var iframes = doc.getElementsByTagName("iframe");
    for (var i=0; i<iframes.length; i++) {
      var w = null;
      if (iframes[i].contentWindow)
        w = iframes[i].contentWindow;
      if (w == awin )
        return iframes[i];
    }
    return false;
  },

   _getSelectionFramePrefFocused: function( parent_frame ) {

    //this.debug
    var focued_frame = document.commandDispatcher.focusedWindow;
    if ( focued_frame ){
      var selection = Components.lookupMethod(focued_frame, 'getSelection').call(focued_frame);
      if ( selection && selection.toString() ) {
        return focued_frame;
      }
    }

    return this.getSelectionFrame( parent_frame );
  },


  handleEvent: function(aEvent) {
    switch (aEvent.type) {
      case 'DOMAttrModified':
        this._DOMAttrModified(aEvent);
        break;
      case 'TabSelect':
        this._TabSelect(aEvent);
        break;
      case 'load':
        this.onload();
        break;
      case 'unload':
        this.onunload();
        break;
    }
  },

  _DOMAttrModified: function(aEvent) {
    var attrName = aEvent.attrName;
    //this.debug(attrName);
    //this.debug(aEvent.newValue);
    switch (attrName) {
      case "checked":
        var target = this.prevelement;
        if (target) {
          target.scrollTop = this.prevelementScrollTop;
          target.scrollLeft = this.prevelementScrollLeft;
          this.prevelement = null;
        }
        break;
      case "hidden":
        //FindbarуБощЭЮшбичд¦уБлхРМцЬЯуБЧуБжуВ¦уВпуГнуГ-уГлуГкуВ¬уГГуГИ
        if (aEvent.newValue) {
          var target = this.prevelement;
          if (target) {
            target.scrollTop = this.prevelementScrollTop;
            target.scrollLeft = this.prevelementScrollLeft;
          }
        }
        this.prevelement = null;
        break;
    }
  },

  _TabSelect: function(aEvent) {
    try {
      var target = this.prevelement;
      if (target) {
        target.scrollTop = this.prevelementScrollTop;
        target.scrollLeft = this.prevelementScrollLeft;
        this.prevelement = null;
      }
    } catch(e) {}
  },

  delayedStartUpTimer: null,
  delayedStartUpTimer2: null,

  onload: function() {
    window.addEventListener('unload', this, false);
    window.removeEventListener('load', this, false);
    //delayed start up
    this.delayedStartUpTimer = setTimeout(function(self) {
      var nTab = 1;
      try {
        if(gBrowser && gBrowser.mTabs)
          nTab = gBrowser.mTabs.length;
      } catch(ex) {}
        self.delayedStartUpTimer2 = setTimeout(function(self) {
        self.init();
      }, nTab*100, self);
    }, 1000, this);
  },

  onunload: function() {
    window.removeEventListener('unload', this, false);
    window.unwatch('gFindBarInitialized');
    gFindBar.removeEventListener("DOMAttrModified", this, false);
    if ("gBrowser" in window && "tabContainer" in gBrowser)
      gBrowser.tabContainer.removeEventListener('TabSelect', this, false);

    if (this.delayedStartUpTimer)
      clearTimeout(this.delayedStartUpTimer);
    if (this.delayedStartUpTimer2)
      clearTimeout(this.delayedStartUpTimer2);
    if(this._timer)
      clearTimeout(this._timer);

    if(this.timerid)
      clearTimeout(this.timerid);
    if (this.timerSmoothScroll)
      clearTimeout(this.timerSmoothScroll);
  }
};
findcenter.onload();
var ucjsFind = findcenter;



(function() {
  const currentRevision = 3.3;

  if (!('piro.sakura.ne.jp.Alice0775' in window)) window['piro.sakura.ne.jp.Alice0775'] = {};

  var loadedRevision = 'boxObject' in window['piro.sakura.ne.jp.Alice0775'] ?
      window['piro.sakura.ne.jp.Alice0775'].boxObject.revision :
      0 ;
  if (loadedRevision && loadedRevision > currentRevision) {
    return;
  }

  var Cc = Components.classes;
  var Ci = Components.interfaces;

  window['piro.sakura.ne.jp.Alice0775'].boxObject = {
    revision : currentRevision,

    getBoxObjectFor : function(aNode, aUnify)
    {
      if (aNode instanceof Range){
        return this.getBoxObjectFromClientRectFor(aNode, aUnify) ;
      }
      return (aNode.ownerDocument.body &&
              !('getBoundingClientRect' in aNode.ownerDocument.body)) ? /*aaaaaaaaaaaa*/
          this.getBoxObjectFromBoxObjectFor(aNode, aUnify) :
          this.getBoxObjectFromClientRectFor(aNode, aUnify) ;
    },

    getBoxObjectFromBoxObjectFor : function(aNode, aUnify)
    {
      var boxObject = aNode.ownerDocument.getBoxObjectFor(aNode);
      var box = {
          x       : boxObject.x,
          y       : boxObject.y,
          width   : boxObject.width,
          height  : boxObject.height,
          screenX : boxObject.screenX,
          screenY : boxObject.screenY
        };
      if (!aUnify) return box;

      var style = this._getComputedStyle(aNode);
      box.left = box.x - this._getPropertyPixelValue(style, 'border-left-width');
      box.top = box.y - this._getPropertyPixelValue(style, 'border-top-width');
      if (style.getPropertyValue('position') == 'fixed') {
        box.left -= frame.scrollX;
        box.top  -= frame.scrollY;
      }
      box.right  = box.left + box.width;
      box.bottom = box.top + box.height;

      return box;
    },

    getBoxObjectFromClientRectFor : function(aNode, aUnify)
    {
      var box = {
          x       : 0,
          y       : 0,
          width   : 0,
          height  : 0,
          screenX : 0,
          screenY : 0
        };
      try {
        if (aNode instanceof Range){
          var zoom = this.getZoom(aNode.startContainer.ownerDocument.defaultView);
        } else {
          var zoom = this.getZoom(aNode.ownerDocument.defaultView);
        }

        var rect = aNode.getBoundingClientRect();
        if (aUnify) {
          box.left   = rect.left;
          box.top    = rect.top;
          box.right  = rect.right;
          box.bottom = rect.bottom;
          return box;
        }

        if (aNode instanceof Range){
          var style = this._getComputedStyle(aNode.startContainer.parentNode);
          var frame = aNode.startContainer.parentNode.ownerDocument.defaultView;
        } else {
          var style = this._getComputedStyle(aNode);
          var frame = aNode.ownerDocument.defaultView;
        }

        // "x" and "y" are offset positions of the "padding-box" from the document top-left edge.
        box.x = rect.left + this._getPropertyPixelValue(style, 'border-left-width');
        box.y = rect.top + this._getPropertyPixelValue(style, 'border-top-width');
        if (style.getPropertyValue('position') != 'fixed') {
          box.x += frame.scrollX;
          box.y += frame.scrollY;
        }

        // "width" and "height" are sizes of the "border-box".
        box.width  = rect.right-rect.left;
        box.height = rect.bottom-rect.top;

        // "screenX" and "screenY" are absolute positions of the "border-box".
        box.screenX = rect.left * zoom;
        box.screenY = rect.top * zoom;

        if ('mozInnerScreenX' in frame && 'mozInnerScreenY' in frame) {
          box.screenX += frame.mozInnerScreenX * zoom;
          box.screenY += frame.mozInnerScreenY * zoom;
        }
        else {
          if (aNode instanceof Range){
            var owner = aNode.startContainer.parentNode;
          } else {
            var owner = aNode;
          }
          while (true)
          {
            owner = this._getFrameOwnerFromFrame(frame);
            frame = owner.ownerDocument.defaultView;
            zoom  = this.getZoom(frame);

            let style = this._getComputedStyle(owner);
            box.screenX += this._getPropertyPixelValue(style, 'border-left-width') * zoom;
            box.screenY += this._getPropertyPixelValue(style, 'border-top-width') * zoom;

            if (!owner) {
              box.screenX += frame.screenX;
              box.screenY += frame.screenY;
              break;
            }
            if (owner.ownerDocument instanceof Ci.nsIDOMXULDocument) {
              let ownerBox = owner.ownerDocument.getBoxObjectFor(owner);
              box.screenX += ownerBox.screenX;
              box.screenY += ownerBox.screenY;
              break;
            }

            let ownerRect = owner.getBoundingClientRect();
            box.screenX += ownerRect.left * zoom;
            box.screenY += ownerRect.top * zoom;
          }
        }
      }
      catch(e) {
        ucjsFind.debug(e);
      }

      for (let i in box)
      {
        box[i] = Math.round(box[i]);
      }

      return box;
    },

    _getComputedStyle : function(aNode)
    {
      return aNode.ownerDocument.defaultView.getComputedStyle(aNode, null);
    },

    _getPropertyPixelValue : function(aStyle, aProperty)
    {
      return parseInt(aStyle.getPropertyValue(aProperty).replace('px', ''));
    },

    _getFrameOwnerFromFrame : function(aFrame)
    {
      var parentItem = aFrame
          .QueryInterface(Ci.nsIInterfaceRequestor)
          .getInterface(Ci.nsIWebNavigation)
          .QueryInterface(Ci.nsIDocShell)
          .QueryInterface(Ci.nsIDocShellTreeNode)
          .QueryInterface(Ci.nsIDocShellTreeItem)
          .parent;
      var isChrome = parentItem.itemType == parentItem.typeChrome;
      var parentDocument = parentItem
          .QueryInterface(Ci.nsIWebNavigation)
          .document;
      var nodes = parentDocument.evaluate(
          '/descendant::*[contains(" frame FRAME iframe IFRAME browser tabbrowser ", concat(" ", local-name(), " "))]',
          parentDocument,
          null,
          Ci.nsIDOMXPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
          null
        );
      for (let i = 0, maxi = nodes.snapshotLength; i < maxi; i++)
      {
        let owner = nodes.snapshotItem(i);
        if (isChrome && owner.wrappedJSObject) owner = owner.wrappedJSObject;
        if (owner.localName == 'tabbrowser') {
          let tabs = owner.mTabContainer.childNodes;
          for (let i = 0, maxi = tabs.length; i < maxi; i++)
          {
            let browser = tabs[i].linkedBrowser;
            if (browser.contentWindow == aFrame)
              return browser;
          }
        }
        else if (owner.contentWindow == aFrame) {
          return owner;
        }
      }
      return null;
    },

    Prefs : Cc['@mozilla.org/preferences-service;1']
      .getService(Ci.nsIPrefBranch)
      .QueryInterface(Ci.nsIPrefBranch2),

    getZoom : function(aFrame)
    {
      try {
        if (!this.Prefs.getBoolPref('browser.zoom.full'))
          return 1;
      }
      catch(e) {
        return 1;
      }
      var markupDocumentViewer = aFrame.top
          .QueryInterface(Ci.nsIInterfaceRequestor)
          .getInterface(Ci.nsIWebNavigation)
          .QueryInterface(Ci.nsIDocShell)
          .contentViewer
          .QueryInterface(Ci.nsIMarkupDocumentViewer);
      return markupDocumentViewer.fullZoom;
    }

  };
})();

hydrolizer, bunda1
Спасибо за помощь;)

bunda1

Find To Center(Firefox 11+)

Как раз пригодилась к только что вышедшему FF10, т.к. прежняя перестала работать!
Так что это Find To Center(Firefox 10+) :)

Inko7
Спасибо, я исправил.