diff --git a/locales/en-US/browser/browser/zen-space-routing.ftl b/locales/en-US/browser/browser/zen-space-routing.ftl index a960e8895..4c070b968 100644 --- a/locales/en-US/browser/browser/zen-space-routing.ftl +++ b/locales/en-US/browser/browser/zen-space-routing.ftl @@ -25,3 +25,9 @@ zen-space-routing-open-in = Open In zen-space-routing-url = URL zen-space-routing-tab-routed-toast = New tab opened in { $targetWorkspace } +tab-context-zen-add-domain-to-sr = + .label = + { $tabCount -> + [one] Add Route for Domain + *[other] Add Route for Domains + } diff --git a/src/zen/ZenComponents.manifest b/src/zen/ZenComponents.manifest index 5cfcfd855..db0c69a49 100644 --- a/src/zen/ZenComponents.manifest +++ b/src/zen/ZenComponents.manifest @@ -16,3 +16,4 @@ category app-startup nsBrowserGlue @mozilla.org/browser/browserglue;1 applicatio #include common/Components.manifest #include sessionstore/SessionComponents.manifest #include live-folders/LiveFoldersComponents.manifest +#include space-routing/SpaceRoutingComponents.manifest diff --git a/src/zen/space-routing/SpaceRoutingComponents.manifest b/src/zen/space-routing/SpaceRoutingComponents.manifest new file mode 100644 index 000000000..d6a8c71a0 --- /dev/null +++ b/src/zen/space-routing/SpaceRoutingComponents.manifest @@ -0,0 +1,5 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +category browser-window-delayed-startup resource:///modules/zen/spacerouting/ZenSpaceRoutingManager.sys.mjs gZenSpaceRoutingManager.onDelayedBrowserStartup \ No newline at end of file diff --git a/src/zen/space-routing/ZenSpaceRoutingManager.sys.mjs b/src/zen/space-routing/ZenSpaceRoutingManager.sys.mjs index d2025d618..b7b40387f 100644 --- a/src/zen/space-routing/ZenSpaceRoutingManager.sys.mjs +++ b/src/zen/space-routing/ZenSpaceRoutingManager.sys.mjs @@ -18,6 +18,58 @@ class nsZenSpaceRoutingManager { this.#readFromDisk(); } + /** + * Auto invoked for every window on delayed startup + * + * @param {nsIDOMWindow} window - The browser window that just started up + */ + onDelayedBrowserStartup(window) { + const element = window.MozXULElement.parseXULToFragment(` + + + `); + window.document.getElementById("context_undoCloseTab").after(element); + + window.document + .getElementById("context_zen-add-domain-to-routing") + .addEventListener("command", this.#onAddSelectedToRouting.bind(this)); + window.document + .getElementById("tabContextMenu") + .addEventListener( + "popupshowing", + this.#updateTabCloseCountState.bind(this) + ); + } + + /** + * Updates the "context_zen-add-domain-to-routing" command + * to reflect the number of selected tabs, when applicable. + * + * @param {Event} event - The event param + */ + #updateTabCloseCountState(event) { + const window = event.target.documentGlobal; + window.document.l10n.setArgs( + window.document.getElementById("context_zen-add-domain-to-routing"), + { tabCount: window.gBrowser.selectedTabs.length } + ); + } + + /** + * Callback for whenever the menuitem command is ran + * + * @param {Event} event - The event parameter + */ + #onAddSelectedToRouting(event) { + const window = event.target.documentGlobal; + const tabs = window.TabContextMenu.contextTab.multiselected + ? window.gBrowser.selectedTabs + : [window.TabContextMenu.contextTab]; + this.addRouteForSelected(tabs, window); + } + /** * Callback that will be executed from tabbrowser.js * This method can be used to stop the tab from being created. @@ -403,6 +455,37 @@ class nsZenSpaceRoutingManager { this.#file.data.defaultRouteExternal = routeType; } + /** + * Adds a new route for all given tabs + * + * @param {Array} selectedTabs - The tabs that should be routed + * @param {Window} parentWindow - The window from which this is being executed + */ + addRouteForSelected(selectedTabs, parentWindow) { + const newRoute = this.createNewRoute(); + let routeReference = ""; + + if (selectedTabs.length == 1) { + newRoute.matchType = "contains"; + routeReference = selectedTabs[0].linkedBrowser.currentURI.host; + } else { + newRoute.matchType = "regex"; + routeReference = "("; + for (let i = 0; i < selectedTabs.length; i++) { + const domain = selectedTabs[i].linkedBrowser.currentURI.host; + routeReference += domain.replaceAll(".", "\."); + if (i != selectedTabs.length - 1) { + routeReference += "|"; + } + } + routeReference += ")"; + } + + newRoute.reference = routeReference; + this.updateRoute(newRoute); + this.openSpaceRoutingDialog(parentWindow); + } + /** * Saves all routes. The list of * routes is stripped of empty routes