Dumby
Здравствуйте, вы когда то сделали кнопку в контекстное меню вкладки "добавить контейнер в закладки"
она создает папку на панели закладок с таким же названием как название контейнера и добавляет в нее вкладки из этого контейнера
// Добавить контейнер в закладки.................... (async id => { var menuitem = document.createXULElement("menuitem"); document.getElementById(id).after(menuitem); typeof addDestructor == "function" && addDestructor(() => menuitem.remove()); menuitem.render = function() { this.id = "context_bookmarkContainer"; this.label = "Добавить контейнер в закладки"; this.setAttribute("oncommand", "bookmark()"); var bm = PlacesUtils.bookmarks, attr = "usercontextid"; var {toolbarGuid: parentGuid, TYPE_FOLDER: type} = bm; this.bookmark = async () => { var tab = TabContextMenu.contextTab; var id = tab.getAttribute(attr); var title = ContextualIdentityService.getUserContextLabel(id); var {guid} = await bm.insert({title, parentGuid, type}); var tabs = []; for(tab of gBrowser.visibleTabs) tab.getAttribute(attr) == id && tabs.unshift(tab) && await bm.insert({ parentGuid: guid, title: tab.label, url: tab.linkedBrowser.currentURI.spec }); gBrowser.removeTabs(tabs); } var raf = () => menuitem.hidden = !TabContextMenu.contextTab.hasAttribute(attr); var {render} = this.constructor.prototype; (this.render = () => { requestAnimationFrame(raf); render.call(menuitem); })(); } })("context_reopenInContainer");
А вы бы не могли пожалуйста сделать чтобы этот процесс происходил автоматически?
Чтобы если создается контейнер, тогда на панели закладок создается папка с таким же названием как у контейнера и в эту папку добавляется вкладка из этого контейнера
Отсутствует
Чтобы если создается контейнер, тогда на панели закладок создается папка с таким же названием как у контейнера
и в эту папку добавляется вкладка из этого контейнера
Не смог понять что за вкладка такая особенная,
и чем обеспечивается её предсуществование
в момент создания контейнера.
Отсутствует
Dumby
Извиняюсь, вот ваш предыдущий код открывает вкладку со строки поиска в контейнере
Чтобы на панели закладок автоматически создавалась папка с таким же названием как у контейнера и вкладка что открывается со строки поиска добавлялась в эту папку
Отредактировано Stkvsky (24-02-2024 21:15:07)
Отсутствует
Stkvsky
Проблема в том, что закладке хорошо бы назначить имя,
такое же, как у этой вкладки в итоге.
Но вкладка свежеиспечённая, ещё только пошла грузиться,
и когда она разродится своим окончательным именем поймать не получается.
Хотел подрядить ProgressListener, но успеха не снискал,
а пробовать что-то ещё мудрёнее желания нет.
Таким образом, могу предложить лишь таймаут,
типа ждём секунду, и добавляем закладку с таким именем,
которое будет у таба на тот момент. Надеюсь, лучше чем ничего.
Код на замену
(proto => { var title, bm = PlacesUtils.bookmarks; var {toolbarGuid: parentGuid, TYPE_FOLDER: type} = bm; var wait = resolve => setTimeout(resolve, 1000); var ntc = async br => { var tab = gBrowser.getTabForBrowser(br); var {guid} = await bm.insert({title, parentGuid, type}); await new Promise(wait); bm.insert({title: tab.label, url: br.currentURI.spec, parentGuid: guid}); } var ds = proto.doSearch; proto.doSearch = function(str, where, e, params) { if (where == "current") where = "tab"; params.userContextId = ContextualIdentityService.create(title = str, "vacation", "purple").userContextId; params.resolveOnNewTabCreated = ntc; ds.apply(this, arguments); } addDestructor(() => proto.doSearch = ds); })(customElements.get("searchbar").prototype);
Отсутствует
Код на замену
Вы бы не могли пожалуйста добавить, чтобы и другие вкладки которые открываются в этом же контейнере, добавлялись в эту же папку закладок?
Отредактировано Stkvsky (28-02-2024 23:22:15)
Отсутствует
Stkvsky
Ууу, это сложновато для меня.
Нужно карту сопоставления userContextId и guid'а папки
куда-то на диск сбрасывать.
Вот, не всё, что хотелось бы, да и запутаться могу запросто,
и тестировать это весьма заморочно.
(proto => { var g = Cu.getGlobalForObject(Cu); var name = "userContextId2FolderGuid.json"; var obj = g[name] ??= g.eval(`(${name => { var obj = globalThis[name] = Object.create(null); var path = obj.path = PathUtils.join(PathUtils.profileDir, name); var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); obj.deleted = new Map(); var map = Object.create(null), guids = new Map(); var running, write = () => { running = false; for(var k in map) return IOUtils.writeJSON(path, map); IOUtils.remove(path); } var save = () => { if (running) timer.cancel(); timer.initWithCallback(write, 500, timer.TYPE_ONE_SHOT); running = true; } var reg = (id, guid) => { if (guid) guids.set(map[id] = guid, +id); else guids.delete(map[id]), delete map[id]; } var {PlacesUtils: pu, ContextualIdentityService: cis} = Services.wm.getMostRecentBrowserWindow(); cis.ensureDataReady(); var ids = new Set(cis.getPublicUserContextIds()); var bm = pu.bookmarks, {toolbarGuid: parentGuid, TYPE_FOLDER: type} = bm; (async () => {try { var shouldSave, data = await IOUtils.readJSON(path); for(var id in data) ids.has(+id) && await bm.fetch({guid: data[id]}) ? guids.set(map[id] = data[id], +id) : shouldSave = true; shouldSave && save(); } catch {}})(); obj.ntc = async br => save(reg( br.getAttribute("usercontextid"), (await bm.insert({title: obj.title, parentGuid, type})).guid )); var insert = tab => { var parentGuid = map[tab.getAttribute("usercontextid")]; parentGuid && bm.insert({title: tab.label, url: tab.linkedBrowser.currentURI.spec, parentGuid}); } obj.insert = e => e.target.ownerGlobal.setTimeout(insert, 1000, e.target); var args = [["bookmark-added", "bookmark-removed"], arr => { var shouldSave; for(var e of arr) if (e.itemType == type) { var {guid} = e; if (e.type[9] == "a") { var id = obj.deleted.get(guid); if (id) obj.deleted.delete(guid), reg(id, guid), shouldSave = true; } else { var id = guids.get(guid); if (id) obj.deleted.set(guid, id), reg(id), shouldSave = true; } } shouldSave && save(); }]; pu.observers.addListener(...args); var qt = "quit-application-granted"; var dt = "contextual-identity-deleted"; var obs = (subj, t) => { var id = subj.wrappedJSObject.userContextId; if (id in map) save(reg(id)); else for(var [key, val] of obj.deleted) if (val == id) return obj.deleted.delete(key); } Services.obs.addObserver(obs, dt); Services.obs.addObserver(obj.unobserve = function quit() { pu.observers.removeListener(...args); Services.obs.removeObserver(quit, qt); Services.obs.removeObserver(obs, dt); }, qt); return obj; }})("${name}");`); addEventListener("TabOpen", obj.insert, false, gBrowser.tabContainer); var ds = proto.doSearch; proto.doSearch = function(str, where, e, params) { if (where == "current") where = "tab"; params.userContextId = ContextualIdentityService.create(obj.title = str, "vacation", "purple").userContextId; params.resolveOnNewTabCreated = obj.ntc; ds.apply(this, arguments); } addDestructor(reason => { proto.doSearch = ds; if (reason[5] == "e" && name in g) { delete g[name]; obj.unobserve(); reason.startsWith("d") ? IOUtils.remove(obj.path) : setTimeout(del => name in g && (g[name].deleted = del), 1e3, obj.deleted); } }); })(customElements.get("searchbar").prototype);
Отсутствует
Bug 1878401 - Always pass BrowsingContext to nsIFilePicker::Init (Firefox 125+)
Соберу, на всякий случай, Custom Buttons 0.0.7.0.0.33.
Отсутствует
Ууу, это сложновато для меня.Нужно карту сопоставления userContextId и guid'а папкикуда-то на диск сбрасывать.Вот, не всё, что хотелось бы, да и запутаться могу запросто,и тестировать это весьма заморочно.скрытый текстВыделить кодКод:
скрытый текстВыделить кодКод:
(proto => { var g = Cu.getGlobalForObject(Cu); var name = "userContextId2FolderGuid.json"; var obj = g[name] ??= g.eval(`(${name => { var obj = globalThis[name] = Object.create(null); var path = obj.path = PathUtils.join(PathUtils.profileDir, name); var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); obj.deleted = new Map(); var map = Object.create(null), guids = new Map(); var running, write = () => { running = false; for(var k in map) return IOUtils.writeJSON(path, map); IOUtils.remove(path); } var save = () => { if (running) timer.cancel(); timer.initWithCallback(write, 500, timer.TYPE_ONE_SHOT); running = true; } var reg = (id, guid) => { if (guid) guids.set(map[id] = guid, +id); else guids.delete(map[id]), delete map[id]; } var {PlacesUtils: pu, ContextualIdentityService: cis} = Services.wm.getMostRecentBrowserWindow(); cis.ensureDataReady(); var ids = new Set(cis.getPublicUserContextIds()); var bm = pu.bookmarks, {toolbarGuid: parentGuid, TYPE_FOLDER: type} = bm; (async () => {try { var shouldSave, data = await IOUtils.readJSON(path); for(var id in data) ids.has(+id) && await bm.fetch({guid: data[id]}) ? guids.set(map[id] = data[id], +id) : shouldSave = true; shouldSave && save(); } catch {}})(); obj.ntc = async br => save(reg( br.getAttribute("usercontextid"), (await bm.insert({title: obj.title, parentGuid, type})).guid )); var insert = tab => { var parentGuid = map[tab.getAttribute("usercontextid")]; parentGuid && bm.insert({title: tab.label, url: tab.linkedBrowser.currentURI.spec, parentGuid}); } obj.insert = e => e.target.ownerGlobal.setTimeout(insert, 1000, e.target); var args = [["bookmark-added", "bookmark-removed"], arr => { var shouldSave; for(var e of arr) if (e.itemType == type) { var {guid} = e; if (e.type[9] == "a") { var id = obj.deleted.get(guid); if (id) obj.deleted.delete(guid), reg(id, guid), shouldSave = true; } else { var id = guids.get(guid); if (id) obj.deleted.set(guid, id), reg(id), shouldSave = true; } } shouldSave && save(); }]; pu.observers.addListener(...args); var qt = "quit-application-granted"; var dt = "contextual-identity-deleted"; var obs = (subj, t) => { var id = subj.wrappedJSObject.userContextId; if (id in map) save(reg(id)); else for(var [key, val] of obj.deleted) if (val == id) return obj.deleted.delete(key); } Services.obs.addObserver(obs, dt); Services.obs.addObserver(obj.unobserve = function quit() { pu.observers.removeListener(...args); Services.obs.removeObserver(quit, qt); Services.obs.removeObserver(obs, dt); }, qt); return obj; }})("${name}");`); addEventListener("TabOpen", obj.insert, false, gBrowser.tabContainer); var ds = proto.doSearch; proto.doSearch = function(str, where, e, params) { if (where == "current") where = "tab"; params.userContextId = ContextualIdentityService.create(obj.title = str, "vacation", "purple").userContextId; params.resolveOnNewTabCreated = obj.ntc; ds.apply(this, arguments); } addDestructor(reason => { proto.doSearch = ds; if (reason[5] == "e" && name in g) { delete g[name]; obj.unobserve(); reason.startsWith("d") ? IOUtils.remove(obj.path) : setTimeout(del => name in g && (g[name].deleted = del), 1e3, obj.deleted); } }); })(customElements.get("searchbar").prototype);
Можно вас попросить еще добавить открытие закладки в контейнере?
Вы когда то уже такое делали, ваш старый код добавлю ниже.
Чтобы ЛКМ по закладке отрывал ее в контейнере (название для контейнера бралось с названия папки в которой находится закладка)
var {PlacesUtils} = ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm"); var {PrivateBrowsingUtils} = ChromeUtils.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); ChromeUtils.import( "resource:///modules/PlacesUIUtils.jsm" ).PlacesUIUtils._openNodeIn = function PUIU__openNodeIn(node, where, win, priv) { if (node && PlacesUtils.nodeIsURI(node) && this.checkURLSecurity(node, win)) { var {uri} = node; var isBookmark = PlacesUtils.nodeIsBookmark(node); if (!PrivateBrowsingUtils.isWindowPrivate(win)) isBookmark ? this.markPageAsFollowedBookmark(uri) : this.markPageAsTyped(uri); var params = {private: priv, inBackground: this.loadBookmarksInBackground}; if (uri.startsWith("javascript:")) params.allowPopups = params.allowInheritPrincipal = true; else if (isBookmark) { var e = win.event; if ( e && !e.button && e.detail <= 1 && !e.ctrlKey && !e.shiftKey && !e.altKey && (e.type == "command" || e.type == "click") && e.target.matches(".bookmark-item, treechildren") ) { if (where == "current") where = "tab"; var title, {parent} = node, {type} = parent; var folder = type == node.RESULT_TYPE_FOLDER || type == node.RESULT_TYPE_FOLDER_SHORTCUT; if (folder) title = PlacesUtils.bookmarks.getLocalizedTitle({ guid: parent.bookmarkGuid, title: parent.title }); var id = params.userContextId = self.newUsercontext(title); folder || updateTitle(id, node.bookmarkGuid); } } win.openTrustedLinkIn(uri, where, params); } } var updateTitle = async (id, guid) => { var {parentGuid} = await PlacesUtils.bookmarks.fetch(guid); var title = PlacesUtils.bookmarks.getLocalizedTitle( await PlacesUtils.bookmarks.fetch(parentGuid) ); var {icon, color} = this.cis.getPublicIdentityFromId(id); this.cis.update(id, title, icon, color); }
И если при открытии закладки в контейнере, контейнер с таким именем(как название папки закладки) уже существует, то открывать в нем же, а не создавать новый
/* var folder = type == node.RESULT_TYPE_FOLDER || type == node.RESULT_TYPE_FOLDER_SHORTCUT; if (folder) title = PlacesUtils.bookmarks.getLocalizedTitle({ guid: parent.bookmarkGuid, title: parent.title }); var id = params.userContextId = self.newUsercontext(title); folder || updateTitle(id, node.bookmarkGuid); } } win.openTrustedLinkIn(uri, where, params); } } var updateTitle = async (id, guid) => { var {parentGuid} = await PlacesUtils.bookmarks.fetch(guid); var title = PlacesUtils.bookmarks.getLocalizedTitle( await PlacesUtils.bookmarks.fetch(parentGuid) ); var {icon, color} = this.cis.getPublicIdentityFromId(id); this.cis.update(id, title, icon, color); } */ if ( type == node.RESULT_TYPE_FOLDER || type == node.RESULT_TYPE_FOLDER_SHORTCUT ) title = PlacesUtils.bookmarks.getLocalizedTitle({ guid: parent.bookmarkGuid, title: parent.title }); else { var quit = false; var until = () => quit; var stop = () => quit = true; var guid, info; PlacesUtils.bookmarks.fetch(node.bookmarkGuid) .then(info => guid = info.parentGuid) .finally(stop); spin(until); quit = false; PlacesUtils.bookmarks.fetch(guid) .then(res => info = res) .finally(stop); spin(until); if (info) title = PlacesUtils.bookmarks.getLocalizedTitle(info); } title = title || "\u200b"; // ZWSP var id = self.cis.getPublicIdentities() .find(find, title)?.userContextId; params.userContextId = id || self.newUsercontext(title); } } win.openTrustedLinkIn(uri, where, params); } } var spin = arg => { var {tm} = Services; spin = tm.spinEventLoopUntilOrShutdown || tm.spinEventLoopUntilOrQuit; var bargs = [tm]; spin.length == 2 && bargs.push("Fetch bookmark folder title sync"); (spin = spin.bind(...bargs))(arg); } var find = function(uc) { return uc.name == this; }
Отсутствует
Можно вас попросить еще добавить открытие закладки в контейнере?
В смысле вписать в первый код
результирующую фаргментов второго и третьего?
Тогда как-то так, наверно
(proto => { var g = Cu.getGlobalForObject(Cu); var name = "userContextId2FolderGuid.json"; var obj = g[name] ??= g.eval(`(${name => { var title; var obj = globalThis[name] = Object.create(null); var path = obj.path = PathUtils.join(PathUtils.profileDir, name); var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); obj.deleted = new Map(); var map = Object.create(null), guids = new Map(); var running, write = () => { running = false; for(var k in map) return IOUtils.writeJSON(path, map); IOUtils.remove(path); } var save = () => { if (running) timer.cancel(); timer.initWithCallback(write, 500, timer.TYPE_ONE_SHOT); running = true; } var reg = (id, guid) => { if (guid) guids.set(map[id] = guid, +id); else guids.delete(map[id]), delete map[id]; } var {PlacesUtils: pu, ContextualIdentityService: cis, PlacesUIUtils, PrivateBrowsingUtils} = Services.wm.getMostRecentBrowserWindow(); cis.ensureDataReady(); var ids = new Set(cis.getPublicUserContextIds()); var bm = pu.bookmarks, {toolbarGuid: parentGuid, TYPE_FOLDER: type} = bm; (async () => {try { var shouldSave, data = await IOUtils.readJSON(path); for(var id in data) ids.has(+id) && await bm.fetch({guid: data[id]}) ? guids.set(map[id] = data[id], +id) : shouldSave = true; shouldSave && save(); } catch {}})(); obj.ntc = async br => save(reg( br.getAttribute("usercontextid"), (await bm.insert({title, parentGuid, type})).guid )); var insert = tab => { var parentGuid = map[tab.getAttribute("usercontextid")]; parentGuid && bm.insert({title: tab.label, url: tab.linkedBrowser.currentURI.spec, parentGuid}); } obj.insert = e => e.target.ownerGlobal.setTimeout(insert, 1000, e.target); obj.newUsercontext = str => cis.create(title = str, "vacation", "purple").userContextId; var args = [["bookmark-added", "bookmark-removed"], arr => { var shouldSave; for(var e of arr) if (e.itemType == type) { var {guid} = e; if (e.type[9] == "a") { var id = obj.deleted.get(guid); if (id) obj.deleted.delete(guid), reg(id, guid), shouldSave = true; } else { var id = guids.get(guid); if (id) obj.deleted.set(guid, id), reg(id), shouldSave = true; } } shouldSave && save(); }]; pu.observers.addListener(...args); var {tm} = Services; var spin = tm.spinEventLoopUntilOrQuit.bind(tm, "Fetch bookmark folder title sync"); var find = function(uc) { return uc.name == this; } obj._opin = PlacesUIUtils._openNodeIn; PlacesUIUtils._openNodeIn = function PUIU__openNodeIn(node, where, win, {priv = false, userContextId = 0} = {}) { if (node && pu.nodeIsURI(node) && this.checkURLSecurity(node, win)) { var {uri} = node, isBookmark = pu.nodeIsBookmark(node); if (!PrivateBrowsingUtils.isWindowPrivate(win)) isBookmark ? this.markPageAsFollowedBookmark(uri) : this.markPageAsTyped(uri); else priv = true; var params = {private: priv, inBackground: this.loadBookmarksInBackground, userContextId}; if (uri.startsWith("javascript:")) params.allowPopups = params.allowInheritPrincipal = true; else if (isBookmark && !userContextId) { var e = win.event; if ( e && !e.button && e.detail <= 1 && !e.ctrlKey && !e.shiftKey && !e.altKey && (e.type == "command" || e.type == "click") && e.target.matches(".bookmark-item, treechildren") ) { if (where == "current") where = "tab"; var title, {parent} = node, {type} = parent; if ( type == node.RESULT_TYPE_FOLDER || type == node.RESULT_TYPE_FOLDER_SHORTCUT ) title = pu.bookmarks.getLocalizedTitle({ guid: parent.bookmarkGuid, title: parent.title }); else { var quit = false; var until = () => quit; var stop = () => quit = true; var guid, info; pu.bookmarks.fetch(node.bookmarkGuid) .then(info => guid = info.parentGuid) .finally(stop); spin(until); quit = false; pu.bookmarks.fetch(guid) .then(res => info = res) .finally(stop); spin(until); if (info) title = pu.bookmarks.getLocalizedTitle(info); } title = title || "\u200b"; // ZWSP var id = cis.getPublicIdentities().find(find, title)?.userContextId; params.userContextId = id || obj.newUsercontext(title); } } win.openTrustedLinkIn(uri, where, params); } } var qt = "quit-application-granted"; var dt = "contextual-identity-deleted"; var obs = (subj, t) => { var id = subj.wrappedJSObject.userContextId; if (id in map) save(reg(id)); else for(var [key, val] of obj.deleted) if (val == id) return obj.deleted.delete(key); } Services.obs.addObserver(obs, dt); Services.obs.addObserver(obj.unobserve = function quit() { pu.observers.removeListener(...args); Services.obs.removeObserver(quit, qt); Services.obs.removeObserver(obs, dt); }, qt); return obj; }})("${name}");`); addEventListener("TabOpen", obj.insert, false, gBrowser.tabContainer); var ds = proto.doSearch; proto.doSearch = function(str, where, e, params) { if (where == "current") where = "tab"; params.userContextId = obj.newUsercontext(str); params.resolveOnNewTabCreated = obj.ntc; ds.apply(this, arguments); } addDestructor(reason => { proto.doSearch = ds; if (reason[5] == "e" && name in g) { delete g[name]; obj.unobserve(); if (reason.startsWith("d")) return IOUtils.remove(obj.path); PlacesUIUtils._openNodeIn = obj._opin; setTimeout(del => name in g && (g[name].deleted = del), 1e3, obj.deleted); } }); })(customElements.get("searchbar").prototype);
Отсутствует
Dumby
Вы бы не могли пожалуйста еще и этот код добавить, вы когда то делали, в новой версии перестал работать:
Он при открытии закладки, если такая закладка уже открыта во вкладке, автоматически переключается на неё
/*переключение на открытую закладку*/ (popup => { var puu = `/PlacesUIUtils.${ parseInt(Services.appinfo.platformVersion) >= 104 ? "sys.mjs" : "jsm" }:`; var skipRe = /\nopenMultipleLinksInTabs@|\/historySidebar.xhtml:/; var treeRe = /@chrome:\/\/browser\/content\/places\/(places|bookmarksSidebar)\.xhtml:/; var timestamp = 0, activate = 0, placesNode; addEventListener("activate", () => activate = Cu.now()); addEventListener("DOMMenuItemActive", e => placesNode = e.target._placesNode); var check = url => { for(var win of BrowserWindowTracker.orderedWindows) if (win.toolbar.visible) for(var tab of (win.gBrowser?.tabs || [])) if (tab.linkedBrowser?.currentURI?.spec == url) return win.focus(), win.gBrowser.selectedTab = tab; } var sels = [ "menuitem[_moz-menuactive]", "#panelMenu_bookmarksMenu > toolbarbutton:is(:active,:focus)", "toolbarbutton.bookmark-item:is(:hover,:-moz-focusring)" ]; addEventListener("TabBrowserInserted", e => { if (timestamp - (timestamp = Cu.now()) > -500) return; var stack = Components.stack.formattedStack; if (!stack.includes(puu) || skipRe.test(stack)) return; if (treeRe.test(stack)) { var win; if (RegExp.$1.startsWith("p") && timestamp - activate < 500) win = Services.wm.getMostRecentWindow("Places:Organizer"); var view = (win || window).document.commandDispatcher.focusedElement?.view; if (view) var node = view.nodeForTreeIndex(view.selection.currentIndex); } else { for(var node of sels) if (node = document.querySelector(node)) break; node = node?._placesNode || popup._view?.selectedNode || placesNode; } if (node && PlacesUtils.nodeIsBookmark(node) && check(node.uri)) { var tab = e.target, br = tab.linkedBrowser; var {loadURI} = br; br.loadURI = () => { br.loadURI = loadURI; gBrowser.removeTab(tab); } } }, true, gBrowser.tabContainer); })(document.getElementById("placesContext"));
Отредактировано Stkvsky (16-03-2024 14:42:05)
Отсутствует
еще и этот код добавить
Код совершенно оконный, не нужно его добавлять ни в какой другой.
Просто дописать в конец, как отдельный, как следующий.
Он при открытии закладки
Нет, не так. Не просто «при открытии закладки»,
а при открытии закладки в новой вкладке (не в текущей).
в новой версии перестал работать
Можно попробовать такую правку применить, и посмотреть как пойдёт.
/* var {loadURI} = br; br.loadURI = () => { br.loadURI = loadURI; gBrowser.removeTab(tab); } */ br.fixupAndLoadURIString = () => { delete br.fixupAndLoadURIString; gBrowser.removeTab(tab); }
Отсутствует
Dumby а можете еще пожалуйста добавить функцию, чтобы при удалении закладки, если она открыта во вкладке, автоматически закрывать эту вкладку.
/*переключение на открытую закладку*/ (popup => { var puu = `/PlacesUIUtils.${ parseInt(Services.appinfo.platformVersion) >= 104 ? "sys.mjs" : "jsm" }:`; var skipRe = /\nopenMultipleLinksInTabs@|\/historySidebar.xhtml:/; var treeRe = /@chrome:\/\/browser\/content\/places\/(places|bookmarksSidebar)\.xhtml:/; var timestamp = 0, activate = 0, placesNode; addEventListener("activate", () => activate = Cu.now()); addEventListener("DOMMenuItemActive", e => placesNode = e.target._placesNode); var check = url => { for(var win of BrowserWindowTracker.orderedWindows) if (win.toolbar.visible) for(var tab of (win.gBrowser?.tabs || [])) if (tab.linkedBrowser?.currentURI?.spec == url) return win.focus(), win.gBrowser.selectedTab = tab; } var sels = [ "menuitem[_moz-menuactive]", "#panelMenu_bookmarksMenu > toolbarbutton:is(:active,:focus)", "toolbarbutton.bookmark-item:is(:hover,:-moz-focusring)" ]; addEventListener("TabBrowserInserted", e => { if (timestamp - (timestamp = Cu.now()) > -100) return; var stack = Components.stack.formattedStack; if (!stack.includes(puu) || skipRe.test(stack)) return; if (treeRe.test(stack)) { var win; if (RegExp.$1.startsWith("p") && timestamp - activate < 500) win = Services.wm.getMostRecentWindow("Places:Organizer"); var view = (win || window).document.commandDispatcher.focusedElement?.view; if (view) var node = view.nodeForTreeIndex(view.selection.currentIndex); } else { for(var node of sels) if (node = document.querySelector(node)) break; node = node?._placesNode || popup._view?.selectedNode || placesNode; } if (node && PlacesUtils.nodeIsBookmark(node) && check(node.uri)) { var tab = e.target, br = tab.linkedBrowser; br.fixupAndLoadURIString = () => { delete br.fixupAndLoadURIString; gBrowser.removeTab(tab); } } }, true, gBrowser.tabContainer); })(document.getElementById("placesContext"));
Отсутствует
Stkvsky
А вот это, наоборот.
Удаление закладки — вещь глобальная, лучше в этот добавлять.
Сначала, дописываем CustomizableUI
/* var {PlacesUtils: pu, ContextualIdentityService: cis, PlacesUIUtils, PrivateBrowsingUtils} = Services.wm.getMostRecentBrowserWindow(); */ var { PlacesUtils: pu, ContextualIdentityService: cis, PlacesUIUtils, PrivateBrowsingUtils, CustomizableUI } = Services.wm.getMostRecentBrowserWindow();
// else if (e.itemType == bm.TYPE_BOOKMARK && e.type[9] == "r") { var {url} = e; for(var win of CustomizableUI.windows) { var tabs = [], gb = win.gBrowser; for(var br of gb.browsers) br.currentURI?.spec == url && tabs.push(gb.getTabForBrowser(br)); var len = tabs.length; if (len) len == 1 ? gb.removeTab(tabs[0]) : gb.removeTabs(tabs); } }
Отсутствует
Можно "приколотить" закрепленную вкладку?
Надо, чтобы ссылки с неё по клику ЛКМ, а также из адресной строки открывались в новой активной вкладке.
И заблокировать закрытие вкладки кликом СКМ по табу.
Отсутствует
Есть ли возможность
Весьма призрачная. Файло выпилили в Firefox 77.
Может что-то такое сойдёт
try {var args = {filterString: gBrowser.currentURI.host};} catch {}
LoginHelper.openPasswordManager(window, args);
Отсутствует