в
136.0 выдает вот такую ошибку
Error sanitizing historyFormDataAndDownloads TypeError: item is undefined
Ну, в 136, Object.keys(Sanitizer.items).join("\n");
(типа список возможностей) выдаёт
cache
cookies
offlineApps
history
formdata
downloads
sessions
siteSettings
openWindows
pluginData
browsingHistoryAndDownloads
cookiesAndStorage
Таким образом, наверно,historyFormDataAndDownloads
browsingHistoryAndDownloads
Отсутствует
Есть такой скрипт ucf_contextmenu_openwith.js:
(this.contextmenuopenwith = { //на основе forum.mozilla-russia.org/viewtopic.php?pid=809407#p809407 _eventListeners: [], init(that) { var Hint = "Открыть выделенный текст или ссылку\nПравый клик | Shift - ссылка из буфера", selector = "#context-sep-selectall", // вставить пункты меню перед этим селектором attricon = true, // false: без иконок атрибут "image" submenu = false, /* подменю программ для ссылок name: 'Prefix или пусто|Имя', path: 'путь', Необязательно: icon: 'иконка', args: `опции через пробел "в двойных кавычках считаются одной"`, roll: аналог args, выполняется средним кликом (+Shift: адрес из буфера) hint: подсказка в строке меню для roll %OpenURI выделенный текст или URL страницы/ссылки */ OS_linux = [ { name: 'Ссылку в |плеер VLC', path: '/usr/bin/vlc', icon: 'moz-icon://stock/vlc?size=menu' }, { name: 'Скачать в |Yt-dlp', path: '/usr/bin/konsole', //предпочтительно .mp4 hevc|h265|avc|h264 <=1080 args: `--hold --workdir ~/Загрузки -e "yt-dlp -f %quotbv[height<=1080][ext=mp4][vcodec~='^(hevc|h265|avc|h264)']+ba[ext~='(aac|m4a)']/best[height<=1080][ext=mp4]/best[height<=1080]/best%quot %OpenURI"`, hint: 'скачать в FFmpeg', roll: `--hold --workdir ~/Загрузки -e "ffmpeg -i %OpenURI -c copy -f mp4 video.mp4"`, icon: 'moz-icon://stock/youtube-dl?size=menu'} ], OS_win = [ { name: 'Ссылку в |плеер MPC-BE', path: 'D:\\[Programs]\\MPC-BlackEdition\\mpc-be64.exe', args: `"%OpenURI"` }, { name: 'Ссылку в |плеер PotPlayer', path: 'D:\\[Programs]\\PotPlayer\\PotPlayerMini64.exe', args: `"%OpenURI"` }, { name: 'Открыть в |Microsoft Edge', path: 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe', args: `"microsoft-edge:%OpenURI%OpenURI "`} ], OS_macosx = [ { name: '|Видео загрузчик yt-dlp', path: '/usr/bin/osascript', args: `-e "tell app %quotTerminal%quot to activate do script %quotrun ytdlp '%OpenURI' || { yt-dlp '%OpenURI' && say сделано;}; exit%quot"`, hint: 'опции --downloader ffmpeg…', roll: `-e "tell app %quotTerminal%quot to activate do script %quotyt-dlp --downloader ffmpeg --hls-use-mpegts '%OpenURI' && say сделано; exit%quot"`, icon: 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4TC0AAAAvD8ADEA8QEfMfQlFt29T7MhRBFNGIJsqLYPhnqEJE/8P8772bd+qxBfOVCwIA' }, { name: 'Ссылку в |плеер MPV', path: '/usr/bin/osascript', //FIX only mpv args: `-e "tell app %quotTerminal%quot to do script %quotopen -b io.mpv '%OpenURI' --args '--ytdl-format=bestvideo[height<=?720][fps<=?30]+bestaudio/best[height<=?720][fps<=?30]'; exit%quot" -e "tell app %quotSystem Events%quot to set visible of process %quotTerminal%quot to false"`, hint: 'скачать книгу в Elib2Ebook', roll: `-e "tell app %quotTerminal%quot to do script %quotcd ${Downloadir()}; Elib2EbookCli --additional -f epub -u '%OpenURI' && say сделано; exit%quot"`, icon: 'moz-icon://file:///System/Applications/Automator.app?size=16' }, { name: 'Открыть в браузере |Safari', path: '/usr/bin/open', args: `-b com.apple.Safari -u "%OpenURI"`, icon: 'chrome://devtools/skin/images/browsers/safari.svg'}, ]; try {var arrOS = eval('OS_'+ AppConstants.platform);} catch {return}; if (!arrOS || !arrOS.length) return; var addListener = (...arr) => { var elm = arr[0]; if (!elm) return; elm.addEventListener(...arr.slice(1)); this._eventListeners.push(arr); }; var readFromClipboard = (url = "") => { try { let trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable); trans.init(docShell.QueryInterface(Ci.nsILoadContext)); trans.addDataFlavor("text/plain"); let {clipboard} = Services, data = {}; clipboard.getData(trans, clipboard.kGlobalClipboard); trans.getTransferData("text/plain", data); if (data.value) url = data.value.QueryInterface(Ci.nsISupportsString).data; } catch {} return url; }; var getCurrentURL = (url = gBrowser.selectedBrowser.currentURI.displaySpec) => { try { let _url = ReaderMode.getOriginalUrl(url); if (_url) url = Services.io.newURI(_url).displaySpec; } catch {} return url; }; var getURL = key => { return !key ? gContextMenu?.linkURI?.displaySpec || getCurrentURL() : readFromClipboard(); }; var popup = document.querySelector("#contentAreaContextMenu"); var create = e => { if (e.target != popup || gContextMenu.webExtBrowserType === "popup" || (gContextMenu.isContentSelected || gContextMenu.onTextInput) && !gContextMenu.linkURL) return; popup.removeEventListener("popupshowing", create); this._eventListeners.shift(); var contextsel = popup.querySelector(`:scope > ${selector}`) || popup.querySelector(":scope > menuseparator:last-of-type"); var fragment = document.createDocumentFragment(); if (arrOS.length == 1) submenu = false; var itemId = 0; arrOS.forEach(item => { let name = item.name.split('|'), {path, args, roll, hint} = item; if (!name || !path) return; if (submenu) name.shift(); name = name.join(''); if (hint) hint = '\nКолёсико: '+ hint; var icon = item.icon || `moz-icon://file://${path}?size=16`; let mitem = document.createXULElement("menuitem"); mitem.id = `ucf-menu-open-with-${++itemId}`; mitem.className = "menuitem-iconic ucf-menu-open-with"; mitem.setAttribute("label", `${name}`); mitem.apppath = path; mitem.roll = roll; mitem.tooltipText = Hint + (hint || ""); mitem.appargs = args; if (attricon) mitem.setAttribute("image", icon); fragment.append(mitem); addListener(mitem, "command", function command(e) { try { let trg = e.currentTarget, args = trg.appargs, file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); if (trg.roll && e.button == 1) args = trg.roll; file.initWithPath(trg.apppath); if (!file.exists()) return; if (file.isExecutable()) { let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess); process.init(file); if (args) { let openuri = false; args = args.split(/\s+(?=(?:[^"]*"[^"]*")*[^"]*$)/).map(sp => { if (/%OpenURI/.test(sp)) { openuri = true; return sp.replace(/^["']+|["']+$/g, "").replace(/%quot/g, '"').replace(/%OpenURI/g, getURL(e.shiftKey || e.button == 2)); } return sp.replace(/^["']+|["']+$/g, "").replace(/%quot/g, '"'); }); if (!openuri) args.push(getURL(e.shiftKey || e.button == 2)); } else args = [getURL(e.shiftKey || e.button == 2)]; process.runwAsync(args, args.length); } else file.launch(); } catch {} }); }); var funcpopupshowing, funcpopuphiding; if (submenu) { let rootmenu = {}; if (fragment.children.length) { rootmenu = document.createXULElement("menu"); rootmenu.id = "ucf-menu-open-with-submenu"; rootmenu.className = "menu-iconic ucf-menu-open-with"; rootmenu.setAttribute("label", "Открыть ссылку в…"); let mpopup = document.createXULElement("menupopup"); mpopup.append(fragment); rootmenu.append(mpopup); contextsel.before(rootmenu); } funcpopupshowing = () => { rootmenu.hidden = false; }; funcpopuphiding = () => { rootmenu.hidden = true; }; } else { contextsel.before(fragment); funcpopupshowing = () => { for(let arr of this._eventListeners) { if (arr[2].name === "command") arr[0].hidden = false; } }; funcpopuphiding = () => { for(let arr of this._eventListeners) { if (arr[2].name === "command") arr[0].hidden = true; } }; } addListener(popup, "popupshowing", function popupshowing(e) { if (e.target != popup || gContextMenu.webExtBrowserType === "popup" || (gContextMenu.isContentSelected || gContextMenu.onTextInput) && !gContextMenu.linkURL) return; funcpopupshowing(); }); addListener(popup, "popuphiding", function popuphiding(e) { if (e.target != popup) return; funcpopuphiding(); }); }; addListener(popup, "popupshowing", create); setUnloadMap("contextmenuopenwith", this.destructor, this); function Downloadir(c = Ci.nsIFile){ var d = Services.dirsvc.get("DfltDwnld",c); try {var d = Services.prefs.getComplexValue("browser.download.dir",c);} catch {} return d.path; } }, destructor() { for(let arr of this._eventListeners) arr.shift().removeEventListener(...arr); } }).init(this);
и возникла проблема с "Открыть в Microsoft Edge", например при открытии https://4pda.to/ ссылка передается в таком виде - https://4pda.to/https://4pda.to/
Можно это как-то поправить?
Отсутствует
https://4pda.to/ ссылка передается в таком виде - https://4pda.to/https://4pda.to/
Ага, а если вместо прописанного
microsoft-edge:%OpenURI%OpenURI
написать
microsoft-edge:%OpenURI%OpenURI%OpenURI
то будет передаваться
microsoft-edge:https://4pda.to/https://4pda.to/https://4pda.to/
Отсутствует
egorsemenov06 пишетв
136.0 выдает вот такую ошибку
Error sanitizing historyFormDataAndDownloads TypeError: item is undefinedНу, в 136, Object.keys(Sanitizer.items).join("\n");
(типа список возможностей) выдаётcache
cookies
offlineApps
history
formdata
downloads
sessions
siteSettings
openWindows
pluginData
browsingHistoryAndDownloads
cookiesAndStorageТаким образом, наверно,
historyFormDataAndDownloads
browsingHistoryAndDownloads
СПАСИБО БОЛЬШОЕ!!!!Работает!
Отсутствует
Farby
Опять или снова отвалился код "Экспорт папки в HTML".
Вы уже помогали... раз и два.
custom_script.js
(async topic => { var imp = (m, n = m) => Cu.import(`resource://gre/modules/${m}.jsm`, {})[n]; var exporter = { get dps() { delete this.dps; return this.dps = imp("DownloadPaths"); }, get exporter() { delete this.exporter; return this.exporter = imp("BookmarkHTMLUtils", "BookmarkExporter"); }, 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( !("inIsolatedMozBrowser" in win.browsingContext.originAttributes) ? win.browsingContext : win, 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 || doc.createElement).call(doc, "menuitem"); for(var args of Object.entries({ label: "Экспорт папки в HTML", selection: "folder", "node-type": "folder", "selection-type": "single|none", id: "placesContext_exportFolder", oncommand: "exporter.export(parentNode);" })) menuitem.setAttribute(...args); 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");
Отсутствует
P.S. Я помню, что сами Вы не пользуетесь UCF.
зато у меня есть лодырь от Dumby
И код выглядит так:
// skip 1st line (async topic => { var imp = (m, n = m) => ChromeUtils.importESModule(`resource://gre/modules/${m}.sys.mjs`)[n]; //var {_uc} = ChromeUtils.importESModule("chrome://userchromejs/content/userChrome.mjs"); var exporter = { get dps() { delete this.dps; return this.dps = imp("DownloadPaths"); }, get exporter() { delete this.exporter; //return this.exporter = _uc.dbg.ref("BookmarkExporter", imp("BookmarkHTMLUtils").exportToFile); 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, win.PlacesUIUtils.getString("EnterExport"), fp.modeSave); fp.init( !("inIsolatedMozBrowser" in win.browsingContext.originAttributes) ? win.browsingContext : win, 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 || doc.createElement).call(doc, "menuitem"); for(var args of Object.entries({ label: "Экспорт папки в HTML", selection: "folder", "node-type": "folder", "selection-type": "single|none", id: "placesContext_exportFolder", //oncommand: "exporter.export(parentNode);" })) menuitem.setAttribute(...args); menuitem.exporter = this; menuitem.addEventListener("command", e => { e.target.exporter.export(e.target.parentNode); }); 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");
Жизнь иногда такое выкидывает, что хочется подобрать...
Отсутствует
Farby
Посмотрите, пожалуйста, ещё раз Async Run Applications 2021.9.7-mod_117+.
Новая версия не интересна. Здесь 3 кнопки, мне так удобнее. Настройки в расширении отвалились давно: есть и их видно, а изменить не получается. Но можно было руками поправить файл в профиле async_run_applications.json.
Теперь кнопок не видно, если вызвать настройки - пусто, хотя файл есть.
Можно что-то сделать или всё, кирдык?
Отсутствует
зато у меня есть лодырь от Dumby
И код выглядит так:
Экспорт папки в HTML
Плиз, поправьте для работы с Aris-t2. Сейчас пункт есть, диалог сохранения есть, но сохранение не происходит.
Отсутствует
Плиз, поправьте для работы с Aris-t2.
Все остальные лоадеры свободны как мухи в самолёте, причина банальна больше нет Cu.inport. Вот что по этому поводу Dumby писсал.
Зато есть дебагер в UCF, когда Aris прикрутит, тогда можно посмотреть будет.
Можно что-то сделать или всё, кирдык?
Ну пока кирдыка на горизонте ли я не видовал, берём тестируем отписываемся.
Отредактировано Farby (07-03-2025 14:08:39)
Жизнь иногда такое выкидывает, что хочется подобрать...
Отсутствует
берём тестируем отписываемся
Работает, даже настройки. Спасибо!
Dumby
Сломалась кнопка для боковой панели (второй спойлер), 4+ года работала. Можно поправить, привык?
Отредактировано xrun1 (07-03-2025 14:35:22)
Отсутствует
Farby
Помогите, пожалуйста. Не получается запустить вашу кнопку Reload user{Chrome, Content}
https://forum.mozilla-russia.org/viewto … 97#p806797
Куда надо помещать код?
Отсутствует
Garalf
mjs - https://forum.mozilla-russia.org/viewto … 97#p806797
scriptsbackground: [ // В фоне [System Principal] { func: 'ChromeUtils.importESModule("chrome://user_chrome_files/content/путь/UCF_userChrome_Reloader.mjs")', },
Отредактировано _zt (08-03-2025 00:12:03)
Отсутствует
Сломалась кнопка для боковой панели (второй спойлер)
O, кнопочка мне понравилась, решил себе оставить
// ==UserScript== // @name Sidebar button Toggle state // @namespace sidebar-button@forum.mozilla-russia.org // @description sidebar button // @include main // @author Dumby // @version 27-08-2020 00:22:15 // @homepageURL https://forum.mozilla-russia.org/viewtopic.php?pid=784391#p784391 // ==/UserScript== try {(lst => { var type = "MozBeforeInitialXULLayout", sidebar = document.getElementById("sidebar"); sidebar.addEventListener(type, lst, true); document.addEventListener("unload", () => sidebar.removeEventListener(type, lst, true), {once: true}); })({ handleEvent(e) { var parent = e.target.querySelector(":root:is(#bookmarksPanel,#history-panel) > #sidebar-search-container"); parent && this.insert(parent); }, insert(parent) { var df = parent.ownerGlobal.MozXULElement.parseXULToFragment(` <hbox> <toolbarbutton id="sidebar-button-toggle-state" tooltiptext="ЛКМ: Закрыть все папки верхнего уровня
((Ctrl или Shift) и ЛКМ) или СКМ: Закрыть все папки
ПКМ: Открыть все папки" /> </hbox> `); var sidebarImg = 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 48 48"><g><path d="M 2.438,0 C 1.087,0 0,1.088 0,2.438 V 45.56 C 0,46.91 1.087,48 2.438,48 H 45.56 C 46.91,48 48,46.91 48,45.56 V 2.438 C 48,1.088 46.91,0 45.56,0 Z" style="fill:%230078ad;fill-opacity:1;" /><path style="opacity:0.25;fill:%23000000;" d="M 5,11 V 39.5 L 13.5,48 H 45.5 C 47,47.9 47.9,47 48,45.5 V 13.6 L 43.4,9 10,8 Z"/><path style="fill:%23ffffff;" d="M 10.9,6 H 37.1 C 41.6,6 45,9.48 45,13.7 V 34.3 C 45,38.7 41.6,42 37.1,42 H 10.9 C 6.51,42 3,38.7 3,34.3 V 13.7 C 3.03,9.48 6.54,6.03 10.9,6 Z M 39.7,34.3 V 13.7 C 39.7,12.3 38.7,11.1 37.1,11.1 H 24 V 36.8 H 37.1 C 38.7,36.8 39.7,35.8 39.7,34.3 Z M 8.25,34.3 C 8.25,35.8 9.42,36.8 10.9,36.8 H 21.4 V 11.1 H 10.9 C 9.42,11.1 8.25,12.3 8.25,13.7 Z" /><path style="fill:%23ffffff;" d="M 12,16.3 H 17.7 C 18.4,16.3 19,15.7 19,15 19,14 18.4,13.4 17.7,13.4 H 12 C 11.2,13.4 10.6,14 10.6,15 10.6,15.7 11.2,16.3 12,16.3 Z M 12,21.8 H 17.7 C 18.4,21.8 19,21.3 19,20.5 19,19.6 18.4,19 17.7,19 H 12 C 11.2,19 10.6,19.6 10.6,20.5 10.6,21.3 11.2,21.8 12,21.8 Z M 14.9,27.4 H 17.7 C 18.4,27.4 19,26.8 19,26.1 19,25.1 18.4,24.6 17.7,24.6 H 14.9 C 14,24.6 13.4,25.1 13.4,26.1 13.4,26.8 14,27.4 14.9,27.4 Z" /></g></svg>'; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution("sidebar-button-toggle-state", Services.io.newURI(sidebarImg)); (this.insert = pn => { pn.prepend(pn.ownerDocument.importNode(df, true)); var btn = pn.firstChild.firstChild; btn.toggleState = this.toggleState; btn.tree = pn.nextSibling; btn.style = "-moz-appearance: none !important; min-width: 2.5em !important; min-height: 2em !important"; btn.style.listStyleImage = 'url("resource://sidebar-button-toggle-state")'; btn.style.MozContextProperties = "fill"; btn.style.setProperty("fill", "currentColor"); btn.addEventListener("click", event => {event.target.toggleState(event);}); })(parent); }, toggleState(e) { if (this.start) return; this.start = true; var {view} = this.tree; var close = e.button < 2; var closeAll = e.button == 1 || e.button == 0 && (e.ctrlKey || e.shiftKey); var index = view.rowCount, i; if (closeAll) for(i = index; i >= 0; i--) view.isContainer(i) && view.isContainerOpen(i) && view.toggleOpenState(i); else for(i = 0; i < index; i++) { if (!view.isContainer(i) || view.isContainerOpen(i) != close) continue; view.toggleOpenState(i); index = view.rowCount; if (close) continue; var node = view._rows[i]; if (node.type == node.RESULT_TYPE_QUERY) i += node.childCount; } this.start = false; } });} catch(ex) {Cu.reportError(ex);}
Жизнь иногда такое выкидывает, что хочется подобрать...
Отсутствует
Farby
Работает, спасибо!
Поведение кнопки немого сломалось, давно уже. Не принципиально, конечно.
При закрытии ЛКМ или СКМ фокус улетает на позицию ниже. Т.е. если была панель закладок --> какая-то папка или закладка, фокус сместится на меню закладок. Если меню закладок --> какая-то папка или закладка --> фокус на другие закладки.
Если это сложно, и так сойдёт.))
Отсутствует
Странное дело, только в этом скрипте в тултипе не работает перенос строки по \n
Либо вы не правильно задали вопрос, либо я чего-то не понимаю. В этом скрипте я не нахожу вхождения "\n"...
PS: Но parseXULToFragment не понимает "\n", ну так то так, на всякий случай.
Жизнь иногда такое выкидывает, что хочется подобрать...
Отсутствует
А это?


Оно же так и было в первоисточнике, не пашет, решил, что какой-то символ кракозябрнулся, заменил на \n. Но это уже в прошлом, т.к. не все опции работают, то сократил тултип до одной строки.
Отсутствует
fuchsfan
У меня работает.
Но оно мне не надо, так как есть
Которые и в истории и в sidebartabs работают
Для вашей версии скрипты AutoClose...
https://github.com/alice0775/userChrome … master/136
Отредактировано _zt (08-03-2025 22:54:44)
Отсутствует
_zt
https://forum.mozilla-russia.org/viewto … 87#p812487
Не удалось запустить MJS-ку. Поясните пожалуйста, код запуска надо помещать
в custom_scripts.js?
Отсутствует
Не удалось запустить MJS-ку.
Есть такая запись, не знаю, правильная или нет.
В папке Firefox использовать config.js с правками от Dumby для активации .JSM, .MJS, кажется, от 09.11.2023, ссылки, увы не имею (или добавить в существующий config.js, где уже имеются антиподписной код).
В папке \chrome\ создать папку \widget\ и в неё поместить файлы скриптов .JSM, .MJS. Их не нужно нигде дополнительно прописывать для активации.
Очистить startupCache.
Добавлено 09-03-2025 10:44:00
Для вашей версии
скрипты AutoClose...
Спасибо.
Отредактировано fuchsfan (09-03-2025 10:44:00)
Отсутствует
С обновлением до FF136, обнаружил некоторые проблемки:
пришло время обносвить сам user_chrome_files на последнюю версию, старый категорически не захотел работать. Всё вроде прописал/подтянул, но скрипт SwitchKeyboardLayout не хочет работать.
// Назначить клавишу F8 для исправления раскладки введенного текста // код SwitchKeyboardLayout в файле custom_script.js try {(id => { var listener = { get obj() { var obj = document.getElementById(id); if (obj) obj = obj.linkedObj; else { obj = Cu.import("resource:///modules/CustomizableUI.jsm", {}) .gPalette.get(id); if (obj) obj = obj.implementation; else { Services.console.logStringMessage(id + " not found"); return this.destroy() || {switch() {}}; } } delete this.obj; return this.obj = obj; }, handleEvent(e) { if (e.key != "F8" || e.ctrlKey || e.shiftKey || e.altKey || e.repeat) return; //e.preventDefault(); //e.stopPropagation(); this.obj.switch(document); }, destroy: function destroy() { removeEventListener("keydown", this, true); removeEventListener("unload", destroy); } }; addEventListener("keydown", listener, true); addEventListener("unload", listener.destroy); })("SwitchKeyboardLayout");} catch(ex) {Cu.reportError(ex);}
// Switch Keyboard Layout button (порт с СВ) try {(keybUtils => CustomizableUI.createWidget({ type: "custom", id: "SwitchKeyboardLayout", onBuild(doc) { var btn = doc.createXULElement("toolbarbutton"); btn.id = this.id; btn.label = btn.tooltipText = "Switch Keyboard Layout"; btn.image = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAk1BMVEX///8/Pz8BAQF8fHwJCQkCAgIJCQl8fHx9fX0AAABJSUkBAQENDQ0wMDBVVVUAAABra2t0dHR7e3thYWEBAQEAAAAAAAABAQEAAAAgICABAQEBAQH8/Pzw8PDp6en39/fj4+Pe3t41V9I/YeWKioqDg4N9fX0jRa8wUrVoaGhkhuxWeNx1dXVCZMhvb28kRqsqTL4KidXxAAAAHHRSTlMAAABndwAAAAA0blVZcm1naWhNa6hrcJ8AAKRU4jk/3gAAAHVJREFUeF6FyMUCwjAUBdEbaQupUMOjqMv/fx1dQN6yZ3aDcWnyw6ezoRWNYc15kqKQZCFlgTKQQwgllL/dn5f3+bPb+6P3CpWNw56srdCZOMzDmA61i8O9nKvRaHLVukEryFKIFtnkj7ENYxmNdd5v+5xj1BcJ/w9Kj6K7ZAAAAABJRU5ErkJggg=="; btn.setAttribute("oncommand", "linkedObj.switch(document);"); btn.className = "toolbarbutton-1 chromeclass-toolbar-additional"; btn.linkedObj = this; return btn; }, switch(doc) { var br = doc.activeElement; br && br.localName == "browser" && br.isRemoteBrowser ? br.messageManager.loadFrameScript(this.url, false) : this.keybUtils.switchSelKeybLayout(); }, get url() { delete this.url; return this.url = `data:;charset=utf-8,(${ encodeURIComponent(keybUtils) }).switchSelKeybLayout()`; }, get keybUtils() { delete this.keybUtils; var def = "let{KeyEvent,HTMLInputElement,HTMLTextAreaElement}=Cu.getGlobalForObject(Services);"; var url = `data:;charset=utf-8,${def}%0Athis.keybUtils=${encodeURIComponent(keybUtils)}`; Services.scriptloader.loadSubScript(url, this); var {id} = this; this.keybUtils.getFocusedElement = function(_subCall, _focusFixed) { var window = Services.focus.activeWindow, {document} = window; var button = document.getElementById(id); if( !_focusFixed && "closeMenus" in window && document.commandDispatcher.focusedElement == button ) { window.closeMenus(button); window.setTimeout(function(_this) { _this.switchSelKeybLayout(_subCall, true); }, 0, this); return; } return document.commandDispatcher.focusedElement; } return this.keybUtils; } }))(`{ //== Options noSelBehavior: { // Shift+Home ctrlKey: false, altKey: false, shiftKey: true, metaKey: false, keyCode: KeyEvent.DOM_VK_HOME, charCode: 0 }, // 0 - do nothing // 1 - convert all text // Or use object like following to simulate "keypress" event: convTableForward: { // ru -> en "\\"": "@", ":": "^", ";": "$", "?": "&", ",": "?", "/": "|", ".": "/", "э": "'", "б": ",", "ю": ".", "Ж": ":", "ж": ";", "Б": "<", "Ю": ">", "Э": "\\"", "х": "[", "ъ": "]", "ё": "\`", "Х": "{", "Ъ": "}", "Ё": "~", "№": "#", "Ф": "A", "ф": "a", "И": "B", "и": "b", "С": "C", "с": "c", "В": "D", "в": "d", "У": "E", "у": "e", "А": "F", "а": "f", "П": "G", "п": "g", "Р": "H", "р": "h", "Ш": "I", "ш": "i", "О": "J", "о": "j", "Л": "K", "л": "k", "Д": "L", "д": "l", "Ь": "M", "ь": "m", "Т": "N", "т": "n", "Щ": "O", "щ": "o", "З": "P", "з": "p", "Й": "Q", "й": "q", "К": "R", "к": "r", "Ы": "S", "ы": "s", "Е": "T", "е": "t", "Г": "U", "г": "u", "М": "V", "м": "v", "Ц": "W", "ц": "w", "Ч": "X", "ч": "x", "Н": "Y", "н": "y", "Я": "Z", "я": "z", __proto__: null }, //== End of options get convTableBackward() { var ctb = { __proto__: null }; var ctf = this.convTableForward; for(var c in ctf) ctb[ctf[c]] = c; delete this.convTableBackward; return this.convTableBackward = ctb; }, inPrimaryLayout: function(s) { for(var i = 0, l = s.length; i < l; ++i) { var c = s.charAt(i); /* if(c in this.convTableForward) return true; if(c in this.convTableBackward) return false; */ var primary = c in this.convTableForward; if(primary ^ c in this.convTableBackward) return primary; } return false; }, switchKeybLayout: function(s, convTable) { var res = ""; for(var i = 0, l = s.length; i < l; ++i) { var c = s.charAt(i); res += c in convTable ? convTable[c] : c; } return res; }, getFocusedElement: function() { return Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager) .getFocusedElementForWindow(content, true, {}); }, switchSelKeybLayout: function(_subCall, _focusFixed) { var fe = this.getFocusedElement(_subCall, _focusFixed); if(!fe) return; if(HTMLInputElement.isInstance(fe) || HTMLTextAreaElement.isInstance(fe)) { var ta = fe; try { var val = ta.value; var sel = val.substring(ta.selectionStart, ta.selectionEnd); } catch(e) { // Non-text HTMLInputElement return; } if(!sel && val && this.noSelBehavior && !_subCall) { if(this.noSelBehavior == 1) { ta.selectionStart = 0; ta.selectionEnd = val.length; sel = val; } else { this.handleNoSel(ta); return; } } if(!sel) return; var res = this.switchKeybLayout( sel, this.inPrimaryLayout(sel) ? this.convTableForward : this.convTableBackward ); if(res != sel) this.insertText(ta, res); } else if(fe.contentEditable == "true") { var doc = fe.ownerDocument; var docURI = doc.documentURI; if( docURI.substr(0, 5) == "data:" && docURI.indexOf("chrome://browser/skin/devtools/") != -1 ) { //~ todo: seems like we only can use paste from clipboard here... return; } var sel = doc.defaultView.getSelection(); var rng = sel.rangeCount && sel.getRangeAt(0); var tmpNode; if(!rng || rng.collapsed) { if(!this.noSelBehavior || _subCall) return; if(this.noSelBehavior == 1) { var r = doc.createRange(); r.selectNodeContents(fe); sel.removeAllRanges(); sel.addRange(r); tmpNode = fe.cloneNode(true); } else { this.handleNoSel(fe); return; } } else { tmpNode = doc.createElementNS("http://www.w3.org/1999/xhtml", "div"); tmpNode.appendChild(rng.cloneContents()); } var orig = tmpNode.innerHTML; var convTable = this.inPrimaryLayout(tmpNode.textContent) ? this.convTableForward : this.convTableBackward; var _this = this; var parseChildNodes = function(node) { if(Element.isInstance(node)) { var childNodes = node.childNodes; for(var i = childNodes.length - 1; i >= 0; --i) parseChildNodes(childNodes[i]); } else if(node.nodeType == node.TEXT_NODE) { var text = node.nodeValue; var newText = _this.switchKeybLayout(node.nodeValue, convTable); if(newText != text) node.parentNode.replaceChild(doc.createTextNode(newText), node); } } parseChildNodes(tmpNode); var res = tmpNode.innerHTML; if(res != orig) doc.execCommand("insertHTML", false, res); } }, handleNoSel: function(node) { this.select(node); this.switchSelKeybLayout(true); }, select: function(node) { var e = this.noSelBehavior; if(!e || typeof e != "object") return; /* var evt = new node.ownerGlobal.KeyboardEvent( "keypress", {bubbles: true, cancelable: true, ...e} ); node.dispatchEvent(evt); }, */ if(ChromeUtils.domProcessChild.childID) { var cmd = this.beh2cmd[e.ctrlKey + "_" + e.shiftKey + "_" + e.keyCode]; cmd && docShell.doCommand(cmd); } else node.dispatchEvent(new node.ownerGlobal.KeyboardEvent( "keypress", {bubbles: true, cancelable: true, ...e} )); }, beh2cmd: { // Ctrl_Shift_VK false_true_36: "cmd_selectLinePrevious", // Shift+Home }, insertText: function(ta, text) { //var editor = ta.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor var editor = ta.editor .QueryInterface(Components.interfaces.nsIPlaintextEditor || Ci.nsIEditor); if(editor.flags & editor.eEditorReadonlyMask) return; var sTop = ta.scrollTop; var sHeight = ta.scrollHeight; var sLeft = ta.scrollLeft; // var sWidth = ta.scrollWidth; if(text) editor.insertText(text); else editor.deleteSelection(0, 0); ta.scrollTop = sTop + (ta.scrollHeight - sHeight); ta.scrollLeft = sLeft; // + (ta.scrollWidth - sWidth); } }`)} catch(ex) {Cu.reportError(ex);}
Uncaught TypeError: Cu.import is not a function
get obj chrome://user_chrome_files/content/custom_scripts/win/F8_kbd_layout.js:10
handleEvent chrome://user_chrome_files/content/custom_scripts/win/F8_kbd_layout.js:25
Dumby
помоги пожалуйста восстановить работу скрипта
Отсутствует