kazarin - надо проверять ссылки, которые даёшь! Там файлы недоступны уже!
custom_buttons-0.0.7.0.0.17-fx-paxmod.xpi bootstrap
dom_inspector-7.0.9-fx-paxmod.xpi bootstrap
Отсутствует
Привет. Подскажите, почему я не могу получить выделенный текст?
И как можно получить выделенный текст самым простым способом?
var w = document.commandDispatcher.focusedWindow, d = w.document, q = w.getSelection().toString(); alert(q);
Отсутствует
почему я не могу получить выделенный текст?
Что значит «не могу»? Вместо alert'а что? Вообще ничего не происходит?
Или сразу краш? Или фига (кукиш) во весь экран? Или что-то ещё альтернативное?
Отсутствует
Необходимо получить куки, определённой вкладки, я новичок, помогите! Тут нашёл,
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/Tab
Что нужно подключить, чтобы работало? Нужно получить все куки вкладки, включая HttpOnly.
Отредактировано Deriax (03-05-2021 22:08:23)
Отсутствует
Путой алерт получается.
Пустой алерт означает, что в окне «document.commandDispatcher.focusedWindow»
ничего не выделено (выделенное в текстовых полях не считается, и никогда не считалось).
Текст на странице выделен, клик по кнопке
Кнопка находится в одном, родительском, процессе,
а текст на странице, как и сама страница, скорее всего, в другом, контентском, процессе.
Можешь проверить на странице, которая заведомо откроется в основном процессе,
например about:support (там выделенное будет алертиться так, как, наверно, и ожидалось).
Тут нашёл,
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/Tab
Где, интересно, «тут» могли куки померещиться?
Отсутствует
Cytrus пишетПутой алерт получается.
Пустой алерт означает, что в окне «document.commandDispatcher.focusedWindow»
ничего не выделено (выделенное в текстовых полях не считается, и никогда не считалось).Текст на странице выделен, клик по кнопке
Кнопка находится в одном, родительском, процессе,
а текст на странице, как и сама страница, скорее всего, в другом, контентском, процессе.
Можешь проверить на странице, которая заведомо откроется в основном процессе,
например about:support (там выделенное будет алертиться так, как, наверно, и ожидалось).Deriax пишетТут нашёл,
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/TabГде, интересно, «тут» могли куки померещиться?
Отсутствует
14f477a2ce81.png
Фу, в переводе это выглядит ещё более непонятно, чем в оригинале.
На самом деле, cookieStoreId — это всего лишь id'шник контейнера,
то есть, всего лишь уточняющий параметр для cookies.get() (и компании), не более того.
Типа — кука, именуемая так-то, с урлом каким-то эдаким, ограниченная контейнером (cookieStoreId) таким-то.
Еще раз: никакого «Хранилища файлов cookie вкладки» (так, как это звучит!) не существует.
Отредактировано Dumby (04-05-2021 02:11:30)
Отсутствует
Подскажите, а как можно получить URL по клику на ссылке?
document.addEventListener('click',e => { if (e.button!=0){return;} if (e.altKey){ e.preventDefault(); // console.log("IMG URL: "+e.target.src); console.log("IMG URL: "+e.target.href); // return; // } // let zzz = e.target.closest('href'); // console.log("URL: " + zzz.href); // return; // } });
Отсутствует
Dumby
В кнопке ucf Quick Toggle Settings на 88 не работает функция перезапуска, которая назначается в пунктах (restart: true,).
Поправьте пожалуйста.
Вот моя кнопка, не помню публиковалась ли она целиком, со всеми вашими правками на тот момент. Никаких недавно обсуждаемых новшеств я в нее не добавлял.
// Quick Toggle от Damby - Быстрое переключение параметров about:config // https://forum.mozilla-russia.org/viewtopic.php?pid=784165#p784165 // Ctrl+ЛКМ или ПКМ - сброс параметра по-умолчанию FF или удаление (async (name, id, func) => { if (name == "Object") return CustomizableUI.createWidget(func()); var win = name == "Window", g = Components.utils.import("resource://gre/modules/Services.jsm", {}); if (g[id]) {if (win) return;} else g[id] = func(); if (win) return CustomizableUI.createWidget(g[id]); addDestructor(r => r[5] == "e" && delete g[id]); g[id].onCreated(this); })(this.constructor.name, "QuickToggleAboutConfigSettings", () => { var {prefs} = Services, db = prefs.getDefaultBranch(""); var pv = parseInt(Services.appinfo.platformVersion); var xul_ns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; //============================================================================= // refresh: // false - перезагрука текущей вкладки // true - перезагрука текущей вкладки минуя кэш // // restart: // false - перезапуск браузера // true - перезапуск браузера с подтверждением // // userChoice: // ваше значение - иконка назначается в 372 строке // // userAlt: // альтернативное значение - иконка назначается в 374 строке var primary = [{ pref: ["network.proxy.type", "Настройки прокси"], userChoice: 5, userAlt: 2, refresh: true, values: [ [0, "Не проксировать", "0"], [5, "Системные (IE)", "5"], [2, "Авто (pacfile)", "2"], [1, "Прописанные", "1"], [4, "Автоопределение", "4"] ]},{ pref: ["network.trr.uri", "DoH DNS провайдер"], userChoice: "https://firefox.dns.nextdns.io/", userAlt: "https://doh.dns.sb/dns-query", restart: true, values: [ ["https://firefox.dns.nextdns.io/", "NextDNS"], ["https://mozilla.cloudflare-dns.com/dns-query", "Cloudflare"], ["https://dns.comss.one/dns-query", "Comss DNS"], ["https://dns.google/dns-query", "Google DNS"] ]},{ pref: ["network.trr.mode", "DoH DNS режим (trr)"], userChoice: 3, userAlt: 2, refresh: true, values: [ [1, "Быстрейший"], [2, "DoH+St.as.reserve"], [3, "Строгий"] ]}, null, { pref: ["permissions.default.image", "Загружать web-графику"], userChoice: 1, userAlt: 2, refresh: true, values: [ [1, "Да"], [3, "С сайта"], [2, "Нет"] ]} ]; //============================================================================= var secondary = [{ pref: ["ui.prefersReducedMotion", "Анимация chrome"], userChoice: 1, userAlt: 0, restart: true, values: [[1, "Отключена"], [0, "Включена"]] },{ pref: ["gfx.webrender.enabled", "Web render"], userChoice: true, userAlt: false, restart: true, values: [[true, "Включен"], [false, "Отключен"]] },{ pref: ["gfx.webrender.force-disabled", "Web render (force-disabled)"], userChoice: false, userAlt: true, restart: true, values: [[true, "Да"], [false, "Нет"]] } ]; return { id: "QuickToggleAboutConfigSettings", label: "Quick Toggle Settings", tooltiptext: "Quick Toggle Settings\n ЛКМ ПКМ", localized: false, image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAKdSURBVDhPjZNLTxNRFMenM9OWTulTEx4KkSg+0mCCujExNTyiLKiQAUofIcR+AOPOlStdGDd+AzdGDQvF+IhBBY0ro8aNUkAXxFhKERRaYOhjOuP/j0NidONNfj2Puef0nHvPFUzT/C9EQQiC5p/JoXeQJ8Ax2jZ+/HtJNpsDwqiapm7ZnmoqWchq2qNGRYl8yRdetPq83dLN20zyezEIiNwMsxZ4obuAm/aitvVQkeX9CBoIOp1N6bX8K/g92+W1u1x+ZAqwJDOVNAsj0TfQW+EPQbbk4uoD+qGfAz2gn/a02vtSsEuSj0Za7b2BD8f10eGKtfnMcmLgg6WfnlUjk7DnGLySGJydUXunoPeIhmG4C+XK2yP+2ovo870kybKuV8rQJ3bX1LRPZXO3UGrwkN/bmdsq5uAfXy4Ws4f9vg74FSERCJxCppNmKmYS6IldkhSlXh0d1mHH6LMYYiWQbIPthG0sk/+EbAIOKA5RBuu08W/PKLnwLQaxBTYAr457SuJOMLbzZye4ZLG9MptaGqIINIsVkAerwgGHI45SBnlYVgvdLI221YIKoqAPdH6N9j+B5O20gr02/HQ87+k639lYP4KM26ta1Us4TCf1hU1tunls/Craufs5X5g86PN2za9vTLR4as+iraOIF1YYjEH5CMcQgnVJsjk5ME8z2bE9biXERJ9W114HnY4m+Pu8dvu+ubXCFNwBVlCviGKdZhh+OPyZmHqlQXG1YWOyTpYrS7peTquRC7xG+HjIPCM7r5PTyAQcXR+zAb4BjjHLNwDfAg/WPjMQucwK6u7cu/Q9MXiNsxC6//i6iAfDjDzRBbBkyXnwDWQs3zJ7/1EsZ/4ZpD+eqwPIwAX4dInHshtAGwhz/iE5SLgdIfwLnaFD0PXeqXgAAAAASUVORK5CYII=", onCreated(btn) { btn.setAttribute("image", this.image); var doc = btn.ownerDocument; btn.btn = true; btn.domParent = null; btn.popups = new btn.ownerGlobal.Array(); this.createPopup(doc, btn, "primary", primary); this.createPopup(doc, btn, "secondary", secondary); this.createCloseMenusOption(doc, btn); btn.linkedObject = this; for(var type of ["command", "contextmenu"]) btn.setAttribute("on" + type, `linkedObject.${type}(event)`); }, createPopup(doc, btn, name, data) { var popup = doc.createElementNS(xul_ns, "menupopup"); var prop = name + "Popup"; btn.popups.push(btn[prop] = popup); popup.id = this.id + "-" + prop; for (var type of ["popupshowing", "click"]) popup.setAttribute("on" + type, `parentNode.linkedObject.${type}(event)`); for(var obj of data) popup.append(this.createElement(doc, obj)); btn.append(popup); }, map: {b: "Bool", n: "Int", s: "String"}, createElement(doc, obj) { if (!obj) return doc.createElementNS(xul_ns, "menuseparator"); var pref = doc.ownerGlobal.Object.create(null), node, img, bool; for(var [key, val] of Object.entries(obj)) { if (key == "pref") { var [apref, lab, akey, ttt] = val; pref.pref = apref; pref.lab = lab || apref; if (ttt) pref.ttt = ttt; } else if (key == "image") img = val, pref.img = true; else if (key != "values") pref[key] = val; else pref.hasVals = true; } var type = prefs.getPrefType(pref.pref); var str = this.map[type == prefs.PREF_INVALID ? obj.values ? (typeof obj.values[0][0])[0] : "b" : type == prefs.PREF_BOOL ? "b" : type == prefs.PREF_INT ? "n" : "s" ]; pref.get = prefs[`get${str}Pref`]; pref.set = prefs[`set${str}Pref`]; node = doc.createElementNS(xul_ns, "menu"); node.className = "menu-iconic"; node.setAttribute("closemenu", "none"); img && node.setAttribute("image", img); akey && node.setAttribute("accesskey", akey); (node.pref = pref).vals = doc.ownerGlobal.Object.create(null); this.createRadios(doc, str.startsWith("B") && !pref.hasVals ? [[true, "true"], [false, "false"]] : obj.values, node.appendChild(doc.createElementNS(xul_ns, "menupopup")) ); if ("userChoice" in obj) pref.noAlt = !("userAlt" in obj); return node; }, createCloseMenusOption(doc, btn) { var pn = this.closePref = "QuickToggleAboutConfigSettings.closeMenus"; var data = [null, { pref: [pn, "Автозакрытие этого меню"], values: [[true, "Да"], [false, "Нет"]] }]; var setCloseMenus = e => { e.stopPropagation(); var trg = e.target, {pref, val} = trg, updPopup = true, clear; switch(e.type) { case "command": pref = (trg = trg.closest("menu")).pref; updPopup = false; break; case "click": if (e.button) return; break; case "contextmenu": e.preventDefault(); clear = pref; } if (!pref) return; if (clear) prefs.clearUserPref(pn); else if (!updPopup && val === pref.val) return; else pref.set(pn, val !== undefined ? val : !pref.val); this.upd(trg); updPopup && this.popupshowing(null, trg.querySelector("menupopup")); } (this.createCloseMenusOption = (doc, btn) => { for(var obj of data) btn.secondaryPopup.append(this.createElement(doc, obj)); var m = btn.secondaryPopup.lastChild; m.style.cssText = "fill: lightblue !important; list-style-image: url(chrome://browser/skin/menu.svg) !important;"; m.setAttribute("oncommand", "setCloseMenus(event)"); m.onclick = m.oncontextmenu = m.setCloseMenus = setCloseMenus; })(doc, btn); }, UserChoiceImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHqSURBVDhPpVJBTxNBGH1LLakxVEJQQIkhlZCAJDYR/BGScNCDwZMcuEji2ZP+BD14MCGciDEaEw8e1At3QGLlwAUOFtm6tut2uwtb2t3p8GbZ0iXlVF/y5ttkv+/Nmzej5XI5/A+6otoxTh1ks9mwhniJHvRiBAHXLjRIEy7yeIqjqAPNuXYHS5jGVby7PTT27eHo7Or9zL3Va/19Xyj5FsuYjLpOcdbBG9xFGh+fZRaGJ5O3tB7tMrcXcGQZP+pb8tXuyjpdPcA89HYHynYazxdvzg5nkgOapFsPNleXP+uY6L6hzYxMT+EC5vCVa4SWAM880Ju4cyVxUXNkERUeuyJLIR1+O6wTqcEEUngEA5eiqZgAAxtMpfur0sIBLA7+hS2NkK5UGVpsqgEJjLMkT4biAkzbE27D5u7/ZAFWSB1l0iRtUokyEj+aCBEXMHcOA70Y/IElfsMUeyiJPIpBHiZZEvv4Vcsrge9Mi1ZO0BJQ98yw9w4tWT4yYNV1ki78AuyggHLNwLZjC1Txnpl60VRMQD2SBl5sGsHaT88XJd+DEzioCAd6rYpN1xf7Jj5T4BMe00eE9pf4GteZ8Ry6mbYKDDyzxAblP4TDT1BUbc2585+yumd1Vc201ZmV7djObQKdopVBRwCOAVyl9qcQtNEaAAAAAElFTkSuQmCC", notUserChoiceImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHqSURBVDhPpVJNSxtRFD1PJ9GMMVpaKyWhRGwRFy7Utv+gVFyUgoWif8Ct+APMsvQX+BuUWhdBcOvSDwi1XVhK0WgmTr4mmphoJvPRe5NnxhLdpAcO9828d869794nXNfF/6BLxo7RqiAcDjciYx3oDwFRBxikT4ey5CtAcg64aZ4ANE1rxDaDLeB176Aae/zx/ZR/NDqEuu1UD39oxsZ2wnIRmwV+8rl7DeLAGzXg+/pidSWivBwVCPQDvH91AfPot/tn6fOedW3NzTT0TYNWD7hsVfWtjH1ZjCjPggImFV25AKpE+xr+6CMxsvzpVXePmE8AipR5Bnzn4bcT0yJoCZSyQDkPXOrEDDHXYG8k0B18/nSBdvukzDPghqlB/xOUi4BBgiIJDUleF0lmVaEo7ngd8EnZP2N0uiolBwXKmksDegrISubovvyPWauR3kPLgBb5q+O8hnMyOD8jJoknTaZPKZLRSQp2+eaA6q9JmWcwTHPWv2cT0E0XGcqos4lkhgz4X7Jql3O1NZNaK2WewSQ9EtqIHcWPd5FybWQNoECNNApkdgmcwv61k47TbDbf0VykrP0hfaPlADAfCmFBERiHQN2sY79UwTqLP1BX+NyDL5HBc+ZR3Xab78xl383cZtAp7o6xAwB/AT+Y7GFJS/NjAAAAAElFTkSuQmCC", UserAltImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAH7SURBVDhPpVJLa1NBFP5mJolNcrWhtiq9Betjk0VFfNS1O7ciXbQguBDXxR9g3Lnown8g3SqCi24K/gCxVbqogiBaxdyY5nFrkt5H5j7GmZvxphDdxA8+Dgzn+86Zcw4RQuB/QHUcG2kHpmkmUWHtEo6DY55mUCIhYkHQOlXA97vv4esUWJaVxBGDp2Vcz54klakbN69kZ8wZRHHsVT9b7e2tHdFH5eEuPqi8vxqsLWDxmIGX5+8/mMufPkdA8zIBiMMuvNo3sbf+bCt2cWd1V+kHBukMVNuFE3h08d7SXHF6glC4oHFXGnTBmA9j1iBnb9+6xvJYfryIjJYdGaL889TlC1cLkyFhQQek3wThjYSUt8GCX9Iky/JniitGF0WtGhpQgdLEJJvO8AMpUgIbtK/JbflmI0cc2Y0oy/JZLRsaEIKYcCemXgvUlVXdOpj/c0Bnf0BXdhXxQEsSpAZqVU7NtkRPJh5aoAmrCYnzA9SpIbDr4G74Lsihr2VDA7Xn5kdvx2mGgnr7soNaSubXQb0GelUv8lt4Pj8rJ6yRGqgjERyVT68P3rarJIo6HojrJOS2h8Yejb6+OdyIe3i1tIlIy0YP6ckCTCOH5WIJKxmGsnwKeB/bbgcvlHj1Cxoq75+XqKD2rFb1Z9rqz6rto5VHDMZFOoPxAPwGQ077rbKVfhEAAAAASUVORK5CYII=", upd(node) { var {pref} = node, def = false, user = false, val; if (prefs.getPrefType(pref.pref) != prefs.PREF_INVALID) { var pn = pref.pref; try {val = pref.defVal = db[pref.get.name](pn); def = true} catch(ex) {def = false;} var user = prefs.prefHasUserValue(pn); if (user) try {val = pref.get(pn, undefined);} catch(ex) {} } if (val == pref.val && def == pref.def && user == pref.user) return; pref.val = val; pref.def = def; pref.user = user; var exists = def || user; var ttt = exists ? val : "Этот преф не существует"; if (ttt === "") ttt = "[ empty_string ]"; ttt += "\n" + pref.pref; if (pref.ttt) ttt += "\n" + pref.ttt; node.tooltipText = ttt; var img, alt = "userAlt" in pref && val == pref.userAlt; if (alt) img = this.UserAltImg; if ("userChoice" in pref) if (val == pref.userChoice) //node.style.removeProperty("color"), img = this.UserChoiceImg; else { //node.style.setProperty("color", "maroon", "important"); if (!alt) img = this.notUserChoiceImg; } if (!pref.img) img ? node.setAttribute("image", img) : node.removeAttribute("image"); user ? node.style.setProperty("font-style", "italic", "important") : node.style.removeProperty("font-style"); var {lab} = pref; if (exists && pref.hasVals) { if (val in pref.vals) var sfx = pref.vals[val] || val; else var sfx = user ? "Другое" : "По умолчанию"; lab += ` — "${sfx}"`; } node.setAttribute("label", lab); }, createRadios(doc, vals, popup) { for(var arr of vals) { if (!arr) { popup.append(doc.createElementNS(xul_ns, "menuseparator")); continue; } var [val, lab, key, ttt] = arr; var menuitem = doc.createElementNS(xul_ns, "menuitem"); menuitem.setAttribute("type", "radio"); menuitem.setAttribute("closemenu", "none"); menuitem.style.setProperty("font-style", "italic", "important"), menuitem.setAttribute("label", popup.parentNode.pref.vals[val] = lab); key && menuitem.setAttribute("accesskey", key); var tip = menuitem.val = val; if (ttt) tip += "\n" + ttt; menuitem.tooltipText = tip; popup.append(menuitem); } }, openPopup(popup) { var btn = popup.parentNode; if (btn.domParent != btn.parentNode) { btn.domParent = btn.parentNode; var pos; if (btn.matches(".widget-overflow-list > :scope")) pos = "after_start"; else var win = btn.ownerGlobal, {width, height, top, bottom, left, right} = btn.closest("toolbar").getBoundingClientRect(), pos = width > height ? `${win.innerHeight - bottom > top ? "after" : "before"}_start` : `${win.innerWidth - right > left ? "end" : "start"}_before`; for(var p of btn.popups) p.setAttribute("position", pos); } popup.openPopup(btn); }, maybeRestart(node, conf) { var msgRest = "Перезапустить браузер?", msgAbort = "Запрос на выход отменен."; if (pv >= 77) { var title = node.closest("toolbarbutton").label; var pp = domWin => Services.prompt.wrappedJSObject.pickPrompter({ domWin, modalType: Ci.nsIPrompt.MODAL_TYPE_WINDOW }); var confirm = win => pp(win).confirm(title, msgRest); var alert = win => pp(win).alert(title, msgAbort); } else { var confirm = win => win.confirm(msgRest); var alert = win => win.alert(msgAbort); } return (this.mayBeRestart = (node, conf) => { var win = node.ownerGlobal; if (conf && !confirm(win)) return; if (win.BrowserUtils.restartApplication() === false) alert(win); else return true; })(node, conf); }, regexpRefresh: /^(?:view-source:)?(?:https?|ftp)/, maybeRe(node, fe) { var {pref} = node; if ("restart" in pref) { if (this.maybeRestart(node, pref.restart)) return; } else this.popupshowing(fe, node.parentNode); if ("refresh" in pref) { var win = node.ownerGlobal; if (this.regexpRefresh.test(win.gBrowser.currentURI.spec)) pref.refresh ? win.BrowserReloadSkipCache() : win.BrowserReload(); } }, maybeClosePopup(e, trg) { !e.ctrlKey && prefs.getBoolPref(this.closePref, undefined) && trg.parentNode.hidePopup(); }, command(e) { var trg = e.target; if (trg.btn) return this.openPopup(trg.primaryPopup); var menu = trg.closest("menu"), newVal = trg.val; this.maybeClosePopup(e, menu); if (newVal != menu.pref.val) menu.pref.set(menu.pref.pref, newVal), this.maybeRe(menu, true); }, popupshowing(e, trg = e.target) { if (trg.state == "closed") return; if (trg.id) { for(var node of trg.children) { if (node.nodeName.endsWith("r")) continue; this.upd(node); !e && node.open && this.popupshowing(null, node.querySelector("menupopup")); } return; } var {pref} = trg.closest("menu"), findChecked = true; var findDef = "defVal" in pref; var checked = trg.querySelector("[checked]"); if (checked) { if (checked.val == pref.val) { if (findDef) findChecked = false; else return; } else checked.removeAttribute("checked"); } if (findDef) { var def = trg.querySelector("menuitem:not([style*=font-style]"); if (def) if (def.val == pref.defVal) { if (findChecked) findDef = false; else return; } else def.style.setProperty("font-style", "italic", "important"); } for(var node of trg.children) if ("val" in node) { if (findChecked && node.val == pref.val) { node.setAttribute("checked", true); if (findDef) findChecked = false; else break; } if (findDef && node.val == pref.defVal) { node.style.removeProperty("font-style"); if (findChecked) findDef = false; else break; } } }, contextmenu(e) { var trg = e.target; if (trg.btn) { if (e.ctrlKey || e.shiftKey) return; if (e.detail == 2) return trg.secondaryPopup.hidePopup(); this.openPopup(trg.secondaryPopup); } else if ("pref" in trg) { this.maybeClosePopup(e, trg); if (trg.pref.user) prefs.clearUserPref(trg.pref.pref), this.maybeRe(trg); } e.preventDefault(); }, click(e) { if (e.button) return; var trg = e.target, {pref} = trg; if (!pref) return; this.maybeClosePopup(e, trg); if (!("noAlt" in pref)) return; if (pref.val == pref.userChoice) if (pref.noAlt) return; else pref.set(pref.pref, pref.userAlt); else pref.set(pref.pref, pref.userChoice); this.maybeRe(trg); } }; });
Отсутствует
Dumby
В кнопке ucf Quick Toggle Settings на 88 не работает функция перезапуска, которая назначается в пунктах (restart: true,).
Поправьте пожалуйста.
Вот моя кнопка, не помню публиковалась ли она целиком, со всеми вашими правками на тот момент. Никаких недавно обсуждаемых новшеств я в нее не добавлял.
строка 282
//if (win.BrowserUtils.restartApplication() === false) alert(win);
if (Services.startup.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit) === false) alert(win);
Отсутствует
не работает функция перезапуска
Да, BrowserUtils изрядно покромсали.
Ещё, смотрю, на 89, так сделанный alert/confirm
уходит в ихний новомодный внутриоконный вариант,
что не очень хорошо сочетается с незакрывающимся меню.
Вобщем, такая правка
/* maybeRestart(node, conf) { var msgRest = "Перезапустить браузер?", msgAbort = "Запрос на выход отменен."; if (pv >= 77) { var title = node.closest("toolbarbutton").label; var pp = domWin => Services.prompt.wrappedJSObject.pickPrompter({ domWin, modalType: Ci.nsIPrompt.MODAL_TYPE_WINDOW }); var confirm = win => pp(win).confirm(title, msgRest); var alert = win => pp(win).alert(title, msgAbort); } else { var confirm = win => win.confirm(msgRest); var alert = win => win.alert(msgAbort); } return (this.mayBeRestart = (node, conf) => { var win = node.ownerGlobal; if (conf && !confirm(win)) return; if (win.BrowserUtils.restartApplication() === false) alert(win); else return true; })(node, conf); }, */ maybeRestart(node, conf) { if (conf && !Services.prompt.confirm(null, this.label, "Перезапустить браузер?")) return; var cancel = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool); Services.obs.notifyObservers(cancel, "quit-application-requested", "restart"); return cancel.data ? Services.prompt.alert(null, this.label, "Запрос на выход отменен.") : this.restart(); }, async restart() { var meth = Services.appinfo.inSafeMode ? "restartInSafeMode" : "quit"; Services.startup[meth](Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart); },
Отсутствует
Dumby просьба «косметически» доработать кнопку Quick Toggle about:config
я добавил скобки [] для строк меню, преф которых не существует (по-умолчанию).
Есть строки, требующие перезапуск браузера или обновление страницы. «Название меню» и «Значение» разделены тире —.
Нужно вместо тире — для строк, требующих refresh, подставлять например символ «⩫»; а для restart символ «↯»
чтобы строка, запрашивающая например перезапуск (restart), выглядела так: Провайдер DNS ↯ Cloudflare
// строка 400 кнопки https://forum.mozilla-russia.org/viewtopic.php?pid=789824#p789824 lab += ` — "${sfx}"`; // тире - обычный параметр, ⩫ требуется обновить страницу, ↯ нужен перезапуск браузера
Отсутствует
я добавил скобки [] для строк меню, преф которых не существует
Так и это, вроде как, не сложнее
Отсутствует
Deriax пишет14f477a2ce81.png
Фу, в переводе это выглядит ещё более непонятно, чем в оригинале.
На самом деле, cookieStoreId — это всего лишь id'шник контейнера,
то есть, всего лишь уточняющий параметр для cookies.get() (и компании), не более того.Типа — кука, именуемая так-то, с урлом каким-то эдаким, ограниченная контейнером (cookieStoreId) таким-то.
Еще раз: никакого «Хранилища файлов cookie вкладки» (так, как это звучит!) не существует.
Пожалуйста, подскажите как получить id контейнера, вообще как это выглядит? Нашёл такое расширение,
https://chrome.google.com/webstore/detail/cookie-tab-viewer/fdlghnedhhdgjjfgdpgpaaiddipafhgk
функционал этого расширения даёт возможность это реализовать, значит это возможно, но как это сделать для firefox не знаю (
Отредактировано Deriax (07-05-2021 12:52:42)
Отсутствует
вообще как это выглядит?
В реальности — это атрибут "usercontextid" <tab>'а и <browser>'а.
Выглядит как число.
А в WebExtensions представлении — ну, смотри сам.
Допустим, например:
Открываем какое-то количество вкладок, в разных контейнерах и не в контейнере.
Берём аддон с нужными permissions и переходим на любой его moz-extension://… адрес.
Открываем там веб-консоль (Ctrl+Shift+K), запускаем код типа такого и смотрим результат.
(await browser.tabs.query({})) .map(tab => tab.cookieStoreId.padEnd(30) + tab.title.slice(0, 100)) .join("\n");
функционал этого расширения даёт возможность это реализовать, значит это возможно, но как это сделать для firefox не знаю (
Может официальный пример немного прояснит.
Отсутствует
Deriax пишетвообще как это выглядит?
В реальности — это атрибут "usercontextid" <tab>'а и <browser>'а.
Выглядит как число.А в WebExtensions представлении — ну, смотри сам.
Допустим, например:
Открываем какое-то количество вкладок, в разных контейнерах и не в контейнере.
Берём аддон с нужными permissions и переходим на любой его moz-extension://… адрес.
Открываем там веб-консоль (Ctrl+Shift+K), запускаем код типа такого и смотрим результат.
[spoiler]Выделить кодКод:
(await browser.tabs.query({})) .map(tab => tab.cookieStoreId.padEnd(30) + tab.title.slice(0, 100)) .join("\n");
функционал этого расширения даёт возможность это реализовать, значит это возможно, но как это сделать для firefox не знаю (
Может официальный пример немного прояснит.
[/spoiler]
На будущее может пригодиться.
Отредактировано Deriax (11-05-2021 19:11:23)
Отсутствует
Dumby - спасибо, кнопку переключения настроек обновил.
Почините скрипт Save HTML, он не работает в Firefox 78 ESR, ошибка консоли: IOUtils is not defined
(async (id, func) => { // дополнительные клики на downloads-button для custom_script_win.js await window.delayedStartupPromise; var btn = document.getElementById("downloads-button"); if (!btn) return; btn.setAttribute("context", "event.stopPropagation()"); // откл контекстное меню btn.tooltipText = GetDynamicShortcutTooltipText(btn.id) +` ПКМ: Сохранить единый .html …Shift Обзор папки «Загрузки» Ролик: Сохранить как файл .txt всё | выделенный текст …Shift Сайт: графика Вкл/Выкл Alt⇧S нажать SingleSave`; // если такой кнопки нет, то выполнить save() var addDestructor = nextDestructor => { var {destructor} = ucf[id]; ucf[id].destructor = () => { try {destructor();} catch(ex) {Cu.reportError(ex);} nextDestructor(); } } var saveSelectionToTxt = async () => { // сохранить страницу или выделенный текст как файл .txt var splice = saveURL.length == 10; var msgName = id + ":Save:GetSelection"; var receiver = msg => { var title = document.title || gBrowser.selectedTab.label; var args = [ "data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + "\n\n" + msg.data), title.replace(/[:\\\/<>?*|"]+/g,'_').replace(/\s+/g,' ').slice(0, 100).trim() + '_' + new Date().toLocaleString('ru').replace(', ','-').replace(/:/g, '։') + '.txt', null, false, true, null, window.document ]; splice && args.splice(5, 0, null); saveURL(...args); } messageManager.addMessageListener(msgName, receiver); addDestructor(() => messageManager.removeMessageListener(msgName, receiver)); var func = fm => { var res, fed, win = {}; var fe = fm.getFocusedElementForWindow(content, true, win); var sel = (win = win.value).getSelection(); if (sel.isCollapsed) { var ed = fe && fe.editor; if (ed && ed instanceof Ci.nsIEditor) sel = ed.selection, fed = fe; } if (sel.isCollapsed) fed && fed.blur(), docShell.doCommand("cmd_selectAll"), res = win.getSelection().toString(), docShell.doCommand("cmd_selectNone"), fed && fed.focus(); res = res || sel.toString(); /\S/.test(res) && sendAsyncMessage("saveSelectionToTxt", res); } var url = "data:;charset=utf-8," + encodeURIComponent(`(${func})`.replace("saveSelectionToTxt", msgName)) + '(Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager));'; (saveSelectionToTxt = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); } // end var save = async () => { // автор: Лекс, правка: Dumby, Dobrov var msgName = id + "ucfDwnldsBtnSaveSnapshotToHTML"; var write = IOUtils.writeUTF8 ? "writeUTF8" : "writeAtomicUTF8"; var Title = function (type) { // получить заголовок (без обрезки, если type не указан) или домен (type <0) var title = (document.title || gBrowser.selectedTab.label); if ( !type ) return title; // заголовок if ( type > 0 ) return title.replace(/[:\\\/<>?*|"]+/g,' ').replace(/\s+/g,' ').replace(/ /g,' ').substr(0, type).trim(); // ограничить длину имени var host = (/^file:\/\//.test(gURLBar.value)) ? '' : gURLBar.value.replace(/^.*url=/,'').replace(/^https?:\/\//,'').replace(/\/.*/,''); return host.replace(/^www\./,'').replace(/^ru\./,'').replace(/^m\./,'').replace(/^forum\./,'').replace(/^club\.dns/,'dns'); }; var msgListener = async msg => { var [fileContent, fileName] = msg.data; var savedir = PathUtils.join(await Downloads.getPreferredDownloadsDirectory(), "_Web", Title(-1)); // каталог Загрузки + домен var path = PathUtils.join(savedir, fileName); await IOUtils[write](path, fileContent); var d = await Downloads.createDownload({ source: "about:blank", target: FileUtils.File(path)}); (await Downloads.getList(Downloads.ALL)).add(d); d.refresh(d.succeeded = true); // помигать кнопкой Загрузки } messageManager.addMessageListener(msgName, msgListener); addDestructor(() => messageManager.removeMessageListener(msgName, msgListener)); var svc = 'globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services'; var url = "data:;charset=utf8," + encodeURIComponent(`(${func})(${svc});`.replace("%MSG_NAME%", msgName)); (save = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); } // end save var listener = e => { // Clicks var trg = e.target, {prefs} = Services; if (e.button == 1) { if (e.shiftKey) { // СКМ + Shift if ( prefs.getIntPref("permissions.default.image", 1) == 1) prefs.setIntPref("permissions.default.image", 2), trg.style.filter = "hue-rotate(180deg) brightness(95%)" else prefs.setIntPref("permissions.default.image", 1), trg.style.filter = ""; BrowserReload(); } else // СКМ Click saveSelectionToTxt(); // сохранить .txt } else if (e.button == 2) { if (e.shiftKey) Downloads.getSystemDownloadsDirectory().then(path => FileUtils.File(path).launch(), Cu.reportError) // Обзор папки «Загрузки» else // ПКМ Click save(); // Single HTML } } var keydown_win = e => { // нажатие клавиш if (!(e.keyCode == 83 && e.shiftKey && e.altKey)) return; var singlesave = document.getElementById("_531906d3-e22f-4a6c-a102-8057b88a1a63_-browser-action"); // SingleSave singlesave ? singlesave.click() : save(); // имитировать клик по кнопке, используя её ID } btn.addEventListener("click", listener); window.addEventListener("keydown", keydown_win); var ucf = window.ucf_custom_script_win || window.ucf_custom_script_all_win; ucf[id] = {destructor() { btn.removeEventListener("click", listener); window.removeEventListener("keydown", keydown_win); }}; ucf.unloadlisteners.push(id); })("downloads-button-click-listener", ({io, focus}) => { var resolveURL = function (url, base) { try { return io.newURI(url, null, io.newURI(base)).spec; } catch {} }; var getSelWin = function (w) { if (w.getSelection().toString()) return w; for (var i = 0, f, r; f = w.frames[i]; i++) { try { if (r = getSelWin(f)) return r; } catch(e) {} } }; var encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.test(src)) { canvas = doc.createElement('canvas'); if (!obj || obj.nodeName.toLowerCase() != 'img') { img = doc.createElement('img'); img.src = src; } else { img = obj; }; if (img.complete) try{ canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; }; var toSrc = function (obj) { var strToSrc = function (str) { var chr, ret = '', i = 0, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'}; while (chr = str.charAt(i++)) { ret += meta[chr] || chr; }; return '\x22' + ret + '\x22'; }, arrToSrc = function (arr) { var ret = []; for (var i = 0; i < arr.length; i++) { ret[i] = toSrc(arr[i]) || 'null'; }; return '[' + ret.join(',') + ']'; }, objToSrc = function (obj) { var val, ret = []; for (var prop in obj) { if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val); }; return '{' + ret.join(',') + '}'; }; switch (Object.prototype.toString.call(obj).slice(8, -1)) { case 'Array': return arrToSrc(obj); case 'Boolean': case 'Function': case 'RegExp': return obj.toString(); case 'Date': return 'new Date(' + obj.getTime() + ')'; case 'Math': return 'Math'; case 'Number': return isFinite(obj) ? String(obj) : 'null'; case 'Object': return objToSrc(obj); case 'String': return strToSrc(obj); default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null'; } }; var mainWin = {}; focus.getFocusedElementForWindow(content, true, mainWin); mainWin = mainWin.value; var selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location; var ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/g; if (selWin) { var rng = win.getSelection().getRangeAt(0); pEle = rng.commonAncestorContainer; ele = rng.cloneContents(); } else { pEle = doc.documentElement; ele = (doc.body || doc.getElementsByTagName('body')[0]).cloneNode(true); }; while (pEle) { if (pEle.nodeType == 1) { clone = pEle.cloneNode(false); clone.appendChild(ele); ele = clone; }; pEle = pEle.parentNode }; var sel = doc.createElement('div'); sel.appendChild(ele); for (var el, all = sel.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (el.style && el.style.backgroundImage) el.style.backgroundImage = el.style.backgroundImage.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href); return prev + encodeImg(url) + next; }); switch (el.nodeName.toLowerCase()) { case 'link': case 'style': case 'script': el.parentNode.removeChild(el); break; case 'a': case 'area': if (el.hasAttribute('href') && el.getAttribute('href').charAt(0) != '#') el.href = el.href; break; case 'img': case 'input': if (el.hasAttribute('src')) el.src = encodeImg(el.src, el); break; case 'audio': case 'video': case 'embed': case 'frame': case 'iframe': if (el.hasAttribute('src')) el.src = el.src; break; case 'object': if (el.hasAttribute('data')) el.data = el.data; break; case 'form': if (el.hasAttribute('action')) el.action = el.action; break; } }; var head = ele.insertBefore(doc.createElement('head'), ele.firstChild); var meta = doc.createElement('meta'); meta.httpEquiv = 'content-type'; meta.content = 'text/html; charset=utf-8'; head.appendChild(meta); var title = doc.getElementsByTagName('title')[0]; if (title) head.appendChild(title.cloneNode(true)); head.copyScript = function (unsafeWin) { if ('$' in unsafeWin) return; var f = doc.createElement('iframe'); f.src = 'about:blank'; f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;'); doc.documentElement.appendChild(f); var str, script = doc.createElement('script'); script.type = 'text/javascript'; for (var name in unsafeWin) { if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue; try { str = toSrc(unsafeWin[name]); if (!/\{\s*\[native code\]\s*\}/.test(str)) { script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n')); } } catch (e) {}; }; f.parentNode.removeChild(f); if (script.childNodes.length) this.nextSibling.appendChild(script); }; head.copyScript(win.wrappedJSObject || win); head.copyStyle = function (s) { if (!s) return; var style = doc.createElement('style'); style.type = 'text/css'; if (s.media && s.media.mediaText) style.media = s.media.mediaText; try { for (var i = 0, rule; rule = s.cssRules[i]; i++) { if (rule.type != 3) { if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) { var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href); if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url); return prev + url + next; }); style.appendChild(doc.createTextNode(css + '\n')); } } else { this.copyStyle(rule.styleSheet); } } } catch(e) { if (s.ownerNode) style = s.ownerNode.cloneNode(false); }; this.appendChild(style); }; var sheets = doc.styleSheets; for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]); head.appendChild(doc.createTextNode('\n')); var doctype = '', dt = doc.doctype; if (dt && dt.name) { doctype += '<!DOCTYPE ' + dt.name; if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22'; if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22'; doctype += '>\n'; }; var fileName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop()); fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).trim(); fileName += "_" + new Date().toLocaleString("ru").replace(", ","-").replace(/:/g, "։"); if (!/\.html?$/.test(fileName)) fileName += '.html'; sendAsyncMessage("%MSG_NAME%", [doctype + sel.innerHTML +'\n<a href='+ (loc.protocol != 'data:' ? loc.href : 'data:uri') +'><small><blockquote>источник: '+ new Date().toLocaleString("ru") +'</blockquote></small></a>', fileName]); }); // END hookClicks
Отсутствует
куки нужной активной вкладки, как это реализовать через xpcom или модуль Services?
Без понятия что значит «куки вкладки», вообще кук не держу.
Возможно что-то типа такого
var {host, originAttributes} = gBrowser.contentPrincipal; var cookies = Services.cookies.getCookiesFromHost(host, originAttributes); var resultAsJSON = JSON.stringify(cookies, null, "\t"); gBrowser.selectedTab = gBrowser.addTrustedTab( "data:text/plain;charset=utf-8," + encodeURIComponent(resultAsJSON) );
Почините скрипт Save HTML, он не работает в Firefox 78 ESR
Что значит «почините»?
Он и не должен работать «в Firefox 78».
Можно попробовать добавить перед строкой с ошибкой
… if (typeof IOUtils != "object") { var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm"); var PathUtils = {join: (...args) => OS.Path.join(...args)}; var IOUtils = {writeUTF8: (path, txt) => OS.File.writeAtomic(path, new TextEncoder().encode(txt))}; }
Отсутствует