Приветствую. Не совсем по теме, но т.к. в кнопках и дополнениях много общего спрошу здесь. В 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")))();
Отсутствует
Dumby
На https://addons.mozilla.org/ru/firefox/ никак версию не обмануть ? Ковырянием в omni и настройках - не катит. Панчить исходник и DLL ?
Манифест рихтовать всякий раз приходится...
Отсутствует
https://addons.mozilla.org
Дела контентские...
Увы, здесь я бесполезен.
Тем не менее, скрипты-то запрещены,
и я не вижу, чтобы AMO превратили в говнище.
Вот посетил попс, и смог скачать
как заявленную актуальную версию (1.60.0),
так и какую-то двадцать второго года (1.44.4).
Ну, в смысле, через ПКМ —> «Сохранить объект как…»
Отсутствует
Dumby
Перестала работать кнопка Экспорт закладок в HTML-файл
(obj => { this._handleClick = () => obj.popup.openPopup(this, "after_start"); this.onmouseenter = e => this.tooltipText = this.label + "\nЛ: Меню кнопки\nП: CB меню\n\nПапка для экспорта:\n" + (obj.path || "Не установлено."); addDestructor(reason => reason == "delete" && Services.prefs.clearUserPref(obj.pref)); })({ get popup() { var popup = document.createElementNS(xulns,"menupopup"); popup.setAttribute("oncommand", "linkedObject[event.target.value]();"); popup.linkedObject = this; var keys = ["label", "value", "image"]; for(var data of [ ["Экспорт закладок в HTML-файл", "export", "data:image/x-icon;base64,AAABAAEAEhIAAAEAIACABQAAFgAAACgAAAASAAAAJAAAAAEAIAAAAAAAWAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////8AAAAAAAAAAAAAAAAAAAAADg/o/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////8AAAAAAAAAAAAAAAAAAAAADg/o/w4P6P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////8AAAAAAAAAAAAAAAAAAAAADg/o/zUq6P8OD+j/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////8AAAAAAAAAAAAAAAAAAAAADg/o/0RC//0cE+X/Dg/o/wAAAAAAAAAAAAAAAAAAAAAAAAAA/////xQW5/8tMOT/Njfw/0BA+v9JSP//UU///1hT//9aVv3/RUL5/zQy+f8zNPH/JSHa/w4P6P8AAAAAAAAAAAAAAAAAAAAA/////xAR5v0UFeL/Hh7v/Soo+P80Mf39PDn+/0I+//05NPn/F5sr/zlO0/08PeL/NDbb/Rwdyv8OD+j/AAAAAAAAAAAAAAAA/////w4P6P8XGOn/Hh7x/yQk9f8rKvX/MjD1/zk0+f85NPn/F5sr/xebK/8lQ6n/Hx/D/w4P6P8AAAAAAAAAAAAAAAAAAAAA/////w4P6P8OD+j/Dg/o/w4P6P8OD+j/Dg/o/w4P6P8OD+j/F5sr/zfyX/0Xmyv/Dg/o/wAAAAAAAAAAAAAAAAAAAAAAAAAA/////33EgP+W8J//m/Sk/6D5qv+k/K7/qPyz/6z8uP9t2H7/QuJf/zz/Xv8f7UX/F5sr/wAAAAAAAAAAAAAAAAAAAAAAAAAA/////wOQFP8f5D3/KexI/zL3U/87/V3/Qf9k/0T/aP9K/2v/Qf9j/zn5Wf8571X/Kt1J/xebK/8AAAAAAAAAAAAAAAAAAAAA/////weUGf0Y6Tj/IvNE/Sn6Tv81/lj9Pv9h/0X9Z/1H/mf/Rvpk/0HvXP064VP/MtZL/RrHN/8Xmyv/AAAAAAAAAAAAAAAA/////wmYHP8JmBz/CZgc/wmYHP8JmBz/CZgc/wmYHP8JmBz/CZgc/zjgUf8x1kj/FMIy/xebK/8AAAAAAAAAAAAAAAAAAAAA//////////////////////////8AAAAAAAAAAAAAAAAAAAAAKL08/zDXSP0NvCz/F5sr/wAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////8AAAAAAAAAAAAAAAAAAAAAHKsv/xS9Lv8Xmyv/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////8AAAAAAAAAAAAAAAAAAAAAF5sr/xebK/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////8AAAAAAAAAAAAAAAAAAAAAF5sr/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//8AAg9/AAIPPwACDx8AAg8PAAIABwACAAMAAgAHAAIADwACAA8AAgAHAAIAAwACAAcAAg8PAAIPHwACDz8AAg9/AAP//wAA="], ["Импорт закладок из HTML-файла", "import", "data:image/x-icon;base64,AAABAAEAEhIAAAEAIACABQAAFgAAACgAAAASAAAAJAAAAAEAIAAAAAAAWAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////8AAAAADg/o/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////8OD+j/Dg/o/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////////////w4P6P81Kuj/Dg/o/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////Dg/o/xwT5f9EQv/9Dg/o/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8OD+j/JSHa/zM08f80Mvn/RUL5/1pW/f9YU///UU///0lI//9AQPr/Njfw/y0w5P8UFuf/AAAAAAAAAAAAAAAA/////w4P6P8cHcr/NDbb/Tw94v85TtP9F5sr/zk0+f9CPv/9PDn+/zQx/f0qKPj/Hh7v/RQV4v8QEeb9AAAAAAAAAAAAAAAA//////////8OD+j/Hx/D/yVDqf8Xmyv/F5sr/zk0+f85NPn/MjD1/ysq9f8kJPX/Hh7x/xcY6f8OD+j/AAAAAAAAAAAAAAAA////////////////Dg/o/xebK/838l/9F5sr/w4P6P8OD+j/Dg/o/w4P6P8OD+j/Dg/o/w4P6P8OD+j/AAAAAAAAAAAAAAAA////////////////F5sr/x/tRf88/17/QuJf/23Yfv+s/Lj/qPyz/6T8rv+g+ar/m/Sk/5bwn/99xID/AAAAAAAAAAAAAAAA//////////8Xmyv/Kt1J/znvVf85+Vn/Qf9j/0r/a/9E/2j/Qf9k/zv9Xf8y91P/KexI/x/kPf8DkBT/AAAAAAAAAAAAAAAA/////xebK/8axzf/MtZL/TrhU/9B71z9Rvpk/0f+Z/9F/Wf9Pv9h/zX+WP0p+k7/IvNE/RjpOP8HlBn9AAAAAAAAAAAAAAAA//////////8Xmyv/FMIy/zHWSP844FH/CZgc/wmYHP8JmBz/CZgc/wmYHP8JmBz/CZgc/wmYHP8JmBz/AAAAAAAAAAAAAAAA////////////////F5sr/w28LP8w10j9KL08/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////////////xebK/8UvS7/HKsv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////8Xmyv/F5sr/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////8AAAAAF5sr/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//8AAgv/AAID/wACA/8AAgP/AAIAAwACAAMAAgADAAIAAwACAAMAAgADAAIAAwACAAMAAgP/AAID/wACA/8AAgv/AAP//wAA="], , ["Открыть папку для экспорта закладок", "reveal", "data:image/x-icon;base64,AAABAAEAEhIAAAEAIACABQAAFgAAACgAAAASAAAAJAAAAAEAIAAAAAAAWAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAABAAAAAWAAAAFQAAABQAAAAUAAAAEwAAABIAAAASAAAAEQAAABAAAAAPAAAADwAAAA4AAAALAAAAAwAAAAAAAAAHAAAALAAAAFUAAABjAAAAYgAAAGEAAABgAAAAYAAAAF0AAABcAAAAWwAAAFsAAABYAAAAVwAAAFYAAABJAAAAKAAAAAcAAAAXCgoKbomJid+Tk5PpkJCQ6I2NjeaLi4vjioqK4oWFhd+FhYXffX193H5+ftt1dXXYc3Nz2HFxcdVoaGjKBAQEawAAABoAAAAhgICAxcTExP++vr7/vr6+/76+vv++vr7/vr6+/76+vv+/v7//v7+//7+/v//AwMD/wMDA/8DAwP/Gxsb/j4+P0wAAACYAAAAjkpKSz8zMzP/Hx8f9x8fH/8fHx/3Hx8f9x8fH/cfHx/3Hx8f/x8fH/cfHx/3Hx8f9x8fH/8fHx/3Jycn/sbGx4gAAACkAAAAkm5ub0tjY2P/T09P909PT/9PT0/3T09P+09PT/tPT0/3T09P/09PT/dPT0/7T09P909PT/9PT0/3W1tb/tbW13wAAACcAAAAloqKi1OHh4f/c3Nz93Nzc/9zc3P3c3Nz+3Nzc/tzc3P3c3Nz/3Nzc/dzc3P7c3Nz93Nzc/9zc3P3g4OD/tra23QAAACYAAAAmqamp1+fn5//i4uL94uLi/+Li4v3i4uL94uLi/eLi4v3i4uL/4uLi/eLi4v3i4uL94uLi/+Li4v3m5ub/s7Oz2gAAACYAAAAnt7e32uzs7P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/t7e3/r6+v1wAAACUAAAAnw8PD3fHx8f/t7e397e3t/+3t7f3t7e397e3t/e3t7f3t7e3/7e3t/e3t7f3t7e397e3t/+3t7f3y8vL/sLCw0wAAACEAAAApy8vL3/b29v/y8vL98vLy//Ly8v3y8vL+8vLy/vHx8f3x8fH/9PT0//T09P/09PT/9PT0//Ly8v77+/v/tra2xQAAABIAAAAl19fX4fr6+v/39/f99/f3//f39/339/f99/f3/v7+/v//////7Ozs6OPj4+Xl5eXo6+vr6v///+/s7OzfJCQkRBEREQMAAAAT0tLS0P///////////////////////////////7y8vL0JCQktCgoKCQ4ODgcMDAwHERERCBMTEwkREREEMzMzAQAAAAAPDw8EGxsbOcTExL3Pz8/Ozs7Oz9DQ0NPFxcXCYGBgbgAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALi4uAR0dHQEREREEEhISBRAQEAMaGhoCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//8AAgABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAB/wACB/8AA///AAP//wAA="], ["Экспорт закладок в HTML без запроса", "silentExport", "data:image/x-icon;base64,AAABAAEAEhIAAAEAIACABQAAFgAAACgAAAASAAAAJAAAAAEAIAAAAAAAWAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAHAAAAAwAAAAAAAAANAAAAMwAAAEsAAABOAAAATgAAAE4AAABOAAAATgAAAE4AAABOAAAATgAAAE4AAABOAAAATgAAAE8AAABKAAAAMQAAAAwAAAAuLCwsl2tra89nZ2fNZ2dnz2dnZ89nZ2fPZ2dnz2dnZ89nZ2fPZ2dnz2dnZ89nZ2fPZ2dnz2dnZ81sbGzPKCgokwAAACsAAABHy8vL/7+/v/+/v7//v7+//729vf+/v7//v7+//7+/v/+/v7//v7+//76+vv++vr7/vr6+/7+/v/+/v7//ycnJ/wAAAEIKCgpQ0tLS/8PDw//Dw8P/wsLC/+fn5/3CwsL/w8PD/8PDw//Dw8P/wsLC/8nJyf/V1dX/x8fH/8PDw//ExMT/0tLS/wAAAEkJCQlQ39/f/9DQ0P/Q0ND/29vb/ykpKbfb29v/0NDQ/9DQ0P/Ozs7/7u7u/6ioqMVsbGyqvr6+0ujo6P/Pz8//39/f/wAAAEgKCgpQ6+vr/9vb2//b29v/5+fn/zIyMrfn5+f/29vb/9vb2//w8PD/ODg4jAAAAHw/Pz+oAAAAcHZ2dqvm5ub/6+vr/wAAAEgJCQlQ8PDw/9/f3//f39//7Ozs/zMzM7fs7Oz/39/f/+Tk5P+urq7ZAAAAa+jo6Prx8fH/w8PD5QAAAGPf39/18vLy/wAAAEgICAhQ9/f3/+bm5v/m5ub/8vLy/zQ0NLfy8vL/5ubm/+zs7P+RkZHOEhISd//////o6Oj//////gAAAGTLy8vq+fn5/wAAAEgJCQlQ/f39/+zs7P/s7Oz/+fn5/zMzM7j5+fn/7Ozs/+7u7v/l5eX3AAAAdoODg7Lq6urmUFBQmwQEBIr5+fn//f39/wAAAEgKCgpN//////Hx8f/x8fH//Pz8/0RERMH8/Pz/8fHx//Hx8f/4+Pj/vb294wAAAJAAAAB6GRkZnN3d3fH09PT//////wAAAEYFBQU3//////X19f/19fX/9fX1///////4+Pj/+Pj4//j4+P/4+Pj//f39//////////////////v7+//4+Pj//////wAAAC8AAAAKfn5+j/39/fn5+fn//Pz8/+Pj4+Pd3d3X3d3d193d3dfd3d3X3d3d193d3dfd3d3X3d3d193d3dfj4+PYeHh4ggcHBwkAAAAAAAAACZubm6b//////////gAAAC0FBQUGDQ0NBA4ODgQNDQ0EDQ0NBA0NDQQNDQ0EDQ0NBA0NDQQaGhoCAAAAAAAAAAAAAAAAFxcXARkZGQs3NzcwISEhHSkpKQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//8AAgABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAwACD/8AA///AAP//wAA="] ]) if (data) { var menuitem = popup.appendChild(document.createElementNS(xulns,"menuitem")); menuitem.className = "menuitem-iconic"; keys.forEach((key, ind) => menuitem.setAttribute(key, data[ind])); } else popup.appendChild(document.createElementNS(xulns,"menuseparator")); delete this.popup; return this.popup = self.appendChild(popup); }, get BookmarkHTMLUtils() { delete this.BookmarkHTMLUtils; Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm", this); return this.BookmarkHTMLUtils; }, pref: "CB.exportsBookmarksToHTMLFile.path", get path() { return Services.prefs.getStringPref(this.pref, null); }, pick(title, modeOpen) { var fp = makeFilePicker(); fp.init(window, title, modeOpen ? fp.modeOpen : fp.modeGetFolder); modeOpen && fp.appendFilters(fp.filterHTML); var {path} = this; if (path) fp.displayDirectory = FileUtils.File(path); return new Promise(resolve => fp.open( res => resolve(res == fp.returnOK && fp.file) )); }, async import() { var file = await this.pick("Выберите HTML-файл для импорта закладок", true); file && this.BookmarkHTMLUtils.importFromFile(file.path).then(null, alert); }, async export(justSetPath) { var dir = await this.pick("Укажите папку для экспорта закладок!"); if (!dir) return; dir.path != this.path && Services.prefs.setStringPref(this.pref, dir.path); justSetPath || this.silentExport(dir); }, silentExport(dir) { if (!dir && !(dir = this.checkPath(this.path))) return; dir.append("bookmarks-" + new Date().toLocaleDateString("mn") + ".html"); this.BookmarkHTMLUtils.exportToFile(dir.path) .then(() => this.notify(dir.path), alert); }, ns: "Папка для экспорта не установлена.\n\nУстановить папку?", nf: path => `Папка для экспорта не найдена.\n${path}\n\nВыбрать другую?`, checkPath(path, justSetPath) { if (!path) return void(confirm(this.ns) && this.export(justSetPath)); var dir = FileUtils.File(path); if (dir.exists() && dir.isDirectory()) return dir; confirm(this.nf(path)) && this.export(justSetPath); }, reveal() { var dir = this.checkPath(this.path, true); dir && dir.reveal(); }, get notify() { var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); var func = path => setTimeout(as.closeAlert, 3500, as.showAlertNotification( self.image, self.label, "Экспортировал закладки как HTML в " + path )); delete this.notify; return this.notify = func; } });
Посмотри пожалуйста...
Отсутствует