Приветствую. Не совсем по теме, но т.к. в кнопках и дополнениях много общего спрошу здесь. В 131 FF кудесники наваяли-изменили так, что перестали работать звуковые уведомления в приложении "Мои уведомления", а разработчик аддона пропал. https://addons.mozilla.org/ru/firefox/a … ent=search
Farby, Dumby, не могли бы вы посмотреть, что изменилось в воспроизведении звуков уведомлений FF131 и скрипты аддона в XPI. Может у вас получится исправить.
Отредактировано manuk (27-09-2024 15:35:23)
На форуме
Dumby, не могли бы вы посмотреть, что изменилось в воспроизведении звуков уведомлений FF131 и скрипты аддона в XPI
FF130, скорее. Какой-то очень странный баг.
Лиса козлится, пишет какую-то дичь, типа
не поддерживается, не удалось загрузить медиаресурс,
не удалось воспроизвести, нет декодеров ...
Думал, может дело в .ogg — но замена на .mp3 хорошего результата не дала.
Думал, может дело в moz-extension:// — но с консоли браузера audio играется.
Тем не менее, по протоколам data: и blob: вроде работает, поэтому,
пока не найдено лучшего решения или не исправлен баг, можно так попробовать
/* playSound(sound, volume) { if (sound !== null && sound !== 'off') { let audio = new Audio() audio.src = sound audio.autoplay = true audio.volume = volume } } */ async playSound(sound, volume) { if (!sound || sound == "off") return; var resolver = Promise.withResolvers(); var reader = new FileReader(); reader.onload = resolver.resolve; reader.readAsDataURL(await (await fetch(sound)).blob()); await resolver.promise; var audio = new Audio(); audio.src = reader.result; audio.autoplay = true; audio.volume = volume; }
/* function playSound(siteSettings){ let options = JSON.parse(localStorage.getItem('options')) let audio = new Audio() audio.autoplay = true audio.src = siteSettings.sound ? siteSettings.sound : options.sound audio.volume = options.volume } */ var db = Object.create(null); async function playSound(siteSettings) { var options = JSON.parse(localStorage.getItem("options")); var audio = new Audio(); audio.autoplay = true; audio.volume = options.volume; var sound = siteSettings.sound || options.sound; audio.src = db[sound] ??= URL.createObjectURL(await (await fetch(sound)).blob()); }
Отсутствует
Dumby, большое спасибо. Прекрасно работает. Догадываюсь, что не одному мне это нужно. Где бы поделиться ссылкой на ваш пост с исправлениями аддона (может в отзывах о "Мои уведомления" на addons.mozilla.org)? Или, кто ищет - тот всегда найдёт?
Отредактировано manuk (28-09-2024 21:23:39)
На форуме
Где бы поделиться ссылкой
Увы, я не знаю где.
Подломали Custom Buttons.
Bug 71895 - Remove Hidden Window from Linux and Windows builds (Firefox 132+)
Bug 1917745 - Remove dom.window.sizeToContent.enabled pref (Firefox 132+)
Отсутствует
Dumby. перестала работать кнопка Экспорт в HTML файл в контекстном меню закладок
/*Initialization Code*/ //-------------------- Экспорт в HTML файл в контекстном меню закладок (popup => addEventListener("popupshowing", { handleEvent() { if (this.shouldHide()) return; var before = document.getElementById("placesContext_openSeparator"); Можно поправить? var menuitem = popup.insertBefore(document.createXULElement("menuitem"), before); menuitem.setAttribute("label", "Экспорт папки в HTML"); menuitem.setAttribute("oncommand", "exportFolder();"); menuitem.exportFolder = this.pick.bind(this); addDestructor(() => menuitem.remove()); (this.handleEvent = () => menuitem.hidden = menuitem.disabled = this.shouldHide())(); }, shouldHide() { var node = popup.triggerNode._placesNode; var hide = !node || node.type != node.RESULT_TYPE_FOLDER; if (!hide) this.guid = node.bookmarkGuid, this.title = node.title; return hide; }, pick() { var fp = makeFilePicker(); fp.init(window, PlacesUIUtils.getString("EnterExport"), fp.modeSave); fp.appendFilters(fp.filterHTML); fp.defaultString = (this.title ? DownloadPaths.sanitize(this.title) : "untitled") + ".html"; fp.open(res => res == fp.returnCancel || this.export(fp.file.path)); }, async export(path) { var tree = await PlacesUtils.promiseBookmarksTree( this.guid, {includeItemIds: true} ); var bookmarks = {children: [ {root: "toolbarFolder"}, {root: "unfiledBookmarksFolder"}, {root: "bookmarksMenuFolder", children: [tree], guid: PlacesUtils.bookmarks.menuGuid} ]}; new this.nsvo.BookmarkExporter(bookmarks).exportToFile(path); }, get nsvo() { delete this.nsvo; return this.nsvo = Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm", {}); } }, false, popup))(document.getElementById("placesContext") || 1);
Отредактировано Garalf (05-10-2024 20:12:16)
Отсутствует
А чего это «Можно поправить?» делает в коде?
Подлежит удалению.
перестала работать кнопка
Очень информативно. Хорошо, 129
/* fp.init(window, PlacesUIUtils.getString("EnterExport"), fp.modeSave); */ fp.init(window.browsingContext, PlacesUIUtils.promptLocalization.formatValueSync("places-bookmarks-export"), fp.modeSave);
Отсутствует
Dumby, большая просьба глянуть, если вам несложно. В браузере r3dfox 128 (и у 130) возник конфликт у последней CB (0.0.7.0.0.34-fx-paxmod) и utils от xiaoxiaoflood, конкретно с версией для скриптов и расширений. С версией только для скриптов конфликта нет, но мне расширения тоже нужны.
Выражается в том, что на странице дополнений становится невозможно посмотреть кнопки или детали расширений, всё перестаёт кликаться, вызывается только окно новой кнопки. В остальном всё работает, меню кнопок можно редактировать через меню правого клика. Проблема только на этой страничке.
И проблема с одной кнопкой (тоже в 128-130), перестала работать перезагрузка страницы в урлбаре, вот этот код
if (gURLBar.focused) { var str = gURLBar.value; getBrowser (). selectedTab = getBrowser (). addTab (str); gURLBar.handleCommand(); } else { BrowserReload(); }
self.image = "data:image/png;base64,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"; var urlbar=document.getElementById("page-action-buttons"); var button=document.getElementById(_id); urlbar.insertBefore(button,urlbar.Child); this.onclick=e=> {if(e.button==0)Rld(); //L if(e.button==1)gShowPopup(this); //M if(e.button==2 && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey){e.preventDefault();CURL();}};//R this.tooltipText="L: Reload\nR: CopyURL"; //////////////////////////////////////////////////////////////////// function Rld(){if (gURLBar.focused) { var str = gURLBar.value; getBrowser (). selectedTab = getBrowser (). addTab (str); gURLBar.handleCommand(); } else { BrowserReload(); } }; //////////////////////////////////////////////////////////////////// function CURL(){gClipboard.write(gURLBar.value); var gub=gURLBar.value,line1=' Адрес скопирован в буфер !',line=" "+line1,i=0; function line_a(){ if(i++<line.length){ gURLBar.value=line.substring (1,i)} setTimeout(function(){line_a()},10)} line_a(); setTimeout(function(){gURLBar.value = readFromClipboard()},1500)}; ////////////////////////////////////////////////////////////////////
Отсутствует
mega.nz
Серьёзно?! Ещё гэ-драйв предложи.
https://www.upload.ee/
Но даже он тут не обязателен, ибо utils невелик размером,
вполне поместится на форум в base64
такая же штука происходит и в обычном 131
Ладно, попробовал взять utils у onemen'а.
Конфликт похожий вижу.
Помогло подправить BootstrapLoader.js
`/* if (addon.__AddonInternal__.optionsType == 1/*AddonManager.OPTIONS_TYPE_DIALOG*/) /*`; if (addon.__AddonInternal__?.optionsType == 1) // AddonManager.OPTIONS_TYPE_DIALOG
Хотел попробовать предыдущую версию CB, но ссылка умерла.
Конечно, такое долго не живёт.
Если кто-то не исключает вероятности,
что может понадобиться «попробовать предыдущую»,
или любую другую, версию, то ожидается,
что он возьмёт её, вовремя скачанную, у себя с диска.
перестала работать перезагрузка страницы
Обсуждалось уже.
На всякий случай полный код кнопки
Функция CURL() ужасна!
При каждом вызове она образует бесконечную петлю
непрекращающейся таймаут-долбёжки, каждый раз новую,
сто раз в секунду, двести, триста...
Интересно, когда браузеру с такого поплохеет.
Вот, надеюсь, такая получше
function CURL() { var msg = " gURLBar.value скопировано в буфер !"; var tick = r => setTimeout(r, 10); var field = gURLBar.inputField, ed = field.editor; var {input} = gURLBar.view; var revert = () => { input._suppressStartQuery = true; ed.undo(); input._suppressStartQuery = false; } (CURL = async () => { gClipboard.write(gURLBar.value); ed.beginTransaction(); field.value = ""; for(char of msg) field.value += char, await new Promise(tick); ed.endTransaction(); setTimeout(revert, 1500); })(); }
Отсутствует
Dumby
Я извиняюсь, а что не так с мегой? Сто лет пользуюсь. Сперва не понял, потом как понял. Вы вот так не глядя, можете коды писать? Это что-то слишком запредельное, буквально сверхспособности
Помогло подправить BootstrapLoader.js
Да, работает! Один знак всего... Спасибо огромное!
что он возьмёт её, вовремя скачанную, у себя с диска.
Так не успел я вовремя какое-то время вообще на форум не заходил.
Обсуждалось уже.
Я искал, но не нашёл
Интересно, когда браузеру с такого поплохеет.
Функцию писал не я я даже так не могу, из этой темы брал, до сих пор проблем не было. И спасибо ещё раз, всё отлично работает!
Отредактировано kazarin (15-10-2024 23:43:49)
Отсутствует
Dumby
// Дополнительные возможности для значка идентификации сайта в строке адреса ..... (identBox => { var tip = "Л: Добавить закладку\nП: О странице"; var icon = gIdentityHandler._identityIcon; addEventListener("mouseenter", () => icon.setAttribute("tooltiptext", tip), false, icon || 1); addDestructor(() => icon.setAttribute("tooltiptext", gNavigatorBundle.getString("identity.icon.tooltip")) ); var listener = { handleEvent(e) { e.ctrlKey || e.shiftKey || e.detail > 1 || this[e.type](e); }, click(e) { if (e.button || !identBox.contains(e.target)) return; e.stopPropagation(); e.preventDefault(); this.bookmarkCurrentPage(gBrowser.selectedBrowser, true); identBox.setAttribute("style", "background: linear-gradient(#0080FF , blue) !important;border-radius: 2px !important; "); setTimeout(() => identBox.removeAttribute("style"), 1400); }, contextmenu(e) { e.preventDefault(); var url = gBrowser.currentURI.spec; BrowserPageInfo(url, url.startsWith("http") ? "permTab" : "permTab"); identBox.setAttribute("style", "background: linear-gradient(#0080FF , red) !important;border-radius: 2px !important; "); setTimeout(() => identBox.removeAttribute("style"), 1400); }, get bookmarkCurrentPage() { delete this.bookmarkCurrentPage; return this.bookmarkCurrentPage = eval(`(${ PlacesCommandHook.bookmarkPage.toSource() .replace("async", "$& function") .replace("unfiledGuid", "menuGuid") })`).bind(PlacesCommandHook); } }; addEventListener("click", listener, true, identBox.parentNode); addEventListener("contextmenu", listener, false, identBox); })(document.getElementById("identity-box") || 1);
Отредактировано ВВП (18-10-2024 00:07:53)
Отсутствует
Перезалейте пожалуйста Custom Buttons 0.0.7.0.0.34
Отсутствует
Как бы на среднюю reload вставить ?
После click(e) {
добавить
if (e.button == 1) return window.BrowserReload ? BrowserReload() : BrowserCommands.reload();
Перезалейте пожалуйста Custom Buttons 0.0.7.0.0.34
Вот, с небольшими правками.
Отсутствует
Bug 1919853 Make DevTools work with CSSNestedDeclarations objects. 132+
Больно ударил по DOMi, но есть такой вариант восстановить
/* this.mRules = viewer.DOMUtils.getCSSStyleRules(aObject); */ this.mRules = "getMatchingCSSRules" in viewer.DOMUtils ? viewer.DOMUtils.getMatchingCSSRules?.(aObject) : viewer.DOMUtils.getCSSStyleRules(aObject);
Жизнь иногда такое выкидывает, что хочется подобрать...
Отсутствует
Приветствую. Дошли руки до 132.0. И что? Как обычно "отвалилась" кнопочка" findbar.
/*Initialization Code*/ ((bar, button = true, insertAtTop = true, ctrlFcloseFinbar = false) => ({ init(parent) { var has = bar = parent.querySelector("#appcontent > findbar"); has || this.initFinbar(parent); var lo = bar.linkedObject; lo.listenCtrlF = ctrlFcloseFinbar ? listen => listen ? addEventListener("keydown", lo, true) : removeEventListener("keydown", lo, true) : () => {}; has && !bar.hidden && lo.listenCtrlF(true); if (button) self._handleClick = () => bar.hidden ? bar.startFind(bar.FIND_NORMAL) : bar.collapsed || bar.close(); addDestructor(lo.destroy, lo); }, destroy(reason) { if (reason[5] != "e") return; bar.close(); bar._browser = {}; bar.remove(); this.setProgressListener(false); if (!this.receiver) this.actorProto.receiveMessage = this.actorReceiveMessage; for(var key of ["gFindBar", "gFindBarInitialized"]) key in this && Object.defineProperty(window, key, this[key]); for(key of this.gBrKeys) gBrowser[key] = this[key]; Services.ppmm.removeDelayedProcessScript(this.url); Services.ppmm.loadProcessScript("data:," + encodeURIComponent(` (ai => ai.processType == ai.PROCESS_TYPE_DEFAULT || ai.processType == ai.PROCESS_TYPE_CONTENT)( Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime) ) && (nsvo => { var proto = nsvo.Finder.prototype; if ("_requestMatchesCount" in proto) { proto.requestMatchesCount = proto._requestMatchesCount; delete proto._requestMatchesCount; } })(Cu.import("resource://gre/modules/Finder.jsm", {}));` ) , false); }, initFinbar(parent) { for(var tab of gBrowser.tabs) { if (!tab._findBar) continue; tab._findBar.browser = null; tab._findBar._browser = {}; tab._findBar.remove(); delete tab._findBar; } bar = document.createXULElement("findbar"); var p = new Proxy({}, {get: () => () => {}}); bar._browser = {finder: p, messageManager: p}; parent.insertBefore(bar, insertAtTop ? parent.firstChild : null); bar.linkedObject = this; ["gFindBar", "gFindBarInitialized"].forEach((key, ind) => { var desc = Object.getOwnPropertyDescriptor(window, key); if (!desc.configurable) return; this[key] = desc; delete window[key]; window[key] = ind ? true : bar; }); var key = "getCachedFindBar" in gBrowser ? "getCachedFindBar" : "getFindBar"; this.gBrKeys = [key]; key = "isFindBarInitialized"; if (key in gBrowser) this.gBrKeys.push(key); this.gBrKeys.forEach((key, ind) => { this[key] = gBrowser[key]; gBrowser[key] = ind ? () => true : () => bar; }); var props = [ "close", "startFind", "onMatchesCountResult", "_updateMatchesCount", "_onBrowserKeypress" ]; if ((this.receiver = "receiveMessage" in bar)) props.push("receiveMessage"); else { this.actorProto = Object.getPrototypeOf( gBrowser.selectedBrowser.browsingContext.currentWindowGlobal.getActor("FindBar") ); this.actorReceiveMessage = this.actorProto.receiveMessage; this.actorProto.receiveMessage = msg => { if (msg.name == "Findbar:Keypress") bar._onBrowserKeypress(msg.data); else if (msg.name == "Findbar:Mouseup") bar.onMouseUp(); } } props.forEach((key, ind) => { var func = bar[key].bind(bar); bar[key] = ind ? (...args) => this[key](...args) || func(...args) : (...args) => func(...args) || this[key](...args); }); this.url = "data:," + encodeURIComponent(` (ai => ai.processType == ai.PROCESS_TYPE_DEFAULT || ai.processType == ai.PROCESS_TYPE_CONTENT)( Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime) ) && (nsvo => { var proto = nsvo.Finder.prototype; if ("_requestMatchesCount" in proto) return; proto._requestMatchesCount = proto.requestMatchesCount; proto.requestMatchesCount = ${ this.newRequestMatchesCount } })(Cu.import("resource://gre/modules/Finder.jsm", {}));` ); delete this.newRequestMatchesCount; Services.ppmm.loadProcessScript(this.url, true); var desc = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value"); var setValue = desc.set.bind(bar._findField); desc.set = val => Components.stack.formattedStack.includes( "set browser@chrome://global/content/elements/findbar.js" ) ? val : setValue(val); Object.defineProperty(bar._findField, "value", desc); }, newRequestMatchesCount: async function requestMatchesCount(aWord, aLinksOnly, aUseSubFrames = true) { if (aLinksOnly && aLinksOnly.constructor.name == "Object") { var {linksOnly, data} = aLinksOnly; aLinksOnly = linksOnly; this.entireWord = data.entireWord; this.caseSensitive = data.caseSensitive; this.onModalHighlightChange(data.useModalHighlight); this.onHighlightAllChange(data.highlightAll); data.highlightAll && await this.highlighter.highlight(true, aWord, linksOnly); this._iterator && this._iterator.reset(); var obj; Object.defineProperty(this, "_currentMatchesCountResult", { configurable: true, enumerable: true, get: (val = obj) => { if (val && val._currentFound) val.total = Math.floor(val.total) + .0001; return obj = val; }, set: val => { if (val) { val.total = 10000; return obj = val; } delete this._currentMatchesCountResult; return obj = this._currentMatchesCountResult = val; } }); } return await this._requestMatchesCount(aWord, aLinksOnly, aUseSubFrames); }, close() { bar.collaped = false; this.setProgressListener(false); this.setBrowser(null, null); }, startFind() { if (this.maybeCollapse(gBrowser.selectedBrowser)) return true; if (bar.hidden) this.setBrowser(300), this.setProgressListener(true); else if (!ctrlFcloseFinbar) setTimeout(() => this.updateMatchesCount(), 100); }, get pf() { delete this.pf; return this.pf = bar.pluralForm || ChromeUtils.import( "resource://gre/modules/PluralForm.jsm" ).PluralForm; }, onMatchesCountResult(res) { if (res.total <= 1000) return; var strTotal = String(res.total); var found = strTotal.includes("."); if (found) strTotal = strTotal.split(".")[0]; if ((res.total = +strTotal.slice(-4)) >= 1000) { res.total = -1; return; } if (res.current > 1000) res.current = +String(res.current).slice(-4); if (res.current && found) return; bar._foundMatches.value = `${+res.total || "Нет"} совпадени${ this.pf.get(res.total, "е;я;й") }.`; bar._foundMatches.hidden = false; return true; }, _updateMatchesCount() { return true; }, _onBrowserKeypress(e) { if (!bar.hidden) return; if (!e.charCode) return true; this.setBrowser(300); this.setProgressListener(true); }, receiveMessage(msg) { msg.target = bar._browser; }, progressListenerAdded: false, setProgressListener(add) { if (add) { if (this.progressListenerAdded) return; this.progressListenerAdded = true; gBrowser.addProgressListener(this); this.listenCtrlF(true); } else { if (!this.progressListenerAdded) return; this.progressListenerAdded = false; gBrowser.removeProgressListener(this); this.listenCtrlF(false); } }, handleEvent(e) { if ( e.ctrlKey && e.code == "KeyF" && !e.shiftKey && !e.altKey && !bar.collapsed ) e.preventDefault(), e.stopPropagation(), bar.close(); }, updateMatchesCount() { var str = bar._findField.value; if (!str) return; var data = { entireWord: bar._entireWord, caseSensitive: bar._typeAheadCaseSensitive, highlightAll: bar._highlightAll, useModalHighlight: bar._useModalHighlight }; bar.browser.finder.requestMatchesCount( bar._findField.value, {linksOnly: bar._findMode == bar.FIND_LINKS, data} ); }, maybeCollapse(br) { return br.isSyntheticDocument || br.documentContentType == "application/vnd.mozilla.xul+xml"; }, setBrowser(updateDelay, br = gBrowser.selectedBrowser) { if (bar._browser != br) { var b = bar._browser; if (b) { this.receiver && b.messageManager .removeMessageListener("Findbar:Mouseup", bar); b.finder.removeResultListener(bar); bar._highlightAll && b.finder.highlight(false); } if (br) { this.receiver && br.messageManager .addMessageListener("Findbar:Mouseup", bar); bar._updateBrowserWithState(); } bar._browser = br; } if (!br) return; bar._updateStatusUI(); bar._foundMatches.value = ""; br.finder.addResultListener(bar); if ( !(bar.collapsed = this.maybeCollapse(br)) && br.currentURI.spec != "about:blank" && updateDelay !== null ) updateDelay ? setTimeout(this.updateMatchesCount, updateDelay) : this.updateMatchesCount(); }, onStateChange(wpr, req, state) { state & Ci.nsIWebProgressListener.STATE_STOP && this.setBrowser(); }, onLocationChange(wpr, req) { req || wpr.isLoadingDocument || gBrowser.selectedTab.hasAttribute("pending") || this.setBrowser(); } }).init(document.getElementById("appcontent")))();
Отредактировано manuk (30-10-2024 14:11:03)
На форуме
если не в тягость
Шутишь? Она была в тягость с самого начала.
Отвал на 132 — это Bug 1916098 - Remove appcontent box.
Ладно, чисто формально, немного подправил-почистил всякое старьё.
Копаться в этом, тестировать, желания нет, и впредь, лучше меня о ней не спрашивать.
((bar, button = true, insertAtTop = true, ctrlFcloseFinbar = false) => ({ init(parent) { var has = bar = parent.querySelector(":scope > findbar"); has || this.initFinbar(parent); var lo = bar.linkedObject; lo.listenCtrlF = ctrlFcloseFinbar ? listen => listen ? addEventListener("keydown", lo, true) : removeEventListener("keydown", lo, true) : () => {}; has && !bar.hidden && lo.listenCtrlF(true); if (button) self._handleClick = () => bar.hidden ? bar.startFind(bar.FIND_NORMAL) : bar.collapsed || bar.close(); addDestructor(lo.destroy, lo); }, destroy(reason) { if (reason[5] != "e") return; bar.close(); bar._browser = {}; bar.remove(); this.setProgressListener(false); this.actorProto.receiveMessage = this.actorReceiveMessage; for(var key of ["gFindBar", "gFindBarInitialized"]) key in this && Object.defineProperty(window, key, this[key]); for(key of this.gBrKeys) gBrowser[key] = this[key]; Services.ppmm.removeDelayedProcessScript(this.url); Services.ppmm.loadProcessScript("data:," + encodeURIComponent(`(url => { var ai = Services.appinfo, pt = ai.processType; if (pt != ai.PROCESS_TYPE_DEFAULT && pt != ai.PROCESS_TYPE_CONTENT) return; var proto = ChromeUtils.importESModule(url).Finder.prototype; if ("_requestMatchesCount" in proto) proto.requestMatchesCount = proto._requestMatchesCount, delete proto._requestMatchesCount; })("resource://gre/modules/Finder.sys.mjs");`), false); }, initFinbar(parent) { for(var tab of gBrowser.tabs) { if (!tab._findBar) continue; tab._findBar.browser = null; tab._findBar._browser = {}; tab._findBar.remove(); delete tab._findBar; } bar = document.createXULElement("findbar"); var p = new Proxy({}, {get: () => () => {}}); bar._browser = {finder: p, messageManager: p}; parent.insertBefore(bar, insertAtTop ? parent.firstChild : null); bar.linkedObject = this; ["gFindBar", "gFindBarInitialized"].forEach((key, ind) => { var desc = Object.getOwnPropertyDescriptor(window, key); if (!desc.configurable) return; this[key] = desc; delete window[key]; window[key] = ind ? true : bar; }); (this.gBrKeys = ["getCachedFindBar", "isFindBarInitialized"]).forEach((key, ind) => { this[key] = gBrowser[key]; gBrowser[key] = ind ? () => true : () => bar; }); [ "close", "startFind", "onMatchesCountResult", "_updateMatchesCount", "_onBrowserKeypress" ] .forEach((key, ind) => { var func = bar[key].bind(bar); bar[key] = ind ? (...args) => this[key](...args) || func(...args) : (...args) => func(...args) || this[key](...args); }); this.actorProto = Object.getPrototypeOf( gBrowser.selectedBrowser.browsingContext.currentWindowGlobal.getActor("FindBar") ); this.actorReceiveMessage = this.actorProto.receiveMessage; this.actorProto.receiveMessage = msg => { if (msg.name == "Findbar:Keypress") bar._onBrowserKeypress(msg.data); else if (msg.name == "Findbar:Mouseup") bar.onMouseUp(); } this.url = "data:," + encodeURIComponent(`(url => { var ai = Services.appinfo, pt = ai.processType; if (pt != ai.PROCESS_TYPE_DEFAULT && pt != ai.PROCESS_TYPE_CONTENT) return; var proto = ChromeUtils.importESModule(url).Finder.prototype; if ("_requestMatchesCount" in proto) return; proto._requestMatchesCount = proto.requestMatchesCount; proto.requestMatchesCount = ${this.newRequestMatchesCount} })("resource://gre/modules/Finder.sys.mjs");`); delete this.newRequestMatchesCount; Services.ppmm.loadProcessScript(this.url, true); var desc = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value"); var setValue = desc.set.bind(bar._findField); desc.set = val => Components.stack.formattedStack.includes( "set browser@chrome://global/content/elements/findbar.js" ) ? val : setValue(val); Object.defineProperty(bar._findField, "value", desc); }, newRequestMatchesCount: async function requestMatchesCount(aWord, aLinksOnly, aUseSubFrames = true) { if (aLinksOnly && aLinksOnly.constructor.name == "Object") { var {linksOnly, data} = aLinksOnly; aLinksOnly = linksOnly; this.entireWord = data.entireWord; this.caseSensitive = data.caseSensitive; this.onModalHighlightChange(data.useModalHighlight); this.onHighlightAllChange(data.highlightAll); data.highlightAll && await this.highlighter.highlight(true, aWord, linksOnly); this._iterator && this._iterator.reset(); var obj; Object.defineProperty(this, "_currentMatchesCountResult", { configurable: true, enumerable: true, get: (val = obj) => { if (val && val._currentFound) val.total = Math.floor(val.total) + .0001; return obj = val; }, set: val => { if (val) { val.total = 10000; return obj = val; } delete this._currentMatchesCountResult; return obj = this._currentMatchesCountResult = val; } }); } return await this._requestMatchesCount(aWord, aLinksOnly, aUseSubFrames); }, close() { bar.collaped = false; this.setProgressListener(false); this.setBrowser(null, null); }, startFind() { if (this.maybeCollapse(gBrowser.selectedBrowser)) return true; if (bar.hidden) this.setBrowser(300), this.setProgressListener(true); else if (!ctrlFcloseFinbar) setTimeout(() => this.updateMatchesCount(), 100); }, onMatchesCountResult(res) { if (res.total <= 1000) return; var strTotal = String(res.total); var found = strTotal.includes("."); if (found) strTotal = strTotal.split(".")[0]; if ((res.total = +strTotal.slice(-4)) >= 1000) { res.total = -1; return; } if (res.current > 1000) res.current = +String(res.current).slice(-4); if (res.current && found) return; var n = res.total, fm = bar._foundMatches; fm.value = `${n || "Нет"} совпадени${"еяй"[ n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2 ]}.`; fm.hidden = false; fm.removeAttribute("data-l10n-id"); return true; }, _updateMatchesCount() { return true; }, _onBrowserKeypress(e) { if (!bar.hidden) return; if (!e.charCode) return true; this.setBrowser(300); this.setProgressListener(true); }, progressListenerAdded: false, setProgressListener(add) { if (add) { if (this.progressListenerAdded) return; this.progressListenerAdded = true; gBrowser.addProgressListener(this); this.listenCtrlF(true); } else { if (!this.progressListenerAdded) return; this.progressListenerAdded = false; gBrowser.removeProgressListener(this); this.listenCtrlF(false); } }, handleEvent(e) { if ( e.ctrlKey && e.code == "KeyF" && !e.shiftKey && !e.altKey && !bar.collapsed ) e.preventDefault(), e.stopPropagation(), bar.close(); }, updateMatchesCount() { var str = bar._findField.value; if (!str) return; var data = { entireWord: bar._entireWord, caseSensitive: bar._typeAheadCaseSensitive, highlightAll: bar._highlightAll, useModalHighlight: bar._useModalHighlight }; bar.browser.finder.requestMatchesCount( bar._findField.value, {linksOnly: bar._findMode == bar.FIND_LINKS, data} ); }, maybeCollapse: br => br.isSyntheticDocument, setBrowser(updateDelay, br = gBrowser.selectedBrowser) { if (bar._browser != br) { var b = bar._browser; if (b) { b.finder.removeResultListener(bar); bar._highlightAll && b.finder.highlight(false); } if (br) bar._updateBrowserWithState(); bar._browser = br; } if (!br) return; bar._updateStatusUI(); bar._foundMatches.value = ""; br.finder.addResultListener(bar); if ( !(bar.collapsed = this.maybeCollapse(br)) && br.currentURI.spec != "about:blank" && updateDelay !== null ) updateDelay ? setTimeout(this.updateMatchesCount, updateDelay) : this.updateMatchesCount(); }, onStateChange(wpr, req, state) { state & Ci.nsIWebProgressListener.STATE_STOP && this.setBrowser(); }, onLocationChange(wpr, req) { req || wpr.isLoadingDocument || gBrowser.selectedTab.hasAttribute("pending") || this.setBrowser(); } }).init(document.getElementById("tabbrowser-tabbox")))();
Отсутствует