Dumby
Круто...А, кто это писал? Тоже того...Доп пункты в about;addons
//Добавление на вкладке дополнения в меню расширений дополнительных пунктов (function(){ var iconURL = ""; if (window.AM_Helper) { window.AM_Helper.uninit(); delete window.AM_Helper; } Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/AddonManager.jsm"); 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; var observer = new MutationObserver(function(e) { e = e[e.length-1]; if(e.attributeName == "loading") { var doc = e.target.ownerDocument; } }); observer.observe(doc.getElementById("detail-view"), {attributes: true}); break; case "popupshowing": this.getAddon(this.win.document.popupNode.value, this.setItemsAttributes, event); break; } }, //Создаем меню addPopupMenu: function(doc) { var mainicon2="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADwAAAAAwAAAP8AAAD/AAAA/wAAAPAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8AAAAAAAAAD/AAAA/wAAAP8AAADwAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPAAAAAAAAAA/wAAAP8AAAD/AAAA8AAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADwAAAAAAAAAP8AAAD/AAAA/wAAAPAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8AAAAAAAAAD/AAAA/wAAAP8AAADwAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPAAAAAAAAAA8wAAAP8AAAD/AAAA8AAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADwAAAAAAAAAPAAAAD/AAAA/wAAAPAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPAAAAAAAAAAAAAAAHsAAAD/AAAAkAAAAAAAAADwAAAA/wAAAP8AAADwAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADwAAAAAAAAAIQAAAD/AAAAjQAAAAAAAAB1AAAA/wAAAP8AAAD/AAAA8AAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8AAAAIoAAAD/AAAAigAAAAAAAABpAAAAAAAAAAAAAAB7AAAA/wAAAIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAigAAAAAAAAB7AAAA8AAAAAAAAACEAAAA/wAAAIcAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAhwAAAAAAAACBAAAA/wAAAPAAAACKAAAA/wAAAIcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEAAAA/wAAAP8AAAD/AAAA/wAAAIcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAIQAAAAAAAAAAAAAAAAAAAAAAB8AAAAfAAAAAAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAxAAAAIgAAAAWAAAAJEAAAEDAAD+BwAA+A8AAA=="; var ins = doc.getElementById("menuitem_uninstallItem"); if (!ins) return; ins = ins.nextSibling; var popup = ins.parentNode; var menuitem = $C("menuseparator", { id: "AM-separator-1" }); popup.insertBefore(menuitem, ins); menuitem = $C("menuitem", { id: "AM-browse-dir", label: "Папка установки", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.browseDir);" }); popup.insertBefore(menuitem, ins); menuitem = $C("menuitem", { id: "AM-browse-Folder", label: "Файл установки", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.Folder);" }); popup.insertBefore(menuitem, ins); menuitem = $C("menuitem", { id: "AM-open-url", label: "Страница на AMO", tooltiptext: null, oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.goAMO);" }); popup.insertBefore(menuitem, ins); menuitem = $C("menuitem", { id: "AM-browse-support", label: "Страница поддержки", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.support);" }); popup.insertBefore(menuitem, ins); menuitem = $C("menuitem", { id: "AM-browse-goHome", label: "Домашняя страница", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.goHome);" }); popup.insertBefore(menuitem, ins); var menu = $C("menu", { id: "AM-menu", class: "menu-iconic", image: mainicon2, label: "Копировать", }); popup.insertBefore(menu, ins); var menuPopup = $C("menupopup", { id: "AM-menupopup", }); menu.appendChild(menuPopup); menuitem = $C("menuitem", { id: "AM-copy-name", label: "Копировать имя", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.copyName);" }); menuPopup.appendChild(menuitem); menuitem = $C("menuitem", { id: "AM-copy-version", label: "Копировать версию", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.copyVersion);" }); menuPopup.appendChild(menuitem); menuitem = $C("menuitem", { id: "AM-copy-NameVersion", label: "Копировать имя и версию", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.copyNameVersion);" }); menuPopup.appendChild(menuitem); menuitem = $C("menuitem", { id: "AM-copy-id", label: "Копировать id", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.copyID);" }); menuPopup.appendChild(menuitem); 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"), isService = (aAddon.type == "service"), isCustomButton = (aAddon.type == "custombuttons"), menuitem ; menuitem = doc.getElementById("AM-browse-dir"); menuitem.hidden = isService || isTheme || isCustomButton; menuitem = doc.getElementById("AM-browse-Folder"); menuitem.hidden = isService || isTheme || isCustomButton || isPlugin; menuitem = doc.getElementById("AM-copy-name"); menuitem.tooltipText = aAddon.name; menuitem = doc.getElementById("AM-copy-version"); menuitem.tooltipText = aAddon.version; menuitem.hidden = isCustomButton || isTheme; menuitem = doc.getElementById("AM-copy-NameVersion"); menuitem.tooltipText = aAddon.name + " " + aAddon.version; menuitem.hidden = isCustomButton || isTheme; menuitem = doc.getElementById("AM-copy-id"); menuitem.tooltipText = "ID: " + aAddon.id; menuitem = doc.getElementById("AM-open-url"); var amoURL = aAddon.reviewURL ? aAddon.reviewURL.replace(/\/reviews\//, "/") : null; menuitem.tooltipText = amoURL; menuitem.hidden = !amoURL || /addons.mozilla.org/.test(aAddon.homepageURL); menuitem = doc.getElementById("AM-browse-support"); menuitem.tooltipText = aAddon.supportURL; menuitem.hidden = !aAddon.supportURL; menuitem = doc.getElementById("AM-browse-goHome"); menuitem.tooltipText = aAddon.homepageURL; menuitem.hidden = !aAddon.homepageURL; }, 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; } } }); }, //Открыть папку установки 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"); 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); } } }, //Копировать имя copyName: function (aAddon) { this.copyToClipboard(aAddon.name); }, //Копировать ID copyID: function (aAddon) { this.copyToClipboard("ID: " + aAddon.id); }, //Копировать версию copyVersion: function (aAddon) { this.copyToClipboard(aAddon.version); }, //Копировать имя и версию copyNameVersion: function (aAddon) { this.copyToClipboard(aAddon.name + " " + aAddon.version); }, //Открыть файл установки Folder: function (aAddon) { 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); if ( dir.exists() ) dir.launch(); var file = Components.classes['@mozilla.org/file/directory_service;1'] .getService(Components.interfaces.nsIProperties) .get('ProfD', Components.interfaces.nsIFile); file.append('extensions'); file.append( aAddon.id + '.xpi' ) if ( file.exists() ) file.launch(); return; }, //Страница на АМО goAMO: function (aAddon) { var sourceTracker = "/?src=external-Add-ons_Manager_Context_Menu-extension"; if (aAddon.reviewURL) { var amoURL = aAddon.reviewURL.replace(/\/reviews\//, "/") .replace(/\/(firefox|seamonkey|thunderbird|android)/, "") .replace(/\/\?src\=api/, sourceTracker); } if (/personas.mozilla.org$/.test(aAddon.id)) { amoURL = "https://addons.mozilla.org/addon/" + aAddon.id.match(/\d+/) + sourceTracker; } openURL(amoURL); }, //Домашняя страница goHome: function (aAddon) { var url = aAddon.homepageURL; if (!url) { if (aAddon.reviewURL) { url = aAddon.reviewURL.replace(/\/reviews\/.*$/, "/"); } else { url = "https://addons.mozilla.org/search/?q=" + encodeURIComponent(aAddon.name); } } openURL(url); }, //Страница поддержки support: function(aAddon) { openURL(aAddon.supportURL); }, //Вспомогательные функции get getPath() { var url = this.win.gViewController.viewObjects.detail._addon; if (!url) return false; return url.pluginFullpath || false; }, 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); } }; AM_Helper.init(); function $C(name, attr) { var el = document.createXULElement(name); if (attr) Object.keys(attr).forEach(function(n){ el.setAttribute(n, attr[n])}); return el; } })(); ((id, g, iconizer) => addDestructor(r => r[5] == "e" && id in g && g[id].destroy()) + addEventListener("shown", { //------------------------------------------------------------------ "Копировать имя_i": "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ==", "Копировать имя"(addon, hideOn) { if (hideOn) return false; gClipboard.write(addon.name); }, //------------------------------------------------------------------ "Копировать ID_i": "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ==", "Копировать ID"(addon, hideOn) { if (hideOn) return false; gClipboard.write(addon.id); }, //------------------------------------------------------------------ "Копировать версию_i": "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ==", "Копировать версию"(addon, hideOn) { if (hideOn) return ["custombuttons"]; gClipboard.write(addon.version); }, //------------------------------------------------------------------ "Домашняя страница"(addon, hideOn) { if (hideOn) return !addon.homepageURL; alert(addon.homepageURL); }, //------------------------------------------------------------------ url: "chrome://mozapps/content/extensions/aboutaddons.html", handleEvent(e) { if (e.target.baseURI != this.url) return; var item = this.getItem(e.target.ownerDocument); var addon = item.addon = e.target.closest("addon-card").addon; for(var child of item.children) { var res = this[child.textContent](addon, true); child.hidden = Array.isArray(res) ? res.includes(addon.type) : res; } e.target.contains(item) || requestAnimationFrame( () => e.target.prepend(item) ); }, click(e) { e.stopPropagation(); iconizer.item.parentNode.hide(); this[e.target.textContent](iconizer.item.addon); }, getItem(doc) { if (iconizer.item) { if (iconizer.item.ownerDocument == doc) return iconizer.item; iconizer.handleEvent(); } var item = doc.createElement("div"); item.id = id; for(var lab of this.labels) item.appendChild( doc.createElement("panel-item") ).append(lab); item.onclick = this.click; doc.ownerGlobal.addEventListener("unload", iconizer); return iconizer.item = item; }, get labels() { delete this.labels; this.click = this.click.bind(this); if (id in g) return this.labels = (iconizer = g[id]).labs; g[id] = iconizer; var css = "", ind = 0, arr = []; var push = (ind, icon) => { var chromeImg = `chrome://custombuttons/content/${id + ind}`; arr.push(["override", chromeImg, icon]); return chromeImg; } var labs = iconizer.labs = Object.keys(this).filter(key => { var res = String(this[key]).startsWith('"'); if (!res) return false; ind++; var icon = this[key + "_i"]; if (icon) css += `\n\t#${ id } > panel-item:nth-child(${ind}) {\n\t\t--icon: url(${ push(ind, icon) }) !important;\n\t}`; return true; }); var ams = Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup); var mUri = Services.io.getProtocolHandler("resource").getSubstitution("custombuttons-modules"); iconizer.iconHelper = ams.registerChrome(mUri, arr); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var md = "@-moz-document url(chrome://mozapps/content/extensions/aboutaddons.html) {"; var uri = Services.io.newURI("data:text/css;charset=utf-8," + encodeURIComponent(md + css + "\n}")); var args = [uri, sss.USER_SHEET]; sss.loadAndRegisterSheet(...args); iconizer.handleEvent = function() { if (!this.item) return; this.item.ownerGlobal.removeEventListener("unload", this); this.item.remove(); this.item = null; } iconizer.destroy = function() { delete g[id]; this.handleEvent(); sss.unregisterSheet(...args); this.iconHelper.destruct(); } return this.labels = labs; } }, true, gBrowser.tabpanels || 1))("CBAddonsMenuExt", Cu.import("resource://gre/modules/Services.jsm", {}), {});
Отредактировано solombala (04-12-2019 17:04:39)
Отсутствует
У вас не работает. У меня работает.
Взял эту кнопку: https://forum.mozilla-russia.org/viewto … 10#p775310, затем заменил этот код:
this.handleClick = function(evt) { var node = evt.target; if (node.nodeName != "button" || node.parentNode == hbox) return; var v1 = node.getAttribute("value1"); var v2 = node.getAttribute("value2"); if (v2) v2 = "=" + v2.replace("%clipboard%", gClipboard.read()); var bb1 = "[" + v1 + (v2 || "") + "]"; var bb2 = "[/" + v1 + "]"; var box = content.document.activeElement; var txt = box.value; var s = box.selectionStart; var e = box.selectionEnd; var bef = txt.substring(0, s); var mid = txt.substring(s, e); var aft = txt.substring(e); var ins = bb1.replace(/%copy%|%move%/, mid) + (v2 == "=%move%" ? "" : mid) + bb2; var val = bef + ins + aft; box.value = val; box.selectionStart = s; box.selectionEnd = s + ins.length; // box.focus(); }
Отредактировано kokoss (04-12-2019 18:42:38)
Win7
Отсутствует
Зашел по ссылке http://custombuttons.mozdev.org/installation.html
Последняя версия от 2011 на мой свежий Firefox не ставится.
А тут люди вроде используют, обсуждают.
Люди добрые! Как мне получить работающую версию этого замечательного плагина?
Отредактировано Eugene20212021 (04-12-2019 21:57:53)
Отсутствует
Dumby
Нельзя глянуть? FindBar в 71 блекнет в ini , приходится в код вставлять и жмакать пару раз , что ни есть гуд.
/*Initialization Code*/ ((bar, button = true, insertAtTop = true, ctrlFcloseFinbar = false) => ({ init(parent) { var has = bar = parent.querySelector("#appcontent > findbar"); has || this.initFinbar(parent); var lo = bar.linkedObject; lo.listenCtrlF = ctrlFcloseFinbar ? listen => listen ? addEventListener("keydown", lo, true) : removeEventListener("keydown", lo, true) : () => {}; has && !bar.hidden && lo.listenCtrlF(true); if (button) self._handleClick = () => bar.hidden ? bar.startFind(bar.FIND_NORMAL) : bar.collapsed || bar.close(); addDestructor(lo.destroy, lo); }, destroy(reason) { if (reason[5] != "e") return; bar.close(); bar._browser = {}; bar.remove(); this.setProgressListener(false); for(var key of ["gFindBar", "gFindBarInitialized"]) Object.defineProperty(window, key, this[key]); gBrowser[this.gBrKey] = this[this.gBrKey]; Services.ppmm.removeDelayedProcessScript(this.url); Services.ppmm.loadProcessScript("data:," + encodeURIComponent(` Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_DEFAULT && Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_CONTENT || (nsvo => { var proto = nsvo.Finder.prototype; if ("_requestMatchesCount" in proto) { proto.requestMatchesCount = proto._requestMatchesCount; delete proto._requestMatchesCount; } })(Cu.import("resource://gre/modules/Finder.jsm", {}));` ) , false); }, initFinbar(parent) { for(var tab of gBrowser.tabs) { if (!tab._findBar) continue; tab._findBar.browser = null; tab._findBar._browser = {}; tab._findBar.remove(); delete tab._findBar; } bar = document.createXULElement("findbar"); var p = new Proxy({}, {get: () => () => {}}); bar._browser = {finder: p, messageManager: p}; parent.insertBefore(bar, insertAtTop ? parent.firstChild : null); bar.linkedObject = this; ["gFindBar", "gFindBarInitialized"].forEach((key, ind) => { this[key] = Object.getOwnPropertyDescriptor(window, key); delete window[key]; window[key] = ind ? true : bar; }); var key = "getCachedFindBar" in gBrowser ? "getCachedFindBar" : "getFindBar"; this[this.gBrKey = key] = gBrowser[key]; gBrowser[key] = () => bar; [ "close", "startFind", "onMatchesCountResult", "_updateMatchesCount", "_onBrowserKeypress", "receiveMessage" ].forEach((key, ind) => { var func = bar[key].bind(bar); bar[key] = ind ? (...args) => this[key](...args) || func(...args) : (...args) => func(...args) || this[key](...args); }); this.url = "data:," + encodeURIComponent(` Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_DEFAULT && Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_CONTENT || (nsvo => { var proto = nsvo.Finder.prototype; if ("_requestMatchesCount" in proto) return; proto._requestMatchesCount = proto.requestMatchesCount; proto.requestMatchesCount = ${ this.newRequestMatchesCount } })(Cu.import("resource://gre/modules/Finder.jsm", {}));` ); delete this.newRequestMatchesCount; Services.ppmm.loadProcessScript(this.url, true); }, newRequestMatchesCount: async function requestMatchesCount(aWord, aLinksOnly) { if (typeof aLinksOnly != "boolean") { var {linksOnly, data} = aLinksOnly; aLinksOnly = linksOnly; this.entireWord = data.entireWord; this.caseSensitive = data.caseSensitive; this.onModalHighlightChange(data.useModalHighlight); this.onHighlightAllChange(data.highlightAll); data.highlightAll && await this.highlighter.highlight(true, aWord, linksOnly); this._iterator && this._iterator.reset(); var obj; Object.defineProperty(this, "_currentMatchesCountResult", { configurable: true, enumerable: true, get: (val = obj) => { if (val) { if (!val.total) val.total = new Number(0); val.currentFound = val._currentFound; } return obj = val; }, set: val => { if (val) return obj = val; delete this._currentMatchesCountResult; return obj = this._currentMatchesCountResult = val; } }); var lfr = this._lastFindResult; lfr !== null && lfr != Ci.nsITypeAheadFind.FIND_NOTFOUND || Object.defineProperty(this, "_lastFindResult", { configurable: true, enumerable: true, get: () => null, set: val => { if (val == Ci.nsITypeAheadFind.FIND_WRAPPED) val = Ci.nsITypeAheadFind.FIND_FOUND; delete this._lastFindResult; return this._lastFindResult = val; } }); } this._requestMatchesCount(aWord, aLinksOnly); }, close() { bar.collaped = false; this.setProgressListener(false); this.setBrowser(null, null); }, startFind() { if (this.maybeCollapse(gBrowser.selectedBrowser)) return true; if (bar.hidden) this.setBrowser(300), this.setProgressListener(true); else if (!ctrlFcloseFinbar) setTimeout(() => this.updateMatchesCount(), 100); }, onMatchesCountResult(res) { if (!("currentFound" in res) || res.total == -1 || res.currentFound) return; bar._foundMatches.value = `${+res.total || "Нет"} совпадени${ bar.pluralForm.get(res.total, "е;я;й") }.`; bar._foundMatches.hidden = false; return true; }, _updateMatchesCount() { return true; }, _onBrowserKeypress(e) { if (!bar.hidden) return; if (!e.charCode) return true; this.setBrowser(300); this.setProgressListener(true); }, receiveMessage(msg) { msg.target = bar._browser; }, progressListenerAdded: false, setProgressListener(add) { if (add) { if (this.progressListenerAdded) return; this.progressListenerAdded = true; gBrowser.addProgressListener(this); this.listenCtrlF(true); } else { if (!this.progressListenerAdded) return; this.progressListenerAdded = false; gBrowser.removeProgressListener(this); this.listenCtrlF(false); } }, handleEvent(e) { if ( e.ctrlKey && e.code == "KeyF" && !e.shiftKey && !e.altKey && !bar.collapsed ) e.preventDefault(), e.stopPropagation(), bar.close(); }, updateMatchesCount() { var str = bar._findField.value; if (!str) return; var data = { entireWord: bar._entireWord, caseSensitive: bar._typeAheadCaseSensitive, highlightAll: bar._highlightAll, useModalHighlight: bar._useModalHighlight }; bar.browser.finder.requestMatchesCount( bar._findField.value, {linksOnly: bar._findMode == bar.FIND_LINKS, data} ); }, maybeCollapse(br) { return br.isSyntheticDocument || br.documentContentType == "application/vnd.mozilla.xul+xml"; }, setBrowser(updateDelay, br = gBrowser.selectedBrowser) { if (bar._browser != br) { var b = bar._browser; if (b) { b.messageManager.removeMessageListener("Findbar:Mouseup", bar); b.finder.removeResultListener(bar); bar._highlightAll && b.finder.highlight(false); } if (br) { br.messageManager.addMessageListener("Findbar:Mouseup", bar); bar._updateBrowserWithState(); } bar._browser = br; } if (!br) return; bar._updateStatusUI(); bar._foundMatches.value = ""; br.finder.addResultListener(bar); if ( !(bar.collapsed = this.maybeCollapse(br)) && br.currentURI.spec != "about:blank" && updateDelay !== null ) updateDelay ? setTimeout(this.updateMatchesCount, updateDelay) : this.updateMatchesCount(); }, onStateChange(wpr, req, state) { state & Ci.nsIWebProgressListener.STATE_STOP && this.setBrowser(); }, onLocationChange(wpr, req) { req || Components.stack.formattedStack.includes("SessionStore.jsm") || this.setBrowser(); } }).init(document.getElementById("appcontent")))();
Отсутствует
Что делает эта кнопка? // Дв.клик по панели вкладок........... ||| Понять не могу, какая панель?
Насчет BBCode, тоже все сделал как надо заменил и подставил в конец, не пашет.
Отредактировано func4ptch4 (05-12-2019 22:17:26)
Отсутствует
func4ptch4
Здесь обе эти кнопки. Работают даже в 73.
Дв.клик по вкладке&Дв. клик по панели вкладок - двойной клик по панели вкладок закрывает все вкладки, а двойной клик по вкладке закрывает другие открытые вкладки. Проверь у себя - у меня все работает, как в однопроцессорном режиме, так и многопроцессорном.
Отредактировано Garalf (05-12-2019 22:49:33)
Отсутствует
Dumby
Больше не знаю к кому обратиться. В 71 прокси frigate https приказали долго жить.(TLS1.1) Кое-что я рихтанул в свойственной мне манере. процесс пошел, но не для гугла с его ютюбом. Короче, Socks 5 применил , но как proxy.pac применить ? Кнопки есть , а Pac как заделать с socks5 ? привожу примеры: Это для Http , к сожалению
Снят вопрос , все сделал.
Отредактировано solombala (06-12-2019 01:51:11)
Отсутствует
Dumby мда, не долго музыка играла
var {label} = gBrowser.selectedTab; var re = /(.+) (\(.+\)) \[(\d{4})[^\]]+\] (.+) (.+) (.+)/; re.test(label) && gClipboard.write( label.replace(re, "$1 $2 ($4) ($3)").replace(/ \/ /g, " - ") );
только я привык к этой кнопке, бац и обновления 71, СВ установлен, но кнопка исчезла из панели, в меню больше нет под ПКМ пункта про кнопку, что делать???
Отсутствует
Garalf
Проверил, и это удобно? у меня по привычке то что по стандарту.
И по привычке тыкаю а там все окна бах и нет..) мда ну эту кнопку, да и 2-клик по вкладке тоже мне легче выборочно.
BBCode работает, вот бы еще меню вылазил по автопопапу, а так все норм.)
solombala, как решил? интересно.
Вроде сокс видел, а вот с авторизацией .pac не сделать.
Отредактировано func4ptch4 (06-12-2019 06:54:52)
Отсутствует
func4ptch4
Прокси нормальный нужен . Пример (сам прокси от фонаря, сам ищи )
var no_proxy = 'DIRECT';
{
var proxy_list = new Array(
'whoer.net',
'yandex.ua',
'yandex.ru',
'rutube.ru',
'ren.tv',
'yadi.sk',
'yandex.net',
'yandex.sx',
'naydex.net',
'youtube.com',
'static.yandex.sx',
'ok.ru',
'vk.com',
'hdrezka.ag',
'mail.ru',
'kinopoisk.ru',
'yastatic.net',
'yandex.sx',
'youtube.com',
'ya.ru',
'2ip.ru',
);
for (var i = 0; i < proxy_list.length; i++){
var value = proxy_list[i];
if (dnsDomainIs(host, '.' + value) || host === value) {
return proxy_server;
}
}
return no_proxy;
}
return no_proxy;
}
Отредактировано solombala (06-12-2019 12:19:29)
Отсутствует
Кстати это нельзя к профилю привязать, а не к диску? file:///D:/proxy/Proxy1.pac
У меня есть вот такая кнопка, если не ошибаюсь от Dumby:
(()=> { // Задать путь к файлу в папке chrome. .......... (({io, dirsvc, prefs}) => { var substitution = "chrome", dir = "UChrm"; var rph = io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); addDestructor(reason => reason[5] == "e" && rph.hasSubstitution(substitution) && rph.setSubstitution(substitution, null)); if (rph.hasSubstitution(substitution)) return; rph.setSubstitution(substitution, io.newFileURI(dirsvc.get(dir, Ci.nsIFile))); })(Services); })();
Далее в папку chrome в профиле я положил файл proxy.pac и в настройках прокси указал resource://chrome/proxy.pac.
У меня это работает в 68 ESR. Сработает ли в более новых версиях, я не знаю.
Отредактировано unter_officer (06-12-2019 15:57:55)
«The Truth Is Out There»
Отсутствует
unter_officer
В 68 тоже не работает ...
Ну, не знаю. У меня работает.
Отредактировано unter_officer (06-12-2019 18:02:50)
«The Truth Is Out There»
Отсутствует
unter_officer
Профиль где? В системе? У меня портабл и профиль в каталоге .
У меня портабл от portableapps.com и профиль в каталоге.
«The Truth Is Out There»
Отсутствует
Нельзя глянуть?
Я же говорил, что не хочу больше с этой темой связываться,
слишком сложно для меня. Ладно, подкрутил тяп-ляп кое-что.
Тестировать не буду, делать правильней и лучше не стану.
Вот, просто чтоб тебе совсем без ничего не остаться
((bar, button = true, insertAtTop = true, ctrlFcloseFinbar = false) => ({ init(parent) { var has = bar = parent.querySelector("#appcontent > findbar"); has || this.initFinbar(parent); var lo = bar.linkedObject; lo.listenCtrlF = ctrlFcloseFinbar ? listen => listen ? addEventListener("keydown", lo, true) : removeEventListener("keydown", lo, true) : () => {}; has && !bar.hidden && lo.listenCtrlF(true); if (button) self._handleClick = () => bar.hidden ? bar.startFind(bar.FIND_NORMAL) : bar.collapsed || bar.close(); addDestructor(lo.destroy, lo); }, destroy(reason) { if (reason[5] != "e") return; bar.close(); bar._browser = {}; bar.remove(); this.setProgressListener(false); if (!this.receiver) this.actorProto.receiveMessage = this.actorReceiveMessage; for(var key of ["gFindBar", "gFindBarInitialized"]) key in this && Object.defineProperty(window, key, this[key]); for(key of this.gBrKeys) gBrowser[key] = this[key]; Services.ppmm.removeDelayedProcessScript(this.url); Services.ppmm.loadProcessScript("data:," + encodeURIComponent(` (ai => ai.processType == ai.PROCESS_TYPE_DEFAULT || ai.processType == ai.PROCESS_TYPE_CONTENT)( Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime) ) && (nsvo => { var proto = nsvo.Finder.prototype; if ("_requestMatchesCount" in proto) { proto.requestMatchesCount = proto._requestMatchesCount; delete proto._requestMatchesCount; } })(Cu.import("resource://gre/modules/Finder.jsm", {}));` ) , false); }, initFinbar(parent) { for(var tab of gBrowser.tabs) { if (!tab._findBar) continue; tab._findBar.browser = null; tab._findBar._browser = {}; tab._findBar.remove(); delete tab._findBar; } bar = document.createXULElement("findbar"); var p = new Proxy({}, {get: () => () => {}}); bar._browser = {finder: p, messageManager: p}; parent.insertBefore(bar, insertAtTop ? parent.firstChild : null); bar.linkedObject = this; ["gFindBar", "gFindBarInitialized"].forEach((key, ind) => { var desc = Object.getOwnPropertyDescriptor(window, key); if (!desc.configurable) return; this[key] = desc; delete window[key]; window[key] = ind ? true : bar; }); var key = "getCachedFindBar" in gBrowser ? "getCachedFindBar" : "getFindBar"; this.gBrKeys = [key]; key = "isFindBarInitialized"; if (key in gBrowser) this.gBrKeys.push(key); this.gBrKeys.forEach((key, ind) => { this[key] = gBrowser[key]; gBrowser[key] = ind ? () => true : () => bar; }); var props = [ "close", "startFind", "onMatchesCountResult", "_updateMatchesCount", "_onBrowserKeypress" ]; if ((this.receiver = "receiveMessage" in bar)) props.push("receiveMessage"); else { this.actorProto = Object.getPrototypeOf( gBrowser.selectedBrowser.browsingContext.currentWindowGlobal.getActor("FindBar") ); this.actorReceiveMessage = this.actorProto.receiveMessage; this.actorProto.receiveMessage = msg => { if (msg.name == "Findbar:Keypress") bar._onBrowserKeypress(msg.data); else if (msg.name == "Findbar:Mouseup") bar.onMouseUp(); } } props.forEach((key, ind) => { var func = bar[key].bind(bar); bar[key] = ind ? (...args) => this[key](...args) || func(...args) : (...args) => func(...args) || this[key](...args); }); this.url = "data:," + encodeURIComponent(` (ai => ai.processType == ai.PROCESS_TYPE_DEFAULT || ai.processType == ai.PROCESS_TYPE_CONTENT)( Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime) ) && (nsvo => { var proto = nsvo.Finder.prototype; if ("_requestMatchesCount" in proto) return; proto._requestMatchesCount = proto.requestMatchesCount; proto.requestMatchesCount = ${ this.newRequestMatchesCount } })(Cu.import("resource://gre/modules/Finder.jsm", {}));` ); delete this.newRequestMatchesCount; Services.ppmm.loadProcessScript(this.url, true); var desc = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value"); var setValue = desc.set.bind(bar._findField); desc.set = val => Components.stack.formattedStack.includes( "set browser@chrome://global/content/elements/findbar.js" ) ? val : setValue(val); Object.defineProperty(bar._findField, "value", desc); }, newRequestMatchesCount: async function requestMatchesCount(aWord, aLinksOnly, aUseSubFrames = true) { if (aLinksOnly && aLinksOnly.constructor.name == "Object") { var {linksOnly, data} = aLinksOnly; aLinksOnly = linksOnly; this.entireWord = data.entireWord; this.caseSensitive = data.caseSensitive; this.onModalHighlightChange(data.useModalHighlight); this.onHighlightAllChange(data.highlightAll); data.highlightAll && await this.highlighter.highlight(true, aWord, linksOnly); this._iterator && this._iterator.reset(); var obj; Object.defineProperty(this, "_currentMatchesCountResult", { configurable: true, enumerable: true, get: (val = obj) => { if (val && val._currentFound) val.total = Math.floor(val.total) + .0001; return obj = val; }, set: val => { if (val) { val.total = 10000; return obj = val; } delete this._currentMatchesCountResult; return obj = this._currentMatchesCountResult = val; } }); } return await this._requestMatchesCount(aWord, aLinksOnly, aUseSubFrames); }, close() { bar.collaped = false; this.setProgressListener(false); this.setBrowser(null, null); }, startFind() { if (this.maybeCollapse(gBrowser.selectedBrowser)) return true; if (bar.hidden) this.setBrowser(300), this.setProgressListener(true); else if (!ctrlFcloseFinbar) setTimeout(() => this.updateMatchesCount(), 100); }, get pf() { delete this.pf; return this.pf = bar.pluralForm || ChromeUtils.import( "resource://gre/modules/PluralForm.jsm" ).PluralForm; }, onMatchesCountResult(res) { if (res.total <= 1000) return; var strTotal = String(res.total); var found = strTotal.includes("."); if (found) strTotal = strTotal.split(".")[0]; if ((res.total = +strTotal.slice(-4)) >= 1000) { res.total = -1; return; } if (res.current > 1000) res.current = +String(res.current).slice(-4); if (res.current && found) return; bar._foundMatches.value = `${+res.total || "Нет"} совпадени${ this.pf.get(res.total, "е;я;й") }.`; bar._foundMatches.hidden = false; return true; }, _updateMatchesCount() { return true; }, _onBrowserKeypress(e) { if (!bar.hidden) return; if (!e.charCode) return true; this.setBrowser(300); this.setProgressListener(true); }, receiveMessage(msg) { msg.target = bar._browser; }, progressListenerAdded: false, setProgressListener(add) { if (add) { if (this.progressListenerAdded) return; this.progressListenerAdded = true; gBrowser.addProgressListener(this); this.listenCtrlF(true); } else { if (!this.progressListenerAdded) return; this.progressListenerAdded = false; gBrowser.removeProgressListener(this); this.listenCtrlF(false); } }, handleEvent(e) { if ( e.ctrlKey && e.code == "KeyF" && !e.shiftKey && !e.altKey && !bar.collapsed ) e.preventDefault(), e.stopPropagation(), bar.close(); }, updateMatchesCount() { var str = bar._findField.value; if (!str) return; var data = { entireWord: bar._entireWord, caseSensitive: bar._typeAheadCaseSensitive, highlightAll: bar._highlightAll, useModalHighlight: bar._useModalHighlight }; bar.browser.finder.requestMatchesCount( bar._findField.value, {linksOnly: bar._findMode == bar.FIND_LINKS, data} ); }, maybeCollapse(br) { return br.isSyntheticDocument || br.documentContentType == "application/vnd.mozilla.xul+xml"; }, setBrowser(updateDelay, br = gBrowser.selectedBrowser) { if (bar._browser != br) { var b = bar._browser; if (b) { this.receiver && b.messageManager .removeMessageListener("Findbar:Mouseup", bar); b.finder.removeResultListener(bar); bar._highlightAll && b.finder.highlight(false); } if (br) { this.receiver && br.messageManager .addMessageListener("Findbar:Mouseup", bar); bar._updateBrowserWithState(); } bar._browser = br; } if (!br) return; bar._updateStatusUI(); bar._foundMatches.value = ""; br.finder.addResultListener(bar); if ( !(bar.collapsed = this.maybeCollapse(br)) && br.currentURI.spec != "about:blank" && updateDelay !== null ) updateDelay ? setTimeout(this.updateMatchesCount, updateDelay) : this.updateMatchesCount(); }, onStateChange(wpr, req, state) { state & Ci.nsIWebProgressListener.STATE_STOP && this.setBrowser(); }, onLocationChange(wpr, req) { req || wpr.isLoadingDocument || gBrowser.selectedTab.hasAttribute("pending") || this.setBrowser(); } }).init(document.getElementById("appcontent")))();
только я привык к этой кнопке, бац и обновления 71
Не подходит тебе CB, не те нынче времена.
Может лучше сделай себе аналогичный WebExtensions.
Прослужит дольше, а если сводить его в мазилу на приём к подписологу,
то вообще будет вечное, разве что только зависимо от рутрекера.
Собственно нужно два текстовых файла и парочка иконок.
Запаковываешь всё это в зип-папку, называешь как_нибудь.xpi
и всё, можно устанавливать. Простенький набросок:
{ "manifest_version": 2, "name": "Some WebExtensions Name", "version": "1.0", "description": "Some WebExtensions Description", "applications": { "gecko": { "id": "{1136c9cb-3899-41d3-8a71-61d74140780d}" } }, "icons": { "32": "webextensions-image32.png" }, "permissions": [ "tabs", "clipboardWrite" ], "browser_action": { "default_icon": "button-image32.png", "default_title": "Some Button Title" }, "background": { "scripts": ["background.js"] } }
background.js
var re = /(.+) (\(.+\)) \[(\d{4})[^\]]+\] (.+) (.+) (.+)/; var query = {active: true, currentWindow: true}; browser.browserAction.onClicked.addListener(async () => { var [tab] = await browser.tabs.query(query); var {title} = tab; re.test(title) && navigator.clipboard.writeText( title .replace(re, "$1 $2 ($4) ($3)") .replace(/ \/ /g, " - ") ); });
Отсутствует
Dumby
Еще не было случая , что бы ты промахнулся... Ф, что на это скажите? https://forum.mozilla-russia.org/viewto … 88#p775488
Лажа какая-то...?
Отредактировано solombala (06-12-2019 22:44:00)
Отсутствует
Dumby я сделал это!!!!!!!! Ох чувак, ну ту крут! Я в глубочайшем восторге! Я хочу знать как это сделано!? Столько лет за компом, надо было языки программирования изучать...
Добавлено 07-12-2019 00:18:55
еще хотел замену двоеточию на юникодный символ,
.replace(/ \: /g, " ׃ ") что то не так сделал, плиз покажи как
Отредактировано Mrakobes666 (07-12-2019 00:18:55)
Отсутствует
что на это скажите?
Ну, попробовал проверить на 73. Такие наблюдения
Создал кнопку и расположил её первой на Панели меню.
Установил network.proxy.type - 2
и network.proxy.autoconfig_url - resource://chrome/proxy.pac
Рестарт. В консоли вижу сообщение:
PAC-alert: [object PACResolutionThreadGlobal]
и, следом за ним, второе:
PAC file installed from file:///C:/Users/Admin/AppData/Roaming/-bla-bla-bla-/chrome/proxy.pac
Так что сама концепция, видимо, работает.
Но, если переместить кнопку на другой тулбар,
который ниже и там кнопки инициализируются позже,
или, даже, дальше вправо по Панели меню,
то никаких подобных сообщений в консоли уже не наблюдается.
То есть, полагаю, здесь весьма скользкая тайминг-грань.
Если так уж прямо нужно «заресурсить» папку chrome,
то надёжнее видоизменить код и расположить его в config.js
// try {(ios => ios.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution("chrome", ios.newFileURI( Cc["@mozilla.org/file/directory_service;1"] .getService(Ci.nsIDirectoryService) .QueryInterface(Ci.nsIProperties) .get("UChrm", Ci.nsIFile) )) )(Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService));} catch(ex) {Cu.reportError(ex);}
.replace(/ \: /g, " ׃ ") что то не так сделал, плиз покажи как
Здесь у тебя идёт замена последовательностей
«пробел — двоеточие — пробел» на последовательность
«пробел — HEBREW PUNCTUATION SOF PASUQ (\u05C3) — пробел».
Код вполне рабочий, обратный экранирующий слэш
в этой регулярке не нужен, но и не мешает.
В примере строки (к сожалению, единственном) в твоём
изначальном вопросе, искомая последовательность не встречается,
так что замысел непонятен, а угадатель из меня никакой.
Отсутствует
так что замысел непонятен, а угадатель из меня никакой
прошу прощения, вот:
Рэмбо: Последняя кровь / Rambo: Last Blood (Адриан Грюнберг / Adrian Grunberg) [2019, США, боевик, триллер, приключения, HDRip] Dub (iTunes)
чтобы имя файла сохранялось я заменяю двоеточие на юникодную крякозябру, спасибо майкрософту...также меняю вопросительный знак на финтифлюшку
Рэмбо׃ Последняя кровь - Rambo׃ Last Blood (Адриан Грюнберг - Adrian Grunberg) (2019)
в этом примере визуально осталось двоеточие, но оно в символах unicode
еще бы ? заменить на .. к примеру ‽
как написать строку реплейс?
Добавлено 07-12-2019 09:43:36
.replace(/: /g, "׃ ")
.replace(/? /g, "‽ ")
не пашет
Отредактировано Mrakobes666 (07-12-2019 09:43:36)
Отсутствует
не пашет
Так у тебя строка с «Рэмбо» не подходит под твой основной RegExp,
потому что она, в отличие от строки с «Как чокнутые», не заканчивается на « :: RuTracker.org».
То, что в предполагаемой результирующей строке от строки с «Рэмбо»
отсутствует напрашивающийся «(Dub (iTunes))» окончательно запутывает ситуацию.
Замысел остаётся непонятен. Тогда наугад — обе строки подходят под RegExp,
и двоеточие, соответственно, будет успешно реплейситься так, как у тебя написано,
но «(Dub (iTunes))» во второй результирующей строке будет.
Вот такой новый RegExp:
var re = /(.+) (\(.+\)) \[(\d{4})[^\]]+\] (.+ \((.+)\))( .+)?/;
Отсутствует
Dumby вот досада, я сам забыл, что под регулярку попадает строка из названия вкладки, сам же это придумал, выходит Вы лучше меня знаете мои же запросы)))
совершенно верно, эта строка:
Рэмбо
Последняя кровь / Rambo
Last Blood (Адриан Грюнберг / Adrian Grunberg) [2019, США, боевик, триллер, приключения, HDRip] Dub (iTunes) :: RuTracker.org
Должна стать этим:
Рэмбо
Последняя кровь - Rambo
Last Blood (Адриан Грюнберг - Adrian Grunberg) (Dub (iTunes)) (2019)
т.е. хотел в том случае, если встречается двоеточие заменять его на юникод, а также вопросительный знак на юникодный же символ
признаюсь, что запутал Вас
var re = /(.+) (\(.+\)) \[(\d{4})[^\]]+\] (.+ \((.+)\))( .+)?/; var query = {active: true, currentWindow: true}; browser.browserAction.onClicked.addListener(async () => { var [tab] = await browser.tabs.query(query); var {title} = tab; re.test(title) && navigator.clipboard.writeText( title .replace(re, "$1 $2 ($4) ($3)") .replace(/ \/ /g, " - ") ); });
этот код работает правильно, информацию об аудиодороге (Dub (iTunes)) вставляет в нужное место
теперь бы дополнить строкой по замене двух запрещенных символов
на
соответственно
чтобы было
Куда ты пропала, Бернадетт
/ Where'd You Go, Bernadette (Ричард Линклейтер / Richard Linklater) [2019, США, драма, комедия, детектив, BDRip] Dub (iTunes) :: RuTracker.org
стало
Куда ты пропала, Бернадетт
- Where'd You Go, Bernadette (Ричард Линклейтер - Richard Linklater) (Dub (iTunes)) (2019)
Отредактировано Mrakobes666 (07-12-2019 13:23:26)
Отсутствует