Dumby
Не могу толком вставить предупреждение на СКМ ...Отражается на другие клики.(UndoClose)
this.onclick = function(e) { if(e.target != this) return; if(e.button == 1 || e.button == 0 && (e.ctrlKey || e.shiftKey || e.altKey || e.metaKey)) this.undoCloseTabsList.clearAllLists(); else if( e.button == 0 || e.button == 2 && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey && this.undoCloseTabsList.options.rightClickToUndoCloseTab ) { if( e.button == 0 && !this.undoCloseTabsList.options.useMenu || e.button == 2 && this.undoCloseTabsList.options.rightClickToUndoCloseTab ) { if(this.undoCloseTabsList.closedTabCount) this.undoCloseTabsList.undoCloseTab(); else this.undoCloseTabsList.drawUndoList() && this.undoCloseTabsList.showMenu(e); } // Allow use "command" section only from hotkey: e.preventDefault(); e.stopPropagation(); } };
Отсутствует
Krtec пишет...такое же поведение при ЛКМ по активной вкладке
скрытый текстВыделить кодКод:
(async ucf => { await delayedStartupPromise; var set = new Set([gBrowser.selectedTab]); var bt = gBrowser._blurTab; gBrowser._blurTab = tab => tab.selected && blur(tab); var blur = (tab, click) => { set.delete(tab); var res; for(var t of set) t.hidden || (res = t); click && set.add(tab); res ? gBrowser.selectedTab = res : bt.call(gBrowser, tab); } var skip, arr = [ ["TabClose", e => set.delete(e.target)], ["TabSelect", e => set.add(e.target, set.delete(e.target))], ["mousedown", e => skip = e.button || !e.target.matches( "tab[selected] :scope:not(.tab-close-button):not(.tab-icon-sound), tab[selected]" ), true], ["click", e => skip || e.ctrKey || e.shiftKey || e.altKey || e.detail != 1 || blur(e.target.closest("tab"), true) ] ]; var id, tc = gBrowser.tabContainer; for(var args of arr) tc.addEventListener(...args); ucf.unloadlisteners.push(id = Symbol()); ucf[id] = {destructor() { set.clear(); for(var args of arr) tc.removeEventListener(...args); }}; })(ucf_custom_script_win);
Так переключение зацикливается между двумя вкладками, хотелось бы по типу перемещения по истории вкладки назад при нажимании кнопки со стрелочкой — страница с которой переключаешся не становится предыдущей, а остаётся следующей по отношению к той, на которую переключился. Очень надеюсь что сие возможно и на вашу помощь.
Отсутствует
Dumby - напомню вопрос в теме UCF - просьба упростить код перехват кликов, убрать LongPress,
он даёт задержку при нажатии кнопок, т.е. убрать задержку, переделать на системные click, dblclick, wheel…
Сделал отладочный скрипт, в нём только кнопка Загрузки + сообщения в консоли и строке статуса:
(async (id) => { // для custom_script_win.js: дополнительные клики и подсказки кнопок © Dumby var dsym = Symbol(), j = (...args) => args.join("\n"), tooltips = { [dsym]: j(GetDynamicShortcutTooltipText("downloads-button"), `\nДвойной клик: открыть [Загрузки]` ), get "downloads-button"() { var hint = this[dsym]; try {var dw = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {dw = Services.dirsvc.get("DfltDwnld", Ci.nsIFile);} //отличается от ⇧ if (dw) hint += "\n\n[Загрузки] — выбранная папка:\n" + dw.path; return hint; } }; /* end tooltips */ var listener = { // дополнительные клики кнопок и перехват существующих filter(sel) { return this.closest(sel); }, find(sel) { return data[sel][this] || data[sel][this + 1]; }, handleEvent(e) { if (this.skip || e.detail > 2) return; var trg = e.target; var sels = this.selectors.filter(this.filter, trg); var {length} = sels; if (!length) return; var dbl = e.detail == 2; var wh = e.type.startsWith("w"); var num = e.metaKey *64 + e.ctrlKey *32 + e.shiftKey *16 + e.altKey *8 + (wh ? 2 : e.button *128 + dbl *4); var obj = data[ length > 1 && sels.find(this.find, num) || sels[0] ]; // wheel if (wh) return obj[num]?.(trg, e.deltaY < 0); // mousedown if (e.type.startsWith("m")) { obj.mousedownTarget && this.stop(e); if (dbl) return; this.longPress = false; if (++num in obj) this.mousedownTID = setTimeout(this.onLongPress, 640, trg, obj, num); if (e.button == 2) this.ctx = trg.getAttribute("context"), trg.setAttribute("context", ""); return; } // click obj.mousedownTarget || this.stop(e); if (this.longPress) return this.longPress = false; dbl ? this.clickTID &&= clearTimeout(this.clickTID) : this.mousedownTID &&= clearTimeout(this.mousedownTID); if (!obj[num]) { if (e.button == 1) return; if (e.button) { num = "context"; for(var p in this.a) this.a[p] = e[p]; } else num = "dispatch", this.mdt = obj.mousedownTarget; obj = this; } dbl ? obj[num](trg) : this.clickTID = setTimeout(this.exec, 300, trg, obj, num); }, get selectors() { this.exec = (trg, obj, num) => { this.clickTID = null; obj[num](trg); } this.onLongPress = (trg, obj, num) => { this.mousedownTID = null; this.longPress = true; obj[num](trg); } delete this.selectors; return this.selectors = Object.keys(data); }, get mdEvent() { delete this.mdEvent; return this.mdEvent = new MouseEvent("mousedown", {bubbles: true}); }, context(trg) { this.ctx ? trg.setAttribute("context", this.ctx) : trg.removeAttribute("context"); trg.dispatchEvent(new MouseEvent("contextmenu", this.a)); }, dispatch(trg) { this.skip = true; this.mdt ? trg.dispatchEvent(this.mdEvent) : trg.click(); this.skip = false; }, stop: e => { e.preventDefault(); e.stopImmediatePropagation(); }, a: {__proto__: null, bubbles: true, screenX: 0, screenY: 0} }; var onMouseenter = e => { var trg = e.target; var hint = tooltips[trg.id] || tooltips[(trg = trg.parentNode).id]; if (hint) trg.tooltipText = hint; } var keydown_win = e => { // нажатие клавиш log(e.keyCode); } window.addEventListener("keydown", keydown_win); var toolbars = ["nav-bar", "ucf-additional-vertical-bar"].map(i => document.getElementById(i)); var events = ["click", "mousedown", "wheel"]; // appMenu-protonMainView toolbars[0].addEventListener("mouseenter", onMouseenter, true); for(var bar of toolbars) for(var type of events) bar.addEventListener(type, listener, true); ucf_custom_script_win.unloadlisteners.push(id); ucf_custom_script_win[id] = {destructor() { window.removeEventListener("keydown", keydown_win); toolbars[0].removeEventListener("mouseenter", onMouseenter, true); for(var bar of toolbars) for(var type of events) bar.removeEventListener(type, listener, true); }} addDestructor = nextDestructor => { var {destructor} = ucf_custom_script_win[id]; ucf_custom_script_win[id].destructor = () => { try {destructor();} catch(ex) {Cu.reportError(ex);} nextDestructor(); } }; // end Hooks prefs.setBoolPref("browser.download.autohideButton", false); // не скрывать кнопку Загрузки var {prefs, dirsvc} = Services, log = msg => Services.console.logStringMessage("[HC] "+ msg), // отладка showInStatusPanel = (info, time = 5000, StatusPanel = window.StatusPanel) => { if (StatusPanel.update.tid) clearTimeout(StatusPanel.update.tid) else { var {update} = StatusPanel; StatusPanel.update = () => {}; StatusPanel.update.ret = () => { StatusPanel.update = update; StatusPanel.update(); } } StatusPanel.update.tid = setTimeout(StatusPanel.update.ret, time); StatusPanel._label = info; log("[HC] "+ info); }, data = { "#downloads-button": { mousedownTarget: true, // + отправить текст в консоль 2(trg, forward) { showInStatusPanel("DW Wheel " + (forward ? "forward" : "backward")); }, 4() { showInStatusPanel("DW Double Left Click"); Downloads.getSystemDownloadsDirectory().then(path => FileUtils.File(path).launch(), Cu.reportError); }, 16(btn) { showInStatusPanel("Shift + ЛКМ"); }, 128() { showInStatusPanel("СКМ Click"); }, 256() { showInStatusPanel("ПКМ Click"); }, 260(btn) { showInStatusPanel("Double ПКМ Click"); }, 264(btn) { showInStatusPanel("Alt + ПКМ"); }, }, }; // end Clicks, HotKeys ================================================== })("hookClicks-and-tooltips-test"); // END hookClicks
Отсутствует
Не могу толком вставить предупреждение на СКМ ...Отражается на другие клики.
Можно, например, так
… //this.undoCloseTabsList.clearAllLists(); Services.prompt.confirm(null, null, "???") && this.undoCloseTabsList.clearAllLists();
хотелось бы по типу перемещения по истории
Как-то это поперёк концепции.
Сомневаюсь, что такое мне в голову поместится.
Ладно, если просто пощёкать подряд чтоб отмотать, то можно, но если активировать вкладку
не таким образом (кликом по активной), то сброс, возвращение к цепочке основного трекера.
(async ucf => { await delayedStartupPromise; var set = new Set([gBrowser.selectedTab]); var bt = gBrowser._blurTab; gBrowser._blurTab = tab => tab.selected && blur(tab,/* flipset ||*/ set); var blur = (tab, s) => { s.delete(tab); var res; for(var t of s) t.hidden || (res = t); res ? gBrowser.selectedTab = res : bt.call(gBrowser, tab); } var re = /\nblur@[^\n]+?\n(?:[^\n]+?\/)?arr<@/; var skip, flipset, arr = [ ["TabClose", e => { set.delete(e.target); flipset?.delete(e.target); }], ["TabSelect", e => { set.delete(e.target); set.add(e.target); if (flipset && !re.test(Components.stack.formattedStack)) flipset = null; }], ["mousedown", e => skip = e.button || !e.target.matches( "tab[selected] :scope:not(.tab-close-button):not(.tab-icon-sound), tab[selected]" ), true], ["click", e => skip || e.ctrKey || e.shiftKey || e.altKey || e.detail != 1 || blur(e.target.closest("tab"), flipset || (flipset = new Set(set))) ] ]; var id, tc = gBrowser.tabContainer; for(var args of arr) tc.addEventListener(...args); ucf.unloadlisteners.push(id = Symbol()); ucf[id] = {destructor() { set = flipset = null; for(var args of arr) tc.removeEventListener(...args); }}; })(ucf_custom_script_win);
просьба упростить код перехват кликов, убрать LongPress,
он даёт задержку при нажатии кнопок, т.е. убрать задержку, переделать на системные click, dblclick, wheel…
Задержку при нажатии кнопок даёт не LongPress, а необходимость поддержки dblclick.
Нужно ведь подождать, что двойной клик случится (или не случится), правда же?
Отредактировано Dumby (22-02-2022 16:59:04)
Отсутствует
Dumby
Можно, например, так
Класс ! А можно туда же еще код , типа, так второй на отмену один черт срабатывает
{ Services.prompt.confirm(null, null, "Удалить список вкладок и сесий ?") && this.undoCloseTabsList.clearAllLists(); SessionStore.canRestoreLastSession = false;}
Отсутствует
Задержку при нажатии кнопок даёт не LongPress, а необходимость поддержки dblclick.
Нужно ведь подождать, что двойной клик случится (или не случится), правда же?
В других скриптах не было задержек для dblclick и обычных кликов - например в сохранить картинку колёсиком можно двойным кликом искать похожие фото.
То есть события addEventListener("dblclick" и "click" - срабатывают без задержек, видимо потому, что их обработка делается системой.
Поэтому я и просил переделать на системные события скрипт перехвата кнопок...
Отсутствует
А можно туда же еще код , типа, так второй на отмену один черт срабатывает
Можно, в круглых скобках и через запятую.
Можно, но не нужно. Лучше простая и понятная классика,
if (…) и {список выражений в фигурных скобках}
{ if(Services.prompt.confirm(null, null, "???")) { this.undoCloseTabsList.clearAllLists(); SessionStore.canRestoreLastSession = false; } }
и "click"
Это где там мог "click" померещиться?
Видимо, я что-то непонятное написал.
Хорошо, переформулирую. Попробуй написать код:
1. Одинарный клик левой кнопкой мыши — console.log(1);
2. Двойной (там же) клик левой кнопкой мыши — только console.log(2);
(без предшествующего console.log(1) от одинарного клика, разумеется).
И чтобы никаких задержек при одинарном клике.
И не мухлевать, никакой "новейший чип «Телепат-3000»"
на комп не устанавливать.
Отсутствует
просто пощёкать подряд чтоб отмотать
Почему-то у меня не "отматывает", всё одно между двумя последними активными переключается. Открыл поочерёдно четыре вкладки, клацнул по четвёртой — переключился на третью, клацнул по третьей — обратно на четвёртую.
Как-то это поперёк концепции.
В данном случае похоже на то. А вообще — аналогично сворачиванию окон. В древней была такая настройка вкладок: "сворачивать щелчком по вкладке". В своё время привык к такому поведению и сейчас его несколько не хватает.
Если нет простого решения, поперёк концепции ломиться не стоит, мышиная замена ctrl+tab тоже вполне себе. Спасибо.
Отсутствует
Попробуй написать код:………
И чтобы никаких задержек при одинарном клике.
Задержек нет в кнопке сохранения картинок для событий "auxclick" и "dblclick" – клик колёсиком и двойной действуют сразу. Значит, это возможно!
Сделал кнопку для "click" и "dblclick" - при двойном клике также срабатывет "click". Кроме того, в коде перехвата кликов задержка для "dblclick" желательна в 2 раза больше, чем на "LongPress", иначе может срабатывать одинарный клик вместе с "dblclick". Ещё после одинарного клика может сработать "LongPress". У меня так было, пока не изменил задержки в setTimeout(.
То есть, недостаток в том, что задержка реакции кнопки на действия не менее пол-секунды.
Просьба упростить тестовый ucf_hookClicks.js, убрать из него "dblclick". Возможно это ускорит в 2 раза реакцию на действия кнопки. Кроме того, на сенсорных экранах удобнее обычный тап (клик) и удержание на кнопке, чем двойной тап, поэтому для сенсорных экранов такая логика лучше. Ещё желательно при долгом клике воспроизвести звук. Встроенный короткий сигнал, если в браузере есть такой или внешний wav aac ogg файл…
if (++num in obj) // задержка реакции кнопки на действия в 2 раза больше, чем "LongPress" this.mousedownTID = setTimeout(this.onLongPress, 250, trg, obj, num); …………… dbl ? obj[num](trg) // после однократного клика действие выполняется с данной задержкой в мс : this.clickTID = setTimeout(this.exec, 500, trg, obj, num); // время ожидания второго клика
Отредактировано Dobrov (22-02-2022 02:56:20)
Отсутствует
Открыл поочерёдно четыре вкладки, клацнул по четвёртой — переключился на третью, клацнул по третьей — обратно на четвёртую
Не, должно переключиться на вторую.
Может кэш залип? Чтобы исключить такой вариант,
следует закрыть Firefox, и удалить папку startupCache
из Локального каталога профиля вручную.
Просьба упростить тестовый ucf_hookClicks.js, убрать из него "dblclick".
Ещё желательно при долгом клике воспроизвести звук. Встроенный короткий сигнал, если в браузере есть такой или внешний wav aac ogg файл…
Хорошо, попробую. Как бы чего-нибудь не испортить.
(async (id) => { // для custom_script_win.js: дополнительные клики и подсказки кнопок © Dumby var dsym = Symbol(), j = (...args) => args.join("\n"), tooltips = { [dsym]: j(GetDynamicShortcutTooltipText("downloads-button"), `\nДвойной клик: открыть [Загрузки]` ), get "downloads-button"() { var hint = this[dsym]; try {var dw = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {dw = Services.dirsvc.get("DfltDwnld", Ci.nsIFile);} //отличается от ⇧ if (dw) hint += "\n\n[Загрузки] — выбранная папка:\n" + dw.path; return hint; } }; /* end tooltips */ var listener = { // дополнительные клики кнопок и перехват существующих filter(sel) { return this.closest(sel); }, find(sel) { return data[sel][this] || data[sel][this + 1]; }, handleEvent(e) { if (this.skip || e.detail > 1) return; var trg = e.target; var sels = this.selectors.filter(this.filter, trg); var {length} = sels; if (!length) return; var wh = e.type.startsWith("w"); var num = e.metaKey *32 + e.ctrlKey *16 + e.shiftKey *8 + e.altKey *4 + (wh ? 2 : e.button *64); var obj = data[ length > 1 && sels.find(this.find, num) || sels[0] ]; // wheel if (wh) return obj[num]?.(trg, e.deltaY < 0); // mousedown if (e.type.startsWith("m")) { obj.mousedownTarget && this.stop(e); this.longPress = false; if (++num in obj) this.mousedownTID = setTimeout(this.onLongPress, 640, trg, obj, num); if (e.button == 2) this.ctx = trg.getAttribute("context"), trg.setAttribute("context", ""); return; } // click obj.mousedownTarget || this.stop(e); if (this.longPress) return this.longPress = false; this.mousedownTID &&= clearTimeout(this.mousedownTID); if (!obj[num]) { if (e.button == 1) return; if (e.button) { num = "context"; for(var p in this.a) this.a[p] = e[p]; } else num = "dispatch", this.mdt = obj.mousedownTarget; obj = this; } obj[num](trg); }, get selectors() { this.onLongPress = (trg, obj, num) => { this.mousedownTID = null; this.longPress = true; obj[num](trg); } delete this.selectors; return this.selectors = Object.keys(data); }, get mdEvent() { delete this.mdEvent; return this.mdEvent = new MouseEvent("mousedown", {bubbles: true}); }, context(trg) { this.ctx ? trg.setAttribute("context", this.ctx) : trg.removeAttribute("context"); trg.dispatchEvent(new MouseEvent("contextmenu", this.a)); }, dispatch(trg) { this.skip = true; this.mdt ? trg.dispatchEvent(this.mdEvent) : trg.click(); this.skip = false; }, stop: e => { e.preventDefault(); e.stopImmediatePropagation(); }, a: {__proto__: null, bubbles: true, screenX: 0, screenY: 0} }; var onMouseenter = e => { var trg = e.target; var hint = tooltips[trg.id] || tooltips[(trg = trg.parentNode).id]; if (hint) trg.tooltipText = hint; } var keydown_win = e => { // нажатие клавиш log(e.keyCode); } window.addEventListener("keydown", keydown_win); var toolbars = ["nav-bar", "ucf-additional-vertical-bar"].map(i => document.getElementById(i)).filter(Boolean); var events = ["click", "mousedown", "wheel"]; // appMenu-protonMainView toolbars[0].addEventListener("mouseenter", onMouseenter, true); for(var bar of toolbars) for(var type of events) bar.addEventListener(type, listener, true); ucf_custom_script_win.unloadlisteners.push(id); ucf_custom_script_win[id] = {destructor() { window.removeEventListener("keydown", keydown_win); toolbars[0].removeEventListener("mouseenter", onMouseenter, true); for(var bar of toolbars) for(var type of events) bar.removeEventListener(type, listener, true); }}; var addDestructor = nextDestructor => { var {destructor} = ucf_custom_script_win[id]; ucf_custom_script_win[id].destructor = () => { try {destructor();} catch(ex) {Cu.reportError(ex);} nextDestructor(); } } // end Hooks var {prefs, dirsvc} = Services, log = msg => Services.console.logStringMessage("[HC] "+ msg); // отладка prefs.setBoolPref("browser.download.autohideButton", false); // не скрывать кнопку Загрузки var showInStatusPanel = (info, time = 5000, StatusPanel = window.StatusPanel) => { if (StatusPanel.update.tid) clearTimeout(StatusPanel.update.tid) else { var {update} = StatusPanel; StatusPanel.update = () => {}; StatusPanel.update.ret = () => { StatusPanel.update = update; StatusPanel.update(); } } StatusPanel.update.tid = setTimeout(StatusPanel.update.ret, time); StatusPanel._label = info; log(info); }, data = { "#downloads-button": { mousedownTarget: true, // + отправить текст в консоль 2(trg, forward) { showInStatusPanel("DW Wheel " + (forward ? "forward" : "backward")); }, 8(btn) { showInStatusPanel("Shift + ЛКМ"); }, 64() { showInStatusPanel("СКМ Click"); }, 128() { showInStatusPanel("ПКМ Click"); }, 132(btn) { showInStatusPanel("Alt + ПКМ"); }, 1(btn) { showInStatusPanel("Left Long Press"); var a = new Audio(); a.volume = .3; a.src = "data:audio/wav;base64,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rWWuFauMYbnPOsbkweKayC8XtvJCabW1fX//pS3GlttbZIiBqogujCkEIFIVlQYlZFMMBiMbsIhpkSEDjsCUEDBkqUq4NA4sQVXSTTfX4mG7Mji9DCa0cpGTSy3Gk/wo1apV4z2R/BvbOIsGCrYmrT6izZ3bFq/TzTXvxyrwifCRMgLuqd0Gft/SI6XJZJGmiANUwBHYOiVIF//7oACugAOmL8jrGXrQakSo/WcvSk28pyOsZetBZBSj9ZyhaLr8OJe6IA4owoxrVSwwtYHGrsTGSSIQe1YBpqK3QQuOzD5MFpWz5MSWHQbNFSDQ7HWColaj/127v7ifiyY7Sj1PpUve2x55XiwRtFSSf1AGcFg41iKKxZp+AIKaUbfEwLeiDUcDdRhbQYkju3sRVUhb6CxWCtJMbIpItKRixIaC9FPhjRll6+VbI/gsT/SUFWnGhQFXKDrFAXqsWE//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////xbFLbZ/IAfSj1A0Go4giiYWKIJJkvUq99hHJX0HsEauwqnfpJyZgaAqaChYVmUTglYRVyTMB4qnBW28D6WyfXyT4M2V1r/2jWxbdbJL9IAdqHOT8VAS0pADk1JE9kTawUpMUaRzdmkna2p5apDbICcUwYmSGi2FF1g+bcPeFAkeJLyIsOqAT+v/7ogDOgAiqGsdjOXpASMO5DGcJSUfoVyGH5YcgxoqkMPwk5IW3a2R9AAHhAxhWi4nSfgIY/1VODSJHRxL+cdp/Yt3dl9x00vDKrZJdmyatz60h7wBWEssrbdIABtFIalKdOHp8i5J7ARfLN+BVaKECuBff/Hm7////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+6AA2oAOOAfIYW9gqhjBCMQd4iVAAAEuAAAAIBSAYxAAAAT///////////////////////8JNpEg4HAkxq4EyVpo2eggIVDbpf/4WULEAAgAAdT/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+6AA2wAPMABLgAAACAAACXAAAAEAAAEuAAAAIAAAJcAAAAT///////////////////////////////////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; a.play(); }, 129(btn) { showInStatusPanel("Right Long Press"); Cc["@mozilla.org/sound;1"].getService(Ci.nsISound).beep(); } }, }; // end Clicks, HotKeys ================================================== })("hookClicks-and-tooltips-test"); // END hookClicks
Отсутствует
не работает из секции по событию "load"
Да, точно, я вижу это, мой косяк.
Дело в том, что из этой точки, стэк вызовов (Components.stack.formattedStack)
будет выглядеть иначе (прицепится "load/"). Заменил пока regexp.
Отсутствует
А в данном случае это имеет значение? Предыдущий вариант, перемещённый в конец custom_script_win ведь тоже работал.
Да нет, никакого особого значения это, надеюсь, не имеет,
просто нехорошо, что из "load" не работало.
А по умолчанию никак заблокировать ?
Если типа из предусмотренного, то, похоже, что никак.
Либо «Всегда спрашивать», либо «Разрешить» (что-то даже разницы не пойму).
Выделить кодКод:
… install: { getDefault() { return Services.prefs.getBoolPref("xpinstall.whitelist.required") ? SitePermissions.UNKNOWN : SitePermissions.ALLOW; }, },
Отредактировано Dumby (23-02-2022 21:19:12)
Отсутствует
kokoss, xrun1, спасибо. Вечно забываю, что кнопка Перезапустить и заново создать кэш быстрого запуска в таких случаях не всегда помогает. А как бы ещё AkelPad заменить на notepad++?
Отредактировано voqabuhe (28-02-2022 04:21:45)
Отсутствует
Dumby - ещё одно неудобство Simple Session Manager в дополнение к перечисленным:
При запуске браузера восстанавливается [boot]-сессия (выделанная красным). Прошло несколько дней, запускаю браузер на другой машине и не понимаю, откуда каждый раз берутся открываемые вкладки.
Удобнее, чтобы при запуске лис показал сообщение (пробовал добавлять showAlertNotification, но в observe(s, t, data… это не работает):
…showAlertNotification(null, this.label, `Восстановление [boot]-сессии\n`+ ИМЯ восстанавливаемой сессии, false);
Отсутствует
в observe(s, t, data… это не работает
Конечно не работает, observe() вызывается по топику "quit-application",
там уже ни что подобное не возможно. Зачем вообще туда,
это ведь нечто противоположное «… чтобы при запуске лис показал …».
Тут нужно что-то в init() добавить, типа такого.
Не связанные, разумеется, напрямую вещи,
но не проверять же ещё что-то дополнительно.
… if (!Services.startup.wasRestarted && this.meta.boot != null) { var name = this.id + "-startup-notification"; var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); as.showAlertNotification( this.image, this.label, "Восстановление [boot]-сессии\n\n" + this.meta.order[this.meta.boot], false, null, null, name ); setTimeout(() => as.closeAlert(name), 5e3); }
Bug 1734987 - Part 2: Refactor verifySignedState to not require AddonInternal
Антиподписячий код с поправкой.
// try {(nsvo => { var g = Cu.getGlobalForObject(nsvo), o = g.Object, {freeze} = o, NEW; o.freeze = obj => { if (Components.stack.caller.filename != "resource://gre/modules/AppConstants.jsm") return freeze(obj); obj.MOZ_REQUIRE_SIGNING = false; if ((NEW = "MOZ_ALLOW_ADDON_SIDELOAD" in obj)) lockPref("extensions.experiments.enabled", true); else obj.MOZ_ALLOW_LEGACY_EXTENSIONS = true, lockPref("extensions.legacy.enabled", true); return (o.freeze = freeze)(obj); } lockPref("xpinstall.signatures.required", false); lockPref("extensions.langpacks.signatures.required", false); nsvo = Cu.import("resource://gre/modules/addons/XPIInstall.jsm", {}); var shouldVerify = nsvo.shouldVerifySignedState; if (shouldVerify.length == 1) nsvo.shouldVerifySignedState = addon => !addon.id && shouldVerify(addon); else { var {Services} = g.ChromeUtils.import("resource://gre/modules/Services.jsm"); var subst = "pkg-proto-patch-tmp-script"; var rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); var func = async proto => Object.assign(proto, eval( `({${proto.verifySignedState}})`.replace("(!", "(addonId || !") )); var code = encodeURIComponent(`(${func})(Package.prototype);`); rph.setSubstitution(subst, Services.io.newURI("data:," + code)); Services.scriptloader.loadSubScript(`resource://${subst}/`, nsvo); rph.setSubstitution(subst, null); } if (NEW) nsvo.XPIDatabase.isDisabledLegacy = () => false; })( "permitCPOWsInScope" in Cu ? Cu.import("resource://gre/modules/WebRequestCommon.jsm", {}) : Cu );} catch(ex) {Cu.reportError(ex);}
Отсутствует