Что за стиль?
«The Truth Is Out There»
Отсутствует
Dumby
подключить в UCF-custom_script.js
Прописал CB drag and go в custom_script_win.js, но не могу сделать копирование адреса перетаскиваемой ссылки. Добавил жест вправо, но код буфера обмена в этом скрипте не работает. В ucf_hookClicks.js работает…
Нужно так — если тащить ссылку вправо, то скопировать её адрес в буфер обмена.
gClipboard(e) { 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);} },
Отредактировано Dobrov (02-01-2022 03:59:02)
Отсутствует
Здравствуйте! С Новым Годом!
Работал на 51 версии Мозиллы и горя не знал. Спасибо изобретателю СВ-кнопок. Но жизнь заставила переходить на новые версии Мозиллы, а на них не могу поставить СВ-замучился. Расскажите, пожалуйста по-порядку: какую из новых версий Мозиллы установить и как поставить на неё СВ и что ещё сделать, чтобы опять всё заработало?
Отредактировано dedfor (02-01-2022 06:09:15)
Отсутствует
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»
Отсутствует