Skip to content

Commit

Permalink
[FB] Workspaces | Create migrator for Workspaces
Browse files Browse the repository at this point in the history
  • Loading branch information
surapunoyousei committed Nov 28, 2023
1 parent db159ba commit 2be2c00
Show file tree
Hide file tree
Showing 18 changed files with 330 additions and 35 deletions.
331 changes: 313 additions & 18 deletions browser/base/content/browser-workspace.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
* 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/. */

const l10n = new Localization(["browser/floorp.ftl", "branding/brand.ftl"], true);
const l10n = new Localization(
["browser/floorp.ftl", "branding/brand.ftl"],
true
);

const WorkspaceUtils = ChromeUtils.importESModule(
"resource:///modules/WorkspaceUtils.sys.mjs"
Expand Down Expand Up @@ -307,13 +310,17 @@ const workspaceFunctions = {
let workspaceAll = Services.prefs
.getStringPref(WorkspaceUtils.workspacesPreferences.WORKSPACE_ALL_PREF)
.split(",");

for (let i = 0; i < workspaceAll.length; i++) {
let label = workspaceAll[i];
workspaceFunctions.WorkspaceContextMenu.addWorkspaceElemToMenu(label);

// Check if workspace tabs are exist
if (!workspaceFunctions.manageWorkspaceFunctions.checkWorkspaceTabsAreExist(workspaceAll[i])) {
if (
!workspaceFunctions.manageWorkspaceFunctions.checkWorkspaceTabsAreExist(
workspaceAll[i]
)
) {
workspaceFunctions.manageWorkspaceFunctions.deleteworkspace(
workspaceAll[i]
);
Expand Down Expand Up @@ -1012,7 +1019,10 @@ const workspaceFunctions = {
return null;
}
let iconURL = settings[targetWorkspaceNumber][workspaceName].icon;
let removeSVG = iconURL.replace("chrome://browser/skin/workspace-icons/", "");
let removeSVG = iconURL.replace(
"chrome://browser/skin/workspace-icons/",
""
);
let result = removeSVG.replace(".svg", "");
return result;
},
Expand All @@ -1038,12 +1048,10 @@ const workspaceFunctions = {
},

setWorkspaceFromPrompt(label) {
let iconName = workspaceFunctions.iconFunctions.getIconNameByWorkspaceName(
label
);
let containerNumber = workspaceFunctions.containerFunctions.getWorkspaceUserContextId(
label
);
let iconName =
workspaceFunctions.iconFunctions.getIconNameByWorkspaceName(label);
let containerNumber =
workspaceFunctions.containerFunctions.getWorkspaceUserContextId(label);

let parentWindow = Services.wm.getMostRecentWindow("navigator:browser");
let object = { workspaceName: label, iconName, containerNumber };
Expand Down Expand Up @@ -1266,8 +1274,10 @@ const workspaceFunctions = {
</vbox>
`);

let iconElem = window.MozXULElement.parseXULToFragment(`<toolbarbutton workspace="${labelDisplay}" iconName="${label}" class="workspace-item-icon toolbarbutton-1" oncommand="workspaceFunctions.manageWorkspaceFunctions.changeWorkspace('${label}')" style="list-style-image: url(${workspaceFunctions.iconFunctions.getWorkspaceIcon(
label)}
let iconElem = window.MozXULElement
.parseXULToFragment(`<toolbarbutton workspace="${labelDisplay}" iconName="${label}" class="workspace-item-icon toolbarbutton-1" oncommand="workspaceFunctions.manageWorkspaceFunctions.changeWorkspace('${label}')" style="list-style-image: url(${workspaceFunctions.iconFunctions.getWorkspaceIcon(
label
)}
)"/>`);

if (nextElem) {
Expand All @@ -1278,9 +1288,7 @@ const workspaceFunctions = {
.before(workspaceItemElem);
}

document
.getElementById(`${label}-button`)
.appendChild(iconElem);
document.getElementById(`${label}-button`).appendChild(iconElem);
if (
Services.prefs
.getStringPref(
Expand Down Expand Up @@ -1346,8 +1354,7 @@ const workspaceFunctions = {
`;

let manageOnBMSIsEnabled = Services.prefs.getBoolPref(
WorkspaceUtils.workspacesPreferences
.WORKSPACE_MANAGE_ON_BMS_PREF
WorkspaceUtils.workspacesPreferences.WORKSPACE_MANAGE_ON_BMS_PREF
);

if (manageOnBMSIsEnabled) {
Expand Down Expand Up @@ -1847,6 +1854,289 @@ const startWorkspace = function () {
});
};

const workspacesMigtation = {
async createBackupFileObject() {
// Migration from floorp to Simple Tab Groups.
// Generate Backup file for Simple Tab Groups. This file is can be used for restore Workspaces & Tabs.
// This file is saved in User's personal desktop directory.

// Create backup JSON file.
let backupData = {
version: "5.2",
groups: [],
lastCreatedGroupPosition: 3,
defaultGroupProps: {},
closePopupAfterChangeGroup: true,
closePopupAfterSelectTab: false,
openGroupAfterChange: false,
alwaysAskNewGroupName: true,
createNewGroupWhenOpenNewWindow: false,
openManageGroupsInTab: true,
showConfirmDialogBeforeGroupArchiving: true,
showConfirmDialogBeforeGroupDelete: true,
showNotificationAfterGroupDelete: true,
showContextMenuOnTabs: true,
showContextMenuOnLinks: true,
defaultBookmarksParent: "toolbar_____",
showExtendGroupsPopupWithActiveTabs: false,
showTabsWithThumbnailsInManageGroups: true,
fullPopupWidth: false,
temporaryContainerTitle: "⌚一時的なコンテナー",
contextMenuTab: [
"open-in-new-window",
"reload",
"discard",
"remove",
"update-thumbnail",
"set-group-icon",
"move-tab-to-group",
],
contextMenuGroup: [
"open-in-new-window",
"sort-asc",
"sort-desc",
"discard",
"discard-other",
"export-to-bookmarks",
"unload",
"archive",
"rename",
"reload-all-tabs",
],
autoBackupEnable: true,
autoBackupLastBackupTimeStamp: 1701171548,
autoBackupIntervalKey: "hours",
autoBackupIntervalValue: 3,
autoBackupIncludeTabThumbnails: false,
autoBackupIncludeTabFavIcons: false,
autoBackupFolderName: "STG-backups-FF-115.6.0",
autoBackupByDayIndex: true,
theme: "auto",
hotkeys: [],
pinnedTabs: [],
containers: {},
};

// Get floorp's Workspaces data.
let allWorkspaces = [];
let usedWorkspacesNumber = [];

allWorkspaces = Services.prefs
.getStringPref(WorkspaceUtils.workspacesPreferences.WORKSPACE_ALL_PREF)
.split(",");

for (let i = 0; i < allWorkspaces.length; i++) {
let workspace = allWorkspaces[i];

let workspaceIcon =
workspaceFunctions.iconFunctions.getWorkspaceIcon(workspace);
let workspacesContainerNo =
workspaceFunctions.containerFunctions.getWorkspaceUserContextId(
workspace
);
let workspacesContainerName = "";

if (workspacesContainerNo == 0) {
workspacesContainerName = "firefox-default";
} else {
workspacesContainerName = "firefox-container-" + workspacesContainerNo;

// Add tabContainerName to usedWorkspacesNumber.
if (!usedWorkspacesNumber.includes(workspacesContainerNo)) {
usedWorkspacesNumber.push(workspacesContainerNo);
}
}

let workspaceObj = {
id: i + 1,
title: workspace,
iconColor: "hsla(70, 100%, 50%, 1)",
iconUrl: await getBase64DataFromPng(workspaceIcon),
iconViewType: null,
tabs: [],
isArchive: false,
discardTabsAfterHide: false,
discardExcludeAudioTabs: false,
prependTitleToWindow: false,
exportToBookmarksWhenAutoBackup: false,
leaveBookmarksOfClosedTabs: false,
newTabContainer: workspacesContainerName,
ifDifferentContainerReOpen: false,
excludeContainersForReOpen: [],
isSticky: false,
catchTabContainers: [],
catchTabRules: "",
moveToGroupIfNoneCatchTabRules: null,
muteTabsWhenGroupCloseAndRestoreWhenOpen: false,
showTabAfterMovingItIntoThisGroup: false,
showOnlyActiveTabAfterMovingItIntoThisGroup: false,
showNotificationAfterMovingTabIntoThisGroup: true,
bookmarkId: null,
};

let allTabs = gBrowser.tabs;

for (let i = 0; i < allTabs.length; i++) {
let tab = allTabs[i];
if (tab.getAttribute("floorpWorkspace") == workspace && !tab.pinned) {
let tabTitle = tab.label;
let tabUrl = tab.linkedBrowser.currentURI.spec;
let tabContainerNo = tab.getAttribute("usercontextid");
let tabContainerName = "";
if (tabContainerNo == 0 || tabContainerNo == undefined || tabContainerNo == null) {
tabContainerName = "firefox-default";
} else {
tabContainerName = "firefox-container-" + tabContainerNo;

// Add tabContainerName to usedWorkspacesNumber.
if (!usedWorkspacesNumber.includes(tabContainerNo)) {
usedWorkspacesNumber.push(tabContainerNo);
}
}

let tabObj = {
url: tabUrl,
title: tabTitle,
cookieStoreId: tabContainerName,
id: i,
};

if (tabObj.cookieStoreId == "firefox-default") {
delete tabObj.cookieStoreId;
}

workspaceObj.tabs.push(tabObj);
}
}

// Add workspaceObj to backupData.
backupData.groups.push(workspaceObj);
}

// Pinned tabs
let tabs = gBrowser.tabs;
for (let i = 0; i < tabs.length; i++) {
let tab = tabs[i];
if (tab.pinned) {
let tabTitle = tab.label;
let tabUrl = tab.linkedBrowser.currentURI.spec;
let tabContainerNo = tab.getAttribute("usercontextid");
let tabContainerName = "";
if (tabContainerNo == 0) {
tabContainerName = "firefox-default";
} else {
tabContainerName = "firefox-container-" + tabContainerNo;

// Add tabContainerName to usedWorkspacesNumber.
if (!usedWorkspacesNumber.includes(tabContainerName)) {
usedWorkspacesNumber.push(tabContainerNo);
}
}

let tabObj = {
url: tabUrl,
title: tabTitle,
cookieStoreId: tabContainerName,
id: i,
};

backupData.pinnedTabs.push(tabObj);
}
}

// Containers Object
let { ContextualIdentityService } = ChromeUtils.importESModule(
"resource://gre/modules/ContextualIdentityService.sys.mjs"
);

let containers = ContextualIdentityService.getPublicIdentities();

for (let i = 0; i < usedWorkspacesNumber.length; i++) {
let containerNo = usedWorkspacesNumber[i];
let containerName = "firefox-container-" + containerNo;

for (let j = 0; j < containers.length; j++) {
let container = containers[j];
if (containerNo == container.userContextId) {
let containerObj = {
name: containerName,
color: container.color,
icon: container.icon,
iconUrl: "resource://usercontext-content/" + container.icon + ".svg",
colorCode: container.color,
cookieStoreId: containerName,
};

backupData.containers[containerName] = containerObj;
}
}
}

// Write backupData to JSON file.
// Save backupData to JSON file. This file is can be used for restore Workspaces & Tabs.
// Save to Desktop.
let path = PathUtils.join(
Services.dirsvc.get("Desk", Ci.nsIFile).path,
"floorp-workspace-backup.json"
);
IOUtils.writeJSON(path, backupData);
}
};

async function getBase64DataFromPng(iconURL) {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();

if (iconURL.endsWith(".png")) {
xhr.open("GET", iconURL, true);
xhr.responseType = "arraybuffer";

xhr.onload = function () {
if (xhr.status == 200) {
let imgData = new Uint8Array(xhr.response);
let base64Data = arrayBufferToBase64(imgData);
let imageDataUri = "data:image/png;base64," + base64Data;

resolve(imageDataUri);
} else {
reject(new Error("Failed to fetch PNG image"));
}
};

xhr.send();

function arrayBufferToBase64(buffer) {
var binary = "";
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return btoa(binary);
}
} else {
xhr.open("GET", iconURL, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
let svgData = xhr.responseText;

let base64Data = btoa(svgData);
let imageDataUri = "data:image/svg+xml;base64," + base64Data;

resolve(imageDataUri);
} else {
reject(new Error("Failed to fetch SVG image"));
}
}
};

xhr.send();
}
});
}


// If you want to enable workspaces by default, Remove these lines. "checkTabGroupAddonInstalledAndStartWorkspace();" is enough.
const tempDisabled = "floorp.browser.workspaces.disabledBySystem";
function disableWorkspacesByDefaultCheck() {
Expand Down Expand Up @@ -1875,3 +2165,8 @@ function disableWorkspacesByDefaultCheck() {
}

disableWorkspacesByDefaultCheck();

Services.obs.addObserver(
workspacesMigtation.createBackupFileObject,
"migrationFromFloorpToSTG"
);
Loading

0 comments on commit 2be2c00

Please sign in to comment.