Dumby
#window-modal-dialog::backdrop {
background-color: inherit !important;
}
Не тухнет, но здесь не помогло. Стоит modal выпасть ,back кнопка тухнет, а после очистки опять горит, а, ссылок там уже нет. Надо или перезапуск делать или новую открывать...
Ясен пень, SanitizeDialog старой FF выпадает окном ,а не modal и не бьет по кнопкам
Отредактировано green25 (23-03-2025 18:50:16)
Отсутствует
Так… значит мне ничего нового прописывать уже было не нужно — заработало только либо после очистки startupCache, либо всё-таки после полного удаления расширения и повторной установки (paxmod, ибо с bootstrap`ом мне ещё лет 6 назад пришлось возиться, так и не добившись результата), довелось завести хотя бы "ночной режим"… Сразу определить работоспособность хотя бы кнопки "Ночной режим" не получилось — после очисти startupCache на спех проверялось только в about:* страницах, где, оказалось, она не работает, но после повторного добавления, наконец заработала (несмотря на то, что «затемнена», как и надпись, если добавлять в специальное "»" подменю). А вот с переключалкой настроек проблемы остались — к тому моменту уже было опробован другой код из какого-то сообщения этой темы (то ли за 21-й то ли 23/24г), но над ним мне тогда пришлось полдня повозиться, чтоб предварительно убедиться в том, что убираемые процедуры и переменные из подозрительного кода не используются в остальных его местах — скорее всего где-то тут была "промашка"…
Отсутствует
green25
В 115 есть отдельный флаг CLEAR_SESSION_HISTORY
А в нынешних версиях уже нет, свалили докучи в CLEAR_HISTORY
В любом случае, для удаления всего,
просто рассылается топик без третьего аргумента:
Services.obs.notifyObservers(null, "browser:purge-session-history");
Отсутствует
Dumby подскажи пожалуйста код скрытия контекстного меню, если код предназначен только для страницы, а не для выделенного текста или медиа и ссылок
Для выделенного текста я использую
addEventListener('popupshowing', e=> { if (e.target != e.currentTarget) return; var sel = gContextMenu.isTextSelected; menu.hidden = !sel; }, false, contextMenu);
(this.contextviewpageinfo = { init(that) { var contextMenu = this.contextMenu = document.querySelector("#contentAreaContextMenu"); if (!contextMenu) return; contextMenu.addEventListener("popupshowing", this); // that.unloadlisteners.push("contextviewpageinfo"); }, handleEvent(e) { if (gContextMenu.isTextSelected || gContextMenu.onImage || gContextMenu.onLink || gContextMenu.webExtBrowserType === "popup") return; if ( document.getElementById("viewPageInf") ) return; var menuitem = document.createXULElement("menuitem"); menuitem.setAttribute("id", "viewPageInf") menuitem.setAttribute("label", "Информация о странице"); menuitem.setAttribute("oncommand", "_viewPageInfo();"); menuitem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACp0lEQVQ4jV2TPW9cVRCGn3fOuffu9Xo3TnCEkANYQotB2WJpUqWwJSqIUuQPRKKlsAUFpeUmEpXXEv+ACClFitQowmUIMmxASowIkjuQk9jr/fDd7F3fQ7HWdcxI04zmfc47RzPif9G4cXdR0iqy5flL9VYRAoe9rCNpG9nW7v1be2/2qxR+/v0c0vp7C/NrV5euMCkijoYTXucnEALDYcaLwx7DLGsjbTy7d7NbAk7FP12/ttSq1uZ48vyYLA/UZhwg+qMCZ5A6GGVDesODDtLK0x8+69rUh9avX1tqWVzn0dMhWR4A8eDOxzy48xEyEWQcB4O0Tlq73JK5dQBr3Li7+P7C/NpsbY4nf2dTTxKYyhnNG/KGeQfeEVXrRJXqWvP2w0UvafXq0rv8+vz4TCwhJz795s/p62ZlHQkJ4uoFTnqvVj2y5UnwZOP8XNPj75rlTze/3MV5YU4IoQCJS5Bzy3b5rXrraDgBQQEMRgUH/QmNL/4oAXHiiSueJPUkM554JmK2FlGppC1fBBjnBeNJ4HAwQWZEicN7KwFRxeHjaU1mSDCbBIZ9jx0cHXfyyQkvD3NCAHPCnOEid85BUvEkMxGV6jQvzkVk45OOSdp+dTDAOZDpFCCcK3cMnziiiidJp+JaPcZZgZzfNmRbR4MBl2aENE0zIXc2go8cUeKJU0+lGvPhlYh/9kfI3Jbt3r+1N85ftykyUkcJ6Ww2SsCPX7+Nc4aPHY2FiH5vzL8vx+2dzeaeP93Ejfykv+zMtwKzAHzy1V8kaVTOXavFfDAP3f0BP+8cdGS2AWAAz+7d7CKtSL22D11U5MQBqha4GAfeqQYuKOP33/Z59PhFmxBWfvm2cXZMb0bz9sNFma3K+eUkSVs+dozyoiPnt2Vua2ezee6c/wN/E94boB6vcgAAAABJRU5ErkJggg=="); menuitem.className = "menuitem-iconic"; menuitem._viewPageInfo = this.viewPageInfo.bind(this); addDestructor(function() { contextMenu.removeChild( menuitem ) }); (this.contextMenu.querySelector("#context-viewsource") || this.contextMenu.lastElementChild).after(menuitem); this.handleEvent = () => menuitem.hidden = (gContextMenu.isTextSelected || gContextMenu.onImage || gContextMenu.onLink || gContextMenu.webExtBrowserType === "popup"); }, viewPageInfo() { BrowserCommands.pageInfo( gContextMenu.contentData.docLocation, "generalTab", gContextMenu.PageInfo, null, gContextMenu.browser ); }, }).init(this);
((id, g) => addDestructor(reason => id in g && g[id].destroy(reason)) || id in g || ({ actions: [{ title: "Перевод из буфера", tooltip: "Перевод из буфера", iconURL: gticon, id: "TranslateBufer1", _insertBeforeActionID: "copyURL", onCommand: (e, btn) => ujs_google_translat('auto|ru') }], init() { g[id] = this; this.actions = this.actions.map(action => { action.extensionID = "custombuttons@xsms.org"; return g.PageActions.addAction(new g.PageActions.Action(action)); }); }, destroy(reason) { if (reason[5] != "e") return; delete g[id]; for(var action of this.actions) action.remove(); } }).init())( "CBPageActionsMaker", ChromeUtils.importESModule("resource:///modules/PageActions.sys.mjs", {}) );
И еще можно на примере показать как добавлять в новый сайдбар (боковую панель) элементы, на пример самое простое - загрузки
Отредактировано Andrey_Krropotkin (28-03-2025 07:39:48)
Отсутствует
Чья кнопка ? Перестала менять ,кроме строки адреса...Раньше в любом поиске меняла....
(keybUtils => { var btn = this; var listener = { handleEvent(e) { if(e.target != btn) return; e.preventDefault(); e.stopPropagation(); this.switch(); }, switch() { var br = document.activeElement; br && br.localName == "browser" && br.isRemoteBrowser ? br.messageManager.loadFrameScript(this.url, false) : this.keybUtils.switchSelKeybLayout(); }, get url() { delete this.url; return this.url = `data:;charset=utf-8,(${ encodeURIComponent(keybUtils) }).switchSelKeybLayout()`; }, get keybUtils() { delete this.keybUtils; var url = "data:;charset=utf-8,this.keybUtils = " + encodeURIComponent(keybUtils); Services.scriptloader.loadSubScript(url, this); this.keybUtils.button = btn; this.keybUtils.getFocusedElement = function(_subCall, _focusFixed) { if( !_focusFixed && "closeMenus" in window && document.commandDispatcher.focusedElement == this.button ) { closeMenus(this.button); setTimeout(function(_this) { _this.switchSelKeybLayout(_subCall, true); }, 0, this); return; } return document.commandDispatcher.focusedElement; } return this.keybUtils; } }; if(btn instanceof XULElement && addEventListener.length > 3) { addEventListener("command", listener, true, this.parentNode); } listener.switch(); })(`{ //== Options noSelBehavior: { // Shift+Home ctrlKey: false, altKey: false, shiftKey: true, metaKey: false, keyCode: KeyEvent.DOM_VK_HOME, charCode: 1 }, // 0 - do nothing // 1 - convert all text // Or use object like following to simulate "keypress" event: /* noSelBehavior: { // Ctrl+Shift+Left ctrlKey: true, altKey: false, shiftKey: true, metaKey: false, keyCode: KeyEvent.DOM_VK_LEFT, charCode: 0 } */ convTableForward: { // ru -> en "\\"": "@", ":": "^", ";": "$", "?": "&", ",": "?", "/": "|", ".": "/", "э": "'", "б": ",", "ю": ".", "Ж": ":", "ж": ";", "Б": "<", "Ю": ">", "Э": "\\"", "х": "[", "ъ": "]", "ё": "\`", "Х": "{", "Ъ": "}", "Ё": "~", "№": "#", "Ф": "A", "ф": "a", "И": "B", "и": "b", "С": "C", "с": "c", "В": "D", "в": "d", "У": "E", "у": "e", "А": "F", "а": "f", "П": "G", "п": "g", "Р": "H", "р": "h", "Ш": "I", "ш": "i", "О": "J", "о": "j", "Л": "K", "л": "k", "Д": "L", "д": "l", "Ь": "M", "ь": "m", "Т": "N", "т": "n", "Щ": "O", "щ": "o", "З": "P", "з": "p", "Й": "Q", "й": "q", "К": "R", "к": "r", "Ы": "S", "ы": "s", "Е": "T", "е": "t", "Г": "U", "г": "u", "М": "V", "м": "v", "Ц": "W", "ц": "w", "Ч": "X", "ч": "x", "Н": "Y", "н": "y", "Я": "Z", "я": "z", __proto__: null }, //== End of options get convTableBackward() { var ctb = { __proto__: null }; var ctf = this.convTableForward; for(var c in ctf) ctb[ctf[c]] = c; delete this.convTableBackward; return this.convTableBackward = ctb; }, inPrimaryLayout: function(s) { for(var i = 0, l = s.length; i < l; ++i) { var c = s.charAt(i); if(c in this.convTableForward) return true; if(c in this.convTableBackward) return false; } return false; }, switchKeybLayout: function(s, convTable) { var res = ""; for(var i = 0, l = s.length; i < l; ++i) { var c = s.charAt(i); res += c in convTable ? convTable[c] : c; } return res; }, getFocusedElement: function() { return Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager) .getFocusedElementForWindow(content, true, {}); }, switchSelKeybLayout: function(_subCall, _focusFixed) { var fe = this.getFocusedElement(_subCall, _focusFixed); if(!fe) return; if(fe instanceof HTMLInputElement || fe instanceof HTMLTextAreaElement) { var ta = fe; try { var val = ta.value; var sel = val.substring(ta.selectionStart, ta.selectionEnd); } catch(e) { // Non-text HTMLInputElement return; } if(!sel && val && this.noSelBehavior && !_subCall) { if(this.noSelBehavior == 1) { ta.selectionStart = 0; ta.selectionEnd = val.length; sel = val; } else { this.handleNoSel(ta); return; } } if(!sel) return; var res = this.switchKeybLayout( sel, this.inPrimaryLayout(sel) ? this.convTableForward : this.convTableBackward ); if(res != sel) this.insertText(ta, res); } else if(fe.contentEditable == "true") { var doc = fe.ownerDocument; var docURI = doc.documentURI; if( docURI.substr(0, 5) == "data:" && docURI.indexOf("chrome://browser/skin/devtools/") != -1 ) { //~ todo: seems like we only can use paste from clipboard here... return; } var sel = doc.defaultView.getSelection(); var rng = sel.rangeCount && sel.getRangeAt(0); var tmpNode; if(!rng || rng.collapsed) { if(!this.noSelBehavior || _subCall) return; if(this.noSelBehavior == 1) { var r = doc.createRange(); r.selectNodeContents(fe); sel.removeAllRanges(); sel.addRange(r); tmpNode = fe.cloneNode(true); } else { this.handleNoSel(fe); return; } } else { tmpNode = doc.createElementNS("http://www.w3.org/1999/xhtml", "div"); tmpNode.appendChild(rng.cloneContents()); } var orig = tmpNode.innerHTML; var convTable = this.inPrimaryLayout(tmpNode.textContent) ? this.convTableForward : this.convTableBackward; var _this = this; var parseChildNodes = function(node) { if(node instanceof Element) { var childNodes = node.childNodes; for(var i = childNodes.length - 1; i >= 0; --i) parseChildNodes(childNodes[i]); } else if(node.nodeType == node.TEXT_NODE) { var text = node.nodeValue; var newText = _this.switchKeybLayout(node.nodeValue, convTable); if(newText != text) node.parentNode.replaceChild(doc.createTextNode(newText), node); } } parseChildNodes(tmpNode); var res = tmpNode.innerHTML; if(res != orig) doc.execCommand("insertHTML", false, res); } }, handleNoSel: function(node) { this.select(node); this.switchSelKeybLayout(true); }, select: function(node) { var e = this.noSelBehavior; if(!e || typeof e != "object") return; var evt = node.ownerDocument.createEvent("KeyboardEvent"); evt.initKeyEvent( "keypress", true /*bubbles*/, true /*cancelable*/, node.ownerDocument.defaultView, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.keyCode, e.charCode ); node.dispatchEvent(evt); }, insertText: function(ta, text) { //var editor = ta.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor var editor = ta.editor .QueryInterface(Components.interfaces.nsIPlaintextEditor || Ci.nsIEditor); if(editor.flags & editor.eEditorReadonlyMask) return; var sTop = ta.scrollTop; var sHeight = ta.scrollHeight; var sLeft = ta.scrollLeft; // var sWidth = ta.scrollWidth; if(text) editor.insertText(text); else editor.deleteSelection(0, 0); ta.scrollTop = sTop + (ta.scrollHeight - sHeight); ta.scrollLeft = sLeft; // + (ta.scrollWidth - sWidth); } }`);
Отсутствует
Dumby
Добавляю закладку !
Стоит появится этому и все identity-icon-box - пропадает ?
СНЯТ ВОПРОС Было:
#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] {
pointer-events: none;
-moz-user-focus: ignore;
}
Надо:
#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] {
pointer-events: inherit;
-moz-user-focus: ignore;
}
Отредактировано green25 (31-03-2025 08:19:04)
Отсутствует
Я считаю что в этом коде слишком перемудрено
А можно поподробнее?
По пунктам, где именно ты считаешь перемудрено.
в ошибках при редактировании любой кнопки в ошибках показывает такое сообщение -TypeError: this.cssProperties is undefined
Это, видимо, из-за options.cssInHelp
Либо переключить в false, либо, если прям очень надо,
то попробовать дописать после var optsOvr = options.codeMirror;
// if (isCSS) { var {generateCssProperties} = require("resource://devtools/server/actors/css-properties.js"); var {CssProperties, normalizeCssData} = require("resource://devtools/client/fronts/css-properties.js"); opts.cssProperties = new CssProperties(normalizeCssData({properties: generateCssProperties(document)})); }
Uncaught Error: Action with ID 'TranslateBufer1' already added
Ну так ChromeUtils.importESModule()
не возвращает ничего даже близко похожего на g
Можно разделить, PageActions отдельно,
а g, допустим, пусть будет SystemGlobal
((id, g, pa) => addDestructor(reason => id in g && g[id].destroy(reason)) || id in g || ({ actions: [{ title: "Перевод из буфера", tooltip: "Перевод из буфера", iconURL: gticon, id: "TranslateBufer1", _insertBeforeActionID: "copyURL", onCommand: (e, btn) => ujs_google_translat('auto|ru') }], init() { g[id] = this; this.actions = this.actions.map(action => { action.extensionID = "custombuttons@xsms.org"; return pa.addAction(new pa.Action(action)); }); }, destroy(reason) { if (reason[5] != "e") return; delete g[id]; for(var action of this.actions) action.remove(); } }).init())( "CBPageActionsMaker", Cu.getGlobalForObject(Cu), PageActions );
на примере показать как добавлять в новый сайдбар (боковую панель) элементы, на пример самое простое - загрузки
Нет такого «как добавлять».
Как-то насильно запихать разве что.
И, из кнопки это не слишком удобно, возможно что-то типа
(() => { var url = "about:downloads"; var img = "chrome://browser/skin/downloads/downloads.svg"; var id = "viewDownloadsSidebar"; var fluentFile = "browser/appmenu.ftl"; var fluentLabel = "appmenuitem-downloads"; var sc = SidebarController; var sep = document.querySelector("#sidebarMenu-popup > menuseparator"); if (sep) { var switcher = document.createXULElement("menuitem"); switcher.dataset.l10nId = fluentLabel; switcher.id = "sidebar-switcher-downloads"; switcher.addEventListener("command", () => sc.toggle(id)); sep.before(switcher); } var sb = sc.makeSidebar({ url, iconUrl: img, elementId: switcher?.id, menuL10nId: fluentLabel, revampL10nId: fluentLabel, menuId: "menu_downloadsSidebar" }); var popup = document.getElementById("viewSidebarMenu"); var menuitem = sc.createMenuItem(id, sb); popup.insertBefore(menuitem,popup.querySelector(".webextension-menuitem")); var maybeAddSidebar = sb => { var bars = sc.sidebars; bars.has(id) || bars.set(id, sb); } Object.defineProperty(sb, "hasOwnProperty", {value(prop) { prop == "extensionId" && setTimeout(maybeAddSidebar, 0, sb); return Object.hasOwn(sb, prop); }, configurable: true, enumerable: true}); sc.sidebars.set(id, sb); var br = sc.browser; var ls = `[href="${fluentFile}"]`; try {var tools = toolsNameMap;} catch {tools = defaultTools;} Object.defineProperty(tools, id, {get() { var doc = br.contentDocument; var cust = doc?.querySelector("sidebar-customize"); if (cust && !doc.head.querySelector(ls)) { var link = doc.createElement("link"); link.rel = "localization"; link.href = fluentFile; doc.head.append(link); link.l10nMap = cbu.dbg.ref("l10nMap", cust.constructor, 0).set(id, fluentLabel); } return "downloads"; }, configurable: true, enumerable: true}); var sm = sc.sidebarMain; var initSM = setTimeout.bind(null, () => { sc._toolsAndExtensions = null; sm.fluentStrings.addResourceIds([fluentFile]); window.dispatchEvent(new CustomEvent("SidebarItemAdded")); }); if (customElements.get("sidebar-main")) initSM(); else { var resolver = Promise.withResolvers(); Promise.any([customElements.whenDefined("sidebar-main"), resolver.promise]) .then(add => add && initSM()); } addDestructor(reason => { if (reason[5] != "e") return; if (sc.isOpen) { var cid = sc.currentID; if (cid == id) sc.hide(); else if (cid == "viewCustomizeSidebar") { var link = br.contentDocument.head.querySelector(ls); link.l10nMap.delete(id); link.remove(); } } menuitem.remove(); switcher?.remove(); sc.sidebars.delete(id); sc.toolsAndExtensions.delete(id); resolver?.resolve(); sm.fluentStrings?.removeResourceIds([fluentFile]); window.dispatchEvent(new CustomEvent("SidebarItemRemoved")); }); })();
Чья кнопка ?
Ничья. Это мод-перемод одной из наследия Infocatcher'а
Андрей когда-то нечто подобное спрашивал,
но там весьма развесисто в смысле правок.
Отсутствует
Bug 721336 - Ban sync XMLHttpRequest with chrome privileges (Firefox 138+)
Отсутствует
Content-Security-Policy: (Политика Report-Only) Настройки страницы блокируют выполнение обработчика события (script-src-attr), поскольку он нарушает следующую директиву: «script-src-attr 'none' 'report-sample' - что это за ошибки, почти во многих кнопках и скриптах
вроде разобрался, только с массивами не понятно
Отредактировано Andrey_Krropotkin (15-04-2025 22:55:48)
Отсутствует
Что делать. В ФФ после 115 скрипты кастомнык не работают.
try { (function() { var Cu = Components.utils; var {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); var sandbox = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal(), { wantComponents: true, sandboxName: "user_chrome_files" }); sandbox.Services = Services; Cu.evalInSandbox(` var Ci = Components.interfaces; var config = { subScript: {}, observe: function(aSubject, aTopic, aData) { if (aTopic == "domwindowopened" && aSubject instanceof Ci.nsIDOMWindow) { aSubject.addEventListener("DOMContentLoaded", function domLoad() { aSubject.removeEventListener("DOMContentLoaded", domLoad, true); var loc = aSubject.location; if (loc && loc.protocol == "chrome:") { try { config.subScript.user_chrome.loadIntoWindow(aSubject, loc.href); } catch(ex) { } } }, true); } else if (aTopic == "profile-after-change") { Services.obs.removeObserver(config, "profile-after-change"); var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append("user_chrome_files"); file.append("user_chrome.manifest"); if (!file.exists() || !file.isFile()) { this.removeObs(); return; } try { var reg = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); reg.autoRegister(file); } catch(ex) { this.removeObs(); return; } try { Services.scriptloader.loadSubScript("chrome://user_chrome_files/content/user_chrome.js", this.subScript, "UTF-8"); } catch(ex) { this.removeObs(); } } }, removeObs: function() { Services.obs.removeObserver(config, "domwindowopened"); } }; Services.obs.addObserver(config, "profile-after-change", false); Services.obs.addObserver(config, "domwindowopened", false); `, sandbox); })(); } catch(ex) {Cu.reportError(ex);}
Отсутствует
green25
Сразу бросается в глаза. Сейчас такая конструкция для всех resource://gre/modules/
ChromeUtils.importESModule("resource://gre/modules/Services.sys.mjs")
а дальше сам смотри
Отсутствует
green25 Попробуй var {Services} = Components.utils.getGlobalForObject(Components.utils);
Отсутствует
green25
Больше вариантов нет
Отсутствует
в 133 прошло, 137 - нет
config.js
// version, date year-month-day: 2025-1-17 (async () => { var file = Services.dirsvc.get("UChrm", Ci.nsIFile), iname; file.append("user_chrome_files"); file.append("user_chrome.manifest"); if (!file.exists() || !file.isFile()) return; switch (Services.appinfo.ID) { case "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}": // Firefox or etc. iname = "user_chrome.js"; break; case "{3550f703-e582-4d05-9a08-453d09bdfdc6}": // Thunderbird iname = "user_chrome_tb.js"; break; default: return; } Components.manager.QueryInterface(Ci.nsIComponentRegistrar) .autoRegister(file); var sandbox = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal(), { wantComponents: true, sandboxName: "UserChromeFiles", wantGlobalProperties: ["ChromeUtils"], }); Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/user_chrome/${iname}`, sandbox); })(); // (async xp => { var imprt, ids = [ "custombuttons@xsms.org", ]; if (Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).inSafeMode) return; if (Cr.NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) var {XPIInternal} = (imprt = url => Cu.import(url, {}))(xp); else { // Fx 101+ var g = Cu.getGlobalForObject(Cu), te = new g.TextEncoder(); var imp = g.ChromeUtils.import, {XPIInternal} = imp(xp); var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); var rph = ios.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); imprt = (url, id) => { var subst = te.encode(id).join(""); rph.setSubstitution(subst, ios.newURI(url)); return imp(`resource://${subst}/`); } } var load = async (file, id) => { var rootURI = XPIInternal.getURIForResourceInFile(file, ""); imprt(rootURI.resolve("startup.jsm"), id).start(rootURI); } var proto = XPIInternal.BootstrapScope.prototype; var func = proto._beforeCallBootstrapMethod; proto._beforeCallBootstrapMethod = () => { proto._beforeCallBootstrapMethod = func; for(var {id, loader, file} of XPIInternal.XPIStates.enabledAddons()) ids.includes(id) && !loader && load(file, id); } })("resource://gre/modules/addons/XPIProvider.jsm"); // try { (function() { var Cu = Components.utils; var {Services} = Components.utils.getGlobalForObject(Components.utils); var sandbox = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal(), { wantComponents: true, sandboxName: "user_chrome_files" }); sandbox.Services = Services; Cu.evalInSandbox(` var Ci = Components.interfaces; var config = { subScript: {}, observe: function(aSubject, aTopic, aData) { if (aTopic == "domwindowopened" && aSubject instanceof Ci.nsIDOMWindow) { aSubject.addEventListener("DOMContentLoaded", function domLoad() { aSubject.removeEventListener("DOMContentLoaded", domLoad, true); var loc = aSubject.location; if (loc && loc.protocol == "chrome:") { try { config.subScript.user_chrome.loadIntoWindow(aSubject, loc.href); } catch(ex) { } } }, true); } else if (aTopic == "profile-after-change") { Services.obs.removeObserver(config, "profile-after-change"); var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append("user_chrome_files"); file.append("user_chrome.manifest"); if (!file.exists() || !file.isFile()) { this.removeObs(); return; } try { var reg = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); reg.autoRegister(file); } catch(ex) { this.removeObs(); return; } try { Services.scriptloader.loadSubScript("chrome://user_chrome_files/content/user_chrome.js", this.subScript, "UTF-8"); } catch(ex) { this.removeObs(); } } }, removeObs: function() { Services.obs.removeObserver(config, "domwindowopened"); } }; Services.obs.addObserver(config, "profile-after-change", false); Services.obs.addObserver(config, "domwindowopened", false); `, sandbox); })(); } catch(ex) {Cu.reportError(ex);}
Отсутствует
Dumby
есть старая кнопка, в ней не работает пункт удалить, ссылается на то что popupNode не определен, посмотри пожалуйста
/*Initialization Code*/ (this.type != "menu" && (this.type = "menu") && !this.hasAttribute("is")) || (popup => { var inserter = { get docShell() { delete this.docShell; return this.docShell = "docShell" in document && document.docShell instanceof Ci.nsIDocShell ? document.docShell : window.docShell; }, get insertText() { delete this.insertText; return this.insertText = text => { if (!this.docShell.isCommandEnabled("cmd_insertText")) return; var params = "createCommandParams" in Components.utils ? Cu.createCommandParams() : Components.classes["@mozilla.org/embedcomp/command-params;1"] .createInstance(Components.interfaces.nsICommandParams); params.setStringValue("state_data", text); this.docShell.doCommandWithParams("cmd_insertText", params); } }, insert(text) { var br = document.activeElement; !br || br.localName != "browser" || !br.isRemoteBrowser ? this.insertText(text) : br.messageManager.loadFrameScript( `data:,(${this.insertText})${encodeURIComponent(text.toSource())}` , false, true); } }; this.onmousedown = e => { if (e.button) return; this.onmousedown = null; var data, save = () => { var link = custombuttons.makeButtonLink("update", _id); var params = custombuttons.cbService.getButtonParameters(link).wrappedJSObject; params.help = JSON.stringify(data, null, "\t"); custombuttons.cbService.installButton(params.wrappedJSObject = params); } popup.setAttribute("context", ""); //popup.setAttribute("onpopupshowing", "firstChild.disabled = !gClipboard.read();"); popup.addEventListener("popupshowing", (event) => {this.firstChild.disabled = !gClipboard.read();}, false); popup.add = () => save(data.push(gClipboard.read())); var menuitem = popup.appendChild(document.createXULElement("menuitem")); menuitem.setAttribute("label", "Добавить из буфера"); // menuitem.setAttribute("oncommand", "parentNode.add();"); menuitem.onclick = function (event) { this.parentNode.add(); }; if (!(data = JSON.parse(this.Help || "[]")).length) return; popup.insert = ind => inserter.insert(data[ind]); popup.delete = ind => save(data.splice(ind, 1)); var df = document.createDocumentFragment(); df.append(document.createXULElement("menuseparator")); var menugroup = df.appendChild(document.createXULElement("menugroup")); //menugroup.setAttribute("oncommand", "parentNode.insert(event.target.index);"); menugroup.onclick = function (event) { this.parentNode.insert(event.target.index); }; menugroup.setAttribute("orient", "vertical"); menugroup.setAttribute("context", "_child"); var context = menugroup .appendChild(document.createXULElement("menupopup")) .appendChild(document.createXULElement("menuitem")); context.setAttribute("label", "Удалить элемент?"); context.setAttribute("oncommand", "event.stopPropagation(); menupopup.delete(popupNode.index);"); //context.onclick = function (event) { event.stopPropagation(); this.menupopup.delete(popupNode.index); }; context.menupopup = popup; data.forEach((text, ind) => { var menuitem = menugroup.appendChild(document.createXULElement("menuitem")); menuitem.setAttribute("label", text.trimLeft().replace(/\s+/g, " ").slice(0, 70)); menuitem.index = ind; }); popup.append(df); } })(this.appendChild(document.createXULElement("menupopup")));
Отредактировано Andrey_Krropotkin (19-04-2025 22:28:30)
Отсутствует
Dumby
Перестал открываться sidebar в 133
/*Initialization Code*/ this.onclick = this.oncontextmenu = function(event) { if (event.button == 0) { var id = "viewHistorySidebar"; SidebarUI.isOpen && SidebarUI.currentID == id || SidebarUI.show(id); if (Services.prompt.confirm(null, "ВНИМАНИЕ !", " Сброс истории ! Кнопки по умолчанию?")){ CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").closed); var s = "browser.zoom.full"; cbu.setPrefs(s, cbu.getPrefs(s) == true ? true : true); SidebarUI.hide(); var s = "media.autoplay.default"; cbu.setPrefs(s, cbu.getPrefs(s) == 5 ? 5: 5); var s = "extensions.long_left_click.timeContent"; cbu.setPrefs(s, cbu.getPrefs(s) == 300 ? 300: 300); var ssi = Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {}).SessionStoreInternal; for(var win of CustomizableUI.windows) { for(var br of win.gBrowser.browsers) try {br.purgeSessionHistory();} catch {}; for(var node of win.document.querySelectorAll('[id="Browser:Back"],[id="Browser:Forward"]')) node.setAttribute("disabled", true); ssi.saveStateDelayed(win); } Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_DOM_STORAGES, () => {}); PlacesUtils.history.clear(); }else if (WindowIsClosing()) { CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").closed); } SidebarUI.hide(); } if(event.button == 1 && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey){ SidebarUI.toggle('viewHistorySidebar'); CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").closed); } if(event.button == 2 && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey){ if (Services.prompt.confirm(null, "ВНИМАНИЕ !", " Сброс Всего ! Кнопки по умолчанию?")){ gBrowser.removeAllTabsBut(gBrowser.selectedTab); Services.obs.notifyObservers(null, "browser:purge-session-history"); Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_HISTORY, () => {}); Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_DOM_STORAGES, () => {}); Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_SECURITY_SETTINGS, () => {}); Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_DOM_PUSH_NOTIFICATIONS, () => {}); Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL_CACHES, () => {}); Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_AUTH_CACHE, () => {}); Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_AUTH_TOKENS, () => {}); Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_DOWNLOADS, () => {}); SidebarUI.hide(); var ssi = Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {}).SessionStoreInternal; for(var win of CustomizableUI.windows) { for(var br of win.gBrowser.browsers) try {br.purgeSessionHistory();} catch {}; for(var node of win.document.querySelectorAll('[id="Browser:Back"],[id="Browser:Forward"]')) node.setAttribute("disabled", true); ssi.saveStateDelayed(win); } (lc => { var {_cps2, name} = FullZoom; _cps2.removeByName(name, lc, {handleCompletion() { _cps2.setGlobal(name, 1.0, lc); for(var [url, zoom] of Object.entries({ "about:preferences": 0.95, "about:preferences#search": 0.95, "about:preferences#privacy": 0.95, "about:preferences#general": 0.95, "about:addons": 0.90, "rezka-ua.tv": 1.1, })) _cps2.set(_cps2.extractDomain(url), name, zoom, lc); }}); })(Cu.createLoadContext()); CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").closed); var s = "browser.zoom.full"; cbu.setPrefs(s, cbu.getPrefs(s) == true ? true : true); var s = "media.autoplay.default"; cbu.setPrefs(s, cbu.getPrefs(s) == 5 ? 5: 5); SidebarUI.hide(); var s = "extensions.long_left_click.timeContent"; cbu.setPrefs(s, cbu.getPrefs(s) == 300 ? 300: 300); Sanitizer.showUI(window); try { Services.cache.evictEntries(Ci.nsICache.STORE_IN_MEMORY); Services.cache.evictEntries(Ci.nsICache.STORE_ON_DISK); } catch(e) { Services.cache2.clear() } var file = Services.dirsvc.get('ProfD', Ci.nsIFile); file.initWithPath(file.path + "\\memory\\start.vbs"); file.launch(); CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").closed); } }; } this.tooltipText = "ЛКМ: Очистка Истории\nСКМ: Боковая история \nПКМ: Окно очистки всего"; (url => addEventListener("pageshow", e => { if (e.target.documentURI != url) return; var rn = e.target.getElementById("historyTree").view._rootNode; var ind = rn.childCount; while(ind--) { var node = rn.getChild(ind); if (node.containerOpen) continue; node.containerOpen = true; Services.xulStore.setValue(url, node.uri, "open", "true"); } }, false, document.getElementById("sidebar") || 1))( "chrome://browser/content/places/historySidebar.xhtml" ); this.oncontextmenu =e=> { e.button && !e.ctrlKey && e.preventDefault() };
/*Initialization Code*/ ((id, g) => { addDestructor(r => r[5] == "e" && id in g && g[id].destroy()); if (g[id]) return; var {obs, xulStore, prefs} = Services; var topic = "quit-application", doc = document.documentURI; obs.addObserver(g[id] = { observe(s, t, data) { this.destroy(); if (data != "shutdown") return; xulStore.removeValue(doc, "sidebar-box", "checked"); for(var pref of [ "intl.accept_languages", "network.proxy.type", "extensions.long_left_click.timeContent", "browser.toolbars.bookmarks.visibility", "general.useragent.override", ]) prefs.clearUserPref(pref); }, destroy() { delete g[id]; obs.removeObserver(this, topic); } }, topic, false); })( "CBQuitApplication", Cu.getGlobalForObject(Cu) ); ((id, g) => { addDestructor(r => r[5] == "e" && id in g && g[id].destroy()); if (g[id]) return; var topic = "quit-application-granted", {obs} = Services; obs.addObserver(g[id] = { // true - disable, false - enable states: { "{97d566da-42c5-4ef4-a03b-5a2e5f7cbcb2}": true, "jid1-s2tSKqH4h0BHUw@jetpack": false, "mozilla_cc3@internetdownloadmanager.com": true, "{74145f27-f039-47ce-a470-a662b129930a}": true, "{acf99872-d701-4863-adc2-cdda1163aa34}": true, "{8f4bbf79-5514-4d04-a901-d5fabfe91d73}": true, }, filter(addon) { var state = this.states[addon.id]; if ( state !== undefined && addon.userDisabled != state && addon.type.endsWith("extension") && addon.location.name != "app-builtin" ) { addon.active = addon.location.get(addon.id).enabled = !(addon.userDisabled = state); return true; } }, observe() { this.destroy(); if (g.XPIDatabase.getAddons().filter(this.filter, this).length) g.XPIDatabase.saveChanges(), g.XPIStates.save(); }, destroy() { delete g[id]; obs.removeObserver(this, topic); } }, topic, false); })( "CBQuitApplicationExtensionsSwitcher", Cu.import("resource://gre/modules/addons/XPIDatabase.jsm", {}) );
Тогда по-проще как сюда второй код всунуть ?
this.click = e => e.button || this.launch();
Отредактировано green25 (05-04-2025 20:41:06)
Отсутствует
Заменить m.setAttribute('oncommand', sCommand); на что другое чтобы избавиться от oncommand
m.onclick = sCommand; ?
...программисты словно войну какую-то ведут за свои обновления. Блин, почему сейчас повсюду мания ухудшать интерфейсы и делать их максимально неудобными?! Radiation
Отсутствует
mokujin не пашет, полностью код
/*Initialization Code*/ var idb=this.id; var button = document.getElementById(idb); this.tooltipText = 'ЛКМ: ExtraConfigMenu\nСКМ: открыть папку Chrome в браузере'; (function(){ var uProfMenu = { // ----- Настройки // ----- Начало // Введите путь к текстовому редактору. Если запись неверна, считывается из view_source.editor.path: TextOpenExe : 'C:\\Program Files (x86)\\AkelPad\\AkelPad.exe', // При желании введите файловый менеджер (оставьте значение пустым для файлового менеджера системы). Примеры: vFileManager: 'C:\\Program Files (x86)\\FreeCommander\\FreeCommander.exe' vFileManager: '', // В Linux следует / можно попытаться отсортировать сценарии userChromeJS, в Windows это может не потребоваться (сортировка не будет чувствительна к регистру * - функция sort () вызывается соответственно с функцией сравнения) sortScripts: 0, // 1, чтобы сделать сортировку // Интеграция папки скриптов GM (0: нет, 1: Greasemonkey [каталог профиля], 2: UserScriptLoader [каталог chrome], 3: scriptish [каталог профиля]): gmOrdner: 0, // Вставить папку CSS (0: нет, 1: папка CSS в каталоге Chrome): cssOrdner: 1, // В строке about: введите адреса, которые также должны быть вызваны. // - Спрятать пункт abouts: [], // - Чтобы пункты about: были перечислены не как подменю, а непосредственно как пункты меню, первый элемент должен иметь значение «0»: // abouts: ['0','about:about','about:addons','about:cache','about:config','about:support'], abouts: ['about:about','about:addons','about:cache','about:config','about:buildconfig','about:crashes','about:home','about:memory','about:plugins','about:support','about:debugging','about:profiles','about:preferences','about:performance','about:firefoxview-next'], // пункт настройки Firefox (0: нет, 1: да): showNormalPrefs: 1, // Предоставляет «список сценариев в буфере обмена» (1: да, 2: с отдельной нумерацией) или нет (0): enableScriptsToClip: 2}; // ----- Конец var menupopup = button.appendChild(createME("menupopup",0,0,0,"ExtraConfigMenu-popup")); button.type = "menu"; button.orient = "horizontal"; // button.setAttribute("onpopupshowing", "getScripts(0)"); // button.setAttribute("onclick", "if (event.button === 1 && !this.open) openTrustedLinkIn('file:///'+getPrefDirectoryPath(`UChrm`), 'tab');"); button.addEventListener("popupshowing", (event) => {getScripts(0)}, false); button.onclick = function (event) { if (event.button === 1 && !this.open) openTrustedLinkIn('file:///'+getPrefDirectoryPath(`UChrm`), 'tab') }; menupopup.appendChild(createME("menuitem","userChrome.js","edit(0,'userChrome.js');","uProfMenu_edit",0)); // Создание подменю для сценариев userChromeJS (они будут заполнены позже) var submenu = menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-ucjs")); submenu.appendChild(createME("menupopup",0,0,0,"submenu-ucjs-items")); var submenu2=menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-css")); submenu2.appendChild(createME("menupopup",0,0,0,"submenu-css-items")); var submenu1=menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-ucxu")); var submenupopup = submenu1.appendChild(createME("menupopup",0,0,0,"submenu-ucxu-items")); if (uProfMenu.enableScriptsToClip) menupopup.appendChild(createME("menuitem","Скопировать в буфер список","getScripts(1)","uProfMenu_clipboard",0)); // Завершить создание подменю для сценариев userChromeJS menupopup.appendChild(document.createXULElement('menuseparator')); // Интеграция конфигурационных файлов menupopup.appendChild(createME("menuitem","userChrome.css","edit(0,'userChrome.css');","uProfMenu_edit1",0)); menupopup.appendChild(createME("menuitem","userContent.css","edit(0,'userContent.css');","uProfMenu_edit1",0)); menupopup.appendChild(createME("menuitem","prefs.js","edit(1,'prefs.js');","uProfMenu_edit",0)); menupopup.appendChild(createME("menuitem","user.js","edit(1,'user.js');","uProfMenu_edit"),0); // Завершить интеграцию конфигурационных файлов menupopup.appendChild(document.createXULElement('menuseparator')); // Интеграция папок switch (uProfMenu.gmOrdner) { case 1: menupopup.appendChild(createME("menuitem","Папка gm_scripts","dirOpen(getPrefDirectoryPath('ProfD')+getDirSep()+'gm_scripts');","uProfMenu_folder"),0); break; case 2: menupopup.appendChild(createME("menuitem","USL Skripte","dirOpen(getPrefDirectoryPath('UChrm')+getDirSep()+'UserScriptLoader');","uProfMenu_folder"),0); break; case 3: menupopup.appendChild(createME("menuitem","Scriptish Skripte","dirOpen(getPrefDirectoryPath('ProfD')+getDirSep()+'scriptish_scripts');","uProfMenu_folder"),0); break; } if (uProfMenu.cssOrdner) { menupopup.appendChild(createME("menuitem","Папка Chrome","prefDirOpen('UChrm');","uProfMenu_folder"),0); menupopup.appendChild(createME("menuitem","Папка CSS","dirOpen(getPrefDirectoryPath('UChrm')+getDirSep()+'CSS');","uProfMenu_folder"),0); } menupopup.appendChild(createME("menuitem","Папка user_chrome_files","dirOpen(getPrefDirectoryPath('UChrm')+getDirSep()+'user_chrome_files');","uProfMenu_folder"),0); menupopup.appendChild(createME("menuitem","Папка профиля","prefDirOpen('ProfD');","uProfMenu_folder"),0); menupopup.appendChild(createME("menuitem","Папка extensions","dirOpen(getPrefDirectoryPath('ProfD')+getDirSep()+'extensions');","uProfMenu_folder"),0); menupopup.appendChild(createME("menuitem","Папка Mozilla","prefDirOpen('CurProcD');","uProfMenu_folder"),0); menupopup.appendChild(createME("menuitem","Папка startupCache","dirOpen(getPrefDirectoryPath('ProfLD')+getDirSep()+'startupCache');","uProfMenu_folder"),0); // Завершить интеграцию папок // Интеграция abouts if (uProfMenu.abouts.length>0) { menupopup.appendChild(document.createXULElement('menuseparator')); // если первая запись массива = '0', не создавайте подменю, а интегрируйте его непосредственно как пункты меню if (uProfMenu.abouts[0]=='0') { for (var i = 1; i < uProfMenu.abouts.length; i++) { menupopup.appendChild(createME("menuitem",uProfMenu.abouts[i],"openTrustedLinkIn('"+uProfMenu.abouts[i]+"','tab')","uProfMenu_about"),0); } } else { // Первая запись массива не равна '0', поэтому устанавливается как подменю var submenu=menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-about")); var submenupopup = submenu.appendChild(createME("menupopup",0,0,0,"submenu-about-items")); fillMenu("submenu-about","submenu-about-items", "about:",uProfMenu.abouts,"uProfMenu_about",1); } } // Завершение интеграции abouts // Разделитель, если он еще не был сгенерирован abouts и будет следовать за другими пунктами меню if (uProfMenu.abouts.length==0 && uProfMenu.showNormalPrefs) menupopup.appendChild(document.createXULElement('menuseparator')); // При желании (см. Раздел настроек), доступ к обычным настройкам Firefox if (uProfMenu.showNormalPrefs) menupopup.appendChild(createME("menuitem","Настройки","try{openOptionsDialog();}catch(e){openPreferences();}","uProfMenu_prefs"),0); if (uProfMenu.showNormalPrefs) menupopup.appendChild(createME("menuitem","Перезапуск","Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart)","uProfMenu_Restart"),0); getDirSep = function () { // Определить операционную систему в соответствии с https://developer.mozilla.org/en/Code_snippets/Miscellaneous var osString = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).OS; var dirsep="/"; switch(osString) { case "WINNT": dirsep="\\"; break; case "Linux": dirsep="/"; break; case "Darwin": dirsep="/"; break; } return dirsep; }; edit = function (OpenMode,Filename){ var Path = ""; var dSep = getDirSep(); // Сделать разделители между папками в зависимости от операционной системы switch (OpenMode){ //Текущая Chrome директория case 0: var Path = getPrefDirectoryPath("UChrm") + dSep + Filename; break; //Текущая Profile директория case 1: var Path = getPrefDirectoryPath("ProfD") + dSep + Filename; break; //Текущая директория Root case 2: var Path = Filename; break; //Текущая CSS директория case 3: var Path = getPrefDirectoryPath("UChrm") + dSep + "CSS" + dSep + Filename; break; } launch(uProfMenu.TextOpenExe,Path); }; dirOpen = function (Path){ if (uProfMenu.vFileManager.length != 0) { var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile); var process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess); var args=[Path]; file.initWithPath(uProfMenu.vFileManager); process.init(file); // Открыть каталог с другим файловым менеджером process.run(false, args, args.length); } else { // Откройте каталог с помощью файлового менеджера системы var dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); dir.initWithPath(Path); dir.launch(); } }; prefDirOpen = function (prefDir){ Path = getPrefDirectoryPath(prefDir); dirOpen(Path); }; getPrefDirectoryPath = function (str){ var file = Components.classes["@mozilla.org/file/directory_service;1"] .getService(Components.interfaces.nsIProperties) .get(str, Components.interfaces.nsIFile); if (str == 'CurProcD') { file = file.parent; }; return file.path; }; launch = function (RanPath,OpenPath){ var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsIFile); var proc = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess); var args = [OpenPath]; file.initWithPath(RanPath); // если редактор, определенный в разделе конфигурации, не найден, переключитесь на настройку в about: config: if (!file.exists()) { var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch); RanPath=pref.getCharPref("view_source.editor.path"); file.initWithPath(RanPath); } proc.init(file); proc.run(false, args, args.length); }; stringComparison = function (a, b){ a = a.toLowerCase(); a = a.replace(/ä/g,"a"); a = a.replace(/ö/g,"o"); a = a.replace(/ü/g,"u"); a = a.replace(/ß/g,"s"); b = b.toLowerCase(); b = b.replace(/ä/g,"a"); b = b.replace(/ö/g,"o"); b = b.replace(/ü/g,"u"); b = b.replace(/ß/g,"s"); return(a==b)?0:(a>b)?1:-1; }; getScripts = function (iType) { // Массивы (по одному массиву для uc.js,uc.xul, css) выбирают имена найденных скриптов var ucJsScripts = []; var ucXulScripts = []; var ucCSScripts = []; // Шаблон поиска, то есть расширения файлов uc.js, uc.xul, css var extjs = /\.uc\.js$/i; var extxul= /\.uc\.xul$/i; var exttcss= /\.css$/i; // Для uc.js, uc.xul var aFolder = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile); aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path); var files = aFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator); // Для css var sFolder = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile); sFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path); sFolder.appendRelativePath("CSS"); var sfiles = sFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator); // Просматривать папки или файлы и проверять, включены ли найденные файлы для uc.js, uc.xul while (files.hasMoreElements()) { var file = files.getNext().QueryInterface(Ci.nsIFile); // нет нужного файла, поэтому продолжайте if (!extjs.test(file.leafName) && !extxul.test(file.leafName)) continue; // uc.js найдено -> положить в массив if (extjs.test(file.leafName)) ucJsScripts.push(file.leafName); // uc.xul найдено -> положить в массив if (extxul.test(file.leafName)) ucXulScripts.push(file.leafName); } // Просматривать папки или файлы и проверять, включены ли найденные файлы для css while (sfiles.hasMoreElements()) { var sfile = sfiles.getNext().QueryInterface(Ci.nsIFile); // нет нужного файла, поэтому продолжайте if (!exttcss.test(sfile.leafName)) continue; // css найдено -> положить в массив if (exttcss.test(sfile.leafName)) ucCSScripts.push(sfile.leafName); } if (uProfMenu.sortScripts) { ucJsScripts.sort(stringComparison); ucXulScripts.sort(stringComparison); ucCSScripts.sort(stringComparison); } // Вызов следующих методов для заполнения подменю или буфера обмена if (iType==0) { fillMenu("submenu-ucjs","submenu-ucjs-items", "Файлы uc.js",ucJsScripts,"uProfMenu_ucjs",0); fillMenu("submenu-ucxu","submenu-ucxu-items", "Файлы uc.xul",ucXulScripts,"uProfMenu_ucxu",0); fillMenu1("submenu-css","submenu-css-items", "Файлы css",ucCSScripts,"uProfMenu_css",0); } else { var result = fillClipboardValue(ucJsScripts,ucXulScripts,ucCSScripts); Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper).copyString(result); } }; function fillMenu (whichsubmenu, whichsubmenuitems, strlabel, scriptArray,sClass,sTyp,sId) { // Добавить заголовок подменю с количеством найденных файлов var e = document.getElementById(whichsubmenu); e.setAttribute('label',strlabel + ' (' + scriptArray.length + ')'); var popup = document.getElementById(whichsubmenuitems); // подменю while(popup.hasChildNodes()){ popup.removeChild(popup.firstChild); } // Подменю заполнить for (var i = scriptArray.length-1; i > -1; i--) { // для пунктов подменю uc.js, uc.xul, abouts if (sTyp==0){ var mitem = createME("menuitem",scriptArray[i],"edit(0,'"+scriptArray[i]+"')",sClass,0); mitem.setAttribute("onclick","openAtGithub(event,'"+scriptArray[i]+"')"); mitem.setAttribute("tooltiptext"," ЛКМ: Редактировать\n СКМ: Поиск по форуму camp-firefox.de\n ПКМ: Поиск по сайту GitHub"); } else { var mitem = createME("menuitem",scriptArray[i],"openTrustedLinkIn('"+scriptArray[i]+"','tab')",sClass,0); } popup.insertBefore(mitem, popup.firstChild); } }; function fillMenu1 (whichsubmenu, whichsubmenuitems, strlabel, scriptArray,sClass,sTyp,sId) { // Добавить заголовок подменю с количеством найденных файлов var e = document.getElementById(whichsubmenu); e.setAttribute('label',strlabel + ' (' + scriptArray.length + ')'); var popup = document.getElementById(whichsubmenuitems); // подменю while(popup.hasChildNodes()){ popup.removeChild(popup.firstChild); } // Подменю заполнить for (var i = scriptArray.length-1; i > -1; i--) { // для пунктов подменю css if (sTyp==0){ var mitem1 = createME("menuitem",scriptArray[i],"edit(3,'"+scriptArray[i]+"')",sClass,0); } popup.insertBefore(mitem1, popup.firstChild); } }; function fillClipboardValue (sArray,xArray,yArray) { var retValue; var s = 0; var x = 0; var y = 0; s = sArray.length; x = xArray.length; y = yArray.length; switch(uProfMenu.enableScriptsToClip) { case 1: retValue = "userChrome/uc.js ("+s+"):\n------------------------\n"+sArray.join("\n")+ "\n\nuserChrome/uc.xul ("+x+"):\n-------------------------\n"+xArray.join("\n")+ "\n\nuserChrome/css ("+y+"):\n-------------------------\n"+yArray.join("\n"); break; case 2: retValue = "userChrome/uc.js ("+s+"):\n------------------------"; for (var i = 0; i < s ; i++) { j = i + 1; retValue = retValue + "\n" + j + ". " + sArray[i]; } retValue = retValue + "\n\nuserChrome/uc.xul ("+x+"):\n-------------------------"; for (var i = 0; i < x ; i++) { g = i + 1; retValue = retValue + "\n" + g + ". " + xArray[i]; } retValue = retValue + "\n\nuserChrome/css ("+y+"):\n-------------------------"; for (var i = 0; i < y ; i++) { h = i + 1; retValue = retValue + "\n" + h + ". " + yArray[i]; } } return retValue; }; function createME (sTyp,sLabel,sCommand,sClass,sId) { // Создание элемента меню, меню или меню - параметры, не используемые для определенных типов, передаются как 0 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; var m = document.createElementNS(XUL_NS, sTyp); switch (sTyp) { case "menuitem": m.setAttribute('label', sLabel); m.setAttribute('oncommand',sCommand); m.setAttribute('class',sClass); break; case "menu": m.setAttribute('label', sLabel); m.setAttribute('id', sId); break; case "menupopup": m.setAttribute('id', sId); break; } return m; }; openAtGithub = function (e,sScript) { if (e.button==1){ // СКМ - Начать поиск на camp-firefox.de (работает, только если имя файла хранится в коде): var sUrl="https://www.google.com/search?as_q="+sScript+"&as_sitesearch=www.camp-firefox.de&gws_rd=ssl"; openWebLinkIn(sUrl, 'tab'); } if (e.button==2){ // ПКМ - Начать поиск на GitHub (работает, только если имя файла хранится в коде): e.preventDefault(); var sUrl="https://www.google.com/search?as_q="+sScript+"&as_sitesearch=github.com&gws_rd=ssl"; openWebLinkIn(sUrl, 'tab'); } }; function cleanFileName(sName) { sName=sName.toLowerCase(); /* Следующий массив содержит регулярные выражения для удаления недопустимых строк: /Datei-Erweiterungen am Ende/, /"ucjs_" am Anfang/, /"_"gefolgtVonZahlUndDanachBeliebigenZeichen/ / "_fx"gefolgtVonZahl(en)/, /"-" oder "+" oder "."/, /"_v"gefolgtVonZahlen */ var regs=[/\.uc\.js$/,/\.uc\.xul$/,/^ucjs_/,/_\d.+/,/_fx\d+/,/[-+\.]/g,/_v\d+/]; for (var i = 0; i < regs.length; i++) { sName=sName.replace(regs[i],""); } return sName; }; })();
Отредактировано Andrey_Krropotkin (07-04-2025 22:22:37)
Отсутствует
И куда ты это месиво собрался втулить ?! Ему 10+лет этому скрипту. С тех пор FF уже четырежды минимум менял-ся.
Тут пару ошибок древнюююююющих было.
В PM вот ↓ работающий код, а как там оно будет в FF последних.., полагаю что никак вообще. ибо такая мешанина что это тот-самый случай, когда написать с нуля проще, чем все это исправлять. Но автору простительно, он на заре это все писал, добавляя по кускам. Да и есть\были отдельные норм. кнопки с меню about:, файлами и открытием папок
/*Initialization Code*/ // ==UserScript== // @name extras_config_menu.uc.js // @compatibility Firefox 8.*, 9.*, 10.*, 11.*, 12.*, 13.*, 14.*, 15.*, 16.*, 17.*, 57.*, 62.* // @include main // @version 1.0.20180914 // ==/UserScript== var idb=this.id; var button = document.getElementById(idb); this.tooltipText = 'ЛКМ: ExtraConfigMenu\nСКМ: открыть папку Chrome в браузере'; (function(){ var uProfMenu = { // ----- Настройки // ----- Начало // Введите путь к текстовому редактору. Если запись неверна, считывается из view_source.editor.path: TextOpenExe : 'd:\\MyPROGRAMs\\FM\\TC9\\Plugins\\exe\\AkelPad\\AkelPad.exe', // При желании введите файловый менеджер (оставьте значение пустым для файлового менеджера системы). Примеры: vFileManager: 'C:\\Program Files (x86)\\FreeCommander\\FreeCommander.exe' vFileManager: '', // В Linux следует / можно попытаться отсортировать сценарии userChromeJS, в Windows это может не потребоваться (сортировка не будет чувствительна к регистру * - функция sort () вызывается соответственно с функцией сравнения) sortScripts: 0, // 1, чтобы сделать сортировку // Интеграция папки скриптов GM (0: нет, 1: Greasemonkey [каталог профиля], 2: UserScriptLoader [каталог chrome], 3: scriptish [каталог профиля]): gmOrdner: 0, // Вставить папку CSS (0: нет, 1: папка CSS в каталоге Chrome): cssOrdner: 1, // В строке about: введите адреса, которые также должны быть вызваны. // - Спрятать пункт abouts: [], // - Чтобы пункты about: были перечислены не как подменю, а непосредственно как пункты меню, первый элемент должен иметь значение «0»: // abouts: ['0','about:about','about:addons','about:cache','about:config','about:support'], abouts: ['about:about','about:addons','about:cache','about:config','about:buildconfig','about:crashes','about:home','about:memory','about:plugins','about:support','about:debugging','about:profiles','about:preferences','about:performance','about:firefoxview-next'], // пункт настройки Firefox (0: нет, 1: да): showNormalPrefs: 1, // Предоставляет «список сценариев в буфере обмена» (1: да, 2: с отдельной нумерацией) или нет (0): enableScriptsToClip: 2}; // ----- Конец var menupopup = button.appendChild(createME("menupopup",0,0,0,"ExtraConfigMenu-popup")); button.type = "menu"; button.orient = "horizontal"; // button.setAttribute("onpopupshowing", "getScripts(0)"); button.addEventListener("popupshowing", (event) => {getScripts(0)}, false); // button.setAttribute("onclick", "if (event.button === 1 && !this.open) gBrowser.selectedTab = gBrowser.addTab('file:///'+getPrefDirectoryPath(`UChrm`), 'tab');"); button.onclick = function (event) { if (event.button === 1 && !this.open) gBrowser.selectedTab = gBrowser.addTab('file:///'+getPrefDirectoryPath(`UChrm`)) }; menupopup.appendChild(createME("menuitem","userChrome.js","edit(0,'userChrome.js');","uProfMenu_edit",0)); // Создание подменю для сценариев userChromeJS (они будут заполнены позже) var submenu = menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-ucjs")); submenu.appendChild(createME("menupopup",0,0,0,"submenu-ucjs-items")); var submenu2=menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-css")); submenu2.appendChild(createME("menupopup",0,0,0,"submenu-css-items")); var submenu1=menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-ucxu")); var submenupopup = submenu1.appendChild(createME("menupopup",0,0,0,"submenu-ucxu-items")); if (uProfMenu.enableScriptsToClip) menupopup.appendChild(createME("menuitem","Скопировать в буфер список","getScripts(1)","uProfMenu_clipboard",0)); // Завершить создание подменю для сценариев userChromeJS //menupopup.appendChild(document.createElement("menuseparator")); menupopup.appendChild(document.createElement("menuseparator")); // Интеграция конфигурационных файлов menupopup.appendChild(createME("menuitem","userChrome.css","edit(0,'userChrome.css');","uProfMenu_edit1",0)); menupopup.appendChild(createME("menuitem","userContent.css","edit(0,'userContent.css');","uProfMenu_edit1",0)); menupopup.appendChild(createME("menuitem","prefs.js","edit(1,'prefs.js');","uProfMenu_edit",0)); menupopup.appendChild(createME("menuitem","user.js","edit(1,'user.js');","uProfMenu_edit"),0); // Завершить интеграцию конфигурационных файлов menupopup.appendChild(document.createElement("menuseparator")); // Интеграция папок switch (uProfMenu.gmOrdner) { case 1: menupopup.appendChild(createME("menuitem","Папка gm_scripts","dirOpen(getPrefDirectoryPath('ProfD')+getDirSep()+'gm_scripts');","uProfMenu_folder"),0); break; case 2: menupopup.appendChild(createME("menuitem","USL Skripte","dirOpen(getPrefDirectoryPath('UChrm')+getDirSep()+'UserScriptLoader');","uProfMenu_folder"),0); break; case 3: menupopup.appendChild(createME("menuitem","Scriptish Skripte","dirOpen(getPrefDirectoryPath('ProfD')+getDirSep()+'scriptish_scripts');","uProfMenu_folder"),0); break; } if (uProfMenu.cssOrdner) { menupopup.appendChild(createME("menuitem","Папка Chrome","prefDirOpen('UChrm');","uProfMenu_folder"),0); menupopup.appendChild(createME("menuitem","Папка CSS","dirOpen(getPrefDirectoryPath('UChrm')+getDirSep()+'CSS');","uProfMenu_folder"),0); } menupopup.appendChild(createME("menuitem","Папка user_chrome_files","dirOpen(getPrefDirectoryPath('UChrm')+getDirSep()+'user_chrome_files');","uProfMenu_folder"),0); menupopup.appendChild(createME("menuitem","Папка профиля","prefDirOpen('ProfD');","uProfMenu_folder"),0); menupopup.appendChild(createME("menuitem","Папка extensions","dirOpen(getPrefDirectoryPath('ProfD')+getDirSep()+'extensions');","uProfMenu_folder"),0); menupopup.appendChild(createME("menuitem","Папка Mozilla","prefDirOpen('CurProcD');","uProfMenu_folder"),0); menupopup.appendChild(createME("menuitem","Папка startupCache","dirOpen(getPrefDirectoryPath('ProfLD')+getDirSep()+'startupCache');","uProfMenu_folder"),0); // Завершить интеграцию папок // Интеграция abouts if (uProfMenu.abouts.length>0) { menupopup.appendChild(document.createElement("menuseparator")); // если первая запись массива = '0', не создавайте подменю, а интегрируйте его непосредственно как пункты меню if (uProfMenu.abouts[0]=='0') { for (var i = 1; i < uProfMenu.abouts.length; i++) { menupopup.appendChild(createME("menuitem",uProfMenu.abouts[i],"gBrowser.selectedTab = gBrowser.addTab('"+uProfMenu.abouts[i]+"')","uProfMenu_about"),0); // menupopup.appendChild(createME("menuitem",uProfMenu.abouts[i],"gBrowser.selectedTab = gBrowser.addTab('"+uProfMenu.abouts[i]+"','tab')","uProfMenu_about"),0); } } else { // Первая запись массива не равна '0', поэтому устанавливается как подменю var submenu=menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-about")); var submenupopup = submenu.appendChild(createME("menupopup",0,0,0,"submenu-about-items")); fillMenu("submenu-about","submenu-about-items", "about:",uProfMenu.abouts,"uProfMenu_about",1); } } // Завершение интеграции abouts // Разделитель, если он еще не был сгенерирован abouts и будет следовать за другими пунктами меню if (uProfMenu.abouts.length==0 && uProfMenu.showNormalPrefs) //menupopup.appendChild(document.createElement("menuseparator")); // При желании (см. Раздел настроек), доступ к обычным настройкам Firefox if (uProfMenu.showNormalPrefs) menupopup.appendChild(createME("menuitem","Настройки","try{openOptionsDialog();}catch(e){openPreferences();}","uProfMenu_prefs"),0); if (uProfMenu.showNormalPrefs) menupopup.appendChild(createME("menuitem","Перезапуск","Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart)","uProfMenu_Restart"),0); getDirSep = function () { // Определить операционную систему в соответствии с https://developer.mozilla.org/en/Code_snippets/Miscellaneous var osString = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).OS; var dirsep="/"; switch(osString) { case "WINNT": dirsep="\\"; break; case "Linux": dirsep="/"; break; case "Darwin": dirsep="/"; break; } return dirsep; }; edit = function (OpenMode,Filename){ var Path = ""; var dSep = getDirSep(); // Сделать разделители между папками в зависимости от операционной системы switch (OpenMode){ //Текущая Chrome директория case 0: var Path = getPrefDirectoryPath("UChrm") + dSep + Filename; break; //Текущая Profile директория case 1: var Path = getPrefDirectoryPath("ProfD") + dSep + Filename; break; //Текущая директория Root case 2: var Path = Filename; break; //Текущая CSS директория case 3: var Path = getPrefDirectoryPath("UChrm") + dSep + "CSS" + dSep + Filename; break; } launch(uProfMenu.TextOpenExe,Path); }; dirOpen = function (Path){ if (uProfMenu.vFileManager.length != 0) { var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile); var process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess); var args=[Path]; file.initWithPath(uProfMenu.vFileManager); process.init(file); // Открыть каталог с другим файловым менеджером process.run(false, args, args.length); } else { // Откройте каталог с помощью файлового менеджера системы var dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); dir.initWithPath(Path); dir.launch(); } }; prefDirOpen = function (prefDir){ Path = getPrefDirectoryPath(prefDir); dirOpen(Path); }; getPrefDirectoryPath = function (str){ var file = Components.classes["@mozilla.org/file/directory_service;1"] .getService(Components.interfaces.nsIProperties) .get(str, Components.interfaces.nsIFile); if (str == 'CurProcD') { file = file.parent; }; return file.path; }; launch = function (RanPath,OpenPath){ var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsIFile); var proc = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess); var args = [OpenPath]; file.initWithPath(RanPath); // если редактор, определенный в разделе конфигурации, не найден, переключитесь на настройку в about: config: if (!file.exists()) { var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch); RanPath=pref.getCharPref("view_source.editor.path"); file.initWithPath(RanPath); } proc.init(file); proc.run(false, args, args.length); }; stringComparison = function (a, b){ a = a.toLowerCase(); a = a.replace(/ä/g,"a"); a = a.replace(/ö/g,"o"); a = a.replace(/ü/g,"u"); a = a.replace(/ß/g,"s"); b = b.toLowerCase(); b = b.replace(/ä/g,"a"); b = b.replace(/ö/g,"o"); b = b.replace(/ü/g,"u"); b = b.replace(/ß/g,"s"); return(a==b)?0:(a>b)?1:-1; }; getScripts = function (iType) { // Массивы (по одному массиву для uc.js,uc.xul, css) выбирают имена найденных скриптов var ucJsScripts = []; var ucXulScripts = []; var ucCSScripts = []; // Шаблон поиска, то есть расширения файлов uc.js, uc.xul, css var extjs = /\.uc\.js$/i; var extxul= /\.uc\.xul$/i; var exttcss= /\.css$/i; // Для uc.js, uc.xul var aFolder = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile); aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path); var files = aFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator); // Для css var sFolder = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile); sFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path); sFolder.appendRelativePath("CSS"); var sfiles = sFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator); // Просматривать папки или файлы и проверять, включены ли найденные файлы для uc.js, uc.xul while (files.hasMoreElements()) { var file = files.getNext().QueryInterface(Ci.nsIFile); // нет нужного файла, поэтому продолжайте if (!extjs.test(file.leafName) && !extxul.test(file.leafName)) continue; // uc.js найдено -> положить в массив if (extjs.test(file.leafName)) ucJsScripts.push(file.leafName); // uc.xul найдено -> положить в массив if (extxul.test(file.leafName)) ucXulScripts.push(file.leafName); } // Просматривать папки или файлы и проверять, включены ли найденные файлы для css while (sfiles.hasMoreElements()) { var sfile = sfiles.getNext().QueryInterface(Ci.nsIFile); // нет нужного файла, поэтому продолжайте if (!exttcss.test(sfile.leafName)) continue; // css найдено -> положить в массив if (exttcss.test(sfile.leafName)) ucCSScripts.push(sfile.leafName); } if (uProfMenu.sortScripts) { ucJsScripts.sort(stringComparison); ucXulScripts.sort(stringComparison); ucCSScripts.sort(stringComparison); } // Вызов следующих методов для заполнения подменю или буфера обмена if (iType==0) { fillMenu("submenu-ucjs","submenu-ucjs-items", "Файлы uc.js",ucJsScripts,"uProfMenu_ucjs",0); fillMenu("submenu-ucxu","submenu-ucxu-items", "Файлы uc.xul",ucXulScripts,"uProfMenu_ucxu",0); fillMenu1("submenu-css","submenu-css-items", "Файлы css",ucCSScripts,"uProfMenu_css",0); } else { var result = fillClipboardValue(ucJsScripts,ucXulScripts,ucCSScripts); Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper).copyString(result); } }; function fillMenu (whichsubmenu, whichsubmenuitems, strlabel, scriptArray,sClass,sTyp,sId) { // Добавить заголовок подменю с количеством найденных файлов var e = document.getElementById(whichsubmenu); e.setAttribute('label',strlabel + ' (' + scriptArray.length + ')'); var popup = document.getElementById(whichsubmenuitems); // подменю while(popup.hasChildNodes()){ popup.removeChild(popup.firstChild); } // Подменю заполнить for (var i = scriptArray.length-1; i > -1; i--) { // для пунктов подменю uc.js, uc.xul, abouts if (sTyp==0){ var mitem = createME("menuitem",scriptArray[i],"edit(0,'"+scriptArray[i]+"')",sClass,0); //mitem.setAttribute("onclick","openAtGithub(event,'"+scriptArray[i]+"')"); mitem.onclick = function (event) { openAtGithub(event,'"+scriptArray[i]+"') }; mitem.setAttribute("tooltiptext"," ЛКМ: Редактировать\n СКМ: Поиск по форуму camp-firefox.de\n ПКМ: Поиск по сайту GitHub"); } else { var mitem = createME("menuitem",scriptArray[i],"gBrowser.selectedTab = gBrowser.addTab('"+scriptArray[i]+"')",sClass,0); } popup.insertBefore(mitem, popup.firstChild); } }; function fillMenu1 (whichsubmenu, whichsubmenuitems, strlabel, scriptArray,sClass,sTyp,sId) { // Добавить заголовок подменю с количеством найденных файлов var e = document.getElementById(whichsubmenu); e.setAttribute('label',strlabel + ' (' + scriptArray.length + ')'); var popup = document.getElementById(whichsubmenuitems); // подменю while(popup.hasChildNodes()){ popup.removeChild(popup.firstChild); } // Подменю заполнить for (var i = scriptArray.length-1; i > -1; i--) { // для пунктов подменю css if (sTyp==0){ var mitem1 = createME("menuitem",scriptArray[i],"edit(3,'"+scriptArray[i]+"')",sClass,0); } popup.insertBefore(mitem1, popup.firstChild); } }; function fillClipboardValue (sArray,xArray,yArray) { var retValue; var s = 0; var x = 0; var y = 0; s = sArray.length; x = xArray.length; y = yArray.length; switch(uProfMenu.enableScriptsToClip) { case 1: retValue = "userChrome/uc.js ("+s+"):\n------------------------\n"+sArray.join("\n")+ "\n\nuserChrome/uc.xul ("+x+"):\n-------------------------\n"+xArray.join("\n")+ "\n\nuserChrome/css ("+y+"):\n-------------------------\n"+yArray.join("\n"); break; case 2: retValue = "userChrome/uc.js ("+s+"):\n------------------------"; for (var i = 0; i < s ; i++) { j = i + 1; retValue = retValue + "\n" + j + ". " + sArray[i]; } retValue = retValue + "\n\nuserChrome/uc.xul ("+x+"):\n-------------------------"; for (var i = 0; i < x ; i++) { g = i + 1; retValue = retValue + "\n" + g + ". " + xArray[i]; } retValue = retValue + "\n\nuserChrome/css ("+y+"):\n-------------------------"; for (var i = 0; i < y ; i++) { h = i + 1; retValue = retValue + "\n" + h + ". " + yArray[i]; } } return retValue; }; function createME (sTyp,sLabel,sCommand,sClass,sId) { // Создание элемента меню, меню или меню - параметры, не используемые для определенных типов, передаются как 0 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; var m = document.createElementNS(XUL_NS, sTyp); switch (sTyp) { case "menuitem": m.setAttribute('label', sLabel); m.setAttribute('oncommand', sCommand); m.setAttribute('class',sClass); break; case "menu": m.setAttribute('label', sLabel); m.setAttribute('id', sId); break; case "menupopup": m.setAttribute('id', sId); break; } return m; }; openAtGithub = function (e,sScript) { if (e.button==1){ // СКМ - Начать поиск на camp-firefox.de (работает, только если имя файла хранится в коде): var sUrl="https://www.google.com/search?as_q="+sScript+"&as_sitesearch=www.camp-firefox.de&gws_rd=ssl"; openWebLinkIn(sUrl, 'tab'); } if (e.button==2){ // ПКМ - Начать поиск на GitHub (работает, только если имя файла хранится в коде): e.preventDefault(); var sUrl="https://www.google.com/search?as_q="+sScript+"&as_sitesearch=github.com&gws_rd=ssl"; openWebLinkIn(sUrl, 'tab'); } }; function cleanFileName(sName) { sName=sName.toLowerCase(); /* Следующий массив содержит регулярные выражения для удаления недопустимых строк: /Datei-Erweiterungen am Ende/, /"ucjs_" am Anfang/, /"_"gefolgtVonZahlUndDanachBeliebigenZeichen/ / "_fx"gefolgtVonZahl(en)/, /"-" oder "+" oder "."/, /"_v"gefolgtVonZahlen */ var regs=[/\.uc\.js$/,/\.uc\.xul$/,/^ucjs_/,/_\d.+/,/_fx\d+/,/[-+\.]/g,/_v\d+/]; for (var i = 0; i < regs.length; i++) { sName=sName.replace(regs[i],""); } return sName; }; })(); /*Initialization Code*/ // ==UserScript== // @name SaveUserChromeJS.uc.js // @author ywzhaiqi // @description установка контекстного меню кнопок на github для скачивания скриптов // @include main // @charset UTF-8 // @version 0.4b // @homepageURL https://github.com/ywzhaiqi/userChromeJS/tree/master/SaveUserChromeJS // @reviewURL http://bbs.kafan.cn/thread-1590873-1-1.html // ==/UserScript== (function() { // Включены ли уведомления после сохранения? var notificationsAfterInstall = true; // Загружается ли скрипт после сохранения (запускать не нужно)? Поддерживается только .uc.js, некоторые скрипты проблематичны. var runWithoutRestart = true; let { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; if (!window.Services) Cu.import("resource://gre/modules/Services.sys.mjs"); const RE_USERCHROME_JS = /\.uc(?:-\d+)?\.(?:js|xul)$|userChrome\.js$/i; const RE_CONTENTTYPE = /text\/html/i; var ns = window.saveUserChromeJS = { init: function() { // добавить в contentAreaContextMenu if ( document.getElementById("uc-install-menu") ) return; var xulns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; var icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAICAAP//AICAgMDAwP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcj7VkAAABfdFJOU/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8Ak5pfLAAAAAlwSFlzAAAOwwAADsMBx2+oZAAAAFxJREFUKFNljgEOwCAIAwuF/395RWXMrDExHLQA3gKYpVXojwPo6SpewDSzAHGAXvWpkQYagNSWN2EyfGUM+G/RQWZFOnSt9AZMR3nGwggivqF1Q12xQVzavRHwALQIAv2bDRzYAAAAAElFTkSuQmCC"; var contextMenu = document.getElementById("contentAreaContextMenu"); var menuitem = document.createElementNS(xulns, "menuitem"); menuitem.setAttribute("id", "uc-install-menu"); menuitem.setAttribute("label", "Установить для userChromeJS"); menuitem.setAttribute("class", "menuitem-iconic"); menuitem.setAttribute("image", icon); menuitem.setAttribute("accessKey", "I"); // menuitem.setAttribute("oncommand", "saveUserChromeJS.saveScript(gContextMenu.linkURL)"); menuitem.onclick = function (event) { saveUserChromeJS.saveScript(gContextMenu.linkURL) }; contextMenu.insertBefore(menuitem, contextMenu.firstChild); contextMenu.addEventListener("popupshowing", this, false); this._menuitem = menuitem; }, handleEvent: function(event){ switch(event.type){ case "popupshowing": if (event.target != event.currentTarget) return; if(gContextMenu.onLink){ this._menuitem.hidden = !RE_USERCHROME_JS.test(gContextMenu.linkURL); }else{ this._menuitem.hidden = true; } break; } }, saveScript: function(url) { var name, fileName, fileExt, charset; name = name && name[1] ? name[1] : decodeURIComponent(url.split("/").pop()); fileName = name.replace(/\.uc\.(js|xul)$|$/i, ".uc.$1").replace(/\s/g, '_'); if (fileName.match(/\.uc\.$/i)) { // Исправить имя var m = url.match(/\.(js|xul)$/); if (m) fileName += m[1]; } charset = "UTF-8"; var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); var err = false; // fp.init(window, "", Ci.nsIFilePicker.modeSave); // fp.init(parseInt(Services.appinfo.platformVersion) < 125 ? window : window.browsingContext,"", fp.modeSave); fp.init(window.browsingContext, "", Ci.nsIFilePicker.modeSave); var SCRIPTS_FOLDER = Services.dirsvc.get("UChrm", Ci.nsIFile); var xhr = new XMLHttpRequest(); var url2 = url.replace("\/blob", "raw"); xhr.open('GET', url2, true); xhr.onload = () => { if (xhr.status == 200) { var uc = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter); uc.charset = 'utf-8'; var text = uc.ConvertFromUnicode(xhr.responseText); } fp.displayDirectory = SCRIPTS_FOLDER; fp.appendFilters(Ci.nsIFilePicker.filterAll); fp.defaultExtension = fileExt; fp.defaultString = fileName; var nsIFilePicker = Components.interfaces.nsIFilePicker; fp.open(function (rv) { if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) { var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); foStream.init(fp.file, 0x02|0x20|0x08, 0666, 0); foStream.write(text, text.length); foStream.close(); if(notificationsAfterInstall){ var win = err ? ns.getMostRecentWindow() : window; win.setTimeout(function(){ fileExt1 = name.match(/\.uc\.(js|xul)$/i); fileExt1 = fileExt && fileExt[1] ? fileExt[1] : "js"; ns.showInstallMessage({ fileExt: fileExt1, fileName: fileName, file: fp.file, charset: charset }); }, 100); } } }); } xhr.send(); }, showInstallMessage: function(info){ var isRun = (info.fileExt == "js"); var mainAction, secondActions; if(runWithoutRestart && isRun){ mainAction = { label: "Выполнить без перезапуска.", accessKey: "a", callback: function(){ var dir = Services.dirsvc.get("UChrm", Ci.nsIFile); dir.initWithPath(dir.path + "\\" + info.fileName); var url = Services.io.newFileURI(dir).spec; let context = {}; Services.scriptloader.loadSubScript( url, context, "UTF-8"); var showedMsg1 = ns.popupNotification({ id: "userchromejs1-install-popup-notification", message: "Скрипт запущен", options: { removeOnDismissal: true, persistWhileVisible: true } }); } }; secondActions = [{ label: "Перезагрузите сейчас", accessKey: "s", callback: ns.restartApp }]; }else{ mainAction = { label: "Перезагрузите сейчас", accessKey: "s", callback: ns.restartApp }; secondActions = null; } var showedMsg = ns.popupNotification({ id: "userchromejs-install-popup-notification", message: "'" + info.fileName + "' Установка завершена.", mainAction: mainAction, secondActions: secondActions, options: { removeOnDismissal: true, persistWhileVisible: true } }); }, popupNotification: function(details){ var win = ns.getMostRecentWindow(); if (win && win.PopupNotifications) { win.PopupNotifications.show( win.gBrowser.selectedBrowser, details.id, details.message, "", details.mainAction, details.secondActions, details.options); return true; } return false; }, getMostRecentWindow: function(){ return Services.wm.getMostRecentWindow("navigator:browser") }, restartApp: function() { Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart) } }; function log(arg){ Application.console.log("[SaveUserChromeJS]" + arg);} })(); window.saveUserChromeJS.init();
...программисты словно войну какую-то ведут за свои обновления. Блин, почему сейчас повсюду мания ухудшать интерфейсы и делать их максимально неудобными?! Radiation
Отсутствует