dedfor - почитай описание, может подойдёт сборка Firefox с коллекцией скриптов?
Отсутствует
Спасибо изобретателю СВ-кнопок. Но жизнь заставила переходить на новые версии Мозиллы, а на них не могу поставить СВ-замучился. Расскажите, пожалуйста по-порядку: какую из новых версий Мозиллы установить и как поставить на неё СВ и что ещё сделать, чтобы опять всё заработало?
Попробуйте esr 91(esr 78.15.0) или 95, актуальная версия CB здесь:https://forum.mozilla-russia.org/viewto … 21#p796421, и что бы установить CB необходимо отключить...https://forum.mozilla-russia.org/viewtopic.php?id=70326, в файл config.js добавите этот код: https://forum.mozilla-russia.org/viewto … 58#p780458.
P,S, а готовые кнопки для актуальных версий поищите в этой теме!
Win7
Отсутствует
Dumby ещё просьба исправить код: расположение закладки в Избранном
на FF 90+ на звёздочке не обновляется tooltip, если закладка добавлена. При этом в контекстом меню всё нормально.
я добавил новый ID звёздочки, но не пашет …})("ucfBookmarksStarFTooltipHelper", "#star-button, #star-button-box, #context-bookmarkpage");
(async (id, sel) => { // Клики на Звёздочке, ToolTip: расположение закладки в Избранном, Недавняя папка var g = Cu.getGlobalForObject(Cu), stt = g[id]; // https://forum.mozilla-russia.org/viewtopic.php?pid=790890#p790890 if (!stt) { var {obs, prefs} = Services, {bookmarks: bm, observers: pobs} = PlacesUtils; stt = g[id] = { bm, help_star: `\nПравый клик Быстрая закладка\n Клик дважды Перевод сайта/выд.текста\nКолёсико масштаб Текст / Всё\nКолёсико ± Масштаб страницы`, // клики заданы в ucf_hookClicks.js pref: `ucf.${id}Guid`, events: ["bookmark-added"], async init() { this.handleEvent = e => this[e.type](e); if ((this.pbm = typeof PlacesBookmarkMoved == "function")) this.events.push("bookmark-moved"); else this.QueryInterface = g.ChromeUtils.generateQI([Ci.nsINavBookmarkObserver]), bm.addObserver(this); pobs.addListener(this.events, this.added = events => { for(var e of events) e.isTagging || this[e.constructor.name](e); }); obs.addObserver(this, "quit-application-granted"); this.args = [b => this.bguids.add(b.parentGuid), {concurrent: true}]; var guid = prefs.getStringPref(this.pref, ""); if (!guid) try {var [guid] = await PlacesUtils.metadata.get( PlacesUIUtils.LAST_USED_FOLDERS_META_KEY, [])} catch {} this.guids.push(guid || await PlacesUIUtils.defaultParentGuid || bm.unfiledGuid); }, observe() { this.pbm || bm.removeObserver(this); pobs.removeListener(this.events, this.added); obs.removeObserver(this, "quit-application-granted"); prefs.setStringPref(this.pref, this.guids[0]); this.removePrefObs(); }, bguids: new g.Set(), guids: new g.Array(), skipTags: true, tt(win) { var list = win.InspectorUtils.getChildrenForNode(win.document.documentElement, true); return list.item(list.length - 1); }, PlacesBookmarkAddition(e) { if (e.itemType == bm.TYPE_BOOKMARK && e.source == bm.SOURCES.DEFAULT) this.guids[0] = e.parentGuid; }, PlacesBookmarkMoved(e) { e.parentGuid != e.oldParentGuid && this.PlacesBookmarkAddition(e); }, onItemMoved(a, b, c, d, e, itemType, f, oldParentGuid, parentGuid, source) { this.PlacesBookmarkMoved({itemType, source, oldParentGuid, parentGuid}); }, fetch(win) { this.bguids.clear(); return bm.fetch({url: win.gBrowser.currentURI.spec}, ...this.args); }, find: obj => obj.name == "tooltiptext" }; var ps = ["onBeginUpdateBatch", "onEndUpdateBatch", "onItemChanged", "onItemVisited"]; var noop = () => {}; for(var p of ps) stt[p] = noop; stt.init(); var func = id => this[id].mouseenter = async function(e) { var win = e.view, star = e.target, result = [], starred = star.hasAttribute("starred"); starred && await this.fetch(win); for(var guid of (starred ? this.bguids : this.guids)) { var arr = [], num = 50; while(--num) { if (!star.matches(":hover")) return; var res = await this.bm.fetch(guid); if (!res) break; if ((guid = res.parentGuid) == this.bm.rootGuid) { arr.unshift(this.bm.getLocalizedTitle(res)); break; } arr.unshift(res.title || "[Безымянная папка]"); } arr.length && result.push(arr.join("\\")); } if (!star.matches(":hover")) return; var text = (await win.document.l10n.formatMessages([{ // стандартная подсказка id: star.getAttribute("data-l10n-id"), args: JSON.parse(star.getAttribute("data-l10n-args")) }]))[0].attributes.find(this.find).value, txt; if (result.length) { txt = result.join("\n"); txt = starred ? `\n\n★ ${result.length > 1 ? "Данные закладки добавлены" : "Данная закладка добавлена"} в:\n${txt}` : "\n\n★ Недавно добавленная папка:\n" + txt; // text += this.help_star +'\n'+ txt; } win.document.tooltipNode == star ? this.tt(win).label = text + this.help_star + txt : star.tooltipText = text + this.help_star + txt; } var url = "data:;charset=utf-8," + encodeURIComponent(`(${func})("${id}")`); g.ChromeUtils.compileScript(url).then(ps => ps.executeInGlobal(g)); } await delayedStartupPromise; var stars = Array.from(document.querySelectorAll(sel)); for(var star of stars) star.addEventListener("mouseenter", stt); var destructor = () => { for(var star of stars) star.removeEventListener("mouseenter", stt); } var ucf = window.ucf_custom_script_win || window.ucf_custom_script_all_win; if (ucf) ucf[id] = {destructor}, ucf.unloadlisteners.push(id); else window.addEventListener("unload", destructor, {once: true}); })("ucfBookmarksStarFTooltipHelper", "#star-button, #star-button-box, #context-bookmarkpage");
Отсутствует
Dumby
Есть у меня вот такая СВ-кнопочка:Возможно её переделать под UCF?скрытый текстВыделить кодКод:
// Иконки сайтов на CB-кнопке .......... addEventListener("TabAttrModified", (e, tab = e.target)=> { if ( tab.selected ) { favIcon.src = tab.image || "chrome://global/skin/icons/defaultFavicon.svg"; } }, true, gBrowser.tabContainer); var favIcon = self.getElementsByClassName("toolbarbutton-icon")[0]; addDestructor(()=> favIcon.removeAttribute("src") );Для FF91.
Вопрос снимается.
Сам сделал.
try { CustomizableUI.createWidget({ id: "ucf_IconsSiteButton", label: "Иконки сайтов на кнопке", // defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onCreated(btn) { btn.setAttribute("image", "chrome://global/skin/icons/defaultFavicon.svg"); gBrowser.tabContainer.addEventListener("TabAttrModified", (e, tab = e.target)=> { if ( tab.selected ) { var favIcon = tab.image || "chrome://global/skin/icons/defaultFavicon.svg"; btn.setAttribute("image", favIcon); } }, true); }, }); } catch(ex) { Cu.reportError(ex); }
Отредактировано unter_officer (02-01-2022 19:34:04)
«The Truth Is Out There»
Отсутствует
Прописал CB drag and go в custom_script_win.js
gClipboard(e) {
Объект же, а не функция. gClipboard: {
исправить код: расположение закладки
Прыгать по версиям неохота, а из-под 94 так попробовал
(async (id, sel) => { // Клики на Звёздочке, ToolTip: расположение закладки в Избранном, Недавняя папка var g = Cu.getGlobalForObject(Cu), stt = g[id]; if (!stt) { var {obs, prefs} = Services, pu = PlacesUtils, {bookmarks: bm, observers: pobs} = pu, stt = g[id] = { bm, help_star: [ // клики заданы в ucf_hookClicks.js "\nПравый клик Быстрая закладка\n", "Клик дважды Перевод сайта/выд.текста", "Колёсико масштаб Текст / Всё", "Колёсико ± Масштаб страницы\n" ].join("\n"), pref: `ucf.${id}Guid`, async init() { var args = [ ["bookmark-added", "bookmark-moved"], events => {for(var e of events) e.isTagging || this[e.constructor.name](e);} ]; pobs.addListener(...args); pu.registerShutdownFunction(() => { pobs.removeListener(...args); prefs.setStringPref(this.pref, this.lastGuid); }); this.args = [ res => this.fetchRes.push(res), {concurrent: true, includePath: true} ]; var guid = prefs.getStringPref(this.pref, ""); if (!guid) try {var [guid] = await PlacesUtils.metadata.get( PlacesUIUtils.LAST_USED_FOLDERS_META_KEY, [])} catch {} this.lastGuid = guid || await PlacesUIUtils.defaultParentGuid || bm.unfiledGuid; }, PlacesBookmarkAddition(e) { if (e.itemType == bm.TYPE_BOOKMARK && e.source == bm.SOURCES.DEFAULT) this.lastGuid = e.parentGuid; }, PlacesBookmarkMoved(e) { e.parentGuid != e.oldParentGuid && this.PlacesBookmarkAddition(e); }, find: obj => obj.name == "tooltiptext", tt(win) { var list = win.InspectorUtils.getChildrenForNode(win.document.documentElement, true); return list.item(list.length - 1); }, mapInfs(inf) { return inf.path.map(this.mapPaths).join("\\"); }, mapPaths: path => bm.getLocalizedTitle(path) || "[Безымянная папка]", }; stt.init(); var func = id => this[id].handleEvent = async function(e) { var win = e.view, star = e.target; var starred = win.BookmarkingUI._itemGuids.size; var arg = starred ? {url: win.gBrowser.currentURI.spec} : this.lastGuid; var arr = this.fetchRes = []; await this.bm.fetch(arg, ...this.args); if (!star.matches(":hover")) return; var len = arr.length; !starred && len && arr[0].path.push(arr[0]); var paths = len ? arr.map(this.mapInfs, this).join("\n") : "<Folder Not Found>"; var header = (await win.document.l10n.formatMessages([{ // стандартная подсказка id: star.getAttribute("data-l10n-id"), args: JSON.parse(star.getAttribute("data-l10n-args")) }]))[0].attributes.find(this.find).value; if (!star.matches(":hover")) return; var footer = "\n★ " + ( starred ? (len > 1 ? "Данные закладки добавлены" : "Данная закладка добавлена") + " в" : "Последний раз добавлялось в папку" ) + ":\n" + paths; var text = header + this.help_star + footer; var tt = star.linkedTooltip; star.contains(tt.triggerNode) ? tt.label = text : star.tooltipText = text; } var url = "data:;charset=utf-8," + encodeURIComponent(`(${func})("${id}")`); g.ChromeUtils.compileScript(url).then(ps => ps.executeInGlobal(g)); } await delayedStartupPromise; var stars = Array.from(document.querySelectorAll(sel)); for(var star of stars) { star.linkedTooltip = stt.tt(window); star.addEventListener("mouseenter", stt); } var destructor = () => { for(var star of stars) star.removeEventListener("mouseenter", stt); } var ucf = window.ucf_custom_script_win || window.ucf_custom_script_all_win; if (ucf) ucf[id] = {destructor}, ucf.unloadlisteners.push(id); else window.addEventListener("unload", destructor, {once: true}); })("ucfBookmarksStarFTooltipHelper", "#star-button-box, #context-bookmarkpage");
Сам сделал.
Это хорошо, но откуда в сандбоксе,
в который грузится custom_script.js, возьмётся gBrowser ?
Наверно в окно положил, но это нехорошо, как по понятиям,
так и по факту — виджет не будет работать во втором
и последующих окнах браузера.
Я вот так записал
(для custom_script.js, как и положено, если явно не указано обратное).
(async def => CustomizableUI.createWidget({ id: "ucf_IconsSiteButton", label: "Иконки сайтов на кнопке", localized: false, onCreated(btn) { var maybeSetImg = (e, icon) => { var tab = e.target; if (tab.selected) { var arr = e.detail.changed; if (arr.includes("selected") || arr.includes("image")) icon.src = tab.image || def; } } var type = "TabAttrModified"; var render = function() { delete this.render; this.render(); var {icon} = this; var win = this.ownerGlobal; var gb = win.gBrowser, tc = gb.tabContainer; var lst = e => maybeSetImg(e, icon); var unl = () => tc.removeEventListener(type, lst); tc.addEventListener(type, lst); win.addEventListener("unload", unl, {once: true}); icon.src = gb.selectedTab.image || def; }; (this.onCreated = btn => btn.render = render)(btn); } }))("chrome://global/skin/icons/defaultFavicon.svg");
Отсутствует
Камрады, я конечно дико извиняюсь, но для обычных пользователей не поленитесь пожалуйста сделать коротенько описание того или иного кода/кнопки - ну типа что она делает, что полезного добавляет. Кому ну совсем не лень - видосик/гифку... а то ну как-то совсем междусобойчик получается. Сорян если неправ, но как-то так оно вот прямо сейчас видется со стороны.
Отредактировано Jurgens (03-01-2022 00:01:12)
Отсутствует
Это хорошо, но откуда в сандбоксе,
в который грузится custom_script.js, возьмётся gBrowser ?Наверно в окно положил, но это нехорошо, как по понятиям,
так и по факту — виджет не будет работать во втором
и последующих окнах браузера.Я вот так записал
(для custom_script.js, как и положено, если явно не указано обратное).скрытый текстВыделить кодКод:
(async def => CustomizableUI.createWidget({ id: "ucf_IconsSiteButton", label: "Иконки сайтов на кнопке", localized: false, onCreated(btn) { var maybeSetImg = (e, icon) => { var tab = e.target; if (tab.selected) { var arr = e.detail.changed; if (arr.includes("selected") || arr.includes("image")) icon.src = tab.image || def; } } var type = "TabAttrModified"; var render = function() { delete this.render; this.render(); var {icon} = this; var win = this.ownerGlobal; var gb = win.gBrowser, tc = gb.tabContainer; var lst = e => maybeSetImg(e, icon); var unl = () => tc.removeEventListener(type, lst); tc.addEventListener(type, lst); win.addEventListener("unload", unl, {once: true}); icon.src = gb.selectedTab.image || def; }; (this.onCreated = btn => btn.render = render)(btn); } }))("chrome://global/skin/icons/defaultFavicon.svg");
Dumby, большое спасибо.
«The Truth Is Out There»
Отсутствует
gClipboard(e) {
Объект же, а не функция. gClipboard: {
Спасибо! Попробую изменить код сам, может получиться. Все изменения вношу в демо-профиль Firefox.
Камрады, я конечно дико извиняюсь, но для обычных пользователей не поленитесь пожалуйста сделать коротенько описание того или иного кода/кнопки - ну типа что она делает, что полезного добавляет.
Запусти демо-профиль Firefox, при наведении на кнопки появляются подробные подсказки, ещё код скриптов подробно прокоменнтирован.
Отсутствует
Dumby - не получается добавить gClipboard в UCF drag and go. Подскажи, как правильно прописать gClipboard в код ?
При этом gClipboard - подключенная как глобальная функция работает - пример в ucf_global_win.js
Второй просьба - добавить в UCF drag and go действия для перетаскивания картинок (там только текст и ссылки?)
Я не нашёл похожий userscript, а в MouseGesture--HY не перетаскивание, а жесты правой кнопкой мыши.
custom_script_win.js loadscript("ucf_global_win.js", globalThis); // глобальные функции ……… loadscript("ucf_mousedrag.js", this); ……… gClipboard: { // this.gClipboard.write… так в ucf_mousedrag.js не работает get ch() { delete this.ch; return this.ch = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, write(str) { this.ch.copyStringToClipboard(str, Services.clipboard.kGlobalClipboard);} }
if (typeof IOUtils != "object") { // Firefox 78 ESR 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))}; } var {prefs, dirsvc} = Services, c = msg => Services.console.logStringMessage("[HC] "+ msg), // отладка glob = { // глобальные функции - общие для всех скриптов custom_script_win.js switchTab(url, but = window) { // открыть вкладку | закрыть, если открыта for(var tab of but.ownerGlobal.gBrowser.tabs) if (tab.linkedBrowser.currentURI.spec == url) {but.ownerGlobal.gBrowser.removeTab(tab); return;}; // закрыть but.ownerGlobal.switchToTabHavingURI(url, true, {relatedToCurrent: true, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()}); }, showInStatus(info, time = 5000, StatusPanel = window.StatusPanel || win.StatusPanel) { if (StatusPanel.update.tid) clearTimeout(StatusPanel.update.tid) else { var {update} = StatusPanel; StatusPanel.update = () => {}; StatusPanel.update.ret = () => { StatusPanel.update = update, StatusPanel.update(); } } StatusPanel.update.tid = setTimeout(StatusPanel.update.ret, time); StatusPanel._label = info; } }, gClipboard = { get ch() { delete this.ch; return this.ch = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, write(str) { this.ch.copyStringToClipboard(str, Services.clipboard.kGlobalClipboard);} }
(async win => ({ // UCF drag and go жесты мыши https://forum.mozilla-russia.org/viewtopic.php?pid=797234#p797234 link: { R: { name: "Копировать ссылку в буфер обмена", cmd() { gClipboard.write(this.val); // глобальные функции glob.showInStatus('в буфере: ' + this.val); } }, U: { name: "Открыть ссылку в новой активной странице", cmd() { win.openUILinkIn(this.val, "tab", this.opts); } }, D: { name: "Открыть ссылку в новой фоновой странице", cmd() { win.openUILinkIn(this.val, "tabshifted", this.opts); } } }, text: { U: { name: "Поиск текста поисковиком по умолчанию в новой активной странице", cmd() { this.search("tab"); } }, D: { name: "Поиск текста поисковиком по умолчанию в новой фоновой странице", cmd() { this.search("tabshifted"); } } }, search(where) { var engine = Services.search[`default${this.opts.private ? "Private" : ""}Engine`]; var submission = engine.getSubmission(this.val, null, ""); win.openUILinkIn(submission.uri.spec, where, {postData: submission.postData, ...this.opts}); }, opts: { //relatedToCurrent: true, triggeringPrincipal: Cu.getObjectPrincipal(this), get userContextId() { return parseInt(win.gBrowser.selectedBrowser.getAttribute("usercontextid")); }, get private() { return win.PrivateBrowsingUtils.isWindowPrivate(win); } }, dragstart(e) { win = e.view.windowRoot.ownerGlobal; //if (!win.gBrowser.currentURI.spec.startsWith("http")) return; if (!e.dataTransfer.mozItemCount || !win.gBrowser.selectedBrowser.matches(":hover")) return; var dt = e.dataTransfer; this.type = this.link; this.dir = this.val = ""; var url = dt.getData("text/x-moz-url-data"); if (url) this.val = url; else { var txt = dt.getData("text/plain"); if (txt) { this.val = txt; if (!this.textLinkRe.test(txt)) this.type = this.text; } else return; } this.x = e.screenX; this.y = e.screenY; this.drag(true); }, drag(init) { var meth = `${init ? "add" : "remove"}EventListener`; for(var type of this.events) win[meth](type, this, true); init || win.StatusPanel.panel.setAttribute("inactive", true); }, events: ["dragover", "drop", "dragend"], dragover(e) { var {x, y} = this, cx = e.screenX, cy = e.screenY; var dx = cx - x, ax = Math.abs(dx), dy = cy - y, ay = Math.abs(dy); if (ax < 10 && ay < 10) return; this.x = cx; this.y = cy; var dir = ax > ay ? dx > 0 ? "R" : "L" : dy > 0 ? "D" : "U"; if (this.dir.endsWith(dir)) return; dir = this.dir += dir; var obj = this.type[dir]; var txt = `${obj ? "Ж" : "Неизвестный ж"}ест мыши: ${dir + (obj ? " " + obj.name : "")}`; win.StatusPanel._labelElement.value = txt; win.StatusPanel.panel.removeAttribute("inactive"); }, dragend(e) { var dt = e.dataTransfer; this.drag(); var obj = this.type[this.dir]; if (!obj || dt.mozUserCancelled) return; var x = e.screenX, y = e.screenY; var wx = win.mozInnerScreenX, wy = win.mozInnerScreenY; x > wx && y > wy && x < wx + win.innerWidth && y < wy + win.innerHeight && obj.cmd.call(this); }, textLinkRe: /^([a-z]+:\/\/)?([a-z]([a-z0-9\-]*\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel)|(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(:[0-9]{1,5})?(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&]*)?)?(#[a-z][a-z0-9_]*)?$|^custombutton:\/\/\S+$/, observe(w) { this.drop = () => this.drag(); this.handleEvent = e => this[e.type](e); var unload = e => { var w = e.target.ownerGlobal; w.gBrowser.tabpanels.removeEventListener("dragstart", this, true); if (w == win) win = null; } (this.observe = w => { //if (!w.toolbar.visible) return; w.gBrowser.tabpanels.addEventListener("dragstart", this, true); w.addEventListener("unload", unload, {once: true}); })(w); }, init(topic, self) { delete this.init; Services.obs.addObserver(self = this, topic); Services.obs.addObserver(function quit(s, t) { Services.obs.removeObserver(self, topic); Services.obs.removeObserver(quit, t); }, "quit-application-granted"); } }).init("browser-delayed-startup-finished"))();
Отредактировано Dobrov (03-01-2022 11:57:00)
Отсутствует
Dumby
Переделайте пожалуйста кнопочку для UCF.
// Автоматически перезагружать вкладку .......... ({ // interval: 1 * 10 * 1000, // интервал обновления = 10 сек. // interval: 1 * 15 * 1000, // интервал обновления = 15 сек. // interval: 1 * 30 * 1000, // интервал обновления = 30 сек. // interval: 1 * 60 * 1000, // интервал обновления = 1 мин. interval: 5 * 60 * 1000, // интервал обновления = 5 мин. // interval: 15 * 60 * 1000, // интервал обновления = 15 мин. // interval: 30 * 60 * 1000, // интервал обновления = 30 мин. // interval: 60 * 60 * 1000; // интервал обновления = 60 мин. id: "cb-auto-reload", init(popup) { this.tabs(this.initTab, true) && this.addStyle(); addDestructor(this.destroy, this); var dsp = e => this[e.type](e); for(var type of ["popupshowing", "TabClose", "SSTabRestored"]) addEventListener(type, dsp, false, (type[0] == "p" ? this.popup = popup : gBrowser.tabContainer) || 1); }, destroy(reason) { this.tabs(this.destroyTab, reason != "delete"); this.menuitem?.remove(); }, tabs(callback, arg) { var res; for(var tab of gBrowser.tabs) { var has = SessionStore.getCustomTabValue(tab, this.id); has && callback.call(this, tab, arg, res = true); } return res; }, initTab(tab, arg) { arg || SessionStore.setCustomTabValue(tab, this.id, "1"); var img = document.createXULElement("hbox"); img.className = this.id; // img.setAttribute("onclick", 'linkedObject.destroyTab(this.closest("tab"))'); img.linkedObject = this; tab.throbber.before(img); tab.setAttribute(this.id, setInterval(this.reload, this.interval, tab)); }, destroyTab(tab, arg) { clearInterval(tab.getAttribute(this.id)); arg || SessionStore.deleteCustomTabValue(tab, this.id); tab.removeAttribute(this.id); tab.querySelector("." + this.id).remove(); }, addStyle() { this.addStyle =()=> {}; var css = ` tab.tabbrowser-tab[${this.id}] .${this.id} { width: 16px; height: 16px; position: relative; margin-top: -1px; margin-inline-start: -2px; margin-inline-end: -14px; background-position: top right; background-repeat: no-repeat; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAEHSURBVHjaYmQAArWgflEglQrEgUCsAsR3gHg9EM++ta7wNSNIASMjQx/rr7fhEd6WrAbaygy3Hr1l2Hjw+u8Xbz+v/P+foYgFZIKEMG94foARKxfTDwZ3G3UGb6Cgj406a2rrhvDnbz5fZwJZ4W+vyRroacdw4MB+hjt37jA8e/aMYd/2NQzOxrKsIHmQIhU1OWGQ0xiSk5MZVFVVGdasWcPg4eHBYKglDxJWAVl3B+gGE5AV8vLyDLdv3wbTrKysDOuOHgMpugMyaT3IkbeBjgVJqKiogOnbUMeD5JmFNT1ufP3+S2b/mfua7z//YH778RvD1iO3GLoXHwH7DqionZGYcAIIMADkw2lofXkQ/wAAAABJRU5ErkJggg=="); z-index: 1000; } tab.tabbrowser-tab[${this.id}]:-moz-locale-dir(rtl) .${this.id} { background-position: top right; } tab.tabbrowser-tab[${this.id}] .tab-icon-image { display: -moz-box; } tab.tabbrowser-tab[${this.id}][pendingicon] .tab-icon-image { visibility: hidden; } // tab.tabbrowser-tab[${this.id}]:not([pendingicon]) .tab-icon-image:not([src]):not([busy]):not([pinned]):not([crashed]):not([sharing]), // tab.tabbrowser-tab[${this.id}] .tab-icon-pending, // tab.tabbrowser-tab[${this.id}] .tab-throbber { // display: none; // } `.replace(/;\s*\n/g, " !important;\n"); var args = ["data:text/css," + encodeURIComponent(css), windowUtils.USER_SHEET]; windowUtils.loadSheetUsingURIString(...args); addDestructor(() => windowUtils.removeSheetUsingURIString(...args)); }, checked(tab = TabContextMenu.contextTab) { return tab.hasAttribute(this.id); }, cmd(tab) { this.addStyle(); (this.cmd = tab => this.checked(tab) ? this.destroyTab(tab) : this.initTab(tab))(tab); }, reload(tab) { gBrowser.reloadTab(tab); }, get shouldHide() { return !TabContextMenu.contextTab .linkedBrowser.currentURI.scheme.startsWith("http"); }, popupshowing(e) { if (this.shouldHide) return; var menuitem = this.menuitem = document.createXULElement("menuitem"); menuitem.id = "cb_AutoReloadTab"; menuitem.setAttribute("type", "checkbox"); menuitem.setAttribute("label", "Автоматически перезагружать"); menuitem.setAttribute("oncommand", "linkedObject.cmd(TabContextMenu.contextTab)"); menuitem.linkedObject = this; this.popup.querySelector("#context_duplicateTab").after(menuitem); (this.popupshowing = e => e.target == this.popup && !(menuitem.hidden = this.shouldHide) && menuitem.setAttribute("checked", this.checked()) )(e); }, TabClose(e) { var intervalId = e.target.getAttribute(this.id); if (!intervalId) return; clearInterval(intervalId); var tab = e.detail.adoptedBy; tab && SessionStore.setCustomTabValue(tab, this.id, "1"); }, SSTabRestored(e) { var tab = e.target; SessionStore.getCustomTabValue(tab, this.id) && !tab.hasAttribute(this.id) && this.initTab(tab, true); } }).init(document.getElementById("tabContextMenu"));
«The Truth Is Out There»
Отсутствует
Dumby
Что это за код? Что чистит?
Отредактировано ВВП (03-01-2022 23:50:05)
Отсутствует
как прописать gClipboard в код ?
не получается добавить gClipboard
Что там может не получиться прописать?
(async win => ({ gClipboard: { write(str) { var kgc = Services.clipboard.kGlobalClipboard; var ch = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); (this.write = str => ch.copyStringToClipboard(str, kgc))(str); } }, link: { R: { name: "Копировать ссылку в буфер обмена", cmd() { this.gClipboard.write(this.val); // местная функция glob.showInStatus('в буфере: ' + this.val); } }, .......
перетаскивания картинок (там только текст и ссылки?)
Там, вроде, картинка рассматривается как ссылка
(на урл изображения, если картинка не ссылка).
Отсутствует
Переделайте пожалуйста кнопочку для UCF.
В первом приближении
(async (id, popup) => ({ // interval: 1 * 10 * 1e3, // интервал обновления = 10 сек. // interval: 1 * 15 * 1e3, // интервал обновления = 15 сек. // interval: 1 * 30 * 1e3, // интервал обновления = 30 сек. // interval: 1 * 60 * 1e3, // интервал обновления = 1 мин. interval: 5 * 60 * 1e3, // интервал обновления = 5 мин. // interval: 15 * 60 * 1e3, // интервал обновления = 15 мин. // interval: 30 * 60 * 1e3, // интервал обновления = 30 мин. // interval: 60 * 60 * 1e3; // интервал обновления = 60 мин. init() { this.addStyle(); var dsp = e => this[e.type](e); var tc = document.getElementById("tabbrowser-tabs"); var types = ["popupshowing", "TabClose", "SSTabRestored"]; (this.destructor = (meth = "removeEventListener") => types.forEach( (type, ind) => (ind ? tc : popup)[meth](type, dsp) ) )("addEventListener"); ucf_custom_script_win[id] = this; ucf_custom_script_win.unloadlisteners.push(id); }, initTab(tab) { SessionStore.setCustomTabValue(tab, id, "1"); var img = document.createXULElement("hbox"); img.className = id; // img.setAttribute("onclick", 'linkedObject.destroyTab(this.closest("tab"))'); // img.linkedObject = this; tab.throbber.before(img); tab.setAttribute(id, setInterval(this.reload, this.interval, tab)); }, destroyTab(tab) { clearInterval(tab.getAttribute(id)); SessionStore.deleteCustomTabValue(tab, id); tab.removeAttribute(id); tab.querySelector("." + id).remove(); }, addStyle() { var css = ` tab.tabbrowser-tab[${id}] .${id} { width: 16px; height: 16px; position: relative; margin-top: -1px; margin-inline-start: -2px; margin-inline-end: -14px; background-position: top right; background-repeat: no-repeat; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAEHSURBVHjaYmQAArWgflEglQrEgUCsAsR3gHg9EM++ta7wNSNIASMjQx/rr7fhEd6WrAbaygy3Hr1l2Hjw+u8Xbz+v/P+foYgFZIKEMG94foARKxfTDwZ3G3UGb6Cgj406a2rrhvDnbz5fZwJZ4W+vyRroacdw4MB+hjt37jA8e/aMYd/2NQzOxrKsIHmQIhU1OWGQ0xiSk5MZVFVVGdasWcPg4eHBYKglDxJWAVl3B+gGE5AV8vLyDLdv3wbTrKysDOuOHgMpugMyaT3IkbeBjgVJqKiogOnbUMeD5JmFNT1ufP3+S2b/mfua7z//YH778RvD1iO3GLoXHwH7DqionZGYcAIIMADkw2lofXkQ/wAAAABJRU5ErkJggg=="); z-index: 1000; } tab.tabbrowser-tab[${id}]:-moz-locale-dir(rtl) .${id} { background-position: top right; } tab.tabbrowser-tab[${id}] .tab-icon-image { display: -moz-box; } tab.tabbrowser-tab[${id}][pendingicon] .tab-icon-image { visibility: hidden; } /* tab.tabbrowser-tab[${id}]:not([pendingicon]) .tab-icon-image:not([src]):not([busy]):not([pinned]):not([crashed]):not([sharing]), tab.tabbrowser-tab[${id}] .tab-icon-pending, tab.tabbrowser-tab[${id}] .tab-throbber { display: none; } */ `.replace(/;\s*\n/g, " !important;\n"); windowUtils.loadSheetUsingURIString( "data:text/css," + encodeURIComponent(css), windowUtils.USER_SHEET ); }, checked(tab = TabContextMenu.contextTab) { return tab.hasAttribute(id); }, cmd(tab) { this.checked(tab) ? this.destroyTab(tab) : this.initTab(tab); }, reload(tab) { gBrowser.reloadTab(tab); }, get shouldHide() { return !TabContextMenu.contextTab .linkedBrowser.currentURI.scheme.startsWith("http"); }, popupshowing(e) { if (this.shouldHide) return; var menuitem = this.menuitem = document.createXULElement("menuitem"); menuitem.id = "cb_AutoReloadTab"; menuitem.setAttribute("type", "checkbox"); menuitem.setAttribute("label", "Автоматически перезагружать"); menuitem.setAttribute("oncommand", "linkedObject.cmd(TabContextMenu.contextTab)"); menuitem.linkedObject = this; popup.querySelector("#context_duplicateTab").after(menuitem); (this.popupshowing = e => e.target == popup && !(menuitem.hidden = this.shouldHide) && menuitem.setAttribute("checked", this.checked()) )(e); }, TabClose(e) { var intervalId = e.target.getAttribute(id); if (!intervalId) return; clearInterval(intervalId); var tab = e.detail.adoptedBy; tab && tab.ownerGlobal.ucf_custom_script_win[id].initTab(tab); }, SSTabRestored(e) { var tab = e.target; SessionStore.getCustomTabValue(tab, id) && !tab.hasAttribute(id) && this.initTab(tab, true); } }).init())("ucf-auto-reload", document.getElementById("tabContextMenu"));
нужен код: очистить lastSession
Тут бы хорошо бы было прикинуть возможность и уровень сложности,
почитав, подробное описание, что могло бы значить «очистить lastSession»,
и посмотрев на предоставленный расклад настроек, но увы, взять негде.
Отредактировано Dumby (04-01-2022 12:13:55)
Отсутствует
Dumby
Этого достаточно ,хотя....Все перелопатил , Где то же поганка зарыта? LastSession.clear(); и это по-ходу не прикрутить ?
Чую отсюда надо взять, но как...
history: { async clear(range) { let refObj = {}; TelemetryStopwatch.start("FX_SANITIZE_HISTORY", refObj); await clearData( range, Ci.nsIClearDataService.CLEAR_HISTORY | Ci.nsIClearDataService.CLEAR_SESSION_HISTORY | Ci.nsIClearDataService.CLEAR_CONTENT_BLOCKING_RECORDS ); // storageAccessAPI permissions record every site that the user // interacted with and thus mirror history quite closely. It makes // sense to clear them when we clear history. However, since their absence // indicates that we can purge cookies and site data for tracking origins without // user interaction, we need to ensure that we only delete those permissions that // do not have any existing storage. let principalsCollector = new PrincipalsCollector(); let principals = await principalsCollector.getAllPrincipals(); await new Promise(resolve => { Services.clearData.deleteUserInteractionForClearingHistory( principals, range ? range[0] : 0, resolve ); }); TelemetryStopwatch.finish("FX_SANITIZE_HISTORY", refObj); }, },
Отредактировано ВВП (04-01-2022 19:31:31)
Отсутствует
В первом приближении
скрытый текстВыделить кодКод:
(async (id, popup) => ({ // interval: 1 * 10 * 1e3, // интервал обновления = 10 сек. // interval: 1 * 15 * 1e3, // интервал обновления = 15 сек. // interval: 1 * 30 * 1e3, // интервал обновления = 30 сек. // interval: 1 * 60 * 1e3, // интервал обновления = 1 мин. interval: 5 * 60 * 1e3, // интервал обновления = 5 мин. // interval: 15 * 60 * 1e3, // интервал обновления = 15 мин. // interval: 30 * 60 * 1e3, // интервал обновления = 30 мин. // interval: 60 * 60 * 1e3; // интервал обновления = 60 мин. init() { this.addStyle(); var dsp = e => this[e.type](e); var tc = document.getElementById("tabbrowser-tabs"); var types = ["popupshowing", "TabClose", "SSTabRestored"]; (this.destructor = (meth = "removeEventListener") => types.forEach( (type, ind) => (ind ? tc : popup)[meth](type, dsp) ) )("addEventListener"); ucf_custom_script_win[id] = this; ucf_custom_script_win.unloadlisteners.push(id); }, initTab(tab) { SessionStore.setCustomTabValue(tab, id, "1"); var img = document.createXULElement("hbox"); img.className = id; // img.setAttribute("onclick", 'linkedObject.destroyTab(this.closest("tab"))'); // img.linkedObject = this; tab.throbber.before(img); tab.setAttribute(id, setInterval(this.reload, this.interval, tab)); }, destroyTab(tab) { clearInterval(tab.getAttribute(id)); SessionStore.deleteCustomTabValue(tab, id); tab.removeAttribute(id); tab.querySelector("." + id).remove(); }, addStyle() { var css = ` tab.tabbrowser-tab[${id}] .${id} { width: 16px; height: 16px; position: relative; margin-top: -1px; margin-inline-start: -2px; margin-inline-end: -14px; background-position: top right; background-repeat: no-repeat; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAEHSURBVHjaYmQAArWgflEglQrEgUCsAsR3gHg9EM++ta7wNSNIASMjQx/rr7fhEd6WrAbaygy3Hr1l2Hjw+u8Xbz+v/P+foYgFZIKEMG94foARKxfTDwZ3G3UGb6Cgj406a2rrhvDnbz5fZwJZ4W+vyRroacdw4MB+hjt37jA8e/aMYd/2NQzOxrKsIHmQIhU1OWGQ0xiSk5MZVFVVGdasWcPg4eHBYKglDxJWAVl3B+gGE5AV8vLyDLdv3wbTrKysDOuOHgMpugMyaT3IkbeBjgVJqKiogOnbUMeD5JmFNT1ufP3+S2b/mfua7z//YH778RvD1iO3GLoXHwH7DqionZGYcAIIMADkw2lofXkQ/wAAAABJRU5ErkJggg=="); z-index: 1000; } tab.tabbrowser-tab[${id}]:-moz-locale-dir(rtl) .${id} { background-position: top right; } tab.tabbrowser-tab[${id}] .tab-icon-image { display: -moz-box; } tab.tabbrowser-tab[${id}][pendingicon] .tab-icon-image { visibility: hidden; } /* tab.tabbrowser-tab[${id}]:not([pendingicon]) .tab-icon-image:not([src]):not([busy]):not([pinned]):not([crashed]):not([sharing]), tab.tabbrowser-tab[${id}] .tab-icon-pending, tab.tabbrowser-tab[${id}] .tab-throbber { display: none; } */ `.replace(/;\s*\n/g, " !important;\n"); windowUtils.loadSheetUsingURIString( "data:text/css," + encodeURIComponent(css), windowUtils.USER_SHEET ); }, checked(tab = TabContextMenu.contextTab) { return tab.hasAttribute(id); }, cmd(tab) { this.checked(tab) ? this.destroyTab(tab) : this.initTab(tab); }, reload(tab) { gBrowser.reloadTab(tab); }, get shouldHide() { return !TabContextMenu.contextTab .linkedBrowser.currentURI.scheme.startsWith("http"); }, popupshowing(e) { if (this.shouldHide) return; var menuitem = this.menuitem = document.createXULElement("menuitem"); menuitem.id = "cb_AutoReloadTab"; menuitem.setAttribute("type", "checkbox"); menuitem.setAttribute("label", "Автоматически перезагружать"); menuitem.setAttribute("oncommand", "linkedObject.cmd(TabContextMenu.contextTab)"); menuitem.linkedObject = this; popup.querySelector("#context_duplicateTab").after(menuitem); (this.popupshowing = e => e.target == popup && !(menuitem.hidden = this.shouldHide) && menuitem.setAttribute("checked", this.checked()) )(e); }, TabClose(e) { var intervalId = e.target.getAttribute(id); if (!intervalId) return; clearInterval(intervalId); var tab = e.detail.adoptedBy; tab && tab.ownerGlobal.ucf_custom_script_win[id].initTab(tab); }, SSTabRestored(e) { var tab = e.target; SessionStore.getCustomTabValue(tab, id) && !tab.hasAttribute(id) && this.initTab(tab, true); } }).init())("ucf-auto-reload", document.getElementById("tabContextMenu"));
Dumby, огромное спасибо.
«The Truth Is Out There»
Отсутствует
Dumby у тебя UA: 78.0, почему ты пользуешься версией Firefox 78, а не более новой?
Если эксперт Dumby выбрал версию от июня 2020г, значит она самая стабильная и быстрая?
Тогда может и остальным сто́ит перейти на FF78 и под неё основные скрипты адаптировать?
Или дело только в твоём профиле и скриптах/кнопках, «привязанных» именно к этой версии?
Dumby - Не мог бы ты перечислить возможности или показать ссылки на кнопки/скрипты, установленные или в твоём профиле или просто полезные всем, как набор must have софта?
Если ты и другие эксперты сделают сборку-профиль Firefox с лучшими скриптами/кнопками, это для начинающих будет полезней, чем
моя сборка Firefox 90+, расширенная возможностями примеров (с небольшими улучшениями) из этого форума!
Отсутствует
Dumby
Вы когда-то делали мне вот такую СВ-кнопку:
// https://forum.mozilla-russia.org/viewtopic.php?pid=782375#p782375 ..... ((g, id) => { addDestructor(r => r[5] == "e" && g[id]?.destroy()); g[id] || ({ check(channel) { var ua, {host} = channel.originalURI; if (host == "site1.org") ua = "User Agent 1"; else if (host == "site2.com") ua = "User Agent 2"; //else if (... ua && channel.setRequestHeader("User-Agent", ua, false); }, init(topics) { var {obs} = Services; this.observe = subj => subj instanceof Ci.nsIHttpChannel && this.check(subj); obs.addObserver(g[id] = this, topics[0], false); obs.addObserver(this.destroy = () => delete g[id] && topics.forEach( (t, ind) => obs.removeObserver(ind ? this.destroy : this, t) ), topics[1], false); } }).init(["http-on-modify-request", "quit-application-granted"]); })(Cu.getGlobalForObject(Cu), "CBUserAgentRequestHeaderSetterObserver");
Если не сложно, не могли бы вы переделать эту кнопку под config.js.
Отредактировано unter_officer (05-01-2022 05:03:02)
«The Truth Is Out There»
Отсутствует
Dobrov
выбрал версию от июня 2020г, значит она самая стабильная и быстрая?
Тогда может и остальным сто́ит перейти на FF78 и под неё основные скрипты адаптировать?
Нет.
дело только в твоём профиле и скриптах/кнопках, «привязанных» именно к этой версии?
Да.
Не мог бы ты перечислить возможности или показать ссылки на кнопки/скрипты, установленные или в твоём профиле или просто полезные всем
Нет. Я без понятия что есть «полезное всем»,
но уверен, что в профиле ничего подобного нету,
ну кроме очевидного, типа Attributes Inspector и всё такое.
вы сказали, что этому коду лучше бы разместиться в config.js или UCF
Ну да, лучше
(async topic => { var observer = channel => { if (channel instanceof Ci.nsIHttpChannel) { var ua, {host} = channel.originalURI; if (host == "site1.org") ua = "User Agent 1"; else if (host == "site2.com") ua = "User Agent 2"; //else if (... ua && channel.setRequestHeader("User-Agent", ua, false); } } var obs = Cc["@mozilla.org/observer-service;1"] .getService(Ci.nsIObserverService); obs.addObserver(observer, topic); obs.addObserver(function quit(s, t) { obs.removeObserver(quit, t); obs.removeObserver(observer, topic); }, "quit-application-granted"); })("http-on-modify-request");
Неужели ничего нельзя заколбасить? Не убрать пункт, а очистить
Я не знаю. Просто не понимаю что ты хочешь.
Ну вот такой код очищает, и пункт на это реагирует.
SessionStore.canRestoreLastSession = false;
Отсутствует
Ну да, лучше
скрытый текстВыделить кодКод:
(async topic => { var observer = channel => { if (channel instanceof Ci.nsIHttpChannel) { var ua, {host} = channel.originalURI; if (host == "site1.org") ua = "User Agent 1"; else if (host == "site2.com") ua = "User Agent 2"; //else if (... ua && channel.setRequestHeader("User-Agent", ua, false); } } var obs = Cc["@mozilla.org/observer-service;1"] .getService(Ci.nsIObserverService); obs.addObserver(observer, topic); obs.addObserver(function quit(s, t) { obs.removeObserver(quit, t); obs.removeObserver(observer, topic); }, "quit-application-granted"); })("http-on-modify-request");
Dumby, большое спасибо. Всё работает.
Единственное, есть маленький нюанс. Если просматривать исходный код любой страницы, то в консоли появляется ошибка:
NS_ERROR_FAILURE: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIURI.host] config.js:333
observer config.js:333
Консоль ссылается вот на эту строку кода: if (channel instanceof Ci.nsIHttpChannel) {
Впрочем, думаю на это можно не обращать внимания.
«The Truth Is Out There»
Отсутствует
думаю на это можно не обращать внимания
Ну почему же, весьма интересное наблюдение. Можно заменить originalURI на URI
он без "view-source:" идёт. Это если и для таких запросов нужно UA устанавливать.
А если не нужно, то можно отсечь, вписать куда-нибудь проверку на это дело, например,
(async topic => { var observer = channel => { if (channel instanceof Ci.nsIHttpChannel) { var uri = channel.originalURI; if (uri.schemeIs("view-source")) return; var ua, {host} = uri;
Отсутствует
Ну почему же, весьма интересное наблюдение. Можно заменить originalURI на URI
он без "view-source:" идёт. Это если и для таких запросов нужно UA устанавливать.
А если не нужно, то можно отсечь, вписать куда-нибудь проверку на это дело, например,скрытый текстВыделить кодКод:
(async topic => { var observer = channel => { if (channel instanceof Ci.nsIHttpChannel) { var uri = channel.originalURI; if (uri.schemeIs("view-source")) return; var ua, {host} = uri;
Dumby, спасибо. Теперь всё супер.
«The Truth Is Out There»
Отсутствует
Подскажите способ проверить наличие файла с системным путём, то есть не привязанным к chrome://…
например файл "/usr/bin/konsole" — ищем в Линукс, "C:\windows\explorer.exe" — в Windows.
а затем запустить найденный файл в Линукс или Windows, в зависимости, в какой системе открыт Firefox.
Отсутствует
Подскажите способ проверить наличие файла
Шутить изволишь?
Отсутствует