|
阅读:2710回复:6
大牛帮忙修复一下 附加组件页增强.uc ?
cc @lonely_8 或者其他大牛,帮忙看看这个能否修复?
// ==UserScript==
// @name AddonsPage.uc.js
// @description 附件组件页面右键新增查看所在目录,详细信息页面新增安装地址或路径,新增 uc脚本管理页面。
// @author ywzhaiqi
// @include main
// @charset utf-8
// @version 2018.06.27
// @downloadURL https://raw.github.com/ywzhaiqi/userChromeJS/master/AddonsPage/AddonsPage.uc.js
// @homepageURL https://github.com/ywzhaiqi/userChromeJS/tree/master/AddonsPage
// @reviewURL http://bbs.kafan.cn/thread-1617407-1-1.html
// @optionsURL about:config?filter=view_source.editor.path
// @note - 附件组件页面右键新增查看所在目录(支持扩展、主题、插件)、复制名字。Greasemonkey、Scriptish 自带已经存在
// @note - 附件组件详细信息页面新增GM脚本、扩展、主题安装地址和插件路径,右键即复制
// @note - 新增 uc脚本管理页面
// @note - 右键菜单 "查看附加组件" 需要 DOM Inspector
// @note - uc脚本管理界面
// @note - 启用禁用需要 rebuild_userChrome.uc.xul
// @note - 编辑命令需要首先设置 view_source.editor.path 的路径
// @note - 图标请自行添加样式,详细信息见主页
// @note 其它信息见主页
// ==/UserScript==
location.href.startsWith('chrome://browser/content/browser.x') && (function(){
var iconURL = ""; // uc Skriptlisten-Symbol
var Config = {
debug: 1, // 1 则uc管理界面右键菜单会有 "重载 uc 脚本" 的菜单
detailView: 1, // Auf Details-Seite Installation-Link hinzufügen
};
if(window.AM_Helper){ // Debugging ändern, neu laden ohne neu zu starten
window.AM_Helper.uninit();
delete window.AM_Helper;
}
if(window.userChromeJSAddon){
window.userChromeJSAddon.uninit();
delete window.userChromeJSAddon;
}
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/AddonManager.jsm");
let isCN = false;
try {
isCN = Services.prefs.getCharPref("general.useragent.locale").indexOf("zh") != -1;
} catch (e) {
try {
isCN = Services.prefs.getCharPref("intl.locale.requested").indexOf("zh") != -1;
} catch (e) {
}
}
var ApplyPatchForScript = (function(){
const USO_URL_RE = /(^https?:\/\/userscripts.org.*\/scripts\/source\/\d+)\.\w+\.js$/i;
const GFO_URL_RE_1 = /(^https?:\/\/greasyfork.org\/scripts\/code\/\w+)\.\w+\.js$/i;
const GFO_URL_RE_2 = /(^https?:\/\/greasyfork.org\/scripts\/[^\/]+\/)code[\.\/].*\w+\.js$/i;
// (http://binux.github.io/ThunderLixianExporter/)master/ThunderLixianExporter.user.js
const GITHUB_URL_RE_1 = /(^https?:\/\/\w+.github.io\/\w+\/)master\/.*.*\w+\.js$/i;
// 从 https://raw.githubusercontent.com/ywzhaiqi/userscript/master/noNoticetitleflashOnBBS.user.js
// 转为 https://github.com/ywzhaiqi/userscript/blob/master/noNoticetitleflashOnBBS.user.js
const GITHUB_URL_RE_2 = /(^https?:\/\/raw.githubusercontent.com\/.*?\/master\/.*\.user\.js$)/i;
function getScriptHomeURL(downURL) {
var url;
if (downURL && downURL.startsWith('http')) {
if (USO_URL_RE.test(downURL)) {
url = RegExp.$1.replace(/source/, "show");
} else if (GFO_URL_RE_1.test(downURL)) {
url = RegExp.$1;
} else if (GFO_URL_RE_2.test(downURL)) {
url = RegExp.$1;
} else if (GITHUB_URL_RE_1.test(downURL)) {
url = RegExp.$1;
} else if (GITHUB_URL_RE_2.test(downURL)) {
url = RegExp.$1.replace('raw.githubusercontent.com', 'github.com')
.replace('/master/', '/blob/master/');
}
}
return url ? decodeURIComponent(url) : null;
}
function addHomePage(){
// 添加 Scriptish 脚本的主页
if (window.Scriptish_config) {
Scriptish_config.scripts.forEach(function(script){
if(script.homepageURL) return;
var url = script.updateURL || script.downloadURL;
script.homepageURL = getScriptHomeURL(url);
});
}
// 添加 Greasemonkey 脚本的主页
AddonManager.getAddonsByTypes(['greasemonkey-user-script'], function (aAddons) {
aAddons.forEach(function (aAddon) {
if (aAddon.homepageURL) return;
var url = aAddon._script._downloadURL || aAddon._script._updateURL;
var homepageURL = getScriptHomeURL(url);
if (homepageURL) {
aAddon.homepageURL = homepageURL;
} else {
// console.log(aAddon.name, url);
}
});
});
}
return {
init: addHomePage
}
})();
setTimeout(function(){
ApplyPatchForScript.init();
}, 2000);
window.AM_Helper = {
init: function(){
document.addEventListener("DOMContentLoaded", this, false);
this.platformVersion = parseFloat(Services.appinfo.platformVersion);
},
uninit: function(){
document.removeEventListener("DOMContentLoaded", this, false);
},
handleEvent: function(event){
switch(event.type){
case "DOMContentLoaded":
var doc = event.target;
var win = doc.defaultView;
if (["about:addons","chrome://mozapps/content/extensions/extensions.xul"].indexOf(doc.URL) == -1)
return;
this.addPopupMenu(doc);
// 给菜单调用
win.AM_Helper = AM_Helper;
this.win = win;
if (Config.detailView) {
var self = this;
var observer = new MutationObserver(function(e) {
e = e[e.length-1];
if(e.attributeName == "loading") {
var doc = e.target.ownerDocument;
self.setUrlOrPath(doc);
}
});
observer.observe(doc.getElementById("detail-view"), {attributes: true});
}
break;
case "popupshowing":
if(this.win.document.popupNode){
this.getAddon(this.win.document.popupNode.value,
this.setItemsAttributes,
event);
}
break;
}
},
addPopupMenu: function(doc){
var ins = doc.getElementById("menuitem_uninstallItem");
if(!ins) return;
ins = ins.nextSibling;
var popup = ins.parentNode;
var menuitem = $C("menuseparator", {
id: "AM-separator-1"
}, doc);
popup.insertBefore(menuitem, ins);
menuitem = $C("menuitem", {
id: "AM-inspect-addon",
label: isCN ? "查看附加组件" : "Inspect Addon",
accesskey: "i",
tooltipText: isCN ? "调用 DOM Inspector 查看 addon 对象" : "Addon mit Dom Inspector inspizieren",
oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.inspectAddon);"
}, doc);
popup.insertBefore(menuitem, ins);
menuitem = $C("menuitem", {
id: "AM-edit-script",
label: isCN ? "编辑" : "Edit",
accesskey: "e",
hidden: true,
oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.editScript);"
}, doc);
popup.insertBefore(menuitem, ins);
menuitem = $C("menuitem", {
id: "AM-reload-uc",
hidden: true,
label: isCN ? "重载 uc 脚本(慎用)" : "Reload uc script",
style: "font-weight:bold",
tooltiptext: "仅部分脚本支持。如有问题,重启解决。",
oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.reloadUserChromeJS);"
}, doc);
popup.insertBefore(menuitem, ins);
menuitem = $C("menuitem", {
id: "AM-browse-dir",
label: isCN ? "查看所在目录" : "Browser Dir",
accesskey: "b",
oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.browseDir);"
}, doc);
popup.insertBefore(menuitem, ins);
menuitem = $C("menuitem", {
id: "AM-open-url",
label: isCN ? "打开安装页面" : "Open Install URL",
accesskey: "u",
tooltiptext: null,
oncommand: "openURL(this.tooltipText)",
}, doc);
popup.insertBefore(menuitem, ins);
menuitem = $C("menuitem", {
id: "AM-copy-name",
label: isCN ? "复制名称" : "Copy Name",
accesskey: "c",
oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.copyName);"
}, doc);
popup.insertBefore(menuitem, ins);
popup.addEventListener("popupshowing", this, true);
},
setItemsAttributes: function(aAddon, event){
var popup = event.target;
var doc = popup.ownerDocument;
var
isExtension = (aAddon.type == "extension"),
isTheme = (aAddon.type == "theme"),
isPlugin = (aAddon.type == "plugin"),
isUserStyle = (aAddon.type == "userstyle"),
isScriptish = (aAddon.type == "userscript"),
isGreasemonkey = (aAddon.type == "user-script") || // Greasemonkey
(aAddon.type == "greasemonkey-user-script"), // Greasemonkey 1.7+
isUserScript = isGreasemonkey || isScriptish,
isUserChromeJS = (aAddon.type == "userchromejs"),
isService = (aAddon.type == "service"),
menuitem
;
menuitem = doc.getElementById("AM-browse-dir");
menuitem.hidden = isUserStyle || isUserScript || isService;
menuitem = doc.getElementById("AM-edit-script");
menuitem.hidden = !isUserChromeJS;
menuitem = doc.getElementById("AM-reload-uc");
menuitem.hidden = !Config.debug || !isUserChromeJS || !aAddon.enabled;
if(Config.debug && isUserChromeJS && aAddon.hasError ){
menuitem.hidden = false;
}
var className = isGreasemonkey ? "greasemonkey" : "";
// install url
menuitem = doc.getElementById("AM-open-url");
var installURL = isExtension ?
(this.getInstallURL(aAddon) || aAddon.homepageURL) :
(aAddon.homepageURL || this.getInstallURL(aAddon));
menuitem.tooltipText = installURL;
menuitem.hidden = !installURL;
menuitem.className = installURL ? className : '';
menuitem = doc.getElementById("AM-inspect-addon");
menuitem.disabled = !("inspectObject" in window);
menuitem.className = menuitem.disabled ? '' : className;
menuitem = doc.getElementById("AM-copy-name");
menuitem.tooltipText = aAddon.name;
menuitem.className = className;
},
getPopupNode: function (aNode) {
var doc = aNode.ownerDocument;
return "triggerNode" in aNode.parentNode ? aNode.parentNode.triggerNode : doc.popupNode;
},
getAddon: function (aId, aCallback, aEvent) {
var self = this;
if (this.win.gDetailView._addon) {
aCallback.apply(this, [this.win.gDetailView._addon, aEvent]);
return;
}
(self.platformVersion < 61.0?
new Promise((resolve, reject) => AddonManager.getAllAddons(addons => resolve(addons))):
AddonManager.getAllAddons()
).then(addons => {
for (var i = 0; i < addons.length; i++) {
if (addons[i].id == aId) {
aCallback.apply(self, [addons[i], aEvent]);
return;
}
}
});
},
inspectAddon: function (aAddon) {
inspectObject(aAddon);
},
inspectUserscript: function (aAddon) {
inspectObject(aAddon._script);
},
browseDir: function (aAddon) {
switch(aAddon.type){
case "plugin":
var pathes = aAddon.pluginFullpath;
for (var i = 0; i < pathes.length; i++) {
this.revealPath(pathes[i]);
}
return;
case "userchromejs":
var file = aAddon._script.file;
if(file.exists())
file.reveal();
return;
}
// addon
var gecko = parseInt(Services.appinfo.platformVersion);
var nsLocalFile = Components.Constructor("@mozilla.org/file/local;1", (gecko >= 14) ? "nsIFile" : "nsILocalFile",
"initWithPath");
var dir = Services.dirsvc.get("ProfD", Ci.nsIFile);
dir.append("extensions");
dir.append(aAddon.id);
var fileOrDir = dir.path + (dir.exists() ? "" : ".xpi");
//Application.console.log(fileOrDir);
try {
(new nsLocalFile(fileOrDir)).reveal();
} catch (ex) {
var addonDir = /.xpi$/.test(fileOrDir) ? dir.parent : dir;
try {
if (addonDir.exists()) {
addonDir.launch();
}
} catch (ex) {
var uri = Services.io.newFileURI(addonDir);
var protSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
getService(Ci.nsIExternalProtocolService);
protSvc.loadUrl(uri);
}
}
},
editScript: function(aAddon) {
if(aAddon.type == "userchromejs"){
var path = aAddon._script.file.path;
this.launchEditor(path);
}
},
reloadUserChromeJS: function (aAddon) {
if(aAddon.type != "userchromejs") return;
var result = confirm("确定要重载吗?\n慎用,仅部分脚本支持,不支持的脚本会出现重复添加按钮或菜单或事件等问题。\n如有问题,重启火狐。");
if(!result) return;
var script = aAddon._script;
Services.obs.notifyObservers(null, "startupcache-invalidate", "");
Services.scriptloader.loadSubScript(script.url, {}, script.charset || "utf-8");
},
launchEditor: function(path){
var editor;
try{
editor = Services.prefs.getCharPref("view_source.editor.path","");
}catch(e){
}
if (!editor) {
var appfile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
appfile.initWithPath(path);
let spWin = window.openDialog("chrome://devtools/content/scratchpad/scratchpad.xul", "Toolkit:Scratchpad", "chrome,resizable=yes,centerscreen,dependent,width=1024,height=600");
spWin.top.moveTo(0, 0);
spWin.top.resizeTo(screen.availWidth, screen.availHeight);
spWin.addEventListener("load", function spWinLoaded() {
spWin.removeEventListener("load", spWinLoaded, false);
let Scratchpad = spWin.Scratchpad;
Scratchpad.setFilename(appfile.path);
Scratchpad.addObserver({
onReady: function () {
Scratchpad.removeObserver(this);
Scratchpad.importFromFile.call(Scratchpad, appfile);
}
});
}, false);
} else {
var UI = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Ci.nsIScriptableUnicodeConverter);
var platform = window.navigator.platform.toLowerCase();
UI.charset = platform.indexOf('win') > -1 ? 'GB2312' : 'UTF-8';
path = UI.ConvertFromUnicode(path);
var appfile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
appfile.initWithPath(editor);
var process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
process.init(appfile);
process.run(false, [path], 1, {});
}
},
copyName: function (aAddon) {
this.copyToClipboard(aAddon.name);
},
getInstallURL: function(aAddon){
aAddon = aAddon || this.win.gViewController.viewObjects.detail._addon;
if(!aAddon) return null;
var url = null;
switch(aAddon.type){
case "extension":
case "theme":
url = (aAddon.contributionURL || aAddon.reviewURL) || null;
return url && url.replace(/\/developers|\/reviews/g, "") || aAddon.creator.url;
case "greasemonkey-user-script":
return aAddon._script._downloadURL || aAddon._script._updateURL;
case "userscript":
url = aAddon._downloadURL || aAddon._updateURL;
return url;
case "userchromejs":
return aAddon.homepageURL || aAddon.reviewURL || aAddon.downloadURL || aAddon.updateURL;
default:
return aAddon.homepageURL;
}
},
get getPath(){
var url = this.win.gViewController.viewObjects.detail._addon;
if(!url) return false;
return url.pluginFullpath || false;
},
setUrlOrPath :function(doc){
var installURL = this.getInstallURL();
if (!installURL && !this.getPath) return;
if(!doc.getElementById("detail-InstallURL-row")){
var value = "",label = "";
if(this.win.gViewController.currentViewId.indexOf("detail")!= -1){
var aAddon = this.win.gViewController.viewObjects.detail._addon;
switch (aAddon.type){
case "extension":
case "theme":
case "greasemonkey-user-script":
value = installURL;
label = "%Installations-Seite%";
break;
case "plugin":
value = this.getPath;
label = "%Pfad%";
break;
}
}
if (!!value && !!label) {
const row = $C("row", {
id: "detail-InstallURL-row",
class: "detail-row-complex",
label: label,
});
row.appendChild($C("label", {
class: "detail-row-label",
value: label,
}));
if (typeof(value) != "string") {
const vbox = row.appendChild($C("vbox"));
for (var i=0;i< value.length;i++) {
vbox.appendChild($C("label", {
class: "detail-row-value text-link",
crop: "end",
value: value[i],
href: value[i],
onclick: `
if(event.button == 0) {
AM_Helper.revealPath(this.value);
} else if (event.button == 2){
AM_Helper.copyToClipboard(this.value);
}
return false;`,
}));
}
} else {
row.appendChild($C("label", {
class: "detail-row-value text-link",
crop: "end",
value: value,
href: value,
onclick: `
if(event.button == 2){
AM_Helper.copyToClipboard(this.value);
return false;
}`,
}));
}
doc.getElementById("detail-rows").appendChild(row);
}
}
},
revealPath: function(path){
var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
file.initWithPath(path);
if(file.exists())
file.reveal();
},
copyToClipboard: function (aString) {
Cc["@mozilla.org/widget/clipboardhelper;1"].
getService(Ci.nsIClipboardHelper).copyString(aString);
}
};
window.userChromeJSAddon = {
scripts:[],
unloads: [],
init: function(){
if ('userchromejs' in AddonManager.addonTypes) return;
this.initScripts();
this.registerProvider();
this.addStyle();
},
uninit: function(){
this.unloads.forEach(function(func){ func(); });
},
initScripts: function(){
var scripts = window.userChrome_js.scripts.concat(window.userChrome_js.overlays);
var self = this;
scripts.forEach(function(script, i){
self.scripts[i] = new ScriptAddon(script);
});
},
getScriptById: function(aId) {
for (var i = 0; i < this.scripts.length; i++) {
if(this.scripts[i].id == aId)
return this.scripts[i];
}
return null;
},
registerProvider: function(){
var types = null;
if (AddonManagerPrivate.AddonType) {
types = [new AddonManagerPrivate.AddonType(
"userchromejs",
"",
isCN ? "脚本" : "userChrome JS",
AddonManager.VIEW_TYPE_LIST,
9000)];
}
const provider = {
getAddonByID: function(aId, aCallback) {
let script = userChromeJSAddon.getScriptById(aId);
if (aCallback)
aCallback(script);
else
return Promise.resolve(script); // Fx61.0-
},
getAddonsByTypes: function(aTypes, aCallback) {
if (aTypes && aTypes.indexOf("userchromejs") < 0) {
if (aCallback)
aCallback([]);
else
return Promise.resolve([]);
} else {
if (aCallback)
aCallback(userChromeJSAddon.scripts);
else
return Promise.resolve(userChromeJSAddon.scripts);
}
}
};
AddonManagerPrivate.registerProvider(provider, types);
this.unloads.push(function(){
AddonManagerPrivate.unregisterProvider(provider);
});
},
addStyle: function(){
let data = '@namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);\
\
@-moz-document url("about:addons"), url("chrome://mozapps/content/extensions/extensions.xul") {\
#category-userchromejs > .category-icon {\
list-style-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAARklEQVQ4jWNgYGD4TyFm+L/uaBJezMDA8H+vgyEGHk4GEIPxGnBhdikKZmBg+P/vEyscjxrASjglEmPAvBMPMPBwMoASDADElRSk+LLlQAAAAABJRU5ErkJggg==);\
}\
}';
let styleService = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
let styleURI = Services.io.newURI("data:text/css," + encodeURIComponent(data), null, null);
styleService.loadAndRegisterSheet(styleURI, Ci.nsIStyleSheetService.USER_SHEET);
this.unloads.push(function(){
styleService.unregisterSheet(styleURI, Ci.nsIStyleSheetService.USER_SHEET);
});
},
};
function AddonAuthor(aName, aURL) {
this.name = aName;
this.url = aURL;
}
AddonAuthor.prototype = {
name: null,
url: null,
// Returns the author's name, defaulting to the empty string
toString() {
return this.name || "";
}
};
function ScriptAddon(aScript) {
this._script = aScript;
this.id = this._script.url;
this.name = this._script.filename;
this.description = this._script.description;
this.enabled = !userChrome_js.scriptDisable[this.name];
// userChrome.js 新增的
this.version = this._script.version || null;
this.creator = this._script.author? new AddonAuthor(this._script.author,this._script.namespace):"";
this.homepageURL = this._script.homepageURL || null;
this.reviewURL = this._script.reviewURL || null;
this.reviewCount = 0;
this.fullDescription = this._script.fullDescription || null;
this.downloadURL = this._script.downloadURL || null;
this.optionsURL = this._script.optionsURL || null;
this.iconURL = this._script.iconURL || iconURL;
//this.updateDate = new Date(this._script.lastModifiedTime) || null;
this.hasError = false;
if(typeof this._script.haserror !="undefined"){
this.hasError = this._script.haserror;
}
if(this.hasError){
this.enabled = false;
this.name = this.name + "(脚本运行错误)";
}
}
ScriptAddon.prototype = {
version: null,
type: "userchromejs",
isCompatible: true,
blocklistState: 0,
appDisabled: false,
scope: AddonManager.SCOPE_PROFILE,
name: null,
creator: null,
pendingOperations: AddonManager.PENDING_NONE, // 必须,否则所有都显示 restart
operationsRequiringRestart: 6,
// operationsRequiringRestart: AddonManager.OP_NEEDS_RESTART_DISABLE,
get optionsURL(){
if (this.isActive && this._script.optionsURL)
return this._script.optionsURL;
},
get isActive() {
return !this.userDisabled? true: false;
},
get userDisabled() {
return !this.enabled? true: false;
},
set userDisabled(val) {
if (val == this.userDisabled) {
return val;
}
AddonManagerPrivate.callAddonListeners(val ? 'onEnabling' : 'onDisabling', this, false);
var needRunMethod = false;
if(val){//disabled
//有 shutdown 方法或者需要重启生效的,直接禁用
if(this._script.shutdown||this.pendingOperations == AddonManager.PENDING_ENABLE){
//非重启生效的,需要运行shutdown方法
needRunMethod = this.pendingOperations == AddonManager.PENDING_NONE;
this.pendingOperations = AddonManager.PENDING_NONE;
}else{
this.pendingOperations = AddonManager.PENDING_DISABLE;
}
}else {
//有 startup 方法或者需要重启失效的,直接启用
if(this._script.startup || this.pendingOperations == AddonManager.PENDING_DISABLE){
//非重启失效的,需要运行 startup 方法
needRunMethod = this.pendingOperations == AddonManager.PENDING_NONE;
this.pendingOperations = AddonManager.PENDING_NONE;
}else{
this.pendingOperations = AddonManager.PENDING_ENABLE;
}
}
this.enabled = !val;
//if (window.userChrome_js && window.userChrome_js.chgScriptStat) {
// window.userChrome_js.chgScriptStat(this.name,needRunMethod);
//}
if(window.userChromejs){
userChromejs.chgScriptStat(this.name);
}
AddonManagerPrivate.callAddonListeners(val ? 'onEnabled' : 'onDisabled', this);
},
get permissions() {
// var perms = AddonManager.PERM_CAN_UNINSTALL;
// perms |= this.userDisabled ? AddonManager.PERM_CAN_ENABLE : AddonManager.PERM_CAN_DISABLE;
var perms;
if(this.hasError){
perms = "";
}else{
perms = this.userDisabled ? AddonManager.PERM_CAN_ENABLE : AddonManager.PERM_CAN_DISABLE;
}
// if (this.updateURL) perms |= AddonManager.PERM_CAN_UPGRADE;
return perms;
},
uninstall: function() {
AddonManagerPrivate.callAddonListeners("onUninstalling", this, false);
this.needsUninstall = true;
this.pendingOperations |= AddonManager.PENDING_UNINSTALL;
AddonManagerPrivate.callAddonListeners("onUninstalled", this);
},
cancelUninstall: function() {
this.needsUninstall = false;
this.pendingOperations ^= AddonManager.PENDING_UNINSTALL;
AddonManagerPrivate.callAddonListeners("onOperationCancelled", this);
},
// Fx62.0-
enable: function() {
this.userDisabled = false;
},
disable: function() {
this.userDisabled = true;
}
};
AM_Helper.init();
//延迟初始化,保证其他脚本已加载
setTimeout(function () {
if(window.userChrome_js){
userChromeJSAddon.init();
}
},1000);
function $C(name, attr, doc) {
var el = (doc || document).createXULElement(name);
if (attr) Object.keys(attr).forEach(function(n){ el.setAttribute(n, attr[n])});
return el;
}
})(); |
|
|
1楼#
发布于:2020-05-09 12:16
修复不了就算了
|
|
|
2楼#
发布于:2020-05-09 16:39
扩展页已经大改版,很难改回去了。
|
|
|
3楼#
发布于:2020-05-09 17:12
|
|
|
4楼#
发布于:2020-05-09 17:42
// ==UserScript==
// @name AddonsPage.uc.js
// @description 附件组件页面右键新增查看所在目录,详细信息页面新增安装地址或路径,新增 uc脚本管理页面。
// @author ywzhaiqi
// @include main
// @charset utf-8
// @version 2018.06.27
// @downloadURL https://raw.github.com/ywzhaiqi/userChromeJS/master/AddonsPage/AddonsPage.uc.js
// @homepageURL https://github.com/ywzhaiqi/userChromeJS/tree/master/AddonsPage
// @reviewURL http://bbs.kafan.cn/thread-1617407-1-1.html
// @optionsURL about:config?filter=view_source.editor.path
// @note - 附件组件页面右键新增查看所在目录(支持扩展、主题、插件)、复制名字。Greasemonkey、Scriptish 自带已经存在
// @note - 附件组件详细信息页面新增GM脚本、扩展、主题安装地址和插件路径,右键即复制
// @note - 新增 uc脚本管理页面
// @note - 右键菜单 "查看附加组件" 需要 DOM Inspector
// @note - uc脚本管理界面
// @note - 启用禁用需要 rebuild_userChrome.uc.xul
// @note - 编辑命令需要首先设置 view_source.editor.path 的路径
// @note - 图标请自行添加样式,详细信息见主页
// @note 其它信息见主页
// ==/UserScript==
location.href.startsWith('chrome://browser/content/browser.x') && (function(){
var iconURL = ""; // uc Skriptlisten-Symbol
var Config = {
debug: 1, // 1 则uc管理界面右键菜单会有 "重载 uc 脚本" 的菜单
detailView: 1, // Auf Details-Seite Installation-Link hinzufügen
};
if(window.AM_Helper){ // Debugging ändern, neu laden ohne neu zu starten
window.AM_Helper.uninit();
delete window.AM_Helper;
}
if(window.userChromeJSAddon){
window.userChromeJSAddon.uninit();
delete window.userChromeJSAddon;
}
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/AddonManager.jsm");
let isCN = false;
try {
isCN = Services.prefs.getCharPref("general.useragent.locale").indexOf("zh") != -1;
} catch (e) {
try {
isCN = Services.prefs.getCharPref("intl.locale.requested").indexOf("zh") != -1;
} catch (e) {
isCN = Services.locale.appLocaleAsBCP47.indexOf("zh") != -1;
}
}
var ApplyPatchForScript = (function(){
const USO_URL_RE = /(^https?:\/\/userscripts.org.*\/scripts\/source\/\d+)\.\w+\.js$/i;
const GFO_URL_RE_1 = /(^https?:\/\/greasyfork.org\/scripts\/code\/\w+)\.\w+\.js$/i;
const GFO_URL_RE_2 = /(^https?:\/\/greasyfork.org\/scripts\/[^\/]+\/)code[\.\/].*\w+\.js$/i;
// (http://binux.github.io/ThunderLixianExporter/)master/ThunderLixianExporter.user.js
const GITHUB_URL_RE_1 = /(^https?:\/\/\w+.github.io\/\w+\/)master\/.*.*\w+\.js$/i;
// 从 https://raw.githubusercontent.com/ywzhaiqi/userscript/master/noNoticetitleflashOnBBS.user.js
// 转为 https://github.com/ywzhaiqi/userscript/blob/master/noNoticetitleflashOnBBS.user.js
const GITHUB_URL_RE_2 = /(^https?:\/\/raw.githubusercontent.com\/.*?\/master\/.*\.user\.js$)/i;
function getScriptHomeURL(downURL) {
var url;
if (downURL && downURL.startsWith('http')) {
if (USO_URL_RE.test(downURL)) {
url = RegExp.$1.replace(/source/, "show");
} else if (GFO_URL_RE_1.test(downURL)) {
url = RegExp.$1;
} else if (GFO_URL_RE_2.test(downURL)) {
url = RegExp.$1;
} else if (GITHUB_URL_RE_1.test(downURL)) {
url = RegExp.$1;
} else if (GITHUB_URL_RE_2.test(downURL)) {
url = RegExp.$1.replace('raw.githubusercontent.com', 'github.com')
.replace('/master/', '/blob/master/');
}
}
return url ? decodeURIComponent(url) : null;
}
function addHomePage(){
// 添加 Scriptish 脚本的主页
if (window.Scriptish_config) {
Scriptish_config.scripts.forEach(function(script){
if(script.homepageURL) return;
var url = script.updateURL || script.downloadURL;
script.homepageURL = getScriptHomeURL(url);
});
}
// 添加 Greasemonkey 脚本的主页
AddonManager.getAddonsByTypes(['greasemonkey-user-script'], function (aAddons) {
aAddons.forEach(function (aAddon) {
if (aAddon.homepageURL) return;
var url = aAddon._script._downloadURL || aAddon._script._updateURL;
var homepageURL = getScriptHomeURL(url);
if (homepageURL) {
aAddon.homepageURL = homepageURL;
} else {
// console.log(aAddon.name, url);
}
});
});
}
return {
init: addHomePage
}
})();
setTimeout(function(){
ApplyPatchForScript.init();
}, 2000);
window.AM_Helper = {
init: function(){
document.addEventListener("DOMContentLoaded", this, false);
this.platformVersion = parseFloat(Services.appinfo.platformVersion);
},
uninit: function(){
document.removeEventListener("DOMContentLoaded", this, false);
},
handleEvent: function(event){
switch(event.type){
case "DOMContentLoaded":
var doc = event.target;
var win = doc.defaultView;
if (["about:addons","chrome://mozapps/content/extensions/extensions.xul"].indexOf(doc.URL) == -1)
return;
this.addPopupMenu(doc);
// 给菜单调用
win.AM_Helper = AM_Helper;
this.win = win;
if (Config.detailView) {
var self = this;
var observer = new MutationObserver(function(e) {
e = e[e.length-1];
if(e.attributeName == "loading") {
var doc = e.target.ownerDocument;
self.setUrlOrPath(doc);
}
});
observer.observe(doc.getElementById("detail-view"), {attributes: true});
}
break;
case "popupshowing":
if(this.win.document.popupNode){
this.getAddon(this.win.document.popupNode.value,
this.setItemsAttributes,
event);
}
break;
}
},
addPopupMenu: function(doc){
var ins = doc.getElementById("menuitem_uninstallItem");
if(!ins) return;
ins = ins.nextSibling;
var popup = ins.parentNode;
var menuitem = $C("menuseparator", {
id: "AM-separator-1"
}, doc);
popup.insertBefore(menuitem, ins);
menuitem = $C("menuitem", {
id: "AM-inspect-addon",
label: isCN ? "查看附加组件" : "Inspect Addon",
accesskey: "i",
tooltipText: isCN ? "调用 DOM Inspector 查看 addon 对象" : "Addon mit Dom Inspector inspizieren",
oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.inspectAddon);"
}, doc);
popup.insertBefore(menuitem, ins);
menuitem = $C("menuitem", {
id: "AM-edit-script",
label: isCN ? "编辑" : "Edit",
accesskey: "e",
hidden: true,
oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.editScript);"
}, doc);
popup.insertBefore(menuitem, ins);
menuitem = $C("menuitem", {
id: "AM-reload-uc",
hidden: true,
label: isCN ? "重载 uc 脚本(慎用)" : "Reload uc script",
style: "font-weight:bold",
tooltiptext: "仅部分脚本支持。如有问题,重启解决。",
oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.reloadUserChromeJS);"
}, doc);
popup.insertBefore(menuitem, ins);
menuitem = $C("menuitem", {
id: "AM-browse-dir",
label: isCN ? "查看所在目录" : "Browser Dir",
accesskey: "b",
oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.browseDir);"
}, doc);
popup.insertBefore(menuitem, ins);
menuitem = $C("menuitem", {
id: "AM-open-url",
label: isCN ? "打开安装页面" : "Open Install URL",
accesskey: "u",
tooltiptext: null,
oncommand: "openURL(this.tooltipText)",
}, doc);
popup.insertBefore(menuitem, ins);
menuitem = $C("menuitem", {
id: "AM-copy-name",
label: isCN ? "复制名称" : "Copy Name",
accesskey: "c",
oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.copyName);"
}, doc);
popup.insertBefore(menuitem, ins);
popup.addEventListener("popupshowing", this, true);
},
setItemsAttributes: function(aAddon, event){
var popup = event.target;
var doc = popup.ownerDocument;
var
isExtension = (aAddon.type == "extension"),
isTheme = (aAddon.type == "theme"),
isPlugin = (aAddon.type == "plugin"),
isUserStyle = (aAddon.type == "userstyle"),
isScriptish = (aAddon.type == "userscript"),
isGreasemonkey = (aAddon.type == "user-script") || // Greasemonkey
(aAddon.type == "greasemonkey-user-script"), // Greasemonkey 1.7+
isUserScript = isGreasemonkey || isScriptish,
isUserChromeJS = (aAddon.type == "userchromejs"),
isService = (aAddon.type == "service"),
menuitem
;
menuitem = doc.getElementById("AM-browse-dir");
menuitem.hidden = isUserStyle || isUserScript || isService;
menuitem = doc.getElementById("AM-edit-script");
menuitem.hidden = !isUserChromeJS;
menuitem = doc.getElementById("AM-reload-uc");
menuitem.hidden = !Config.debug || !isUserChromeJS || !aAddon.enabled;
if(Config.debug && isUserChromeJS && aAddon.hasError ){
menuitem.hidden = false;
}
var className = isGreasemonkey ? "greasemonkey" : "";
// install url
menuitem = doc.getElementById("AM-open-url");
var installURL = isExtension ?
(this.getInstallURL(aAddon) || aAddon.homepageURL) :
(aAddon.homepageURL || this.getInstallURL(aAddon));
menuitem.tooltipText = installURL;
menuitem.hidden = !installURL;
menuitem.className = installURL ? className : '';
menuitem = doc.getElementById("AM-inspect-addon");
menuitem.disabled = !("inspectObject" in window);
menuitem.className = menuitem.disabled ? '' : className;
menuitem = doc.getElementById("AM-copy-name");
menuitem.tooltipText = aAddon.name;
menuitem.className = className;
},
getPopupNode: function (aNode) {
var doc = aNode.ownerDocument;
return "triggerNode" in aNode.parentNode ? aNode.parentNode.triggerNode : doc.popupNode;
},
getAddon: function (aId, aCallback, aEvent) {
var self = this;
if (this.win.gDetailView._addon) {
aCallback.apply(this, [this.win.gDetailView._addon, aEvent]);
return;
}
(self.platformVersion < 61.0?
new Promise((resolve, reject) => AddonManager.getAllAddons(addons => resolve(addons))):
AddonManager.getAllAddons()
).then(addons => {
for (var i = 0; i < addons.length; i++) {
if (addons[i].id == aId) {
aCallback.apply(self, [addons[i], aEvent]);
return;
}
}
});
},
inspectAddon: function (aAddon) {
inspectObject(aAddon);
},
inspectUserscript: function (aAddon) {
inspectObject(aAddon._script);
},
browseDir: function (aAddon) {
switch(aAddon.type){
case "plugin":
var pathes = aAddon.pluginFullpath;
for (var i = 0; i < pathes.length; i++) {
this.revealPath(pathes[i]);
}
return;
case "userchromejs":
var file = aAddon._script.file;
if(file.exists())
file.reveal();
return;
}
// addon
var gecko = parseInt(Services.appinfo.platformVersion);
var nsLocalFile = Components.Constructor("@mozilla.org/file/local;1", (gecko >= 14) ? "nsIFile" : "nsILocalFile",
"initWithPath");
var dir = Services.dirsvc.get("ProfD", Ci.nsIFile);
dir.append("extensions");
dir.append(aAddon.id);
var fileOrDir = dir.path + (dir.exists() ? "" : ".xpi");
//Application.console.log(fileOrDir);
try {
(new nsLocalFile(fileOrDir)).reveal();
} catch (ex) {
var addonDir = /.xpi$/.test(fileOrDir) ? dir.parent : dir;
try {
if (addonDir.exists()) {
addonDir.launch();
}
} catch (ex) {
var uri = Services.io.newFileURI(addonDir);
var protSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
getService(Ci.nsIExternalProtocolService);
protSvc.loadUrl(uri);
}
}
},
editScript: function(aAddon) {
if(aAddon.type == "userchromejs"){
var path = aAddon._script.file.path;
this.launchEditor(path);
}
},
reloadUserChromeJS: function (aAddon) {
if(aAddon.type != "userchromejs") return;
var result = confirm("确定要重载吗?\n慎用,仅部分脚本支持,不支持的脚本会出现重复添加按钮或菜单或事件等问题。\n如有问题,重启火狐。");
if(!result) return;
var script = aAddon._script;
Services.obs.notifyObservers(null, "startupcache-invalidate", "");
Services.scriptloader.loadSubScript(script.url, {}, script.charset || "utf-8");
},
launchEditor: function(path){
var editor;
try{
editor = Services.prefs.getCharPref("view_source.editor.path","");
}catch(e){
}
if (!editor) {
var appfile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
appfile.initWithPath(path);
let spWin = window.openDialog("chrome://devtools/content/scratchpad/scratchpad.xul", "Toolkit:Scratchpad", "chrome,resizable=yes,centerscreen,dependent,width=1024,height=600");
spWin.top.moveTo(0, 0);
spWin.top.resizeTo(screen.availWidth, screen.availHeight);
spWin.addEventListener("load", function spWinLoaded() {
spWin.removeEventListener("load", spWinLoaded, false);
let Scratchpad = spWin.Scratchpad;
Scratchpad.setFilename(appfile.path);
Scratchpad.addObserver({
onReady: function () {
Scratchpad.removeObserver(this);
Scratchpad.importFromFile.call(Scratchpad, appfile);
}
});
}, false);
} else {
var UI = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Ci.nsIScriptableUnicodeConverter);
var platform = window.navigator.platform.toLowerCase();
UI.charset = platform.indexOf('win') > -1 ? 'GB2312' : 'UTF-8';
path = UI.ConvertFromUnicode(path);
var appfile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
appfile.initWithPath(editor);
var process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
process.init(appfile);
process.run(false, [path], 1, {});
}
},
copyName: function (aAddon) {
this.copyToClipboard(aAddon.name);
},
getInstallURL: function(aAddon){
aAddon = aAddon || this.win.gViewController.viewObjects.detail._addon;
if(!aAddon) return null;
var url = null;
switch(aAddon.type){
case "extension":
case "theme":
url = (aAddon.contributionURL || aAddon.reviewURL) || null;
return url && url.replace(/\/developers|\/reviews/g, "") || aAddon.creator.url;
case "greasemonkey-user-script":
return aAddon._script._downloadURL || aAddon._script._updateURL;
case "userscript":
url = aAddon._downloadURL || aAddon._updateURL;
return url;
case "userchromejs":
return aAddon.homepageURL || aAddon.reviewURL || aAddon.downloadURL || aAddon.updateURL;
default:
return aAddon.homepageURL;
}
},
get getPath(){
var url = this.win.gViewController.viewObjects.detail._addon;
if(!url) return false;
return url.pluginFullpath || false;
},
setUrlOrPath :function(doc){
var installURL = this.getInstallURL();
if (!installURL && !this.getPath) return;
if(!doc.getElementById("detail-InstallURL-row")){
var value = "",label = "";
if(this.win.gViewController.currentViewId.indexOf("detail")!= -1){
var aAddon = this.win.gViewController.viewObjects.detail._addon;
switch (aAddon.type){
case "extension":
case "theme":
case "greasemonkey-user-script":
value = installURL;
label = "%Installations-Seite%";
break;
case "plugin":
value = this.getPath;
label = "%Pfad%";
break;
}
}
if (!!value && !!label) {
const row = $C("row", {
id: "detail-InstallURL-row",
class: "detail-row-complex",
label: label,
});
row.appendChild($C("label", {
class: "detail-row-label",
value: label,
}));
if (typeof(value) != "string") {
const vbox = row.appendChild($C("vbox"));
for (var i=0;i< value.length;i++) {
vbox.appendChild($C("label", {
class: "detail-row-value text-link",
crop: "end",
value: value[i],
href: value[i],
onclick: `
if(event.button == 0) {
AM_Helper.revealPath(this.value);
} else if (event.button == 2){
AM_Helper.copyToClipboard(this.value);
}
return false;`,
}));
}
} else {
row.appendChild($C("label", {
class: "detail-row-value text-link",
crop: "end",
value: value,
href: value,
onclick: `
if(event.button == 2){
AM_Helper.copyToClipboard(this.value);
return false;
}`,
}));
}
doc.getElementById("detail-rows").appendChild(row);
}
}
},
revealPath: function(path){
var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
file.initWithPath(path);
if(file.exists())
file.reveal();
},
copyToClipboard: function (aString) {
Cc["@mozilla.org/widget/clipboardhelper;1"].
getService(Ci.nsIClipboardHelper).copyString(aString);
}
};
window.userChromeJSAddon = {
scripts:[],
unloads: [],
init: function(){
if ('userchromejs' in AddonManager.addonTypes) return;
this.initScripts();
document.addEventListener('DOMContentLoaded', (event) => {
if(event.target.location.href != 'chrome://mozapps/content/extensions/aboutaddons.html') return;
const doc = event.target;
this.addCategoryButton(doc);
const main = doc.getElementById('main');
if(main){
const observer = new doc.defaultView.MutationObserver((m) => {
if(!doc.querySelector('addon-list[type="userchromejs"]'))
return;
doc.querySelector('.header-name').textContent = isCN ? "管理您的脚本" : "Manage Yors userChromeJSs";
for(const addonCard of doc.querySelectorAll('addon-card')){
this.addToggleButton(doc, addonCard);
}
});
observer.observe(main, {childList: true});
}
}, false);
this.registerProvider();
this.addStyle();
},
addCategoryButton: function(doc) {
const pcb = doc.querySelector('button.category[name="plugin"]');
if(!pcb) return;
doc.defaultView.setTimeout(() => {
const isSelected = !doc.querySelector('button.category[aria-selected="true"]');
const scb = pcb.cloneNode(true);
scb.setAttribute('viewid', 'addons://list/userchromejs');
scb.setAttribute('name', 'userchromejs');
scb.toggleAttribute('selected', isSelected);
scb.setAttribute('aria-selected', isSelected);
scb.firstElementChild.removeAttribute('data-l10n-id');
scb.firstElementChild.textContent = isCN ? "脚本" : "userChrome JS";
pcb.after(scb);
if(isSelected){
pcb.click();
doc.defaultView.setTimeout(() => {
scb.click();
}, 0);
}
}, 0);
},
addToggleButton: function (doc, addonCard) {
if(addonCard.querySelector('panel-item[action="toggle-disabled"]'))
return;
const moreBtn = addonCard.querySelector('.more-options-button');
if(!moreBtn) return;
const toggleButton = doc.createElement('input');
toggleButton.type = 'checkbox';
toggleButton.className = 'toggle-button extension-enable-button';
toggleButton.setAttribute('action', 'toggle-disabled');
moreBtn.before(toggleButton);
const _update = addonCard.update;
if(typeof _update === 'function'){
const updateToggleButton = function () {
if(this.addon && this.addon.type === 'userchromejs'){
const toggleButton = this.card.querySelector('input.toggle-button');
toggleButton.checked = !this.addon.userDisabled;
const toggleDisabledAction = toggleButton.checked ? 'enable' : 'disable';
this.card.ownerDocument.l10n.setAttributes(
toggleButton,
`${toggleDisabledAction}-addon-button-label`
);
}
}
addonCard.update = function (...args) {
const rt = _update.apply(this, args);
updateToggleButton.call(this);
return rt;
}
updateToggleButton.call(addonCard);
}
},
uninit: function(){
this.unloads.forEach(function(func){ func(); });
},
initScripts: function(){
var scripts = window.userChrome_js.scripts.concat(window.userChrome_js.overlays);
var self = this;
scripts.forEach(function(script, i){
self.scripts[i] = new ScriptAddon(script);
});
},
getScriptById: function(aId) {
for (var i = 0; i < this.scripts.length; i++) {
if(this.scripts[i].id == aId)
return this.scripts[i];
}
return null;
},
registerProvider: function(){
var types = null;
if (AddonManagerPrivate.AddonType) {
types = [new AddonManagerPrivate.AddonType(
"userchromejs",
"",
isCN ? "脚本" : "userChrome JS",
AddonManager.VIEW_TYPE_LIST,
9000)];
}
const provider = {
getAddonByID: function(aId, aCallback) {
let script = userChromeJSAddon.getScriptById(aId);
if (aCallback)
aCallback(script);
else
return Promise.resolve(script); // Fx61.0-
},
getAddonsByTypes: function(aTypes, aCallback) {
if (aTypes && aTypes.indexOf("userchromejs") < 0) {
if (aCallback)
aCallback([]);
else
return Promise.resolve([]);
} else {
if (aCallback)
aCallback(userChromeJSAddon.scripts);
else
return Promise.resolve(userChromeJSAddon.scripts);
}
}
};
AddonManagerPrivate.registerProvider(provider, types);
this.unloads.push(function(){
AddonManagerPrivate.unregisterProvider(provider);
});
},
addStyle: function(){
let data = '\
@-moz-document url("about:addons"), url("chrome://mozapps/content/extensions/extensions.xul"), url("chrome://mozapps/content/extensions/aboutaddons.html") {\
.category[name="userchromejs"] {\
background-image: url(chrome://devtools/skin/images/tool-styleeditor.svg);\
}\
#category-userchromejs > .category-icon {\
list-style-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAARklEQVQ4jWNgYGD4TyFm+L/uaBJezMDA8H+vgyEGHk4GEIPxGnBhdikKZmBg+P/vEyscjxrASjglEmPAvBMPMPBwMoASDADElRSk+LLlQAAAAABJRU5ErkJggg==);\
}\
}';
let styleService = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
let styleURI = Services.io.newURI("data:text/css," + encodeURIComponent(data), null, null);
styleService.loadAndRegisterSheet(styleURI, Ci.nsIStyleSheetService.USER_SHEET);
this.unloads.push(function(){
styleService.unregisterSheet(styleURI, Ci.nsIStyleSheetService.USER_SHEET);
});
},
};
function AddonAuthor(aName, aURL) {
this.name = aName;
this.url = aURL;
}
AddonAuthor.prototype = {
name: null,
url: null,
// Returns the author's name, defaulting to the empty string
toString() {
return this.name || "";
}
};
function ScriptAddon(aScript) {
this._script = aScript;
this.id = this._script.filename;
this.name = this._script.filename;
this.description = this._script.description;
this.enabled = !userChrome_js.scriptDisable[this.name];
// userChrome.js 新增的
this.version = this._script.version || null;
this.creator = this._script.author? new AddonAuthor(this._script.author,this._script.namespace):"";
this.homepageURL = this._script.homepageURL || null;
this.reviewURL = this._script.reviewURL || null;
this.reviewCount = 0;
this.fullDescription = this._script.fullDescription || null;
this.downloadURL = this._script.downloadURL || null;
this.optionsURL = this._script.optionsURL || null;
this.iconURL = this._script.iconURL || iconURL;
//this.updateDate = new Date(this._script.lastModifiedTime) || null;
this.hasError = false;
if(typeof this._script.haserror !="undefined"){
this.hasError = this._script.haserror;
}
if(this.hasError){
this.enabled = false;
this.name = this.name + "(脚本运行错误)";
}
}
ScriptAddon.prototype = {
version: null,
type: "userchromejs",
isCompatible: true,
blocklistState: 0,
appDisabled: false,
scope: AddonManager.SCOPE_PROFILE,
name: null,
creator: null,
pendingOperations: AddonManager.PENDING_NONE, // 必须,否则所有都显示 restart
operationsRequiringRestart: 6,
// operationsRequiringRestart: AddonManager.OP_NEEDS_RESTART_DISABLE,
get optionsURL(){
if (this.isActive && this._script.optionsURL)
return this._script.optionsURL;
},
get isActive() {
return !this.userDisabled? true: false;
},
get userDisabled() {
return !this.enabled? true: false;
},
set userDisabled(val) {
if (val == this.userDisabled) {
return val;
}
AddonManagerPrivate.callAddonListeners(val ? 'onEnabling' : 'onDisabling', this, false);
var needRunMethod = false;
if(val){//disabled
//有 shutdown 方法或者需要重启生效的,直接禁用
if(this._script.shutdown||this.pendingOperations == AddonManager.PENDING_ENABLE){
//非重启生效的,需要运行shutdown方法
needRunMethod = this.pendingOperations == AddonManager.PENDING_NONE;
this.pendingOperations = AddonManager.PENDING_NONE;
}else{
this.pendingOperations = AddonManager.PENDING_DISABLE;
}
}else {
//有 startup 方法或者需要重启失效的,直接启用
if(this._script.startup || this.pendingOperations == AddonManager.PENDING_DISABLE){
//非重启失效的,需要运行 startup 方法
needRunMethod = this.pendingOperations == AddonManager.PENDING_NONE;
this.pendingOperations = AddonManager.PENDING_NONE;
}else{
this.pendingOperations = AddonManager.PENDING_ENABLE;
}
}
this.enabled = !val;
//if (window.userChrome_js && window.userChrome_js.chgScriptStat) {
// window.userChrome_js.chgScriptStat(this.name,needRunMethod);
//}
if(window.userChromejs){
userChromejs.chgScriptStat(this.name);
}
AddonManagerPrivate.callAddonListeners(val ? 'onEnabled' : 'onDisabled', this);
},
get permissions() {
// var perms = AddonManager.PERM_CAN_UNINSTALL;
// perms |= this.userDisabled ? AddonManager.PERM_CAN_ENABLE : AddonManager.PERM_CAN_DISABLE;
var perms;
if(this.hasError){
perms = "";
}else{
perms = this.userDisabled ? AddonManager.PERM_CAN_ENABLE : AddonManager.PERM_CAN_DISABLE;
}
// if (this.updateURL) perms |= AddonManager.PERM_CAN_UPGRADE;
return perms;
},
uninstall: function() {
AddonManagerPrivate.callAddonListeners("onUninstalling", this, false);
this.needsUninstall = true;
this.pendingOperations |= AddonManager.PENDING_UNINSTALL;
AddonManagerPrivate.callAddonListeners("onUninstalled", this);
},
cancelUninstall: function() {
this.needsUninstall = false;
this.pendingOperations ^= AddonManager.PENDING_UNINSTALL;
AddonManagerPrivate.callAddonListeners("onOperationCancelled", this);
},
// Fx62.0-
enable: function() {
this.userDisabled = false;
},
disable: function() {
this.userDisabled = true;
}
};
AM_Helper.init();
//延迟初始化,保证其他脚本已加载
setTimeout(function () {
if(window.userChrome_js){
userChromeJSAddon.init();
}
},1000);
function $C(name, attr, doc) {
var el = (doc || document).createXULElement(name);
if (attr) Object.keys(attr).forEach(function(n){ el.setAttribute(n, attr[n])});
return el;
}
})();
显示 uc 脚本勉强能救活,至于脚本前面的能(右键菜单?)就没办法了,新版扩展页无右键功能。 |
|
|
5楼#
发布于:2020-05-09 21:16
赞
|
|
|
6楼#
发布于:2020-05-10 14:38
lonely_8:// ==UserScript==大神能帮忙修复一下BMMultiColumn脚本吗?其他都还好,就这个多栏书签离不了,或者有什么更好的方法,CSS能做到自适应吗 https://www.firefox.net.cn/read-121616 |
|