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 (Вчера 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 (Вчера 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 (Вчера 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:05:53)
Отсутствует