mirror of
https://github.com/zen-browser/desktop.git
synced 2026-05-25 06:18:34 +00:00
no-bug: Add space button
This commit is contained in:
@@ -151,3 +151,5 @@ zen-window-sync-migration-dialog-accept = Got It
|
||||
zen-appmenu-new-blank-window =
|
||||
.label = New blank window
|
||||
|
||||
zen-spaces-search-placeholder =
|
||||
.placeholder = Search your spaces...
|
||||
|
||||
23
src/browser/base/content/zen-panels/spaces-search.inc
Normal file
23
src/browser/base/content/zen-panels/spaces-search.inc
Normal file
@@ -0,0 +1,23 @@
|
||||
# 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/.
|
||||
|
||||
<panel id="zen-spaces-popup"
|
||||
nonnativepopover="true"
|
||||
type="arrow"
|
||||
orient="vertical"
|
||||
side="bottom"
|
||||
hidden="true"
|
||||
consumeoutsideclicks="never">
|
||||
<hbox class="zen-spaces-list-header" flex="1">
|
||||
<image class="zen-spaces-list-search-icon" src="chrome://global/skin/icons/search-glass.svg"/>
|
||||
<html:input id="zen-spaces-list-search"
|
||||
data-l10n-id="zen-spaces-search-placeholder"
|
||||
type="search" />
|
||||
</hbox>
|
||||
<scrollbox class="zen-spaces-list-scrollbox" flex="1">
|
||||
<vbox id="zen-spaces-list"></vbox>
|
||||
<hbox id="zen-spaces-search-no-results" hidden="true" flex="1"
|
||||
data-l10n-id="zen-spaces-search-no-results" />
|
||||
</scrollbox>
|
||||
</panel>
|
||||
@@ -5,6 +5,7 @@
|
||||
#include zen-panels/theme-picker.inc
|
||||
#include zen-panels/emojis-picker.inc
|
||||
#include zen-panels/folders-search.inc
|
||||
#include zen-panels/spaces-search.inc
|
||||
#include zen-panels/site-data.inc
|
||||
|
||||
#include zen-panels/popups.inc
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
EXTRA_JS_MODULES += [
|
||||
"sys/ZenActorsManager.sys.mjs",
|
||||
"sys/ZenCustomizableUI.sys.mjs",
|
||||
"sys/ZenSearchPopup.sys.mjs",
|
||||
"sys/ZenUIMigration.sys.mjs",
|
||||
]
|
||||
|
||||
|
||||
152
src/zen/common/sys/ZenSearchPopup.sys.mjs
Normal file
152
src/zen/common/sys/ZenSearchPopup.sys.mjs
Normal file
@@ -0,0 +1,152 @@
|
||||
/* 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/. */
|
||||
|
||||
/*
|
||||
* Generic searchable XUL <panel> driver. One instance owns one panel +
|
||||
* its search input + list + (optional) no-results element, and exposes
|
||||
* `populate(items)` and `open(anchor, options)`.
|
||||
*
|
||||
* Each item passed to `populate` is `{ label, render?, onPick }`:
|
||||
* - label: string used for the data-label search filter.
|
||||
* - render: optional () => Element factory. If omitted a bare hbox
|
||||
* with a <label> is created.
|
||||
* - onPick: callback invoked when the item is clicked or activated
|
||||
* via Enter on the keyboard.
|
||||
*
|
||||
* The driver handles:
|
||||
* - filtering by lowercased substring match against data-label;
|
||||
* - arrow-key / Tab navigation with [selected="true"] highlight;
|
||||
* - Enter to activate the highlighted item;
|
||||
* - autofocus of the search input on popupshown;
|
||||
* - cleanup of all listeners on popuphidden.
|
||||
*/
|
||||
export class ZenSearchPopup {
|
||||
#panel = null;
|
||||
#searchInput = null;
|
||||
#list = null;
|
||||
#noResults = null;
|
||||
#itemSelector = ".zen-search-popup-item";
|
||||
#items = [];
|
||||
|
||||
/**
|
||||
* @param {object} aOptions
|
||||
* @param {Element} aOptions.panel The <panel> XUL element.
|
||||
* @param {Element} aOptions.searchInput The search <html:input>.
|
||||
* @param {Element} aOptions.list The container holding items.
|
||||
* @param {Element} [aOptions.noResults] Optional "no results" element.
|
||||
* @param {string} [aOptions.itemSelector] Per-item selector. Default
|
||||
* is `.zen-search-popup-item`; custom items must carry that class
|
||||
* or override this option.
|
||||
*/
|
||||
constructor({ panel, searchInput, list, noResults, itemSelector }) {
|
||||
this.#panel = panel;
|
||||
this.#searchInput = searchInput;
|
||||
this.#list = list;
|
||||
this.#noResults = noResults;
|
||||
if (itemSelector) this.#itemSelector = itemSelector;
|
||||
}
|
||||
|
||||
populate(items) {
|
||||
this.#items = items;
|
||||
this.#list.innerHTML = "";
|
||||
const doc = this.#panel.ownerDocument;
|
||||
for (const item of items) {
|
||||
let node;
|
||||
if (typeof item.render === "function") {
|
||||
node = item.render();
|
||||
} else {
|
||||
node = doc.createXULElement("hbox");
|
||||
const label = doc.createXULElement("label");
|
||||
label.setAttribute("value", item.label);
|
||||
node.appendChild(label);
|
||||
}
|
||||
node.classList.add(this.#itemSelector.replace(/^\./, ""));
|
||||
node.setAttribute("data-label", item.label);
|
||||
node.addEventListener("click", () => {
|
||||
this.#panel.hidePopup();
|
||||
item.onPick?.(item);
|
||||
});
|
||||
this.#list.appendChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
open(anchor, { position = "after_end", onShown, onHidden } = {}) {
|
||||
if (!this.#panel || !this.#list) return;
|
||||
|
||||
this.#panel.hidden = false;
|
||||
|
||||
if (this.#searchInput) this.#searchInput.value = "";
|
||||
if (this.#noResults) this.#noResults.hidden = true;
|
||||
|
||||
const doc = this.#panel.ownerDocument;
|
||||
const sel = this.#itemSelector;
|
||||
|
||||
const onSearch = () => {
|
||||
const query = (this.#searchInput?.value || "").toLowerCase();
|
||||
let visible = 0;
|
||||
for (const item of this.#list.querySelectorAll(sel)) {
|
||||
const label = item.getAttribute("data-label")?.toLowerCase() || "";
|
||||
const found = label.includes(query);
|
||||
item.hidden = !found;
|
||||
if (found) visible++;
|
||||
}
|
||||
if (this.#noResults) this.#noResults.hidden = visible > 0;
|
||||
};
|
||||
if (this.#searchInput) {
|
||||
this.#searchInput.addEventListener("input", onSearch);
|
||||
}
|
||||
|
||||
const onKeyDown = event => {
|
||||
if (
|
||||
event.key === "ArrowDown" ||
|
||||
event.key === "ArrowUp" ||
|
||||
event.key === "Tab"
|
||||
) {
|
||||
event.preventDefault();
|
||||
const isUp =
|
||||
event.key === "ArrowUp" || (event.key === "Tab" && event.shiftKey);
|
||||
const items = Array.from(this.#list.querySelectorAll(sel)).filter(
|
||||
it => !it.hidden
|
||||
);
|
||||
if (!items.length) return;
|
||||
let index = items.indexOf(
|
||||
this.#list.querySelector(`${sel}[selected="true"]`)
|
||||
);
|
||||
index = isUp
|
||||
? (index - 1 + items.length) % items.length
|
||||
: (index + 1) % items.length;
|
||||
items.forEach(it => it.removeAttribute("selected"));
|
||||
const target = items[index];
|
||||
target.setAttribute("selected", "true");
|
||||
target.scrollIntoView({ block: "nearest", behavior: "smooth" });
|
||||
} else if (event.key === "Enter") {
|
||||
const sel2 = this.#list.querySelector(`${sel}[selected="true"]`);
|
||||
if (sel2) sel2.click();
|
||||
}
|
||||
};
|
||||
doc.addEventListener("keydown", onKeyDown);
|
||||
|
||||
const onPanelShown = event => {
|
||||
if (event.target !== this.#panel) return;
|
||||
this.#searchInput?.focus();
|
||||
this.#searchInput?.select?.();
|
||||
onShown?.();
|
||||
};
|
||||
this.#panel.addEventListener("popupshown", onPanelShown);
|
||||
|
||||
const onPanelHidden = event => {
|
||||
if (event.target !== this.#panel) return;
|
||||
if (this.#searchInput) {
|
||||
this.#searchInput.removeEventListener("input", onSearch);
|
||||
}
|
||||
doc.removeEventListener("keydown", onKeyDown);
|
||||
this.#panel.removeEventListener("popupshown", onPanelShown);
|
||||
this.#panel.removeEventListener("popuphidden", onPanelHidden);
|
||||
onHidden?.();
|
||||
};
|
||||
this.#panel.addEventListener("popuphidden", onPanelHidden);
|
||||
|
||||
this.#panel.openPopup(anchor, position);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import { nsZenDOMOperatedFeature } from "chrome://browser/content/zen-components/ZenCommonUtils.mjs";
|
||||
import { ZenSearchPopup } from "resource:///modules/ZenSearchPopup.sys.mjs";
|
||||
|
||||
function formatRelativeTime(timestamp) {
|
||||
const now = Date.now();
|
||||
@@ -42,6 +43,7 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
);
|
||||
|
||||
#popup = null;
|
||||
#searchPopup = null;
|
||||
#popupTimer = null;
|
||||
#mouseTimer = null;
|
||||
#lastHighlightedGroup = null;
|
||||
@@ -188,15 +190,12 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
|
||||
#initTabsPopup() {
|
||||
this.#popup = document.getElementById("zen-folder-tabs-popup");
|
||||
|
||||
const search = this.#popup.querySelector("#zen-folder-tabs-list-search");
|
||||
const tabsList = this.#popup.querySelector("#zen-folder-tabs-list");
|
||||
|
||||
search.addEventListener("input", () => {
|
||||
const query = search.value.toLowerCase();
|
||||
for (const item of tabsList.children) {
|
||||
item.hidden = !item.getAttribute("data-label").includes(query);
|
||||
}
|
||||
this.#searchPopup = new ZenSearchPopup({
|
||||
panel: this.#popup,
|
||||
searchInput: this.#popup.querySelector("#zen-folder-tabs-list-search"),
|
||||
list: this.#popup.querySelector("#zen-folder-tabs-list"),
|
||||
noResults: document.getElementById("zen-folder-tabs-search-no-results"),
|
||||
itemSelector: ".folders-tabs-list-item",
|
||||
});
|
||||
|
||||
this.#popup.addEventListener("mouseover", () => {
|
||||
@@ -788,93 +787,18 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
document.getElementById("zen-folder-tabs-search-no-results").hidden = true;
|
||||
this.#populateTabsList(activeGroup);
|
||||
|
||||
const search = this.#popup.querySelector("#zen-folder-tabs-list-search");
|
||||
document.l10n.setArgs(search, {
|
||||
"folder-name": activeGroup.name,
|
||||
});
|
||||
const tabsList = this.#popup.querySelector("#zen-folder-tabs-list");
|
||||
|
||||
const onSearchInput = () => {
|
||||
const query = search.value.toLowerCase();
|
||||
let foundTabs = 0;
|
||||
for (const item of tabsList.children) {
|
||||
const found = item.getAttribute("data-label").includes(query);
|
||||
item.hidden = !found;
|
||||
if (found) {
|
||||
foundTabs++;
|
||||
}
|
||||
}
|
||||
document.getElementById("zen-folder-tabs-search-no-results").hidden =
|
||||
foundTabs > 0;
|
||||
};
|
||||
search.addEventListener("input", onSearchInput);
|
||||
|
||||
const onKeyDown = event => {
|
||||
// Arrow down and up to navigate through the list
|
||||
if (
|
||||
event.key === "ArrowDown" ||
|
||||
event.key === "ArrowUp" ||
|
||||
event.key === "Tab"
|
||||
) {
|
||||
event.preventDefault();
|
||||
let isUp =
|
||||
event.key === "ArrowUp" || (event.key === "Tab" && event.shiftKey);
|
||||
const items = Array.from(tabsList.children).filter(
|
||||
item => !item.hidden
|
||||
);
|
||||
if (items.length === 0) {
|
||||
return;
|
||||
}
|
||||
let index = items.indexOf(
|
||||
tabsList.querySelector(".folders-tabs-list-item[selected]")
|
||||
);
|
||||
if (!isUp) {
|
||||
index = (index + 1) % items.length;
|
||||
} else {
|
||||
index = (index - 1 + items.length) % items.length;
|
||||
}
|
||||
items.forEach(item => item.removeAttribute("selected"));
|
||||
const targetItem = items[index];
|
||||
targetItem.setAttribute("selected", "true");
|
||||
targetItem.scrollIntoView({ block: "start", behavior: "smooth" });
|
||||
} else if (event.key === "Enter") {
|
||||
// Enter to select the currently highlighted item
|
||||
const highlightedItem = tabsList.querySelector(
|
||||
".folders-tabs-list-item[selected]"
|
||||
);
|
||||
if (highlightedItem) {
|
||||
highlightedItem.click();
|
||||
}
|
||||
}
|
||||
};
|
||||
document.addEventListener("keydown", onKeyDown);
|
||||
document.l10n.setArgs(
|
||||
this.#popup.querySelector("#zen-folder-tabs-list-search"),
|
||||
{ "folder-name": activeGroup.name }
|
||||
);
|
||||
|
||||
const target = event.target;
|
||||
target.setAttribute("open", true);
|
||||
|
||||
const handlePopupHidden = event => {
|
||||
if (event.target !== this.#popup) {
|
||||
return;
|
||||
}
|
||||
search.value = "";
|
||||
target.removeAttribute("open");
|
||||
search.removeEventListener("input", onSearchInput);
|
||||
document.removeEventListener("keydown", onKeyDown);
|
||||
};
|
||||
|
||||
this.#popup.addEventListener(
|
||||
"popupshown",
|
||||
() => {
|
||||
search.focus();
|
||||
search.select();
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
|
||||
this.#popup.addEventListener("popuphidden", handlePopupHidden, {
|
||||
once: true,
|
||||
this.#searchPopup.open(target, {
|
||||
position: this.#searchPopupOptions,
|
||||
onHidden: () => target.removeAttribute("open"),
|
||||
});
|
||||
this.#popup.openPopup(target, this.#searchPopupOptions);
|
||||
}
|
||||
|
||||
get #searchPopupOptions() {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
|
||||
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
|
||||
import { ZenSpacesSearch } from "resource:///modules/zen/ZenSpacesSearch.sys.mjs";
|
||||
|
||||
const lazy = {};
|
||||
|
||||
@@ -77,6 +78,7 @@ class nsZenLittleWindow {
|
||||
if (!this.#isLittleWindow(win)) {
|
||||
return;
|
||||
}
|
||||
ZenSpacesSearch.init(win);
|
||||
const observer = new win.ResizeObserver(entries => {
|
||||
if (win.closed) {
|
||||
return;
|
||||
|
||||
142
src/zen/little-window/ZenSpacesSearch.sys.mjs
Normal file
142
src/zen/little-window/ZenSpacesSearch.sys.mjs
Normal file
@@ -0,0 +1,142 @@
|
||||
/* 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/. */
|
||||
|
||||
import { ZenSearchPopup } from "resource:///modules/ZenSearchPopup.sys.mjs";
|
||||
|
||||
const lazy = {};
|
||||
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
ZenSessionStore: "resource:///modules/zen/ZenSessionManager.sys.mjs",
|
||||
});
|
||||
|
||||
/*
|
||||
* Owns the "send to a synced window" split-button that lives in the
|
||||
* nav-bar of a little window. Main click opens the urlbar's current
|
||||
* value in a fresh synced browser window using the active workspace;
|
||||
* the dropdown opens a ZenSearchPopup over #zen-spaces-popup so the
|
||||
* user can pick a different workspace to land in.
|
||||
*/
|
||||
class ZenSpacesSearchService {
|
||||
/**
|
||||
* Per-window setup.
|
||||
* @param {Window} aWindow A little window.
|
||||
*/
|
||||
init(aWindow) {
|
||||
if (!aWindow || aWindow._zenSpacesSearchInited) return;
|
||||
aWindow._zenSpacesSearchInited = true;
|
||||
|
||||
const doc = aWindow.document;
|
||||
const panel = doc.getElementById("zen-spaces-popup");
|
||||
if (!panel) return;
|
||||
|
||||
const popup = new ZenSearchPopup({
|
||||
panel,
|
||||
searchInput: doc.getElementById("zen-spaces-list-search"),
|
||||
list: doc.getElementById("zen-spaces-list"),
|
||||
noResults: doc.getElementById("zen-spaces-search-no-results"),
|
||||
itemSelector: ".zen-spaces-list-item",
|
||||
});
|
||||
|
||||
const parts = this.#injectButton(aWindow);
|
||||
if (!parts) return;
|
||||
const { button, main, dropmarker } = parts;
|
||||
|
||||
main.addEventListener("click", event => {
|
||||
if (event.button !== 0) return;
|
||||
this.#openInWorkspace(aWindow, null);
|
||||
});
|
||||
|
||||
dropmarker.addEventListener("click", event => {
|
||||
if (event.button !== 0) return;
|
||||
event.stopPropagation();
|
||||
this.#openSpacesPopup(aWindow, popup, button);
|
||||
});
|
||||
}
|
||||
|
||||
#injectButton(aWindow) {
|
||||
const doc = aWindow.document;
|
||||
const target = doc.getElementById("nav-bar-customization-target");
|
||||
if (!target) return null;
|
||||
|
||||
const button = doc.createXULElement("hbox");
|
||||
button.id = "zen-little-window-send-to-window";
|
||||
button.setAttribute("removable", "false");
|
||||
|
||||
const main = doc.createXULElement("hbox");
|
||||
main.classList.add("zen-stw-main");
|
||||
|
||||
const prefix = doc.createXULElement("label");
|
||||
prefix.classList.add("zen-stw-prefix");
|
||||
prefix.setAttribute(
|
||||
"data-l10n-id",
|
||||
"zen-little-window-send-to-window-prefix"
|
||||
);
|
||||
|
||||
const spaceName = doc.createXULElement("label");
|
||||
spaceName.classList.add("zen-stw-space-name");
|
||||
spaceName.setAttribute(
|
||||
"value",
|
||||
aWindow.gZenWorkspaces?.getActiveWorkspaceFromCache?.()?.name || ""
|
||||
);
|
||||
|
||||
main.appendChild(prefix);
|
||||
main.appendChild(spaceName);
|
||||
|
||||
const separator = doc.createXULElement("hbox");
|
||||
separator.classList.add("zen-stw-separator");
|
||||
|
||||
const dropmarker = doc.createXULElement("hbox");
|
||||
dropmarker.classList.add("zen-stw-dropmarker");
|
||||
const dropIcon = doc.createXULElement("image");
|
||||
dropIcon.classList.add("zen-stw-dropmarker-icon");
|
||||
dropmarker.appendChild(dropIcon);
|
||||
|
||||
button.appendChild(main);
|
||||
button.appendChild(separator);
|
||||
button.appendChild(dropmarker);
|
||||
|
||||
target.appendChild(button);
|
||||
return { button, main, dropmarker, spaceName };
|
||||
}
|
||||
|
||||
#openSpacesPopup(aWindow, popup, anchor) {
|
||||
const workspaces = lazy.ZenSessionStore.getClonedSpaces();
|
||||
|
||||
popup.populate(
|
||||
workspaces.map(space => ({
|
||||
label: space.name || space.uuid,
|
||||
render: () => {
|
||||
const node = aWindow.document.createXULElement("hbox");
|
||||
const label = aWindow.document.createXULElement("label");
|
||||
label.setAttribute("value", space.name || space.uuid);
|
||||
label.classList.add("zen-spaces-list-item-label");
|
||||
node.appendChild(label);
|
||||
return node;
|
||||
},
|
||||
onPick: () => this.#openInWorkspace(aWindow, space.uuid),
|
||||
}))
|
||||
);
|
||||
popup.open(anchor);
|
||||
}
|
||||
|
||||
#openInWorkspace(aWindow, workspaceUuid) {
|
||||
const url = aWindow.gURLBar?.value?.trim();
|
||||
if (!url) return;
|
||||
|
||||
const args = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
|
||||
const urlString = Cc["@mozilla.org/supports-string;1"].createInstance(
|
||||
Ci.nsISupportsString
|
||||
);
|
||||
urlString.data = url;
|
||||
args.appendElement(urlString);
|
||||
|
||||
const opts = { args, zenSyncedWindow: true };
|
||||
if (workspaceUuid) opts.zenInitialWorkspace = workspaceUuid;
|
||||
|
||||
const newWin = aWindow.OpenBrowserWindow(opts);
|
||||
if (newWin) aWindow.close();
|
||||
}
|
||||
}
|
||||
|
||||
export const ZenSpacesSearch = new ZenSpacesSearchService();
|
||||
@@ -4,4 +4,5 @@
|
||||
|
||||
EXTRA_JS_MODULES.zen += [
|
||||
"ZenLittleWindow.sys.mjs",
|
||||
"ZenSpacesSearch.sys.mjs",
|
||||
]
|
||||
|
||||
@@ -8,10 +8,115 @@
|
||||
* suppressed so the window acts as a quick search/launch box.
|
||||
*/
|
||||
|
||||
:root[zen-little-window="true"] {
|
||||
#zen-little-window-send-to-window {
|
||||
align-items: stretch;
|
||||
border-radius: var(--border-radius-small);
|
||||
background: light-dark(white, rgba(0, 0, 0, 0.4));
|
||||
height: 32px;
|
||||
margin-inline: 4px;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
align-self: center;
|
||||
box-shadow: 0 0 1px 2px rgba(0, 0, 0, 0.01);
|
||||
|
||||
#urlbar {
|
||||
width: 100%;
|
||||
.zen-stw-main,
|
||||
.zen-stw-dropmarker {
|
||||
align-items: center;
|
||||
padding-inline: 12px;
|
||||
transition: background 80ms ease;
|
||||
|
||||
&:hover {
|
||||
background: var(--toolbarbutton-active-background, color-mix(in srgb, currentColor 12%, transparent));
|
||||
}
|
||||
}
|
||||
|
||||
.zen-stw-prefix {
|
||||
color: color-mix(in srgb, currentColor 60%, transparent);
|
||||
margin-inline-end: 6px;
|
||||
}
|
||||
|
||||
.zen-stw-space-name {
|
||||
color: var(--zen-primary-color, currentColor);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.zen-stw-separator {
|
||||
width: 1px;
|
||||
background: color-mix(in srgb, currentColor 18%, transparent);
|
||||
margin-block: 6px;
|
||||
}
|
||||
|
||||
.zen-stw-dropmarker {
|
||||
padding-inline: 8px;
|
||||
}
|
||||
|
||||
.zen-stw-dropmarker-icon {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
-moz-context-properties: fill;
|
||||
fill: color-mix(in srgb, currentColor 65%, transparent);
|
||||
list-style-image: url("chrome://global/skin/icons/arrow-down.svg");
|
||||
}
|
||||
}
|
||||
|
||||
#zen-spaces-popup {
|
||||
--arrowpanel-padding: 0;
|
||||
--zen-spaces-list-padding: 6px;
|
||||
padding: var(--zen-spaces-list-padding);
|
||||
min-width: 250px;
|
||||
|
||||
.zen-spaces-list-header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 6px;
|
||||
border-bottom: 1px solid color-mix(in srgb, currentColor, transparent 90%);
|
||||
}
|
||||
|
||||
.zen-spaces-list-search-icon {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin-inline: 4px 6px;
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
#zen-spaces-list-search {
|
||||
flex: 1;
|
||||
background: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
.zen-spaces-list-item {
|
||||
padding: 6px 10px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover,
|
||||
&[selected="true"] {
|
||||
background: var(--toolbarbutton-hover-background);
|
||||
}
|
||||
&[active="true"]::after {
|
||||
content: "•";
|
||||
margin-inline-start: auto;
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
#zen-spaces-search-no-results {
|
||||
padding: 12px;
|
||||
opacity: 0.7;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
:root[zen-little-window="true"] {
|
||||
toolbarspring[cui-areatype="toolbar"],
|
||||
#nav-bar-customization-target > .toolbarbutton-1[disabled="true"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&[zen-has-empty-tab="true"] {
|
||||
@@ -24,7 +129,8 @@
|
||||
}
|
||||
|
||||
#urlbar[breakout-extend] {
|
||||
min-width: 100% !important;
|
||||
min-width: 600px !important;
|
||||
max-width: 600px !important;
|
||||
left: 50% !important;
|
||||
top: 0 !important;
|
||||
transform: translate(10px, 0) !important;
|
||||
@@ -43,4 +149,14 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (-moz-platform: macos) {
|
||||
#nav-bar {
|
||||
padding-inline-start: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
#urlbar-container {
|
||||
--border-radius-medium: var(--border-radius-small);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user