teruimisu
小狐狸
小狐狸
  • UID57823
  • 注册日期2020-07-02
  • 最后登录2023-08-18
  • 发帖数22
  • 经验34枚
  • 威望0点
  • 贡献值40点
  • 好评度1点
  • 社区居民
阅读:1719回复:2

Firefox 115ESR可移动的按钮菜单脚本求修复

楼主#
更多 发布于:2023-07-04 17:15
更新到Firefox 115ESR后脚本失效,求万能的坛友修复
// ==UserScript==
// @name   AnotherButton
// @description  可移动的按钮菜单
// @author         feiruo
// @charset        UTF-8
// @include   main
// @id              [A26C02CA]
// @inspect         window.anoBtn
// @startup         window.anoBtn.init();
// @shutdown        window.anoBtn.onDestroy();
// @config    window.anoBtn.EditFile(anoBtn.File);
// @reviewURL  http://bbs.kafan.cn/thread-1657589-1-1.html
// @homepageURL  https://github.com/feiruo/userChromeJS/tree/master/anoBtn
// @downloadURL  https://github.com/feiruo/userChromeJS/raw/master/anoBtn/anoBtn.uc.js
// @note   支持菜单和脚本设置重载
// @note   需要 _anoBtn.js 配置文件
// @version   1.4.1  2016.11.07  14:30 Fix For E10s。
// ==/UserScript==
(function(CSS) {
 let {
  classes: Cc,
  interfaces: Ci,
  utils: Cu,
  results: Cr
 } = Components;
 if (!window.Services) Cu.import("resource://gre/modules/Services.jsm");
 if (window.anoBtn) {
  window.anoBtn.onDestroy();
  delete window.anoBtn;
 }
    var useScraptchpad = true;  // 如果不存在编辑器,则使用代码片段速记器,否则设置编辑器路径
 var anoBtn = {
        get File() {
   let aFile;
            aFile = FileUtils.getFile("UChrm", ["local", "_anoBtn.js"], false);
            if (!aFile.exists()) {
                saveFile(aFile, '');
                alert('_anoBtn.js配置为空,该文件在local目录下');
            }
            delete this.file;
            return this.file = aFile;
        },
  get FocusedWindow() {
   var title = gBrowser.selectedTab.label || gBrowser.selectedBrowser.contentTitle;
   var url = gBrowser.currentURI.spec || gBrowser.selectedBrowser.currentURI.spec;
   var cont;
   if (gMultiProcessBrowser) {
    function listener(message) {
     cont = message.objects.cont;
     return cont;
    }
    window.messageManager.addMessageListener("AnotherButton:AnotherButton-e10s-content-" + this.E10SMSG, listener);
    window.messageManager.removeMessageListener("AnotherButton:AnotherButton-e10s-content-" + this.E10SMSG, listener);
   } else {
    return window.content || gBrowser.selectedBrowser._contentWindow;
   }
   // return window.content || gBrowser.selectedBrowser._contentWindow;
  },
  init: function() {
   var ins = $("menu_ToolsPopup").firstChild;
   ins.parentNode.insertBefore($C("menuitem", {
    id: "anoBtn_set",
    label: "自定义按钮",
    tooltiptext: "左键:重载配置\n右键:编辑配置",
    class: "menuitem-iconic",
    onclick: "anoBtn.BtnClick(event);",
   }), ins);
   if (!this.E10SMSG) this.E10SMSG = Math.floor(Math.random() * 900000 + 99999);
   if (gMultiProcessBrowser) {
    if (!this.IsMultiProcessScript) {
     var script = "data:application/javascript," + encodeURIComponent('sendAsyncMessage("AnotherButton:AnotherButton-e10s-content-' + this.E10SMSG + '", {}, {cont: content,})');
     window.messageManager.loadFrameScript(script, true);
     this.IsMultiProcessScript = true;
    }
   }
   this.ToRegExp();
   this.Rebuild();
   //setTimeout(function() {
   // anoBtn.Rebuild();
   //}, 1000); //again for webDeveloperMenu
   this.style = addStyle(CSS);
   window.addEventListener("unload", function() {
    anoBtn.onDestroy();
   }, false);
  },
  ToRegExp: function() {
   let he = "(?:_HTML(?:IFIED)?|_ENCODE)?";
   let rTITLE = "%TITLE" + he + "%|%t\\b";
   let rTITLES = "%TITLES" + he + "%|%t\\b";
   let rURL = "%(?:R?LINK_OR_)?URL" + he + "%|%u\\b";
   let rHOST = "%HOST" + he + "%|%h\\b";
   let rIP = "%IP" + he + "%";
   let rBASEDOMAIN = "%BASEDOMAIN" + he + "%";
   let rSEL = "%SEL" + he + "%|%s\\b";
   let rLINK = "%R?LINK(?:_TEXT|_HOST)?" + he + "%|%l\\b";
   let rIMAGE = "%IMAGE(?:_URL|_ALT|_TITLE)" + he + "%|%i\\b";
   let rIMAGE_BASE64 = "%IMAGE_BASE64" + he + "%|%i\\b";
   let rMEDIA = "%MEDIA_URL" + he + "%|%m\\b";
   let rCLIPBOARD = "%CLIPBOARD" + he + "%|%p\\b";
   let rFAVICON = "%FAVICON" + he + "%";
   let rEMAIL = "%EMAIL" + he + "%";
   let rExt = "%EOL" + he + "%";
   let rFAVICON_BASE64 = "%FAVICON_BASE64" + he + "%";
   let rRLT_OR_UT = "%RLT_OR_UT" + he + "%"; // 链接文本或网页标题
   this.rTITLE = new RegExp(rTITLE, "i");
   this.rTITLES = new RegExp(rTITLES, "i");
   this.rURL = new RegExp(rURL, "i");
   this.rIP = new RegExp(rIP, "i");
   this.rHOST = new RegExp(rHOST, "i");
   this.rBASEDOMAIN = new RegExp(rBASEDOMAIN, "i");
   this.rSEL = new RegExp(rSEL, "i");
   this.rLINK = new RegExp(rLINK, "i");
   this.rIMAGE = new RegExp(rIMAGE, "i");
   this.rMEDIA = new RegExp(rMEDIA, "i");
   this.rCLIPBOARD = new RegExp(rCLIPBOARD, "i");
   this.rFAVICON = new RegExp(rFAVICON, "i");
   this.rEMAIL = new RegExp(rEMAIL, "i");
   this.rExt = new RegExp(rExt, "i");
   this.rFAVICON_BASE64 = new RegExp(rFAVICON_BASE64, "i");
   this.rIMAGE_BASE64 = new RegExp(rIMAGE_BASE64, "i");
   this.rRLT_OR_UT = new RegExp(rRLT_OR_UT, "i");
   this.regexp = new RegExp([rTITLE, rTITLES, rURL, rHOST, rBASEDOMAIN, rIP, rSEL, rLINK, rIMAGE, rIMAGE_BASE64, rMEDIA, rCLIPBOARD, rFAVICON, rFAVICON_BASE64, rEMAIL, rExt, rRLT_OR_UT].join("|"), "ig");
  },
  onDestroy: function() {
   this.RebuildBtn();
   this.RebuildPopup();
   if ($("anoBtn_set"))
    $("anoBtn_set").parentNode.removeChild($("anoBtn_set"));
   Services.obs.notifyObservers(null, "startupcache-invalidate", "");
  },
  BtnClick: function(event) {
   if (event.target != event.currentTarget) return;
   event.stopPropagation();
   event.preventDefault();
   switch (event.target.id) {
    case 'anoBtn_set':
     switch (event.button) {
      case 0:
       anoBtn.Rebuild(true);
       break;
      case 1:
       break;
      case 2:
       anoBtn.EditFile(anoBtn.file);
       break;
     }
     break;
    case 'anoBtn_Icon':
     //$("anoBtn_Popup").openPopup(event.target);
     //$("anoBtn_Popup").showPopup();
     $('anoBtn_Popup').addEventListener('popupshowing', this, false);
     break;
   }
   return;
  },
  Rebuild: function(isAlert) {
   var MenuDate = this.LoadFile(this.File);
   !!this.BuildPopup && this.BuildPopup.Remove();
   if (!MenuDate) return;
   this.anomenu = MenuDate.anomenu;
   this.anobtnset = MenuDate.anobtnset;
   this.RebuildBtn(true);
   this.RebuildPopup(true);
   if (isAlert) alert('配置已经重新载入');
  },
  /*****************************************************************************************/
  RebuildBtn: function(isAlert) {
   var icon = $("anoBtn_Icon");
   if (icon) icon.parentNode.removeChild(icon);
   delete icon;
   if (!isAlert) return;
   var iconInTag = this.anobtnset.intags ? this.anobtnset.intags : "tabbrowser-tabs";
   var iconImage = this.anobtnset.image ? this.anobtnset.image : "chrome://branding/content/icon16.png";
   var intags = $(iconInTag);
   var orientation = this.anobtnset.orientation ? this.anobtnset.orientation : 'before';
   if ($('anoBtn_set')) $('anoBtn_set').setAttribute('image', iconImage);
   var IconType = this.IconSstatusBarPanel ? 'statusbarpanel' : 'image';
   this.icon = $C('toolbarbutton', {
    id: 'anoBtn_Icon',
    tooltiptext: '快速打开指定选项',
    class: 'toolbarbutton-1 chromeclass-toolbar-additional',
    popup: 'anoBtn_Popup',
    context: 'anoBtn_Popup',
    type: 'menu',
    removable: true,
    image: iconImage,
    src: iconImage,
    onclick: "anoBtn.BtnClick(event);",
   });
   if (this.anobtnset.Icon_Pos === 0) {
    ToolbarManager.addWidget(window, this.icon, true);
   } else if (this.anobtnset.Icon_Pos === 1) {
    $('urlbar-icons').appendChild(this.icon);
   } else if (this.anobtnset.Icon_Pos === 2) {
    if (orientation == 'before')
     intags.parentNode.insertBefore(this.icon, intags);
    else if (orientation == 'after') {
     var parentEl = intags.parentNode;
     if (parentEl.lastChild == intags) {
      parentEl.appendChild(this.icon);
     } else {
      parentEl.insertBefore(this.icon, intags.nextSibling);
     }
    }
   }
   if (this.anobtnset.IconSstatusBarPanel)
    this.icon.classList.add('class', 'statusbarpanel-iconic');
   return true;
  },
  RebuildPopup: function(isAlert) {
   if (!this.anomenu) return;
   var Popup = $("anoBtn_Popup");
   if (Popup) Popup.parentNode.removeChild(Popup);
   this.Popup = null;
   !!this.BuildPopup && this.BuildPopup.Remove();
   delete this.BuildPopup;
   delete Popup;
   if (!isAlert) return;
   if (!this.BuildPopup) {
    this.BuildPopup = new AnoBtn_BuildPopup('anoBtn', $C("menupopup", {
     id: "anoBtn_Popup",
     position: this.anobtnset.position,
     // onpopupshowing: "anoBtn.PopupShowing(event);"
    }));
   }
   this.BuildPopup.Build(this.anomenu);
   this.icon.appendChild(this.BuildPopup.Popup);
  },
  onCommand: function(event) {
   if (event.target != event.currentTarget) return;
   var menuitem = event.target;
   var text = menuitem.getAttribute("text") || "";
   var keyword = menuitem.getAttribute("keyword") || "";
   var url = menuitem.getAttribute("url") || "";
   var where = menuitem.getAttribute("where") || "";
   var exec = menuitem.getAttribute("exec") || "";
   var Post = menuitem.getAttribute("Post") || "";
   var Action = menuitem.getAttribute("Action") || "";
   if (Post)
    return this.PostData(this.ConvertText(url), this.ConvertText(Post));
   if (keyword) {
    let param = (text ? (text = this.ConvertText(text)) : "");
    let engine = Services.search.getEngineByAlias(keyword);
    if (engine) {
     let submission = engine.getSubmission(param);
     this.OpenCommand(event, submission.uri.spec, where);
    } else {
     PlacesUtils.keywords.fetch(keyword || '').then(entry => {
      if (!entry) return;
      let newurl = entry.url.href.replace('%s', encodeURIComponent(param));
      this.OpenCommand(event, newurl, where);
     });
    }
   } else if (url)
    this.OpenCommand(event, this.ConvertText(url), where || "tab");
   else if (exec)
    this.Exec(exec, this.ConvertText(text));
   else if (text)
    this.Copy(this.ConvertText(text));
   else if (Action)
    this.OpenAction(Action);
  },
  OpenAction: function(url, fId, val, bId, bClass) {
   var wrap = {
    try: function(js) {
     return "try{" + js + "}catch(e){}";
    },
    delay: function(js) {
     return wrap.try("content.window.setTimeout(function(){" + wrap.try(js) + "},100);");
    },
    doOnLoad: function(js) {
     return wrap.try("let onLoad = function(){" +
      "removeEventListener('load',onLoad,true);" +
      wrap.try(js) +
      "};" +
      "addEventListener('load',onLoad,true);");
    },
    quotes: function(str) {
     return "\"" + str + "\"";
    },
    getElement: function(id) {
     const selector = "form #" + id;
     return "content.window.document.querySelector(" + wrap.quotes(selector) + ")";
    },
    getElementC: function(id) {
     const selector = "form ." + id;
     return "content.window.document.querySelector(" + wrap.quotes(selector) + ")";
    }
   };
   function openURL(url) {
    var browser = window.getBrowser();
    try {
     window.TreeStyleTabService.readyToOpenChildTab(browser.selectedTab);
    } catch (e) {}
    var newTab = browser.addTab(url, {
     ownerTab: browser.selectedTab,
     relatedToCurrent: true
    });
    browser.selectedTab = newTab;
    return browser.getBrowserForTab(newTab);
   }
   var contentScript = wrap.getElement(fId) + ".value = " + wrap.quotes(this.ConvertText(val)) + ";";
   if (bId)
    contentScript += wrap.delay(wrap.getElement(bId) + ".click();")
   else if (bClass)
    contentScript += wrap.delay(wrap.getElementC(bClass) + ".click();")
   contentScript = "data:text/javascript," + encodeURIComponent(wrap.doOnLoad(contentScript));
   var targetBrowser = openURL(url);
   targetBrowser.messageManager.loadFrameScript(contentScript, false);
  },
  OpenCommand: function(event, url, where, postData) {
   var uri;
   try {
    uri = Services.io.newURI(url, null, null);
   } catch (e) {
    return console.log("URL 不正确: " + url);
   }
   if (uri.scheme === "javascript")
    loadURI(url);
   else if (where)
    openTrustedLinkIn(uri.spec, where, false, postData || null);
   else if (event.button == 1)
    openNewTabWith(uri.spec);
   else
    openUILink(uri.spec, event);
  },
  Exec: function(path, arg) {
   var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
   var process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
   try {
    var a;
    if (typeof arg == 'string' || arg instanceof String) {
     a = arg.split(/\s+/)
    } else if (Array.isArray(arg)) {
     a = arg;
    } else {
     a = [arg];
    }
    file.initWithPath(path);
    if (!file.exists()) {
     Cu.reportError('File Not Found: ' + path);
     return;
    }
    if (file.isExecutable()) {
     process.init(file);
     process.runw(false, a, a.length);
    } else {
     file.launch();
    }
   } catch (e) {
    console.log(e);
   }
  },
  PostData: function(aURI, aPostData) {
   var stringStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
   if ("data" in stringStream)
    stringStream.data = aPostData;
   else
    stringStream.setData(aPostData, aPostData.length);
   var PostData = Cc["@mozilla.org/network/mime-input-stream;1"].createInstance(Ci.nsIMIMEInputStream);
   PostData.addHeader("Content-Type", "application/x-www-form-urlencoded");
   PostData.addContentLength = true;
   PostData.setData(stringStream);
   gBrowser.loadOneTab(aURI, null, null, PostData, false);
  },
  ConvertText: function(text) {
   var that = this;
   var tab = document.popupNode && document.popupNode.localName == "tab" ? document.popupNode : null;
   var win = tab ? tab.linkedBrowser.contentWindow : this.FocusedWindow;
   var title = gBrowser.selectedTab.label || gBrowser.selectedBrowser.contentTitle;
   var url = gBrowser.currentURI.spec || gBrowser.selectedBrowser.currentURI.spec;
   var host;
            try{
                  var host = gBrowser.currentURI.asciiHostPort || gBrowser.currentURI.HostPort || gBrowser.currentURI.hostPort || gBrowser.currentURI.host;
            }catch(e){
                  host = url;
            }
   function convert(str) {
    switch (str) {
     case "%T":
     case "%TITLE%":
      return title;
     case "%TITLES%":
      return title.replace(/\s-\s.*/i, "").replace(/_[^\[\]【】]+$/, "");
     case "%U":
     case "%URL%":
      return url;
     case "%H":
     case "%HOST%":
      return host;
     case "%S":
     case "%SEL%":
      return that.getSelection(win) || "";
     case "%P":
     case "%CLIPBOARD%":
      return readFromClipboard() || "";
     case "%FAVICON%":
      return gBrowser.getIcon(tab ? tab : null) || "";
     case "%FAVICON_BASE64%":
      return img2base64(gBrowser.getIcon(tab ? tab : null));
     case "%EMAIL%":
      return getEmailAddress() || "";
     case "%IP%":
      return FeiRuoNet && FeiRuoNet.Caches.DNS[gBrowser.selectedBrowser.currentURI.host];
     case "%BASEDOMAIN%":
      var eTLDService = Cc["@mozilla.org/network/effective-tld-service;1"].getService(Ci.nsIEffectiveTLDService);
      return eTLDService.getBaseDomain(makeURI(gBrowser.selectedBrowser.currentURI.spec));
     case "%EOL%":
      return "\r\n";
    }
    return str;
   }
   function htmlEscape(s) {
    return (s + "").replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/\"/g, """).replace(/\'/g, "'");
   };
   function getEmailAddress() {
    var url = context.linkURL;
    if (!url || !/^mailto:([^?]+).*/i.test(url)) return "";
    var addresses = RegExp.$1;
    try {
     var characterSet = context.target.ownerDocument.characterSet;
     const textToSubURI = Cc['@mozilla.org/intl/texttosuburi;1'].getService(Ci.nsITextToSubURI);
     addresses = textToSubURI.unEscapeURIForUI(characterSet, addresses);
    } catch (ex) {}
    return addresses;
   }
   function img2base64(imgsrc) {
    if (typeof imgsrc == 'undefined') return "";
    const NSURI = "http://www.w3.org/1999/xhtml";
    var img = new Image();
    var that = this;
    var canvas,
     isCompleted = false;
    img.onload = function() {
     var width = this.naturalWidth,
      height = this.naturalHeight;
     canvas = document.createElementNS(NSURI, "canvas");
     canvas.width = width;
     canvas.height = height;
     var ctx = canvas.getContext("2d");
     ctx.drawImage(this, 0, 0);
     isCompleted = true;
    };
    img.onerror = function() {
     Components.utils.reportError("Count not load: " + imgsrc);
     isCompleted = true;
    };
    img.src = imgsrc;
    var thread = Cc['@mozilla.org/thread-manager;1'].getService().mainThread;
    while (!isCompleted) {
     thread.processNextEvent(true);
    }
    var data = canvas ? canvas.toDataURL("image/png") : "";
    canvas = null;
    return data;
   }
   return text.replace(this.regexp, function(str) {
    str = str.toUpperCase().replace("%LINK", "%RLINK");
    if (str.indexOf("_HTMLIFIED") >= 0)
     return htmlEscape(convert(str.replace("_HTMLIFIED", "")));
    if (str.indexOf("_HTML") >= 0)
     return htmlEscape(convert(str.replace("_HTML", "")));
    if (str.indexOf("_ENCODE") >= 0)
     return encodeURIComponent(convert(str.replace("_ENCODE", "")));
    return convert(str);
   });
  },
  handleRelativePath: function(path) {
   if (path) {
    //path = path.replace(/\//g, '\\').toLocaleLowerCase();
    path = path.replace(/\//g, '\\');
    var profD = Cc['@mozilla.org/file/directory_service;1'].getService(Ci.nsIProperties).get("ProfD", Ci.nsIFile);
    if (/^(\\)/.test(path)) {
     if (path.startsWith('\\..\\')) {
      return profD.parent.path + path.replace('\\..', '');
     }
     return profD.path + path;
    } else {
     return path;
    }
   }
  },
  getSelection: function(win) {
   win || (win = this.FocusedWindow);
   var selection = this.getRangeAll(win).join(" ");
   if (!selection) {
    let element = document.commandDispatcher.focusedElement;
    let isOnTextInput = function(elem) {
     return elem instanceof HTMLTextAreaElement ||
      (elem instanceof HTMLInputElement && elem.mozIsTextField(true));
    };
    if (isOnTextInput(element)) {
     selection = element.QueryInterface(Ci.nsIDOMNSEditableElement)
      .editor.selection.toString();
    }
   }
   if (selection) {
    selection = selection.replace(/^\s+/, "")
     .replace(/\s+$/, "")
     .replace(/\s+/g, " ");
   }
   return selection;
  },
  getRangeAll: function(win) {
   win || (win = this.FocusedWindow);
   var sel = win.getSelection();
   var res = [];
   for (var i = 0; i < sel.rangeCount; i++) {
    res.push(sel.getRangeAt(i));
   };
   return res;
  },
  /*****************************************************************************************/
  EditFile: function (aFile, aLineNumber) {
            if (!aFile || !aFile.exists() || !aFile.isFile()) return;
            var editor;
            try {
                editor = Services.prefs.getComplexValue("view_source.editor.path", Ci.nsIFile);
            } catch (e) {
            }
            if (!editor || !editor.exists()) {
                if (useScraptchpad) {
                    this.openScriptInScratchpad(window, aFile);
                    return;
                } else {
                    alert("请先设置编辑器的路径!!!");
                    var fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker);
                    fp.init(window, "设置全局脚本编辑器", fp.modeOpen);
                    fp.appendFilter("执行文件", "*.exe");
                    if (fp.show() == fp.returnCancel || !fp.file)
                        return;
                    else {
                        editor = fp.file;
                        Services.prefs.setCharPref("view_source.editor.path", editor.path);
                    }
                }
            }
            // 调用自带的
   if(typeof(userChrome) == 'undefined') { 
    this.openScriptInScratchpad(window, aFile);
                return;
   } else {   
            var aURL = userChrome.getURLSpecFromFile(aFile);
            var aDocument = null;
            var aCallBack = null;
            var aPageDescriptor = null;
            gViewSourceUtils.openInExternalEditor({
                URL: aURL,
                lineNumber: aLineNumber
            }, aPageDescriptor, aDocument, aLineNumber, aCallBack); 
   }
  },
        openScriptInScratchpad: function (parentWindow, file) {
            let spWin = window.openDialog("chrome://devtools/content/scratchpad/index.xul", "Toolkit:Scratchpad", "chrome,resizable=yes,centerscreen,dependent");
            spWin.addEventListener("load", function spWinLoaded() {
                spWin.removeEventListener("load", spWinLoaded, false);
                let Scratchpad = spWin.Scratchpad;
                Scratchpad.setFilename(file.path);
                Scratchpad.addObserver({
                    onReady: function () {
                        Scratchpad.removeObserver(this);
                        Scratchpad.importFromFile.call(Scratchpad, file);
                    }
                });
            }, false);
        },
  Copy: function(str) {
   if (!str) str = this.icon.tooltipText;
   Cc['@mozilla.org/widget/clipboardhelper;1'].createInstance(Ci.nsIClipboardHelper).copyString(str);
   StatusPanel._label = "已复制: " + str;
  },
  OpenScriptInScratchpad: function(parentWindow, file) {
   let spWin = (parentWindow.Scratchpad || Services.wm.getMostRecentWindow("navigator:browser").Scratchpad).openScratchpad();
   spWin.addEventListener("load", function spWinLoaded() {
    spWin.removeEventListener("load", spWinLoaded, false);
    let Scratchpad = spWin.Scratchpad;
    Scratchpad.setFilename(file.path);
    Scratchpad.addObserver({
     onReady: function() {
      Scratchpad.removeObserver(this);
      Scratchpad.importFromFile.call(Scratchpad, file);
     }
    });
   }, false);
  },
  LoadFile: function(aFile, isAlert) {
   if (!aFile || !aFile.exists() || !aFile.isFile())
    return null;
   var fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
   var sstream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
   fstream.init(aFile, -1, 0, 0);
   sstream.init(fstream);
   var data = sstream.read(sstream.available());
   try {
    data = decodeURIComponent(escape(data));
   } catch (e) {}
   sstream.close();
   fstream.close();
   if (!data) {
    var errmsg = "Rebuild Error:【" + aFile.leafName + "】文件不存在";
    console.log(errmsg);
    if (isAlert)
     alert(errmsg);
    return null;
   }
   var sandbox = new Cu.Sandbox(new XPCNativeWrapper(window));
   sandbox.Components = Components;
   sandbox.Cc = Cc;
   sandbox.Ci = Ci;
   sandbox.Cr = Cr;
   sandbox.Cu = Cu;
   sandbox.Services = Services;
   sandbox.locale = Services.prefs.getCharPref("general.useragent.locale","zh-CN");
   try {
    var lineFinder = new Error();
    Cu.evalInSandbox(data, sandbox, "1.8");
   } catch (e) {
    let line = e.lineNumber - lineFinder.lineNumber - 1;
    var errmsg = 'Error: ' + e + "\n请重新检查【" + aFile.leafName + "】文件第 " + line + " 行";
    console.log(errmsg);
    if (isAlert)
     alert(errmsg);
   }
   return sandbox || null;
  },
 };
 function AnoBtn_BuildPopup(ID, Popup) {
  this.ID = ID;
  if (typeof Popup == 'string')
   Popup = document.getElementById(Popup);
  Popup = Popup || document.getElementById(ID) || document.getElementById(ID + '_Popup');
  if (!Popup || !Popup.tagName || Popup.tagName != "menupopup") {
   Popup = document.createXULElement("menupopup");
   Popup.setAttribute('id', thins.ID + '_Popup')
  }
  this.Popup = Popup;
  this.Remove();
 }
 AnoBtn_BuildPopup.prototype = {
  ID: null,
  Popup: null,
  isReady: false,
  Remove: function() {
   Array.prototype.slice.call((this.Popup || document).querySelectorAll("." + this.ID + "_MenuNote")).forEach(item => {
    $("main-menubar").appendChild(item);
    item.classList.remove(this.ID + '_CustomMenu');
   });
   Array.prototype.slice.call((this.Popup).querySelectorAll("." + this.ID + "_CustomMenu")).forEach(item => {
    item.parentNode.removeChild(item);
   });
  },
  Build: function(Menus) {
   if (!Menus) return this.Remove();
   for (let obj of Menus) {
    if (!obj) continue;
    //this.Popup.appendChild(this.CreateMenuitem(obj));
    const menuitem = this.CreateMenuitem(obj);
    this.Popup.appendChild(menuitem);
    if(menuitem.render){
     for(const child of menuitem.childNodes){
      if(child.localName !== 'menupopup')
       child.remove();
     }
     menuitem.renderedOnce = false;
     menuitem.render();
    }
   }
   this.isReady = true;
   return this.Popup;
  },
  CreateMenuitem: function(obj, i) {
   if (obj.MapFolder)
    return this.CreateMenu(this.EnumerateFolder(obj));
   let menuitem;
   if (obj.id && (menuitem = $(obj.id))) {
    let dupMenuitem;
    let isDupMenu = (obj.clone != false);
    if (isDupMenu)
     dupMenuitem = menuitem.cloneNode(true);
    else
     dupMenuitem = menuitem;
     
    for (let key in obj) {
     let val = obj[key];
     if (typeof val == "function")
      obj[key] = val = "(" + val.toString() + ").call(this, event);";
     dupMenuitem.setAttribute(key, val);
    }
     
    let type = dupMenuitem.nodeName,
     cls = dupMenuitem.classList;
    if ((type == 'menuitem' || type == 'menu') && !cls.contains(type + '-iconic')) cls.add(type + '-iconic');
    if (!cls.contains(this.ID + '_CustomMenu')) cls.add(this.ID + '_CustomMenu');
    if (!isDupMenu && !cls.contains(this.ID + '_MenuNote')) cls.add(this.ID + '_MenuNote');
    return dupMenuitem;
   }
   if (obj.child)
    return this.CreateMenu(obj);
   if (obj.label === "separator" || (!obj.label && !obj.image && !obj.text && !obj.keyword && !obj.url && !obj.oncommand && !obj.command)) {
    menuitem = document.createXULElement("menuseparator");
   } else if (obj.oncommand || obj.command) {
    let org = obj.command ? document.getElementById(obj.command) : null;
    if (org && org.localName === "menuseparator") {
     menuitem = document.createXULElement("menuseparator");
    } else {
     menuitem = document.createXULElement("menuitem");
     if (obj.command)
      menuitem.setAttribute("command", obj.command);
     if (!obj.label)
      obj.label = obj.command || obj.oncommand;
    }
   } else {
    menuitem = document.createXULElement("menuitem");
    if (!obj.label)
     obj.label = obj.exec || obj.keyword || obj.url || obj.text || "NoName";
    if (obj.keyword && !obj.text) {
     let index = obj.keyword.search(/\s+/);
     if (index > 0) {
      obj.text = obj.keyword.substr(index).trim();
      obj.keyword = obj.keyword.substr(0, index);
     }
    }
    if (obj.where && /\b(tab|tabshifted|window|current)\b/i.test(obj.where))
     obj.where = RegExp.$1.toLowerCase();
    if (obj.where && !("acceltext" in obj))
     obj.acceltext = obj.where;
    if (obj.exec)
     obj.exec = this.handleRelativePath(obj.exec);
   }
   for (let key in obj) {
     let val = obj[key];
    if (key === "command" || key === "MapFolder" || key === "Filter" || key === "Sort" || key === "ExcludeDir") continue;
    if (typeof val == "function")
     obj[key] = val = "(" + val.toString() + ").call(this, event);";
    menuitem.setAttribute(key, val);
   }
   var cls = menuitem.classList;
   cls.add(this.ID + "_CustomMenu");
   let type = menuitem.nodeName;
   if ((type == 'menuitem' || type == 'menu') && (!cls.contains(type + '-iconic')))
    cls.add(type + '-iconic');
   if (menuitem.localName == "menuseparator")
    return menuitem;
   if (!obj.onclick)
    menuitem.setAttribute("onclick", "checkForMiddleClick(this, event)");
   if (obj.oncommand || obj.command)
    return menuitem;
   menuitem.setAttribute("oncommand", "anoBtn.onCommand(event);");
   this.SetMenusIcon(menuitem, obj);
   return menuitem;
  },
  CreateMenu: function(menuObj, i) {
   var menu = document.createXULElement("menu");
   var Popup = menu.appendChild(document.createXULElement("menupopup"));
   if (menuObj.MapFolder)
    menuObj = this.EnumerateFolder(menuObj);
    for (let key in menuObj) {
      
     let val = menuObj[key];
    if (key === "child" || key === "MapFolder" || key === "Sort" || key === "Filter" || key === "Exclude" || key === "Directories" || key === "FilterDirs" || key === "ExcludeDirs") continue;
    if (key === 'onshowing') {
     this.customShowings.push({
      item: menu,
      fnSource: menuObj.onshowing.toString()
     });
     delete menuObj.onshowing;
     continue;
    }
    if (typeof val == "function")
     menuObj[key] = val = "(" + val.toString() + ").call(this, event);"
    menu.setAttribute(key, val);
   }
   let cls = menu.classList;
   cls.add(this.ID + "_CustomMenu");
   cls.add("menu-iconic");
   menuObj.child && menuObj.child.forEach(function(obj) {
    Popup.appendChild(this.CreateMenuitem(obj));
   }, this);
   if (!menu.hasAttribute('label')) {
    let firstItem = menu.querySelector('menuitem');
    if (firstItem) {
     let command = firstItem.getAttribute('command');
     if (command)
      firstItem = document.getElementById(command) || firstItem;
     ['label', 'accesskey', 'image', 'icon'].forEach(function(n) {
      if (!menu.hasAttribute(n) && firstItem.hasAttribute(n))
       menu.setAttribute(n, firstItem.getAttribute(n));
     }, this);
     menu.setAttribute('onclick', "if (event.target != event.currentTarget) return;var firstItem = event.currentTarget.querySelector('menuitem');if (!firstItem) return;if (event.button === 1) {checkForMiddleClick(firstItem, event);} else {firstItem.doCommand();closeMenus(event.currentTarget);}");
    }
   }
   return menu;
  },
  EnumerateFolder: function(obj) {
   obj || (obj = {});
   var path = this.handleRelativePath(obj.MapFolder);
   var dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
   dir.initWithPath(path);
   if (!dir.exists() || !dir.isDirectory())
    return obj;
   var Entries = dir.directoryEntries;
   var ExcludeDirs = obj.ExcludeDirs ? ((typeof obj.ExcludeDirs == "string") ? (new RegExp(obj.ExcludeDirs)) : obj.ExcludeDirs) : null;
   var FilterDirs = obj.FilterDirs ? ((typeof obj.FilterDirs == "string") ? (new RegExp(obj.FilterDirs)) : obj.FilterDirs) : null;
   obj.child || (obj.child = []);
   if (obj.child.length > 0 && obj.child[obj.child.length - 1].label != "separator") {
    obj.child.push({
     label: 'separator',
    });
   }
   while (Entries.hasMoreElements()) {
    var Entry = Entries.getNext();
    Entry.QueryInterface(Components.interfaces.nsIFile);
    if (Entry.isDirectory() && (typeof obj.Directories === 'number') && (obj.Directories > 0)) {
     if (ExcludeDirs && ExcludeDirs.test(Entry.leafName)) continue;
     if (FilterDirs && !FilterDirs.test(Entry.leafName)) continue;
     obj.child.push(this.EnumerateFolder({
      label: Entry.leafName,
      MapFolder: Entry.path,
      exec: Entry.path,
      Directories: obj.Directories - 1,
      Filter: obj.Filter,
      Exclude: obj.Exclude,
      ExeText: obj.ExeText,
      FilterDirs: obj.FilterDirs,
      ExcludeDirs: obj.ExcludeDirs,
      onclick: "anoBtn.onCommand(event);",
      Sort: 0,
      image: "moz-icon://" + Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getURLSpecFromFile(Entry) + "?size=16",
     }))
     continue;
    }
    if (!Entry.isFile()) continue;
    var Exclude = obj.Exclude ? ((typeof obj.Exclude == "string") ? (new RegExp(obj.Exclude)) : obj.Exclude) : null;
    var Filter = obj.Filter ? ((typeof obj.Filter == "string") ? (new RegExp(obj.Filter)) : obj.Filter) : null;
    if (Exclude && Exclude.test(Entry.leafName)) continue;
    if (Filter && !Filter.test(Entry.leafName)) continue;
    var child = {
     label: Entry.leafName.substr(0, Entry.leafName.lastIndexOf(".")),
     exec: Entry.path,
     Sort: 1,
     tooltiptext: Entry.path,
    };
    var text;
    if (typeof obj.ExeText == 'object') {
     var Program = obj.ExeText.Program ? ((typeof obj.ExeText.Program == "string") ? (new RegExp(obj.ExeText.Program)) : obj.ExeText.Program) : null;
     if (Program.test(Entry.leafName)) {
      text = obj.ExeText.text.replace(/%DIR%/i, dir.leafName).replace(/%EXE%/i, obj.label)
     }
    }
    if (!!text) child.text = text;
    obj.child.push(child);
   }
   if (obj && obj.child && obj.child[obj.child.length - 1] && obj.child[obj.child.length - 1].label == "separator")
    delete obj.child[obj.child.length - 1];
   obj.MapFolder = false;
   obj.child.sort(function(a, b) {
    return a.Sort - b.Sort;
   });
   return obj;
  },
  handleRelativePath: function(path) {
   if (path) {
    //path = path.replace(/\//g, '\\').toLocaleLowerCase();
    path = path.replace(/\//g, '\\');
    var profD = Cc['@mozilla.org/file/directory_service;1'].getService(Ci.nsIProperties).get("ProfD", Ci.nsIFile);
    if (/^(\\)/.test(path)) {
     if (path.startsWith('\\..\\')) {
      return profD.parent.path + path.replace('\\..', '');
     }
     return profD.path + path;
    } else {
     return path;
    }
   }
  },
  SetMenusIcon: function(menu, obj) {
   if (menu.hasAttribute("src") || menu.hasAttribute("image") || menu.hasAttribute("icon"))
    return;
   if (obj.exec) {
    var aFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    try {
     aFile.initWithPath(obj.exec);
    } catch (e) {
     return;
    }
    if (!aFile.exists()) {
     menu.setAttribute("disabled", "true");
    } else {
     let fileURL = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getURLSpecFromFile(aFile);
     menu.setAttribute("image", "moz-icon://" + fileURL + "?size=16");
    }
    return;
   }
   if (obj.keyword) {
    let engine = Services.search.getEngineByAlias(obj.keyword);
    if (engine && engine.iconURI) {
     menu.setAttribute("image", engine.iconURI.spec);
     return;
    }
   }
   var setIconCallback = function(url) {
    let uri, iconURI;
    try {
     uri = Services.io.newURI(url, null, null);
    } catch (e) {}
    if (!uri) return;
    menu.setAttribute("scheme", uri.scheme);
    PlacesUtils && PlacesUtils.favicons && PlacesUtils.favicons.getFaviconDataForPage(uri, {
     onComplete: function(aURI, aDataLen, aData, aMimeType) {
      try {
       // javascript: URI の host にアクセスするとエラー
       menu.setAttribute("image", aURI && aURI.spec ?
        "moz-anno:favicon:" + aURI.spec :
        "moz-anno:favicon:" + uri.scheme + "://" + uri.host + "/favicon.ico");
      } catch (e) {}
     }
    });
   }
   PlacesUtils && PlacesUtils.keywords && PlacesUtils.keywords.fetch(obj.keyword || '').then(entry => {
    let url;
    if (entry) {
     url = entry.url.href;
    } else {
     url = (obj.url + '').replace(/%TITLE(?:_HTML(?:IFIED)?|_ENCODE)?%|%t\b|%TITLES(?:_HTML(?:IFIED)?|_ENCODE)?%|%t\b|%(?:R?LINK_OR_)?URL(?:_HTML(?:IFIED)?|_ENCODE)?%|%u\b|%HOST(?:_HTML(?:IFIED)?|_ENCODE)?%|%h\b|%BASEDOMAIN(?:_HTML(?:IFIED)?|_ENCODE)?%|%h\b|%IP(?:_HTML(?:IFIED)?|_ENCODE)?%|%h\b|%SEL(?:_HTML(?:IFIED)?|_ENCODE)?%|%s\b|%R?LINK(?:_TEXT|_HOST)?(?:_HTML(?:IFIED)?|_ENCODE)?%|%l\b|%IMAGE(?:_URL|_ALT|_TITLE)(?:_HTML(?:IFIED)?|_ENCODE)?%|%i\b|%IMAGE_BASE64(?:_HTML(?:IFIED)?|_ENCODE)?%|%i\b|%MEDIA_URL(?:_HTML(?:IFIED)?|_ENCODE)?%|%m\b|%CLIPBOARD(?:_HTML(?:IFIED)?|_ENCODE)?%|%p\b|%FAVICON(?:_HTML(?:IFIED)?|_ENCODE)?%|%FAVICON_BASE64(?:_HTML(?:IFIED)?|_ENCODE)?%|%EMAIL(?:_HTML(?:IFIED)?|_ENCODE)?%|%EOL(?:_HTML(?:IFIED)?|_ENCODE)?%|%RLT_OR_UT(?:_HTML(?:IFIED)?|_ENCODE)?%/gi, "");
    }
    setIconCallback(url);
   }, e => {
    console.log(e)
   }).catch(e => {});
  }
 };
 window.AnoBtn_BuildPopup = AnoBtn_BuildPopup;
 // 来自 User Agent Overrider 扩展
 const ToolbarManager = (function() {
  /**
   * Remember the button position.
   * This function Modity from addon-sdk file lib/sdk/widget.js, and
   * function BrowserWindow.prototype._insertNodeInToolbar
   */
  let layoutWidget = function(document, button, isFirstRun) {
   // Add to the customization palette
   let toolbox = document.getElementById('navigator-toolbox');
   toolbox.palette.appendChild(button);
   // Search for widget toolbar by reading toolbar's currentset attribute
   let container = null;
   let toolbars = document.getElementsByTagName('toolbar');
   let id = button.getAttribute('id');
   for (let i = 0; i < toolbars.length; i += 1) {
    let toolbar = toolbars[i];
    if (toolbar.getAttribute('currentset').indexOf(id) !== -1) {
     container = toolbar;
    }
   }
   // if widget isn't in any toolbar, default add it next to searchbar
   if (!container) {
    if (isFirstRun) {
     container = document.getElementById('nav-bar');
    } else {
     return;
    }
   }
   // Now retrieve a reference to the next toolbar item
   // by reading currentset attribute on the toolbar
   let nextNode = null;
   let currentSet = container.getAttribute('currentset');
   let ids = (currentSet === '__empty') ? [] : currentSet.split(',');
   let idx = ids.indexOf(id);
   if (idx !== -1) {
    for (let i = idx; i < ids.length; i += 1) {
     nextNode = document.getElementById(ids[i]);
     if (nextNode) {
      break;
     }
    }
   }
   // Finally insert our widget in the right toolbar and in the right position
   container.insertItem(id, nextNode, null, false);
   // Update DOM in order to save position
   // in this toolbar. But only do this the first time we add it to the toolbar
   if (ids.indexOf(id) === -1) {
    container.setAttribute('currentset', container.currentSet);
    document.persist(container.id, 'currentset');
   }
  };
  let addWidget = function(window, widget, isFirstRun) {
   try {
    layoutWidget(window.document, widget, isFirstRun);
   } catch (error) {
    console.log(error);
   }
  };
  let removeWidget = function(window, widgetId) {
   try {
    let widget = window.document.getElementById(widgetId);
    widget.parentNode.removeChild(widget);
   } catch (error) {
    console.log(error);
   }
  };
  let exports = {
   addWidget: addWidget,
   removeWidget: removeWidget,
  };
  return exports;
 })();
 function log(str) {
  console.log("[Another Button Debug] ", arguments);
 }
 function alert(aString, aTitle) {
  Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService).showAlertNotification("", aTitle || "Another Button", aString, false, "", null);
 }
 function $(id) {
  return document.getElementById(id);
 }
 function $C(name, attr) {
  var el = document.createXULElement(name);
  if (attr) Object.keys(attr).forEach(function(n) {return el.setAttribute(n, attr[n])});
  return el;
 }
 function addStyle(css) {
  var pi = document.createProcessingInstruction(
   'xml-stylesheet',
   'type="text/css" href="data:text/css;utf-8,' + encodeURIComponent(css) + '"'
  );
  return document.insertBefore(pi, document.documentElement);
 }
 anoBtn.init();
 window.anoBtn = anoBtn;
})('\
#anoBtn_Icon dropmarker {\
    display: none;\
}\
'.replace(/\n|\t/g, ''));
viewtheard
千年狐狸
千年狐狸
  • UID2383
  • 注册日期2005-01-20
  • 最后登录2024-04-29
  • 发帖数1974
  • 经验483枚
  • 威望1点
  • 贡献值360点
  • 好评度20点
  • 社区居民
  • 忠实会员
1楼#
发布于:2023-07-06 22:18
太长了吧,看得头晕
My Technical Blog: http://art-technical.blogspot.com/
cooling
小狐狸
小狐狸
  • UID36051
  • 注册日期2011-04-20
  • 最后登录2024-02-02
  • 发帖数12
  • 经验43枚
  • 威望0点
  • 贡献值8点
  • 好评度0点
  • 社区居民
2楼#
发布于:2023-07-19 19:15
我在116b2这个能用,但要注意配置文件_anoBtn.js,我发现目录枚举会导致出图标点不动。
https://blog.iplayloli.com/anotherbuttonucjs.html
喜欢firefox,不喜欢chrome
游客

返回顶部