Skip to content

Instantly share code, notes, and snippets.

@dpschen
Last active April 10, 2024 21:42
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save dpschen/ffcff6d1c6a2f02b85690a5943769b78 to your computer and use it in GitHub Desktop.
Save dpschen/ffcff6d1c6a2f02b85690a5943769b78 to your computer and use it in GitHub Desktop.
Find duplicates links in OneTab
(function findDuplicatesInOnetab() {
const isOneTab = document
.querySelector("title")
?.innerHTML.includes("OneTab"); // cheap OneTab check
if (!isOneTab) {
alert("Run this script in a OneTab tab");
return;
}
const getOneTabLinks = () => [
...document.querySelectorAll("#contentAreaDiv [href]"),
];
const getDuplicateLinks = (links) => {
let linkList = links || getOneTabLinks();
linkList = linkList.map((linkEl) => ({
link: linkEl.getAttribute("href"),
linkEl,
}));
const duplicateLinks = [];
const groupedDuplicates = [];
linkList.forEach(({ link, linkEl }, index) => {
const alreadyFound = duplicateLinks.includes(link);
if (alreadyFound) {
return;
}
const foundDuplicateEls = linkList
.filter(({ link: linkCompare }, indexCompare) => {
const alreadyFound = duplicateLinks.includes(linkCompare);
if (index === indexCompare || alreadyFound || link !== linkCompare) {
return false;
}
return true;
})
.map(({ linkEl }) => linkEl);
if (foundDuplicateEls.length) {
duplicateLinks.push(link);
groupedDuplicates.push({
link,
linkEls: [linkEl, ...foundDuplicateEls],
});
}
});
return groupedDuplicates;
};
const scrollToEl = (el) => {
el.scrollIntoView({ behavior: "smooth", block: "center" });
};
const markLink = (el, text) => {
el.style.backgroundColor = "#DE5918";
el.style.color = "#fff";
if (text) {
const duplicateMarker = document.createElement("span");
duplicateMarker.innerHTML = text;
duplicateMarker.classList.add("duplicate-marker");
duplicateMarker.style.marginRight = "20px";
el.insertAdjacentElement("afterbegin", duplicateMarker);
}
};
const unMarkLinks = (linkEls = getOneTabLinks()) => {
linkEls.forEach((el) => {
el.style.backgroundColor = undefined;
el.style.color = undefined;
const duplicateMarker = el.querySelector(".duplicate-marker");
if (duplicateMarker) duplicateMarker.remove();
});
};
const findDuplicates = (links) => {
unMarkLinks(links);
const groupedDuplicates = getDuplicateLinks(links);
if (!groupedDuplicates.length) {
alert("No Duplicates Found");
} else {
groupedDuplicates.forEach((duplicate, groupIndex) =>
duplicate.linkEls.forEach((el, duplicateIndex) =>
markLink(
el,
`${groupIndex + 1}/${groupedDuplicates.length} | ${
duplicateIndex + 1
}/${duplicate.linkEls.length}`
)
)
);
alert(`${groupedDuplicates.length} Duplicates Found`);
scrollToEl(groupedDuplicates[0].linkEls[0]);
}
};
findDuplicates(getOneTabLinks());
})();
@sychochicken
Copy link

Hello, I've just used this and it worked very well, thank you for your work.

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