В 106 отвалился "Пункт для контекстного меню адресной строки, подставляющий модификаторы поиска".
Кто-нибудь знает, что не так?
Отсутствует
"подставляющий модификаторы поиска"
попробовал запустить код через userCromeJS от Ксяо на 106.0.1, не заработала только очистка мышкой #searchbar. брал из второго спойлера с пометкой Update, может в этом проблема...
Жизнь иногда такое выкидывает, что хочется подобрать...
Отсутствует
Подскажите код, который осуществляет перезапуск браузера с текущими аргументами командной строки. Взятый отсюда https://forum.mozilla-russia.org/viewto … 43#p798943 перезапускает без аргументов.
Отсутствует
Обновил UserChromeFiles и Demo-ПРОФИЛЬ для Firefox 84+
Изменения в основном для совместимости с новыми версиями Firefox, в Демо-профиле изменено 555 файлов.
Если оформление браузера «неправильное», скачайте aris-t2 стиль, соответствующий вашей версии Firefox.
current (Firefox 110+), legacy/fx101-108, legacy/fx91-100, legacy/fx60-90
удалите папки «config, css, image» из «Ваш-профиль/chrome/user_chrome_files/custom_styles/aris-t2» и скопируйте такие же для вашего Firefox, например из fx91-100.
Отредактировано Dobrov (20-05-2023 15:14:09)
Отсутствует
Dumby, можно заставить работать эти скрипты FirefoxTaskManager part1, part2 (не знаю, почему автор разбил на две части) и aboutconfig_menu.uc.js в 68ESR..? Размеры, конечно, не хилые, но, может, посмотрите, что можно сделать..?
Отсутствует
и aboutconfig_menu.uc.js в 68ESR
Сначала убрать, на всякий случай, строку console.log("aboutconfig_menu.uc.js");
Затем заменить btn.type = 'menu'; на btn.setAttribute("type", "menu");
И должно работать. Ну, иконку ещё заменить, в 68 нет никакого «ion.svg».
Расположить, разумеется, в custom_script.js, а не в окно.
А FirefoxTaskManager — вот тут не знаю.
Для меня всё упирается в CSS. Если JS ещё могу поправить,
то как спозиционировать то, что скрипт суёт во вкладки, так, как в 102, я совершенно без понятия.
Отсутствует
Dumby
должно работать
Спасибо, работает.
что скрипт суёт во вкладки, так, как в 102, я совершенно без понятия
А если упростить задачу: вот этот адаптировать под 68. На 78 проверял, там, вроде, только выпадающий список без "вторжения" во вкладки.
Судя по потрохам скрипта, задачу это не упрощает. Отбой, извиняюсь за отнятое время.
Отредактировано LGS (07-11-2022 23:00:20)
Отсутствует
там, вроде, только выпадающий список без "вторжения" во вкладки
Вторжение есть, div.tabBars добавляется в табский vbox.tab-background
Но да, что-то никакого видимого тултипа это не образует.
Так что попробуем вернуться к предыдущему варианту.
Насчёт позиционирования, оно работает, если .tab-content'у назначить position: relative
Как бы это чего-нибудь не сломало, надо приглядеться.
Кстати вот про «не знаю, почему автор разбил на две части»,
надо полагать, это потому, что скрипты сделаны под «xiaoxiaoflood's uc loader»,
и у второго (part2) присутствует директива @onlyonce, то есть он должен исполняться только один раз.
Итак, part2.
Убираем строку console.log("taskmonitor_part2.js");
Меняем btn.type = 'menu'; на btn.setAttribute("type", "menu");
В стиль (он там в конце) добавляем
tab.tabbrowser-tab .tab-content {position: relative !important;}
И перемещаем скрипт в custom_script.js, если он ещё не там.
part1
Меняем (все) document.body на просто document
то есть убираем «.body», в 68 у документа нет никакого body
И меняем эти четыре строки
/* var insertNode = tabNode.getElementsByClassName("tab-content")[0]; */ var insertNode = document.getAnonymousElementByAttribute(tabNode, "class", "tab-content"); /* var close_button = tabNode.getElementsByClassName("tab-content")[0].getElementsByClassName("tab-close-button")[0]; */ var close_button = insertNode.querySelector(":scope > .tab-close-button"); /* if ( _btnNode ) btnNode = _btnNode.getElementsByClassName("toolbarbutton-badge-stack")[0]; */ if (_btnNode) btnNode = document.getAnonymousElementByAttribute(_btnNode, "class", "toolbarbutton-badge-stack"); /* contParent = document.createXULElement("div"); */ contParent = document.createXULElement("box");
Отсутствует
Dumby, круто, как всегда, огромное спасибо:
// var fftm_widget = win.documen.getElementsByClassName("fftm_widget_class")[0];
var fftm_widget = document.getElementById("fftm_widget");
// var _btnNode = win.documen.getElementsByAttribute("data-extensionid",addonId)[0];
var _btnNode = document.getElementsByAttribute("data-extensionid",addonId
Отредактировано LGS (08-11-2022 18:49:02)
Отсутствует
пришлось помимо четырех строк еще три заменить
Видимо реплейс «.body» прошёл кривовато.
В приведённых строках везде «win.documen»
без буквы «t» на конце слова документ.
Отсутствует
В приведённых строках везде «win.documen»
без буквы «t» на конце слова документ.
Мой косяк, когда в редакторе замену делал document.body на document букву t потерял. В оригинале все нормально. Странно, что вообще сработала замена трех строк.
Вернул букву t, три строки привел в первоначальное состояние - все нормально. Невнимательность повлекла за собой лишние телодвижения.
Отредактировано LGS (08-11-2022 19:44:39)
Отсутствует
Случайно заметил, что обновился скрипт от Alice0775 memoryMinimizationButton.uc.js. Убрал 3 сообщения слева снизу и заменил "всплывашкой". Кнопка у меня в боковой панели, добавил отступ - в v.107 прижалась влево к границе окна. Если кто пользуется, в CustomStylesScripts.jsm секция load: [ // По событию "load"
{ path: "memoryMinimizationButton.uc.js", ucfobj: false, },
// ==UserScript== // https://raw.githubusercontent.com/alice0775/userChrome.js/master/108/memoryMinimizationButton.uc.js // @name memoryMinimizationButton.uc.js // @namespace http://space.geocities.yahoo.co.jp/gl/alice0775 // @description memory minimization button // @charset utf-8 // @include main // @include about:processes?memoryMinimizationButton // @compatibility Firefox 108 // @author Alice0775 // @version 2022/10/18 10:00 fix Bug 1790616 // @version 2022/06/18 00:00 kil process // @version 2018/10/09 00:00 fix CSS // @version 2018/09/07 23:00 fix initial visual status // ==/UserScript== var memoryMinimizationButton = { get memoryMinimizationButton(){ return document.getElementById("memoryMinimizationButton"); }, get statusinfo() { if ("StatusPanel" in window) { // fx61+ return StatusPanel._labelElement.value; } else { return XULBrowserWindow.statusTextField.label; } }, set statusinfo(val) { if ("StatusPanel" in window) { // fx61+ StatusPanel._label = val; } else { XULBrowserWindow.statusTextField.label = val; } if(this._statusinfotimer) clearTimeout(this._statusinfotimer); this._statusinfotimer = setTimeout(() => {this.hideStatusInfo();}, 2000); this._laststatusinfo = val; return val; }, init: function() { let style = ` #memoryMinimizationButton { width: 16px; height: 16px; margin-left: 5px; /* со 107-й сломалось, добавил */ list-style-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuMWMqnEsAAAFdSURBVFhH7VbLbsMwDMsef5dc8z/53F13GXZYm5kaZciqnKro2hxaAkRkmkqI2gI6KNZ1vStPEJluyS6WZVlB3xDpWc3q/Ewf6ASClwicLkhojc5PxaDvgQIU4dWSPjEa/Z1y1ed5fqPUeCmJVhAGUC9YNzz4ghNEelYDrI5aAozjeNyD5QBqgF34DJAN8GN4oGb3cJ527fftumEqgAVurdk7Um680zR92bXWEdMBWB+s14+TegFf93hpgF5dgylK/cFSPSGvOgKA9afWgP4y+lR/xKuOwMN6AdwFXff4H0eAqfhWnU9Mhdx+rrtMBSjER3TUtLYaqOMYjaldN8wGuBmfAWqAcmMPe1ACYF6lIBUZXXFO29I3/5IVoFMpcLoA2iX96gVLiBb0bb6gINSy/WLsgb4HDgBD0BzqXsv0i8nDm+/JCC8lKW5zY4SGvT9LBdbVS0g/64q4fxh+AZvdJHHKcZdFAAAAAElFTkSuQmCC'); } @media (min-resolution: 1.1dppx) { #memoryMinimizationButton { width: 32px; height: 32px; } } `.replace(/\s+/g, " "); let sss = Components.classes['@mozilla.org/content/style-sheet-service;1'] .getService(Components.interfaces.nsIStyleSheetService); let newURIParam = { aURL: 'data:text/css,' + encodeURIComponent(style), aOriginCharset: null, aBaseURI: null } let cssUri = Services.io.newURI(newURIParam.aURL, newURIParam.aOriginCharset, newURIParam.aBaseURI); if (!sss.sheetRegistered(cssUri, sss.AUTHOR_SHEET)) sss.loadAndRegisterSheet(cssUri, sss.AUTHOR_SHEET); if (this.memoryMinimizationButton) return; ChromeUtils.import("resource:///modules/CustomizableUI.jsm"); try { CustomizableUI.createWidget({ //must run createWidget before windowListener.register because the register function needs the button added first id: 'memoryMinimizationButton', type: 'custom', defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function(aDocument) { var toolbaritem = aDocument.createElementNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', 'toolbarbutton'); var props = { id: "memoryMinimizationButton", class: "toolbarbutton-1 chromeclass-toolbar-additional", tooltiptext: "Memory minimization(shift+click; kill other tabs)", oncommand: "memoryMinimizationButton.doMinimize(event);", type: CustomizableUI.TYPE_TOOLBAR, label: "Memory minimization", removable: "true" }; for (var p in props) { toolbaritem.setAttribute(p, props[p]); } return toolbaritem; }, }); } catch(ee) {} }, doMinimize: function(event) { function doGlobalGC() { Services.obs.notifyObservers(null, "child-gc-request"); Cu.forceGC(); } function doCC() { Services.obs.notifyObservers(null, "child-cc-request"); if (typeof window.windowUtils != "undefined") window.windowUtils.cycleCollect(); else window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils).cycleCollect(); } function doMemMinimize(event) { if (event.button == 1 || event.shiftKey || event.altKey || event.ctrlKey) memoryMinimizationButton.kill(); Services.obs.notifyObservers(null, "child-mmu-request"); var gMgr = Cc["@mozilla.org/memory-reporter-manager;1"] .getService(Ci.nsIMemoryReporterManager); // gMgr.minimizeMemoryUsage(() => {if (!(event.button == 1 || event.shiftKey || event.altKey)) memoryMinimizationButton.displayStatus("Memory minimization done")}); gMgr.minimizeMemoryUsage(() => {if (!(event.button == 1 || event.shiftKey || event.altKey)) memoryMinimizationButton.displayStatus("")}); } function sendHeapMinNotifications() { function runSoon(f) { var tm = Cc["@mozilla.org/thread-manager;1"] .getService(Ci.nsIThreadManager); tm.mainThread.dispatch({ run: f }, Ci.nsIThread.DISPATCH_NORMAL); } function sendHeapMinNotificationsInner() { var os = Cc["@mozilla.org/observer-service;1"] .getService(Ci.nsIObserverService); os.notifyObservers(null, "memory-pressure", "heap-minimize"); if (++j < 3) runSoon(sendHeapMinNotificationsInner); } var j = 0; sendHeapMinNotificationsInner(); } // this.displayStatus("Memory minimization start") doGlobalGC(); doCC(); //sendHeapMinNotifications(); // Добавил всплывашку setTimeout((event)=> {doMemMinimize(event);}, 1000, event); var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); alertsService.showAlertNotification("chrome://user_chrome_files/content/custom_styles/icons/information-16.png", "Memory", "Потребление памяти минимизировано!"); setTimeout(() => alertsService.closeAlert(), 2000); }, _statusinfotimer: null, _laststatusinfo: null, displayStatus: function(val) { this.statusinfo = val; }, hideStatusInfo: function() { if(this._statusinfotimer) clearTimeout(this._statusinfotimer); this._statusinfotimer = null; if (this._laststatusinfo == this.statusinfo) this.statusinfo = ""; }, kill: function() { this.browser = document.createXULElement("browser"); this.browser.src = "about:processes?memoryMinimizationButton"; document.documentElement.appendChild(this.browser); setTimeout(() => { this.browser.src = "about:blank"; document.documentElement.removeChild(this.browser); delete this.browser; // Services.console.logStringMessage("killing done"); // this.displayStatus("Memory minimization done") }, 8000); } } if (location.href == "chrome://browser/content/browser.xhtml") { memoryMinimizationButton.init(); } else if (location.href == "about:processes?memoryMinimizationButton") { // Services.console.logStringMessage("killing start"); setTimeout(() => { let closeButtons = document.querySelectorAll("tr.process > td.close-icon"); for(let closeButton of closeButtons) { let row = closeButton.parentNode; let canKill = true; for (let childRow = row.nextSibling; childRow && !childRow.classList.contains("process"); childRow = childRow.nextSibling ) { let win = childRow.win; if (win?.tab?.tab?.selected) { canKill = false; break; } } if (canKill) Control._handleKill(closeButton); } return; /* let closeButtons = document.querySelectorAll("tr.process > td.close-icon"); for(let closeButton of closeButtons) { closeButton.click(); } */ }, 5000); }
(async id => ({ delay: 2e3, val: "", init(topic, mm) { Services.obs.addObserver(mm = this, topic); Services.obs.addObserver(function quit(s, t) { this.timer?.cancel(); Services.obs.removeObserver(mm, topic); Services.obs.removeObserver(quit, t); }, "quit-application-granted"); }, observe(win) { var df = win.MozXULElement.parseXULToFragment( `<hbox id="${id}" tooltiptext="${ "ЛКМ: Минимизировать потребление памяти
ПКМ: about:performance
Ctrl+ПКМ: about:debugging#/runtime/this-firefox" }" onclick="event.button || ${ "memoryMinimizationButton.doMinimize(event)" }"><label id="${id += "-label"}"/></hbox>` ); this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); (this.observe = async win => { this.timer.cancel(); await new Promise(ChromeUtils.idleDispatch); var clone = win.document.importNode(df, true); clone.firstChild.oncontextmenu = this.about; win.document.getElementById("star-button-box").after(clone); this.notify(); })(win); }, about(e) { var gb = e.view.gBrowser; gb.selectedTab = gb.addTrustedTab(`about:${ e.ctrlKey ? "debugging#/runtime/this-firefox" : "performance" }`); }, async notify() { var info = await ChromeUtils.requestProcInfo(); var bytes = info.memory; for(var child of info.children) bytes += child.memory; this.timer.initWithCallback(this, this.delay, this.timer.TYPE_ONE_SHOT); var prev = this.val; if ((this.val = this.mgb(bytes)) != prev) for(var win of CustomizableUI.windows) { var lab = win.document.getElementById(id); if (lab) lab.value = this.val; } }, mgb: bytes => bytes < 1073741824 ? Math.round(bytes / 1048576) + "MB" : (bytes / 1073741824).toFixed(2) + "GB" }).init("browser-delayed-startup-finished"))("ucf-mem-indicator");
Отредактировано xrun1 (28-12-2022 13:34:33)
Отсутствует
xrun1
Кнопка в панель адреса
+ та и следующая страница обсуждения, если на кнопку в строке адреса надо повесить функцию очистки по клику и ...
А секция sendHeapMinNotifications() разве не к уведомлениям в статусе относится?
Отсутствует
секция sendHeapMinNotifications() разве не к уведомлениям в статусе относится?
Это функция и вызов её закомментарил, там всего одно место как раз перед моей "всплывашкой". Правильно это или что-то ф-ция делает ещё - не знаю...
За ссылку на разговор о кнопке спасибо. Я помню, что-то было на пару страниц, читал, но ссылку у себя не сохранил.
Что касается очистки по клику, так это есть. Скрипт создаёт свою кнопку, но я ей не пользуюсь, она сидит в боковой панели. А по клику ЛКМ на кнопке в строке адреса как раз и вызывается функция из скрипта memoryMinimizationButton.doMinimize(event). Я кнопку компоновал из нескольких сообщений, в том числе из Вашего.
Отсутствует
xrun1
Понятно. Только непонятно, нужна ли мне последняя секция?
var memoryMinimizationButton = { get memoryMinimizationButton(){ return document.getElementById("memoryMinimizationButton"); }, doMinimize: function(event) { function doGlobalGC() { Services.obs.notifyObservers(null, "child-gc-request"); Cu.forceGC(); } function doCC() { Services.obs.notifyObservers(null, "child-cc-request"); if (typeof window.windowUtils != "undefined") window.windowUtils.cycleCollect(); else window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils).cycleCollect(); } function doMemMinimize(event) { memoryMinimizationButton.kill(); Services.obs.notifyObservers(null, "child-mmu-request"); var gMgr = Cc["@mozilla.org/memory-reporter-manager;1"] .getService(Ci.nsIMemoryReporterManager); } doGlobalGC(); doCC(); // Всплывашка setTimeout((event)=> {doMemMinimize(event);}, 1000, event); var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); alertsService.showAlertNotification("chrome://user_chrome_files/content/custom_styles/icons/information-16.png", "Memory Minimization", "Минимизация памяти выполнена!"); setTimeout(() => alertsService.closeAlert(), 2000); }, kill: function() { this.browser = document.createXULElement("browser"); this.browser.src = "about:processes?memoryMinimizationButton"; document.documentElement.appendChild(this.browser); setTimeout(() => { this.browser.src = "about:blank"; document.documentElement.removeChild(this.browser); delete this.browser; }, 8000); } } if (location.href == "about:processes?memoryMinimizationButton") { setTimeout(() => { let closeButtons = document.querySelectorAll("tr.process > td.close-icon"); for(let closeButton of closeButtons) { closeButton.click(); } }, 5000); }
Отсутствует
нужна ли мне последняя секция?
Думаю, нет. Как я понял, по задумке автора по shift+click должны закрываться другие табы. У меня не закрываются. Может потому, что у меня нет кнопки закрытия вкладки, а в этой секции скрипт кликает по ней.))
Отсутствует
а у меня окно кук невозможно по вертикали уменьшить .оно тогда пропадает и при повторном нажатии его не видно и только востанавливать из бекапа.
У меня окно кук в 107.0.1 выглядит так:
«The Truth Is Out There»
Отсутствует
Dumby
на ff 107 заметил, что перестал работать скрипт SwitchKeyboardLayout
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(fe instanceof HTMLInputElement || fe instanceof HTMLTextAreaElement) { 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(node instanceof Element) { 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);}
Отредактировано Inko7 (07-12-2022 23:23:38)
Отсутствует
на ff 107 заметил, что перестал работать скрипт
Не вижу на 107.0.1 такого.
Но, x instanceof *Element лучше заменить на *Element.isInstance(x)
Там три вхождения (поиск по «instanceof»).
Отсутствует
не долго радовался((
скопировал правленый файл скрипта, принес с работы домой, заменил им текущий нерабочий, перегрузил FF с очисткой кэша - не заработало!
начал разбираться:
оказывается, если тыцкать саму кнопку, то раскладка слов исправляется! не работает код на горячую клавишу F8
// Назначить клавишу 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);}
Dumby
извиняюсь, что не верно и не разобравшись озвучил суть проблемы
почини пожалуйста эту переключалку по F8
Отсутствует