не понимаю, как этот win.browsingContext прописывать!
.browsingContext нужен только для случая Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker);, посему я придумал такой вариант:
// fp.init(win fp.init((parseInt(Services.appinfo.platformVersion) >= 125 ? win.browsingContext : win)
Жизнь иногда такое выкидывает, что хочется подобрать...
Отсутствует
Dumby
Пока работает, но если не трудно, переделайте пожалуйста JSM'ку в MJS.
// // Открывать ссылки длинным кликом .......... // Dumby: https://forum.mozilla-russia.org/viewtopic.php?pid=797864#p797864 ..... // var delay = 500; // время удержания в мс var inBackground = false; // открывать в фоновой вкладке var relatedToCurrent = false; // открывать рядом с related вкладкой var name = "LPA", EXPORTED_SYMBOLS = [name + "Child", name + "Parent"]; var u = {get timer() { delete this.timer; return this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); }}; inBackground == null ? Object.defineProperty(u, "bg", { get: Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch) .getBoolPref.bind(null, "browser.tabs.loadInBackground") }) : u.bg = inBackground; if (!ChromeUtils.domProcessChild.childID) { var triggeringPrincipal = Cu.getObjectPrincipal(Cu); var LPAParent = class extends JSWindowActorParent { receiveMessage(msg) { var [link, inBackground, ref] = msg.data; this.manager.browsingContext.top .embedderElement.ownerGlobal.gBrowser.addTab(link, { triggeringPrincipal, relatedToCurrent, inBackground, }); } } ChromeUtils.registerWindowActor(name, { allFrames: true, parent: {moduleURI: __URI__}, messageManagerGroups: ["browsers"], child: {moduleURI: __URI__, events: {mousedown: {}}} }); } class LPAChild extends JSWindowActorChild { handleEvent(e) { if (e.type == "mousedown") { if (e.button || e.shiftKey || e.altKey || e.detail != 1) return; var a = e.originalTarget.closest("a[href]"); if (!a || a.href.startsWith("javascript:")) return; this.ctrl = e.ctrlKey; this.initLongPress(a); } else e.type == "click" && !this.link && e.preventDefault(), this.destroyLongPress(); } timeout() { var bg = this.ctrl != u.bg; var data = [this.link.href, bg]; this.sendAsyncMessage("", data); this.link = null; bg || this.destroyLongPress() //|| this.contentWindow.windowUtils.sendMouseEventToWindow("mouseup", -1, -1, 0, 1, 0); // Linux (?) } initLongPress(a) { this.contentWindow.addEventListener("click", this, true); this.contentWindow.addEventListener("dragstart", this, false); u.timer.initWithCallback(() => this.timeout(), delay, u.timer.TYPE_ONE_SHOT); this.link = a; } destroyLongPress() { this.contentWindow.removeEventListener("click", this, true); this.contentWindow.removeEventListener("dragstart", this, false); this.link && u.timer.cancel(); this.link = null; } didDestroy() { this.link && this.destroyLongPress(); } }
«The Truth Is Out There»
Отсутствует
Не понял. Если сделал как написано в первой строке
конвертированного скрипта — значит изменился.
Сделал давно, и уже забыл.
Хорошо, попробую.
Спасибо, на 115esr работают.
ChromeUtils.importESModule("……….mjs"); - это вариант импорта? Типа так -
(async url => ChromeUtils.importESModule("chrome://user_chrome_files/content/custom_scripts/.....mjs"
));
Отсутствует
.browsingContext нужен только для случая Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker);
Тут — да.
Но, в общем случае, наверно стоит сказать,
что, теоретически, где-то ещё,
может использоваться функция окна браузера, именуемая makeFilePicker()
// fp.init(win
fp.init((parseInt(Services.appinfo.platformVersion) >= 125 ? win.browsingContext : win)
Да, суть выражена верно.
Разве что заключение выражения
образующего первый аргумент для fp.init()
в круглые скобки здесь представляется избыточным.
А как сделать, чтоб скрипт SingleHTML.mjs был совместим с FF115+
Не вижу какой-то несовместимости с FF115+
Наоборот, для такой совместимости можно кое-что зачистить, например:
Там, где Services, просто сразу пишем Services.
Метод write() подлежит удалению,
тогда, в save(), как и прокомментировано, «IOUtils.writeUTF8 вместо this.write».
Модуль Timer.jsm в 115 уже сконвертирован в Timer.sys.mjs
можно сразу использовать ChromeUtils.importESModule()
Но, нужен ли этот импорт как таковой?
В методе Succes() мы имеем win,
и с него уже берутся win.FileUtils и win.Downloads
Вот точно так же, вместо setTimeout можно написать win.setTimeout
и ничего не импортировать.
переделайте пожалуйста JSM'ку в MJS
Чисто формально, достаточно заменить парочку
moduleURI: __URI__
на
esModuleURI: Components.stack.filename
и перед class LPAChild extends JSWindowActorChild {
добавить
export {LPAParent};
export
Но сам код какой-то неполноценный,
весьма нуждается в некоем переосмыслении.
Типа так -
(async url => ChromeUtils.importESModule("chrome://user_chrome_files/content/custom_scripts/.....mjs"
));
Так ты определил асинхронную функцию импрота модуля.
Вникуда и внизачем.
Но если добавить перед оконечной точкой с запятой «;»
круглые скобки «()», оператор вызова этой функции,
то импорт произойдёт.
url тоже можно заменить на круглые скобки, раз не используется. (не обязательно)
Vitaliy V.
Ну вот, с кода
@supports selector(:-moz-lwtheme) { * { color: green !important; } } @supports not selector(:-moz-lwtheme) { * { color: red !important; } }
Отсутствует
Чисто формально, достаточно заменить парочку
moduleURI: __URI__
на
esModuleURI: Components.stack.filenameи перед class LPAChild extends JSWindowActorChild {
добавить
export {LPAParent};export
Но сам код какой-то неполноценный,
весьма нуждается в некоем переосмыслении.
Dumby, большое спасибо. Всё работает.
«The Truth Is Out There»
Отсутствует
Dumby
У меня сейчас так
(async url => ChromeUtils.importESModule(url))("chrome://user_chrome_files/content/custom_scripts/....mjs"
);
вы выше написали про встроенный метод, вот я и подумал, что это пример импорта.
Вы как то делали переключалку доп панелей, так она теперь по ПКМ еще и меню вызывает, можете поправить?
Отсутствует
Dumby
Вот эту JSM'ку не поможете переделать в MJS?
// // Кнопка сохраняет страницу с картинками или её часть, если она выделена, в html одним файлом .......... // Dumby: https://forum.mozilla-russia.org/viewtopic.php?pid=796993#p796993 ..... // var name = "UCFSaveSnapshotToHTML", EXPORTED_SYMBOLS = [name + "Child"]; if (!ChromeUtils.domProcessChild.childID) { ChromeUtils.import("resource:///modules/CustomizableUI.jsm").CustomizableUI.createWidget({ label: "Cохранить страницу в html", tooltiptext: "Cохранить страницу в html", id: "ucf_SaveSnapshotToHTML", localized: false, onCreated(btn) { btn._handleClick = click; btn.setAttribute("image", "chrome://devtools/skin/images/tool-application.svg"); } }); var click = async function() { var win = this.ownerGlobal; var bc = win.gBrowser.selectedBrowser.browsingContext; var fbc = win.Services.focus.focusedContentBrowsingContext; if (!fbc || fbc.top.id != bc.id) fbc = bc; var cwg = fbc.currentWindowGlobal; var fp = picker(win, "", Ci.nsIFilePicker.modeSave); var [fileContent, fileName] = await cwg.domProcess.getActor(name).sendQuery("", cwg.innerWindowId); fp.defaultString = fileName; fp.appendFilters(fp.filterHTML); fp.appendFilters(fp.filterAll); await new Promise(fp.open) != fp.returnCancel && IOUtils.writeUTF8(fp.file.path, fileContent, {mode: "overwrite"}); } var picker = (...args) => { ChromeUtils.registerProcessActor(name, { includeParent: true, child: {moduleURI: __URI__} }); return (picker = Components.Constructor( "@mozilla.org/filepicker;1", "nsIFilePicker", "init" ))(...args); } } class UCFSaveSnapshotToHTMLChild extends JSProcessActorChild { receiveMessage(msg) { return snap(WindowGlobalChild.getByInnerWindowId(msg.data).browsingContext.window); } } var snap = mainWin => { var resolveURL = function (url, base) { try { return (new URL(url, base)).href; } 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(/[\.]+/ig, ' ').replace(/[\,]+/ig, ' ').replace(/[\']+/ig, ' ').replace(/^\s+|\s+$/g, '').replace(/\s+/g, '_').slice(0, 100); fileName += (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()) + ']'; })(); if(!/\.html?$/.test(fileName))fileName += '.html'; return [doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->', fileName]; }
«The Truth Is Out There»
Отсутствует
unter_officer на предыдущей странице SingleHTML.mjs сохраняет страницу или выделенное.
Ваш код добавляет пункт меню "Всё или выбранное в единый HTML" в "гамбургер".
Я "гамбургером" не пользуюсь, он у меня скрыт. Поэтому мне это не подходит.
«The Truth Is Out There»
Отсутствует
unter_officer - код универсальный, вы прочитали середину, но не увидели команду вызова в начале!
Добавить в любую кнопку: Cu.getGlobalForObject(Cu)[Symbol.for("SingleHTML")](true,window);
Кроме того, SingleHTML.mjs позволяет 1) сохранять страницу с выбором папки или автоматически.
2) сохранять в любые папки/подпапки, используя имя вкладки или домен. Пишем "Сайт||Фото|" в extensions.user_chrome_files.savedirs:
сохранение Html/Pics. [Загрузки]/"_Html/subdir|_Pics/subdir" «subdir: пусто | 0 имя страницы | 1 домен»
3) пути/имена страниц меняются на лету из кнопки настроек скрипта ucf_hookClicks.js или правкой extensions.user_chrome_files.savedirs.
Vitaliy V. может сможешь решить давнюю проблему скрипта SingleHTML.mjs ?
Этот код не сохраняет SVG-графику, но работает быстрее, чем дополнение SingleFile и сохраняет страницу более компактно.
https://meteo7.ru/forecast/59003
Отредактировано Dobrov (21-03-2024 04:31:28)
Отсутствует
Dobrov
Извините, но мне нужна простая кнопка без всяких наворотов, в которой, в случае необходимости, я хоть что-то могу попытаться понять, а не такой комбайн.
И уж тем более без установки дополнительных скриптов в виде ucf_hookClicks.js или подобных.
«The Truth Is Out There»
Отсутствует
Вы как то делали переключалку доп панелей, так она теперь по ПКМ еще и меню вызывает, можете поправить?
Чтобы далеко не ходить, заменил image на "about:logo".
Сунул код в 126.0a1, жму ПКМ — верхний тулбар переключается.
Но никакого «еще и меню» при этом увидеть не сподобился.
Таким образом, ответ — нет, я не могу поправить то, что не сломано.
Извините, но мне нужна простая кнопка
Да, но сам принцип конвертации от этого же не меняется.
Всё тот же esModuleURI: Components.stack.filename вместо moduleURI: __URI__
Всё та же инструкция export перед class
И ChromeUtils.importESModule("resource:///modules/CustomizableUI.sys.mjs")
вместо ChromeUtils.import("resource:///modules/CustomizableUI.jsm")
EXPORTED_SYMBOLS тогда долой (не обязательно).
Ну, и picker(win.browsingContext вместо picker(win если 125+
Отсутствует
Да, но сам принцип конвертации от этого же не меняется.
Dumby, большое спасибо. Всё получилось.
Вы как то делали переключалку доп панелей, так она теперь по ПКМ еще и меню вызывает, можете поправить?
_zt, вы смогли понять, когда начинает появляться контекстное меню?
Дело в том, что я за последние три недели дважды сталкивался с таким поведением этого скрипта, но причину так и не понял.
То есть, всё нормально работает 5-7-10 дней и вдруг, ни с того ни с сего, появляется контекстное меню. Перезапустишь браузер и опять всё нормально работает.
Отредактировано unter_officer (21-03-2024 12:10:06)
«The Truth Is Out There»
Отсутствует
Dumby
А вы потаскайте кнопку по панелям. UCF последний.
unter_officer
Нет не смог, сначала думал, что после перемещения кнопок.
Я вернулся на свой первоначальный вариант, он рабочий - 16-12-2021 02:14:46
Vitaliy V.
У меня есть одна проблема с вертикальной панелью нового UCF. На ней расположено два растягивающихся интервала - 1. сначала кнопки скриптов и расширений, 2. потом интервал, 3. потом кнопки ATB - вверх и вниз страницы через обычный пробел, 4. потом интервал и 5. еще пара кнопок. Так вот, две последние кнопки от расширений, из первого блока кнопок, постоянно сваливаются вниз, в позицию между кнопками ATB. Происходит это после скрытия/показа панели любым из скриптов выше.
Может сделаете переключалку панелей одной кнопкой, без подобных спецэффектов?
Отсутствует
_zt
Я порылся в своих архивах и нашел вот такой вариант, только не помню где я его взял.
Он почти такой же как этот, за исключением пары строчек.
(async () => CustomizableUI.createWidget({ id: "additional-toolbars-button", label: "Панели", tooltiptext: "ЛКМ: Переключить верт. панель\nПКМ: Переключить доп. панель", localized: false, // defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { btn.setAttribute("context", false); btn.setAttribute("image", "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 16 16'><g><rect x='0' y='0' width='16' height='16' rx='1' ry='1' style='fill:rgb(0, 120, 173);'/><path style='fill:white;' d='M 2.5,1 C 1.7,1 1,1.7 1,2.5 V 13.5 C 1,14.3 1.7,15 2.5,15 H 13.5 C 14.3,15 15,14.3 15,13.5 V 2.5 C 15,1.7 14.3,1 13.5,1 Z M 3,2 H 13 C 13.7,2 14,2.3 14,3 V 13 C 14,13.7 13.7,14 13,14 H 3 C 2.3,14 2,13.7 2,13 V 3 C 2,2.3 2.3,2 3,2 Z M 7.3,3.03 C 7.11,3.03 6.95,3.2 6.95,3.4 V 4.09 C 6.6,4.18 6.28,4.34 5.96,4.5 L 5.45,3.99 C 5.39,3.93 5.3,3.9 5.23,3.9 5.14,3.9 5.04,3.93 4.95,3.99 L 3.99,4.98 C 3.84,5.1 3.85,5.33 3.99,5.49 L 4.5,5.96 C 4.31,6.28 4.18,6.6 4.09,6.95 H 3.37 C 3.17,6.95 3.01,7.11 3.01,7.3 V 8.67 C 3.01,8.89 3.17,9.05 3.37,9.05 H 4.09 C 4.18,9.4 4.31,9.72 4.5,10 L 3.99,10.5 C 3.85,10.7 3.84,10.9 3.99,11 L 4.95,12 C 5.1,12.1 5.33,12.1 5.45,12 L 5.96,11.5 C 6.28,11.7 6.6,11.8 6.95,11.9 V 12.6 C 6.95,12.8 7.11,13 7.3,13 H 8.7 C 8.89,13 9.05,12.8 9.05,12.6 V 11.9 C 9.4,11.8 9.72,11.7 10,11.5 L 10.5,12 C 10.7,12.1 10.9,12.1 11.1,12 L 12,11 C 12.2,10.9 12.2,10.7 12,10.5 L 11.5,10 C 11.7,9.72 11.8,9.4 11.9,9.05 H 12.6 C 12.8,9.05 13,8.89 13,8.67 V 7.3 C 13,7.11 12.8,6.95 12.6,6.95 H 11.9 C 11.8,6.6 11.7,6.28 11.5,5.96 L 12,5.49 C 12.2,5.33 12.2,5.1 12,4.98 L 11.1,3.99 C 10.9,3.86 10.7,3.86 10.5,3.99 L 10,4.5 C 9.72,4.34 9.4,4.18 9.05,4.09 V 3.4 C 9.05,3.2 8.89,3.03 8.7,3.03 Z M 8,6.5 C 8.8,6.5 9.5,7.2 9.5,8 9.5,8.8 8.8,9.5 8,9.5 7.2,9.5 6.5,8.8 6.5,8 6.5,7.2 7.2,6.5 8,6.5 Z'/></g></svg>"); }, 0: "ucf-additional-vertical-bar", 2: "ucf-additional-top-bar", onClick(e) { var id = this[e.button]; id && CustomizableUI.setToolbarVisibility(id, e.target.ownerDocument.querySelector('#' + id).collapsed); } }))();
Отредактировано unter_officer (21-03-2024 20:25:24)
«The Truth Is Out There»
Отсутствует
Я вернулся на свой первоначальный вариант, он рабочий
Насколько понимаю, для ЛКМ эти две строки не нужны. Они только для ПКМ, чтобы меню не появлялось.
e.preventDefault();
e.stopPropagation();
Превент может использоваться для предотвращения появления контекстного
меню при ПКМ (Windows)
Это сказано по ссылке в посте №1381 (выше).
Отсутствует
А вы потаскайте кнопку по панелям.
Потаскал. По этим четырём.
#toolbar-menubar, #TabsToolbar-customization-target,
#nav-bar-customization-target, #PersonalToolbar.
И после каждого такого потаскушества, честно жал ПКМ.
Но никакого контекстного меню увидеть так и не смог.
Тем не менее, любая осознанная модификация кода
всегда только приветствуется, будь то
btn.setAttribute("context", false) или btn.setAttribute("context", "")
или, даже пожёстче, btn.setAttribute("oncontextmenu", "return false");
Отсутствует
И после каждого такого потаскушества, честно жал ПКМ.
Но никакого контекстного меню увидеть так и не смог.
Dumby, да тут и правда мистика какая-то.
Я этим скриптом пользуюсь где-то года два и никогда проблем не возникало, от слова совсем.
Первый раз я словил контекстное меню дней 20-25 назад. Причем я никаких кнопок не таскал, просто при очередном открытии доп.панели появилось меню.
Подумал, ну чего с FF не бывает, перезагрузил браузер и забыл про это. А позавчера вдруг опять словил этот глюк.
А тут оказывается и _zt описывает туже проблему, с тем же скриптом.
Странно как-то всё это. И в тоже время хочется понять, что это было.
P.S. В общем посмотрю как в дальнейшем будет работать скрипт, который я выложил чуть выше.
«The Truth Is Out There»
Отсутствует
Может попробуете у себя?
Не стал, так как вперед попробовал предложенное Dumby btn.setAttribute("oncontextmenu", "return false");
проблема исчезла. Значит дело именно в этой строке.
Еще б разобраться со скачками кнопок на вертикальной панели, после ее скрытия.
Отсутствует
Еще б разобраться со скачками кнопок на вертикальной панели, после ее скрытия.
Вот с этим у меня пока проблем нет.
«The Truth Is Out There»
Отсутствует
Вопрос: чем заменить Services.wm.getMostRecentWindow("navigator:browser") на что-то попроще?
Хочу вызывать функцию globalThis[Symbol…… из другого js-кода без аргументов, но выдаёт ошибку win.gBrowser is undefined, если запускать так:
Cu.getGlobalForObject(Cu)[Symbol.for("SingleHTML")]();
пробовал разные варианты, пока в SingleHTML.mjs вписал такой второй аргумент по-умолчанию:
SingleHTML(to = false, win = this.ownerGlobal || Services.wm.getMostRecentWindow("navigator:browser")) {…
Отсутствует
Тестируйте обновление UCF https://github.com/VitaliyVstyle/Vitali … hromeFiles
есть новая функция
может сможешь решить давнюю проблему скрипта SingleHTML.mjs ?
Этот код не сохраняет SVG-графику
Посмотрел код, вывод такой нужно изображения искать не в клонированном DOM а оригинальном там значения img.width img.height не равны нулю.
Перелапачивать весь код мне лень, чтобы хоть как то работало попробуй изменить функцию encodeImg
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.naturalWidth || img.width || 128; canvas.height = img.naturalHeight || img.height || 128; canvas.getContext('2d').drawImage(img, 0, 0, canvas.width, canvas.height); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; },
У меня есть одна проблема с вертикальной панелью нового UCF
Если в обновленном UCF проблемма присутствует сделайте видео как это происходит
Хотя это может быть связано с вашими кнопками или кодом
Отсутствует
Тестируйте обновление UCF
У меня появляющаяся дополнительная панель перекрывает и верхнюю часть страницы.
Надо-бы брать высоту дополнительной панели под #nav-bar из высоты панели вкладок.
Но хватит одной вертикальной панели, т.к. избыток места на всех мониторах щас тока по ширине.
Отсутствует
Dumby вы делали когда то кнопку Скопировать текст ссылки как в нее добавить иконку
(async (id, url) => { if (location != url) return; var menuitem = document.createXULElement("menuitem"); document.getElementById(id).after(menuitem); var hidden = () => !nsContextMenu.contentData.context.linkTextStr; menuitem.hidden = true; menuitem.render = () => { if (hidden()) return; menuitem.hidden = false; menuitem.id = id + "text"; menuitem.label = "Скопировать текст ссылки"; menuitem.setAttribute("oncommand", "navigator.clipboard.writeText(gContextMenu.linkTextStr);"); delete menuitem.render; menuitem.render(); menuitem.render = () => menuitem.hidden = hidden(); } })("context-copylink", "chrome://browser/content/browser.xhtml");
Отсутствует