Adicionar opção para carregamento delayed (apos n segundos)
This commit is contained in:
+3
-2
@@ -11,6 +11,7 @@
|
|||||||
--accent: #7fff6e;
|
--accent: #7fff6e;
|
||||||
--muted: #6b6b7a;
|
--muted: #6b6b7a;
|
||||||
--text: #e8e8ec;
|
--text: #e8e8ec;
|
||||||
|
--border: #2a2a32;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@@ -22,7 +23,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
gap: 24px;
|
gap: 20px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
border: 1px solid #2a2a32;
|
border: 1px solid var(--border);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
(() => {
|
(() => {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const destUrl = params.get('url');
|
const destUrl = params.get('url');
|
||||||
|
const loadDelay = params.get('load_delay'); // seconds, or null
|
||||||
|
|
||||||
if (!destUrl) {
|
if (!destUrl) {
|
||||||
document.querySelector('.label').textContent = 'No URL provided.';
|
document.querySelector('.label').textContent = 'No URL provided.';
|
||||||
@@ -17,8 +18,14 @@
|
|||||||
function navigate() {
|
function navigate() {
|
||||||
if (navigated) return;
|
if (navigated) return;
|
||||||
navigated = true;
|
navigated = true;
|
||||||
|
if( destUrl.indexOf('chrome://')==0 ) {
|
||||||
|
document.querySelector('.ring').style.display = 'none';
|
||||||
|
document.querySelector('.label').textContent = 'Cant load url';
|
||||||
|
}
|
||||||
|
else {
|
||||||
location.replace(destUrl);
|
location.replace(destUrl);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// "Load now" button — immediate bypass
|
// "Load now" button — immediate bypass
|
||||||
document.getElementById('goNow').addEventListener('click', navigate);
|
document.getElementById('goNow').addEventListener('click', navigate);
|
||||||
@@ -36,4 +43,8 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( loadDelay!=null ) {
|
||||||
|
setTimeout(navigate, loadDelay*1000);
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "URL Launcher",
|
"name": "URL Launcher",
|
||||||
"version": "1.0.1",
|
"version": "1.1.0",
|
||||||
"description": "Paste a list of URLs and open them all as tabs, with optional lazy-load on focus.",
|
"description": "Paste a list of URLs and open them all as tabs, with optional lazy-load on focus.",
|
||||||
"action": {
|
"action": {
|
||||||
"default_popup": "popup.html",
|
"default_popup": "popup.html",
|
||||||
|
|||||||
+31
-1
@@ -305,6 +305,25 @@
|
|||||||
background: rgba(127,255,110,0.1);
|
background: rgba(127,255,110,0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Checkboxes stack ── */
|
||||||
|
.checkboxes {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delay-hint {
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 10px;
|
||||||
|
font-family: 'JetBrains Mono', monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-label.disabled {
|
||||||
|
opacity: 0.35;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* ── Focus mode indicator ── */
|
/* ── Focus mode indicator ── */
|
||||||
.mode-badge {
|
.mode-badge {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
@@ -377,10 +396,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="options">
|
<div class="options">
|
||||||
|
<div class="checkboxes">
|
||||||
<label class="checkbox-label" title="Each URL opens via an intermediate page and only navigates when you focus that tab">
|
<label class="checkbox-label" title="Each URL opens via an intermediate page and only navigates when you focus that tab">
|
||||||
<input type="checkbox" id="lazyLoad" checked />
|
<input type="checkbox" id="lazyLoad" checked />
|
||||||
<span class="custom-checkbox">
|
<span class="custom-checkbox">
|
||||||
<!-- checkmark -->
|
|
||||||
<svg viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M1.5 5L4 7.5L8.5 2.5" stroke="#0d0d0f" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M1.5 5L4 7.5L8.5 2.5" stroke="#0d0d0f" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
</svg>
|
</svg>
|
||||||
@@ -388,6 +407,17 @@
|
|||||||
<span class="checkbox-text">Wait for focus to load</span>
|
<span class="checkbox-text">Wait for focus to load</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<label class="checkbox-label" id="delayedLoadLabel" title="Each tab auto-loads after a staggered timer: 1s, 2s, 3s… Requires 'Wait for focus'">
|
||||||
|
<input type="checkbox" id="delayedLoad" checked />
|
||||||
|
<span class="custom-checkbox">
|
||||||
|
<svg viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M1.5 5L4 7.5L8.5 2.5" stroke="#0d0d0f" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span class="checkbox-text">Delayed load <span class="delay-hint" id="delayHint">(1s, 2s, 3s…)</span></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button class="launch-btn" id="openBtn" disabled>
|
<button class="launch-btn" id="openBtn" disabled>
|
||||||
<svg viewBox="0 0 13 13" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 13 13" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M2 6.5h9M7.5 3l4 3.5-4 3.5" stroke="#0d0d0f" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
<path d="M2 6.5h9M7.5 3l4 3.5-4 3.5" stroke="#0d0d0f" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
(() => {
|
(() => {
|
||||||
const urlInput = document.getElementById('urlInput');
|
const urlInput = document.getElementById('urlInput');
|
||||||
const lazyLoad = document.getElementById('lazyLoad');
|
const lazyLoad = document.getElementById('lazyLoad');
|
||||||
|
const delayedLoad = document.getElementById('delayedLoad');
|
||||||
|
const delayedLoadLabel = document.getElementById('delayedLoadLabel');
|
||||||
const openBtn = document.getElementById('openBtn');
|
const openBtn = document.getElementById('openBtn');
|
||||||
const extractBtn = document.getElementById('extractBtn');
|
const extractBtn = document.getElementById('extractBtn');
|
||||||
const urlCount = document.getElementById('urlCount');
|
const urlCount = document.getElementById('urlCount');
|
||||||
@@ -52,13 +54,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateBadge() {
|
function updateBadge() {
|
||||||
if (lazyLoad.checked) {
|
const isLazy = lazyLoad.checked;
|
||||||
|
const isDelayed = delayedLoad.checked;
|
||||||
|
|
||||||
|
if (isLazy && isDelayed) {
|
||||||
|
modeBadge.textContent = 'lazy + delay';
|
||||||
|
modeBadge.className = 'mode-badge';
|
||||||
|
} else if (isLazy) {
|
||||||
modeBadge.textContent = 'lazy';
|
modeBadge.textContent = 'lazy';
|
||||||
modeBadge.className = 'mode-badge';
|
modeBadge.className = 'mode-badge';
|
||||||
} else {
|
} else {
|
||||||
modeBadge.textContent = 'eager';
|
modeBadge.textContent = 'eager';
|
||||||
modeBadge.className = 'mode-badge off';
|
modeBadge.className = 'mode-badge off';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delayed load only makes sense when lazy is on
|
||||||
|
delayedLoadLabel.classList.toggle('disabled', !isLazy);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Event listeners ────────────────────────────────────────
|
// ── Event listeners ────────────────────────────────────────
|
||||||
@@ -68,6 +79,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
lazyLoad.addEventListener('change', updateBadge);
|
lazyLoad.addEventListener('change', updateBadge);
|
||||||
|
delayedLoad.addEventListener('change', updateBadge);
|
||||||
|
|
||||||
extractBtn.addEventListener('click', () => {
|
extractBtn.addEventListener('click', () => {
|
||||||
const urls = extractURLs(urlInput.value);
|
const urls = extractURLs(urlInput.value);
|
||||||
@@ -92,16 +104,25 @@
|
|||||||
setStatus('');
|
setStatus('');
|
||||||
|
|
||||||
const useLazy = lazyLoad.checked;
|
const useLazy = lazyLoad.checked;
|
||||||
|
const useDelayed = delayedLoad.checked && useLazy;
|
||||||
let opened = 0;
|
let opened = 0;
|
||||||
|
|
||||||
for (const url of urls) {
|
for (let i = 0; i < urls.length; i++) {
|
||||||
|
const url = urls[i];
|
||||||
try {
|
try {
|
||||||
let targetUrl = url;
|
let targetUrl = url;
|
||||||
|
|
||||||
if (useLazy) {
|
if (useLazy) {
|
||||||
// Build the extension loader URL with the target as ?url=…
|
// Build the extension loader URL with the target as ?url=…
|
||||||
const loaderBase = chrome.runtime.getURL('loader.html');
|
const loaderBase = chrome.runtime.getURL('loader.html');
|
||||||
targetUrl = `${loaderBase}?url=${encodeURIComponent(url)}`;
|
const params = new URLSearchParams({ url });
|
||||||
|
|
||||||
|
if (useDelayed) {
|
||||||
|
// 1-based delay: first tab = 1s, second = 2s, …
|
||||||
|
params.set('load_delay', i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
targetUrl = `${loaderBase}?${params.toString()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
await chrome.tabs.create({ url: targetUrl, active: false });
|
await chrome.tabs.create({ url: targetUrl, active: false });
|
||||||
|
|||||||
Reference in New Issue
Block a user