Сложные скрипты все починили, вам же надо хотелку. Тоже самое, но с перламутровыми пуговицами.
Мне надо исправить то, что есть.
Но те, кто может исправить, это делать по каким-то своим внутренним убеждениям не хочет. Другие же предлагают альтернативу, которая по тем или иным причинам мне не подходит, или не работает.
Вот и остается, что дербанить Save, и вместо одного фала скрипта, получить два. Да, пока работает, но это извращение какое-то.
«The Truth Is Out There»
Отсутствует
Строка меню в гамбургере "Сохранить страницу | выбранное как HTML"
на замену
// в custom_script.js (async url => ChromeUtils.importESModule(url))( "chrome://user_chrome_files/content/custom_scripts/Actors/AppMenuTbbSaveHTMLChild.mjs"); // или в scriptsbackground: [ // In the background [System Principal] // { func: 'ChromeUtils.importESModule("chrome://user_chrome_files/content/custom_scripts/Actors/AppMenuTbbSaveHTMLChild.mjs");' }, var self, name = "AppMenuTbbSaveHTML"; var {io, focus, obs} = globalThis.Services; export class AppMenuTbbSaveHTMLChild extends JSWindowActorChild { receiveMessage() { return htmlAndName(this.contentWindow); } } ChromeUtils.domProcessChild.childID || ({ init(topic) { ChromeUtils.registerWindowActor(name, { allFrames: true, child: {esModuleURI: Components.stack.filename}, messageManagerGroups: ["browsers"] }); obs.addObserver(self = this, topic); obs.addObserver(function quit(s, t) { obs.removeObserver(quit, t); obs.removeObserver(self, topic); }, "quit-application-granted"); this.handleEvent = e => this[e.type](e); }, observe(win) { win.document.getElementById("appMenu-popup") .addEventListener("popupshowing", this); win.addEventListener("unload", this); }, popupshowing(e) { this.unload(e); var popup = e.target; var btn = popup.ownerDocument.createXULElement("toolbarbutton"); btn.id = "appMenu-ucf-save-html-button"; btn.className = "subviewbutton subviewbutton-iconic"; btn.setAttribute("label", "Страница | выбранное в единый HTML"); btn.setAttribute("image", "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='context-fill' fill-opacity='context-fill-opacity'><path d='M12.225.01H2.656v5.993l.955-.125L3.569.677 11 .76l-.042 4.375h4.275l.041 10.125-12.575.042-.042.708h13.281V3.737L12.225.01zm-.272 1.613 2.384 2.394h-2.384V1.623zm2.93 10.318.062 1.333-2.992.063V8.003h1.328v4l1.601-.063zM4.647 8.002h-.664v1.334h.664v4h1.329v-4h.664V8.003H4.648zm5.313 0-.664 1.074-.664-1.074H7.305v5.334h1.328V10.53l.664 1.073.664-1.073v2.807h1.328V8.003H9.961zm-7.969 2h-.664v-2H0v5.334h1.328v-2h.664v2H3.32V8.003H1.992v2z'/></svg>"); btn.saveHTML = this.saveHTML; popup.querySelector('toolbarbutton[id^="appMenu-print-button"]').before(btn); btn.addEventListener("command", (e) => {e.target.saveHTML();}); }, unload(e) { var win = e.target.ownerGlobal; win.removeEventListener("unload", this); win.document.getElementById("appMenu-popup").removeEventListener("popupshowing", this); win.document.getElementById("appMenu-popup").removeEventListener("command", (e) => {e.target.saveHTML();}); }, async saveHTML() { var win = this.ownerGlobal; var br = win.gBrowser.selectedBrowser; var bc = focus.focusedContentBrowsingContext; if (bc?.top.embedderElement != br) bc = br.browsingContext; var actor = bc?.currentWindowGlobal?.getActor(name); actor && self.save(win, ...await actor.sendQuery("")); }, async save(win, fileContent, fileName) { var fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker); fp.init( !("inIsolatedMozBrowser" in win.browsingContext.originAttributes) ? win.browsingContext : win, "", fp.modeSave); fp.defaultString = fileName; fp.appendFilters(fp.filterHTML); fp.appendFilters(fp.filterAll); var res = await new Promise(fp.open); if (res == fp.returnOK || res == fp.returnReplace) this.write(fp.file.path, fileContent); }, write(path, html) { if (typeof IOUtils == "object") var write = IOUtils.writeUTF8 || IOUtils.writeAtomicUTF8; // Fx 85+ || 82-84 if (!write) { // Fx 79-81 var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm"); write = (path, txt) => OS.File.writeAtomic(path, new TextEncoder().encode(txt)); } (this.write = write)(path, html); } }).init("browser-delayed-startup-finished"); var htmlAndName = async mainWin => { var resolveURL = function (url, base) { try { return io.newURI(url, null, io.newURI(base)).spec; } catch {} }; 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 encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.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((/\.jpe?g/i.test(src) ? '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 = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'}; while (chr = str.charAt(i++)) { ret += meta[chr] || chr; }; return '\x22' + ret + '\x22'; }, 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 (obj.hasOwnProperty(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) ? String(obj) : 'null'; case 'Object': return objToSrc(obj); case 'String': return strToSrc(obj); default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null'; } }; var selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location; var ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/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, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href); return prev + encodeImg(url) + next; }); 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) != '#') 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 (unsafeWin) { if ('$' in unsafeWin) return; var f = doc.createElement('iframe'); f.src = 'about:blank'; f.setAttribute('style', '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 unsafeWin) { if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue; try { str = toSrc(unsafeWin[name]); if (!/\{\s*\[native code\]\s*\}/.test(str)) { script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n')); } } catch (e) {}; }; f.parentNode.removeChild(f); if (script.childNodes.length) this.nextSibling.appendChild(script); }; head.copyScript(win.wrappedJSObject || win); 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))) { var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href); if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url); return prev + url + next; }); style.appendChild(doc.createTextNode(css + '\n')); } } 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('\n')); var doctype = '', dt = doc.doctype; if (dt && dt.name) { doctype += '<!DOCTYPE ' + dt.name; if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22'; if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22'; doctype += '>\n'; }; var fileName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop()); fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).replace(/^\s+|\s+$/g, ''); fileName += (function () { var d = new Date(), z = function(n){return '_' + (n < 10 ? '0' : '') + n}; return z(d.getHours()) + z(d.getMinutes()) + z(d.getSeconds()); })(); if(!/\.html?$/.test(fileName))fileName += '.html'; return [doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->', fileName]; }
Жизнь иногда такое выкидывает, что хочется подобрать...
Отсутствует
contextviewpageinfo.js
Там, где другому пользователю "с большим скрипом, но все же помогли исправить", этот скрипт есть в двух вариантах, на панель и в контекст, работает в 139.
Отсутствует
Виталий выложил новую версию UCF
styleschrome - CssChrome stylesall - CssAllFrame stylescontent - CssContent scriptsbackground - JsBackground scriptschrome - JsChrome scriptsallchrome - JsAllChrome scriptscontent - JsContent domload - DOMContentLoaded типа JsChrome.DOMContentLoaded JsAllChrome.DOMContentLoaded ну и остальное JsChrome.load JsAllChrome.load JsContent.DOMWindowCreated JsContent.DOMContentLoaded JsContent.pageshow
Чтобы перевести рег. выражения из CustomStylesScripts.mjs в строку для записи в prefs.json (новый файл настроек) - откройте консоль, введите RegExp и в конце .source
Например, вводим:
получаем строку
prefs.json вручную править не надо, все делается через страницу настроек.
Добавлено Вчера 19:09:24
И самое главное забыл. Если в начале файла стиля/скрипта добавить строки, например
/** @UCF @param {"prop":"JsAllChrome.load","ucfobj":false,"urlregxp":"^chrome:\\/\\/browser\\/content\\/(?:browser|places\\/(?:bookmarksSidebar|places))\\.xhtml"} @UCF @UCF @param {"prop":"JsContent.pageshow","ucfobj":false,"urlregxp":"^chrome:\\/\\/browser\\/content\\/(?:browser|places\\/(?:bookmarksSidebar|places))\\.xhtml"} @UCF */
то он сразу пропишется на странице настроек в нужном разделе (в данном случае в двух разделах), но что бы его включить все равно мышкой тыкнуть придется и перезагрузится с пересозданием кеша.
Отредактировано _zt (Вчера 19:10:39)
Отсутствует
Там, где другому пользователю
Я там устал читать. Теряю изначальную мысль обсуждения к окончанию.
На предыдущей странице получил рабочий код.
unter_officer, Farby
Спасибо.
Отредактировано xrun1 (Вчера 20:31:26)
Отсутствует
выложил выше полностью рабочий вариант Save
Функции, вроде, работают (те, что проверил). А вот внешний вид не комильфо.
Системная тема. Слева мой вариант сейчас и то, что Вы выложили. https://imgsh.net/i/2c45617ddf
В тёмной теме значки видны. https://imgsh.net/i/95027066e7
Внешний вид, лично меня, пугает. Может, что-то сделал не так? У меня выглядит одинаково и на чистом профиле, и со стилями.
Отсутствует
xrun1
При чем тут иконки, главное что скрипт рабочий, а иконки свои сделайте, я же сделал для себя когда меня те что были в оригинале не устроили.
Можете сравнением перенести измененные строки из моего варианта в старый и будут у вас привычные иконки. В скрипте ссылки на предыдущие версии есть.
А насчет блока с PNG - я хз почему так, может потому что скрипт на 138 не тестировался или потому что вы с лопуховатыми меню сидите. Можно из fulltheme взять menu_max138.css (в 139 menu.css). Все что после /* icons in menu --> */ можете удалить или оставить, но тогда и папка svg понадобится. У меня так выглядит: https://s1.directupload.eu/images/250521/3qgv8tge.png
ps^ все равно все ваши стили для меню в 139 отвалятся, так что можете уже сейчас начинать их выкидывать.
Добавлено Вчера 22:56:02
ps2^ папка svg с пятью иконками понадобится даже если удалить блок начиная с /* icons in menu --> */ А именно: menu-right-icon.svg, checkbox-icon.svg, checkbox-icon-checked.svg, radio-icon.svg и radio-icon-checked.svg
Отредактировано _zt (Вчера 22:57:54)
Отсутствует
_zt
Всё нормально. Это был чистый скрипт. Кривенько вышла группа PNG, но это я забыл о стилях. Приношу извинения. Со стилями всё выровнялось, иконки заменяются (на скрине заменил 2 первые). Чек и радио buttons не потребовались.
https://imgsh.net/i/a1b6791b71
все равно все ваши стили для меню в 139 отвалятся, так что можете уже сейчас начинать их выкидывать
Чёй-то отвалятся? А хоть и отвалятся - починю, первый раз что ли?
Отсутствует