SafariHighlight.uc.js ver. 0.9
0.9.2にverUPしました。
userChrome.js(http://forums.mozillazine.org/viewtopic.php?t=556229)用のスクリプトです。
Safariのインライン検索のハイライトみたいに動作させるスクリプトです。
SearchWP(http://legege.com/en/mozilla/searchwp)と、Googlebar Lite(http://www.borngeek.com/firefox/googlebarlite/)のハイライトにも対応しています。
設定項目(ソースの最初の辺り)
動作確認
マイナーなMODってゆーな!変更点
- オーバーレイの不透明度を変更できるようにした。
- piroさんのXUL/Migemoによる実装を取り込み、ヒット箇所のアニメーションを実装。
- 細かいバグの修正。
既知の不具合
- リンク等がクリックできなくなる。
- z-indexを無効化することによる、使用しているページのデザインがハイライト中は崩れてしまう、筈。
- 横スクロールバーが存在するとオーバーレイの横幅がおかしい。
注意
約1週間対応が行えないので、0.8をバックアップしておく事をお勧めします。
// ==UserScript== // @name SafariHighlight // @namespace http://kuonn.mydns.jp // @author DeaR // @include chrome://browser/content/browser.xul // @description Safari like Highlight // @version 0.9 // @compatibility Firefox 2.0 - 3.0 // ==/UserScript== // this script based on // Greased Lightbox (http://shiftingpixel.com/lightbox) // userContent.js (http://pc11.2ch.net/test/read.cgi/software/1168635399/419) // ucjs_findbar (http://space.geocities.yahoo.co.jp/gl/alice0775/view/20070301/1172678601) // XUL/Migemo (http://piro.sakura.ne.jp/xul/_xulmigemo.html) var safariHighlight = { alwaysHighlight : true, // 常に検索開始時は強調表示する clickAndExit : true, // 画面クリックでハイライトを終了する overlayOpacity : 0.3, // オーバーレイの不透明度 (0:透明, 1:不透明) hitAnimeation : true, // ヒット箇所のアニメーションを行う。 get browser() { return document.getElementById("content") || // Firefox document.getElementById("messagepane") || // Thunderbird document.getElementById("help-content"); // Help }, get activeBrowser() { return ("SplitBrowser" in window ? SplitBrowser.activeBrowser : null ) || this.browser; }, initializeHighlightScreen : function(aFrame) { if(!aFrame) aFrame = this.activeBrowser.contentWindow; if(aFrame.frames && aFrame.frames.length) { var self = this; Array.prototype.slice.call(aFrame.frames).forEach(function(aSubFrame) { self.initializeHighlightScreen(aSubFrame); }); } if(aFrame.document instanceof HTMLDocument) this.addHighlightScreen(aFrame.document); }, addHighlightScreen : function(aDocument) { var doc = aDocument; if (doc.getElementById("__moz_findSafariHighlightStyle")) return; var pageSize = this.getPageSize(doc.defaultView); var heads = doc.getElementsByTagName("head"); if(heads.length > 0) { var objHead = heads[0]; var node = doc.createElement("style"); node.id = "__moz_findSafariHighlightStyle"; node.type = "text/css"; node.innerHTML = this.highlightStyle + "#__moz_findSafariHighlightScreen {" + " height: " + pageSize.height + "px;" + " opacity : " + this.overlayOpacity + ";" + " -moz-opacity : " + this.overlayOpacity + ";" + "}"; objHead.insertBefore(node, objHead.firstChild); } var bodies = doc.getElementsByTagName("body"); if(bodies.length == 0) return; var objBody = bodies[0]; var screen = doc.createElement("div"); screen.setAttribute("id", "__moz_findSafariHighlightScreen"); objBody.insertBefore(screen, objBody.firstChild); }, highlightStyle : String(<![CDATA[ :root[__moz_findSafariHighlightScreen="on"] * { z-index : auto !important; } :root[__moz_findSafariHighlightScreen="on"] #__firefox-findbar-search-id, /* Fx2 */ :root[__moz_findSafariHighlightScreen="on"] .__mozilla-findbar-search, /* Fx3 */ :root[__moz_findSafariHighlightScreen="on"] .searchwp-term-highlight1, /* SearchWP */ :root[__moz_findSafariHighlightScreen="on"] .searchwp-term-highlight2, :root[__moz_findSafariHighlightScreen="on"] .searchwp-term-highlight3, :root[__moz_findSafariHighlightScreen="on"] .searchwp-term-highlight4, :root[__moz_findSafariHighlightScreen="on"] .GBL-Highlighted /* Googlebar Lite */ { position : relative !important; z-index : 3000000 !important; } #__moz_findSafariHighlightScreen { left : 0; top : 0; width : 100%; border : 0; margin : 0; padding : 0; background : #000000; position : absolute; display : none; z-index : 1000000 !important; } :root[__moz_findSafariHighlightScreen="on"] > body > #__moz_findSafariHighlightScreen { display : block !important; } :root[__moz_findSafariHighlightScreen="on"] embed { visibility : hidden !important; } :root[__moz_findSafariHighlightScreen="on"] iframe { position : relative; z-index : 2000000 !important; } ]]>), getPageSize : function(aWindow) { var xScroll = aWindow.document.body.scrollWidth; var yScroll = aWindow.innerHeight + aWindow.scrollMaxY; var windowWidth = aWindow.innerWidth; var windowHeight = aWindow.innerHeight; var pageHeight = (yScroll < windowHeight) ? windowHeight : yScroll ; var pageWidth = (xScroll < windowWidth) ? windowWidth : xScroll ; return { width : pageWidth, height : pageHeight, wWidth : windowWidth, wHeight : windowHeight }; }, destroyHighlightScreen : function(aFrame) { if(!aFrame) aFrame = this.activeBrowser.contentWindow; if(aFrame.frames && aFrame.frames.length) { var self = this; Array.prototype.slice.call(aFrame.frames).forEach(function(aSubFrame) { self.destroyHighlightScreen(aSubFrame); }); } if(!(aFrame.document instanceof HTMLDocument)) return; aFrame.document.documentElement.removeAttribute("__moz_findSafariHighlightScreen"); if(this.clickAndExit) aFrame.removeEventListener("click", function(event) { safariHighlight.onClick(event); }, true); }, toggleHighlightScreen : function(aHighlight, aFrame) { if(!aFrame) aFrame = this.activeBrowser.contentWindow; if(aFrame.frames && aFrame.frames.length) { var self = this; Array.prototype.slice.call(aFrame.frames).forEach(function(aSubFrame) { self.toggleHighlightScreen(aHighlight, aSubFrame); }); } if(!(aFrame.document instanceof HTMLDocument)) return; if(window.content) window.content.__moz_findSafariHighlightScreen = aHighlight; if(aHighlight) { aFrame.document.documentElement.setAttribute("__moz_findSafariHighlightScreen", "on"); if(this.clickAndExit) aFrame.addEventListener("click", function(event) { safariHighlight.onClick(event); }, true); } else { aFrame.document.documentElement.removeAttribute("__moz_findSafariHighlightScreen"); if(this.clickAndExit) aFrame.removeEventListener("click", function(event) { safariHighlight.onClick(event); }, true); } }, findCommand : function() { this.initializeHighlightScreen(); var highlightBtn; if("gFindBar" in window && "onFindAgainCommand" in gFindBar) { // Fx3 var findbar = document.getElementById("FindToolbar"); highlightBtn = document.getAnonymousElementByAttribute(findbar, "anonid", "highlight"); } else if(typeof gFindBar == "object") { // Fx2 highlightBtn = document.getElementById("highlight"); } if(highlightBtn.getAttribute("checked") != "true") { highlightBtn.setAttribute("checked", "true"); gFindBar.toggleHighlight(true); this.toggleHighlightScreen(true); } }, onClick : function(aEvent) { var highlightBtn; if("gFindBar" in window && "onFindAgainCommand" in gFindBar) { // Fx3 var findbar = document.getElementById("FindToolbar"); highlightBtn = document.getAnonymousElementByAttribute(findbar, "anonid", "highlight"); } else if(typeof gFindBar == "object") { // Fx2 highlightBtn = document.getElementById("highlight"); } if(highlightBtn.checked) { highlightBtn.removeAttribute("checked"); highlightBtn.setAttribute("checkeState", "0"); gFindBar.toggleHighlight(false); } if(typeof gSearchWP != "undefined") { // SearchWP highlightBtn = document.getElementById("searchwp-highlight-button"); if(highlightBtn.checked) { highlightBtn.checked = false; gSearchWPOverlay.toggleHighlight(false); } } if(typeof GBL_Listener != "undefined") { // Googlebar Lite highlightBtn = document.getElementById("GBL-TB-Highlighter"); if(highlightBtn.checked) GBL_ToggleHighlighting(); } this.destroyHighlightScreen(null); }, restoreHighlightScreen : function() { if("gFindBar" in window && "onFindAgainCommand" in gFindBar) { // Fx3 var findbar = document.getElementById("FindToolbar"); highlightBtn = document.getAnonymousElementByAttribute(findbar, "anonid", "highlight"); } else if(typeof gFindBar == "object") { // Fx2 highlightBtn = document.getElementById("highlight"); } if(highlightBtn.getAttribute("checked") == "true") this.toggleHighlightScreen(true); }, // Safari style highlight, animation // based on XUL/Migemo (http://piro.sakura.ne.jp/xul/_xulmigemo.html) NSResolver : { lookupNamespaceURI : function(aPrefix) { switch (aPrefix) { case "xul": return "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; case "html": case "xhtml": return "http://www.w3.org/1999/xhtml"; case "xlink": return "http://www.w3.org/1999/xlink"; default: return ""; } } }, getFoundRange : function(aFrame) { var docShell = aFrame.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShell); var selCon = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsISelectionDisplay) .QueryInterface(Components.interfaces.nsISelectionController); if(selCon.getDisplaySelection() == selCon.SELECTION_ATTENTION) { var sel = aFrame.getSelection(); var range = sel.getRangeAt(0); return range; } return null; }, highlightFocusedFound : function(aFrame) { if(this.highlightFocusedFoundTimer) window.clearTimeout(this.highlightFocusedFoundTimer); this.highlightFocusedFoundTimer = window.setTimeout( "safariHighlight.highlightFocusedFoundCallback()", 0); }, highlightFocusedFoundCallback : function(aFrame) { this.highlightFocusedFoundTimer = null; if(!aFrame) aFrame = this.activeBrowser.contentWindow; var range = this.getFoundRange(aFrame); if(range) { var node = range.startContainer; try { var xpathResult = aFrame.document.evaluate( "ancestor-or-self::*[@id = '__firefox-findbar-search-id' or @class = '__mozilla-findbar-search']", node, this.NSResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null); } catch(e) { var xpathResult = document.evaluate( 'ancestor-or-self::*[@id = "__firefox-findbar-search-id" or @class = "__mozilla-findbar-search"]', node, this.NSResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null); } if(xpathResult.singleNodeValue) this.animateFoundNode(xpathResult.singleNodeValue); return true; } if(aFrame.frames && aFrame.frames.length) { var frames = aFrame.frames; for(var i = 0, maxi = frames.length; i < maxi; i ++) { if(this.highlightFocusedFound(frames[i])) break; } } return false; }, animateFoundNode : function(aNode) { if(this.animationTimer) { this.animationNode.style.top = 0; window.clearInterval(this.animationTimer); this.animationTimer = null; this.animationNode = null; } this.animationNode = aNode; this.animationStart = (new Date()).getTime(); this.animationTimer = window.setInterval(this.animateFoundNodeCallback, 1, this); }, animateFoundNodeCallback : function(aThis) { var node = aThis.animationNode; var now = (new Date()).getTime(); if(aThis.animationTime <= (now - aThis.animationStart) || !node.parentNode) { node.style.top = 0; window.clearInterval(aThis.animationTimer); aThis.animationTimer = null; aThis.animationNode = null; } else { var step = ((now - aThis.animationStart) || 1) / aThis.animationTime; var y = parseInt(10 * Math.sin((180 - (180 * step)) * Math.PI / 180)); node.style.top = "-0." + y + "0em"; } }, animationTimer : null, animationTime : 250, }; (function() { if(typeof XMigemoUI != "undefined") // XUL/Migemo return; if("gFindBar" in window && "onFindAgainCommand" in gFindBar) { // Fx3 try { eval("gFindBar.open = " + gFindBar.open.toSource().replace( "return true;", "safariHighlight.initializeHighlightScreen();" + "safariHighlight.restoreHighlightScreen();" + "return true;")); eval("gFindBar.close = " + gFindBar.close.toSource().replace( "document.commandDispatcher.suppressFocusScroll = suppressedScroll;", "safariHighlight.destroyHighlightScreen();" + "document.commandDispatcher.suppressFocusScroll = suppressedScroll;")); eval("gFindBar.toggleHighlight = " + gFindBar.toggleHighlight.toSource().replace( "if (aHighlight) {", "safariHighlight.initializeHighlightScreen();" + "safariHighlight.toggleHighlightScreen(aHighlight);" + "if (aHighlight) {")); if(safariHighlight.alwaysHighlight) { eval("gFindBar._find = " + gFindBar._find.toSource().replace( "var val = aValue || this._findField.value", "var val = aValue || this._findField.value" + "safariHighlight.findCommand();")); eval("gFindBar.onFindAgainCommand = " + gFindBar.onFindAgainCommand.toSource().replace( "var findString = this._browser.fastFind.searchString || this._findField.value;", "safariHighlight.findCommand();" + "var findString = this._browser.fastFind.searchString || this._findField.value;")); } if(safariHighlight.hitAnimeation) { eval("gFindBar._updateStatusUI = " + gFindBar._updateStatusUI.toSource().replace( "switch (res) {", "if(arguments[0] != Components.interfaces.nsITypeAheadFind.FIND_NOTFOUND)" + " safariHighlight.highlightFocusedFound();" + "switch (res) {")); } } catch(e) {} } else if(typeof gFindBar == "object") { // Fx2 try { eval("gFindBar.openFindBar = " + gFindBar.openFindBar.toSource().replace( "return true;", "safariHighlight.initializeHighlightScreen();" + "safariHighlight.restoreHighlightScreen();" + "return true;")); eval("gFindBar.closeFindBar = " + gFindBar.closeFindBar.toSource().replace( "setTimeout(findBar_DelayedCloseFindBar, 0);", "safariHighlight.destroyHighlightScreen();" + "setTimeout(findBar_DelayedCloseFindBar, 0);")); eval("gFindBar.toggleHighlight = " + gFindBar.toggleHighlight.toSource().replace( "if (aHighlight) {", "safariHighlight.initializeHighlightScreen();" + "safariHighlight.toggleHighlightScreen(aHighlight);" + "if (aHighlight) {")); if(safariHighlight.alwaysHighlight) { eval("gFindBar.findNext = " + gFindBar.findNext.toSource().replace( "var fastFind = getBrowser().fastFind;", "safariHighlight.findCommand();" + "var fastFind = getBrowser().fastFind;")); eval("gFindBar.findPrevious = " + gFindBar.findPrevious.toSource().replace( "var fastFind = getBrowser().fastFind;", "safariHighlight.findCommand();" + "var fastFind = getBrowser().fastFind;")); } if(safariHighlight.hitAnimeation) { eval("gFindBar.updateStatus = " + gFindBar.updateStatus.toSource().replace( "var findBar = document.getElementById(\"FindToolbar\");", "if(arguments[0] != Components.interfaces.nsITypeAheadFind.FIND_NOTFOUND)" + " safariHighlight.highlightFocusedFound();" + "var findBar = document.getElementById(\"FindToolbar\");")); } } catch(e) {} } if(typeof gSearchWP != "undefined") { // SearchWP try { eval("gSearchWPOverlay.toggleHighlight = " + gSearchWPOverlay.toggleHighlight.toSource().replace( "gSearchWPHighlighting.toggleHighlight(aHighlight);", "safariHighlight.initializeHighlightScreen();" + "safariHighlight.toggleHighlightScreen(aHighlight);" + "gSearchWPHighlighting.toggleHighlight(aHighlight);")); } catch(e) {} } if(typeof GBL_Listener != "undefined") { // Googlebar Lite try { eval("GBL_ToggleHighlighting = " + GBL_ToggleHighlighting.toSource().replace( "var hb = document.getElementById(\"GBL-TB-Highlighter\");", "var hb = document.getElementById(\"GBL-TB-Highlighter\");" + "safariHighlight.initializeHighlightScreen();" + "safariHighlight.toggleHighlightScreen(!hb.checked);")); } catch(e) {} } })();