feat(workspaces): migrate workspace data to synced preferences

This commit migrates the workspace data storage from local files to synced preferences, ensuring consistency across devices and improving user experience.

-  The `_syncPref` property is introduced for referencing the synced preference name.
-  The `onSyncChange` method handles changes to the synced preference, automatically propagating workspace data updates.
-  The `saveWorkspaces` and `unsafeSaveWorkspaces` methods are updated to interact with the synced preference instead of local files.
-  The `_workspaces` method retrieves workspace data directly from the synced preference.
-  The `initializeWorkspaces` method now handles preference syncing and login for Weave integration.
-  Removed unnecessary local file operations and caching related to workspace data.
This commit is contained in:
Kristijan Ribarić 2024-09-21 21:34:53 +02:00
parent 6fc85d1c09
commit ce4dd38b4b

View file

@ -4,7 +4,8 @@ var ZenWorkspaces = {
* Stores workspace IDs and their last selected tabs. * Stores workspace IDs and their last selected tabs.
*/ */
_lastSelectedWorkspaceTabs: {}, _lastSelectedWorkspaceTabs: {},
SYNC_PREF_NAME: "services.sync.prefs.sync.zen.workspaces.data",
ACTIVE_WORKSPACE_PREF: "zen.workspaces.active",
init() { init() {
if (!this.shouldHaveWorkspaces) { if (!this.shouldHaveWorkspaces) {
console.warn('ZenWorkspaces: !!! ZenWorkspaces is disabled in hidden windows !!!'); console.warn('ZenWorkspaces: !!! ZenWorkspaces is disabled in hidden windows !!!');
@ -17,6 +18,10 @@ var ZenWorkspaces = {
}); });
}, },
get _syncPref() {
return "zen.workspaces.data";
},
get shouldShowIconStrip() { get shouldShowIconStrip() {
delete this.shouldShowIconStrip; delete this.shouldShowIconStrip;
this.shouldShowIconStrip = Services.prefs.getBoolPref('zen.workspaces.show-icon-strip', true); this.shouldShowIconStrip = Services.prefs.getBoolPref('zen.workspaces.show-icon-strip', true);
@ -38,30 +43,35 @@ var ZenWorkspaces = {
return this.workspaceEnabled; return this.workspaceEnabled;
}, },
getActiveWorkspaceFromCache() {
return this._workspaceCache.workspaces.find((workspace) => workspace.used);
},
// Wrorkspaces saving/loading // Wrorkspaces saving/loading
get _storeFile() { get _storeFile() {
return PathUtils.join(PathUtils.profileDir, 'zen-workspaces', 'Workspaces.json'); return PathUtils.join(PathUtils.profileDir, 'zen-workspaces', 'Workspaces.json');
}, },
async _workspaces() { _workspaces() {
if (!this._workspaceCache) { const syncedData = Services.prefs.getStringPref(this._syncPref, "{}");
this._workspaceCache = await IOUtils.readJSON(this._storeFile); let parsedData = JSON.parse(syncedData);
if (!this._workspaceCache.workspaces) { if (!parsedData.workspaces) {
this._workspaceCache.workspaces = []; parsedData.workspaces = [];
} }
}
return this._workspaceCache; return parsedData;
}, },
async onWorkspacesEnabledChanged() { getActiveWorkspace() {
const workspaces = this._workspaces();
const activeWorkspaceId = Services.prefs.getStringPref(this.ACTIVE_WORKSPACE_PREF, "");
return workspaces.workspaces.find(workspace => workspace.uuid === activeWorkspaceId) || workspaces.workspaces[0];
},
setActiveWorkspace(workspaceId) {
Services.prefs.setStringPref(this.ACTIVE_WORKSPACE_PREF, workspaceId);
},
onWorkspacesEnabledChanged() {
if (this.workspaceEnabled) { if (this.workspaceEnabled) {
throw Error("Shoud've had reloaded the window"); throw Error("Shoud've had reloaded the window");
} else { } else {
this._workspaceCache = null;
document.getElementById('zen-workspaces-button')?.remove(); document.getElementById('zen-workspaces-button')?.remove();
for (let tab of gBrowser.tabs) { for (let tab of gBrowser.tabs) {
gBrowser.showTab(tab); gBrowser.showTab(tab);
@ -69,39 +79,46 @@ var ZenWorkspaces = {
} }
}, },
async onWorkspacesIconStripChanged() { onWorkspacesIconStripChanged() {
this.shouldShowIconStrip = Services.prefs.getBoolPref('zen.workspaces.show-icon-strip', true); this.shouldShowIconStrip = Services.prefs.getBoolPref('zen.workspaces.show-icon-strip', true);
await this._expandWorkspacesStrip(); this._expandWorkspacesStrip();
}, },
async initializeWorkspaces() { async initializeWorkspaces() {
Services.prefs.addObserver('zen.workspaces.enabled', this.onWorkspacesEnabledChanged.bind(this)); Services.prefs.addObserver('zen.workspaces.enabled', this.onWorkspacesEnabledChanged.bind(this));
Services.prefs.addObserver('zen.workspaces.show-icon-strip', this.onWorkspacesIconStripChanged.bind(this)); Services.prefs.addObserver('zen.workspaces.show-icon-strip', this.onWorkspacesIconStripChanged.bind(this));
let file = new FileUtils.File(this._storeFile); Services.prefs.addObserver(this._syncPref, this.onSyncChange.bind(this));
if (!file.exists()) {
await IOUtils.writeJSON(this._storeFile, {}); this.initializeWorkspacesButton();
}
await this.initializeWorkspacesButton();
if (this.workspaceEnabled) { if (this.workspaceEnabled) {
// Enable syncing for custom preference
Services.prefs.setBoolPref(this.SYNC_PREF_NAME, true);
if (!Weave.Service.isLoggedIn) {
await Weave.Service.login();
}
this._initializeWorkspaceCreationIcons(); this._initializeWorkspaceCreationIcons();
this._initializeWorkspaceEditIcons(); this._initializeWorkspaceEditIcons();
this._initializeWorkspaceTabContextMenus(); this._initializeWorkspaceTabContextMenus();
window.addEventListener('TabClose', this.handleTabClose.bind(this)); window.addEventListener('TabClose', this.handleTabClose.bind(this));
window.addEventListener('TabBrowserInserted', this.onTabBrowserInserted.bind(this)); window.addEventListener('TabBrowserInserted', this.onTabBrowserInserted.bind(this));
let workspaces = await this._workspaces(); let workspaces = this._workspaces();
if (workspaces.workspaces.length === 0) { if (workspaces.workspaces.length === 0) {
await this.createAndSaveWorkspace('Default Workspace', true); this.createAndSaveWorkspace('Default Workspace', true);
} else { } else {
let activeWorkspace = workspaces.workspaces.find((workspace) => workspace.used); let activeWorkspace = this.getActiveWorkspace();
if (!activeWorkspace) { if (!activeWorkspace) {
activeWorkspace = workspaces.workspaces.find((workspace) => workspace.default); activeWorkspace = workspaces.workspaces.find((workspace) => workspace.default);
activeWorkspace.used = true; if (activeWorkspace) {
await this.saveWorkspaces(); this.setActiveWorkspace(activeWorkspace.uuid);
}
} }
if (!activeWorkspace) { if (!activeWorkspace) {
activeWorkspace = workspaces.workspaces[0]; activeWorkspace = workspaces.workspaces[0];
activeWorkspace.used = true; this.setActiveWorkspace(activeWorkspace.uuid);
await this.saveWorkspaces();
} }
this.changeWorkspace(activeWorkspace, true); this.changeWorkspace(activeWorkspace, true);
} }
@ -166,8 +183,8 @@ var ZenWorkspaces = {
} }
}, },
async saveWorkspace(workspaceData) { saveWorkspace(workspaceData) {
let json = await IOUtils.readJSON(this._storeFile); let json = this._workspaces();
if (typeof json.workspaces === 'undefined') { if (typeof json.workspaces === 'undefined') {
json.workspaces = []; json.workspaces = [];
} }
@ -178,32 +195,39 @@ var ZenWorkspaces = {
json.workspaces.push(workspaceData); json.workspaces.push(workspaceData);
} }
console.info('ZenWorkspaces: Saving workspace', workspaceData); console.info('ZenWorkspaces: Saving workspace', workspaceData);
await IOUtils.writeJSON(this._storeFile, json);
this._workspaceCache = null;
await this._updateWorkspacesChangeContextMenu(); // Save to synced preference
const workspacesJson = JSON.stringify(json);
Services.prefs.setStringPref(this._syncPref, workspacesJson);
this._updateWorkspacesChangeContextMenu();
}, },
async removeWorkspace(windowID) { removeWorkspace(windowID) {
let json = await this._workspaces(); let json = this._workspaces();
console.info('ZenWorkspaces: Removing workspace', windowID); console.info('ZenWorkspaces: Removing workspace', windowID);
await this.changeWorkspace(json.workspaces.find((workspace) => workspace.uuid !== windowID)); this.changeWorkspace(json.workspaces.find((workspace) => workspace.uuid !== windowID));
this._deleteAllTabsInWorkspace(windowID); this._deleteAllTabsInWorkspace(windowID);
delete this._lastSelectedWorkspaceTabs[windowID]; delete this._lastSelectedWorkspaceTabs[windowID];
json.workspaces = json.workspaces.filter((workspace) => workspace.uuid !== windowID); json.workspaces = json.workspaces.filter((workspace) => workspace.uuid !== windowID);
await this.unsafeSaveWorkspaces(json); this.unsafeSaveWorkspaces(json);
await this._propagateWorkspaceData(); this._propagateWorkspaceData();
await this._updateWorkspacesChangeContextMenu(); this._updateWorkspacesChangeContextMenu();
}, },
async saveWorkspaces() { saveWorkspaces() {
await IOUtils.writeJSON(this._storeFile, await this._workspaces()); const workspacesJson = JSON.stringify(this._workspaces());
this._workspaceCache = null; Services.prefs.setStringPref(this._syncPref, workspacesJson);
}, },
async unsafeSaveWorkspaces(workspaces) { unsafeSaveWorkspaces(workspaces) {
await IOUtils.writeJSON(this._storeFile, workspaces); const workspacesJson = JSON.stringify(workspaces);
this._workspaceCache = workspaces; Services.prefs.setStringPref(this._syncPref, workspacesJson);
},
onSyncChange() {
console.info("Syncing workspaces...");
this._propagateWorkspaceData();
}, },
// Workspaces dialog UI management // Workspaces dialog UI management
@ -213,10 +237,10 @@ var ZenWorkspaces = {
PanelUI.showSubView('PanelUI-zen-workspaces-create', parentPanel); PanelUI.showSubView('PanelUI-zen-workspaces-create', parentPanel);
}, },
async openEditDialog(workspaceUuid) { openEditDialog(workspaceUuid) {
this._workspaceEditDialog.setAttribute('data-workspace-uuid', workspaceUuid); this._workspaceEditDialog.setAttribute('data-workspace-uuid', workspaceUuid);
document.getElementById('PanelUI-zen-workspaces-edit-save').setAttribute('disabled', 'true'); document.getElementById('PanelUI-zen-workspaces-edit-save').setAttribute('disabled', 'true');
let workspaces = (await this._workspaces()).workspaces; let workspaces = this._workspaces().workspaces;
let workspaceData = workspaces.find((workspace) => workspace.uuid === workspaceUuid); let workspaceData = workspaces.find((workspace) => workspace.uuid === workspaceUuid);
this._workspaceEditInput.textContent = workspaceData.name; this._workspaceEditInput.textContent = workspaceData.name;
this._workspaceEditInput.value = workspaceData.name; this._workspaceEditInput.value = workspaceData.name;
@ -255,14 +279,15 @@ var ZenWorkspaces = {
let currentContainer = document.getElementById('PanelUI-zen-workspaces-current-info'); let currentContainer = document.getElementById('PanelUI-zen-workspaces-current-info');
let workspaceList = document.getElementById('PanelUI-zen-workspaces-list'); let workspaceList = document.getElementById('PanelUI-zen-workspaces-list');
if (!ignoreStrip) { if (!ignoreStrip) {
await this._expandWorkspacesStrip(); this._expandWorkspacesStrip();
} }
const createWorkspaceElement = (workspace) => { const createWorkspaceElement = (workspace) => {
let element = document.createXULElement('toolbarbutton'); let element = document.createXULElement('toolbarbutton');
element.className = 'subviewbutton'; element.className = 'subviewbutton';
element.setAttribute('tooltiptext', workspace.name); element.setAttribute('tooltiptext', workspace.name);
element.setAttribute('zen-workspace-id', workspace.uuid); element.setAttribute('zen-workspace-id', workspace.uuid);
if (workspace.used) { let activeWorkspace=this.getActiveWorkspace();
if (workspace.uuid === activeWorkspace.uuid) {
element.setAttribute('active', 'true'); element.setAttribute('active', 'true');
} }
if (workspace.default) { if (workspace.default) {
@ -305,19 +330,19 @@ var ZenWorkspaces = {
popup.openPopup(button, 'after_end'); popup.openPopup(button, 'after_end');
}); });
element.appendChild(childs); element.appendChild(childs);
element.onclick = (async () => { element.onclick = (() => {
if (event.target.closest('.zen-workspace-actions')) { if (event.target.closest('.zen-workspace-actions')) {
return; // Ignore clicks on the actions button return; // Ignore clicks on the actions button
} }
await this.changeWorkspace(workspace); this.changeWorkspace(workspace);
let panel = document.getElementById('PanelUI-zen-workspaces'); let panel = document.getElementById('PanelUI-zen-workspaces');
PanelMultiView.hidePopup(panel); PanelMultiView.hidePopup(panel);
document.getElementById('zen-workspaces-button').removeAttribute('open'); document.getElementById('zen-workspaces-button').removeAttribute('open');
}).bind(this, workspace); }).bind(this, workspace);
return element; return element;
}; };
let workspaces = await this._workspaces(); let workspaces = this._workspaces();
let activeWorkspace = workspaces.workspaces.find((workspace) => workspace.used); let activeWorkspace = this.getActiveWorkspace();
currentContainer.innerHTML = ''; currentContainer.innerHTML = '';
workspaceList.innerHTML = ''; workspaceList.innerHTML = '';
workspaceList.parentNode.style.display = 'flex'; workspaceList.parentNode.style.display = 'flex';
@ -332,7 +357,7 @@ var ZenWorkspaces = {
currentContainer.appendChild(currentWorkspace); currentContainer.appendChild(currentWorkspace);
} }
for (let workspace of workspaces.workspaces) { for (let workspace of workspaces.workspaces) {
if (workspace.used) { if (workspace.uuid === activeWorkspace.uuid) {
continue; continue;
} }
let workspaceElement = createWorkspaceElement(workspace); let workspaceElement = createWorkspaceElement(workspace);
@ -340,13 +365,13 @@ var ZenWorkspaces = {
} }
}, },
async openWorkspacesDialog(event) { openWorkspacesDialog(event) {
if (!this.workspaceEnabled) { if (!this.workspaceEnabled) {
return; return;
} }
let target = event.target; let target = event.target;
let panel = document.getElementById('PanelUI-zen-workspaces'); let panel = document.getElementById('PanelUI-zen-workspaces');
await this._propagateWorkspaceData({ this._propagateWorkspaceData({
ignoreStrip: true ignoreStrip: true
}); });
PanelMultiView.openPopup(panel, target, { PanelMultiView.openPopup(panel, target, {
@ -355,7 +380,7 @@ var ZenWorkspaces = {
}).catch(console.error); }).catch(console.error);
}, },
async initializeWorkspacesButton() { initializeWorkspacesButton() {
if (!this.workspaceEnabled) { if (!this.workspaceEnabled) {
return; return;
} else if (document.getElementById('zen-workspaces-button')) { } else if (document.getElementById('zen-workspaces-button')) {
@ -367,11 +392,11 @@ var ZenWorkspaces = {
const wrapper = document.createXULElement('toolbarbutton'); const wrapper = document.createXULElement('toolbarbutton');
wrapper.id = 'zen-workspaces-button'; wrapper.id = 'zen-workspaces-button';
nextSibling.after(wrapper); nextSibling.after(wrapper);
await this._expandWorkspacesStrip(); this._expandWorkspacesStrip();
}, },
async _expandWorkspacesStrip() { _expandWorkspacesStrip() {
let workspaces = await this._workspaces(); let workspaces = this._workspaces();
let workspaceList = document.getElementById('zen-workspaces-button'); let workspaceList = document.getElementById('zen-workspaces-button');
const newWorkspacesButton = document.createXULElement(this.shouldShowIconStrip ? 'hbox' : 'toolbarbutton'); const newWorkspacesButton = document.createXULElement(this.shouldShowIconStrip ? 'hbox' : 'toolbarbutton');
newWorkspacesButton.id = 'zen-workspaces-button'; newWorkspacesButton.id = 'zen-workspaces-button';
@ -380,23 +405,24 @@ var ZenWorkspaces = {
newWorkspacesButton.setAttribute('tooltiptext', 'Workspaces'); newWorkspacesButton.setAttribute('tooltiptext', 'Workspaces');
if (this.shouldShowIconStrip) { if (this.shouldShowIconStrip) {
const activeWorkspace = this.getActiveWorkspace();
for (let workspace of workspaces.workspaces) { for (let workspace of workspaces.workspaces) {
let button = document.createXULElement('toolbarbutton'); let button = document.createXULElement('toolbarbutton');
button.className = 'subviewbutton'; button.className = 'subviewbutton';
button.setAttribute('tooltiptext', workspace.name); button.setAttribute('tooltiptext', workspace.name);
button.setAttribute('zen-workspace-id', workspace.uuid); button.setAttribute('zen-workspace-id', workspace.uuid);
if (workspace.used) { if (workspace.uuid === activeWorkspace.uuid) {
button.setAttribute('active', 'true'); button.setAttribute('active', 'true');
} }
if (workspace.default) { if (workspace.default) {
button.setAttribute('default', 'true'); button.setAttribute('default', 'true');
} }
button.onclick = (async (_, event) => { button.onclick = ((_, event) => {
// Make sure it's not a context menu event // Make sure it's not a context menu event
if (event.button !== 0) { if (event.button !== 0) {
return; return;
} }
await this.changeWorkspace(workspace); this.changeWorkspace(workspace);
}).bind(this, workspace); }).bind(this, workspace);
let icon = document.createXULElement('div'); let icon = document.createXULElement('div');
icon.className = 'zen-workspace-icon'; icon.className = 'zen-workspace-icon';
@ -409,22 +435,28 @@ var ZenWorkspaces = {
event.preventDefault(); event.preventDefault();
this.openWorkspacesDialog(event); this.openWorkspacesDialog(event);
}); });
} else {
// Add context menu listener for non-strip mode
newWorkspacesButton.addEventListener('contextmenu', (event) => {
event.preventDefault();
this.openWorkspacesDialog(event);
});
} }
workspaceList.after(newWorkspacesButton); workspaceList.after(newWorkspacesButton);
workspaceList.remove(); workspaceList.remove();
if (!this.shouldShowIconStrip) { if (!this.shouldShowIconStrip) {
await this._updateWorkspacesButton(); this._updateWorkspacesButton();
} }
}, },
async _updateWorkspacesButton() { _updateWorkspacesButton() {
let button = document.getElementById('zen-workspaces-button'); let button = document.getElementById('zen-workspaces-button');
if (!button) { if (!button) {
return; return;
} }
let activeWorkspace = (await this._workspaces()).workspaces.find((workspace) => workspace.used); let activeWorkspace = this.getActiveWorkspace();
if (activeWorkspace) { if (activeWorkspace) {
button.setAttribute('as-button', 'true'); button.setAttribute('as-button', 'true');
button.classList.add('toolbarbutton-1', 'zen-sidebar-action-button'); button.classList.add('toolbarbutton-1', 'zen-sidebar-action-button');
@ -505,7 +537,7 @@ var ZenWorkspaces = {
tab.setAttribute('zen-workspace-id', window.uuid); tab.setAttribute('zen-workspace-id', window.uuid);
}, },
async saveWorkspaceFromCreate() { saveWorkspaceFromCreate() {
let workspaceName = this._workspaceCreateInput.value; let workspaceName = this._workspaceCreateInput.value;
if (!workspaceName) { if (!workspaceName) {
return; return;
@ -513,13 +545,13 @@ var ZenWorkspaces = {
this._workspaceCreateInput.value = ''; this._workspaceCreateInput.value = '';
let icon = document.querySelector('#PanelUI-zen-workspaces-create-icons-container [selected]'); let icon = document.querySelector('#PanelUI-zen-workspaces-create-icons-container [selected]');
icon?.removeAttribute('selected'); icon?.removeAttribute('selected');
await this.createAndSaveWorkspace(workspaceName, false, icon?.label); this.createAndSaveWorkspace(workspaceName, false, icon?.label);
document.getElementById('PanelUI-zen-workspaces').hidePopup(true); document.getElementById('PanelUI-zen-workspaces').hidePopup(true);
await this._updateWorkspacesButton(); this._updateWorkspacesButton();
await this._propagateWorkspaceData(); this._propagateWorkspaceData();
}, },
async saveWorkspaceFromEdit() { saveWorkspaceFromEdit() {
let workspaceUuid = this._workspaceEditDialog.getAttribute('data-workspace-uuid'); let workspaceUuid = this._workspaceEditDialog.getAttribute('data-workspace-uuid');
let workspaceName = this._workspaceEditInput.value; let workspaceName = this._workspaceEditInput.value;
if (!workspaceName) { if (!workspaceName) {
@ -528,13 +560,13 @@ var ZenWorkspaces = {
this._workspaceEditInput.value = ''; this._workspaceEditInput.value = '';
let icon = document.querySelector('#PanelUI-zen-workspaces-edit-icons-container [selected]'); let icon = document.querySelector('#PanelUI-zen-workspaces-edit-icons-container [selected]');
icon?.removeAttribute('selected'); icon?.removeAttribute('selected');
let workspaces = (await this._workspaces()).workspaces; let workspaces = this._workspaces().workspaces;
let workspaceData = workspaces.find((workspace) => workspace.uuid === workspaceUuid); let workspaceData = workspaces.find((workspace) => workspace.uuid === workspaceUuid);
workspaceData.name = workspaceName; workspaceData.name = workspaceName;
workspaceData.icon = icon?.label; workspaceData.icon = icon?.label;
await this.saveWorkspace(workspaceData); this.saveWorkspace(workspaceData);
await this._updateWorkspacesButton(); this._updateWorkspacesButton();
await this._propagateWorkspaceData(); this._propagateWorkspaceData();
this.closeWorkspacesSubView(); this.closeWorkspacesSubView();
}, },
@ -570,22 +602,16 @@ var ZenWorkspaces = {
return (this.tabContainer = document.getElementById("tabbrowser-tabs")); return (this.tabContainer = document.getElementById("tabbrowser-tabs"));
}, },
async changeWorkspace(window, onInit = false) { changeWorkspace(window, onInit = false) {
if (!this.workspaceEnabled) { if (!this.workspaceEnabled) {
return; return;
} }
this.tabContainer._invalidateCachedTabs(); this.tabContainer._invalidateCachedTabs();
const shouldAllowPinnedTabs = this._shouldAllowPinTab; const shouldAllowPinnedTabs = this._shouldAllowPinTab;
let firstTab = undefined; let firstTab = undefined;
let workspaces = await this._workspaces(); // Set the active workspace
for (let workspace of workspaces.workspaces) { this.setActiveWorkspace(window.uuid);
if (workspace.uuid === window.uuid && workspace.used) {
// If the workspace is already active, do nothing
return;
}
workspace.used = workspace.uuid === window.uuid;
}
await this.unsafeSaveWorkspaces(workspaces);
console.info('ZenWorkspaces: Changing workspace to', window.uuid); console.info('ZenWorkspaces: Changing workspace to', window.uuid);
for (let tab of gBrowser.tabs) { for (let tab of gBrowser.tabs) {
if ((tab.getAttribute('zen-workspace-id') === window.uuid && !(tab.pinned && !shouldAllowPinnedTabs)) || !tab.hasAttribute('zen-workspace-id')) { if ((tab.getAttribute('zen-workspace-id') === window.uuid && !(tab.pinned && !shouldAllowPinnedTabs)) || !tab.hasAttribute('zen-workspace-id')) {
@ -618,22 +644,22 @@ var ZenWorkspaces = {
} }
this.tabContainer._invalidateCachedTabs(); this.tabContainer._invalidateCachedTabs();
document.documentElement.setAttribute('zen-workspace-id', window.uuid); document.documentElement.setAttribute('zen-workspace-id', window.uuid);
await this.saveWorkspaces();
await this._updateWorkspacesButton(); this._updateWorkspacesButton();
await this._propagateWorkspaceData(); this._propagateWorkspaceData();
await this._updateWorkspacesChangeContextMenu(); this._updateWorkspacesChangeContextMenu();
document.getElementById('tabbrowser-tabs')._positionPinnedTabs(); document.getElementById('tabbrowser-tabs')._positionPinnedTabs();
}, },
async _updateWorkspacesChangeContextMenu() { _updateWorkspacesChangeContextMenu() {
const workspaces = await this._workspaces(); const workspaces = this._workspaces();
const menuPopup = document.getElementById('context-zen-change-workspace-tab-menu-popup'); const menuPopup = document.getElementById('context-zen-change-workspace-tab-menu-popup');
menuPopup.innerHTML = ''; menuPopup.innerHTML = '';
const activeWorkspace = workspaces.workspaces.find((workspace) => workspace.used); const activeWorkspace = this.getActiveWorkspace();
for (let workspace of workspaces.workspaces) { for (let workspace of workspaces.workspaces) {
const menuItem = document.createXULElement('menuitem'); const menuItem = document.createXULElement('menuitem');
@ -660,34 +686,35 @@ var ZenWorkspaces = {
return window; return window;
}, },
async createAndSaveWorkspace(name = 'New Workspace', isDefault = false, icon = undefined) { createAndSaveWorkspace(name = 'New Workspace', isDefault = false, icon = undefined) {
if (!this.workspaceEnabled) { if (!this.workspaceEnabled) {
return; return;
} }
let workspaceData = this._createWorkspaceData(name, isDefault, icon); let workspaceData = this._createWorkspaceData(name, isDefault, icon);
await this.saveWorkspace(workspaceData); this.saveWorkspace(workspaceData);
await this.changeWorkspace(workspaceData); this.setActiveWorkspace(workspaceData.uuid);
this.changeWorkspace(workspaceData);
return workspaceData;
}, },
async onTabBrowserInserted(event) { onTabBrowserInserted(event) {
let tab = event.originalTarget; let tab = event.originalTarget;
if (tab.getAttribute('zen-workspace-id') || !this.workspaceEnabled) { if (tab.getAttribute('zen-workspace-id') || !this.workspaceEnabled) {
return; return;
} }
let workspaces = await this._workspaces();
let activeWorkspace = workspaces.workspaces.find((workspace) => workspace.used); let activeWorkspace = this.getActiveWorkspace();
if (!activeWorkspace) { if (!activeWorkspace) {
return; return;
} }
tab.setAttribute('zen-workspace-id', activeWorkspace.uuid); tab.setAttribute('zen-workspace-id', activeWorkspace.uuid);
}, },
async onLocationChange(browser) { onLocationChange(browser) {
let tab = gBrowser.getTabForBrowser(browser); let tab = gBrowser.getTabForBrowser(browser);
let workspaceID = tab.getAttribute('zen-workspace-id'); let workspaceID = tab.getAttribute('zen-workspace-id');
if (!workspaceID) { if (!workspaceID) {
let workspaces = await this._workspaces(); let activeWorkspace = this.getActiveWorkspace();
let activeWorkspace = workspaces.workspaces.find((workspace) => workspace.used);
if (!activeWorkspace || tab.hasAttribute('hidden')) { if (!activeWorkspace || tab.hasAttribute('hidden')) {
return; return;
} }
@ -700,12 +727,12 @@ var ZenWorkspaces = {
// Context menu management // Context menu management
_contextMenuId: null, _contextMenuId: null,
async updateContextMenu(_) { updateContextMenu(_) {
console.assert(this._contextMenuId, 'No context menu ID set'); console.assert(this._contextMenuId, 'No context menu ID set');
document document
.querySelector(`#PanelUI-zen-workspaces [zen-workspace-id="${this._contextMenuId}"] .zen-workspace-actions`) .querySelector(`#PanelUI-zen-workspaces [zen-workspace-id="${this._contextMenuId}"] .zen-workspace-actions`)
.setAttribute('active', 'true'); .setAttribute('active', 'true');
const workspaces = await this._workspaces(); const workspaces = this._workspaces();
let deleteMenuItem = document.getElementById('context_zenDeleteWorkspace'); let deleteMenuItem = document.getElementById('context_zenDeleteWorkspace');
if ( if (
workspaces.workspaces.length <= 1 || workspaces.workspaces.length <= 1 ||
@ -722,20 +749,20 @@ var ZenWorkspaces = {
defaultMenuItem.removeAttribute('disabled'); defaultMenuItem.removeAttribute('disabled');
} }
let openMenuItem = document.getElementById('context_zenOpenWorkspace'); let openMenuItem = document.getElementById('context_zenOpenWorkspace');
if (workspaces.workspaces.find((workspace) => workspace.uuid === this._contextMenuId).used) { if (this._contextMenuId=== this.getActiveWorkspace().uuid) {
openMenuItem.setAttribute('disabled', 'true'); openMenuItem.setAttribute('disabled', 'true');
} else { } else {
openMenuItem.removeAttribute('disabled'); openMenuItem.removeAttribute('disabled');
} }
}, },
async contextChangeContainerTab(event) { contextChangeContainerTab(event) {
let workspaces = await this._workspaces(); let workspaces = this._workspaces();
let workspace = workspaces.workspaces.find((workspace) => workspace.uuid === this._contextMenuId); let workspace = workspaces.workspaces.find((workspace) => workspace.uuid === this._contextMenuId);
let userContextId = parseInt(event.target.getAttribute('data-usercontextid')); let userContextId = parseInt(event.target.getAttribute('data-usercontextid'));
workspace.containerTabId = userContextId; workspace.containerTabId = userContextId;
await this.saveWorkspace(workspace); this.saveWorkspace(workspace);
await this._propagateWorkspaceData(); this._propagateWorkspaceData();
}, },
onContextMenuClose() { onContextMenuClose() {
@ -748,36 +775,36 @@ var ZenWorkspaces = {
this._contextMenuId = null; this._contextMenuId = null;
}, },
async setDefaultWorkspace() { setDefaultWorkspace() {
let workspaces = await this._workspaces(); let workspaces = this._workspaces();
for (let workspace of workspaces.workspaces) { for (let workspace of workspaces.workspaces) {
workspace.default = workspace.uuid === this._contextMenuId; workspace.default = workspace.uuid === this._contextMenuId;
} }
await this.unsafeSaveWorkspaces(workspaces); this.unsafeSaveWorkspaces(workspaces);
await this._propagateWorkspaceData(); this._propagateWorkspaceData();
}, },
async openWorkspace() { openWorkspace() {
let workspaces = await this._workspaces(); let workspaces = this._workspaces();
let workspace = workspaces.workspaces.find((workspace) => workspace.uuid === this._contextMenuId); let workspace = workspaces.workspaces.find((workspace) => workspace.uuid === this._contextMenuId);
await this.changeWorkspace(workspace); this.changeWorkspace(workspace);
}, },
async contextDelete(event) { contextDelete(event) {
this.__contextIsDelete = true; this.__contextIsDelete = true;
event.stopPropagation(); event.stopPropagation();
await this.removeWorkspace(this._contextMenuId); this.removeWorkspace(this._contextMenuId);
this.__contextIsDelete = false; this.__contextIsDelete = false;
}, },
async contextEdit(event) { contextEdit(event) {
event.stopPropagation(); event.stopPropagation();
await this.openEditDialog(this._contextMenuId); this.openEditDialog(this._contextMenuId);
}, },
async changeWorkspaceShortcut(offset = 1) { changeWorkspaceShortcut(offset = 1) {
// Cycle through workspaces // Cycle through workspaces
let workspaces = await this._workspaces(); let workspaces = this._workspaces();
let activeWorkspace = workspaces.workspaces.find((workspace) => workspace.used); let activeWorkspace = workspaces.workspaces.find((workspace) => workspace.used);
let workspaceIndex = workspaces.workspaces.indexOf(activeWorkspace); let workspaceIndex = workspaces.workspaces.indexOf(activeWorkspace);
// note: offset can be negative // note: offset can be negative
@ -799,7 +826,7 @@ var ZenWorkspaces = {
document.getElementById('context_closeDuplicateTabs').after(menu); document.getElementById('context_closeDuplicateTabs').after(menu);
}, },
async changeTabWorkspace(workspaceID) { changeTabWorkspace(workspaceID) {
const tabs = TabContextMenu.contextTab.multiselected ? gBrowser.selectedTabs : [TabContextMenu.contextTab]; const tabs = TabContextMenu.contextTab.multiselected ? gBrowser.selectedTabs : [TabContextMenu.contextTab];
const previousWorkspaceID = document.documentElement.getAttribute('zen-workspace-id'); const previousWorkspaceID = document.documentElement.getAttribute('zen-workspace-id');
for (let tab of tabs) { for (let tab of tabs) {
@ -810,14 +837,14 @@ var ZenWorkspaces = {
delete this._lastSelectedWorkspaceTabs[previousWorkspaceID]; delete this._lastSelectedWorkspaceTabs[previousWorkspaceID];
} }
} }
const workspaces = await this._workspaces(); const workspaces = this._workspaces();
await this.changeWorkspace(workspaces.workspaces.find((workspace) => workspace.uuid === workspaceID)); this.changeWorkspace(workspaces.workspaces.find((workspace) => workspace.uuid === workspaceID));
}, },
// Tab browser utilities // Tab browser utilities
createContainerTabMenu(event) { createContainerTabMenu(event) {
let window = event.target.ownerGlobal; let window = event.target.ownerGlobal;
const workspace = this._workspaceCache.workspaces.find((workspace) => this._contextMenuId === workspace.uuid); const workspace = this._workspaces().workspaces.find((workspace) => this._contextMenuId === workspace.uuid);
let containerTabId = workspace.containerTabId; let containerTabId = workspace.containerTabId;
return window.createUserContextMenu(event, { return window.createUserContextMenu(event, {
isContextMenu: true, isContextMenu: true,
@ -830,7 +857,7 @@ var ZenWorkspaces = {
if (typeof userContextId !== 'undefined' || !this.workspaceEnabled) { if (typeof userContextId !== 'undefined' || !this.workspaceEnabled) {
return [userContextId, false]; return [userContextId, false];
} }
const activeWorkspace = this.getActiveWorkspaceFromCache(); const activeWorkspace = this.getActiveWorkspace();
return [activeWorkspace?.containerTabId, true]; return [activeWorkspace?.containerTabId, true];
}, },
}; };