Created
September 20, 2021 11:11
-
-
Save Luckz/74cdd60a795e72f677c0db5c660a4922 to your computer and use it in GitHub Desktop.
Tabs Outliner: kill duplicate windows
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ctrl - shift - J on Tabs Outliner to open dev tools, | |
// then Sources -> Snippets -> New Snippet. | |
// Rightclick -> Run to execute. | |
// cyrb53 stolen from https://stackoverflow.com/a/52171480 | |
const cyrb53 = function(str, seed = 0) { | |
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed; | |
for (let i = 0, ch; i < str.length; i++) { | |
ch = str.charCodeAt(i); | |
h1 = Math.imul(h1 ^ ch, 2654435761); | |
h2 = Math.imul(h2 ^ ch, 1597334677); | |
} | |
h1 = Math.imul(h1 ^ (h1>>>16), 2246822507) ^ Math.imul(h2 ^ (h2>>>13), 3266489909); | |
h2 = Math.imul(h2 ^ (h2>>>16), 2246822507) ^ Math.imul(h1 ^ (h1>>>13), 3266489909); | |
return 4294967296 * (2097151 & h2) + (h1>>>0); | |
}; | |
function nodeterate(currentNode, stringBuilder) { | |
if (currentNode.type == "separatorline") stringBuilder.push("separatorline"); | |
else if (currentNode.type == "textnote") stringBuilder.push(`textnote ${currentNode?.persistentData?.note}`); | |
else if (currentNode.type == "win" || currentNode.type == "savedwin") stringBuilder.push("window"); | |
else stringBuilder.push(currentNode.getHref()); | |
for (const sn of currentNode.subnodes) { | |
nodeterate(sn, stringBuilder); | |
} | |
} | |
function nukeNodeArray(nodeArray) { | |
const DUMMY = false; | |
for (const currentNode of nodeArray) { | |
if (currentNode.type !== "win" && currentNode.type !== "savedwin") { | |
console.log("this node should not have almost died:"); | |
console.log(currentNode); | |
continue; | |
} | |
if (DUMMY) { | |
console.log("would now kill:"); | |
console.log(currentNode); | |
} else { | |
console.log("removing node:"); | |
console.log(currentNode); | |
currentNode.removeOwnTreeFromParent(); | |
} | |
} | |
} | |
function killDupes(killActive = false) { | |
let dupes = {}; | |
for (const nod of treeView.treeModel.currentSession_rootNode.subnodes) { // only check root level nodes, don't do complex recursive checks for "sub-roots" | |
const strbld = []; | |
nodeterate(nod, strbld); | |
const hash = cyrb53(strbld.join()); | |
if (dupes.hasOwnProperty(hash)) dupes[hash].push(nod); | |
else dupes[hash] = [nod]; | |
} | |
for (const duperino of Object.values(dupes)) { | |
if (duperino.length < 2) continue; | |
const inactiveNodes = duperino.filter(x => x.type !== "win"); // keep loaded window(s) alive | |
if (inactiveNodes.length < duperino.length) { | |
if ((duperino.length - inactiveNodes.length) > 1) { | |
console.log("WARNING: duplicate active windows ->"); | |
for (const loadedWindow of duperino.filter(x => x.type == "win")) console.log(loadedWindow); | |
} | |
nukeNodeArray(inactiveNodes); | |
if (killActive) nukeNodeArray(duperino.filter(x => x.type == "win").slice(1)); | |
} | |
else { // keep oldest | |
nukeNodeArray(duperino.slice(1)); | |
} | |
} | |
} | |
killDupes(); | |
// to also prune duplicate *loaded* windows down to a single one, try: killDupes(true); | |
// note that this will disregard how many subnodes are loaded! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
var NodeTypesEnum = {TAB:"tab", SAVEDTAB:"savedtab", WAITINGTAB:"waitingtab", ATTACHWAITINGTAB:"attachwaitingtab", WINDOW:"win", SAVEDWINDOW:"savedwin", WAITINGWINDOW:"waitingwin", SESSION:"session", TEXTNOTE:"textnote", SEPARATORLINE:"separatorline", GROUP:"group"};
relevant types seem to be tab, savedtab, win, savedwin, and perhaps separatorline and textnote. I guess the root node could be session, groups are actually win/savedwin and not group, and IDK what the three waiting ones are.