Dumby
Понял в чем было дело. По инструкции для MMPaste.jsm нужно было:
можно добавив в конфигурационный CustomStylesScripts.jsm
в массив UcfStylesScripts.scriptsbackground объект вида
{ func: 'ChromeUtils.import("chrome://user_chrome_files/content/custom_scripts/MMPaste.jsm");' },
а у меня скрипты загружались уже через сам файл custom_script.js
(() => { var loadscript = name => { try { Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${name}`, globalThis, "UTF-8"); } catch(e) {} }; loadscript("./js/kbd_layout.js"); loadscript("./js/MiddleMouse_Paste.js"); })();
Отсутствует
"./js/kbd_layout.js"
Это что ещё за дот-слэш в начале?
В данном случае — совершенно неуместно.
Работает, видимо, только потому, что где-то стоит защита от подобных выкрутасов.
но так же они тоже подгружались, просто как-то не совсем корректно?
kbd_layout.js — это просто скрипт.
Можно грузить так, как у тебя, можно инлайн,
можно любым другим аналогичным способом, так что здесь всё верно.
А Middle Mouse Paste — это модуль (jsm'ка, пока ещё).
Модули не грузят как скрипт. Их импортируют.
Так что здесь неверно, следует импортировать так, как сказано.
Отсутствует
Dumby
А так-то, допустим, если уже установлена какая-либо обезьяна, то скриптов для неё, делающих нечто подобное, должно быть (ну, я так предполагаю) навалом
Да, есть маленько.
В таком случае можно попробовать заменить все browser.storage.sync на browser.storage.local и заново посетить настройки аддона.
Уже не хочу, так как найденный скрипт работает лучше, например на github внешние ссылки корректно открывает в новой вкладке, ну и т.п.
Только вот, можете этот скрипт переделать под ucf, с настройками в самом файле.
Отсутствует
Middle Mouse Paste — это модуль (jsm'ка, пока ещё).
Раз jsm-ки скоро отвалится, то весь UCF и CustomStylesScripts.jsm и CustomStylesScriptsChild.jsm тоже перестанут работать?
var EXPORTED_SYMBOLS = ["MouseImgSaverChild", "MouseImgSaverParent"]; // by Dumby сохранить картинку колёсиком или перетащив вправо; DBL поиск похожих var u = {get it() { // https://forum.mozilla-russia.org/viewtopic.php?pid=793837#p793837 delete this.it; return this.it = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools); }}; for(let name of ["E10SUtils", "PrivateBrowsingUtils"]) ChromeUtils.defineModuleGetter(u, name, `resource://gre/modules/${name}.jsm`); class MouseImgSaverChild extends JSWindowActorChild { handleEvent(e) { // клики мышью if (e.button > 1) return; // только ЛКМ, СКМ var trg = e.explicitOriginalTarget; // dragstart trg.nodeType == Node.ELEMENT_NODE && trg instanceof Ci.nsIImageLoadingContent && this[e.type](trg, e); } handleDragEvent(e) { this[e.type](e); } dragstart(trg, e) { this.trg = trg; this.x = e.screenX; this.y = e.screenY; this.drag("add"); this.handleEvent = this.handleDragEvent; this.checkTextLinkyTool(trg.ownerDocument); } events = ["dragover", "drop", "dragend"]; drag(meth = (delete this.handleEvent, delete this.trg, "remove")) { meth += "EventListener"; var win = this.contentWindow; for(var type of this.events) win[meth](type, this, true); } drop() { this.drag(); } dragover(e) { var {x, y} = this, cx = e.screenX, cy = e.screenY, dx = cx - x, ax = Math.abs(dx), ay = Math.abs(cy - y); if (ax < 10 && ay < 10) return; if (dx < 0 || ax < ay) return this.drag(); this.x = cx; this.y = cy; } dragend(e) { // перетаскивание рисунка var dt = e.dataTransfer, {trg} = this; this.drag(); dt.mozUserCancelled || this.send(trg, e.screenX); // сохранить // dt.mozUserCancelled || this.sendAsyncMessage("dragend", (trg.currentRequestFinalURI || uri).spec); } auxclick(trg) { // клик СКМ trg.matches(":any-link :scope") || this.send(trg); } dblclick(trg) { // ЛКМ trg.matches(":any-link :scope") || this.sendAsyncMessage("dblclick", (trg.currentRequestFinalURI || uri).spec); } send(trg, sx) { var uri = trg.currentURI; if (!uri) return; var doc = trg.ownerDocument; var cookieJarSettings = u.E10SUtils .serializeCookieJarSettings(doc.cookieJarSettings); var referrerInfo = Cc["@mozilla.org/referrer-info;1"] .createInstance(Ci.nsIReferrerInfo); referrerInfo.initWithElement(trg); referrerInfo = u.E10SUtils.serializeReferrerInfo(referrerInfo); var contentType = null, contentDisposition = null; try { var props = u.it.getImgCacheForDocument(doc).findEntryProperties(uri, doc); var cs = Ci.nsISupportsCString; try {contentType = props.get("type", cs).data;} catch {} try {contentDisposition = props.get("content-disposition", cs).data;} catch {} } catch {} this.sendAsyncMessage("", { title: trg.closest("[title]")?.title, url: (trg.currentRequestFinalURI || uri).spec, contentType, referrerInfo, cookieJarSettings, contentDisposition, sx, isPrivate: u.PrivateBrowsingUtils.isContentWindowPrivate(trg.ownerGlobal) }); } checkTextLinkyTool(doc) { if (doc.title || !doc.documentURI.startsWith("moz-extension:")) return; var lab = doc.querySelector("body > label#lblFrom:first-child")?.textContent; if (lab) doc.title = lab.slice(0, lab.lastIndexOf("(")); } } if (!ChromeUtils.domProcessChild.childID) { ChromeUtils.registerWindowActor("MouseImgSaver", { allFrames: true, parent: {moduleURI: __URI__}, messageManagerGroups: ["browsers"], child: {moduleURI: __URI__, events: {auxclick: {capture: true}, dblclick: {capture: true}, dragstart: {capture: true}}} }); var wref, titles = Object.create(null); var data = Object.assign(Object.create(null), { "browser.download.dir": {type: "String", get set() { var win = wref.get(), {prefs, dirsvc} = win.Services var {DownloadPaths, FileUtils} = win; var map = val => DownloadPaths.sanitize(val); win.Downloads.getList(win.Downloads.ALL).then(list => list.addView({ onDownloadChanged(download) { if (!download.stopped) return; var {url} = download.source, title = titles[url]; if (!title) return; delete titles[url]; if (!download.succeeded) return; var file = FileUtils.File(download.target.path), {leafName} = file; var ext = leafName.slice(leafName.lastIndexOf(".")); var newName = map(title) + ext, {parent} = file; var newFile = parent.clone(); newFile.append(newName); try { newFile.createUnique(file.NORMAL_FILE_TYPE, file.permissions); file.renameTo(parent, newFile.leafName); download.target.path = newFile.path; download.refresh(); } catch {} } })); Object.defineProperty(this, "set", {get() { try {var dir = prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {var dir = dirsvc.get("DfltDwnld", Ci.nsIFile);} var arr = prefs.getStringPref("ucf.savedirs", "_Web||_Images|0").split('|').slice(2, 4); // подпапки в [Загрузках]: нет | папка графики | имя вкладки | домен arr[1] = (arr[1]) ? wref.get().gBrowser.selectedTab.label.slice(0, 64).replace(/ \| — Mozilla Firefox|[\\\/?*\"'`]+/g,'').replace(/\s+/g,' ').replace(/[|<>]+/g,'_').replace(/:/g,'։').trim() : ""; // имя вкладки arr.map(map).forEach(dir.append); dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777); return dir.path; }}); return this.set; }}, "browser.download.folderList": {type: "Int", set: 2}, "browser.download.useDownloadDir": {type: "Bool", set: true} }); var MouseImgSaverParent = class extends JSWindowActorParent { receiveMessage(msg) { var win = msg.target.browsingContext.topChromeWindow, {name} = msg; if (name) return this[name](win, msg.data); var {url, contentType, contentDisposition, sx, title, isPrivate, referrerInfo, cookieJarSettings} = msg.data; if (sx && sx > win.mozInnerScreenX + win.innerWidth) return; if (title) titles[url] = title; wref = Cu.getWeakReference(win); var p = win.Services.prefs; 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 {win.internalSave( url, null, // document null, // file name contentDisposition, contentType, false, // do not bypass the cache null, // filepicker title key null, // chosen data u.E10SUtils.deserializeReferrerInfo(referrerInfo), u.E10SUtils.deserializeCookieJarSettings(cookieJarSettings), win.document, // initiating doc true, // skip prompt for where to save null, // cache key isPrivate, win.document.nodePrincipal );} finally { for(var pref in data) data[pref].val === null ? p.clearUserPref(pref) : p[`set${data[pref].type}Pref`](pref, data[pref].val); } } dblclick(win, imgURL) { var gb = win.gBrowser, index = gb.selectedTab._tPos + 1; gb.selectedTab = gb.addTrustedTab('https://yandex.ru/images/search?rpt=imageview&url=' + imgURL, {index}); } } }
Отсутствует
Раз jsm-ки скоро отвалится, то весь UCF и CustomStylesScripts.jsm и CustomStylesScriptsChild.jsm тоже перестанут работать?
ESM модули вместо них, несложная конвертация модулей jsm --> mjs, у меня уже работает на FF 103
Отредактировано Vitaliy V. (06-07-2022 14:46:22)
Отсутствует
с настройками в самом файле
Что-то мне в голову не влезает то, что там навёрнуто,
не смог понять как это должно работать, сколько ни пытался.
Могу попробовать просто процитировать, без осознания,
но вряд ли из этого что-то выйдет.
var cfg = { rootzone: false, parent: true, neighbor: true, host: true, child: true, background: false, insert: true, setParent: true }; var name = "ExternalLinkNewtaber"; if (ChromeUtils.domProcessChild.childID) { var empty = new RegExp("^$"); var click = function(e) { e.preventDefault(); e.stopImmediatePropagation(); this.ownerGlobal.windowGlobalChild .getActor(name).sendAsyncMessage("", this.href); } var EXPORTED_SYMBOLS = [name + "Child"]; var ExternalLinkNewtaberChild = class extends JSWindowActorChild { actorCreated() { this.pp = this.ph = empty; var host = this.contentWindow.location.hostname; // quot =========================================================================== let parent = host.replace(/^[^.]*\./, '').replace(/\./g, '\\\.'); host = host.replace(/\./g, '\\\.'); if (cfg.parent){this.pp = new RegExp(`^${parent}$`);} // abc.x => ^abc\.x$ if (cfg.neighbor){ const flat = host.replace(/\..*/, ''); if (cfg.parent){ this.pp = new RegExp(`[^(${flat}\.)]?${parent}$`); // abc.x + *.abc.x => [^(w\.)]?abc\.x$ } else {this.pp = new RegExp(`[^(${flat})]?\.${parent}$`);} // *.abc.x => [^(w)]?\.abc\.x$ } if (!cfg.rootzone && parent.search(/\..+\./) == -1){this.pp = empty;} if (cfg.host){this.ph = new RegExp(`^${host}$`);} // w.abc.x => ^w\.abc\.x$ if (cfg.child){ if (cfg.host){ this.ph = new RegExp(`(.+\.)?${host}$`); // w.abc.x + *.w.abc.x => (.+\.)?w\.abc\.x$ } else {this.ph = new RegExp(`.+\.${host}$`);} // *.w.abc.x => .+\.w\.abc\.x$ } // =========================================================================== quot } handleEvent(e) { for(var a of this.document.getElementsByTagName("a")) if (a.hasAttribute("href")) { var {host} = a; !host || empty.test(host) || this.pp.test(host) || this.ph.test(host) || a.addEventListener("click", click); } } } } else { var {background, insert, setParent} = cfg; var arg = insert || setParent, fg = !background; var EXPORTED_SYMBOLS = [name + "Parent"]; var ExternalLinkNewtaberParent = class extends JSWindowActorParent { receiveMessage(msg) { var opts, gb = this.browsingContext.topChromeWindow.gBrowser; if (arg) { opts = {}; var st = gb.selectedTab; if (insert) opts.index = st._tPos + 1; if (setParent) opts.ownerTab = st; } var tab = gb.addTrustedTab(msg.data, opts); if (fg) gb.selectedTab = tab; } } ChromeUtils.registerWindowActor(name, { allFrames: true, matches: ["*://*/*"], messageManagerGroups: ["browsers"], parent: {moduleURI: __URI__}, child: {moduleURI: __URI__, events: {load: {capture: true}}} }); }
просьба переделать в JS модуль сохранения картинок ClickPicSave.jsm
Сейчас пока не очень удобно, поскольку лисьи jsm'ки ещё не сконвертированы.
А вообще это не очень сложно (и, нужен Firefox 103+).
Сам модуль импортируется не ChromeUtils.import() а ChromeUtils.importESModule()
При регистрации ChromeUtils.register{Window, Process}Actor() указываем не moduleURI а esModuleURI
Свойства __URI__ в этих модулях нет, подойдёт Components.stack.filename
Вместо var EXPORTED_SYMBOLS = []; используем инструкцию export
Ну, вобщем, как-то так:
export {MouseImgSaverChild, MouseImgSaverParent}; var u = {get it() { delete this.it; return this.it = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools); }}; ["E10SUtils", "PrivateBrowsingUtils"].forEach(name => Object.defineProperty(u, name, { configurable: true, enumerable: true, get() { var url = `resource://gre/modules/${name}.`; try {var exp = ChromeUtils.importESModule(url + "sys.mjs");} catch {exp = ChromeUtils.import(url + "jsm");} delete this[name]; return this[name] = exp[name]; } })); class MouseImgSaverChild extends JSWindowActorChild { handleEvent(e) { // клики мышью if (e.button > 1) return; // только ЛКМ, СКМ var trg = e.explicitOriginalTarget; // dragstart trg.nodeType == Node.ELEMENT_NODE && trg instanceof Ci.nsIImageLoadingContent && this[e.type](trg, e); } handleDragEvent(e) { this[e.type](e); } dragstart(trg, e) { this.trg = trg; this.x = e.screenX; this.y = e.screenY; this.drag("add"); this.handleEvent = this.handleDragEvent; this.checkTextLinkyTool(trg.ownerDocument); } events = ["dragover", "drop", "dragend"]; drag(meth = (delete this.handleEvent, delete this.trg, "remove")) { meth += "EventListener"; var win = this.contentWindow; for(var type of this.events) win[meth](type, this, true); } drop() { this.drag(); } dragover(e) { var {x, y} = this, cx = e.screenX, cy = e.screenY, dx = cx - x, ax = Math.abs(dx), ay = Math.abs(cy - y); if (ax < 10 && ay < 10) return; if (dx < 0 || ax < ay) return this.drag(); this.x = cx; this.y = cy; } dragend(e) { // перетаскивание рисунка var dt = e.dataTransfer, {trg} = this; this.drag(); dt.mozUserCancelled || this.send(trg, e.screenX); // сохранить // dt.mozUserCancelled || this.sendAsyncMessage("dragend", (trg.currentRequestFinalURI || uri).spec); } auxclick(trg) { // клик СКМ trg.matches(":any-link :scope") || this.send(trg); } dblclick(trg) { // ЛКМ trg.matches(":any-link :scope") || this.sendAsyncMessage("dblclick", (trg.currentRequestFinalURI || uri).spec); } send(trg, sx) { var uri = trg.currentURI; if (!uri) return; var doc = trg.ownerDocument; var cookieJarSettings = u.E10SUtils .serializeCookieJarSettings(doc.cookieJarSettings); var referrerInfo = Cc["@mozilla.org/referrer-info;1"] .createInstance(Ci.nsIReferrerInfo); referrerInfo.initWithElement(trg); referrerInfo = u.E10SUtils.serializeReferrerInfo(referrerInfo); var contentType = null, contentDisposition = null; try { var props = u.it.getImgCacheForDocument(doc).findEntryProperties(uri, doc); var cs = Ci.nsISupportsCString; try {contentType = props.get("type", cs).data;} catch {} try {contentDisposition = props.get("content-disposition", cs).data;} catch {} } catch {} this.sendAsyncMessage("", { title: trg.closest("[title]")?.title, url: (trg.currentRequestFinalURI || uri).spec, contentType, referrerInfo, cookieJarSettings, contentDisposition, sx, isPrivate: u.PrivateBrowsingUtils.isContentWindowPrivate(trg.ownerGlobal) }); } checkTextLinkyTool(doc) { if (doc.title || !doc.documentURI.startsWith("moz-extension:")) return; var lab = doc.querySelector("body > label#lblFrom:first-child")?.textContent; if (lab) doc.title = lab.slice(0, lab.lastIndexOf("(")); } } if (!ChromeUtils.domProcessChild.childID) { var esModuleURI = Components.stack.filename; ChromeUtils.registerWindowActor("MouseImgSaver", { allFrames: true, parent: {esModuleURI}, messageManagerGroups: ["browsers"], child: {esModuleURI, events: {auxclick: {capture: true}, dblclick: {capture: true}, dragstart: {capture: true}}} }); var wref, titles = Object.create(null); var data = Object.assign(Object.create(null), { "browser.download.dir": {type: "String", get set() { var win = wref.get(), {prefs, dirsvc} = win.Services var {DownloadPaths, FileUtils} = win; var map = val => DownloadPaths.sanitize(val); win.Downloads.getList(win.Downloads.ALL).then(list => list.addView({ onDownloadChanged(download) { if (!download.stopped) return; var {url} = download.source, title = titles[url]; if (!title) return; delete titles[url]; if (!download.succeeded) return; var file = FileUtils.File(download.target.path), {leafName} = file; var ext = leafName.slice(leafName.lastIndexOf(".")); var newName = map(title) + ext, {parent} = file; var newFile = parent.clone(); newFile.append(newName); try { newFile.createUnique(file.NORMAL_FILE_TYPE, file.permissions); file.renameTo(parent, newFile.leafName); download.target.path = newFile.path; download.refresh(); } catch {} } })); Object.defineProperty(this, "set", {get() { try {var dir = prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {var dir = dirsvc.get("DfltDwnld", Ci.nsIFile);} var arr = prefs.getStringPref("ucf.savedirs", "_Web||_Images|0").split('|').slice(2, 4); // подпапки в [Загрузках]: нет | папка графики | имя вкладки | домен arr[1] = (arr[1]) ? wref.get().gBrowser.selectedTab.label.slice(0, 64).replace(/ \| — Mozilla Firefox|[\\\/?*\"'`]+/g,'').replace(/\s+/g,' ').replace(/[|<>]+/g,'_').replace(/:/g,'։').trim() : ""; // имя вкладки arr.map(map).forEach(dir.append); dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777); return dir.path; }}); return this.set; }}, "browser.download.folderList": {type: "Int", set: 2}, "browser.download.useDownloadDir": {type: "Bool", set: true} }); var MouseImgSaverParent = class extends JSWindowActorParent { receiveMessage(msg) { var win = msg.target.browsingContext.topChromeWindow, {name} = msg; if (name) return this[name](win, msg.data); var {url, contentType, contentDisposition, sx, title, isPrivate, referrerInfo, cookieJarSettings} = msg.data; if (sx && sx > win.mozInnerScreenX + win.innerWidth) return; if (title) titles[url] = title; wref = Cu.getWeakReference(win); var p = win.Services.prefs; 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 {win.internalSave( url, null, // original url null, // document null, // file name contentDisposition, contentType, false, // do not bypass the cache null, // filepicker title key null, // chosen data u.E10SUtils.deserializeReferrerInfo(referrerInfo), u.E10SUtils.deserializeCookieJarSettings(cookieJarSettings), win.document, // initiating doc true, // skip prompt for where to save null, // cache key isPrivate, win.document.nodePrincipal );} finally { for(var pref in data) data[pref].val === null ? p.clearUserPref(pref) : p[`set${data[pref].type}Pref`](pref, data[pref].val); } } dblclick(win, imgURL) { var gb = win.gBrowser, index = gb.selectedTab._tPos + 1; gb.selectedTab = gb.addTrustedTab('https://yandex.ru/images/search?rpt=imageview&url=' + imgURL, {index}); } } }
Отсутствует
не работает, или я не знаю как его прописать
Да обычная jsm'ка, как и другие. То есть ChromeUtils.import("урл");
Чтоб совсем уж не работало это вряд ли. Откровенно "внешние" ссылки
должны открываться в новой вкладке, во всяком случае те, которые в есть в html сразу.
А вот конфигурация — вообще непонятно, ну кроме background, insert, setParent.
Отсутствует
Dumby
Точно, забыл ее в лоадере проверить. Работает не хуже чем в обезьяне, на первый взгляд. Спасибо.
Я не знаю чего он там учесть пытался, без parent: true host: true она работает плохо, все подряд открывает в новой, в том числе и когда здесь по имени щелкаешь. Возможно последовательно опции добавлял, да так и оставил, у меня все как по умолчанию.
Отредактировано _zt (07-07-2022 07:12:41)
Отсутствует
Привет мастерам!
Ребят, пару кнопок из шапки задействовал, работают прекрасно, спасибо большое создателям. Единственное, что поменял бы на свой вкус - сами иконки кнопок. Подскажите как можно это сделать, пожалуйста!
Отсутствует
ez7pac
Свою иконку конвертируете в формат base64. Онлайн-конвертеров в сети полно.
Ищете в коде кнопки что-то типа такого
Это иконка из , можно взять то, что между двойными кавычками, вставить в адресную строку и посмотреть. Заменяете на свой код.
Или смотрите уже сконвертированные иконки в коде типа
Механизм такой же - заменяете на свой код то, что между двойными кавычками.
Отсутствует
xrun1
Ага, понял, спасибо!
Такого нет:
Т.е. иконка не дефолтная, а своя.
Вот такое есть
С конвертацией и заменой разберусь, думаю. Но тогда другой вопрос возник - а нельзя вместо кода иконки, вот этого "непонятного", воткнуть в код кнопки дефолтную иконку? Я там (chrome://browser/skin/browser.css) глянул - подходящие для меня есть.
Если можно, то как это сделать, чтобы не накосячить?
Отсутствует
ez7pac
Ещё можно так:
#ID кнопки> .toolbarbutton-icon { list-style-image: url("chrome://browser/skin/history.svg"); }
Win7
Отсутствует
xrun1
Спасибо за консультацию. Воткнул дефолтную иконку вместо авторской - кнопка работает, все нормально.
kokoss
Спасибо, но это для меня слишком сложно, я дуб в этих делах. Заморачиваюсь максимум раз в два, а то и три года, когда приходится переходить на более свежую версию браузера. То, что помнил после прошлого перехода, давно вылетело из головы
+++
Ребят, теперь еще вопрос возник. Я за эти кнопки зацепился потому, что Add Toolbars Buttons на 102-й версии работает не полноценно, а к трем кнопкам оттуда привык, не хочется их терять. Две нашел в этой теме - выпадающее меню расширений и перезапуск браузера. Осталась кнопка менеджера паролей, но тут ее не вижу. Может плохо искал? Не поможете с ней?
Или, возможно, автор таки собирается обновить расширение, так мне намного проще, честно сказать. Он, по моему, тоже в этой теме бывает. Виталий, если не ошибаюсь.
+++
ЗЫ. Еще забыл. Вот кнопка меню расширений. Как можно переназначить клавиши? Т.е. , в ней менеджер дополнений открывается СКМ, а мне было бы привычней ПКМ.
try {(() => { var id = "ucf-aom-button", label = "Дополнения", tooltiptext = "ЛКМ: Меню дополнений\nShift+ЛКМ: Меню дополнений + открыть менеджер\nСКМ: Открыть менеджер дополнений", img = "chrome://mozapps/skin/extensions/extension.svg", show_version = true, show_description = true, user_permissions = true, show_hidden = true, show_disabled = true, enabled_first = true, exceptions_listset = new Set([ ]); exceptions_type_listset = new Set([ ]); if (!("AddonManager" in this)) ChromeUtils.defineModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm"); if (!("GlobalManager" in this)) XPCOMUtils.defineLazyGetter(this, "GlobalManager", () => ChromeUtils.import("resource://gre/modules/ExtensionParent.jsm").ExtensionParent.GlobalManager); var extensionOptionsMenu = { get alertsService() { delete this.alertsService; return this.alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); }, get clipboardHelp() { delete this.clipboardHelp; return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, get exceptions_type_listarr() { delete this.exceptions_type_listarr; var arr = ["extension", "theme", "locale", "dictionary"]; if (!exceptions_type_listset.size) return this.exceptions_type_listarr = arr; return this.exceptions_type_listarr = arr.filter(type => !exceptions_type_listset.has(type)); }, populateMenu: async function(e) { var popup = e.target, doc = e.view.document; var addons = await AddonManager.getAddonsByTypes(this.exceptions_type_listarr); var addonsMap = new WeakMap(), setAttributesMenu = (mi, addon, extension) => { var permissions, uuid, props = { label: `${addon.name}${show_version ? ` ${addon.version}` : ""}`, class: "menuitem-iconic", tooltiptext: `${(show_description && addon.description) ? `${addon.description}\n` : ""}ID: ${addon.id}${addon.isActive && (uuid = extension?.uuid) ? `\nUUID: ${uuid}` : ""}${(user_permissions && (permissions = addon.userPermissions?.permissions)?.length) ? `\nРазрешения: ${permissions.join(", ")}` : ""}\n${addon.optionsURL ? "\nЛКМ: Настройки" : ""}\nCtrl+ЛКМ: Копировать ID${uuid ? "\nShift+ЛКМ: Копировать UUID" : ""}${addon.creator?.url ? "\nCtrl+Shift+ЛКМ: Автор" : ""}${addon.homepageURL ? "\nСКМ: Домашняя страница" : ""}${!addon.isBuiltin ? "\nCtrl+СКМ: Просмотр источника" : ""}\nShift+СКМ: Просмотр источника во вкладке\nПКМ: Включить/Отключить${(!addon.isSystem && !addon.isBuiltin) ? "\nCtrl+ПКМ: Удалить" : ""}`, }; for (let p in props) mi.setAttribute(p, props[p]); if (addon.iconURL) mi.setAttribute("image", addon.iconURL); var cls = mi.classList; addon.isActive ? cls.remove("ucf-disabled") : cls.add("ucf-disabled"); addon.optionsURL ? cls.remove("ucf-notoptions") : cls.add("ucf-notoptions"); addon.isSystem ? cls.add("ucf-system") : cls.remove("ucf-system"); cls.add(`ucf-type-${addon.type}`); }; addons.filter(a => !(a.iconURL || "").startsWith("resource://search-extensions/")).sort((a, b) => { var ka = `${(enabled_first ? a.isActive ? "0" : "1" : "")}${a.type || ""}${a.name.toLowerCase()}`; var kb = `${(enabled_first ? b.isActive ? "0" : "1" : "")}${b.type || ""}${b.name.toLowerCase()}`; return (ka < kb) ? -1 : 1; }).forEach(addon => { if (!exceptions_listset.has(addon.id) && (!addon.hidden || show_hidden) && (!addon.userDisabled || show_disabled)) { let extension = GlobalManager.extensionMap.get(addon.id), mi = doc.createXULElement("menuitem"); setAttributesMenu(mi, addon, extension); mi._Addon = addon; mi._Extension = extension; popup.append(mi); addonsMap.set(addon, mi); } }); var click = (e) => { this.handleClick(e); }; popup.addEventListener("click", click); var listener = { onEnabled: addon => { var mi = addonsMap.get(addon); if (mi) setAttributesMenu(mi, addon, mi._Extension); }, onDisabled: addon => { listener.onEnabled(addon); }, onInstalled: addon => { var extension = GlobalManager.extensionMap.get(addon.id), mi = doc.createXULElement("menuitem"); setAttributesMenu(mi, addon, extension); mi._Addon = addon; mi._Extension = extension; popup.prepend(mi); addonsMap.set(addon, mi); }, onUninstalled: addon => { var mi = addonsMap.get(addon); if (mi) { mi.remove(); addonsMap.delete(addon); } }, }; AddonManager.addAddonListener(listener); popup.addEventListener("popuphiding", (e) => { AddonManager.removeAddonListener(listener); popup.removeEventListener("click", click); addonsMap = null; while (popup.hasChildNodes()) popup.firstChild.remove(); }, { once: true }); }, handleClick: function(e) { var win = e.view, mi = e.target; if (!("_Addon" in mi) || !("_Extension" in mi)) return; var addon = mi._Addon, extension = mi._Extension; switch (e.button) { case 0: if (e.ctrlKey && e.shiftKey) { if (addon.creator?.url) win.gBrowser.selectedTab = this.addTab(win, addon.creator.url); } else if (e.ctrlKey) { this.clipboardHelp.copyString(addon.id); try { this.alertsService.showAlertNotification(`${img}`, "ID в буфере обмена!", addon.id, false); } catch(e) {} } else if (e.shiftKey) { if (extension?.uuid) { this.clipboardHelp.copyString(extension.uuid); try { this.alertsService.showAlertNotification(`${img}`, "UUID в буфере обмена!", extension.uuid, false); } catch(e) {} } } else if (addon.isActive && addon.optionsURL) this.openAddonOptions(addon, win); win.closeMenus(mi); break; case 1: if (e.ctrlKey) { if (!addon.isBuiltin) this.browseDir(addon); } else if (e.shiftKey) this.browseDir(addon, win); else if (addon.homepageURL) win.gBrowser.selectedTab = this.addTab(win, addon.homepageURL); win.closeMenus(mi); break; case 2: if (!e.ctrlKey) { let endis = addon.userDisabled ? "enable" : "disable"; if (addon.id == "screenshots@mozilla.org") Services.prefs.setBoolPref("extensions.screenshots.disabled", !addon.userDisabled); else if (addon.id == "webcompat-reporter@mozilla.org") Services.prefs.setBoolPref("extensions.webcompat-reporter.enabled", addon.userDisabled); addon[endis]({ allowSystemAddons: true }); } else if (!addon.isSystem && !addon.isBuiltin && Services.prompt.confirm(win, null, `Удалить ${addon.name}?`)) addon.uninstall(); break; } }, openAddonOptions: function(addon, win) { switch (addon.optionsType) { case 5: win.BrowserOpenAddonsMgr(`addons://detail/${encodeURIComponent(addon.id)}/preferences`); break; case 3: win.switchToTabHavingURI(addon.optionsURL, true); break; } }, browseDir: function(addon, win) { try { if (!win) { let file = Services.io.getProtocolHandler("file") .QueryInterface(Ci.nsIFileProtocolHandler) .getFileFromURLSpec(addon.getResourceURI().QueryInterface(Ci.nsIJARURI).JARFile.spec); if (file.exists()) file.launch(); } else win.gBrowser.selectedTab = this.addTab(win, addon.getResourceURI().spec); } catch (e) {} }, addTab: function(win, url, params = {}) { params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); params.relatedToCurrent = true; return win.gBrowser.addTab(url, params); }, }; CustomizableUI.createWidget({ id: id, type: "custom", label: label, tooltiptext: tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function(doc) { var btn = doc.createXULElement("toolbarbutton"), win = doc.defaultView, props = { id: id, label: label, tooltiptext: tooltiptext, type: "menu", class: "toolbarbutton-1 chromeclass-toolbar-additional", }; for (let p in props) btn.setAttribute(p, props[p]); btn.addEventListener("click", (e) => { if (e.button == 0) { if (e.shiftKey) win.BrowserOpenAddonsMgr(); } else if (e.button == 1) win.BrowserOpenAddonsMgr(); }); var mp = doc.createXULElement("menupopup"); mp.id = `${id}-popup`; mp.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); }); mp.addEventListener("contextmenu", (e) => { e.preventDefault(); e.stopPropagation(); }); mp.addEventListener("popupshowing", (e) => { extensionOptionsMenu.populateMenu(e); }); btn.append(mp); var btnstyle = "data:text/css;charset=utf-8," + encodeURIComponent(` #${id}, #${id}-popup menuitem { list-style-image: url("${img}") !important; } #${id}-popup menuitem::after { display: -moz-box !important; content: "" !important; height: 16px !important; width: 16px !important; padding: 0 !important; border: 1px solid rgb(0, 116, 232) !important; border-radius: 0 !important; background-repeat: no-repeat !important; background-position: center !important; background-size: 16px !important; background-color: rgb(0, 116, 232) !important; background-image: url("${checked}") !important; opacity: 1 !important; } #${id}-popup menuitem.ucf-disabled::after { border-color: currentColor !important; background-color: transparent !important; background-image: none !important; opacity: .6 !important; } #${id}-popup menuitem.ucf-disabled > label, #${id}-popup menuitem.ucf-notoptions > label { opacity: .6 !important; } #${id}-popup menuitem.ucf-system > label { text-decoration: underline !important; text-decoration-style: dotted !important; } #${id}-popup menuitem > label { margin-inline-end: 0 !important; } #${id}-popup menuitem > .menu-accel-container { display: -moz-box !important; padding: 4px !important; margin: 0 !important; opacity: 1 !important; } #${id}-popup menuitem > .menu-accel-container .menu-iconic-accel { display: -moz-box !important; margin: 0 !important; height: 8px !important; width: 8px !important; border-radius: 4px !important; background-color: transparent !important; opacity: 1 !important; font-size: 0 !important; } #${id}-popup menuitem.ucf-type-dictionary > .menu-accel-container .menu-iconic-accel { background-color: rgb(227, 27, 93) !important; } #${id}-popup menuitem.ucf-type-locale > .menu-accel-container .menu-iconic-accel { background-color: rgb(48, 172, 55) !important; } #${id}-popup menuitem.ucf-type-theme > .menu-accel-container .menu-iconic-accel { background-color: rgb(219, 106, 0) !important; } `); try { win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET); } catch (e) {} return btn; }, }); })();} catch (e) {}
Отредактировано ez7pac (13-07-2022 17:59:29)
Отсутствует
Я за эти кнопки зацепился потому, что Add Toolbars Buttons на 102-й версии работает не полноценно,
Win7
Отсутствует
Add Toolbars Buttons на 102-й версии работает не полноценно, а к трем кнопкам оттуда привык, не хочется их терять.
Всё работает, спасибо Dumby, №340
Отсутствует
kokoss
voqabuhe
Ай, спасибо! Значит, не нашел. А из расширения перехожу на домашнюю страницу - 404.
+++
Все, разобрался, отредактировал, расширение заработало как положено.
Спасибо за помощь и консультации еще раз, парни!
+++
Опять 25
С кодом для отключения проверки не разберусь никак! Ткните носом, плиз, где он прячется.
Отредактировано ez7pac (13-07-2022 19:19:24)
Отсутствует
В папке установки , в файле config.js.
В папке браузера? И добавлял этот код - https://forum.mozilla-russia.org/viewtopic.php?pid=800159#p800159, и заменял то, что там было - пофиг
Отсутствует
В папке браузера? И добавлял этот код - https://forum.mozilla-russia.org/viewtopic.php?pid=800159#p800159, и заменял то, что там было - пофиг
Инструкция, с описанием куда добавить: https://forum.mozilla-russia.org/viewtopic.php?id=70326
Win7
Отсутствует
kokoss
Оба файла присутствуют по дефолту. Портабл родом отсюда - https://github.com/wvxwxvw/LibPortablePlus
И config.js, и config-prefs.js (код там правильный) есть и лежат на своих местах. Так дописывал код в config.js к имеющемуся, и заменял - эффекта нет - "работа дополнения не была проверена...". Хотя само расширение работает нормально. В 91-й версии никаких предупреждений нет. Вот и чешу репу - что я делаю не так...
Отсутствует
Осталась кнопка менеджера паролей, но тут ее не вижу. Может плохо искал? Не поможете с ней?
/* https://forum.mozilla-russia.org/viewtopic.php?pid=788786#p788786 есть для окна куков другой код, запоминает положение окна https://forum.mozilla-russia.org/viewtopic.php?pid=788799#p788799 */ try {CustomizableUI.createWidget({ label: "ПАРОЛИ/КУКИ", tooltiptext: "ЛКМ: См. ПАРОЛИ\nПКМ: См. КУКИ", id: "ucf-logins-sitedata", localized: false, onCreated(btn) { btn._handleClick = btn.oncontextmenu = e => this.view(e, btn.ownerGlobal); btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAADo0lEQVR42pWUf0idVRzGP+d4vVfbFFeu/SErV1bUBiI6ivajUcEiiiBoaTEEo7Lsj2W1P6Q2xFiL0Qp0q/7pB2GLijZGG/aDSPuBxBbkGm3O7IJuRJmod+t6r+89p+d9b6TWhu17uefe97zn+5zn+3yfcwznCz9e7c2S5fr3i8Ec5yLCzHtq96txdGNZSoE+a8mxgRG2cx/t5uTFAd7u17GOPrbl9oDdibGjdPgrtOIlwd7TtI2aN8zCbGcBn/dJJb7LdtP2n1XP+Q8Z+a2St5bVzVPmlPInBVKHnw/Y7tdr7OE7yjhksnM2sTxrHJ/7Sr0booIbaDSDeC9pjec8EQH6TdRzgofNALddqBR/HWNU84B5n0+j533EWcYKKZwyjZyZz/BJ36XxVkrpZPDnOMUJy4xmCmOSsxDSZwPKrtylhjXwqtnvR3mGczxBwOXEbIaU+4YMLWYNSUPTcA9pt1GLFQEUFek3fBCQE6oNp204NUXvWIUfrGsmyS6mNV/bo+F6bfg0HP/gNHWsMmwaDCKLhGGtwwks5mweKcS2OawrYOJchz9Y08ExsjgxTweOm/pNhhvD3YPE+B0JPv5kh2HzcEogi0XOEQtfCcxGdKeEWRqRDfHHf7/L71hjuYSDpFVFThQvXeGpOkqaJa6YPsPXt/xqaBhWoitRWi4PmFH2oja6K3fyYLILm20hq6ljRzb6vfUZyvmS6bi2KTBk0lpaDtVbHGO9hhOf/WFoTKaEIoaiFdO6YMZhF9fyzvIBGpJ3knOHKEy8RnfFY35AJnexVn1d1FAn/81MezUklC3Bn7wSAk4JpYRpARa5nMovJBv7iKnE/ZS508RzX/B2ZYP/kRcFslXsQq3lQSeHSPrY338X5Yaoyq6eZZgVYFyAQUbtLe7lK1fP0p+2cvTuVn9SzNK05hsVWslGWNhgMqqqwB0W10fN1fLkPxo6aRjHRQydPUV31bWRgb+3ezT/ePiGbNwSm56Uo/qY4GW1bUgbeXMvo7PG3jw8KcDSqMs2ZBgaMPYm+65qkoFfV+IjODVBFlUFlkTwgrmGNi4QAkz6yHuhP0JtstYwemaV79xQBdkDcnq+UiffpYNmbuY9Y0jNOZQS0My5HJpGugTYooLziamz8EP/Wn/4oRpm4p1IAbl4QjrtNytp+n/XV/PYSpV5GaYge2RvSXHtt/JaGVsk9O6o1BKekuC7FwKbfx/++3Y5oINvdFBzGsvpN+uj07tg/AUtF37/2LRsMgAAAABJRU5ErkJggg=="); }, view(e, win) { if (e && (e.ctrlKey || e.shiftKey)) return; var uri = win.gBrowser.selectedBrowser.currentURI; try { var url = win.ReaderMode.getOriginalUrl(uri.spec); if (url) uri = Services.io.newURI(url); } catch {} try {var tld = Services.eTLD.getBaseDomain(uri);} catch {var tld = uri.asciiHost;} e ? this.viewCookies(tld, win) : this.viewPasswords(tld, uri, win); return false; }, viewPasswords(tld, uri, win) { try { tld = Services.io.newURI(`${uri.scheme}://${tld}`).displayHost; } catch {} var params = new win.URLSearchParams({...(tld && {filter: tld})}); var gb = win.gBrowser; var separator = params.toString() ? "?" : ""; var tabToSelect, url = `about:logins${separator}${params}`; for (var tab of gb.visibleTabs) { var {spec} = tab.linkedBrowser.currentURI; if (!spec.startsWith("about:logins")) continue; if (spec != url) { var pending = tab.hasAttribute("pending"); if (pending) gb.selectedTab = tab; tab.linkedBrowser.loadURI( url, {triggeringPrincipal: tab.nodePrincipal} ); if (pending) return; } tabToSelect = tab; break; } gb.selectedTab = tabToSelect || gb.addTrustedTab(url); }, async viewCookies(tld, window) { var notFound, wt = "Browser:SiteDataSettings"; var url = "chrome://browser/content/preferences/dialogs/siteDataSettings.xhtml"; var win = Services.wm.getMostRecentWindow(wt); if (!win) { notFound = true; await window.SiteDataManager.updateSites(); win = window.openDialog(url, wt, "chrome,dialog=no,centerscreen,resizable"); var e = await new Promise(resolve => win.windowRoot.addEventListener("DOMContentLoaded", resolve, {once: true}) ); win = e.target.ownerGlobal; } var doc = win.document, de = doc.documentElement; de.setAttribute("persist", "screenX screenY width height"); if (notFound) { de.setAttribute("windowtype", wt); var xs = Services.xulStore, {id} = de; var x = xs.getValue(url, id, "screenX"); var y = xs.getValue(url, id, "screenY"); x && de.setAttribute("screenX", x); y && de.setAttribute("screenY", y); } var sb = doc.querySelector("#searchBox"); sb.inputField.setUserInput(tld); setTimeout(() => sb.editor.selection.collapseToEnd(), 50); notFound || win.focus(); } });} catch(ex) {Cu.reportError(ex);}
Добавлено 13-07-2022 22:02:50
А какие кнопки не работают в расширении и что с ним не так?
Сообщения на форуме видел, но у меня работает. Может, не теми кнопками пользуюсь, вот и прошу конкретики.
Отредактировано xrun1 (13-07-2022 22:03:24)
Отсутствует