mirror of
https://github.com/zen-browser/desktop.git
synced 2025-10-14 13:56:11 +00:00
no-bug - Improved initial startup performance and loading speeds, c=common, tabs, workspaces, t=perf
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
diff --git a/browser/base/content/browser-init.js b/browser/base/content/browser-init.js
|
diff --git a/browser/base/content/browser-init.js b/browser/base/content/browser-init.js
|
||||||
index 3d5173315812589c0b79beec5f0419fc37cb8868..c4216db9e414fbbaead6ecd89b40366b0d8a50c1 100644
|
index bcbfab4a3781ff3c7349115751b3830976eec4bf..1ab08a9344b16cbe791182fce3f6fbf59ca3df91 100644
|
||||||
--- a/browser/base/content/browser-init.js
|
--- a/browser/base/content/browser-init.js
|
||||||
+++ b/browser/base/content/browser-init.js
|
+++ b/browser/base/content/browser-init.js
|
||||||
@@ -175,6 +175,8 @@ var gBrowserInit = {
|
@@ -186,6 +186,8 @@ var gBrowserInit = {
|
||||||
},
|
},
|
||||||
|
|
||||||
onLoad() {
|
onLoad() {
|
||||||
@@ -11,11 +11,3 @@ index 3d5173315812589c0b79beec5f0419fc37cb8868..c4216db9e414fbbaead6ecd89b40366b
|
|||||||
gBrowser.addEventListener("DOMUpdateBlockedPopups", e =>
|
gBrowser.addEventListener("DOMUpdateBlockedPopups", e =>
|
||||||
PopupBlockerObserver.handleEvent(e)
|
PopupBlockerObserver.handleEvent(e)
|
||||||
);
|
);
|
||||||
@@ -310,6 +312,7 @@ var gBrowserInit = {
|
|
||||||
TelemetryTimestamps.add("delayedStartupStarted");
|
|
||||||
|
|
||||||
this._cancelDelayedStartup();
|
|
||||||
+ gZenWorkspaces.afterLoadInit();
|
|
||||||
|
|
||||||
gBrowser.addEventListener(
|
|
||||||
"PermissionStateChange",
|
|
||||||
|
@@ -36,7 +36,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async #waitAndCleanup() {
|
async #waitAndCleanup() {
|
||||||
await SessionStore.promiseAllWindowsRestored;
|
|
||||||
await SessionStore.promiseInitialized;
|
await SessionStore.promiseInitialized;
|
||||||
this.#cleanup();
|
this.#cleanup();
|
||||||
}
|
}
|
||||||
|
@@ -65,23 +65,10 @@
|
|||||||
this.observer.addPinnedTabListener(this._onPinnedTabEvent.bind(this));
|
this.observer.addPinnedTabListener(this._onPinnedTabEvent.bind(this));
|
||||||
|
|
||||||
this._zenClickEventListener = this._onTabClick.bind(this);
|
this._zenClickEventListener = this._onTabClick.bind(this);
|
||||||
gZenWorkspaces.addChangeListeners(this.onWorkspaceChange.bind(this));
|
|
||||||
|
|
||||||
await ZenPinnedTabsStorage.promiseInitialized;
|
|
||||||
gZenWorkspaces._resolvePinnedInitialized();
|
gZenWorkspaces._resolvePinnedInitialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
async onWorkspaceChange(newWorkspace, onInit) {
|
|
||||||
if (!this.enabled || PrivateBrowsingUtils.isWindowPrivate(window)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onInit) {
|
|
||||||
await this._refreshPinnedTabs({ init: onInit });
|
|
||||||
this._hasFinishedLoading = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log(message) {
|
log(message) {
|
||||||
if (this._canLog) {
|
if (this._canLog) {
|
||||||
console.log(`[ZenPinnedTabManager] ${message}`);
|
console.log(`[ZenPinnedTabManager] ${message}`);
|
||||||
@@ -149,13 +136,19 @@
|
|||||||
return this._enabled && !gZenWorkspaces.privateWindowOrDisabled;
|
return this._enabled && !gZenWorkspaces.privateWindowOrDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _refreshPinnedTabs({ init = false } = {}) {
|
async refreshPinnedTabs({ init = false } = {}) {
|
||||||
|
await ZenPinnedTabsStorage.promiseInitialized;
|
||||||
await gZenWorkspaces.promiseSectionsInitialized;
|
await gZenWorkspaces.promiseSectionsInitialized;
|
||||||
await this._initializePinsCache();
|
await this._initializePinsCache();
|
||||||
await this._initializePinnedTabs(init);
|
(async () => {
|
||||||
if (init) {
|
// Execute in a separate task to avoid blocking the main thread
|
||||||
this._resolveInitializedPinnedCache();
|
await SessionStore.promiseAllWindowsRestored;
|
||||||
}
|
await gZenWorkspaces.promiseInitialized;
|
||||||
|
await this._initializePinnedTabs(init);
|
||||||
|
if (init) {
|
||||||
|
this._hasFinishedLoading = true;
|
||||||
|
}
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _initializePinsCache() {
|
async _initializePinsCache() {
|
||||||
@@ -439,7 +432,7 @@
|
|||||||
|
|
||||||
await this.savePin(pin);
|
await this.savePin(pin);
|
||||||
this.resetPinChangedUrl(tab);
|
this.resetPinChangedUrl(tab);
|
||||||
await this._refreshPinnedTabs();
|
await this.refreshPinnedTabs();
|
||||||
gZenUIManager.showToast('zen-pinned-tab-replaced');
|
gZenUIManager.showToast('zen-pinned-tab-replaced');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -482,7 +475,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.onLocationChange(browser);
|
this.onLocationChange(browser);
|
||||||
await this._refreshPinnedTabs();
|
await this.refreshPinnedTabs();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _removePinnedAttributes(tab, isClosing = false) {
|
async _removePinnedAttributes(tab, isClosing = false) {
|
||||||
@@ -508,7 +501,7 @@
|
|||||||
tab.setAttribute('zen-workspace-id', workspace.uuid);
|
tab.setAttribute('zen-workspace-id', workspace.uuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await this._refreshPinnedTabs();
|
await this.refreshPinnedTabs();
|
||||||
tab.dispatchEvent(
|
tab.dispatchEvent(
|
||||||
new CustomEvent('ZenPinnedTabRemoved', {
|
new CustomEvent('ZenPinnedTabRemoved', {
|
||||||
detail: { tab },
|
detail: { tab },
|
||||||
@@ -958,7 +951,7 @@
|
|||||||
const uuid = tab.getAttribute('zen-pin-id');
|
const uuid = tab.getAttribute('zen-pin-id');
|
||||||
await ZenPinnedTabsStorage.updatePinTitle(uuid, newTitle, isEdited, notifyObservers);
|
await ZenPinnedTabsStorage.updatePinTitle(uuid, newTitle, isEdited, notifyObservers);
|
||||||
|
|
||||||
await this._refreshPinnedTabs();
|
await this.refreshPinnedTabs();
|
||||||
|
|
||||||
const browsers = Services.wm.getEnumerator('navigator:browser');
|
const browsers = Services.wm.getEnumerator('navigator:browser');
|
||||||
|
|
||||||
@@ -1110,8 +1103,4 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.gZenPinnedTabManager = new ZenPinnedTabManager();
|
window.gZenPinnedTabManager = new ZenPinnedTabManager();
|
||||||
|
|
||||||
gZenPinnedTabManager.promisePinnedCacheInitialized = new Promise((resolve) => {
|
|
||||||
gZenPinnedTabManager._resolveInitializedPinnedCache = resolve;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
@@ -46,11 +46,7 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||||||
if (this.privateWindowOrDisabled) {
|
if (this.privateWindowOrDisabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await Promise.all([
|
await Promise.all([this.promiseDBInitialized, this.promisePinnedInitialized]);
|
||||||
this.promiseDBInitialized,
|
|
||||||
this.promisePinnedInitialized,
|
|
||||||
SessionStore.promiseAllWindowsRestored,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
@@ -119,6 +115,8 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||||||
|
|
||||||
window.addEventListener('resize', this.onWindowResize.bind(this));
|
window.addEventListener('resize', this.onWindowResize.bind(this));
|
||||||
this.addPopupListeners();
|
this.addPopupListeners();
|
||||||
|
|
||||||
|
await this.afterLoadInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
log(...args) {
|
log(...args) {
|
||||||
@@ -128,14 +126,15 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async afterLoadInit() {
|
async afterLoadInit() {
|
||||||
await SessionStore.promiseInitialized;
|
|
||||||
if (!this._hasInitializedTabsStrip) {
|
if (!this._hasInitializedTabsStrip) {
|
||||||
await this.delayedStartup();
|
await this.delayedStartup();
|
||||||
}
|
}
|
||||||
await this.promiseSectionsInitialized;
|
|
||||||
this.log('gZenWorkspaces initialized');
|
|
||||||
|
|
||||||
await this.initializeWorkspaces();
|
await this.initializeWorkspaces();
|
||||||
|
await this.promiseSectionsInitialized;
|
||||||
|
|
||||||
|
// Non UI related initializations
|
||||||
|
this._initializeWorkspaceCreationIcons();
|
||||||
|
this._initializeWorkspaceTabContextMenus();
|
||||||
if (
|
if (
|
||||||
Services.prefs.getBoolPref('zen.workspaces.swipe-actions', false) &&
|
Services.prefs.getBoolPref('zen.workspaces.swipe-actions', false) &&
|
||||||
this.workspaceEnabled &&
|
this.workspaceEnabled &&
|
||||||
@@ -297,9 +296,6 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||||||
this._pinnedTabsResizeObserver = new ResizeObserver(this.onPinnedTabsResize.bind(this));
|
this._pinnedTabsResizeObserver = new ResizeObserver(this.onPinnedTabsResize.bind(this));
|
||||||
await this.waitForPromises();
|
await this.waitForPromises();
|
||||||
await this._createDefaultWorkspaceIfNeeded();
|
await this._createDefaultWorkspaceIfNeeded();
|
||||||
await this.initializeTabsStripSections();
|
|
||||||
this._resolveSectionsInitialized();
|
|
||||||
this._initializeEmptyTab();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _createDefaultWorkspaceIfNeeded() {
|
async _createDefaultWorkspaceIfNeeded() {
|
||||||
@@ -375,6 +371,7 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async initializeTabsStripSections() {
|
async initializeTabsStripSections() {
|
||||||
|
await SessionStore.promiseAllWindowsRestored;
|
||||||
const perifery = document.getElementById('tabbrowser-arrowscrollbox-periphery');
|
const perifery = document.getElementById('tabbrowser-arrowscrollbox-periphery');
|
||||||
perifery.setAttribute('hidden', 'true');
|
perifery.setAttribute('hidden', 'true');
|
||||||
const tabs = gBrowser.tabContainer.allTabs;
|
const tabs = gBrowser.tabContainer.allTabs;
|
||||||
@@ -409,6 +406,7 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||||||
this._hasInitializedTabsStrip = true;
|
this._hasInitializedTabsStrip = true;
|
||||||
this.registerPinnedResizeObserver();
|
this.registerPinnedResizeObserver();
|
||||||
this._fixIndicatorsNames(workspaces);
|
this._fixIndicatorsNames(workspaces);
|
||||||
|
this._resolveSectionsInitialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
getEssentialsSection(container = 0) {
|
getEssentialsSection(container = 0) {
|
||||||
@@ -836,40 +834,38 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async initializeWorkspaces() {
|
async initializeWorkspaces() {
|
||||||
if (this.workspaceEnabled) {
|
let activeWorkspace = await this.getActiveWorkspace();
|
||||||
this._initializeWorkspaceCreationIcons();
|
this.activeWorkspace = activeWorkspace?.uuid;
|
||||||
this._initializeWorkspaceTabContextMenus();
|
try {
|
||||||
await this.workspaceBookmarks();
|
if (activeWorkspace) {
|
||||||
window.addEventListener('TabBrowserInserted', this.onTabBrowserInserted.bind(this));
|
window.gZenThemePicker = new ZenThemePicker();
|
||||||
let activeWorkspace = await this.getActiveWorkspace();
|
await gZenThemePicker.onWorkspaceChange(activeWorkspace);
|
||||||
this.activeWorkspace = activeWorkspace?.uuid;
|
|
||||||
try {
|
|
||||||
if (activeWorkspace) {
|
|
||||||
window.gZenThemePicker = new ZenThemePicker();
|
|
||||||
await this.changeWorkspace(activeWorkspace, { onInit: true });
|
|
||||||
gBrowser.tabContainer._positionPinnedTabs();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error('gZenWorkspaces: Error initializing theme picker', e);
|
|
||||||
}
|
}
|
||||||
this.onWindowResize();
|
} catch (e) {
|
||||||
if (window.gZenSessionStore) {
|
console.error('gZenWorkspaces: Error initializing theme picker', e);
|
||||||
await gZenSessionStore.promiseInitialized;
|
|
||||||
}
|
|
||||||
await this._selectStartPage();
|
|
||||||
this._fixTabPositions();
|
|
||||||
this._resolveInitialized();
|
|
||||||
this._clearAnyZombieTabs(); // Dont call with await
|
|
||||||
|
|
||||||
const tabUpdateListener = this.updateTabsContainers.bind(this);
|
|
||||||
window.addEventListener('TabOpen', tabUpdateListener);
|
|
||||||
window.addEventListener('TabClose', tabUpdateListener);
|
|
||||||
window.addEventListener('TabAddedToEssentials', tabUpdateListener);
|
|
||||||
window.addEventListener('TabRemovedFromEssentials', tabUpdateListener);
|
|
||||||
window.addEventListener('TabPinned', tabUpdateListener);
|
|
||||||
window.addEventListener('TabUnpinned', tabUpdateListener);
|
|
||||||
window.addEventListener('aftercustomization', tabUpdateListener);
|
|
||||||
}
|
}
|
||||||
|
this.onWindowResize();
|
||||||
|
await gZenSessionStore.promiseInitialized;
|
||||||
|
await this.initializeTabsStripSections();
|
||||||
|
this._initializeEmptyTab();
|
||||||
|
await this.workspaceBookmarks();
|
||||||
|
await gZenPinnedTabManager.refreshPinnedTabs({ init: true });
|
||||||
|
await this.changeWorkspace(activeWorkspace, { onInit: true });
|
||||||
|
await this._selectStartPage();
|
||||||
|
this._fixTabPositions();
|
||||||
|
this._resolveInitialized();
|
||||||
|
this._clearAnyZombieTabs(); // Dont call with await
|
||||||
|
|
||||||
|
const tabUpdateListener = this.updateTabsContainers.bind(this);
|
||||||
|
window.addEventListener('TabOpen', tabUpdateListener);
|
||||||
|
window.addEventListener('TabClose', tabUpdateListener);
|
||||||
|
window.addEventListener('TabAddedToEssentials', tabUpdateListener);
|
||||||
|
window.addEventListener('TabRemovedFromEssentials', tabUpdateListener);
|
||||||
|
window.addEventListener('TabPinned', tabUpdateListener);
|
||||||
|
window.addEventListener('TabUnpinned', tabUpdateListener);
|
||||||
|
window.addEventListener('aftercustomization', tabUpdateListener);
|
||||||
|
|
||||||
|
window.addEventListener('TabBrowserInserted', this.onTabBrowserInserted.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
async _selectStartPage() {
|
async _selectStartPage() {
|
||||||
@@ -1412,129 +1408,118 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _propagateWorkspaceData({ ignoreStrip = false, clearCache = true } = {}) {
|
async _propagateWorkspaceDataForWindow(browser, { ignoreStrip = false, clearCache = true } = {}) {
|
||||||
const currentWindowIsPrivate = this.isPrivateWindow;
|
let workspaceList = browser.document.getElementById('PanelUI-zen-workspaces-list');
|
||||||
await this.foreachWindowAsActive(async (browser) => {
|
const createWorkspaceElement = (workspace) => {
|
||||||
// Do not update the window if workspaces are not enabled in it.
|
let element = browser.document.createXULElement('toolbarbutton');
|
||||||
// For example, when the window is in private browsing mode.
|
element.className = 'subviewbutton zen-workspace-button';
|
||||||
if (
|
element.setAttribute('tooltiptext', workspace.name);
|
||||||
!browser.gZenWorkspaces.workspaceEnabled ||
|
element.setAttribute('zen-workspace-id', workspace.uuid);
|
||||||
browser.gZenWorkspaces.isPrivateWindow !== currentWindowIsPrivate
|
if (this.isWorkspaceActive(workspace)) {
|
||||||
) {
|
element.setAttribute('active', 'true');
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
let containerGroup = undefined;
|
||||||
let workspaceList = browser.document.getElementById('PanelUI-zen-workspaces-list');
|
try {
|
||||||
const createWorkspaceElement = (workspace) => {
|
containerGroup = browser.ContextualIdentityService.getPublicIdentities().find(
|
||||||
let element = browser.document.createXULElement('toolbarbutton');
|
(container) => container.userContextId === workspace.containerTabId
|
||||||
element.className = 'subviewbutton zen-workspace-button';
|
|
||||||
element.setAttribute('tooltiptext', workspace.name);
|
|
||||||
element.setAttribute('zen-workspace-id', workspace.uuid);
|
|
||||||
if (this.isWorkspaceActive(workspace)) {
|
|
||||||
element.setAttribute('active', 'true');
|
|
||||||
}
|
|
||||||
let containerGroup = undefined;
|
|
||||||
try {
|
|
||||||
containerGroup = browser.ContextualIdentityService.getPublicIdentities().find(
|
|
||||||
(container) => container.userContextId === workspace.containerTabId
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('gZenWorkspaces: Error setting container color', e);
|
|
||||||
}
|
|
||||||
if (containerGroup) {
|
|
||||||
element.classList.add('identity-color-' + containerGroup.color);
|
|
||||||
element.setAttribute('data-usercontextid', containerGroup.userContextId);
|
|
||||||
}
|
|
||||||
// Set draggable attribute based on reorder mode
|
|
||||||
if (this.isReorderModeOn(browser)) {
|
|
||||||
element.setAttribute('draggable', 'true');
|
|
||||||
}
|
|
||||||
element.addEventListener(
|
|
||||||
'dragstart',
|
|
||||||
function (event) {
|
|
||||||
if (this.isReorderModeOn(browser)) {
|
|
||||||
this.draggedElement = element;
|
|
||||||
event.dataTransfer.effectAllowed = 'move';
|
|
||||||
event.dataTransfer.setData('text/plain', element.getAttribute('zen-workspace-id'));
|
|
||||||
|
|
||||||
// Create a transparent drag image for Linux
|
|
||||||
if (AppConstants.platform === 'linux') {
|
|
||||||
const dragImage = document.createElement('canvas');
|
|
||||||
dragImage.width = 1;
|
|
||||||
dragImage.height = 1;
|
|
||||||
event.dataTransfer.setDragImage(dragImage, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
element.classList.add('dragging');
|
|
||||||
} else {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
}.bind(browser.gZenWorkspaces)
|
|
||||||
);
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('gZenWorkspaces: Error setting container color', e);
|
||||||
|
}
|
||||||
|
if (containerGroup) {
|
||||||
|
element.classList.add('identity-color-' + containerGroup.color);
|
||||||
|
element.setAttribute('data-usercontextid', containerGroup.userContextId);
|
||||||
|
}
|
||||||
|
// Set draggable attribute based on reorder mode
|
||||||
|
if (this.isReorderModeOn(browser)) {
|
||||||
|
element.setAttribute('draggable', 'true');
|
||||||
|
}
|
||||||
|
element.addEventListener(
|
||||||
|
'dragstart',
|
||||||
|
function (event) {
|
||||||
|
if (this.isReorderModeOn(browser)) {
|
||||||
|
this.draggedElement = element;
|
||||||
|
event.dataTransfer.effectAllowed = 'move';
|
||||||
|
event.dataTransfer.setData('text/plain', element.getAttribute('zen-workspace-id'));
|
||||||
|
|
||||||
element.addEventListener(
|
// Create a transparent drag image for Linux
|
||||||
'dragover',
|
if (AppConstants.platform === 'linux') {
|
||||||
function (event) {
|
const dragImage = document.createElement('canvas');
|
||||||
if (this.isReorderModeOn(browser) && this.draggedElement) {
|
dragImage.width = 1;
|
||||||
event.preventDefault();
|
dragImage.height = 1;
|
||||||
event.dataTransfer.dropEffect = 'move';
|
event.dataTransfer.setDragImage(dragImage, 0, 0);
|
||||||
|
|
||||||
// Ensure the dragover effect is visible on Linux
|
|
||||||
if (AppConstants.platform === 'linux') {
|
|
||||||
const targetId = element.getAttribute('zen-workspace-id');
|
|
||||||
const draggedId = this.draggedElement.getAttribute('zen-workspace-id');
|
|
||||||
if (targetId !== draggedId) {
|
|
||||||
element.classList.add('dragover');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.bind(browser.gZenWorkspaces)
|
|
||||||
);
|
|
||||||
|
|
||||||
element.addEventListener('dragenter', function (event) {
|
element.classList.add('dragging');
|
||||||
if (this.isReorderModeOn(browser) && this.draggedElement) {
|
} else {
|
||||||
element.classList.add('dragover');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
element.addEventListener('dragleave', function (event) {
|
|
||||||
element.classList.remove('dragover');
|
|
||||||
});
|
|
||||||
|
|
||||||
element.addEventListener(
|
|
||||||
'drop',
|
|
||||||
async function (event) {
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
element.classList.remove('dragover');
|
}
|
||||||
if (this.isReorderModeOn(browser)) {
|
}.bind(browser.gZenWorkspaces)
|
||||||
const draggedWorkspaceId = event.dataTransfer.getData('text/plain');
|
);
|
||||||
const targetWorkspaceId = element.getAttribute('zen-workspace-id');
|
|
||||||
if (draggedWorkspaceId !== targetWorkspaceId) {
|
element.addEventListener(
|
||||||
await this.moveWorkspace(draggedWorkspaceId, targetWorkspaceId);
|
'dragover',
|
||||||
}
|
function (event) {
|
||||||
if (this.draggedElement) {
|
if (this.isReorderModeOn(browser) && this.draggedElement) {
|
||||||
this.draggedElement.classList.remove('dragging');
|
event.preventDefault();
|
||||||
this.draggedElement = null;
|
event.dataTransfer.dropEffect = 'move';
|
||||||
|
|
||||||
|
// Ensure the dragover effect is visible on Linux
|
||||||
|
if (AppConstants.platform === 'linux') {
|
||||||
|
const targetId = element.getAttribute('zen-workspace-id');
|
||||||
|
const draggedId = this.draggedElement.getAttribute('zen-workspace-id');
|
||||||
|
if (targetId !== draggedId) {
|
||||||
|
element.classList.add('dragover');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.bind(browser.gZenWorkspaces)
|
}
|
||||||
);
|
}.bind(browser.gZenWorkspaces)
|
||||||
|
);
|
||||||
|
|
||||||
element.addEventListener(
|
element.addEventListener('dragenter', function (event) {
|
||||||
'dragend',
|
if (this.isReorderModeOn(browser) && this.draggedElement) {
|
||||||
function (event) {
|
element.classList.add('dragover');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
element.addEventListener('dragleave', function (event) {
|
||||||
|
element.classList.remove('dragover');
|
||||||
|
});
|
||||||
|
|
||||||
|
element.addEventListener(
|
||||||
|
'drop',
|
||||||
|
async function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
element.classList.remove('dragover');
|
||||||
|
if (this.isReorderModeOn(browser)) {
|
||||||
|
const draggedWorkspaceId = event.dataTransfer.getData('text/plain');
|
||||||
|
const targetWorkspaceId = element.getAttribute('zen-workspace-id');
|
||||||
|
if (draggedWorkspaceId !== targetWorkspaceId) {
|
||||||
|
await this.moveWorkspace(draggedWorkspaceId, targetWorkspaceId);
|
||||||
|
}
|
||||||
if (this.draggedElement) {
|
if (this.draggedElement) {
|
||||||
this.draggedElement.classList.remove('dragging');
|
this.draggedElement.classList.remove('dragging');
|
||||||
this.draggedElement = null;
|
this.draggedElement = null;
|
||||||
}
|
}
|
||||||
const workspaceElements = browser.document.querySelectorAll('.zen-workspace-button');
|
}
|
||||||
for (const elem of workspaceElements) {
|
}.bind(browser.gZenWorkspaces)
|
||||||
elem.classList.remove('dragover');
|
);
|
||||||
}
|
|
||||||
}.bind(browser.gZenWorkspaces)
|
|
||||||
);
|
|
||||||
|
|
||||||
let childs = browser.MozXULElement.parseXULToFragment(`
|
element.addEventListener(
|
||||||
|
'dragend',
|
||||||
|
function (event) {
|
||||||
|
if (this.draggedElement) {
|
||||||
|
this.draggedElement.classList.remove('dragging');
|
||||||
|
this.draggedElement = null;
|
||||||
|
}
|
||||||
|
const workspaceElements = browser.document.querySelectorAll('.zen-workspace-button');
|
||||||
|
for (const elem of workspaceElements) {
|
||||||
|
elem.classList.remove('dragover');
|
||||||
|
}
|
||||||
|
}.bind(browser.gZenWorkspaces)
|
||||||
|
);
|
||||||
|
|
||||||
|
let childs = browser.MozXULElement.parseXULToFragment(`
|
||||||
<div class="zen-workspace-icon">
|
<div class="zen-workspace-icon">
|
||||||
</div>
|
</div>
|
||||||
<vbox>
|
<vbox>
|
||||||
@@ -1549,133 +1534,156 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||||||
</toolbarbutton>
|
</toolbarbutton>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
// use text content instead of innerHTML to avoid XSS
|
// use text content instead of innerHTML to avoid XSS
|
||||||
childs.querySelector('.zen-workspace-icon').textContent =
|
childs.querySelector('.zen-workspace-icon').textContent =
|
||||||
browser.gZenWorkspaces.getWorkspaceIcon(workspace);
|
browser.gZenWorkspaces.getWorkspaceIcon(workspace);
|
||||||
childs.querySelector('.zen-workspace-name').textContent = workspace.name;
|
childs.querySelector('.zen-workspace-name').textContent = workspace.name;
|
||||||
if (containerGroup) {
|
if (containerGroup) {
|
||||||
childs.querySelector('.zen-workspace-container').textContent =
|
childs.querySelector('.zen-workspace-container').textContent =
|
||||||
ContextualIdentityService.getUserContextLabel(containerGroup.userContextId);
|
ContextualIdentityService.getUserContextLabel(containerGroup.userContextId);
|
||||||
|
}
|
||||||
|
|
||||||
|
childs.querySelector('.zen-workspace-actions').addEventListener(
|
||||||
|
'command',
|
||||||
|
((event) => {
|
||||||
|
let button = event.target;
|
||||||
|
this._contextMenuId = button
|
||||||
|
.closest('toolbarbutton[zen-workspace-id]')
|
||||||
|
.getAttribute('zen-workspace-id');
|
||||||
|
const popup = button.ownerDocument.getElementById('zenWorkspaceActionsMenu');
|
||||||
|
popup.openPopup(button, 'after_end');
|
||||||
|
}).bind(browser.gZenWorkspaces)
|
||||||
|
);
|
||||||
|
element.appendChild(childs);
|
||||||
|
element.onclick = (async () => {
|
||||||
|
if (this.isReorderModeOn(browser)) {
|
||||||
|
return; // Return early if reorder mode is on
|
||||||
}
|
}
|
||||||
|
if (event.target.closest('.zen-workspace-actions')) {
|
||||||
|
return; // Ignore clicks on the actions button
|
||||||
|
}
|
||||||
|
const workspaceId = element.getAttribute('zen-workspace-id');
|
||||||
|
const workspaces = await this._workspaces();
|
||||||
|
const workspace = workspaces.workspaces.find((w) => w.uuid === workspaceId);
|
||||||
|
await this.changeWorkspace(workspace);
|
||||||
|
let panel = this.ownerWindow.document.getElementById('PanelUI-zen-workspaces');
|
||||||
|
PanelMultiView.hidePopup(panel);
|
||||||
|
}).bind(browser.gZenWorkspaces);
|
||||||
|
return element;
|
||||||
|
};
|
||||||
|
|
||||||
childs.querySelector('.zen-workspace-actions').addEventListener(
|
const createLastPositionDropTarget = () => {
|
||||||
'command',
|
const element = browser.document.createXULElement('div');
|
||||||
((event) => {
|
element.className = 'zen-workspace-last-place-drop-target';
|
||||||
let button = event.target;
|
|
||||||
this._contextMenuId = button
|
|
||||||
.closest('toolbarbutton[zen-workspace-id]')
|
|
||||||
.getAttribute('zen-workspace-id');
|
|
||||||
const popup = button.ownerDocument.getElementById('zenWorkspaceActionsMenu');
|
|
||||||
popup.openPopup(button, 'after_end');
|
|
||||||
}).bind(browser.gZenWorkspaces)
|
|
||||||
);
|
|
||||||
element.appendChild(childs);
|
|
||||||
element.onclick = (async () => {
|
|
||||||
if (this.isReorderModeOn(browser)) {
|
|
||||||
return; // Return early if reorder mode is on
|
|
||||||
}
|
|
||||||
if (event.target.closest('.zen-workspace-actions')) {
|
|
||||||
return; // Ignore clicks on the actions button
|
|
||||||
}
|
|
||||||
const workspaceId = element.getAttribute('zen-workspace-id');
|
|
||||||
const workspaces = await this._workspaces();
|
|
||||||
const workspace = workspaces.workspaces.find((w) => w.uuid === workspaceId);
|
|
||||||
await this.changeWorkspace(workspace);
|
|
||||||
let panel = this.ownerWindow.document.getElementById('PanelUI-zen-workspaces');
|
|
||||||
PanelMultiView.hidePopup(panel);
|
|
||||||
}).bind(browser.gZenWorkspaces);
|
|
||||||
return element;
|
|
||||||
};
|
|
||||||
|
|
||||||
const createLastPositionDropTarget = () => {
|
element.addEventListener(
|
||||||
const element = browser.document.createXULElement('div');
|
'dragover',
|
||||||
element.className = 'zen-workspace-last-place-drop-target';
|
function (event) {
|
||||||
|
if (this.isReorderModeOn(browser) && this.draggedElement) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.dataTransfer.dropEffect = 'move';
|
||||||
|
|
||||||
element.addEventListener(
|
// Ensure the dragover effect is visible on Linux
|
||||||
'dragover',
|
if (AppConstants.platform === 'linux') {
|
||||||
function (event) {
|
|
||||||
if (this.isReorderModeOn(browser) && this.draggedElement) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.dataTransfer.dropEffect = 'move';
|
|
||||||
|
|
||||||
// Ensure the dragover effect is visible on Linux
|
|
||||||
if (AppConstants.platform === 'linux') {
|
|
||||||
element.classList.add('dragover');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.bind(browser.gZenWorkspaces)
|
|
||||||
);
|
|
||||||
|
|
||||||
element.addEventListener(
|
|
||||||
'dragenter',
|
|
||||||
function (event) {
|
|
||||||
if (this.isReorderModeOn(browser) && this.draggedElement) {
|
|
||||||
element.classList.add('dragover');
|
element.classList.add('dragover');
|
||||||
}
|
}
|
||||||
}.bind(browser.gZenWorkspaces)
|
}
|
||||||
);
|
}.bind(browser.gZenWorkspaces)
|
||||||
|
);
|
||||||
|
|
||||||
element.addEventListener(
|
element.addEventListener(
|
||||||
'dragleave',
|
'dragenter',
|
||||||
function (event) {
|
function (event) {
|
||||||
element.classList.remove('dragover');
|
if (this.isReorderModeOn(browser) && this.draggedElement) {
|
||||||
}.bind(browser.gZenWorkspaces)
|
element.classList.add('dragover');
|
||||||
);
|
}
|
||||||
|
}.bind(browser.gZenWorkspaces)
|
||||||
|
);
|
||||||
|
|
||||||
element.addEventListener(
|
element.addEventListener(
|
||||||
'drop',
|
'dragleave',
|
||||||
async function (event) {
|
function (event) {
|
||||||
event.preventDefault();
|
element.classList.remove('dragover');
|
||||||
element.classList.remove('dragover');
|
}.bind(browser.gZenWorkspaces)
|
||||||
|
);
|
||||||
|
|
||||||
if (this.isReorderModeOn(browser)) {
|
element.addEventListener(
|
||||||
const draggedWorkspaceId = event.dataTransfer.getData('text/plain');
|
'drop',
|
||||||
await this.moveWorkspaceToEnd(draggedWorkspaceId);
|
async function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
element.classList.remove('dragover');
|
||||||
|
|
||||||
if (this.draggedElement) {
|
if (this.isReorderModeOn(browser)) {
|
||||||
this.draggedElement.classList.remove('dragging');
|
const draggedWorkspaceId = event.dataTransfer.getData('text/plain');
|
||||||
this.draggedElement = null;
|
await this.moveWorkspaceToEnd(draggedWorkspaceId);
|
||||||
}
|
|
||||||
|
if (this.draggedElement) {
|
||||||
|
this.draggedElement.classList.remove('dragging');
|
||||||
|
this.draggedElement = null;
|
||||||
}
|
}
|
||||||
}.bind(browser.gZenWorkspaces)
|
}
|
||||||
);
|
}.bind(browser.gZenWorkspaces)
|
||||||
|
);
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (clearCache) {
|
if (clearCache) {
|
||||||
browser.gZenWorkspaces._workspaceCache = null;
|
browser.gZenWorkspaces._workspaceCache = null;
|
||||||
browser.gZenWorkspaces._workspaceBookmarksCache = null;
|
browser.gZenWorkspaces._workspaceBookmarksCache = null;
|
||||||
}
|
}
|
||||||
let workspaces = await browser.gZenWorkspaces._workspaces();
|
let workspaces = await browser.gZenWorkspaces._workspaces();
|
||||||
if (clearCache) {
|
if (clearCache) {
|
||||||
browser.dispatchEvent(
|
browser.dispatchEvent(
|
||||||
new CustomEvent('ZenWorkspacesUIUpdate', {
|
new CustomEvent('ZenWorkspacesUIUpdate', {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
detail: { activeIndex: browser.gZenWorkspaces.activeWorkspace },
|
detail: { activeIndex: browser.gZenWorkspaces.activeWorkspace },
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await browser.gZenWorkspaces.workspaceBookmarks();
|
await browser.gZenWorkspaces.workspaceBookmarks();
|
||||||
workspaceList.innerHTML = '';
|
workspaceList.innerHTML = '';
|
||||||
workspaceList.parentNode.style.display = 'flex';
|
workspaceList.parentNode.style.display = 'flex';
|
||||||
if (workspaces.workspaces.length <= 0) {
|
if (workspaces.workspaces.length <= 0) {
|
||||||
workspaceList.innerHTML = 'No workspaces available';
|
workspaceList.innerHTML = 'No workspaces available';
|
||||||
workspaceList.setAttribute('empty', 'true');
|
workspaceList.setAttribute('empty', 'true');
|
||||||
} else {
|
} else {
|
||||||
workspaceList.removeAttribute('empty');
|
workspaceList.removeAttribute('empty');
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let workspace of workspaces.workspaces) {
|
for (let workspace of workspaces.workspaces) {
|
||||||
let workspaceElement = createWorkspaceElement(workspace);
|
let workspaceElement = createWorkspaceElement(workspace);
|
||||||
workspaceList.appendChild(workspaceElement);
|
workspaceList.appendChild(workspaceElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
workspaceList.appendChild(createLastPositionDropTarget());
|
workspaceList.appendChild(createLastPositionDropTarget());
|
||||||
|
if (!ignoreStrip) {
|
||||||
|
browser.gZenWorkspaces._fixIndicatorsNames(workspaces);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!ignoreStrip) {
|
async _propagateWorkspaceData({ ignoreStrip = false, clearCache = true, onInit = false } = {}) {
|
||||||
browser.gZenWorkspaces._fixIndicatorsNames(workspaces);
|
const currentWindowIsPrivate = this.isPrivateWindow;
|
||||||
|
if (onInit) {
|
||||||
|
if (currentWindowIsPrivate) return;
|
||||||
|
return await this._propagateWorkspaceDataForWindow(this.ownerWindow, {
|
||||||
|
ignoreStrip,
|
||||||
|
clearCache,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await this.foreachWindowAsActive(async (browser) => {
|
||||||
|
// Do not update the window if workspaces are not enabled in it.
|
||||||
|
// For example, when the window is in private browsing mode.
|
||||||
|
if (
|
||||||
|
!browser.gZenWorkspaces.workspaceEnabled ||
|
||||||
|
browser.gZenWorkspaces.isPrivateWindow !== currentWindowIsPrivate
|
||||||
|
) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
this._propagateWorkspaceDataForWindow(browser, {
|
||||||
|
ignoreStrip,
|
||||||
|
clearCache,
|
||||||
|
}).catch(console.error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2505,7 +2513,7 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||||||
// Update workspace UI
|
// Update workspace UI
|
||||||
await this._updateWorkspacesChangeContextMenu();
|
await this._updateWorkspacesChangeContextMenu();
|
||||||
// gZenUIManager.updateTabsToolbar();
|
// gZenUIManager.updateTabsToolbar();
|
||||||
await this._propagateWorkspaceData({ clearCache: false });
|
await this._propagateWorkspaceData({ clearCache: false, onInit });
|
||||||
|
|
||||||
gZenThemePicker.onWorkspaceChange(workspace);
|
gZenThemePicker.onWorkspaceChange(workspace);
|
||||||
|
|
||||||
|
@@ -584,7 +584,4 @@ var ZenWorkspaceBookmarksStorage = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
ZenWorkspacesStorage.promiseDBInitialized = new Promise((resolve) => {
|
ZenWorkspacesStorage.init();
|
||||||
ZenWorkspacesStorage._resolveDBInitialized = resolve;
|
|
||||||
ZenWorkspacesStorage.init();
|
|
||||||
});
|
|
||||||
|
Reference in New Issue
Block a user