Dumby т.е. как я понял получается что они вырезали старые функции а новые еще не ввели, и пока про эту кнопку можно забыть
На форуме
Dumby
Код хорош, а нельзя и на открыть новую вкладку подобное ?
(flags => { var clear = Services.clearData.deleteData.bind(null, flags, () => {}); var skip, check = () => { skip = null; for(var w of CustomizableUI.windows) for(var tab of gBrowser.tabs) try { if (tab.linkedBrowser.URI.host) return; } catch {} clear(); } addEventListener("TabClose", e => skip ??= setTimeout(check, 400), false, gBrowser.tabContainer); })(Ci.nsIClearDataService.CLEAR_DOM_STORAGES);
Отсутствует
и на открыть новую вкладку подобное
На «открыть новую вкладку» рассылается топик "browser-open-newtab-start",
так что можно попробовать добавить в код обсёрвер, как-то так:
(flags => { var clear = Services.clearData.deleteData.bind(null, flags, () => {}); var skip, check = () => { skip = null; for(var w of CustomizableUI.windows) for(var tab of gBrowser.tabs) try { if (tab.linkedBrowser.URI.host) return; } catch {} clear(); } addEventListener("TabClose", e => skip ??= setTimeout(check, 400), false, gBrowser.tabContainer); var topic = "browser-open-newtab-start"; var obs = subj => Cu.getGlobalForObject(subj.wrappedJSObject) == window && clear(); Services.obs.addObserver(obs, topic); addDestructor(() => Services.obs.removeObserver(obs, topic)); })(Ci.nsIClearDataService.CLEAR_DOM_STORAGES);
Отсутствует
Dumby
Класс!
Перестало работать в 115 SessionStore.jsm -это ? Менял не помогло
if(event.button == 2 && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey){ var cancel = true; Services.obs.addObserver(function wfp(win, topic) { Services.obs.removeObserver(wfp, topic); var sd = win.gSanitizePromptDialog, {sanitize} = sd; sd.sanitize = e => cancel = sanitize.call(sd, e); }, "widget-first-paint"); SidebarUI.hide(); Sanitizer.showUI(window); var ssi = Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {}).SessionStoreInternal; if (cancel) return;
Отредактировано green25 (17-03-2025 18:41:55)
Отсутствует
Вот такой вопрос. Есть в настройках переключатель - показать новую боковую панель. Есть обычная старая боковая панель. Нужна кнопка переключения между старой и новой. т.к в новой не отображаются пункты с других кнопок и дополнений. т.к. еще не перешли на новую боковую панель. Из новых показывает только BrowserConsole от Dumby, которая сделана на USF
Добавлено 20-03-2025 22:12:22
Есть кнопка
// http://infocatcher.ucoz.net/js/cb/editCustomButtonInTab.js // https://github.com/Infocatcher/Custom_Buttons/tree/master/Edit_Custom_Button_in_Tab // Edit Custom Button in Tab button for Custom Buttons // (code for "initialization" section) // (c) Infocatcher 2012-2014 // version 0.1.8.3 - 2014-01-12 // Note: // In Firefox 3.6 and older: // - Force enables "Save size and position of editor windows separately for each custom button" // option for editor in tab (because doesn't work without this) // - tab with editor can't be closed sometimes using OK/Cancel buttons var editInTabLabel = (function() { var locale = (function() { if("Services" in window && "locale" in Services) { var locales = Services.locale.requestedLocales // Firefox 64+ || Services.locale.getRequestedLocales && Services.locale.getRequestedLocales(); if(locales) return locales[0]; } var prefs = "Services" in window && Services.prefs || Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefBranch); function pref(name, type) { return prefs.getPrefType(name) != prefs.PREF_INVALID ? prefs["get" + type + "Pref"](name) : undefined; } if(!pref("intl.locale.matchOS", "Bool")) { // Also see https://bugzilla.mozilla.org/show_bug.cgi?id=1414390 var locale = pref("general.useragent.locale", "Char"); if(locale && locale.substr(0, 9) != "chrome://") return locale; } return Components.classes["@mozilla.org/chrome/chrome-registry;1"] .getService(Components.interfaces.nsIXULChromeRegistry) .getSelectedLocale("global"); })().match(/^[a-z]*/)[0]; if(locale == "ru") return "Редактировать во вкладке…"; return "Edit button in tab…"; })(); const editorBaseUri = "chrome://custombuttons/content/editor.xul"; const cbIdTabAttr = "custombuttons-editInTab-id"; const editId = "custombuttons-contextpopup-edit"; const editInTabId = editId + "InTab"; var editInTab = document.getElementById(editInTabId); if(editInTab) editInTab.parentNode.removeChild(editInTab); var editItem = document.getElementById(editId); editInTab = editItem.cloneNode(true); editInTab.id = editInTabId; editInTab.setAttribute("cb_id", editInTabId); editInTab.setAttribute("label", editInTabLabel); editInTab.setAttribute("oncommand", "editCustomButtonInTab();"); if(!Object.create) // Firefox 3.6 and older editInTab.removeAttribute("observes"); editInTab.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAitJREFUeNrEk0tIVVEUhr99zrnHc1+SkYQVFWo20G6SgkFRDorEILFJDoogkoLoXfOopEZCYIFlIITlRIUiC5UmFZVk1igwCAozfD9uat17z97tc5XK0pGDFiz289/rXz//FkopFhMGiwyr5GoHHgkpZUnCde9LqXwwHyuR3HVNIzZpGrubbLtjfHwYyzvywIYpHp0o386ajAAD3/R1MRfugZeFoGcgbm9pedo+7VVVCMvTwKt8tGwrfXGb5mfRJFj8VV0Ki7hpk9t5gW35lYx9GcSZGFOGSjJQvuXpYd4PTLPUYU6m+Q1SgzbBkEPey0tUHjlJfU8j0c8j+Aa/ahFn2x2cdknVgLBfpx5DyTQIBGx8+oHjras4vX8DtfWNFG0q4gmPyas9VqgZqEbNAEvPUnW1sCMI+QVBPXc02Ar5ONiURW55NsHus1TkjNDW2srHdYcormo/Z2kG+0p35BPTfaaHrVnBBAmt75QwKK3LYuPetdDbDxMTdHc2ELn4gfWj32l+MFQhdla1KVdKpCvxBPXAcWUSlQEaYgeIlK2GvmENHuHOmxVcW3mLoDuqn09gGjNiF8xnEPWw+DUFpTA0BS+uc/tdDodrnhf+445dV9p/LaQw+SH8nBfVRBMpKi0zm5LIEupq7lF541Vhy6lIV3XGTRw5qdWXM078bRSBK3zs6b3MWxEgplxSPnWS2e8kwXfPbO4SanIefy4cf7bWtdAl8d9/408BBgBVmNFVzOyEfgAAAABJRU5ErkJggg=="); editItem.parentNode.insertBefore(editInTab, editItem.nextSibling); Array.prototype.filter.call( // Process already cloned menu items document.getElementsByAttribute("observes", editItem.getAttribute("observes")), function(mi) { var id = mi.id || ""; return mi != editItem && id.substr(0, editId.length) == editId && id.substr(0, editInTabId.length) != editInTabId; } ).forEach(function(editItem, i) { var clone = editInTab.cloneNode(true); clone.id += "-cloned-" + i; editItem.parentNode.insertBefore(clone, editItem.nextSibling); }); // Process #custombuttons-contextpopup-sub const editIdSub = editId + "-sub"; var editItemSub = document.getElementById(editIdSub); if(editItemSub) { var clone = editInTab.cloneNode(true); if(editItemSub.hasAttribute("observes")) clone.setAttribute("observes", editItemSub.getAttribute("observes")); else clone.removeAttribute("observes"); clone.id += "-sub"; editItemSub.parentNode.insertBefore(clone, editItemSub.nextSibling); } window.editCustomButtonInTab = function(btn, newTab) { // Should be global to work in cloned menus if(!btn) btn = custombuttons.popupNode; if(!btn) return; var btnId = btn.id; var link = custombuttons.makeButtonLink("edit", btnId); var cbService = "cbICustomButtonsService" in Components.interfaces ? Components.classes["@xsms.nm.ru/custombuttons/cbservice;1"] .getService(Components.interfaces.cbICustomButtonsService) : Components.classes["@xsms.nm.ru/custombuttons/cbservice;1"] // Custom Buttons 0.0.5.9+ .getService(Components.interfaces.nsISupports) .wrappedJSObject; var param = cbService.getButtonParameters(link); var editorUriFull = editorBaseUri + "?window=" + cbService.getWindowId(document.documentURI) + "&id=" + btnId; var editorUri = cbService.mode & 64 /*CB_MODE_SAVE_EDITOR_SIZE_SEPARATELY*/ || !Object.create // Firefox 3.6 and older ? editorUriFull : editorBaseUri; // Search for already opened tab var rawParam = unwrap(param); var isSeaMonkey = "Services" in window && Services.appinfo.name == "SeaMonkey"; var ws = Components.classes["@mozilla.org/appshell/window-mediator;1"] .getService(Components.interfaces.nsIWindowMediator) .getEnumerator(isSeaMonkey ? null : "navigator:browser"); while(ws.hasMoreElements()) { let win = ws.getNext(); if(isSeaMonkey && win.location.href != "chrome://navigator/content/navigator.xul") continue; let gBrowser = win.gBrowser; let tabs = gBrowser.tabs || gBrowser.tabContainer.childNodes; for(let i = 0, l = tabs.length; i < l; ++i) { let tab = tabs[i]; if(tab == newTab) continue; let browser = tab.linkedBrowser; if(!browser) continue; let loc = browser.currentURI.spec; if(loc.substr(0, editorBaseUriLength) != editorBaseUri) continue; let isSameEditor = loc == editorUriFull || tab.getAttribute(cbIdTabAttr) == btnId; let win = browser.contentWindow; // Will be null for unloaded tab if(!isSameEditor && win) { let rawWin = unwrap(win); let winParam = "arguments" in rawWin && rawWin.arguments.length ? unwrap(rawWin.arguments[0]) : rawWin.editor && rawWin.editor.param; isSameEditor = winParam && winParam.buttonLink == link; } if(isSameEditor) { gBrowser.selectedTab = tab; win && win.focus(); newTab && setTimeout(function() { gBrowser.removeTab(newTab); }, 0); return; } } } // Or open new tab var tab = newTab; if(!tab) { tab = gBrowser.selectedTab = gBrowser.addTab(editorUri, { triggeringPrincipal: "Services" in window // Firefox 63+ && Services.scriptSecurityManager && Services.scriptSecurityManager.getSystemPrincipal() }); initSessionStore(); tab.setAttribute(cbIdTabAttr, btn.id); } var browser = tab.linkedBrowser; browser.addEventListener("DOMContentLoaded", function load(e) { var doc = e.target; if(doc.location != editorUri) return; browser.removeEventListener(e.type, load, false); var win = doc.defaultView; win.arguments = [param]; var iconLink = doc.createElementNS("http://www.w3.org/1999/xhtml", "link"); iconLink.rel = "shortcut icon"; //iconLink.href = "chrome://custombuttons-context/content/icons/default/custombuttonsEditor.ico"; iconLink.href = getStdImage(rawParam.image); iconLink.style.display = "none"; doc.documentElement.insertBefore(iconLink, doc.documentElement.firstChild); var alreadyAsked = false; function checkUnsaved(e) { if(alreadyAsked) return; var dlg = unwrap(doc).documentElement; if( "_fireButtonEvent" in dlg ? !dlg._fireButtonEvent("cancel") : !dlg.cancelDialog() ) e.preventDefault(); } function onDialogCancel(e) { alreadyAsked = true; // win.setTimeout shouldn't fire while confirmation dialog from the same window are opened win.setTimeout(function() { alreadyAsked = false; }, 100); } function destroy(e) { win.removeEventListener("dialogcancel", onDialogCancel, false); win.removeEventListener("beforeunload", checkUnsaved, false); win.removeEventListener("unload", destroy, false); } win.addEventListener("dialogcancel", onDialogCancel, false); win.addEventListener("beforeunload", checkUnsaved, false); win.addEventListener("unload", destroy, false); }, false); }; function unwrap(o) { return o.wrappedJSObject || o; // Firefox 3.6 and older } function getStdImage(iid) { if(/^custombuttons-stdicon-(\d)$/.test(iid)) switch(+RegExp.$1) { // chrome://custombuttons/skin/custombuttons.css // toolbarbutton[cb-stdicon="custombuttons-stdicon-*"] { ... } case 1: return "chrome://custombuttons/skin/button.png"; case 2: return "chrome://custombuttons/skin/stdicons/rbutton.png"; case 3: return "chrome://custombuttons/skin/stdicons/gbutton.png"; case 4: return "chrome://custombuttons/skin/stdicons/bbutton.png"; } return iid || "chrome://custombuttons/skin/button.png"; } function initSessionStore() { initSessionStore = function() {}; var ss = "nsISessionStore" in Components.interfaces ? ( Components.classes["@mozilla.org/browser/sessionstore;1"] || Components.classes["@mozilla.org/suite/sessionstore;1"] ).getService(Components.interfaces.nsISessionStore) : SessionStore; // Firefox 61+ https://bugzilla.mozilla.org/show_bug.cgi?id=1450559 ss.persistTabAttribute(cbIdTabAttr); } function checkTab(tab) { var cbId = tab.getAttribute(cbIdTabAttr); if(!cbId) return; initSessionStore(); let btn = document.getElementById(cbId); if(btn) editCustomButtonInTab(btn, tab); } const editorBaseUriLength = editorBaseUri.length; // We can't use only SSTabRestoring: user can reload tab with editor addEventListener("DOMContentLoaded", function(e) { var doc = e.target; if(doc.location.href.substr(0, editorBaseUriLength) != editorBaseUri) return; var tabs = gBrowser.tabs || gBrowser.tabContainer.childNodes; for(var i = 0, l = tabs.length; i < l; ++i) { let tab = tabs[i]; let browser = tab.linkedBrowser; if(browser && browser.contentDocument == doc) { checkTab(tab); break; } } }, true, document.getElementById("appcontent")); // Firefox 60+, gBrowser isn't a DOM node anymore checkTab(gBrowser.selectedTab); function destructor(reason) { if(reason == "update" || reason == "delete") { Array.prototype.slice.call(document.getElementsByAttribute("cb_id", editInTabId)).forEach(function(btn) { btn.parentNode.removeChild(btn); }); delete window.editCustomButtonInTab; } } if( typeof addDestructor == "function" // Custom Buttons 0.0.5.6pre4+ && addDestructor != ("addDestructor" in window && window.addDestructor) ) addDestructor(destructor, this); else this.onDestroy = destructor;
if(true) return; // Disabled by Disable Initialization button // https://github.com/Infocatcher/Custom_Buttons/tree/master/CB_Source_Editor // http://infocatcher.ucoz.net/js/cb/cbSourceEditor.js // Source Editor (formerly Orion Editor) button for Custom Buttons // (code for "initialization" section) // (c) Infocatcher 2012-2019 // version 0.1.0a10 - 2019-12-25 var options = { cssInHelp: true, codeMirror: { lineNumbers: true, enableCodeFolding: true, showTrailingSpace: true, lineWrapping: true, autocomplete: true, fontSize: 12 }, orion: { lineNumbers: true } }; // Also see devtools.editor.* preferences in about:config const watcherId = "customButtonsSourceEditor_" + this.id; var {Components} = window; // Prevent garbage collection in Firefox 3.6 and older var storage = (function() { if(!("Services" in window)) // Firefox 3.6 and older return Application.storage; // Simple replacement for Application.storage // See https://bugzilla.mozilla.org/show_bug.cgi?id=1090880 var global = Components.utils.getGlobalForObject(Components.utils); // Ensure, that we have global object (because window.Services may be overwritten) //var global = Components.utils.import("resource://gre/modules/Services.jsm", {}); var ns = "_cbSourceEditorStorage"; // Note: Firefox 57+ returns NonSyntacticVariablesObject w/o .Object property var storage = global[ns] || (global[ns] = Components.utils.getGlobalForObject(global).Object.create(null)); return { get: function(key, defaultVal) { if(key in storage) return storage[key]; return defaultVal; }, set: function(key, val) { if(key === null) delete storage[key]; else storage[key] = val; } }; })(); var watcher = storage.get(watcherId, null); if(!watcher) { watcher = { REASON_STARTUP: 1, REASON_SHUTDOWN: 2, REASON_WINDOW_LOADED: 3, REASON_WINDOW_CLOSED: 4, get obs() { delete this.obs; return this.obs = Components.classes["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService); }, get ww() { delete this.ww; return this.ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] .getService(Components.interfaces.nsIWindowWatcher); }, get wm() { delete this.wm; return this.wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] .getService(Components.interfaces.nsIWindowMediator); }, get platformVersion() { delete this.platformVersion; return this.platformVersion = parseFloat(Services.appinfo.platformVersion); }, get hasCodeMirror() { delete this.hasCodeMirror; return this.hasCodeMirror = Services.appinfo.name == "Pale Moon" //~ todo: test || this.platformVersion >= 27; }, init: function(reason) { if(!this.hasCodeMirror) { this.isBrowserWindow = function() { return false; }; } this.obs.addObserver(this, "quit-application-granted", false); var ws = this.wm.getEnumerator(null); while(ws.hasMoreElements()) this.initWindow(ws.getNext(), reason); this.ww.registerNotification(this); }, destroy: function(reason) { this.obs.removeObserver(this, "quit-application-granted"); var ws = this.wm.getEnumerator(null); while(ws.hasMoreElements()) this.destroyWindow(ws.getNext(), reason); this.ww.unregisterNotification(this); }, initWindow: function(window, reason, isFrame) { if(this.isBrowserWindow(window)) { this.initBrowserWindow(window, reason); return; } if(!this.isEditorWindow(window)) return; _log("initWindow(): isFrame: " + isFrame); var document = window.document; if(isFrame) window.addEventListener("unload", this, false); Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader) .loadSubScript("chrome://global/content/globalOverlay.js", window); var isCodeMirror = false; try { // See chrome://browser/content/devtools/scratchpad.js ChromeUtils.importESModule("resource://devtools/client/netmonitor/src/components/source-editor.jsm", window); } catch(e) { var g = ChromeUtils.importESModule("resource://devtools/shared/loader/Loader.sys.mjs") var require = (g.devtools || g).require; [ "devtools/sourceeditor/editor", "devtools/client/sourceeditor/editor", // Firefox 44+ "devtools/client/shared/sourceeditor/editor" // Firefox 68+ ].some(function(path) { try { return window.SourceEditor = require(path); } catch(e) { } return null; }); isCodeMirror = true; } var SourceEditor = window.SourceEditor; if(this.platformVersion >= 73) { var psXUL = '<popupset id="sourceEditorPopupset">\ <linkset>\ <html:link rel="localization" href="toolkit/global/textActions.ftl" />\ </linkset>\ <menupopup id="sourceEditorContext"\ onpopupshowing="popupHandler(event.target)"\ oncommand="popupHandler(event.target)">\ \ <menuitem id="menu_undo" data-l10n-id="text-action-undo" />\ <menuitem id="menu_redo" data-l10n-id="text-action-redo" />\ <menuseparator/>\ <menuitem id="menu_cut" data-l10n-id="text-action-cut" />\ <menuitem id="menu_copy" data-l10n-id="text-action-copy" />\ <menuitem id="menu_paste" data-l10n-id="text-action-paste" />\ <menuitem id="menu_delete" data-l10n-id="text-action-delete" />\ <menuseparator/>\ <menuitem id="menu_selectAll" data-l10n-id="text-action-select-all" />\ <menuseparator/>\ <menuitem id="menu_find" label="&findCmd.label;" accesskey="&findCmd.accesskey;" />\ <menuitem id="menu_findAgain" label="&findAgainCmd.label;" accesskey="&findAgainCmd.accesskey;" />\ <menuseparator/>\ <menuitem id="se-menu-gotoLine" label="&gotoLineCmd.label;" accesskey="&gotoLineCmd.accesskey;" />\ </menupopup>\ </popupset>'; var ps = window.MozXULElement.parseXULToFragment(psXUL, [ "chrome://global/locale/editMenuOverlay.dtd", "chrome://devtools/locale/sourceeditor.dtd" ]); if(!this.popupHandler) { var commands = {module: {}}; ps.querySelectorAll("menuitem").forEach(function(menuitem) { commands[menuitem.id] = menuitem.id.replace(/^(se-)?menu./, "cmd_"); }); Services.scriptloader.loadSubScript( "resource://devtools/client/shared/sourceeditor/editor-commands-controller.js", commands ); var createController = function(editor) { var res = editor.popupCmdController = commands.createController(editor); res.docShell = editor.container.contentWindow.docShell; return res; } var getObj = function(cmd, controller) { return controller.supportsCommand(cmd) ? controller: controller.docShell; } var setDisabled = function(menuitem) { var cmd = commands[menuitem.id]; menuitem.disabled = !getObj(cmd, this).isCommandEnabled(cmd); } this.popupHandler = function(node) { var ed = node.ownerDocument.activeElement.contentWindow.editor; var controller = ed.popupCmdController || createController(ed); var cmd = commands[node.id]; if(cmd) getObj(cmd, controller).doCommand(cmd); else node.menuitems.forEach(setDisabled, controller); } } var popup = ps.querySelector("menupopup"); popup.menuitems = popup.querySelectorAll("menuitem"); popup.popupHandler = this.popupHandler; } else { // See view-source:chrome://browser/content/devtools/scratchpad.xul // + view-source:chrome://browser/content/devtools/source-editor-overlay.xul var psXUL = (isCodeMirror ? '<!DOCTYPE popupset [\ <!ENTITY % editMenuStrings SYSTEM "chrome://global/locale/editMenuOverlay.dtd">\ %editMenuStrings;\ <!ENTITY % sourceEditorStrings SYSTEM "' + ( Services.appinfo.name == "Pale Moon" || Services.appinfo.name == "Basilisk" ? this.platformVersion >= 4.1 ? "chrome://devtools/locale/sourceeditor.dtd" : "chrome://global/locale/devtools/sourceeditor.dtd" : this.platformVersion >= 45 ? "chrome://devtools/locale/sourceeditor.dtd" : "chrome://browser/locale/devtools/sourceeditor.dtd" ) + '">\ %sourceEditorStrings;\ ]>\ <popupset id="sourceEditorPopupset"\ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">\ <menupopup id="sourceEditorContext"\ onpopupshowing="goUpdateSourceEditorMenuItems()">\ <menuitem id="menu_undo" label="&undoCmd.label;" accesskey="&undoCmd.accesskey;"\ oncommand="goDoCommand(\'cmd_undo\')" />\ <menuitem id="menu_redo" label="&redoCmd.label;" accesskey="&redoCmd.accesskey;"\ oncommand="goDoCommand(\'cmd_redo\')" />\ <menuseparator/>\ <menuitem id="menu_cut" label="&cutCmd.label;" accesskey="&cutCmd.accesskey;"\ oncommand="goDoCommand(\'cmd_cut\')" />\ <menuitem id="menu_copy" label="©Cmd.label;" accesskey="©Cmd.accesskey;"\ oncommand="goDoCommand(\'cmd_copy\')" />\ <menuitem id="menu_paste" label="&pasteCmd.label;" accesskey="&pasteCmd.accesskey;"\ oncommand="goDoCommand(\'cmd_paste\')" />\ <menuitem id="menu_delete" label="&deleteCmd.label;" accesskey="&deleteCmd.accesskey;"\ oncommand="goDoCommand(\'cmd_delete\')" />\ <menuseparator/>\ <menuitem id="menu_selectAll" label="&selectAllCmd.label;" accesskey="&selectAllCmd.accesskey;"\ oncommand="goDoCommand(\'cmd_selectAll\')" />\ <menuseparator/>\ <menuitem id="menu_find" label="&findCmd.label;" accesskey="&findCmd.accesskey;" />\ <menuitem id="menu_findAgain" label="&findAgainCmd.label;" accesskey="&findAgainCmd.accesskey;" />\ <menuseparator/>\ <menuitem id="se-menu-gotoLine"\ label="&gotoLineCmd.label;"\ accesskey="&gotoLineCmd.accesskey;"\ key="key_gotoLine"\ oncommand="goDoCommand(\'cmd_gotoLine\')"/>\ </menupopup>\ </popupset>' : '<popupset id="sourceEditorPopupset"\ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">\ <menupopup id="sourceEditorContext"\ onpopupshowing="goUpdateSourceEditorMenuItems()">\ <menuitem id="se-menu-undo"/>\ <menuitem id="se-menu-redo"/>\ <menuseparator/>\ <menuitem id="se-menu-cut"/>\ <menuitem id="se-menu-copy"/>\ <menuitem id="se-menu-paste"/>\ <menuitem id="se-menu-delete"/>\ <menuseparator/>\ <menuitem id="se-menu-selectAll"/>\ <menuseparator/>\ <menuitem id="se-menu-find"/>\ <menuitem id="se-menu-findAgain"/>\ <menuseparator/>\ <menuitem id="se-menu-gotoLine"/>\ </menupopup>\ </popupset>' ).replace(/>\s+</g, "><"); var ps = this.parseXULFromString(psXUL); // "Edit Custom Button in Tab" button, Firefox 71+ if(isFrame && "parseFromSafeString" in window.DOMParser.prototype) ps = window.MozXULElement.parseXULToFragment(ps.outerHTML); } document.documentElement.appendChild(ps); window.setTimeout(function() { function appendNode(nodeName, id) { var node = document.createElementNS(xulns, nodeName); node.id = id; document.documentElement.appendChild(node); } appendNode("commandset", "editMenuCommands"); appendNode("commandset", "sourceEditorCommands"); appendNode("keyset", "sourceEditorKeys"); appendNode("keyset", "editMenuKeys"); this.loadOverlays( window, function done() { window.setTimeout(function() { var mp = document.getElementById("sourceEditorContext"); if(mp.state == "closed") return; Array.prototype.forEach.call( mp.getElementsByAttribute("command", "*"), function(mi) { var cmd = mi.getAttribute("command"); var controller = document.commandDispatcher .getControllerForCommand(cmd); if(controller && !controller.isCommandEnabled(cmd)) mi.setAttribute("disabled", "true"); } ); }, 0); if(!isCodeMirror) return; // See view-source:chrome://browser/content/devtools/scratchpad.xul in Firefox 27.0a1 window.goUpdateSourceEditorMenuItems = function() { goUpdateGlobalEditMenuItems(); var commands = ["cmd_undo", "cmd_redo", "cmd_cut", "cmd_paste", "cmd_delete"]; commands.forEach(goUpdateCommand); }; var cmdsMap = { "se-menu-undo": "cmd_undo", "se-menu-redo": "cmd_redo", "se-menu-cut": "cmd_cut", "se-menu-copy": "cmd_copy", "se-menu-paste": "cmd_paste", "se-menu-delete": "cmd_delete", __proto__: null }; for(var id in cmdsMap) { var mi = document.getElementById(id); mi && mi.setAttribute("command", cmdsMap[id]); } // We can't use command="cmd_selectAll", menuitem will be wrongly disabled sometimes var enabledCmdsMap = { "se-menu-selectAll": "cmd_selectAll", "se-menu-findAgain": "cmd_findAgain", __proto__: null }; for(var id in enabledCmdsMap) { var mi = document.getElementById(id); if(mi) { mi.removeAttribute("command"); mi.removeAttribute("disabled"); mi.setAttribute("oncommand", "goDoCommand('" + enabledCmdsMap[id] + "');"); } } // Workaround: emulate keyboard shortcut var keyCmdsMap = { "menu_find": { keyCode: KeyboardEvent.DOM_VK_F, charCode: "f".charCodeAt(0), ctrlKey: true }, "menu_findAgain": { keyCode: KeyboardEvent.DOM_VK_G, charCode: "g".charCodeAt(0), ctrlKey: true }, __proto__: null }; var _key = function() { var e = this._keyData; var evt = document.createEvent("KeyboardEvent"); evt.initKeyEvent( "keydown", true /*bubbles*/, true /*cancelable*/, window, e.ctrlKey || false, e.altKey || false, e.shiftKey || false, e.metaKey || false, e.keyCode || 0, e.charCode || 0 ); document.commandDispatcher.focusedElement.dispatchEvent(evt); }; for(var id in keyCmdsMap) { var mi = document.getElementById(id); if(mi) { mi.removeAttribute("command"); mi.removeAttribute("disabled"); mi.setAttribute("oncommand", "this._key();"); mi._keyData = keyCmdsMap[id]; mi._key = _key; } } // Fix styles for autocomplete tooltip function css(uri) { document.insertBefore(document.createProcessingInstruction( "xml-stylesheet", 'href="' + uri + '" type="text/css"' ), document.documentElement); } css("resource://devtools/client/themes/variables.css"); css("resource://devtools/client/themes/common.css"); css("chrome://devtools/skin/tooltips.css"); if(this.platformVersion >= 68) window.setTimeout(function fixSelection() { var sheets = document.styleSheets; for(var i = sheets.length - 1; i >= 0; --i) { var sheet = sheets[i]; if(sheet.href != "resource://devtools/client/themes/common.css") continue; try { var rules = sheet.cssRules; } catch(e) { // InvalidAccessError: // A parameter or an operation is not supported by the underlying object return window.setTimeout(fixSelection, 10); } for(var j = 0, len = rules.length; j < len; ++j) if(rules[j].selectorText == "::selection") return !sheet.deleteRule(j); break; } return false; }, 10); }.bind(this), ["chrome://global/content/editMenuOverlay.xul", function check(window) { return window.document.getElementById("editMenuCommands").hasChildNodes(); }], ["chrome://browser/content/devtools/source-editor-overlay.xul", function check(window) { return window.document.getElementById("sourceEditorCommands").hasChildNodes(); }] ); }.bind(this), 500); // We should wait to not break other extensions with document.loadOverlay() var tabs = document.getElementById("custombuttons-editbutton-tabbox"); var selectedPanel = tabs.selectedPanel; Array.prototype.slice.call(document.getElementsByTagName("cbeditor")).forEach(function(cbEditor) { if("__sourceEditor" in cbEditor) return; var code = cbEditor.value; var isCSS = options.cssInHelp && cbEditor.id == "help"; if(isCodeMirror) { var opts = { mode: isCSS ? SourceEditor.modes.css : SourceEditor.modes.js, value: code, lineNumbers: true, enableCodeFolding: true, showTrailingSpace: true, autocomplete: true, contextMenu: "sourceEditorContext" }; var optsOvr = options.codeMirror; for(var opt in optsOvr) if(optsOvr.hasOwnProperty(opt)) opts[opt] = optsOvr[opt]; var se = new SourceEditor(opts); if("codeMirror" in se) window.setTimeout(function() { if("insertCommandsController" in se) se.insertCommandsController(); // Pale Moon and Basilisk else this.insertCommandsController(se); }.bind(this), 200); } else { var se = new SourceEditor(); } se.__isCodeMirror = isCodeMirror; var seElt = document.createElementNS(xulns, "hbox"); if(cbEditor.id) seElt.id = "sourceEditor-" + cbEditor.id; seElt.className = "sourceEditor"; seElt.setAttribute("flex", 1); seElt.__sourceEditor = se; cbEditor.parentNode.insertBefore(seElt, cbEditor); //cbEditor.setAttribute("hidden", "true"); cbEditor.setAttribute("collapsed", "true"); cbEditor.parentNode.appendChild(cbEditor); cbEditor.__sourceEditor = se; cbEditor.__sourceEditorElt = seElt; cbEditor.__defineGetter__("value", function() { if("__sourceEditor" in this) { var se = this.__sourceEditor; if(!se.__initialized) return se.__value; return se.getText().replace(/\r\n?|\n\r?/g, "\n"); } return this.textbox.value; }); cbEditor.__defineSetter__("value", function(v) { if("__sourceEditor" in this) { var se = this.__sourceEditor; if(!se.__initialized) { var _this = this; se.__onLoadCallbacks.push(function() { _this.value = v; }); return se.__value = v; } return se.setText(v.replace(/\r\n?|\n\r?/g, "\n")); } return this.textbox.value = v; }); cbEditor.selectLine = function(lineNumber) { if("__sourceEditor" in this) { var se = this.__sourceEditor; if(!se.__initialized) { var _this = this, args = arguments; se.__onLoadCallbacks.push(function() { _this.selectLine.apply(_this, args); }); return undefined; } if(se.__isCodeMirror) { //se.focus(); //se.setCursor({ line: lineNumber - 1, ch: 0 }); //~ todo: optimize var val = this.value; var lines = val.split("\n"); var line = Math.min(lineNumber - 1, lines.length); var ch = lines[line].length; se.focus(); return se.setSelection({ line: line, ch: 0 }, { line: line, ch: ch }); } else { var selStart = se.getLineStart(lineNumber - 1); var selEnd = se.getLineEnd(lineNumber - 1, false); se.focus(); return se.setSelection(selStart, selEnd); } } return this.__proto__.selectLine.apply(this, arguments); }; // For edit_button() from chrome://custombuttons/content/editExternal.js seElt.__cbEditor = cbEditor; seElt.__defineGetter__("localName", function() { return "cbeditor"; }); seElt.__defineGetter__("value", function() { return this.__cbEditor.value; }); seElt.__defineSetter__("value", function(val) { this.__cbEditor.value = val; }); se.__initialized = false; se.__onLoadCallbacks = []; se.__value = code; var onTextChanged = se.__onTextChanged = function() { window.editor.changed = true; }; var isLoaded = reason == this.REASON_WINDOW_LOADED; function done() { se.__initialized = true; se.__onLoadCallbacks.forEach(function(fn) { try { fn(); } catch(e) { Components.utils.reportError(e); } }); delete se.__onLoadCallbacks; delete se.__value; } if(isCodeMirror) { se.appendTo(seElt).then(function() { try { se.setupAutoCompletion(); } catch(e) { Components.utils.reportError(e); } if("setFontSize" in se) try { se.setFontSize(options.codeMirror.fontSize); } catch(e) { Components.utils.reportError(e); } window.setTimeout(function() { window.editor.changed = false; // Strange... window.setTimeout(function() { // Workaround for unexpected onTextChanged() calls if(window.editor.changed && cbEditor.value == code) window.editor.changed = false; }, 100); se.on("change", onTextChanged); if(isLoaded) { if("clearHistory" in se) se.clearHistory(); else { var seGlobal = Components.utils.getGlobalForObject(SourceEditor.prototype); // Note: this is resource://app/modules/devtools/gDevTools.jsm scope in Firefox 34+ var cm = seGlobal.editors.get(se); cm.clearHistory(); } } }, isFrame ? 50 : 15); // Oh, magic delays... done(); // See resource:///modules/devtools/sourceeditor/editor.js // doc.defaultView.controllers.insertControllerAt(0, controller(this, doc.defaultView)); var controllers = window.controllers; // nsIControllers var controller = se.__cmdController = controllers.getControllerAt(0); if("__cmdControllers" in tabs) tabs.__cmdControllers.push(controller); else { tabs.__cmdControllers = [controller]; var onSelect = tabs.__onSelect = function() { var seElt = tabs.selectedPanel; if(!seElt || !("__sourceEditor" in seElt)) return; var se = seElt.__sourceEditor; var curController = se.__cmdController; tabs.__cmdControllers.forEach(function(controller) { try { if(controller == curController) controllers.insertControllerAt(0, controller); else controllers.removeController(controller); } catch(e) { } }); }; tabs.addEventListener("select", onSelect, false); window.setTimeout(onSelect, 0); // Activate controller from selected tab } }); } else { var opts = { mode: isCSS ? SourceEditor.MODES.CSS : SourceEditor.MODES.JAVASCRIPT, showLineNumbers: true, initialText: code, placeholderText: code, // For backward compatibility contextMenu: "sourceEditorContext" }; var optsOvr = options.orion; for(var opt in optsOvr) if(optsOvr.hasOwnProperty(opt)) opts[opt] = optsOvr[opt]; se.init(seElt, opts, function callback() { done(); isLoaded && se.resetUndo && se.resetUndo(); se.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onTextChanged); // Hack to use selected editor var controller = se.ui._controller; controller.__defineGetter__("_editor", function() { var seElt = tabs.selectedPanel; var se = seElt && seElt.__sourceEditor || document.getElementsByTagName("cbeditor")[0].__sourceEditor; return se; }); controller.__defineSetter__("_editor", function() {}); }); } }, this); // Trick to select correct tab (especially if was selected "Button settings" tab) tabs.tabs.advanceSelectedTab(1, true); tabs.tabs.advanceSelectedTab(-1, true); var origExecCmd = window.editor.execute_oncommand_code; window.editor.execute_oncommand_code = function() { var cd = document.commandDispatcher; var cdFake = { __proto__: cd, get focusedElement() { var selectedTab = tabs.selectedTab; if(selectedTab && selectedTab.id == "code-tab") return document.getElementById("code").textbox.inputField; return cd.focusedElement; } }; document.__defineGetter__("commandDispatcher", function() { return cdFake; }); try { var ret = origExecCmd.apply(this, arguments); } catch(e) { Components.utils.reportError(e); } // document.hasOwnProperty("commandDispatcher") == false, so we cat just delete our fake property delete document.commandDispatcher; return ret; }; window.addEventListener("load", function ensureObserversAdded() { window.removeEventListener("load", ensureObserversAdded, false); window.setTimeout(function() { window.editor.removeObservers(); }, 0); window.setTimeout(function() { window.editor.addObservers(); }, 0); }, false); // Fix for Ctrl+S hotkey (catched by CodeMirror) var hke = this.handleKeyEvent; window.addEventListener("keydown", hke, true); window.addEventListener("keypress", hke, true); window.addEventListener("keyup", hke, true); }, insertCommandsController: function(se) { this.insertCommandsController = insertCommandsController; return insertCommandsController(se); // devtools/client/sourceeditor/editor-commands-controller in Pale Moon/Basilisk function createController(ed) { return { supportsCommand: function (cmd) { switch (cmd) { case "cmd_find": case "cmd_findAgain": case "cmd_gotoLine": case "cmd_undo": case "cmd_redo": case "cmd_delete": case "cmd_selectAll": return true; } return false; }, isCommandEnabled: function (cmd) { let cm = ed.codeMirror; switch (cmd) { case "cmd_find": case "cmd_gotoLine": case "cmd_selectAll": return true; case "cmd_findAgain": return cm.state.search != null && cm.state.search.query != null; case "cmd_undo": return ed.canUndo(); case "cmd_redo": return ed.canRedo(); case "cmd_delete": return ed.somethingSelected(); } return false; }, doCommand: function (cmd) { let cm = ed.codeMirror; let map = { "cmd_selectAll": "selectAll", "cmd_find": "find", "cmd_undo": "undo", "cmd_redo": "redo", "cmd_delete": "delCharAfter", "cmd_findAgain": "findNext" }; if (map[cmd]) { cm.execCommand(map[cmd]); return; } if (cmd == "cmd_gotoLine") { ed.jumpToLine(); } }, onEvent: function () {} }; } function insertCommandsController(sourceEditor) { let input = sourceEditor.codeMirror.getInputField(); let controller = createController(sourceEditor); input.controllers.insertControllerAt(0, controller); } }, destroyWindow: function(window, reason, isFrame) { if(reason == this.REASON_WINDOW_CLOSED) window.removeEventListener(this.loadEvent, this, false); // Window can be closed before DOMContentLoaded if(this.isBrowserWindow(window)) { this.destroyBrowserWindow(window, reason); return; } if(!this.isEditorWindow(window) || !("SourceEditor" in window)) return; _log("destroyWindow(): isFrame: " + isFrame); var document = window.document; if(isFrame) window.removeEventListener("unload", this, false); var tabs = document.getElementById("custombuttons-editbutton-tabbox"); if("__onSelect" in tabs) { tabs.removeEventListener("select", tabs.__onSelect, false); delete tabs.__onSelect; delete tabs.__cmdControllers; } Array.prototype.slice.call(document.getElementsByTagName("cbeditor")).forEach(function(cbEditor) { if(!("__sourceEditor" in cbEditor)) return; var se = cbEditor.__sourceEditor; var isCodeMirror = se.__isCodeMirror; if(isCodeMirror) se.off("change", se.__onTextChanged); else se.removeEventListener(window.SourceEditor.EVENTS.TEXT_CHANGED, se.__onTextChanged); delete se.__onTextChanged; if(reason == this.REASON_SHUTDOWN) { var val = cbEditor.value; delete cbEditor.value; delete cbEditor.selectLine; var seElt = cbEditor.__sourceEditorElt; seElt.parentNode.insertBefore(cbEditor, seElt); seElt.parentNode.removeChild(seElt); delete cbEditor.__sourceEditorElt; delete cbEditor.__sourceEditor; delete seElt.__sourceEditor; delete seElt.__cbEditor; cbEditor.value = val; window.setTimeout(function() { cbEditor.removeAttribute("collapsed"); }, 0); } se.destroy(); if("__cmdController" in se) { try { window.controllers.removeController(se.__cmdController); } catch(e) { } delete se.__cmdController; } }, this); if(reason == this.REASON_SHUTDOWN) { delete window.editor.execute_oncommand_code; [ "sourceEditorPopupset", "editMenuCommands", "sourceEditorCommands", "sourceEditorKeys", "editMenuKeys" ].forEach(function(id) { var node = document.getElementById(id); node && node.parentNode.removeChild(node); }); [ // chrome://global/content/globalOverlay.js "closeWindow", "canQuitApplication", "goQuitApplication", "goUpdateCommand", "goDoCommand", "goSetCommandEnabled", "goSetMenuValue", "goSetAccessKey", "goOnEvent", "visitLink", "setTooltipText", "NS_ASSERT", // chrome://global/content/editMenuOverlay.xul => view-source:chrome://global/content/editMenuOverlay.js "goUpdateGlobalEditMenuItems", "goUpdateUndoEditMenuItems", "goUpdatePasteMenuItems" ].forEach(function(p) { delete window[p]; }); for(var child = document.documentElement; child = child.previousSibling; ) { if( child.nodeType == child.PROCESSING_INSTRUCTION_NODE && child.data.indexOf("://devtools/") != -1 ) { setTimeout(function(child) { child.parentNode.removeChild(child); }, 0, child); } } delete window.SourceEditor; } var hke = this.handleKeyEvent; window.removeEventListener("keydown", hke, true); window.removeEventListener("keypress", hke, true); window.removeEventListener("keyup", hke, true); //~ todo: we have one not removed controller! //LOG("getControllerCount(): " + window.controllers.getControllerCount()); }, initBrowserWindow: function(window, reason) { _log("initBrowserWindow()"); window.addEventListener("DOMContentLoaded", this, false); Array.prototype.forEach.call(window.frames, function(frame) { this.initWindow(frame, reason, true); }, this); }, destroyBrowserWindow: function(window, reason) { _log("destroyBrowserWindow()"); window.removeEventListener("DOMContentLoaded", this, false); Array.prototype.forEach.call(window.frames, function(frame) { this.destroyWindow(frame, reason, true); }, this); }, isEditorWindow: function(window) { return window.location.href.substr(0, 41) == "chrome://custombuttons/content/editor.xul"; }, isBrowserWindow: function(window) { var loc = window.location.href; return loc == "chrome://browser/content/browser.xul" || loc == "chrome://browser/content/browser.xhtml" // Firefox 69+ || loc == "chrome://navigator/content/navigator.xul"; }, get loadEvent() { // "DOMContentLoaded" -> initWindow() may hang editor window (and browser) delete this.loadEvent; return this.loadEvent = this.platformVersion >= 73 ? "load" : "DOMContentLoaded"; }, observe: function(subject, topic, data) { if(topic == "quit-application-granted") this.destroy(); else if(topic == "domwindowopened") subject.addEventListener(this.loadEvent, this, false); else if(topic == "domwindowclosed") this.destroyWindow(subject, this.REASON_WINDOW_CLOSED); }, handleEvent: function(e) { switch(e.type) { case "DOMContentLoaded": case "load": //var window = e.currentTarget; var window = e.target.defaultView || e.target; window.removeEventListener(e.type, this, false); var isFrame = window != e.currentTarget; this.initWindow(window, this.REASON_WINDOW_LOADED, isFrame); break; case "unload": //var window = e.currentTarget; var window = e.target.defaultView || e.target; window.removeEventListener(e.type, this, false); this.destroyWindow(window, this.REASON_WINDOW_CLOSED, true); } }, handleKeyEvent: function(e) { if( (e.keyCode == e.DOM_VK_S || String.fromCharCode(e.charCode).toUpperCase() == "S") && e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey ) { e.preventDefault(); e.stopPropagation(); if(e.type == "keydown") { var window = e.currentTarget; window.editor.updateButton(); } } }, loadOverlays: function() { this.runGenerator(this.loadOverlaysGen, this, arguments); }, get loadOverlaysGen() { var fn = this._loadOverlaysGen.toString() .replace(/__yield/g, "yield"); try { new Function("function test() { yield 0; }"); } catch(e) { // Firefox 58+: SyntaxError: yield expression is only valid in generators fn = fn.replace("function", "function*"); // Firefox 26+ } delete this.loadOverlaysGen; return this.loadOverlaysGen = eval("(" + fn + ")"); }, _loadOverlaysGen: function loadOverlaysGen(window, callback/*, overlayData1, ...*/) { var gen = loadOverlaysGen.__generator; for(var i = 2, l = arguments.length; i < l; ++i) { var overlayData = arguments[i]; this.loadOverlay(window, overlayData[0], overlayData[1], function() { gen.next(); }); __yield(0); } callback(); __yield(0); }, loadOverlay: function(window, uri, check, callback) { var document = window.document; var stopWait = Date.now() + 4500; window.setTimeout(function load() { _log("loadOverlay(): " + uri); var tryAgain = Date.now() + 800; try { document.loadOverlay(uri, null); } catch(e) { window.setTimeout(callback, 0); return; } window.setTimeout(function ensureLoaded() { if(check(window)) window.setTimeout(callback, 0); else if(Date.now() > stopWait) return; else if(Date.now() > tryAgain) window.setTimeout(load, 0); else window.setTimeout(ensureLoaded, 50); }, 50); }, 0); }, runGenerator: function(genFunc, context, args) { var gen = genFunc.apply(context, args); genFunc.__generator = gen; gen.next(); }, parseXULFromString: function(xul) { xul = xul.replace(/>\s+</g, "><"); try { return new DOMParser().parseFromString(xul, "application/xml").documentElement; } catch(e) { // See http://custombuttons.sourceforge.net/forum/viewtopic.php?f=5&t=3720 // + https://forum.mozilla-russia.org/viewtopic.php?pid=732243#p732243 var dummy = document.createElement("dummy"); dummy.innerHTML = xul.trimLeft(); return dummy.firstChild; } } }; storage.set(watcherId, watcher); setTimeout(function() { watcher.init(watcher.REASON_STARTUP); }, 50); } function destructor(reason) { if(reason == "update" || reason == "delete") { watcher.destroy(watcher.REASON_SHUTDOWN); storage.set(watcherId, null); } } if( typeof addDestructor == "function" // Custom Buttons 0.0.5.6pre4+ && addDestructor != ("addDestructor" in window && window.addDestructor) ) addDestructor(destructor, this); else this.onDestroy = destructor; function ts() { var d = new Date(); var ms = d.getMilliseconds(); return d.toTimeString().replace(/^.*\d+:(\d+:\d+).*$/, "$1") + ":" + "000".substr(("" + ms).length) + ms + " "; } function _log(s) { Services.console.logStringMessage("[Custom Buttons :: Source Editor] " + ts() + s); }
Отредактировано Andrey_Krropotkin (20-03-2025 22:31:24)
На форуме
Перестало работать в 115 SessionStore.jsm -это ? Менял не помогло
Я ничего не понял.
Что оно делало, при чём здесь SessionStore,
и почему jsm, что менял, и чему не помогло.
Вообще-то, топик "widget-first-paint" — он для top-level окон.
А в 115 это добро открывается во внутриоконном диаложке.
Так что, здесь больше подходит листенер.
И что там за cancel
Когда-то давно, метод sanitize() возвращал логическое значение,
true если случилась ошибка, не при самой очистке, а при исполнении именно этой функции.
А в 115 он ничего не возвращает.
Если нужно знать, не свалился ли код в блок catch {}
то можно попробовать проверять e.defaultPrevented
document.getElementById("window-modal-dialog").addEventListener("dialogopen", e => { var win = e.target.querySelector("browser.dialogFrame").contentWindow; var sd = win.gSanitizePromptDialog, {sanitize} = sd; sd.sanitize = e => { sanitize.call(sd, e); alert(`Catch${e.defaultPrevented ? " not" : ""} happens.`); } }, {once: true}); Sanitizer.showUI(window);
"version": "0.0.7.0.0.35", (Обзор...0) не работает ?
Поставил 0.0.7.0.0.35 в 115.
У меня кнопка «Обзор… (O)» работает.
Нужна кнопка переключения между старой и новой.
Берёшь любую кнопку, которая
переключает какую-нибудь логическую настройку,
и приспосабливаешь под настройку "sidebar.revamp"
надо 2 раза повторить. чтобы открыть во вкладке, первый раз открывет пустое поле в /*Initialization Code*/
Ну так всё, нет больше SessionStore.persistTabAttribute()
Можно попробовать переделать на SessionStore.{g, s}etCustomTabValue()
/* || tab.getAttribute(cbIdTabAttr) == btnId; */ || SessionStore.getCustomTabValue(tab, cbIdTabAttr) == btnId; ..... /* initSessionStore(); tab.setAttribute(cbIdTabAttr, btn.id); */ SessionStore.setCustomTabValue(tab, cbIdTabAttr, btn.id); ..... /* var cbId = tab.getAttribute(cbIdTabAttr); if(!cbId) return; initSessionStore(); */ var cbId = SessionStore.getCustomTabValue(tab, cbIdTabAttr); if(!cbId) return;
/* var iconLink = doc.createElementNS("http://www.w3.org/1999/xhtml", "link"); iconLink.rel = "shortcut icon"; //iconLink.href = "chrome://custombuttons-context/content/icons/default/custombuttonsEditor.ico"; iconLink.href = getStdImage(rawParam.image); iconLink.style.display = "none"; doc.documentElement.insertBefore(iconLink, doc.documentElement.firstChild); */ gBrowser.setIcon(tab, getStdImage(rawParam.image), null, document.nodePrincipal); Object.defineProperty(doc, "body", {configurable: true, enumerable: true, value: doc.documentElement}); this.browsingContext.currentWindowGlobal.getActor("BrowserElement").receiveMessage = function() {};
Есть ли возможность реананимировать спорную кнопку
А сам-то как думаешь? Как по мне, так страшно даже приступить.
Для начала, нужно XUL <popupset>'а подсовременить.
Добавить ещё <link> локализации, и оставшиеся три менюитема перевести на data-l10n-id
То есть, примерно так
// var psXUL = '<popupset id="sourceEditorPopupset">\ <linkset>\ <html:link rel="localization" href="toolkit/global/textActions.ftl" />\ <html:link rel="localization" href="devtools/client/styleeditor.ftl" />\ </linkset>\ <menupopup id="sourceEditorContext"\ onpopupshowing="popupHandler(event.target)"\ oncommand="popupHandler(event.target)">\ \ <menuitem id="menu_undo" data-l10n-id="text-action-undo" />\ <menuitem id="menu_redo" data-l10n-id="text-action-redo" />\ <menuseparator/>\ <menuitem id="menu_cut" data-l10n-id="text-action-cut" />\ <menuitem id="menu_copy" data-l10n-id="text-action-copy" />\ <menuitem id="menu_paste" data-l10n-id="text-action-paste" />\ <menuitem id="menu_delete" data-l10n-id="text-action-delete" />\ <menuseparator/>\ <menuitem id="menu_selectAll" data-l10n-id="text-action-select-all" />\ <menuseparator/>\ <menuitem id="menu_find" data-l10n-id="styleeditor-find" />\ <menuitem id="menu_findAgain" data-l10n-id="styleeditor-find-again" />\ <menuseparator/>\ <menuitem id="se-menu-gotoLine" data-l10n-id="styleeditor-go-to-line" />\ </menupopup>\ </popupset>';
И, чуть CSS'а подсадить, а то, как минимум, <iframe> сам занимать всё место не хочет.
Где-то в методе initWindow(), например, после var document = window.document;
// var sheet = new window.CSSStyleSheet(); sheet.replaceSync("iframe{flex-grow:1!important;border:none!important}.tab-middle{outline:none!important}"); document.adoptedStyleSheets.push(sheet);
Отсутствует
Dumby, приветствую. Заметил, что кнопка:
(popup => { var id = "cswem-menugroup"; var mid = "_5dd73bb9-e728-4d1e-990b-c77d8e03670f_-menuitem-_root_menu"; var css = ` #${id} { padding-left: 30px; display: grid; grid-template-columns: repeat(auto-fill, 32px); grid-auto-rows: 26px; } #${id} > menuitem { -moz-box-pack: center; } #${mid}, #${id}:empty, #context-searchselect, #context-keywordfield, #${id} > menuitem > :not(.menu-iconic-left) { display: none; } /* #${id} > menuitem > .menu-iconic-left > .menu-iconic-icon { margin-inline: 2px -3px; } */ `.replace(/;$/gm, " !important;"); var url = "data:text/css," + encodeURIComponent(css), type = windowUtils.USER_SHEET; windowUtils.loadSheetUsingURIString(url, type); var menugroup = document.createXULElement("menugroup"); menugroup.id = id; menugroup.hidden = true; var find = info => info.type == "command"; menugroup.setAttribute("oncommand", "handleCommand(event);"); menugroup.handleCommand = e => { var target = e.target.linkedMenuitem; var {button, ctrlKey, shiftKey, altKey, metaKey} = e; Services.els.getListenerInfoFor(target).find(find).listenerObject({ button, target, currentTarget: target, ctrlKey, shiftKey, altKey, metaKey }); } document.getElementById("context-searchselect").after(menugroup); var kwf = document.getElementById("context-keywordfield"); Object.defineProperty(kwf, "hidden", { configurable: true, enumerable: true, get: () => true, set() {} }); addEventListener("popuphidden", e => { if (menugroup.firstChild && e.target == popup) menugroup.textContent = ""; }, false, popup); var fillMenugroup = menu => { var p = menu.querySelector(":scope > menupopup"); for(var menuitem of menu.getElementsByTagName("menuitem")) { var m = document.createXULElement("menuitem"); m.className = "menuitem-iconic"; m.setAttribute("image", menuitem.getAttribute("image")); var tt = menuitem.getAttribute("label"); if (menuitem.closest("menupopup") != p) tt = menuitem.closest("menu").getAttribute("label") + "\n" + tt; m.setAttribute("tooltiptext", tt); m.linkedMenuitem = menuitem; menugroup.append(m); } var lc = menugroup.lastChild; menugroup.style.setProperty( "height", (lc.screenY + lc.scrollHeight - menugroup.screenY) + "px", "important" ); } var mo = new MutationObserver(muts => { for(var mut of muts) for(var node of mut.addedNodes) if (node.id == mid) return fillMenugroup(node); }); mo.observe(popup, {childList: true}); addDestructor(() => { mo.disconnect(); delete kwf.hidden; menugroup.remove(); windowUtils.removeSheetUsingURIString(url, type); }); })(document.getElementById("contentAreaContextMenu"));
Отредактировано manuk (22-03-2025 11:42:23)
Отсутствует
Dumby спасибо, все работает
На форуме
Так-с… версия 0.0.7.0.0.11 перестала работать (истекли сертификаты?)… накатываю из другого профиля версию 0.0.7.0.0.16 — заработало (надолго ли?), но кнопка быстрого переключения about:config параметров слетела/съехала и перестала фурычить (c 2020 года не было нужды обновлять её).
Проверяю 0.0.7.0.0.31 — ну, обновило, кнопка так и остались "поехавшей"… И уже тот код кнопки, что был давно адаптирован под 0.0.7.0.0.16 уже не работает…
Но забавно то, что само расширение CustomButtons работает. Проблема осталась только в кнопках (которые теперь больше не работают)…
Вопрос, будет ли он ещё поддерживаться старыми версиями от 60-ых до 91esr (чтобы знать, стоит ли возиться с Quick toggle about:config preferences)?
Отредактировано T0PMØ3iLLA (22-03-2025 18:04:46)
Отсутствует
Dumby
Не фига не понял...
Что здесь исправить ?
if(event.button == 2 && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey){ var cancel = true; Services.obs.addObserver(function wfp(win, topic) { Services.obs.removeObserver(wfp, topic); var sd = win.gSanitizePromptDialog, {sanitize} = sd; sd.sanitize = e => cancel = sanitize.call(sd, e); }, "widget-first-paint"); Sanitizer.showUI(window); if (cancel) return;
Отсутствует
Andrey_Krropotkin
Это ваше ?Как аввтопопуп убрать ? Рарку с закладками открываю и при наваждении мыши и это открывается..
// http://infocatcher.ucoz.net/js/cb/toggleRestartlessAddons.js // https://forum.mozilla-russia.org/viewtopic.php?id=57948 // https://github.com/Infocatcher/Custom_Buttons/tree/master/Toggle_Restartless_Add-ons // Toggle Restartless Add-ons button for Custom Buttons // (code for "initialization" section) // Also the code can be used from main window context (as Mouse Gestures code, for example) // Also you can check for add-ons updates using right-click: // copy all code from // https://github.com/Infocatcher/Custom_Buttons/blob/master/Check_for_Addons_Updates/checkForAddonsUpdates.js // after "//== Check for Addons Updates begin"
Отсутствует
начала странно себя вести. Или так всегда было? Первый раз при выделении отображает нормально. Если кликнуть и перейти, а потом вернуться, выделить другой текст, то без перезагрузки страницы только иконка гугла.
Да, я вижу это.
Было ли так всегда — я без понятия, поскольку не пользуюсь.
Но это не кнопка так себя ведёт, а именно ContextSearch.
Она же не сама выдумывает что показывать, а всего лишь
отображает те пункты меню, которые заказал этот WebExtensions.
Проверить достаточно несложно — комментируешь строку /*#${mid},*/
таким образом пункт от CS перестанет быть скрытым,
и теперь можно кликать и сравнивать то, что создаёт код,
с тем, что есть в субменю аддона. Должно совпадать.
Так-с… версия 0.0.7.0.0.11 перестала работать (истекли сертификаты?)… накатываю из другого профиля версию 0.0.7.0.0.16 — заработало (надолго ли?), но кнопка быстрого переключения about:config параметров слетела/съехала и перестала фурычить (c 2020 года не было нужды обновлять её).
Проверяю 0.0.7.0.0.31 — ну, обновило, кнопка так и остались "поехавшей"… И уже тот код кнопки, что был давно адаптирован под 0.0.7.0.0.16 уже не работает…
Бессмыслица какая-то.
Расширение и код кнопок адаптируются под версию браузера,
а не код кнопки под версию расширения.
Вопрос, будет ли он ещё поддерживаться старыми версиями
от 60-ых
Нет, такая древность слишком экстремальна.
Нынешний антиподписячий код — это, вроде, для 65+
Что здесь исправить ?
Говорю же — понятия не имею.
Смысл этого огрызка кода ускользает от меня.
и при наваждении мыши
Значит onmouseover в коде ищи, или типа того.
Отсутствует
green25 это не мое, не пользуюсь
Garalf , чуть попозже, у меня там сборная солянка, а так есть QuickToggle в теме
На форуме
Dumby
Благодарю с popup справился..Но это же ваша фишка, сам бы не того..И не срабатывает в 115 . Sanitizer.showUI(window); - без толку коды остальные не работают
if(event.button == 2 && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey){ var cancel = true; Services.obs.addObserver(function wfp(win, topic) { Services.obs.removeObserver(wfp, topic); var sd = win.gSanitizePromptDialog, {sanitize} = sd; sd.sanitize = e => cancel = sanitize.call(sd, e); }, "widget-first-paint"); SidebarUI.hide(); Sanitizer.showUI(window); var ssi = Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {}).SessionStoreInternal; if (cancel) return; CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").closed); var s = "browser.zoom.full"; cbu.setPrefs(s, cbu.getPrefs(s) == true ? true : true); var s = "intl.accept_languages"; cbu.setPrefs(s, cbu.getPrefs(s) == "ru" ? "ru": "ru"); 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); document.querySelector( "#mainPopupSet > tooltip[onpopupshowing*=undoCloseTabsList]" )?.undoCloseTabsList.updUI(); (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.88, "rezka-ua.tv": 1.1, "https://www.youtube.com": 1.0, })) _cps2.set(_cps2.extractDomain(url), name, zoom, lc); }}); })(Cu.createLoadContext()); 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); gBrowser.removeAllTabsBut(gBrowser.selectedTab); } }; 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() }; var style = custombutton.buttonGetHelp(self).replace(/id/g, _id); var uri = makeURI('data:text/css,'+ encodeURIComponent(style)); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); sss.loadAndRegisterSheet(uri, 0);
Отсутствует
Garalf
onmousedown вместо onmouseover
и все в елочку!
Вот как растяг.пробел сделать толком..
*|*:root:not([inFullscreen]) #toolbar-menubar > :-moz-any(toolbarspring,spacer,[id^="wrapper-customizableui-special-spring"]) { -moz-flex-grow: 1 !important; -moz-box-flex: 1!important; max-width: none !important; } *|*:root:not([inFullscreen])#toolbar-menubar toolbarpaletteitem, [id^=wrapper-customizableui-special-spring], #toolbar-menubar toolbarspring{ max-width: none !important; -moz-flex-grow: 1 !important; -moz-box-flex: 1!important; }
Отредактировано green25 (22-03-2025 21:22:57)
Отсутствует
Расширение и код кнопок адаптируются под версию браузера, а не код кнопки под версию расширения.
Хм… вот тут я не пойму, что ж тогда осталось "не починено"… Переношу ещё одну кнопку "Ночной режим" («изуродовать стиль страницы»), со "старого профиля" (где Custom Buttons 0.0.7.0.0.16 всё ещё работает) — и она тоже ничего не делает на этом проблемном профиле (впрочем, как и на CustomButtons 0.0.7.0.0.31, и на 0.0.7.0.0.35)… Как выяснить, что мешает этим кнопкам работать? 91esr.
раздел с "установленными пользовательскими кнопками" не показывается в about:addons! в старом профиле (где эти кнопки работают), оказывается, тоже этого раздела больше нет
Отредактировано T0PMØ3iLLA (22-03-2025 22:05:53)
Отсутствует
Sanitizer.showUI(window); - без толку коды остальные не работают
В 115 появление диалога очистки не вызывает
приостановку исполнения JS-кода в окне браузера.
Можно внутрь переопределённого sanitize() добавлять.
document.getElementById("window-modal-dialog").addEventListener("dialogopen", e => { var win = e.target.querySelector("browser.dialogFrame").contentWindow; var sd = win.gSanitizePromptDialog, {sanitize} = sd; sd.sanitize = e => { sanitize.call(sd, e); CustomizableUI.setToolbarVisibility("PersonalToolbar", false); Services.prefs.setBoolPref("browser.zoom.full", true); Services.prefs.setCharPref("intl.accept_languages", "ru"); Services.prefs.setIntPref("media.autoplay.default", 5); Services.prefs.setIntPref("extensions.long_left_click.timeContent", 300); SidebarUI.hide(); var sel = "#mainPopupSet > tooltip[onpopupshowing*=undoCloseTabsList]"; document.querySelector(sel)?.undoCloseTabsList.updUI(); var lc = Cu.createLoadContext(); var {_cps2, name} = FullZoom; _cps2.removeByName(name, lc, {handleCompletion() { _cps2.setGlobal(name, 1, lc); for(var [url, zoom] of Object.entries({ "about:addons": .88, "about:preferences": .95, "about:preferences#search": .95, "about:preferences#privacy": .95, "about:preferences#general": .95, "rezka-ua.tv": 1.1, "https://www.youtube.com": 1, })) _cps2.set(_cps2.extractDomain(url), name, zoom, lc); }}); Services.cache2.clear(); var file = Services.dirsvc.get("ProfD", Ci.nsIFile); ["memory", "start.vbs"].forEach(file.append); file.launch(); gBrowser.removeAllTabsBut(gBrowser.selectedTab); } }, {once: true}); SidebarUI.hide(); Sanitizer.showUI(window);
как растяг.пробел сделать толком..
Можно посмотреть как это сделано в UCF.
Хм… вот тут я не пойму, что ж тогда осталось "не починено"
А мне тем более не понять, ведь неизвестно что именно делалось.
Напомню некоторые вещи.
Причём, не просто перезапуск, а перезапуск с очисткой startupCache.
Перезапуск кодом не представляется достаточно надёжным, поскольку
программную очистку startupCache при перезапуске починили только в Firefox 115.
Поэтому, лучше сделать всё самому вручную.
После установки идём на страницу about:profiles
находим текущий профиль, и жмём кнопку открытия локального каталога профиля.
Теперь выходим из браузера (Ctrl+Shift+Q), чуть ждём,
и в открытом ранее окне локального каталога профиля удаляем папку startupCache
Всё, теперь можно снова запускать Firefox, установка завершена.
Ещё, у тебя ни слова не сказано о том, какого вида установлен Custom Buttons.
Если bootstrap, то хорошо бы проверить, всё ли в порядке с установленным bootstrap-loader'ом.
А если paxmod, то в этом случае, настоятельно рекомендуется иметь код-запускатор.
Формально, paxmod это WebExtensions, а запускаются они очень поздно.
Может на глаз, в 91, это не так заметно, как в каких-нибудь шиздесятых,
но проблема ещё и в том, что сам момент запуска, в некоторых пределах,
плавает во времени. Это создаёт нездоровую внутреннюю обстановку для кода,
неизвестно что уже есть, а чего ещё нет. А с запускатором всё стабильно.
Код примерно такой. Добавить можно сразу после антиподписячего.
Кстати, для Firefox 91 ESR антиподписячий код не обязателен.
Эта версия избавлена от подписячества от природы, поэтому достаточно двух настроек
xpinstall.signatures.required и extensions.experiments.enabled
// (async xp => { var imp, 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} = Cu.import(xp + "jsm", {}); imp = uri => Cu.import(uri.resolve("startup.jsm"), {}); } else { // Fx 101+ var g = Cu.getGlobalForObject(Cu), te = new g.TextEncoder(); var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); var rph = ios.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); var impJSM = g.ChromeUtils.import, impESM = g.ChromeUtils.importESModule; try {var exp = impESM(xp + "sys.mjs");} catch {exp = impJSM(xp + "jsm");} var {XPIInternal} = exp; var ss = (subst, uri, ext) => rph.setSubstitution( subst, ios.newURI(uri.resolve("startup." + ext)) ); try {var useESM = parseInt(Services.appinfo.platformVersion) >= 108;} catch {} imp = (uri, id) => { var subst = te.encode(id).join(""); var url = `resource://${subst}/`; if (useESM) try { ss(subst, uri, "mjs"); return impESM(url); } catch(ex) { if (!ex || ex.message != "Failed to load " + url) return Cu.reportError(ex); } ss(subst, uri, "jsm"); return impJSM(url); } } var load = async (file, id) => { var rootURI = XPIInternal.getURIForResourceInFile(file, ""); imp(rootURI, 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.");
Как выяснить, что мешает этим кнопкам работать?
91esr.
Вообще-то, сначала неплохо бы в консоль браузера посмотреть.
Если там нет подсказок, то остаётся только отладочные логи в код втыкать.
Ну, или можешь URL кнопки дать, а я посмотрю, есть ли там какая-то несовместимость с 91.
Отредактировано Dumby (Вчера 12:18:39)
Отсутствует
Garalf простая кнопка в секцию код
/*CODE*/ var icon =this.icon || document.getAnonymousElementByAttribute(this, "class", "toolbarbutton-icon"); icon.style.transition = "transform 0.2s ease-in-out"; icon.style.transform = icon.style.transform ? "" : "rotate(180deg)"; var prefBranch = Components.classes["@mozilla.org/preferences-service;1"]. getService(Components.interfaces.nsIPrefBranch); var pref = "sidebar.revamp"; if (prefBranch.getBoolPref(pref) == true) { prefBranch.setBoolPref(pref, false); } else { prefBranch.setBoolPref(pref, true); }
иконка
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABdSURBVDiN7dKhCoBAEEXRg0G7/rBB/VvNrkWDCoILLovB4IUHMwxcJjy+xICA9SEBfUwQUB9zeyRGg/lcisuhxJTw6YgqJsjiF3xNsNhL8kRjL92NXnqVu+yXX2cDxHgdEn8H0pcAAAAASUVORK5CYII=
чуть посложнее
/*Initialization Code*/ var prefBranch = Components.classes["@mozilla.org/preferences-service;1"]. getService(Components.interfaces.nsIPrefBranch); var pref = new Object(); pref["Разрешить JavaScript"] = "javascript.enabled"; pref["Контекстное меню сайтов"] = "dom.event.contextmenu.enabled"; pref["Боковая панель"] = "sidebar.revamp"; pref["Загружать изображение"] = "permissions.default.image"; var strEnable = "Опция включена"; var strDisable = "Опция выключена"; var imgEnable = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAltJREFUOMtt0l9olXUcx/HX8zzThHh07cLQJSZoozXNONMonYxI6zhwhnVnGQldqASZKN50USgWE0ThgCEiZV2JyNDpEnXMLhbuNBC7SOnfVHQj5p/Hmmw+53hxzo7T9bv5Xfy+78/v8/1+P4EnT7NqvIOMVEYkRF6q16hjegxBsVgMgiAoBk/AWRyQminyf2cguzi7veOrjg+xBD8H4+Cd2A7xNJLZxDUkMISrTH8QO7e3R/3z9TCKVSWBJitEOsFC1BOXpZOyfhzFOptPeW3O6wqFgh9Of7/7/bc/2BJoVi11CbVewXziMhiX4SSkY/lx2VktYOOejXJHcwOmeKlKqkWk1jTiholNJ/iu6VAF/iL/uVx3jsiz7lsdlqdNLcaNdMxF2+Jd1s5bB/Zd2qOt70tmVcoyoUijiPq6F7SvPGNp7fLK69b5m322YBs4fOVbn/R8WppJTbkgkqmSKsD+1gOWzmwyMDzgp+unrZm71q5X28Dxv9tt6N70uLsUkUIo0iuiMFIADc80aH7uLd8sOygQ6L7RZf3ZVoqJeAweqmjlSynDyH+joK76RUdWtJsUTvLLP3nvda4ynD5aJ6VMPBL41wmp/puDN0FVWGVyONnlO79pPbXS8IOkYhuSX3EL3JA6Frrgrsj6vit9Fdlr967KnnzTnfuDkrEwFUgu4iJK/X/svFulxP/lj5qG6hkL5r7c2D/Yb82Od12+9runUkYS/MnIhbL1IkJf65Lz+ObR5A0cFJld/kXlhtR1fOS8H8eQYEL0FpnqaS3IoBGhVK9IHid0uT2+/CEAYcfQrHKJYQAAAABJRU5ErkJggg=="; var imgDisable = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAeJJREFUOMudk81qU1EUhb+7krYZaIkUhQQcqLVG30BKCyoOOtFROgiJZuxTXF/CcaEhhtyROCoO/C19BNOgM0mgk6IpGNN713WQUKMVU1yjczjrfJyz914Bf6hef5wbDn/clFTAFJVVAPTiOO4lSdKJouj7tD+Y3lQqletID7DPAwjwyakAjjLi5XajsX8KUK1W7xmvYTD0wR2hHgjjonAJVJjY95rN5s4JYHNz81o2m60BiWO/Kd0q7YZh6OnXhWGobvfTbfBdICNlnjca2/tBvV7PjYajJ4hF269brdZb/qFqpbpqfB84GgwGzzQajVaQFiUOkiT5wAwtryzvjb/IuXw+XxJQmJRqP4qiZBYgDENjdwDSlIKMixIEQabHGSWpB2DSooRSm/+SHaca00SaJMWzX3RxPBnqyXYfjKUb5XI5M7MGT0MBpQmor8PDwy7wFfvS3Nzc+ixA52NnVVJB0sCJO8G4t5WrhkeSbPv98XH8Lorav3WkXC5nFhZya3ayBmQcu9lqt7q/RrlSuWNYBwKkAxx34thfEGSz85eBEvbFiX232Wy+OhWmWq12JU3Th7bz0xHyZGX7mx2/aLfbn/+aRoCNjY2FpQtLK4gCdjE2QVb0YtPP5ea7W1tbw2n/Tyf84OJw4lGJAAAAAElFTkSuQmCC"; // Создать меню для кнопки ............. var xulNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; var menu = document.createElementNS(xulNS, "menupopup"); onclick="this.parentNode.menuClick(event)"; menu.addEventListener("popupshowing", function (event) { this.parentNode.popupShowing(event); }, false); var menuitem = document.createXULElement("menuitem"); menuitem.setAttribute("class", "menuitem-iconic"); menuitem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAG7SURBVChTVZBNSBMAAEY/a8OCZZlBZS6EiIpcplLU6FAZGc1Dt2p4SAcOKhEtEhb2M1mHgRGLTSwarY02RlRQ7GBjMWObEow6BCMomES2rQiDOgTtdRGjd3rwbk9aZFd76879bb5y8Oshe8t6S4f+p8v94rd/bl/kJ3Ds+YVs6s8JX4fxX19mT/ziG0mKfCbJHOAqqGaxHrw2kj8+naZAmTIlKrznDbYZR6LTK6l5u79apkCOj8xTpMg8RTK8pUSELVZtarBlwiR4TZ4EQe4t+WP6PjRZtLm7NXil+ogUUfq+m4cbz9tLD0nyhDG23m88oFOVDHGCxPCwbliS1vSOEiVEmDSOivaW3FznNpOM0jAgSXU9IwTwM4aXowta0Wm821UdIsA5+surHXU9vZ8G8HEJG6uerjwtNZ3Mj+PkDgHchAnh4SYhnNygO6sN0m474wxzmQRJ4sSZYoqruPDhRFZJBk9z1pTzMsEzUrwkwQRe6vM73hknl1a352aJcJYYUQaJkcOSVq2WS5JBJm00PhiiraiZV6TQrPWLC2NcZq1VrVQjk8xqUb/O6NaRhcM/5NOgLmqPtqlehr9YnhNpYwJ0TAAAAABJRU5ErkJggg=="); menuitem.setAttribute("label", "About:сonfig"); menuitem.setAttribute("tooltiptext", "Во вкладке без настройки или с настройкой, скопированной из буфера"); menuitem.setAttribute("onclick", "document.getElementById('" + this.id + "').openConfigManager(event);"); menu.appendChild(menuitem); var menuitem = document.createXULElement("menuitem"); menuitem.setAttribute("class", "menuitem-iconic"); menuitem.setAttribute("image", imgEnable); menuitem.setAttribute("label", "Боковая панель"); menuitem.setAttribute("tooltiptext", strEnable); menuitem.setAttribute("onclick", "document.getElementById('" + this.id + "').togglePreference(this.label);"); menu.appendChild(menuitem); var menuitem = document.createXULElement("menuitem"); menuitem.setAttribute("class", "menuitem-iconic"); menuitem.setAttribute("image", imgEnable); menuitem.setAttribute("label", "Контекстное меню сайтов"); menuitem.setAttribute("tooltiptext", strEnable); menuitem.setAttribute("onclick", "document.getElementById('" + this.id + "').togglePreference(this.label);"); menu.appendChild(menuitem); var menuitem = document.createXULElement("menuitem"); menuitem.setAttribute("class", "menuitem-iconic"); menuitem.setAttribute("image", imgEnable); menuitem.setAttribute("label", "Разрешить JavaScript"); menuitem.setAttribute("tooltiptext", strEnable); menuitem.setAttribute("onclick", "document.getElementById('" + this.id + "').togglePreference(this.label);"); menu.appendChild(menuitem); var menuitem = document.createXULElement("menuitem"); menuitem.setAttribute("class", "menuitem-iconic"); menuitem.setAttribute("image", imgEnable); menuitem.setAttribute("label", "Загружать изображение"); menuitem.setAttribute("tooltiptext", strEnable); menuitem.setAttribute("onclick", "document.getElementById('" + this.id + "').togglePreference(this.label);"); menu.appendChild(menuitem); this.appendChild(menu); this.type = "menu"; this.orient = "horizontal"; this.menuClick = function (event) { event.preventDefault(); event.stopPropagation(); this.open = false; }; this.openConfigManager = function () { var clip = gClipboard.read(); gBrowser.selectedBrowser.messageManager.loadFrameScript('data:,docShell.doCommand("cmd_copy")', false); var br = (gBrowser.selectedTab = gBrowser.addTrustedTab("about:config")).linkedBrowser; var insert = () => { br.contentDocument.getElementById("about-config-search") .editor.paste(Ci.nsISelectionController.SELECTION_NORMAL); clip && gClipboard.write(clip); } br.addEventListener("pageshow", () => setTimeout(insert, 200), {once: true}); }; this.popupShowing = function(event) { var nodeList = this.getElementsByTagName("menuitem"); for (var i = 0; i < nodeList.length; i++) { var label = nodeList[i].getAttribute("label"); if (label == "Боковая панель" || label == "Контекстное меню сайтов" || label == "Разрешить JavaScript") { if (prefBranch.getBoolPref(pref[label]) == true) { nodeList[i].setAttribute("image", imgEnable); nodeList[i].setAttribute("tooltiptext", strEnable); } else { nodeList[i].setAttribute("image", imgDisable); nodeList[i].setAttribute("tooltiptext", strDisable); } } if (label == "Загружать изображение") { if (prefBranch.getIntPref(pref[label]) == 1) { nodeList[i].setAttribute("image", imgEnable); nodeList[i].setAttribute("tooltiptext", strEnable); } else { nodeList[i].setAttribute("image", imgDisable); nodeList[i].setAttribute("tooltiptext", strDisable); } } } }; this.togglePreference = function(label) { if (label == "Боковая панель" || label == "Контекстное меню сайтов" || label == "Разрешить JavaScript") { if (prefBranch.getBoolPref(pref[label]) == true) { prefBranch.setBoolPref(pref[label], false); } else { prefBranch.setBoolPref(pref[label], true); } } if (label == "Загружать изображение") { if (prefBranch.getIntPref(pref[label]) == 1) { prefBranch.setIntPref(pref[label], 2); } else { prefBranch.setIntPref(pref[label], 1); } BrowserCommands.reload(); } };
Отредактировано Andrey_Krropotkin (Вчера 13:17:36)
На форуме
Dumby
В 115 появление диалога очистки не вызывает
приостановку исполнения JS-кода в окне браузера.
Можно внутрь переопределённого sanitize() добавлять.
Это класс !
Можно посмотреть как это сделано в UCF.
А это же просто откровенное фуфло...Растяг пробел должен быть одним , а не кучей.
Отсутствует
Dumby Подскажи - команда или код для расширений - Закрепить и открепить на панели расширений (toolbar-context-pin-to-toolbar)
На форуме
откровенное фуфло
Ага, у тебя зато конфета.
Какое-то -moz-старьё типа -moz-flex-grow и -moz-box-flex
Не нужно там всё это, оно и так уже флекс.
*|*:root:not([inFullscreen])#toolbar-menubar — вообще песня.
И чего вообще ты хочешь? Что значит «сделать толком»?
Выглядит так, словно попытка сделать
растягивающийся пробел на панели меню безразмерным.
Хорошо, вот смотри, назначаем, для наглядности,
background-color и снимаем max-width
Чем не устраивает?
#toolbar-menubar :is( toolbarspring, [id^=wrapper-customizableui-special-spring] ) { background-color: springgreen !important; max-width: none !important; }
Тогда, либо скрыть этот spacer, либо влепить
ратягивающемуся пробелу и его обёртке гигантский флекс,
то есть, дописать ещё что-то типа flex: 9999 !important;
Как избавиться. Как окно выпадет это и не только (c window-modal-dialog связано ?) Так темнеет все
#window-modal-dialog::backdrop {
background-color: rgba(255, 255, 50, .2) !important;
}
Dumby Подскажи - команда или код для расширений - Закрепить и открепить на панели расширений (toolbar-context-pin-to-toolbar)
Подобные коды теперь находятся по адресу
chrome://browser/content/main-popupset.js
Для toolbar-context-pin-to-toolbar там такое:
// case "toolbar-context-pin-to-toolbar": gUnifiedExtensions.onPinToToolbarChange( event.target.parentElement, event ); break;
Отсутствует