Skip to content

Instantly share code, notes, and snippets.

@Gkjsdll
Last active March 16, 2023 01:47
Show Gist options
  • Save Gkjsdll/b627d77deea71815493977259b8211b8 to your computer and use it in GitHub Desktop.
Save Gkjsdll/b627d77deea71815493977259b8211b8 to your computer and use it in GitHub Desktop.
Adds a link to the top of any OneTab page to open all links in new tabs/windows
// ==UserScript==
// @name OneTab "Open All"
// @namespace http://tampermonkey.net/
// @version 0.6.2
// @description Add "Open All" to OneTab page
// @author Zack (Gkjsdll) Winchell
// @match *://www.one-tab.com/page/*
// @noframes
// @icon https://www.one-tab.com/web/images/favicon/favicon-32x32.png
// @grant GM.getValue
// @grant GM.setValue
// @grant window.close
// ==/UserScript==
(async () => {
'use strict';
let autoClose = GM.getValue('autoClose', false);
const allLinks = document.querySelectorAll('img + a');
const firstLinkParent = allLinks[0].parentElement;
const openAllLinkParent = firstLinkParent.cloneNode(true);
const onAutoCloseChange = (event) => {
autoClose = event.target.checked;
GM.setValue('autoClose');
};
const _openLinks = () => {
const reversedLinks = [...allLinks].reverse();
for (const link of reversedLinks) {
link.rel = 'noopener noreferrer';
window.open(link.href, '_blank');
}
if (autoClose) {
window.close();
}
};
const openLinks = (() => {
let invoked = false;
return () => {
if (invoked) {
return;
}
invoked = true;
_openLinks();
};
})();
const openAllImage = openAllLinkParent.querySelector('img');
openAllImage.src = '/web/images/favicon/favicon-32x32.png';
const openAllLink = openAllLinkParent.querySelector('a');
openAllLink.href = '#';
openAllLink.innerText = 'Open all links in this OneTab';
openAllLink.addEventListener('click', openLinks);
let secondsToAutoOpen = 3;
const autoOpenText = document.createElement('p');
autoOpenText.innerText = `Auto-opening links in ${secondsToAutoOpen} seconds, click here to cancel.`;
autoOpenText.style.marginBottom = '0px';
autoOpenText.style.paddingLeft = '24px';
autoOpenText.style.cursor = 'pointer';
const target = firstLinkParent.parentElement;
target.insertBefore(openAllLinkParent, firstLinkParent);
target.insertBefore(autoOpenText, openAllLinkParent);
const autoCloseRow = document.createElement('div');
autoCloseRow.style.alignItems = 'flex-start';
autoCloseRow.style.display = 'flex';
autoCloseRow.style.gap = '6px';
autoCloseRow.style.paddingLeft = '24px';
const autoCloseCheckbox = document.createElement('input');
autoCloseCheckbox.type = 'checkbox';
autoCloseCheckbox.checked = autoClose;
autoCloseCheckbox.addEventListener('change', onAutoCloseChange);
autoCloseRow.appendChild(autoCloseCheckbox);
const autoCloseLabel = document.createElement('p');
autoCloseLabel.style.marginTop = '0px';
autoCloseLabel.style.padding = '0px';
autoCloseLabel.textContent = 'Auto-close this page after opening links';
autoCloseRow.appendChild(autoCloseLabel);
target.insertBefore(autoCloseRow, openAllLinkParent);
const cancelAutoOpen = () => {
secondsToAutoOpen = -1;
autoOpenText.innerText = 'Auto-open links cancelled.';
autoOpenText.style.cursor = 'initial';
autoOpenText.removeEventListener('click', cancelAutoOpen);
};
const onKeyDown = (keypress) => {
switch (keypress.key) {
case ' ': {
openLinks();
break;
}
}
};
autoOpenText.addEventListener('click', cancelAutoOpen);
document.body.addEventListener('keydown', onKeyDown);
while (secondsToAutoOpen >= 0) {
if (secondsToAutoOpen < 0) {
break;
}
if (secondsToAutoOpen === 0) {
openLinks();
autoOpenText.innerText = 'Opening links now.';
break;
}
autoOpenText.innerText = `Auto-opening links in ${secondsToAutoOpen} seconds, click here to cancel.`;
await new Promise((resolve) => setTimeout(resolve, 1000));
secondsToAutoOpen -= 1;
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment