Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save weynhamz/b795a49a1713ef7a59e0cf9cf1fb1225 to your computer and use it in GitHub Desktop.
Save weynhamz/b795a49a1713ef7a59e0cf9cf1fb1225 to your computer and use it in GitHub Desktop.
A nodejs script to transfer a directory of firefox "Session Manager + Tree Style Tabs" sessions to chrome "Tabs Outliner" session tree.
var chSession = {
type: 2000,
node: {
type: 'session'
},
};
var chSavedWin = [
2001,
{
type: 'savedwin',
data: {
type: 'normal'
},
marks: {
relicons: []
}
}
];
var newObj = [];
newObj.push(chSession);
var fs = require('fs');
var ffSessionGroups = {};
var ffSessionL1Weight = 0;
fs.readdirSync('sessions').forEach(file => {
console.log(file);
var ffSession = fs.readFileSync('sessions/' + file, 'utf8');
var ffSessionArr = ffSession.split(/\n|\t|\r/);
// session title and session group title
var ffSessionTitle = null;
var ffSessionGroupTitle = null;
ffSessionArr.forEach(function (element) {
var reg = /^name=(.*)/;
if (reg.test(element)) {
ffSessionTitle = element.replace(reg, '$1');
}
var reg1 = /^group=(.*)/;
if (reg1.test(element)) {
ffSessionGroupTitle = element.replace(reg1, '$1');
}
});
// form a weight array of the current session
var ffSessionWeightArr = [];
// session in the gorup
if (ffSessionGroupTitle) {
if (!ffSessionGroups.hasOwnProperty(ffSessionGroupTitle)) {
// first time encounter this group
ffSessionGroups[ffSessionGroupTitle] = {};
ffSessionGroups[ffSessionGroupTitle]['weight'] = ffSessionL1Weight;
ffSessionGroups[ffSessionGroupTitle]['sessions'] = [];
// create the group item
var sessionGroup = [
2001,
{
type: 'group',
data: {},
marks: {
customTitle: ffSessionGroupTitle,
relicons: []
}
},
[ffSessionL1Weight]
];
newObj.push(sessionGroup);
ffSessionL1Weight++;
}
ffSessionWeightArr.push(ffSessionGroups[ffSessionGroupTitle]['weight']);
ffSessionWeightArr.push(ffSessionGroups[ffSessionGroupTitle]['sessions'].length);
ffSessionGroups[ffSessionGroupTitle]['sessions'].push(file);
}
// session not the gorup
else {
ffSessionWeightArr.push(ffSessionL1Weight);
ffSessionL1Weight++;
}
// process each session as a group
var group = [
2001,
{
type: 'group',
data: {},
marks: {
customTitle: ffSessionTitle,
relicons: []
}
},
ffSessionWeightArr
];
newObj.push(group);
var ffSessionObj = JSON.parse(ffSessionArr[ffSessionArr.length - 1]);
var ffSessionTree = [];
var ffSessionTreeIds = [];
var ffwindowWeight = 0
ffSessionObj.windows.forEach(function (window) {
// create window item
var trail = JSON.parse(JSON.stringify(ffSessionWeightArr));
trail.push(ffwindowWeight);
var savedwin = JSON.parse(JSON.stringify(chSavedWin));
savedwin.push(trail);
newObj.push(savedwin);
window.tabs.forEach(function (tab) {
tab['windowWeight'] = ffwindowWeight;
ffSessionTree[tab['extData']['treestyletab-id']] = tab;
ffSessionTreeIds.push(tab['extData']['treestyletab-id']);
}, this);
ffwindowWeight++;
}, this);
// Get a registry of all the children of a tab
var ffTabChildren = [];
ffSessionTreeIds.forEach(function (tabId) {
var tab = ffSessionTree[tabId];
if (tab['extData']['treestyletab-children']) {
ffTabChildren[tab['extData']['treestyletab-id']] = tab['extData']['treestyletab-children'].split('|');
} else {
ffTabChildren[tab['extData']['treestyletab-id']] = [];
}
}, this);
// Get a registry of the parent and sibling weight mapping of a tab
var ffTabParentAndWeight = {};
ffSessionTreeIds.forEach(function (element) {
var e = ffSessionTree[element];
if (e['extData']['treestyletab-parent'] && ffTabChildren[e['extData']['treestyletab-parent']]) {
ffTabParentAndWeight[e['extData']['treestyletab-id']] = {};
ffTabParentAndWeight[e['extData']['treestyletab-id']]['parent'] = e['extData']['treestyletab-parent'];
ffTabParentAndWeight[e['extData']['treestyletab-id']]['weight'] = ffTabChildren[e['extData']['treestyletab-parent']].findIndex(function (x) {
return x == e['extData']['treestyletab-id'];
});
}
}, this);
// A function to recursively get the trail of the tab weight
function getWeight(tabId, tabTrail) {
if (ffTabParentAndWeight.hasOwnProperty(tabId)) {
getWeight(ffTabParentAndWeight[tabId]['parent'], tabTrail);
tabTrail.push(ffTabParentAndWeight[tabId]['weight']);
} else {
tabTrail.push(0);
}
}
ffSessionTreeIds.forEach(function (tabId) {
var tab = ffSessionTree[tabId];
if (tab['entries'].length == 0) {
return;
}
var tabWeightArr = JSON.parse(JSON.stringify(ffSessionWeightArr));
tabWeightArr.push(tab.windowWeight);
getWeight(tabId, tabWeightArr);
var data = {};
data['active'] = true;
data['audible'] = false;
data['favIconUrl'] = tab['attributes']['image'];
data['title'] = tab['entries'][0]['title'];
data['url'] = tab['entries'][0]['url']
var savedTab = [];
savedTab.push(2001);
savedTab.push({data: data});
savedTab.push(tabWeightArr);
newObj.push(savedTab);
});
});
var json = JSON.stringify(newObj);
fs.writeFile('migrated-firefox-session-manager-session.tree', json, 'utf8');
@weynhamz
Copy link
Author

Just put this script besides Session Manager's sessions folder in your Firefox profile directory, then run with 'node firefox-session-manager-to-chrome-tabs-outliner.js', at the end you will see migrated-firefox-session-manager-session.tree file, then import it using Chrome 'Tabs Outliner' import feature (Paid Only).

Attention: This script currently only supports sessions saved Firefox Session Manager extension with 'Tree Style Tabs' extension enabled, it can be altered to work without the need of 'Tree Style Tabs' extension, but that's another story.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment