|
阅读:2395回复:4
搜索辅助脚本SafariHighlight在ff4.0beta2上失效了,有有人能修复一下啊?
或者给推荐个类似效果的,
谢谢. // ==UserScript==
// @name SafariHighlight
// @namespace http://kuonn.mydns.jp
// @author DeaR
// @include main
// @description Safari like Highlight
// @version 1.0.0
// @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:不透明)
hitAnimation : true, // ヒット箇所のアニメーションを行う
clickElement : true, // 要素の下にあるリンクにクリックイベントを送る。
searchWP : false, // SearchWPに対応させる。
googlebarLite : false, // GooglebarLiteに対応させる。
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_safarihighlight-style"))
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_safarihighlight-style";
node.type = "text/css";
node.innerHTML = this.highlightStyle +
"#__moz_safarihighlight-screen {" +
" 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_safarihighlight-screen");
objBody.insertBefore(screen, objBody.firstChild);
},
highlightStyle : String(<![CDATA[
:root[__moz_safarihighlight-screen="on"] * {
z-index : auto !important;
}
:root[__moz_safarihighlight-screen="on"] #__firefox-findbar-search-id, /* Fx2 */
:root[__moz_safarihighlight-screen="on"] .__mozilla-findbar-search, /* Fx3 */
:root[__moz_safarihighlight-screen="on"] .searchwp-term-highlight1, /* SearchWP 1 */
:root[__moz_safarihighlight-screen="on"] .searchwp-term-highlight2,
:root[__moz_safarihighlight-screen="on"] .searchwp-term-highlight3,
:root[__moz_safarihighlight-screen="on"] .searchwp-term-highlight4,
:root[__moz_safarihighlight-screen="on"] .searchwp-term, /* SearchWP 2 */
:root[__moz_safarihighlight-screen="on"] .GBL-Highlighted, /* Googlebar Lite */
:root[__moz_safarihighlight-screen="on"] __mozilla-grep-search /* GrepSidebar */ {
position : relative !important;
z-index : 3000000 !important;
}
#__moz_safarihighlight-screen {
left : 0;
top : 0;
width : 100%;
border : 0;
margin : 0;
padding : 0;
background : #000000;
position : absolute;
display : none;
z-index : 1000000 !important;
}
:root[__moz_safarihighlight-screen="on"] > body > #__moz_safarihighlight-screen {
display : block !important;
}
:root[__moz_safarihighlight-screen="on"] embed {
visibility : hidden !important;
}
:root[__moz_safarihighlight-screen="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_safarihighlight-screen");
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_SafariHighlightScreen = aHighlight;
if(aHighlight) {
aFrame.document.documentElement.setAttribute("__moz_safarihighlight-screen", "on");
if(this.clickAndExit)
aFrame.addEventListener("click", function(event) {
safariHighlight.onClick(event);
}, true);
} else {
aFrame.document.documentElement.removeAttribute("__moz_safarihighlight-screen");
if(this.clickAndExit)
aFrame.removeEventListener("click", function(event) {
safariHighlight.onClick(event);
}, true);
}
},
findCommand : function() {
this.initializeHighlightScreen();
var highlightBtn;
if(this.fxVer == 3) { // Fx3
var findbar = document.getElementById("FindToolbar");
highlightBtn = document.getAnonymousElementByAttribute(findbar, "anonid", "highlight");
} else if(this.fxVer == 2) { // 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(this.fxVer == 3) { // Fx3
var findbar = document.getElementById("FindToolbar");
highlightBtn = document.getAnonymousElementByAttribute(findbar, "anonid", "highlight");
} else if(this.fxVer == 2) { // Fx2
highlightBtn = document.getElementById("highlight");
}
if(highlightBtn.checked) {
highlightBtn.removeAttribute("checked");
highlightBtn.setAttribute("checkeState", "0");
gFindBar.toggleHighlight(false);
}
if(this.searchWP && typeof gSearchWP != "undefined") { // SearchWP 1
highlightBtn = document.getElementById("searchwp-highlight-button");
if(highlightBtn.checked) {
highlightBtn.checked = false;
gSearchWPOverlay.toggleHighlight(false);
}
}
if(this.searchWP && typeof searchwp != "undefined") { // SearchWP 2
highlightBtn = document.getElementById("searchwp-highlight-button");
if(highlightBtn.checked) {
highlightBtn.checked = false;
searchwp.Preferences.highlightMatchCase = false;
searchwp.Preferences.highlighted = false;
}
}
if(this.googlebarLite && typeof GBL_Listener != "undefined") { // Googlebar Lite
highlightBtn = document.getElementById("GBL-TB-Highlighter");
if(highlightBtn.checked)
GBL_ToggleHighlighting();
}
this.destroyHighlightScreen(null);
if(this.clickElement)
setTimeout(function(aEvent,self){
self.resendClickEvent(aEvent);
}, 1200, aEvent, this);
},
restoreHighlightScreen : function() {
if(this.fxVer == 3) { // Fx3
var findbar = document.getElementById("FindToolbar");
highlightBtn = document.getAnonymousElementByAttribute(findbar, "anonid", "highlight");
} else if(this.fxVer == 2) { // 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 : 500,
// version check
_fxVer : 0,
get fxVer() {
if(this._fxVer == 0) {
var appInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
if(appInfo.version.substr(0, 1) == "3") // Fx3
this._fxVer = 3;
else // Fx2
this._fxVer = 2;
}
return this._fxVer;
},
// getClickableElementFromPoint
// based on XUL/Migemo (http://piro.sakura.ne.jp/xul/_xulmigemo.html)
resendClickEvent : function(aEvent)
{
/*
var utils = aEvent.view
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
if ('sendMouseEvent' in utils) { // Firefox 3
var flags = 0;
const nsIDOMNSEvent = Components.interfaces.nsIDOMNSEvent;
if (aEvent.altKey) flags |= nsIDOMNSEvent.ALT_MARK;
if (aEvent.ctrlKey) flags |= nsIDOMNSEvent.CONTROL_MARK;
if (aEvent.shiftKey) flags |= nsIDOMNSEvent.SHIFT_MARK;
if (aEvent.metaKey) flags |= nsIDOMNSEvent.META_MARK;
window.setTimeout(function(aX, aY, aButton, flags) {
utils.sendMouseEvent('mousedown', aX, aY, aButton, 1, flags);
utils.sendMouseEvent('mouseup', aX, aY, aButton, 1, flags);
}, 0, aEvent.clientX, aEvent.clientY, aEvent.button, flags);
}
else { // Firefox 2, emulation
*/
var args = [
'click',
aEvent.bubbles,
aEvent.cancelable,
aEvent.view,
1,
aEvent.screenX,
aEvent.screenY,
aEvent.clientX,
aEvent.clientY,
aEvent.ctrlKey,
aEvent.altKey,
aEvent.shiftKey,
aEvent.metaKey,
aEvent.button
];
window.setTimeout(function(aSelf, aFrame, aX, aY) {
var node = aSelf.getClickableElementFromPoint(aFrame, aX, aY);
if(!node)
return;
var event = aFrame.document.createEvent('MouseEvents');
args.push(node);
event.initMouseEvent.apply(event, args);
node.dispatchEvent(event);
if('focus' in node)
node.focus();
}, 0, this, aEvent.view, aEvent.screenX, aEvent.screenY);
/*
}
*/
},
getClickableElementFromPoint : function(aWindow, aScreenX, aScreenY)
{
var accNode;
try {
var accService = Components.classes['@mozilla.org/accessibilityService;1']
.getService(Components.interfaces.nsIAccessibilityService);
var acc = accService.getAccessibleFor(aWindow.document);
var box = aWindow.document.getBoxObjectFor(aWindow.document.documentElement);
accNode = acc.getChildAtPoint(aScreenX, aScreenY);
accNode = accNode.QueryInterface(Components.interfaces.nsIAccessNode).DOMNode;
}
catch(e) {}
var filter = function(aNode) {
switch (aNode.localName.toUpperCase()) {
case 'A':
if(aNode.href)
return NodeFilter.FILTER_ACCEPT;
break;
case 'INPUT':
case 'TEXTAREA':
case 'BUTTON':
case 'SELECT':
return NodeFilter.FILTER_ACCEPT;
break;
}
return NodeFilter.FILTER_SKIP;
};
if(accNode &&
accNode.nodeType == Node.ELEMENT_NODE &&
filter(accNode) == NodeFilter.FILTER_ACCEPT)
return accNode;
var doc = aWindow.document;
var startNode = accNode || doc;
var walker = aWindow.document.createTreeWalker(startNode, NodeFilter.SHOW_ELEMENT, filter, false);
for(var node = walker.firstChild(); node != null; node = walker.nextNode()) {
var box = doc.getBoxObjectFor(node);
var l = box.screenX;
var t = box.screenY;
var r = l + box.width;
var b = t + box.height;
if(l <= aScreenX && aScreenX <= r && t <= aScreenY && aScreenY <= b)
return node;
}
return null;
}
};
(function() {
if(safariHighlight.searchWP && typeof searchwp != "undefined") { // SearchWP 2
try {
eval("searchwp.Highlighting.toggleHighlight = " +
searchwp.Highlighting.toggleHighlight.toSource().replace(
"if (searchwp.Preferences.highlighted && !searchwp.Preferences.highlightMatchCase) {",
"safariHighlight.initializeHighlightScreen();" +
"safariHighlight.toggleHighlightScreen(!searchwp.Preferences.highlighted || !searchwp.Preferences.highlightMatchCase);" +
"if (searchwp.Preferences.highlighted && !searchwp.Preferences.highlightMatchCase) {"));
} catch(e) {}
}
if(typeof XMigemoUI != "undefined") // XUL/Migemo
return;
var appInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
if(appInfo.version.substr(0, 1) == "3") { // 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.hitAnimation) {
eval("gFindBar._updateStatusUI = " +
gFindBar._updateStatusUI.toSource().replace(
"switch (res) {",
"if(arguments[0] != Components.interfaces.nsITypeAheadFind.FIND_NOTFOUND)" +
" safariHighlight.highlightFocusedFound();" +
"switch (res) {"));
}
} catch(e) {
window.addEventListener("load", function() {
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.hitAnimation) {
eval("gFindBar._updateStatusUI = " +
gFindBar._updateStatusUI.toSource().replace(
"switch (res) {",
"if(arguments[0] != Components.interfaces.nsITypeAheadFind.FIND_NOTFOUND)" +
" safariHighlight.highlightFocusedFound();" +
"switch (res) {"));
}
} catch(e) {}
}, false);
}
} else { // 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.hitAnimation) {
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(safariHighlight.searchWP && typeof gSearchWP != "undefined") { // SearchWP 1
try {
eval("gSearchWPOverlay.toggleHighlight = " +
gSearchWPOverlay.toggleHighlight.toSource().replace(
"gSearchWPHighlighting.toggleHighlight(aHighlight);",
"safariHighlight.initializeHighlightScreen();" +
"safariHighlight.toggleHighlightScreen(aHighlight);" +
"gSearchWPHighlighting.toggleHighlight(aHighlight);"));
} catch(e) {}
}
if(safariHighlight.googlebarLite && 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) {}
}
})(); |
|
|
|
1楼#
发布于:2010-08-10 00:04
楼主签名中的ff界面。
minefield按钮(不清楚是不是这名字),按钮,地址栏,状态栏按钮同在一排是怎么完成的? |
|
|
|
2楼#
发布于:2010-08-10 00:04
隔壁halffog已经修改了一个可用的。
|
|
|
3楼#
发布于:2010-08-10 00:04
把脚本里的两处appInfo.version.substr(0, 1) == "3"
替换成 appInfo.version.substr(0, 1) == "3" || appInfo.version.substr(0, 1) == "4" |
|
|
4楼#
发布于:2010-08-10 00:04
这个脚本最近好像又不行了,
在b10pre每夜版中, 搜索的时候,效果还能出来,不过紧接着firefox就失去响应了, 哪位再出手修理下吧 ,或者有类似的脚本给推荐个? |
|
|
