Отсутствует
dinn, Andrey_Krropotkin
Да, спасибо. У меня попутно ещё одна кнопка отвалилась "Память/минимизировать в адресной строке".
// https://forum.mozilla-russia.org/viewtopic.php?pid=789048#p789048 // https://forum.mozilla-russia.org/viewtopic.php?pid=789076#p789076 // https://forum.mozilla-russia.org/viewtopic.php?pid=791818#p791818 // https://forum.mozilla-russia.org/viewtopic.php?pid=795879#p795879 // здесь трындёж на 2-3 страницы https://forum.mozilla-russia.org/viewtopic.php?id=9591&p=612 (async id => ({ delay: 2e3, val: "", init(topic, mm) { Services.obs.addObserver(mm = this, topic); Services.obs.addObserver(function quit(s, t) { this.timer?.cancel(); Services.obs.removeObserver(mm, topic); Services.obs.removeObserver(quit, t); }, "quit-application-granted"); }, observe(win) { var df = win.MozXULElement.parseXULToFragment( /* `<hbox id="${id}"><label id="${id += "-label"}"/></hbox>` */ `<hbox id="${id}" tooltiptext="${ "ЛКМ: Минимизировать потребление памяти
ПКМ: about:process
Ctrl+ПКМ: about:debugging#/runtime/this-firefox" }" onclick="event.button || ${ "memoryMinimizationButton.doMinimize(event)" }"><label id="${id += "-label"}"/></hbox>` ); this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); (this.observe = async win => { this.timer.cancel(); await new Promise(ChromeUtils.idleDispatch); /* win.document.getElementById("star-button-box") .after(win.document.importNode(df, true)); this.notify(); })(win); }, */ var clone = win.document.importNode(df, true); clone.firstChild.oncontextmenu = this.about; win.document.getElementById("star-button-box").after(clone); this.notify(); })(win); }, about(e) { var gb = e.view.gBrowser; gb.selectedTab = gb.addTrustedTab(`about:${ e.ctrlKey ? "debugging#/runtime/this-firefox" : "processes" }`); }, async notify() { var info = await ChromeUtils.requestProcInfo(); var bytes = info.memory; for(var child of info.children) bytes += child.memory; this.timer.initWithCallback(this, this.delay, this.timer.TYPE_ONE_SHOT); var prev = this.val; if ((this.val = this.mgb(bytes)) != prev) for(var win of CustomizableUI.windows) { var lab = win.document.getElementById(id); if (lab) lab.value = this.val; } }, mgb: bytes => bytes < 1073741824 ? Math.round(bytes / 1048576) + "MB" : (bytes / 1073741824).toFixed(2) + "GB" }).init("browser-delayed-startup-finished"))("ucf-mem-indicator");
На форуме
_zt - это не стиль, это делается только скриптом, мозиловский блокируется и заменяется новым. Сделал скрин из глючного зарубежного скрипта undoCloseTab вот отсюда, которым не пользуюсь и в том скрипте намешано так, что ничего не поймешь. Пользуюсь undoCloseTab от Виталия. Там у этого человека еще в 2 скриптах такое же, но я не разобрался и поэтому спросил, может кто сварганит именно на тултипы, где есть ссылки - типа пунктов Журнала, Закладок
А если ты про боковую панель, то в Настройки- Основные есть пункт: Показать боковую панель, я именно про это. Переключает вид боковой панели
xrun1 - да именно про этот скрипт в этом посте, и повторюсь при переключении на новый вид боковой панели - не работает, при старом виде - работает
Отредактировано Andrey_Krropotkin (01-05-2025 09:02:14)
Отсутствует
но 1 и 3 нет
может так
btn.addEventListener(type, this); .. handleEvent(e) { this[e.type](e); }, .. popup.addEventListener(type, this);
Отсутствует
У меня попутно ещё одна кнопка отвалилась "Память/минимизировать в адресной строке"
Там функция из скрипта по ЛКМ не запускалась. С параметром security.browser_xhtml_csp.enabled --> false заработало
Плохой совет дал, если речь об "on" атрибутах. Думаю, никому не составит сложности переделать под addEventListener.
Совет для quick_toggle_about_config_button.js тоже дал, но никто даже не попытался попробовать
Отсутствует
Совет для quick_toggle_about_config_button.js тоже дал, но никто даже не попытался попробовать
Это №1980? Я, например, не понял. Мне надо написать, что закомментировать и что и куда вставить
Код своих кнопок выкладывал выше, №1970 и №1978.
Мне UCF без чужой помощи, как от дохлого осла уши. Те 5 кнопок, что сваял сам, однокомандные и без них смогу обойтись. Сам сложное не напишу и готовое не исправлю. Это продукт для тех, кто разбирается в кишках Firefox. А я простой пользователь, а не потрошитель. Мне готовенькое надо.
Так что, пока сработало с security.browser_xhtml_csp.enabled в false - буду пользоваться своими кнопками. Когда отвалятся - буду искать варианты на замену.
Или предлагай вариант по шаблону выше.
На форуме
security.browser_xhtml_csp.* // default values
Если оба поставить в true, то блокировок для скриптов не будет, а только ошибки в консоли
// btn.linkedObject = this; .. // btn.setAttribute("on" + type, `linkedObject.${type}(event)`); btn.addEventListener(type, this); .. // popup.setAttribute("on" + type, `parentNode.linkedObject.${type}(event)`); popup.addEventListener(type, this); .. // m.setAttribute("oncommand", "setCloseMenus(event)"); m.addEventListener("command", setCloseMenus); // m.onclick = m.oncontextmenu = m.setCloseMenus = setCloseMenus; .. handleEvent(e) { this[e.type](e); },
Отсутствует
dinn
Работает, спасибо.
А что с этой?
// https://forum.mozilla-russia.org/viewtopic.php?pid=789048#p789048 // https://forum.mozilla-russia.org/viewtopic.php?pid=789076#p789076 // https://forum.mozilla-russia.org/viewtopic.php?pid=791818#p791818 // https://forum.mozilla-russia.org/viewtopic.php?pid=795879#p795879 // здесь трындёж на 2-3 страницы https://forum.mozilla-russia.org/viewtopic.php?id=9591&p=612 (async id => ({ delay: 2e3, val: "", init(topic, mm) { Services.obs.addObserver(mm = this, topic); Services.obs.addObserver(function quit(s, t) { this.timer?.cancel(); Services.obs.removeObserver(mm, topic); Services.obs.removeObserver(quit, t); }, "quit-application-granted"); }, observe(win) { var df = win.MozXULElement.parseXULToFragment( /* `<hbox id="${id}"><label id="${id += "-label"}"/></hbox>` */ `<hbox id="${id}" tooltiptext="${ "ЛКМ: Минимизировать потребление памяти
ПКМ: about:process
Ctrl+ПКМ: about:debugging#/runtime/this-firefox" }" onclick="event.button || ${ "memoryMinimizationButton.doMinimize(event)" }"><label id="${id += "-label"}"/></hbox>` ); this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); (this.observe = async win => { this.timer.cancel(); await new Promise(ChromeUtils.idleDispatch); /* win.document.getElementById("star-button-box") .after(win.document.importNode(df, true)); this.notify(); })(win); }, */ var clone = win.document.importNode(df, true); clone.firstChild.oncontextmenu = this.about; win.document.getElementById("star-button-box").after(clone); this.notify(); })(win); }, about(e) { var gb = e.view.gBrowser; gb.selectedTab = gb.addTrustedTab(`about:${ e.ctrlKey ? "debugging#/runtime/this-firefox" : "processes" }`); }, async notify() { var info = await ChromeUtils.requestProcInfo(); var bytes = info.memory; for(var child of info.children) bytes += child.memory; this.timer.initWithCallback(this, this.delay, this.timer.TYPE_ONE_SHOT); var prev = this.val; if ((this.val = this.mgb(bytes)) != prev) for(var win of CustomizableUI.windows) { var lab = win.document.getElementById(id); if (lab) lab.value = this.val; } }, mgb: bytes => bytes < 1073741824 ? Math.round(bytes / 1048576) + "MB" : (bytes / 1073741824).toFixed(2) + "GB" }).init("browser-delayed-startup-finished"))("ucf-mem-indicator");
На форуме
В 139 версии у меня отвалилось несколько скриптов. Но в первую очередь хотелось бы исправить два скрипта.
Первый в консоль пишет: "Content-Security-Policy: Параметры страницы заблокировали выполнение JavaScript eval (script-src), поскольку он нарушает следующую директиву: «script-src chrome: moz-src: resource: 'report-sample'» (Отсутствует 'unsafe-eval')"
Второй в консоль пишет: "EvalError: call to Function() blocked by CSP"
Я знаю, что можно поиграться параметрами about:config - security.browser_xhtml_csp.* и в 139 - security.allow_unsafe_dangerous_privileged_evil_eval, но думаю, что это временное решение и рано или поздно эти параметры выпилят и все равно придется править скрипты.
Просьба к знатокам, помогите исправить эти два скрипта.
// // Сохранять изображение без запроса в указанную папку, из контекстного меню ..... // try { (this.contextsaveimg = { path: "E:\\Download", init(that) { var contextMenu = this.contextMenu = document.querySelector("#contentAreaContextMenu"); if (!contextMenu) return; contextMenu.addEventListener("popupshowing", this); that.setUnloadMap("contextsaveimg", this.destructor, this); }, destructor() { this.contextMenu.removeEventListener("popupshowing", this); }, handleEvent(e) { if (!gContextMenu.onImage || gContextMenu.webExtBrowserType === "popup") return; var menuitem = document.createXULElement("menuitem"); menuitem.setAttribute("id", "ucf_SaveImg"); menuitem.setAttribute("label", "Сохранить изображение в папку: " + this.path); menuitem.addEventListener("click", function(e) { saveImg(); }); menuitem.className = "menuitem-iconic"; menuitem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABAnAAAQJwAAAAAAAAAAAAAAAAEGAQECKAABATsAAAAoAAAAFAAAAAkAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIjRRXUVtk8U+Y4TGKUBYrRgmNpcOFR91BQgMWAECBD8AAQEqAAAAGAAAAAwAAAAGAAAAAQAAAAAAAAAAAAAAAEVrp7Nws9//fcr6/3W+9f5wten5ZKHQ7lWGsedDaI7QL0hjtR4sQKERGSaBBgkOXgAAACoAAAAEAAAAAAAAAABKdrK+aqjY/4XO7P+AyfL/fcXy/4HL+/97xPT/eMHy/3e+8f9trt77YpvI8Ux0m98TGymTAAAAJQAAAAAAAAAAVIS7yGWh0/8yTVv/UniH/0htff+L0e//WIab/0x2i/9XiKL/RGp+/zNRYv9dkrP+S26S2QQGClwAAAAGAAAAAGeYxtFxrtr/IDA7/01mbf8sPkP/SWZw/zlSWv88Vl//LkRL/3Wsv/83UVr/XYqe/3+51PQaJDCWAAAAGwAAAAB5qtHajMXk/yY1Pf9fa23/GB8g/2yGjP8mMDL/Sl9k/0RYXP9wmKL/dZ+r/4i6y/+n4PD+TmV5yQECA0UAAAACh7bX46zh8/9tjZj/gpen/4GMk//G4Oj/kJ6f/52clf+svbz/f5id/3yXnv+gx9L/wez1/5u0xuwPExt+AAAAEJTA3ey/7vr/ve35/7Hf8v+w0ub/ubvE/8a4uf/NwLv/083I/9Pl6//T7ff/0O32/9fw9v/a6vL8P0ZYtAAAAC+iy+P2zvX8/831/P/K6e3/y7Kg/+GNZf/vlWr/6Zx3/9qegv/Ino7/t8TQ/7HM4/+itc3yu8ja52BtirQAAAEkqs/l9dv8/f/b/P3/1dzU/9qXcf/slmb/+aFr//+td//+rXb/+aRu/9+1k/+/2uL/RldrtiIrPU0ZITEoAAAAA46017zX8Pf85/7+/+X8+//g7+3+yryw+O6odPz/wYj/9bJ7/+KpgP/nqn3/0tPJ/kRTY6QAAQEYAAAAAAAAAAA6V3Yuboyqj6C81My50ubgo7zR1I92bLbzt3/3/tGZ/8aTZttfY2+PbX2Sn3GFm7EiLDtNAAAABQAAAAAAAAAAAgMEAAUHCgYYJDETIS4+LjMwNU+3e029/NGZ/vHHlPRrSSx/BQUFEAMFBwcEBQcJAQECAgAAAAAAAAAAAAAAAAAAAAAAAAAAEQgAA1wvElSsaz3B9LZ8+fC7gu6WZ0COFg0GGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADcTAQrWbS+y7pdZ8eOVWMqUWy91IRIJFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AACf/wAAgH8AAIAfAACADwAAgA8AAIAHAACABwAAgA8AAIAPAADOHwAA/v8AAP//AAD//wAA//8AAA=="); (this.contextMenu.querySelector("#context-sendimage") || this.contextMenu.lastElementChild).after(menuitem); this.handleEvent = () => menuitem.hidden = (!gContextMenu.onImage || gContextMenu.webExtBrowserType === "popup"); function saveImg() { var p = Services.prefs; var data = Object.assign(Object.create(null), { "browser.download.folderList": { type: "Int", set: 2 }, "browser.download.useDownloadDir": { type: "Bool", set: true }, "browser.download.dir": { type: "String", set: this.path } }); var lazy = {PrivateBrowsingUtils}; var save = eval(`(function ${gContextMenu.saveMedia})`.replace("\n false, // don't", "\n true, //")); (menuitem.saveImg = () => { for(var pref in data) { var obj = data[pref], meth = `et${obj.type}Pref`; obj.val = p.prefHasUserValue(pref) ? p["g" + meth](pref) : null; p["s" + meth](pref, obj.set); } try {save.call(gContextMenu);} finally { for(var pref in data) data[pref].val === null ? p.clearUserPref(pref) : p[`set${data[pref].type}Pref`](pref, data[pref].val); } })(); } } }).init(this); } catch(e) { Cu.reportError(e); }
// // Сохранить как PNG ..... // (async func => CustomizableUI.createWidget({ id: "ucf_SaveAsPNG", label: "Сохранить как PNG", tooltiptext: "Сохранить как PNG", localized: false, // defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { var win = btn.ownerGlobal; new win.Function("_id, xhtmlns, addDestructor", func.toString().slice(7, -1)).call( btn, this.id, "http://www.w3.org/1999/xhtml", destructor => win.addEventListener("unload", destructor, {once: true}) ); btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGwSURBVHjarJPPaxNBGIafmd1km23saqtRaLB6kFYl2ELpRayCVL20RvCmJwk9ePNWvPsXtCA9eNCDeO0hLemPo96LYAuKkRhtsBViEtI0rrt+GyFQ1oMkfjAf883M+8w7w4zyfZ9uwsxms10RzCBNTd3sSLy2lvsDCCKzWMCKGHgotOTAlpamJPm+jCmFL00bmmbD5WlmsKXTdBltB3bcxowaLWJwsTpi4bvNVu1JMmVn5cmcqTB6/DAg3hcjGpUFskjZjlgFKdmvVIiISKlfUhlyQMVPywgDjvX1YCjpOBZ2fZ+9+TuUpxcZuz7Ebl7ArkfM0dgDcOAFCvfwHTi9URJJi2RCqEuPmRxPUXn9imodLo1D6orGjMHW6govZqfDDkYviDXBlZ4vsFsrk8vXqZRWeDY8hz55lvvpGU7sFEn0RhhTtTBg/tETCvlNdj68papsUoND3Lh6iyPOOYrvv/JufYNrqcssbW8zkjwdBnz7/JKL50/x4F4at9GgsFckX/2IefQHZyb6mbl9l2LpE8ff1PnufWkD/t87yC1v/pvi4V8AwZvuNFS33/m3AAMAhEeAiqLmty4AAAAASUVORK5CYII="); } }))(() => { ((main, parts) => this._handleClick = () => { var df = MozXULElement.parseXULToFragment(` <menupopup> <menuitem class="menuitem-iconic" image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAOwSURBVHjaYmBiYuJvamo+xiIsLLL3uaazMUAAMTY3txxjAAFubq7/ZiYm/wECACIA3f8AGhobzGhoaP8QFRr/6enp/wT5+fgBLS0tAOLi4gCnp6cAAoixtrbuFBsb6x+QNnZ2jo0MXz9/+Qdk/wfhO3fu/Gc5cuwoA4NqHEOoszjDrVu3GFiAogxJtiwMagrCQHMeMgAEoHhsdRCG4Tj463+rxGFIqN2CYI7wBpiaWhzPheF5SMhIKliCYiQtyTC4hvSLcu7cHYQQl5SSDyFGa23UWkfvfXTORWNMpiIYH2NV1xXN5gvq9kfqNjtSStF7mkAhBPTXHm3TYL1qsV2+8LyfIaXEbRjAyuzpUOCcI+cMYgzp31hCnft+fgII6Cm95oiICOd///4CFTAwAOWBgBFIM7Lw8vLZM5w7d+7/t2/fwA4DOfDp02d/QQ4GWv1z6tSpU5g+ffrI8OnTJyagFUx2Tu5MsnIyTDk52UyfPn5k/vXr9x+mjx8+MsTFxTGERMUzVK09yCAsn8AwY+ZMhlevX0Pc9PTZM4a3b94wXHjwmaEsu5th87GpQIcyMdy+fZvh79+/DEwfP35giIuPZ3hzbTeDCtcjhngnEwZVVRWGz58/g+ON5dOnz6BYYKioqGY4eOggg5SuBYORkRHDixcvQL5hZNTR0flnY2PD+O8fKAwYgGHwHyTMwMzMwrBt2zZHgAA9Uz1Lw1AUPWlKE1vFlEIFHRoKQgcRtDSLIAiCgoJuiovYP6DopnR1EdRYHO3W6tbg5K5LwclmVQviRwutpSaQtI3P+yIK7/Eu94t77jkPiqIcGUaZ5vlmlvXFbNui12LEBSPo/uU29/EYrYQ1m01WqVRYPn++FQiHI3Mj8RG4jst7wHFcFAoFaFoGsixBliRoGc338dg3AQuKojc2OoZ+vzcZ4JRwQNQAxVIJsVgMuVwO8/OL2D29xPjSHvpCHAf7+36M57iuSzUdnzISg4d3AvxgVqHrJ5BCIcxu7KCdWoLx3MFLaBjOxDJSC1lIsowzXUfVNFEnJflrJi2i1WrBtm1MpzNgAoN5U8TtySE61Sccb6/jIjuF3uMduo5DOWk/l9fwxQr0o+6J+rSqqlxjQq1WQ9kw8PH2CoF5cLtd8gaRSCSwsrqKZDJJu3A8WZbFer2hB2nLAc5ZNBplHFskEsEmSUcURV8q+GXTH5ffBo1OUzNFGUa7/cm4eGcEIbA2MBBW6df8VnC1s3/zv8mfScchaq+GhgavfwBr4dP0kYqtcwAAAABJRU5ErkJggg==" label="Сохранить всю страницу как PNG" value="all"/> <menuitem class="menuitem-iconic" image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAOwSURBVHjaYmBiYuJvamo+xiIsLLL3uaazMUAAMTY3txxjAAFubq7/ZiYm/wECACIA3f8AGhobzGhoaP8QFRr/6enp/wT5+fgBLS0tAOLi4gCnp6cAAoixtrbuFBsb6x+QNnZ2jo0MXz9/+Qdk/wfhO3fu/Gc5cuwoA4NqHEOoszjDrVu3GFiAogxJtiwMagrCQHMeMgAEoHhsdRCG4Tj463+rxGFIqN2CYI7wBpiaWhzPheF5SMhIKliCYiQtyTC4hvSLcu7cHYQQl5SSDyFGa23UWkfvfXTORWNMpiIYH2NV1xXN5gvq9kfqNjtSStF7mkAhBPTXHm3TYL1qsV2+8LyfIaXEbRjAyuzpUOCcI+cMYgzp31hCnft+fgII6Cm95oiICOd///4CFTAwAOWBgBFIM7Lw8vLZM5w7d+7/t2/fwA4DOfDp02d/QQ4GWv1z6tSpU5g+ffrI8OnTJyagFUx2Tu5MsnIyTDk52UyfPn5k/vXr9x+mjx8+MsTFxTGERMUzVK09yCAsn8AwY+ZMhlevX0Pc9PTZM4a3b94wXHjwmaEsu5th87GpQIcyMdy+fZvh79+/DEwfP35giIuPZ3hzbTeDCtcjhngnEwZVVRWGz58/g+ON5dOnz6BYYKioqGY4eOggg5SuBYORkRHDixcvQL5hZNTR0flnY2PD+O8fKAwYgGHwHyTMwMzMwrBt2zZHgAA9Uz1Lw1AUPWlKE1vFlEIFHRoKQgcRtDSLIAiCgoJuiovYP6DopnR1EdRYHO3W6tbg5K5LwclmVQviRwutpSaQtI3P+yIK7/Eu94t77jkPiqIcGUaZ5vlmlvXFbNui12LEBSPo/uU29/EYrYQ1m01WqVRYPn++FQiHI3Mj8RG4jst7wHFcFAoFaFoGsixBliRoGc338dg3AQuKojc2OoZ+vzcZ4JRwQNQAxVIJsVgMuVwO8/OL2D29xPjSHvpCHAf7+36M57iuSzUdnzISg4d3AvxgVqHrJ5BCIcxu7KCdWoLx3MFLaBjOxDJSC1lIsowzXUfVNFEnJflrJi2i1WrBtm1MpzNgAoN5U8TtySE61Sccb6/jIjuF3uMduo5DOWk/l9fwxQr0o+6J+rSqqlxjQq1WQ9kw8PH2CoF5cLtd8gaRSCSwsrqKZDJJu3A8WZbFer2hB2nLAc5ZNBplHFskEsEmSUcURV8q+GXTH5ffBo1OUzNFGUa7/cm4eGcEIbA2MBBW6df8VnC1s3/zv8mfScchaq+GhgavfwBr4dP0kYqtcwAAAABJRU5ErkJggg==" label="Сохранить видимую часть страницы как PNG" value="page"/> <menuitem class="menuitem-iconic" image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKaSURBVHjaYpx94sPD44//CDG9+/SDp8bsBw9AADEmrX7zmQEIGF+//fD/w8dPDAABxNix6/nbcA0GIQYoYGJiZGSQFBdmOHnqLAMrKwsDQAAxJq958/n/f4jsm2//GBifP3v+/8cfiMDDj/8ZmHi5ORl4gPjPn18M///9ZWDh5uVm4GJkYfj56zcD9z9GBoAAYmwH2aL8UwimDRk8+fyfgYWRgZFBgI+b4TsWBR+BtoNcxcDDwwW2R1iQn2HvgcMMX799Y/j6/TvDzz+/GVj+/fvPvO0BC8N/oGpGhv8ML3m0GS59EwWbcP/9XwaAAGSRwQ3CMAxFfxq3TgrqiSMswARMwSJMxZEdGAXBAEiQquICJMFuekDqwTlY38/Wi9kf78OqNTO8kndretBh+1puuvl+R8Dpwm9iruG8xPP/tIGzhULc1OB6voJJXxGjQpumGpsKCc8wEqISwGJfA1P1IYCEmCegkTmqLIELT/8KC+/x+cbxBpEPOl8zbn0q5voWXdcipQQrgZiC/QlQORmzNBAEUfjt7N4ichBUDIKCWNsJhiBiZ2mZf5XC0v/gT7C10lqwNMVBkBC9kKAmt7e+uQtJxBS6cNwy7L2b981bTrz/fnmIxnHTYN081i1F8PQacddDzm0M+UfAYPw/gfyTlqMNVfOJVxIGpfxNgMcZRwoYpkVpe1ezLn/jplc7B2wWb+1gwwfuvxg31lwi7MAimOU4E+IevuXoXt+gILTE1aQ1VBJnwNYR9ltXFKCweM9RWFpYCnjWiukU7dYJLs7PUMyKuglNAZt6GVncZ7SgIU2ZJ8M/bLqVQEFYN9hJPQ5201pgvhztjnk2ZhOYh+esd/vY39ZPZYWBXlURqZ4Qwg8uZXU3gM7p3vAbsXveewxHZWUAAAAASUVORK5CYII=" label="Сохранить выбранный элемент страницы как PNG" value="click"/> <menuitem class="menuitem-iconic" image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAL/SURBVHjaYijccvd25ZHvv5n4RSUVQs2vswAEECOIxwACy+8v/3/30Zv/AAHE0Hb6y+//UPDv4///LD/+MjJ8+PqF4cvnnww/vgkxAAQQY8Xhb78YgQCsj5mFgQGm/P+v///fvvj/n+n/fwaGe//vMexg2Mrw7BsDA8vXHwwMPN/5GdQ/mzG8BbIBAoiRfdqvX8xf/rBCDAEaAWL8ByOgmZwMLBXGvxnrzLgYVj9cyfCL+TfDj9+/Gd7//sAQw5vK8PEXAwMTRBsD0Li3DNKikgwC4twM3NIMDF9/fGf4CVTA8u0fM+ODjwwM7qJZDH8/MTBI/GFgUAba/QYo+fEnAwNAADKoXQVhIAjOJYfgsxIR/AwRi/yBlY3gz9j7FUI+wt7CwkbEzs7CNIo2Yl53t3duElDBhYXZZXaWGbHYKW0M4b+cex7WG9FaxmxGfNcfYNH3T+pr/LcSzu1h3Wx11EU2eOkYYRSi7jVgrQeb1TDtzFHkLgu13GQIBgGkJ6GFxva8h6XqX0kgRlF+AfkEw4S7ujEGbKnAzDa6GNEYLvOh2N6wOUGaVXHKayqQsHeiHgyfqKJ51sbxjvAWoG1qWWkYiKJnZhKTpgapK1tEslRw50+4camIGz/ObfcuBP0HBREEn12I+MBUadPM5HomqbWgi8kJydzHOfdctXmU29Vhbhqq8leNfxQyLP6lWgjjdxds9Yxs95ZRVAo+h8yFqEau2fHEKjpKqgojRDg+H0iw1gb212NY2oC/MCxz5DxGaYgPsKrGsnRYUEusnvKb4MNqnBlN5aZD8q54Hb2gP+gj62bohOyKdVxgobTBk3vE7cMzDhYPkVA0NW0xaBrlk6BZtRN20I16SMIWPt0CJlLQowqJStE2YwqnQRbE2ZwazrYURDquL5zcnCINU4xdiYo7QXXo4TesSMaIGGRTJ6jnqBxvkJNwfhFa2Ovu1jlrwXjD2gZ9wITeKVhImEFXgXcIgrvri/udqySztpDZemJurTzK70h/3h1xY3xpvwGLI42vrCwxmAAAAABJRU5ErkJggg==" label="Сохранить выбранную область страницы как PNG" value="clipping"/> </menupopup> `); var popup = df.firstChild; popup.setAttribute("context", ""); popup.addEventListener("command", e => popup.handleCommand(e)); popup.handleCommand = e => { var name = _id + ":DataURLReady"; main = main.replace("%MESSAGE_NAME%", name); var urls = {}, configurable = true, enumerable = true; Object.entries(parts).forEach(([key, part]) => Object.defineProperty(urls, key, { configurable, enumerable, get() { var value = `data:;charset=utf-8,({${ encodeURIComponent(main + part) }%0A}).init("${key}")`; Object.defineProperty(urls, key, {configurable, enumerable, value}); return value; } })); var getTabLabel = () => { var label = gBrowser.selectedTab.label; var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " "); return label.substring(0, 50); } var listener = msg => { var fp = makeFilePicker(); fp.init( !("inIsolatedMozBrowser" in window.browsingContext.originAttributes) ? window.browsingContext : window , "Сохранить как…", fp.modeSave); fp.appendFilter("", "*.png"); var fileName = getTabLabel(); fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '').replace(/\s+/g, '_').slice(0, 100).replace(/^\s+|\s+$/g, ''); var fileDate = (function () { var d = new Date(), z = function(n){return (n < 10 ? '0' : '') + n}; return '[' + z(d.getFullYear()) + '_' + z(d.getMonth()+1) + '_' + z(d.getDate()) + '\u2014' + z(d.getHours()) + '_' + z(d.getMinutes()) + '_' + z(d.getSeconds()) + ']'; })(); fp.defaultString = fileName + "_" + fileDate + ".png"; fp.open(res => res == fp.returnCancel || !fp.file || makeWebBrowserPersist().saveURI( Services.io.newURI(msg.data), document.nodePrincipal, null, null, null, null, null, fp.file, null, null )); } messageManager.addMessageListener(name, listener); addDestructor(() => messageManager.removeMessageListener(name, listener)); (popup.handleCommand = e => gBrowser.selectedBrowser.messageManager .loadFrameScript(urls[e.target.value], false) )(e); } this.append(df); (this._handleClick = () => popup.openPopup(this, "after_start"))(); })(` init(cmd) { cmd.startsWith("c") ? this[cmd].init(this[cmd].parent = this) : this[cmd](); }, capture(win, x, y, width, height) { var canvas = win.document.createElementNS("${xhtmlns}", "canvas"); canvas.width = width; canvas.height = height; var ctx = canvas.getContext("2d"); var tryDraw = ind => { try {ctx.drawWindow(win, x, y, canvas.width, canvas.height, "white")} catch(ex) {canvas.height = ind * canvas.width; tryDraw(--ind);} } tryDraw(17); sendAsyncMessage("%MESSAGE_NAME%", canvas.toDataURL("image/png")); }, `, { all: `all() { var win = content; this.capture(win, 0, 0, win.innerWidth + win.scrollMaxX, win.innerHeight + win.scrollMaxY); }`, page: `page() { var win = content, doc = win.document, body = doc.body, html = doc.documentElement; var scrX = (body.scrollLeft || html.scrollLeft) - html.clientLeft; var scrY = (body.scrollTop || html.scrollTop) - html.clientTop; this.capture(win, scrX, scrY, win.innerWidth, win.innerHeight); }`, clipping: `clipping: { handleEvent(e) { if (e.button) return false; e.preventDefault(); e.stopPropagation(); switch(e.type) { case "mousedown": this.downX = e.pageX; this.downY = e.pageY; this.bs.left = this.downX + "px"; this.bs.top = this.downY + "px"; this.body.appendChild(this.box); this.flag = true; break; case "mousemove": if (!this.flag) return; this.moveX = e.pageX; this.moveY = e.pageY; if (this.downX > this.moveX) this.bs.left = this.moveX + "px"; if (this.downY > this.moveY) this.bs.top = this.moveY + "px"; this.bs.width = Math.abs(this.moveX - this.downX) + "px"; this.bs.height = Math.abs(this.moveY - this.downY) + "px"; break; case "mouseup": this.uninit(); break; } }, init() { var win = {}; Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager) .getFocusedElementForWindow(content, true, win); this.win = win.value; this.doc = this.win.document; this.body = this.doc.body; if (!HTMLBodyElement.isInstance(this.body)) { Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService) .showAlertNotification("${self.image}", ${JSON.stringify(self.label)}, "Не удается захватить!"); return false; } this.flag = null; this.box = this.doc.createElement("div"); this.bs = this.box.style; this.bs.border = "red dashed 1px"; this.bs.position = "absolute"; this.bs.zIndex = "2147483647"; this.defaultCursor = this.win.getComputedStyle(this.body, "").cursor; this.body.style.cursor = "crosshair"; ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit() { var pos = [this.win, parseInt(this.bs.left), parseInt(this.bs.top), parseInt(this.bs.width), parseInt(this.bs.height)]; this.body.style.cursor = this.defaultCursor; this.body.removeChild(this.box); this.parent.capture.apply(this, pos); ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.removeEventListener(type, this, true)); } }`, click: `click: { getPosition() { var html = this.doc.documentElement; var body = this.doc.body; var rect = this.target.getBoundingClientRect(); return [ this.win, Math.round(rect.left) + (body.scrollLeft || html.scrollLeft) - html.clientLeft, Math.round(rect.top) + (body.scrollTop || html.scrollTop) - html.clientTop, parseInt(rect.width), parseInt(rect.height) ]; }, highlight() { this.orgStyle = this.target.hasAttribute("style") ? this.target.style.cssText : false; this.target.style.cssText += "outline: red 1px solid; outline-offset: 1px; -moz-outline-radius: 2px;"; }, lowlight() { if (this.orgStyle) this.target.style.cssText = this.orgStyle; else this.target.removeAttribute("style"); }, handleEvent(e) { switch(e.type) { case "click": if (e.button) return; e.preventDefault(); e.stopPropagation(); this.lowlight(); this.parent.capture.apply(this, this.getPosition()); this.uninit(); break; case "mouseover": if (this.target) this.lowlight(); this.target = e.target; this.highlight(); break; } }, init() { this.win = content; this.doc = content.document; ["click", "mouseover"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit() { this.target = false; ["click", "mouseover"].forEach(type=> this.doc.removeEventListener(type, this, true)); } }` }); });
«The Truth Is Out There»
Отсутствует
xrun1 более жесткие условия задашь сам, иначе не минимизировать будет не только по левой, но и по средней и по боковым кнопкам мыши.
// https://forum.mozilla-russia.org/viewtopic.php?pid=789048#p789048 // https://forum.mozilla-russia.org/viewtopic.php?pid=789076#p789076 // https://forum.mozilla-russia.org/viewtopic.php?pid=791818#p791818 // https://forum.mozilla-russia.org/viewtopic.php?pid=795879#p795879 // здесь трындёж на 2-3 страницы https://forum.mozilla-russia.org/viewtopic.php?id=9591&p=612 (async id => ({ delay: 2e3, val: "", init(topic, mm) { Services.obs.addObserver(mm = this, topic); Services.obs.addObserver(function quit(s, t) { this.timer?.cancel(); Services.obs.removeObserver(mm, topic); Services.obs.removeObserver(quit, t); }, "quit-application-granted"); }, observe(win) { var df = win.MozXULElement.parseXULToFragment( /* `<hbox id="${id}"><label id="${id += "-label"}"/></hbox>` */ `<hbox id="${id}" tooltiptext="${ "ЛКМ: Минимизировать потребление памяти
ПКМ: about:process
Ctrl+ПКМ: about:debugging#/runtime/this-firefox" }"><label id="${id += "-label"}"/></hbox>` ); this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); (this.observe = async win => { this.timer.cancel(); await new Promise(ChromeUtils.idleDispatch); /* win.document.getElementById("star-button-box") .after(win.document.importNode(df, true)); this.notify(); })(win); }, */ var clone = win.document.importNode(df, true); clone.firstChild.addEventListener("click", this.memind); win.document.getElementById("star-button-box").after(clone); this.notify(); })(win); }, memind(e) { if (e.button) { var gb = e.view.gBrowser; gb.selectedTab = gb.addTrustedTab(`about:${ e.ctrlKey ? "debugging#/runtime/this-firefox" : "processes" }`); } else e.view.memoryMinimizationButton.doMinimize(e); }, async notify() { var info = await ChromeUtils.requestProcInfo(); var bytes = info.memory; for(var child of info.children) bytes += child.memory; this.timer.initWithCallback(this, this.delay, this.timer.TYPE_ONE_SHOT); var prev = this.val; if ((this.val = this.mgb(bytes)) != prev) for(var win of CustomizableUI.windows) { var lab = win.document.getElementById(id); if (lab) lab.value = this.val; } }, mgb: bytes => bytes < 1073741824 ? Math.round(bytes / 1048576) + "MB" : (bytes / 1073741824).toFixed(2) + "GB" }).init("browser-delayed-startup-finished"))("ucf-mem-indicator");
Отредактировано dinn (Вчера 16:46:15)
Отсутствует
// Кнопка Save - Основной скрипт в Save_Script.js // Правка Vitaliy V. 2505 // Предыдущая версия // https://forum.mozilla-russia.org/viewtopic.php?pid=809376#p809376 (async () => CustomizableUI.createWidget({ id: "ucf-cbbtn-Save", tooltiptext: "Сохранить страницу\n/ часть / выбранное", nameSaveScript: "Save_Script.js", localized: false, cbu: { types: { 128: "Bool", boolean: "Bool", 64: "Int", number: "Int", 32: "String", string: "String" }, getPrefs(pref) { try { return Services.prefs[`get${ this.types[Services.prefs.getPrefType(pref)] }Pref`](pref); } catch {return null;} }, setPrefs(pref, val) { Services.prefs[`set${this.types[typeof val]}Pref`](pref, val); } }, gClipboard: { get ch() { delete this.ch; return this.ch = Cc["@mozilla.org/widget/clipboardhelper;1"] .getService(Ci.nsIClipboardHelper); }, write(str) { this.ch.copyStringToClipboard(str, Services.clipboard.kGlobalClipboard); } }, custombuttonsUtils: { writeFile(path, data) { try { if (path.includes(":\\")) path = path.replace(/\//g, "\\"); var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(path); file.exists() && file.remove(false); var strm = Cc["@mozilla.org/network/file-output-stream;1"] .createInstance(Ci.nsIFileOutputStream); strm.init(file, 0x04 | 0x08, 420, 0); strm.write(data, data.length); strm.flush(); strm.close(); } catch(ex) { Cu.reportError("Custom Buttons: " + [path, "---", ex, ex.stack].join("\n")); } } }, addDestructor(destructor, context) { this._destructors.push({destructor, context}); }, addEventListener(...args) { var trg = args[3]; if (!trg) trg = args[3] = this.ownerGlobal; trg.addEventListener(...args); this._handlers.push(args); }, onCreated(btn) { var win = btn.ownerGlobal; btn._handlers = new win.Array(); btn._destructors = new win.Array(); win.addEventListener("unload", this, {once: true}); btn.self = btn; btn._id = this.id; btn.cbu = this.cbu; btn.xhtmlns = "http://www.w3.org/1999/xhtml"; btn.addDestructor = this.addDestructor.bind(btn); btn.addEventListener = this.addEventListener.bind(btn); btn.gClipboard = this.gClipboard; btn.custombuttonsUtils = this.custombuttonsUtils; Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/custom_scripts/custom_js/${this.nameSaveScript}`, btn); btn.setAttribute("image", this.image); }, get image() { var img = `${this.id.toLowerCase()}-img`; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(img, Services.io.newURI("data:image/svg+xml;base64,77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgMjYgMjYiIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+DQogIDxwYXRoIGQ9Ik0xOCA5TDE1IDlMMTUgMkwxOCAyIFogTSAyNiA2TDI2IDIzQzI2IDI0LjY1NjI1IDI0LjY1NjI1IDI2IDIzIDI2TDMgMjZDMS4zNDM3NSAyNiAwIDI0LjY1NjI1IDAgMjNMMCAzQzAgMS4zNDM3NSAxLjM0Mzc1IDAgMyAwTDIwIDBDMjAuODI4MTI1IDAgMjEuMjg1MTU2IDAuMDQyOTY4OCAyMy42MjEwOTQgMi4zNzg5MDZDMjUuOTU3MDMxIDQuNzE0ODQ0IDI2IDUuMTcxODc1IDI2IDYgWiBNIDUgOUM1IDkuNTUwNzgxIDUuNDQ5MjE5IDEwIDYgMTBMMTkgMTBDMTkuNTUwNzgxIDEwIDIwIDkuNTUwNzgxIDIwIDlMMjAgMkMyMCAxLjQ0OTIxOSAxOS41NTA3ODEgMSAxOSAxTDYgMUM1LjQ0OTIxOSAxIDUgMS40NDkyMTkgNSAyIFogTSAyMyAxNEMyMyAxMy40NDkyMTkgMjIuNTUwNzgxIDEzIDIyIDEzTDQgMTNDMy40NDkyMTkgMTMgMyAxMy40NDkyMTkgMyAxNEwzIDI0QzMgMjQuNTUwNzgxIDMuNDQ5MjE5IDI1IDQgMjVMMjIgMjVDMjIuNTUwNzgxIDI1IDIzIDI0LjU1MDc4MSAyMyAyNFoiIGZpbGw9IiM4RThFOTgiIC8+DQo8L3N2Zz4=")); delete this.image; return this.image = `resource://${img}`; }, handleEvent(e) { var btn = e.target.getElementById(this.id); for(var args of btn._handlers) args.pop().removeEventListener(...args); delete btn._handlers; for(var {destructor, context} of btn._destructors) try {destructor.call(context, "destructor");} catch(ex) {Cu.reportError(ex);} delete btn._destructors; } }))();
// Скрипт Save // Правка Vitaliy V. 2505 // Предыдущая версия // https://forum.mozilla-russia.org/viewtopic.php?pid=781458#p781458 // https://forum.mozilla-russia.org/viewtopic.php?pid=799602#p799602 // https://forum.mozilla-russia.org/viewtopic.php?pid=799639#p799639 // https://forum.mozilla-russia.org/viewtopic.php?pid=805016#p805016 // Кнопка-виджет в Save_Button.js self.label = "Save"; self.type = "menu"; // Создать меню для кнопки ... var array = [ { label: "Сохранить favicon сайта", func: () => saveFavicon(), image: "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAADUElEQVRYCe2WS0gVYRiGZ8pQ8oJZYXbBWkZEBFEUlQlBEi0zwWWLtoEg1ULRRSCRXQgM3VSbCIJAcNMiRGgVRVZSq1DpImam0U1Nz/S80//JOJ6bYUTg4X2+9/u//zL/XM6Z43lLn398BfyFHD8IgjzGV0IVyDfh0hvCA7gP3b7vT+KLJw5cAq3wBTJJYy4waNWi7ICFauETmH66ZAK/61BOGlif8lFCzR9vgsk+NEMCpP4gCK6C9IOwxxYn3we2iSvkgyBpbiOJb2OzdiY1gamNJBdegnQhvhDFVpD6CHnQAaaG+Pi0bWbVQAKk0xpMshekKUKpalGorQO7BbvVR7sOJK11XLWMMLoExkBqtQk0LoLUabW409kFUov10dAtwQI9R6usbp5jScTPkRfDMDxmZjUuVSnAeKRGc47GXOsoY564/BE+AmvhLJyBWc15OJikDY3SWwR/Q+MsuobfiRk8lA4YJi5U4jr4NP4cApBWEraCJvbi6bSTzmXwCr6D5BN2QDEchG6YL65AC0i3o70UjoD0OlpPljNoAKTD0X4Kd0A6H61rp9F2uWv0OTfTVVE+ppAB3UIN0dnKjRcusWOEzfgGysKq5w05N8t3yTfn6eyr6yxwbmZrbrCCPL4B3SvVA4UIqeqRIbNpqrHxNcMJ8Q28Dauet965Waqzsv6oF7qGzXFNb6NL3jkPLb4BvVbVsU0hwmeXr3aezmzMeGyQrTkYrfvRBo+oviI91BIwCHbZcsl171Qf8NJ/ttDtg850EpfULifRCR/gd+AheSh1hIkCG8jBR8GeetJFla5K6h8idjbNJto5ZD0MwUmYBukSYTtch3uQTNUUT0Ev1IO0gnADSqGdY8zgqcUGCmAIpJue+9C4CFKnK80zOpO9jG5Rl94T8udNSlZgYLLX8R7qUqrXcRmd9jrepXVp14GU/etYEwWzmsDURpILz0C6rDFRKF4D6SkhDzrA1BAdm1XOTB+aQbvHgv4gCC6BNEXYbwuRVwTB7P9B/TMapC0lCI0w52G3eVk5k2vhI5jsMk9QSPendIT+E1kdJNMgFioC3ZIPeCYNM0BnXZhpXfUv6NKw8HImHfI87xhUwGbv96cf64Eu6PF9fwZf0v9xBX4BW7VJooPQ4WAAAAAASUVORK5CYII="}, { label: "Копировать favicon сайта в base64", func: () => copyFaviconData(), image: "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAC6UlEQVRYCe2VS2hTQRSGJzFFMFRtEUNBaRptpVUEFdyoCxcuRESkBVcGEYRCEQUXQXBpoQjik25EkSxEfCDiSkEUbNGCC1204KOoIBqQplRplRpz/f5wpwwxbZ6ii5b/m/OYM2cmNzdTY+b//vETCFS7v+d5IXrsgD3QBmFIwQDcCAQCH7B/R2zeBW9gNmWYSEKk5ieg6UnI1wiJXsjXexIdNTsEzQ6D1YDvZLEbtQn2Jkh6Oik58M7zvGWarwqaROEHSKcZekB6ahsTbAcpzRADe4grtsbaoHXKsMepXQhTkIaDIP1io4Qg2AIeNEAPDIEUZz4mpyJYHIIxqEYJd/OQG5TgR40xjZCBOyB1MgThAUyA1WacZhiBYVgNG2ATVCY+9laQPtoOBHr0GK/V5mRJXAap14/3K4Anii0h65RoJ/26MI3sJ8mS0xNYT24xvtVy34mQV60uKaW+a6gIGjVABqpRv7u5Tu7Gc/pcq+MUPAPpJ4NiWVyjT6bY4ikJ3+ArWOldsX75lo++Cs6Dftsd2LMgJW03gpWQ9WnCXgXpLUPxr50iNbiIHYdpmIALUO9ssoS4CzpBSjOENY89BtJLhjMg6UA7NV8QKvSyJLDDMJt0AyaZXGub4AdhN9wH/R9own4GKaPB54RdU9BS9BpKlRrfonib24x4DdwGV1MEh9y6gj5Fo1CJXrHoCCyyjfFPwRhcghabn9NSWOkBWJqTvh79nzBE+loWuBuSa4HrcBfWuXM5n2S1B6BFTjPNieogDs/B1WBuU4biPwmKylDuLmCnqDGmGw4YYyKQr082EbAOi0bxY1Cp0ix8bIwJwi6og3xNk3gI+7jUdEHh+tIBwNUggS6ZIWy1ytLgGjT72/1pmNQ7oJ/MOfw2t4K4FfrgC5Sreyxod/sV9Ck6CisKTvpJ5uuhG15AMele2esvrb1h93boA13BmBnpKcWJ9C7UfuP8jmzUCP2Qgkee5y3Nr5mP/+sn8Bs4IBR11QNlKgAAAABJRU5ErkJggg=="}, { separator: ''}, { label: "Сохранить ярлык страницы как …", func: () => saveShortcuts(), image: "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAACsklEQVRYCe2Xy29MYRjGe6Z0U6UXl2RiTCoV0UU3EguxlBaR7qjoiKWyROzUyr9g0YuNS9jwD4iSSCxQS0NqEjuShhKNykzm83uGd/rN6BzmnDMrTp7f977f7XnPbU4ybW3/+hG04gY45zbiOwy9UILHQRC8JbZWFA7gEnwBX2U692Bry84A83a4CWEqMLk58ZPAVMVvE03vSc7AIByGR2C6k+gJ4FpfPM9Y2i9CX49mzv08yoSMPx8rx+w6mH4rbuYsOASmkzYeK+J22q0eDYurCMuGwDShsVjgpNv6higt0mwPM2T+HJiOhK39qzmcdoPpsjbR6YQO5T6MZZ1zOkmCW6Lp9Ocj5ZgcAOk5TTecgBV4BevMlDzrnCuA6bzNxYq4DcA89MIYFEFapumSOTHraotP0U/m6ysj6INjYMW/k4/+Kt5P7l/5DP2U5ppGG2EI9kLGDMhPQQmkbzTDoMcxSVwC0wxJ5OI5Ni+A6QWJbnuOWAJJxUdINK53grSqa2TNF9cm0GZCVc/IeiAHJZBUXB+ZPjrzYFogydndaiqyMQWzYPpEotvaTRyHEkiV4jKnE8AuOAh7NBYJNtcXLzDWLzPiKOhFI7gijV5AXXmg+dhgqKuYJppUPCtjBrpgGaQizXHQM39J3Kk1scHoApiqxWXM4HrIwwqMgd4Fe+H2a00sMNwAn0FapKlcuW/KWAdUPqPEK271GPDXRcrxOgqms2EmLMrAR5DyYWv/NJfyFuzw8ideXpNSMc3AA+gB6aqa2GA8DqaRtQyZTMNrMM2utS7SGI5Z51wZpIc0NT8t+vXFbzHWHqlYo00Y3gXTnHNOX7hB4gR8AFPyxXVSuG+BAoTpBpPJXrmKG5hvg/tQL/1ELzJY82hsX9TY0IxC+g7sw3gTvIOn/L36SvyvRO/AD94bS0nNXI/tAAAAAElFTkSuQmCC"}, { separator: ''}, { label: "Сохранить страницу как PDF", func: () => savePageToPDF(), image: "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAACt0lEQVRYCb2XS2sTURTHz8T0aQ21tVHRLtxYqI+F4EY3UVCLi8YHSKG40KWK+Akq6kcQv4Da+liIpbrwRWtF0ZUENyq468JSC8VqtaYl/g5k0pvJTHJ7Mxr+v3vOvXPuOSczk0kiEvIqFAptcA0+w0+w0XeCHsK2kJT2SyTogBy46hsb99pW9IKBbL7N2iCoXjE8gjmopg4ODkELqOYZsp7njWPtRfFNsASqOwwVDUZlI1bjMSX9wuuLivfXE75TtLuwa0B1g3dQUMeS6UBcM/MHNHEEG6lgA61G5Izh27iLIUEtrI3SxGFsqIINhAbVudjEfm0iIyGv/9GAlvUvx26dmMTZwLKZOMRfz5reqA3YkpIlr37nHikyItIIpjYy2QqqXgZ9RrzBVoqbJQu+eioj3FZIeB58Zc0sTpeATPq0fImdhA1mwgj/ecS6ODVAsuPQDZ3gPzVxVy/XBhYo1QrTkAJnuTYwTsU07IMv4CynBnhEf6XiGDTBa3CWUwPFai+K1uYmLIZWmnoa6CfdPNzkk9CMdZJTAxTcTLWMiJyCdTDCmtNDzWkTBS/AR3gCR+EdjNHEb2wvqCZE5CL3yyI2Uqs+AxRJke0c5OAWTMIS7IBjkIApOAOHoKo0uGqAeZDi+tPrOmvt0A9/4DSkYTtchjzshAkR0TODsRQFQr8LWE/CJZgF1RBDyjKtENsDvsq+C5K1krCrkZjHsAf0nT/jul7Fj0U1G6DKQTgAH0BP+VlsbLJp4C3VRsGDE7z7KWxsStbKRME5Yk7CP1EikHXBmHcZfr1u2kjww/DLXW64LnD6Y1KeaWVGPg/ugyrP0LlyVKTsEnC6Zwi4S8AgDMAW5k+xeXBRA5v6YD+ohqkxq04kFNSfWzls3HpPwvbIwuYBAtvA/3u+jO8q3fuJzVdgrVnD9/8CvFxMGTTWer0AAAAASUVORK5CYII="}, { label: "Печать страницы / печать в PDF", func: () => document.querySelector("#mainCommandSet > command#cmd_print").doCommand(), image: "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAC6ElEQVRYCd2WzW8NURjGZ6hqKFckNIidhUY/fCysmm7KxkaIhAVNETtJcxf+AURISxMbEZvGBgtBokU3NrpxW410JxVarCiVNKQtx+/Re2TmzseZe29Xmud3zpz3fd53zkzn3ju+52X/M8Ycwn0V3kMBRkDzG9/3Dcdlyy+ngg2M498BpfpOYBS0GbupiSybyrwBTr6LE+gkTN4kwyZYAUn6RkKbsRTY0FtiIZWzgV4q87AAW0AnaGbeA7tBs9YrOU7SVxLBu/Qk0wa4+uUUToGueoArOcBxRPh0R5pI2A1pbmVdB3EqxAUjMRrvA6ujEUNKgKIaaIEuuA7DMA+SnqmU6mIKZz9IMwyriuGKJuo3wAJIF5xNcNXDLEi3nAUOA03OgJUe7PQKnMfBqj3d7c7SaBCkCbcbB84BkKYYlhGqWNTn4CdIfc5GuBrAPjCXnQUOA72Cd7PNYfc8CvJg1egscBho9BikdwzurwBMIyBl+7ymbIAm62EOpN4U62IKVxNYdS9GKx9pdBKs9jo74TwPkj6zm50FDgONBkGaZMh0+x9ilJ46ejvTNGkA+zBfCRWQaIW1oSALYo1wCbaxrEr06AarllAzondBn817zB3gvj2hDu4FPV+BNBpxEx2GoF6yOA2rI+YKAvRpBqt8pAWZIYjTD4J/70qkqIwAPS6C9ItB7xHhaoI3wKUXGE5A0u96uGlxhb8WPoE0VAyHJzJtkFVfMF6D7eEu8St8x8DqSLyLKA49iEyZ9RvnKUoTRd6HMZA+MuhtKeK3v25dZB5AVvkYN0KaDpPU6xiT18Nr3LwOUmGX++EZZFF/UjOK14Gumsnom68uyRsbp2on3IY5SNI0ifrSBorBc7A6WOrJvKbDVuiBGYjTfYI5NWTW/7yDeRysbipXNXTLwTn4AKWaJTBdhOmf7nBUU/XJgw1oWAudxpjXkKTPJM6CH6xd0mM1h3ZjTB+MgU76iLnTGLNmSU/23zf7A6yAD944M8WnAAAAAElFTkSuQmCC"}, { label: "Сохранить страницу / выбор как HTML", func: () => savePageToHTML(), image: "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAADCUlEQVRYCb2XTUhUURTH37zU8mORNtpEJTQIQlCrgqiFrkoImk2EYS2jhW3ah5TRqpULoVZtkrJFZbmoGBDsaxXZrhEiamdWZJZW6ky/I+8OZ968N+/Om0j+v3vOvfe8c8+7780dx3EC/gqFQgtchln4CTb6TtB92BWQ0n6IBG3wBuLqMxfut10x4Q/k4puMDYDoKc0kfINKamNyCBpBtEiTSSQSU1h7sXgKVkF0i6aswLBsxEo8pqhlvL6weDPuGseze7AbQDTKHRTEsWTOF7eJ/l2KOIINlb+AJhU5r3wb93dAUCNjExRxGBsofwGBQTUObuR6KaLXCfj7HwXIsuZx7JWO5l8WsKYTB/itjMmLWo8tqq7o1e6Mk6LXcZwG0NpKZweIdtPIGfECWy5elgwYdZdHxBsh4SAYZXSWWI+ATC5MwjikdcIQPxsy7rhhE5XGOR/yzD+EE/CMIpLYWIpVgLfSrGe3YQchlmopIKVWbGUX5LFUvRO1FNCvCsjhyxH+ikLS+NZyrSMJJPkQpEG+LY8xZHQQ5wp0wghYq9pz4CuZn0MHiOZo5HN+CmtUzRdY1Z+CHlZJgdm5e/hToPVId6J8kygqzmHbzxJ0HIwWcWS7P2K1lnUnynejAtT8sPLz+KfhAxyFP2B0kWK3mE6UdaMCZJ6E8q4kxfe4xmE0gb8PkpCF9yDqpLkKVrIqgMVWyfYOjKY9R17Ic/gXYAGMBii6wXQqWbfSpG/uuurvFJ/C8jCKPwODYCRnglVuqyAv6wg2C6Iz3KH8kyG+QxEFnC4wesDYL9OxtiSt+HXMfBOMgegxTRc0w0mYB9EMjTkn1tem3w1GmfVBr6lmB+ROl7gzOQV7uH4BXsIPuAFv4TwcIOYT1kp1vqgl1W/Hz0GZWGCaQQFjpQ4VJQWrrnLZo3aI9cNEpSlxyZeAOyBaoSk5I0p2gDuT53ibDLLN/djtXPAEuwJxVM9FfXAIRGOs8UWcUFiw1h+npAjUa0Y3hy6sJwhsAfPzfA0/ruTaHBdfgma9hvH/Ag7EeepKNPfrAAAAAElFTkSuQmCC"}, { label: "Сохранить URL, страницу / выбор как TXT", func: () => saveSelectionToTxt(), image: "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAACKElEQVRYCe2XP0scQRjGd2WjpRAQi4ipvOvSCpIujX8gEkIasVA5CxG0igGLhFj4MfQ7CPkGp5Upki5nYQKiiCAnCpp4cP6eeIOb2ZlZMeddocfzm3nned+dnZudO70osl71ej2GWfgKF/C/0hzbTFKybuUeUvgZ7kuf7LvGaYO7PmP8M4qiBD7CITRDvUyyAjXoj+P4gD4rFjACRsVsxd0cJiyC0XB6lo70gLgT7ltd6RvYC0jnWhK3fQE6bMF3yoN7ScE0SIscoDM8Pcd3MnJYp74cqklCyUauQD8D0geaM3gBxiP0apNMGbxKvJmbxAlhBaSaGjgG4xF6pWu9yUyCrR0Ho2Km4I4GE6Y/huPpaTrSg3bEuY+A1b9iYQsgTXKoTvHeMJiKwq85avfDJddfuXk1zyl4DVIXzSkMgPEInVpyupaZuwPU6+/BFr10qQb2wHiETp073ZDJ1j4ewswGsStjmMsgjXKwTvAmGMxDnlap/xIqSkLJRq6XfgikJ2qgD4xH6JWu9SaVuM0CflG4AdJvNbADxiP0Std6k5kEW/t4CF278hZzFaRBDlWVnSoxeA8hDVO7GypQLlGTQzf5Akim/ikD4xE61el0LdNMaNn/DCuM1kC6UAPfwXiETlWdbshkax/eIWz7/wP2Av6EHlGTcubL7O909iHU4aqRka8fqEfEzVBPYxLN/a0RuzsOYkt/nGZWwQJi0Lv/Qd8saa5S5mYYV1bQVfz1oDyqAAAAAElFTkSuQmCC"}, { separator: ''}, { label: "Копировать изображение / текст в base64", func: () => copyFileToBase(), image: "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAAEEfUpiAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAM/SURBVEhL7ZdfZNZRGMfPuzFGIyJGdBExRaTxXqQRXY0ouxgjIiKi7hsxIrqLXUVEKV1EjGU0pYgxIpaIXYwRJbqIkbfP95zn+fn9eX/vu3d7I+nL933Ov+d5zu+c5zznvOGPoNVqvbNiRKPUMGUygc5JKybVsrowoJ9cxyv9UB+DTZUb1qABD+FMo9FoUl+m/B0Ow3ow8LAVu4CRs+amggE6DiA35Ts1lSBNpzX5pBNKHXfgCJyBcZG0lPuQz+GgfaIUNqBcv4ftYQPTStbgnsndIW6FgMsniIPwM9RWjDPny8juQPmtz7kTNKY8zr9xEG7ReRKOwgc2+HjqTk4kyxvmBrbgEJ1v4Cbli7E1hFP6QXkBEbfB6jKe9kk/Ag3al0dwKDaEcAaFHypIIbZUIWe9Iz+DfwD5RdT5fQF9ERdZxJtWroVnDZ0YRZ+Unxr3w+3BVrVrJLaDUsJeK9832RaMmzBHhUykA38aeStVC8gCSZCypEejQ2twIhVj1lDyvRprISyZlPKoFedMZpCBj6kY5rG+AVcor6WmDApxeV/A2KQYW4EMaPWFKyYF9yjvOqna4sexIYRZY4Tn9tcIbaGS/wjUMf6Ax0v0KXUdhatQht24cvG5GAcUdGw1YAJKeUHKSEExIqg9mxnIl7cPZlSImTiD3WAnBrQm/UnpfwWydNAOLLaHhO/YF/iJHdbd2BdUJoBThY3O5rHY0B6rTCIf+P0Bzm97mEFdluetqwDaOz9+ekA+I+t4+hnXdTXFV/5K1d6BPUWqH8IlbM1buQBPBWOIfD7VVaAcom04Ar/BdbiMIZ34jsCenPmrYAUdz5AV+AQuIHrZU6WaSmoVsKX4UY4XFLCyXQtPBHtMCj9RapZJ+1n1xRFsFY4qLy/ariHc+VfoT5xa+ATiw8kwjKHKCWAS8QimWoS2LQM6M4jpVAu6yabRiTFEnwe2WHjReDbXW9fvC+EuA8etHEFdX5yfmB5sEWbU91lO9Zchu047oZAHMKTr5AZUAqqDVuI6DvQQjkDvGaLX6yXeZ5VE5MCoLshDUIaV+dZR0DO2Z2Ar/+SZw062erW3kZzBNfgSKpp35LwbdnId/kcfEcJvJ7yZGHuzI6wAAAAASUVORK5CYII="}, { separator: ''}, { label: "(Меню ПКМ) Сохр./добавить текст в файл", value: "Save.SelectionToFile" }, { label: "(Меню ПКМ) Открыть текст в редакторе", value: "Save.TextToEditor"}, ]; var menuPopup = self.appendChild(document.createXULElement("menupopup")); array.forEach((m,i)=> { if ("separator" in m) { menuPopup.appendChild(document.createXULElement("menuseparator")); return }; var mItem = menuPopup.appendChild(document.createXULElement("menuitem")); mItem.setAttribute("label", m.label); mItem.setAttribute("class", "menuitem-iconic"); if ("image" in m) mItem.setAttribute("image", m.image || array[i-1].image); if ("value" in m) { mItem.setAttribute('type', 'checkbox'); mItem.setAttribute('checked', cbu.getPrefs(m.value) ); mItem.onclick =()=> cbu.setPrefs(m.value, !cbu.getPrefs(m.value)); } if ("func" in m) mItem.addEventListener("command", m.func); }); menuPopup.onclick = e => e.stopPropagation(); function aDate() { var t=new Date(); var y=1900+t.getYear(); var min=t.getMinutes(); if (min<10){min="0"+min}; var h=t.getHours(); var m=t.getMonth();switch(m){case 0: m="января";break;case 1: m="февраля";break;case 2: m="марта";break;case 3: m="апреля";break;case 4: m="мая";break;case 5: m="июня";break;case 6: m="июля";break;case 7: m="августа";break;case 8: m="сентября";break;case 9: m="октября";break;case 10: m="ноября";break;default: m="декабря";} var d=t.getDate(); var curdate=d+" "+m+" "+y+" "+"г"; var myfilename=curdate; return myfilename; } // Копировать favicon сайта в base64 function FaviconToBase(image) { var canvas = document.createElementNS(xhtmlns, 'canvas'); canvas.width = image.naturalWidth; canvas.height = image.naturalHeight; var ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0); var base64 = canvas.toDataURL(); gClipboard.write(base64); var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); var alertName = "FaviconToBase"; as.showAlertNotification( base64, "Скрипт Save - FaviconToBase", "Значок скопирован как base64", false, "", null, alertName ); setTimeout(as.closeAlert, 5e3, alertName); }; // Сохранить страницу / выбор как HTML function savePageToHTML() { var vert = String.raw`javascript:(function(){var getSelWin=function(w){if(w.getSelection().toString())return w;for(var i=0,f,r;f=w.frames[i];i++){try{if(r=getSelWin(f))return r}catch(e){}}};var selWin=getSelWin(window),win=selWin||window,doc=win.document,loc=win.location;var qualifyURL=function(url,base){if(!url||/^([a-z]+:|%23)/.test(url))return url;var a=doc.createElement('a');if(base){a.href=base;a.href=a.protocol+(url.charAt(0)=='/'%3F(url.charAt(1)=='/'%3F'':'//'+a.host):'//'+a.host+a.pathname.slice(0,(url.charAt(0)!='%3F'&&a.pathname.lastIndexOf('/')+1)||a.pathname.length))+url}else{a.href=url};return a.href};var encodeImg=function(src,obj){var canvas,img,ret=src;if(/^https%3F:%5C/%5C//.test(src)){canvas=doc.createElement('canvas');if(!obj||obj.nodeName.toLowerCase()!='img'){img=doc.createElement('img');img.src=src}else{img=obj};if(img.complete)try{canvas.width=img.width;canvas.height=img.height;canvas.getContext('2d').drawImage(img,0,0);ret=canvas.toDataURL((/%5C.jpe%3Fg/i.test(src)%3F'image/jpeg':'image/png'))}catch(e){};if(img!=obj)img.src='about:blank'};return ret};var toSrc=function(obj){var strToSrc=function(str){var chr,ret='',i=0,meta={'%5Cb':'%5C%5Cb','%5Ct':'%5C%5Ct','%5Cn':'%5C%5Cn','%5Cf':'%5C%5Cf','%5Cr':'%5C%5Cr','%5Cx22':'%5C%5C%5Cx22','%5C%5C':'%5C%5C%5C%5C'};while(chr=str.charAt(i++)){ret+=meta[chr]||chr};return'%5Cx22'+ret+'%5Cx22'},arrToSrc=function(arr){var ret=[];for(var i=0;i<arr.length;i++){ret[i]=toSrc(arr[i])||'null'};return'['+ret.join(',')+']'},objToSrc=function(obj){var val,ret=[];for(var prop in obj){if(Object.prototype.hasOwnProperty.call(obj,prop)&&(val=toSrc(obj[prop])))ret.push(strToSrc(prop)+': '+val)};return'{'+ret.join(',')+'}'};switch(Object.prototype.toString.call(obj).slice(8,-1)){case'Array':return arrToSrc(obj);case'Boolean':case'Function':case'RegExp':return obj.toString();case'Date':return'new Date('+obj.getTime()+')';case'Math':return'Math';case'Number':return isFinite(obj)%3FString(obj):'null';case'Object':return objToSrc(obj);case'String':return strToSrc(obj);default:return obj%3F(obj.nodeType==1&&obj.id%3F'document.getElementById('+strToSrc(obj.id)+')':'{}'):'null'}};var ele,pEle,clone,reUrl=/(url%5C(%5Cx22%3F)(.+%3F)(%5Cx22%3F%5C))/g;if(selWin){var rng=win.getSelection().getRangeAt(0);pEle=rng.commonAncestorContainer;ele=rng.cloneContents()}else{pEle=doc.documentElement;ele=(doc.body||doc.getElementsByTagName('body')[0]).cloneNode(true)};while(pEle){if(pEle.nodeType==1){clone=pEle.cloneNode(false);clone.appendChild(ele);ele=clone};pEle=pEle.parentNode};var sel=doc.createElement('div');sel.appendChild(ele);for(var el,all=sel.getElementsByTagName('*'),i=all.length;i--;){el=all[i];if(el.style&&el.style.backgroundImage)el.style.backgroundImage=el.style.backgroundImage.replace(reUrl,function(a,b,c,d){return b+encodeImg(qualifyURL(c))+d});switch(el.nodeName.toLowerCase()){case'link':case'style':case'script':el.parentNode.removeChild(el);break;case'a':case'area':if(el.hasAttribute('href')&&el.getAttribute('href').charAt(0)!='%23')el.href=el.href;break;case'img':case'input':if(el.hasAttribute('src'))el.src=encodeImg(el.src,el);break;case'audio':case'video':case'embed':case'frame':case'iframe':if(el.hasAttribute('src'))el.src=el.src;break;case'object':if(el.hasAttribute('data'))el.data=el.data;break;case'form':if(el.hasAttribute('action'))el.action=el.action;break}};var head=ele.insertBefore(doc.createElement('head'),ele.firstChild);var meta=doc.createElement('meta');meta.httpEquiv='content-type';meta.content='text/html; charset=utf-8';head.appendChild(meta);var title=doc.getElementsByTagName('title')[0];if(title)head.appendChild(title.cloneNode(true));head.copyScript=function(){if('$'in win)return;var f=doc.createElement('iframe');f.src='about:blank';f.style.cssText ='position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;';doc.documentElement.appendChild(f);var str,script=doc.createElement('script');script.type='text/javascript';for(var name in win){if(name in f.contentWindow||!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name))continue;try{str=toSrc(win[name]);if(!/%5C{%5Cs*%5C[native code%5C]%5Cs*%5C}/.test(str)){script.appendChild(doc.createTextNode('var '+name+' = '+str.replace(/<%5C/(script>)/ig,'<%5C%5C/$1')+';%5Cn'))}}catch(e){}};f.parentNode.removeChild(f);if(script.childNodes.length)this.nextSibling.appendChild(script)};head.copyScript();head.copyStyle=function(s){if(!s)return;var style=doc.createElement('style');style.type='text/css';if(s.media&&s.media.mediaText)style.media=s.media.mediaText;try{for(var i=0,rule;rule=s.cssRules[i];i++){if(rule.type!=3){if((!rule.selectorText||rule.selectorText.indexOf(':')!=-1)||(!sel.querySelector||sel.querySelector(rule.selectorText))){style.appendChild(doc.createTextNode(rule.cssText.replace(reUrl,function(a,b,c,d){var url=qualifyURL(c,s.href);if(rule.type==1&&rule.style&&rule.style.backgroundImage)url=encodeImg(url);return b+url+d})+'%5Cn'))}}else{this.copyStyle(rule.styleSheet)}}}catch(e){if(s.ownerNode)style=s.ownerNode.cloneNode(false)};this.appendChild(style)};var sheets=doc.styleSheets;for(var j=0;j<sheets.length;j++)head.copyStyle(sheets[j]);head.appendChild(doc.createTextNode('%5Cn'));var doctype='',dt=doc.doctype;if(dt&&dt.name){doctype+='<!DOCTYPE '+dt.name;if(dt.publicId)doctype+=' PUBLIC %5Cx22'+dt.publicId+'%5Cx22';if(dt.systemId)doctype+=' %5Cx22'+dt.systemId+'%5Cx22';doctype+='>%5Cn'};var href = 'data:text/html;charset=utf-8,' + encodeURIComponent(doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->');var a = document.documentElement.appendChild(document.createElement("a"));a.setAttribute("href", href);var name = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop());name=name.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).replace(/^\s+|\s+$/g, '');name += (function () {var d = new Date(), z=function(n){return '_' + (n < 10 ? '0' : '') + n};return z(d.getHours()) + z(d.getMinutes()) + z(d.getSeconds());})();a.setAttribute("download", name + ".html");a.click();a.remove();})();`; gBrowser.fixupAndLoadURIString(vert, {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()}); }; // Получить имя файла async function pick(fileName) { try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); await IOUtils.makeDirectory(file.path); } catch { file = Services.dirsvc.get("Desk", Ci.nsIFile); } var fp = makeFilePicker(); fp.init(window.browsingContext, "", fp.modeSave); fp.displayDirectory = file; fp.defaultString = fileName; return await new Promise(fp.open) != fp.returnCancel && fp.file; } // Сохранить favicon сайта function saveFavicon() { var dn = "favicon"; var re = /^data:(image\/[^;,]+)/i; var ms = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService); (saveFavicon = async () => { var url = gBrowser.selectedTab.image; if (!url) return; if (re.test(url)) { try {var name = gBrowser.currentURI.host || dn;} catch {name = dn;} name += "." + ms.getPrimaryExtension(RegExp.$1, "ico"); } else var name = Services.io.newURI(url).QueryInterface(Ci.nsIURL).fileName; var file = await pick(name); file && IOUtils.write(file.path, new Uint8Array(await (await fetch(url)).arrayBuffer())); })(); } // Сохранить ярлык страницы как … function saveShortcuts() { var img = self.getAttribute("image"); var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); (saveShortcuts = async () => { var file = await pick(getTabLabel() + ".url"); if (file) await IOUtils.writeUTF8(file.path, `[InternetShortcut]\r\nURL=${gBrowser.currentURI.spec}\r\n`), as.showAlertNotification( gBrowser.selectedTab.image || img, file.leafName, "Сохранил в: " + file.parent.path ); })(); } // Копировать изображение или текстовой файл в base64 ... function copyFileToBase(){ var fp = window.makeFilePicker(); fp.init(window.browsingContext, "Открыть файл", fp.modeOpen); fp.appendFilter( "Text and images", "*.txt; *.text; *.css; *.js; *.ini; *.rdf; *.xml; *.html; *.htm; *.shtml;\ *.xhtml; *.json; *.jpe; *.jpg; *.jpeg; *.gif; *.png; *.bmp; *.ico; *.svg;\ *.svgz; *.tif; *.tiff; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw; *.webp"); fp.open(re=> { if ( re != fp.returnOK ) return; var file = fp.file; var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); inputStream.init(file, 0x01, 0o600, 0); var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream); stream.setInputStream(inputStream); var encoded = btoa(stream.readBytes(stream.available())); var contentType = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService).getTypeFromFile(file); var dataURI = "data:" + contentType + ";charset=utf-8;base64," + encoded; gClipboard.write(dataURI); var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); var alertName = "FileToBase"; as.showAlertNotification( dataURI, "Скрипт Save - FileToBase", "Файл скопирован как base64", false, "", null, alertName ); setTimeout(as.closeAlert, 5e3, alertName); }); }; // Сохранить страницу как PDF, скриптом ... function savePageToPDF() { var ps = Ci.nsIPrintSettings, cfg = { paperWidth: 8.5, paperHeight: 11, paperSizeUnit: ps.kPaperSizeInches, // kPaperSizeMillimeters marginLeft: .2, marginRight: .2, marginTop: .2, marginBottom: .2, edgeLeft: .1, edgeRight: .1, edgeTop: 0, edgeBottom: 0, headerStrLeft: "&T", headerStrCenter: "", headerStrRight: "&U", footerStrLeft: "&PT", footerStrCenter: "", footerStrRight: "&D", printBGColors: true, printBGImages: false, scaling: 1, shrinkToFit: true, // overrides scaling orientation: ps.kPortraitOrientation, // kLandscapeOrientation printerName: "", printSilent: true, printToFile: true, showPrintProgress: false, isInitializedFromPrefs: false, isInitializedFromPrinter: false, outputFormat: ps.kOutputFormatPDF, outputDestination: ps.kOutputDestinationFile, }; ps = Cc["@mozilla.org/gfx/printsettings-service;1"] .getService(Ci.nsIPrintSettingsService).createNewPrintSettings(); for(var key in cfg) if (key in ps) ps[key] = cfg[key]; (savePageToPDF = async () => { try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); await IOUtils.makeDirectory(file.path); } catch { file = Services.dirsvc.get("Desk", Ci.nsIFile); } file.append(`Snap ${new Date().toLocaleString("mn").replace(/:/g, "\ua789")}.pdf`); ps.toFileName = file.path; await gBrowser.selectedBrowser.browsingContext.print(ps); //file.launch(); })(); }; // Копировать favicon сайта в base64 ... function copyFaviconData() { var img = new Image(); img.src = gBrowser.selectedTab.image; FaviconToBase(img); }; // Сохранить URL, страницу / выбор как TXT ... function saveSelectionToTxt() { // [129+] l11 = length >= 11; https://forum.mozilla-russia.org/profile.php?id=71856 var {length} = saveURL, splice = length > 9, l11 = length >= 11; var msgName = _id + ":Save:GetSelection"; var receiver = msg => { var args = [ "data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + "\r\n\r\n" + msg.data), getTabLabel() + ' ' + aDate().replace(/:/g, ".") + ".txt", null, false, false, null, window.document ]; splice && args.splice(5, 0, null) && l11 && args.splice(1, 0, null); saveURL(...args); } messageManager.addMessageListener(msgName, receiver); addDestructor(() => messageManager.removeMessageListener(msgName, receiver)); var func = fm => { var res, fed, win = {}; var fe = fm.getFocusedElementForWindow(content, true, win); var sel = (win = win.value).getSelection(); if (sel.isCollapsed) { var ed = fe && fe.editor; if (ed && ed instanceof Ci.nsIEditor) sel = ed.selection, fed = fe; } if (sel.isCollapsed) fed && fed.blur(), docShell.doCommand("cmd_selectAll"), res = win.getSelection().toString(), docShell.doCommand("cmd_selectNone"), fed && fed.focus(); res = res || sel.toString(); /\S/.test(res) && sendAsyncMessage("NAME", res); } var url = "data:charset=utf-8," + encodeURIComponent(`(${func})`.replace("NAME", msgName)) + '(Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager));'; (saveSelectionToTxt = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); } // Добавляем в контекстного меню страницы новые пункты ... ((contextMenu, el)=> { // в контекстное меню выделенного текста ... var saveItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el); saveItem.id = "content-saveItem"; saveItem.setAttribute("label", "Сохр./добавить текст в файл"); saveItem.setAttribute("class", "menuitem-iconic"); saveItem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAADAgBEDRIXnwxQjKQNWp6pDFWXqAxXm6gMV5moDFeaqAxXmqgMV5qoDFebqAxVlqgNW5+pCkyIogwSFqgDAgBHDQoFhyszOv8hheP+IJH7/x+L8v8fjfb/H433/x+N9v8fjfb/H432/x+N9/8fi/L/IJH7/yGF5P0kLTTvDAcDgwgICIQ8Ojf/0czA+Oji1fzh18r85NzO/OTbz/zj287849vO/OPbzvzk3M/84dfK++ji1f3Sy8D5NDIvywYGB3kKCgqFQ0A8/+XXw/v979f/9uTO//rp0f/66NH/+ujR//rn0f/66NH/+ujR//bkzv/979f/5tfD/UZBPv8KCwqEDQwMhUVDQP/f08X7+OrZ/+zf0P/v5NP/8OPT/+/j0//v4tP/8OPT/+/j0//s39D/+OrZ/+DTxfxEQj//DAwMhA8PD4VKR0T/4dXG+/rr2v/v4tH/9OXU//Ll1P/z5dT/8+XU//Pl1P/05NT/7+DR//rr2v/i1cX7SkhE/w8PD4USEhKFT0xI/+XXxfv97tr/9ePR//no1P/459T/+OfU//jn1P/459T/+OfU//Xk0f/97tr/5dfF+09MSf8SEhGFFRQUhVNQTv/j2cv7+u/g//Hm2P/169v/9Orb//Tq2//06tv/9erb//br3P/x5tf/+e/g/+PZzPtTUU7/FBQUhRgXF4VXU1D/2828+/Lk0f/q2sf/7d3K/+3dyv/t3cr/7N3K/+rayP/r28n/69vI//Ll0v/azbv7VlNP/xgXF4UfHh6FTktJ/1JOTPtZVFL/Uk5L/1FNSv9RTUr/UU1K/1JPTP9YVVD/VVJP/09NSv9WUk//UU1L+05LSf8fHh2FIR8fhVVTUP9FQkD7UlBM/6Wlj/+4uJ7/sLCX/7S0mv+xsJn/oKCQ/6+vmv+hoYv/TEtH/0NCQPtVUk//IR8fhSMhIIVcWVb/SEVF+19dVv/f3sP////e//X10v///93/2di8/1lYWP+eno//5+fG/19dV/9JRkb7W1hV/yMhIYUkJCOFXltZ/0tJSPtdW1f/0NC4/+/u1P/h4cj/8PDV/7++q/8vLC7/e3lw/9fWv/9eXVf/TElJ+15bWf8lJCKEJSQjhF9cWf9LSUf5XVtX/tbVwf/5+OL/6enV//j54v/GxrX/QD0+/42Kgv/d3cr/YF5a/k5LSvlhXlv/JSUjhCkoKIZpZWT/VVJR/WNhXP/V1cT//f3s/+3t3v/8/Or/zc2//01LSf+VlIz/4eDS/2hmYv9YVVT8aWVj/ycmJoIaGRlYSEVE1DYzM8NKSUfP0dHG9/X16P/n59v+7e3g/+jo3f/X2M3+6uve/9bWzPdOTUvNOjg3y0RBQLwPDw8lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); saveItem.onclick =()=> saveSelectionToFile(); var editorItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el); editorItem.id = "content-editorItem"; editorItem.setAttribute("label", "Открыть текст в редакторе"); editorItem.setAttribute("class", "menuitem-iconic"); editorItem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcXFz/Wlpa/1paWv9aWlr/Wlpa/1paWv9aWlr/Wlpa/1paWv9aWlr/Wlpa/1paWv9cXFz/AAAAAAAAAAAAAAAAXFxc//n7+f39/v3+/f79/v7+/v7+/v7+/v7+/f7+/v3+/v78/v7+/P////v////2XV1d/wAAAAAAAAAAAAAAAF9fX//7/fv/FVcX/wBIAv8ASAL/AEgC/wBIAv8ASAL/AEgC/wBIAv8VVxf//f78/2BgYP8AAAAAAAAAAAAAAABhYWH/+/78/zRtNf8otUX/KLVF/yi1Rf8otUX/ZLal/ypBSf9Upcv/NG01//z+/P9kZGT/AAAAAAAAAAAAAAAAZGRk//v+/P9Yh1n/MtB1/zLQdf8y0HX/MtB1/3PZrv9Tpcz/AXfF/2WYiP/8/v3/Z2dn/wAAAAAAAAAAAAAAAGZmZv/8/v3/gKSB/zvdof873aH/O92h/zvdof873aH/Fsj4/wSo6/8Ldr3//f7+/2tra/8AAAAAAAAAAAAAAABpaWn//P/+/6fAqP9C4bn/QuG5/0Lhuf9C4bn/QuG5/1vkxf8GwP7/AXfH/5HD4v9ubm7/AAAAAAAAAAAAAAAAa2tr//z//v/L2sz/lt7S/5be0v+W3tL/lt7S/5be0v+W3tL/Ms34/wSv8P8Abr7/cnJy/wAAAAAAAAAAAAAAAG5ubv/9/v7/6vDq/2Xo3f9l6N3/Zejd/2Xo3f9l6N3/Zejd/2Xo3f8GwP7/AXvJ/1uPsP8AAAAAAAAAAAAAAABwcHD//v////Hu5//l4NT/5eDU/+Xg1P/l4NT/5eDU/+Xg1P/l4NT/XNT5/wS39/8Abr//5PH2GgAAAAAAAAAAc3Nz/////////////v79//7+/f/+/v3//v79//7+/f/+/v3//v79//////8Gwf7/AYPN/xh+wukAAAAAAAAAAHV1df//////7Onh/+Xg1P/l4NT/5eDU/+Xg1P/l4NT/gYGB/4CAgP+AgID/U67L/wS2+P8AbcD/4ezzIAAAAAB4eHj///////39/P///////////////////////Pv6/4CAgP/9/f3//f39/4GBgf4Nwv3+UI+q/4x+d9IAAAAAenp6//////+Wlpf/9/X0/5OTlP/18/L/k5OU//Lv7f+AgID//f39/4GBgf6EhIRd8OXhU8yplP9yWU7/zsjCXH19ff+3t7f/////KLq6uv////8ourq6/////yi6urr/gICA/4GBgf6EhIRdAAAAAAAAAACxqMC5HhmE/wAAdP+AgID/gICA/56entOBgYH/n5+f1oGBgf+fn5/WgYGB/4GBgf+EhIRJAAAAAAAAAAAAAAAA5Of3EAcKj/8AAHP/AAesQQAHrEEAB6xBAAesQQAHrEEAB6xBAAesQQAHrEEAB6xBAAOsQQADrEEAAaxBAAGsQQAArEEAGKxBADisQQ=="); editorItem.onclick =()=> textToEditor(); // устанавливаем где и при каких настройках показывать новые пункты .... addEventListener('popupshowing', e=> { if (e.target != e.currentTarget) return; var sel = gContextMenu.isTextSelected; saveItem.hidden = !sel || !cbu.getPrefs("Save.SelectionToFile"); editorItem.hidden = !sel || !cbu.getPrefs("Save.TextToEditor"); }, false, contextMenu); // удалять новые пункти при изменениях .... addDestructor(()=> { saveItem.remove(); editorItem.remove(); }); })(document.getElementById("contentAreaContextMenu"), document.getElementById("context-sep-open")); // Сохранить или добавить выделенный текст в файл в папке загрузок, если назначена, // иначе на Рабочий стол ............. function saveSelectionToFile() { var line = ".".repeat(62) + "\n"; var hint = "Нажмите чтобы открыть файл"; var prfx = "Выбранный текст сохранен в файл "; var img = self.getAttribute("image"); var desk = Services.dirsvc.get("Desk", Ci.nsIFile); var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); (saveSelectionToFile = async () => { var time = aDate(), url = gBrowser.currentURI.displaySpec; var text = `${line}${getTabLabel()} - ${time}\n${url}\n\n${ gContextMenu.contentData.selectionInfo.fullText }\n\n\n`; try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); var msg = prfx + "в папку " + file.leafName; await IOUtils.makeDirectory(file.path); } catch(ex) { file && Cu.reportError(ex); file = desk.clone(); var msg = prfx + "на рабочий стол"; } file.append(`Save - ${time}.txt`); await IOUtils.writeUTF8(file.path, text, {mode: file.exists() ? "append" : "create"}); var name = "sstf-" + Cu.now(); as.showAlertNotification( gBrowser.selectedTab.image || img, msg, hint, true, "", (s, t) => t == "alertclickcallback" && file.launch(), name ); setTimeout(as.closeAlert, 8e3, name); })(); }; // Создать текстовой файл с выбранным текстом в папке загрузок, если назначена, // иначе на Рабочий стол, и открыть в редакторе ... function textToEditor() { let browserMM = gBrowser.selectedBrowser.messageManager; browserMM.addMessageListener('getSelect', function listener(message) { // создать текст для записи var text = convertFromUnicode("UTF-8", message.data); try {var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {file = Services.dirsvc.get("Desk", Ci.nsIFile);} file.append("TextToEditor.txt"); custombuttonsUtils.writeFile(file.path, text); file.launch(); browserMM.removeMessageListener('getSelect', listener, true); }); browserMM.loadFrameScript('data:,sendAsyncMessage("getSelect", content.document.getSelection().toString())', false); }; // Конвертировать текст в юникод ... function convertFromUnicode(charset, str) { var converter = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter); converter.charset = charset; str = converter.ConvertFromUnicode(str); return str + converter.Finish(); }; // Получить название вкладки без не сохраняемых символов и лишних пробелов ... function getTabLabel() { var label = gBrowser.selectedTab.label; var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " "); return label.substring(0, 50); }; ((main, parts) => this.onmousedown = e => { if (e.button) return; this.onmousedown = null; var df = MozXULElement.parseXULToFragment(` <menugroup orient="vertical"> <menuseparator/> <menuitem class="menuitem-iconic" image="data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAACpElEQVRYCe2XT4hNURzHz8UwwxRGwxTKZPGksCGLWXg2ZmbjlVJqZKMUlpZKycZaycpGZFiIUiQZJcpCYsdi1jSjZIZJM6/n8y3nde6f887p3sbbeH0/5/zO7/zO7/7euefe3jOm4NNqtfrhCnyGnxCjHwQ9hOGClPEuEgzAByirWRYeiL1ikg1k8W18EyC9onkM36GTBpi8BH0gzdE0kiSZoo8XFx+CJZDu0uQK9GUjVvF0bS1gjfnirX+FNf72e+hXgnSdb9CSEcnXTFwv4wcUMUrvVbaAtU7kjGPHmL8LgvrwPaKII/SFWlXodZwsHmI4CdshJ3ZpZ86ZdqxhqCLGiX1pMp9gAcSr+kP0VdTLYt2OOkV8xG4rewvaE7EGO2RzNANrNjKvg9pD31bMDjwj+gWshyLtMMZMwz2oG2NWg6stDLaBtJtG74g39HnxbRpgVctHlPOQ8DxYNdwsdvtc33LYz31J/1UBvuub4Blg3/ayehyka5xiveEOMqib8OcJ8alTn10SLIAF++EqSDdpFkCPpfUx9Eovs44FdP0WpEpnu5frKaiR26orT0Hqi7qD4Bmg7BEWnALpAodqHt8og2MQ0i3iX3cKChbA4hqcAekizTzsA+vD9OotM5UL0K+baRJJTTWgX0jWx9ArrfVO5ibY2v+HsGhXDuM8C9JpDtUcO3WUwUkI6QbxU52CYg7hMAmOg3SORvd1F731YXr1lJnKBcyS5B1IS2rgC1gfplda653MTbC1XT+Ev5yqBh27qrnZSaD3iDN0THZgEEr9MXHSpEzyJXAfpEWaTW5A6hByYmcImCRgAk7AVsb6TbiIXUY9LBqDEZDucI1vMrxwwap/TklRqPd4N3gv7E4Q2A/273kTu6y09hOLL8M69xrW/gOmqWkAQxEbGgAAAABJRU5ErkJggg==" label="Сохранить всю страницу как PNG" value="all"/> <menuitem class="menuitem-iconic" image="data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAC1klEQVRYCb2XO2gUQRjHd+OeMZpCTxIFAz5ATwVtfKDEIpUGES6oiBDUQiWFvU1QEBEbO7HSRohERYIBKxEU9bQSuULC2YiFYIjiKzHKGdffd2SO2b3Z3dnNmfD/zXwz871u5y7HOY7hz/f9drgIb2EKbPQdp/uw1pDSfosEeShDVn0icIdtRTfsSPAQe/0gesbwAL5CnPIcnoc2EP1gKLqu+5jZXhRfCX9ANMzQ0GBUNnzFn6muaazeKH+136KM2XkL8wIQXeMV+GJYMh7yW8R6hCb2MUcq3MBizXNCs23M3wanNvZGaWIvs1HhBoxOc9xsJV6a6HEMf/PRgJRV17FVFjrNbGBGT2ywl7Enb9Qcc11e3YoxuEMJWhfj8p6zO9DjOM5C0LWCRReINjPI/4gXzI2iUBGUCsqDjQLEqVv5mmYCz4BSUfdp0Rf/0X4UldvqCgj+AH0QpbGog6R9qwb4hzRJolFouqwa4PLkY7QtZfVXNP4rKcaqAZKshueQRhtxrkCs5utNGNmEF3kSPJDP+Z7gVuJKYhKdrBqYvctSYrYMDqmugDdjDk7DFdiUoV5DiNUT0KKGsA/DNzhGE2t4OtPYmWX9BCi2nSpH4CycgE7YAHOSdQNU2QWiGwxdIPpIY61wGWrfB8wH4CYMikMSXpKDdp7D9kF0kqHM4x+n0HXsU3AI+yXzcXgHJUgnEhi/DSULZztBVJIB+mAA/sITEFUZBsGTGAXrAigFvg2VT23GI7IBceD8KYjkx8obMeAeeHAQ1otfGPYjGwh0Gg7U1yTZz3o3jMEkfIZLMMxV+MwjkFrhBn5qGTqwK6D0BeMqnKPgFHMadWrO0ry21ExeZQdk+mGipQmY5HPhLoiqDMt1h8AT4JVN4HAbh344CqtYP2SuQhblCOqFbhDdooZcndhmKJiHMjRbr0m41Fw1tItjO6if5zPYWSWxFYIvwJJQmdryH5Bn0+cd0zmPAAAAAElFTkSuQmCC" label="Сохранить видимую часть как PNG" value="page"/> <menuitem class="menuitem-iconic" image="data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAACe0lEQVRYCc2Xv2sUQRTHZ2M0RgNq9M5gVLAxENBOIaRJmhiri2ChpLCy8h+wEsTGf8BK0EZJVBAF04hwoMFGSBDSxP9AohBMTJR4rJ8HzuXt7uwys3scHt/vvDdv3q/dmbu9NcbxieN4AN6DX+BP6IMfOL2CZxwp/U0kGISfYVl8I/CCb8Uo7UjwE2yzUPCB4Q1ch0UYZPEO7IeCDYZGFEVNpD8oPgT/QMEcQ6bBvGz4ij+ijW206Tx/a++xyj95DrkHCh5wBbEonvya8tvP/CVNXELmIt3AAeW5pnQf9bfDqR/ba5qYQjqRbsDpVNHYR7w0MWEcn240IGXtdpyXiWYnG2jpxA79CDY5qHuRbfS2terKM1JMGGP2QY3jTE5CwSiD/EZ8RGbBYWlAi5GsRzkLCW9Bi4bO0skt0HnT+ru0wc671YCtl5GVG+C+Xof1TGZPQ+UGqPMILtHEGDIYnWhAnhfDVG7GcXwVGQTvryHJD5H5LDwFT8BjsAZtjj70efxu8gx5jO4FG+zjvIDTOCyCPMge0sQmTbwocrRrIVsgT0obVySliftFDnotpIElHVigb7F2A3ohZAtmyHgaDsE6tGfgNrpcNcJsM1zh9i8iw8HeBf8UE/MLCjYYJl1VsY9Ai4b2CdkCHaf1FpMVeJErbyKD0Bvk7Xa+jPkTxeX2o4ahcgMUfh9WMundk5x2f/bfNbCl7kFN6VXVukqwqfSkyvekBku9mCQz7c7IF8HnULDDcHR31ZjEIeRAreEwj8MsvAaHmb9F7sAykD+g0wSOQ8FTanwXJZcUrPpySgonlrEezi2sF3AcgPb1vIVeFhK7SvBdeFDXsPpfv6YmkcwUIdAAAAAASUVORK5CYII=" label="Сохранить выбранный элемент как PNG" value="click"/> <menuitem class="menuitem-iconic" image="data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAABrklEQVRYCe2Xu0oDQRSGZ71HU2gkKmhjJQjaWdmk0nRpBR/BdxDEZ/ANFC+FKFiJYCHYiqW+gSSCeEViWL8DzmYyOyvLbkg14f/n/HP2zDkns0uyo5TjE4ZhEe7CR/gB0+CVoDM470iZ3kWCEryHWdFg4UraioEdyOJ9fJtQcMNwAV/gfyhxcRsWoOCNoRYEwTU2PSg+A3+g4JAh1mBSNmIlHhPhC1VNitf+Pi3+7BK2Hwr2+AahiJR8suJGmJ/SxDo2EXYDo0Zk3dBp5LcjqIDvnCbWsE7YDTiDcjqHWS9NVJTj04sGpKy+HcsyMdnNBlpmYoeewCcP6iA2wkCk8otjUlSUUkPQxDSTOShYZJDfiFtsHDwsNaixEI/I5iHhFtSomVm6eQvMvLa+sh163qsGdL2Y9Q34HfA74HfA74DfAb8D9g58Gv+XZUPnlVNGgndDd0peWcow08GkM1N7Rr4AnkBBk2GyfVWpjndCDiJ1Ao4IkKPZBnaW+SW2CbNAXkCrLFyFggNqPItIJAXzHk5J4cQd3vHEwuYFAotQH89b6KyQtQ8s3oFjZg2tfwH5w9EYtWehDwAAAABJRU5ErkJggg==" label="Сохранить выбранную область как PNG" value="clipping"/> </menugroup> `); var menugroup = df.firstChild; menugroup.setAttribute("context", ""); menugroup.handleCommand = e => { var name = _id + ":DataURLReady"; main = main.replace("%MESSAGE_NAME%", name); var urls = {}, configurable = true, enumerable = true; Object.entries(parts).forEach(([key, part]) => Object.defineProperty(urls, key, { configurable, enumerable, get() { var value = `data:;charset=utf-8,({${ encodeURIComponent(main + part) }%0A}).init("${key}")`; Object.defineProperty(urls, key, {configurable, enumerable, value}); return value; }})); var getTabLabel = () => { var label = gBrowser.selectedTab.label; var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " "); return label.substring(0, 50); } var listener = msg => { var fp = makeFilePicker(); fp.init(window.browsingContext, "Сохранить как…", fp.modeSave); fp.appendFilter("", "*.png"); fp.defaultString = getTabLabel() + ".png"; fp.open(res => { if (res == fp.returnCancel || !fp.file) return; var wbp = makeWebBrowserPersist(), args = [ Services.io.newURI(msg.data), document.nodePrincipal, null, null, null, null, fp.file, null ]; //wbp.saveURI.length == 9 && splice(args); var {length} = wbp.saveURI; length >= 9 && splice(args); length == 10 && args.splice(3, 0, null); wbp.saveURI(...args); }); } var splice = arr => { var fox74 = parseInt(Services.appinfo.platformVersion) >= 74; var args = [fox74 ? 7 : 2, 0, fox74 ? Ci.nsIContentPolicy.TYPE_IMAGE : null]; (splice = arr => arr.splice(...args))(arr); } messageManager.addMessageListener(name, listener); addDestructor(() => messageManager.removeMessageListener(name, listener)); (menugroup.handleCommand = e => gBrowser.selectedBrowser.messageManager .loadFrameScript(urls[e.target.value], false) )(e); } menugroup.addEventListener("command", e => menugroup.handleCommand(e)); menuPopup.querySelector('menuitem[label*="ярлык"]').after(df); })(` init(cmd) { cmd.startsWith("c") ? this[cmd].init(this[cmd].parent = this) : this[cmd](); }, capture(win, x, y, width, height) { var canvas = win.document.createElementNS("${xhtmlns}", "canvas"); canvas.width = width; canvas.height = height; var ctx = canvas.getContext("2d"); var tryDraw = ind => { try {ctx.drawWindow(win, x, y, canvas.width, canvas.height, "white")} catch(ex) {canvas.height = ind * canvas.width; tryDraw(--ind);} } tryDraw(17); sendAsyncMessage("%MESSAGE_NAME%", canvas.toDataURL("image/png")); }, `, { all: `all() { var win = content; this.capture(win, 0, 0, win.innerWidth + win.scrollMaxX, win.innerHeight + win.scrollMaxY); }`, page: `page() { var win = content, doc = win.document, body = doc.body, html = doc.documentElement; var scrX = (body.scrollLeft || html.scrollLeft) - html.clientLeft; var scrY = (body.scrollTop || html.scrollTop) - html.clientTop; this.capture(win, scrX, scrY, win.innerWidth, win.innerHeight); }`, clipping: `clipping: { handleEvent(e) { if (e.button) return false; e.preventDefault(); e.stopPropagation(); switch(e.type) { case "mousedown": this.downX = e.pageX; this.downY = e.pageY; this.bs.left = this.downX + "px"; this.bs.top = this.downY + "px"; this.body.appendChild(this.box); this.flag = true; break; case "mousemove": if (!this.flag) return; this.moveX = e.pageX; this.moveY = e.pageY; if (this.downX > this.moveX) this.bs.left = this.moveX + "px"; if (this.downY > this.moveY) this.bs.top = this.moveY + "px"; this.bs.width = Math.abs(this.moveX - this.downX) + "px"; this.bs.height = Math.abs(this.moveY - this.downY) + "px"; break; case "mouseup": this.uninit(); break; } }, init() { var win = {}; Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager) .getFocusedElementForWindow(content, true, win); this.win = win.value; this.doc = this.win.document; this.body = this.doc.body; if (!HTMLBodyElement.isInstance(this.body)) { Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService) .showAlertNotification("${self.image}", ${JSON.stringify(self.label)}, "Не удается захватить!"); return false; } this.flag = null; this.box = this.doc.createElement("div"); this.bs = this.box.style; this.bs.border = "#0f0 dashed 2px"; this.bs.position = "absolute"; this.bs.zIndex = "2147483647"; this.defaultCursor = this.win.getComputedStyle(this.body, "").cursor; this.body.style.cursor = "crosshair"; ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit() { var pos = [this.win, parseInt(this.bs.left), parseInt(this.bs.top), parseInt(this.bs.width), parseInt(this.bs.height)]; this.body.style.cursor = this.defaultCursor; this.body.removeChild(this.box); this.parent.capture.apply(this, pos); ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.removeEventListener(type, this, true)); } }`, click: `click: { getPosition() { var html = this.doc.documentElement; var body = this.doc.body; var rect = this.target.getBoundingClientRect(); return [ this.win, Math.round(rect.left) + (body.scrollLeft || html.scrollLeft) - html.clientLeft, Math.round(rect.top) + (body.scrollTop || html.scrollTop) - html.clientTop, parseInt(rect.width), parseInt(rect.height) ]; }, highlight() { this.orgStyle = this.target.hasAttribute("style") ? this.target.style.cssText : false; this.target.style.cssText += "outline: red 2px solid; outline-offset: 2px; -moz-outline-radius: 2px;"; }, lowlight() { if (this.orgStyle) this.target.style.cssText = this.orgStyle; else this.target.removeAttribute("style"); }, handleEvent(e) { switch(e.type){ case "click": if (e.button) return; e.preventDefault(); e.stopPropagation(); this.lowlight(); this.parent.capture.apply(this, this.getPosition()); this.uninit(); break; case "mouseover": if (this.target) this.lowlight(); this.target = e.target; this.highlight(); break; } }, init() { this.win = content; this.doc = content.document; ["click", "mouseover"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit() { this.target = false; ["click", "mouseover"].forEach(type=> this.doc.removeEventListener(type, this, true)); } }` });
Добавлено Вчера 23:33:33
// Пункт конт.меню закладок "Экспорт папки в HTML" - от Dumby // https://forum.mozilla-russia.org/viewtopic.php?pid=803127#p803127 // + правка от VitalyV под 139+ (async topic => { var imp = m => ChromeUtils.importESModule(`resource://gre/modules/${m}.sys.mjs`)[m]; var exporter = { get dps() { delete this.dps; return this.dps = imp("DownloadPaths"); }, get exporter() { delete this.exporter; return this.exporter = UcfPrefs.dbg.ref("BookmarkExporter", imp("BookmarkHTMLUtils").exportToFile); }, async export(popup) { var win = popup.ownerGlobal, tn = popup.triggerNode; var node, pu = win.PlacesUtils, bm = pu.bookmarks; if (tn.nodeName == "treechildren") node = popup._view.selectedNode; else if (tn.id == "OtherBookmarks") node = {bookmarkGuid: bm.unfiledGuid, title: tn.getAttribute("label")}; else node = tn._placesNode || popup._view.result.root; var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); fp.init(win.browsingContext, win.PlacesUIUtils.promptLocalization.formatValueSync("places-bookmarks-export"), fp.modeSave); fp.appendFilters(fp.filterHTML); fp.defaultString = (node.title ? this.dps.sanitize(node.title) : "untitled") + ".html"; if (await new Promise(fp.open) == fp.returnCancel) return; var tree = await pu.promiseBookmarksTree(pu.getConcreteItemGuid(node), {includeItemIds: true}); tree.title = bm.getLocalizedTitle(tree); var bookmarks = {children: [ {root: "toolbarFolder"}, {root: "unfiledBookmarksFolder"}, {root: "bookmarksMenuFolder", children: [tree], guid: bm.menuGuid} ]}; new this.exporter(bookmarks).exportToFile(fp.file.path); }, observe(doc) { var popup = doc.querySelector("menupopup#placesContext"); if (!popup) return; var menuitem = doc.createXULElement("menuitem"); for(let args of Object.entries({ label: "Экспорт папки в HTML", selection: "folder", "node-type": "folder", "selection-type": "single|none", id: "placesContext_exportFolder", })) menuitem.setAttribute(...args); menuitem.addEventListener("command", e => exporter.export(e.currentTarget.parentElement)); menuitem.exporter = this; doc.getElementById("placesContext_openSeparator").before(menuitem); } }; Services.obs.addObserver(exporter, topic); Services.obs.addObserver(function quit(s, t) { Services.obs.removeObserver(quit, t); Services.obs.removeObserver(exporter, topic); }, "quit-application-granted"); })("chrome-document-loaded");
Добавлено Вчера 23:36:01
To be continued... Как напишете чего нибудь.
Отредактировано _zt (Вчера 23:36:01)
Отсутствует