Neu: DoubleDouble Tools
This commit is contained in:
19
README.md
19
README.md
@@ -310,6 +310,25 @@ Stellt die Navigation-Links für "Abos" und "Verlauf" in der YouTube-Sidebar wie
|
||||
|
||||
---
|
||||
|
||||
### 17. `doubledouble-tools.user.js`
|
||||
**[Installieren](https://git.ponywave.de/Akamaru/Userscripts/raw/branch/master/doubledouble-tools.user.js)**
|
||||
|
||||
**Beschreibung:**
|
||||
Erweiterte Einstellungen und Features für DoubleDouble Music Downloader (doubledouble.top). Bietet eine zentrale Settings-Verwaltung und verhindert automatische Downloads.
|
||||
|
||||
**Funktionen:**
|
||||
- Settings-Icon (⚙️) oben rechts öffnet Modal mit allen Einstellungen
|
||||
- **Funktionale Settings:** Upload to external service (pixeldrain/litterbox/sendcm), Hide my download, Spotify Format (OGG/MP3), Add metadata
|
||||
- **Kosmetische Settings:** Hide QQDL notice, Hide "Recently Downloaded" (blockiert auch `/recent` Requests), Hide Footer
|
||||
- **Server-Wahl:** Auto-Redirect von doubledouble.top zu EU/US Server
|
||||
- **Download-Link anzeigen:** Zeigt Modal mit Download-Link statt Auto-Download
|
||||
- Modal mit drei Buttons: "Download Now", "Copy Link" (kopiert URL), "Close"
|
||||
- Alle Einstellungen werden automatisch auf die Seiten-Checkboxen angewendet
|
||||
- Persistent gespeichert mit GM_getValue/GM_setValue
|
||||
- Injection in Page Context für zuverlässige window.open Interception
|
||||
|
||||
---
|
||||
|
||||
## Übersicht der enthaltenen UserStyles
|
||||
|
||||
### 1. `myanimelist-tweaks.user.css`
|
||||
|
||||
594
doubledouble-tools.user.js
Normal file
594
doubledouble-tools.user.js
Normal file
@@ -0,0 +1,594 @@
|
||||
// ==UserScript==
|
||||
// @name DoubleDouble Tools
|
||||
// @namespace https://git.ponywave.de/Akamaru/Userscripts
|
||||
// @version 1.0
|
||||
// @description Enhanced settings and features for DoubleDouble music downloader
|
||||
// @author Akamaru
|
||||
// @match https://doubledouble.top/*
|
||||
// @match https://eu.doubledouble.top/*
|
||||
// @match https://us.doubledouble.top/*
|
||||
// @icon https://www.google.com/s2/favicons?domain=eu.doubledouble.top&sz=32
|
||||
// @grant GM_getValue
|
||||
// @grant GM_setValue
|
||||
// @grant GM_addStyle
|
||||
// @grant GM_setClipboard
|
||||
// @run-at document-start
|
||||
// @updateURL https://git.ponywave.de/Akamaru/Userscripts/raw/branch/master/doubledouble-tools.user.js
|
||||
// @downloadURL https://git.ponywave.de/Akamaru/Userscripts/raw/branch/master/doubledouble-tools.user.js
|
||||
// ==/UserScript==
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
console.log('[DoubleDouble Tools] Script loaded');
|
||||
|
||||
// Default settings
|
||||
const DEFAULT_SETTINGS = {
|
||||
uploadExternal: true,
|
||||
uploadService: 'pdrain',
|
||||
hideDownload: false,
|
||||
spotifyFormat: 'ogg',
|
||||
spotifyMetadata: true,
|
||||
hideQQDL: false,
|
||||
hideRecent: false,
|
||||
hideFooter: false,
|
||||
serverChoice: 'auto', // 'auto', 'eu', 'us'
|
||||
showDownloadLink: false
|
||||
};
|
||||
|
||||
// Settings management
|
||||
function getSettings() {
|
||||
try {
|
||||
const stored = GM_getValue('doubledouble_settings', '{}');
|
||||
const settings = JSON.parse(stored);
|
||||
return { ...DEFAULT_SETTINGS, ...settings };
|
||||
} catch (e) {
|
||||
console.error('[DoubleDouble Tools] Error loading settings:', e);
|
||||
return DEFAULT_SETTINGS;
|
||||
}
|
||||
}
|
||||
|
||||
function saveSettings(settings) {
|
||||
GM_setValue('doubledouble_settings', JSON.stringify(settings));
|
||||
}
|
||||
|
||||
// Apply cosmetic settings (CSS)
|
||||
function applyCosmetics(settings) {
|
||||
let css = '';
|
||||
|
||||
if (settings.hideQQDL) {
|
||||
css += '.lucida-link { display: none !important; }\n';
|
||||
}
|
||||
|
||||
if (settings.hideRecent) {
|
||||
css += '#recently-downloaded { display: none !important; }\n';
|
||||
}
|
||||
|
||||
if (settings.hideFooter) {
|
||||
css += '.footer { display: none !important; }\n';
|
||||
}
|
||||
|
||||
// Settings icon styles
|
||||
css += `
|
||||
#dd-tools-settings-icon {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
z-index: 10000;
|
||||
background: #333;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
#dd-tools-settings-icon:hover {
|
||||
background: #555;
|
||||
}
|
||||
|
||||
#dd-tools-modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.7);
|
||||
z-index: 10001;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#dd-tools-modal.active {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#dd-tools-modal-content {
|
||||
background: #1a1a1a;
|
||||
color: white;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
max-width: 500px;
|
||||
width: 90%;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
#dd-tools-modal h2 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 20px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.dd-tools-section {
|
||||
margin-bottom: 25px;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid #333;
|
||||
}
|
||||
|
||||
.dd-tools-section:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.dd-tools-section h3 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 15px;
|
||||
font-size: 16px;
|
||||
color: #aaa;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.dd-tools-option {
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.dd-tools-option label {
|
||||
flex: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dd-tools-option input[type="checkbox"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dd-tools-option select {
|
||||
background: #333;
|
||||
color: white;
|
||||
border: 1px solid #555;
|
||||
border-radius: 4px;
|
||||
padding: 5px 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#dd-tools-close {
|
||||
background: #d9534f;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
padding: 10px 20px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
margin-top: 20px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
#dd-tools-close:hover {
|
||||
background: #c9302c;
|
||||
}
|
||||
|
||||
#dd-tools-download-link-display {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: #1a1a1a;
|
||||
color: white;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
z-index: 10002;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.5);
|
||||
min-width: 400px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#dd-tools-download-link-display.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#dd-tools-download-link-display h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#dd-tools-download-link-display input {
|
||||
width: 100%;
|
||||
background: #333;
|
||||
color: white;
|
||||
border: 1px solid #555;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
margin: 10px 0;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
#dd-tools-download-link-display button {
|
||||
background: #5cb85c;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
padding: 10px 20px;
|
||||
cursor: pointer;
|
||||
margin-right: 10px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
#dd-tools-download-link-display button:hover {
|
||||
background: #449d44;
|
||||
}
|
||||
|
||||
#dd-tools-copy-link {
|
||||
background: #f0ad4e !important;
|
||||
}
|
||||
|
||||
#dd-tools-copy-link:hover {
|
||||
background: #ec971f !important;
|
||||
}
|
||||
|
||||
#dd-tools-download-link-display button.secondary {
|
||||
background: #777;
|
||||
}
|
||||
|
||||
#dd-tools-download-link-display button.secondary:hover {
|
||||
background: #555;
|
||||
}
|
||||
`;
|
||||
|
||||
GM_addStyle(css);
|
||||
}
|
||||
|
||||
// Server redirect
|
||||
function handleServerRedirect(settings) {
|
||||
if (window.location.hostname === 'doubledouble.top' && settings.serverChoice !== 'auto') {
|
||||
const newUrl = window.location.href.replace('doubledouble.top', `${settings.serverChoice}.doubledouble.top`);
|
||||
window.location.href = newUrl;
|
||||
}
|
||||
}
|
||||
|
||||
// Block /recent requests
|
||||
function blockRecentRequests(settings) {
|
||||
if (!settings.hideRecent) return;
|
||||
|
||||
// Intercept fetch
|
||||
const originalFetch = window.fetch;
|
||||
window.fetch = function(...args) {
|
||||
const url = args[0];
|
||||
if (typeof url === 'string' && url.includes('/recent')) {
|
||||
console.log('[DoubleDouble Tools] Blocked fetch to /recent');
|
||||
return Promise.resolve(new Response('[]', {
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
}));
|
||||
}
|
||||
return originalFetch.apply(this, args);
|
||||
};
|
||||
|
||||
// Intercept XMLHttpRequest
|
||||
const originalOpen = XMLHttpRequest.prototype.open;
|
||||
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
|
||||
if (typeof url === 'string' && url.includes('/recent')) {
|
||||
console.log('[DoubleDouble Tools] Blocked XMLHttpRequest to /recent');
|
||||
// Replace with dummy request
|
||||
return originalOpen.call(this, method, 'data:text/plain,[]', ...rest);
|
||||
}
|
||||
return originalOpen.call(this, method, url, ...rest);
|
||||
};
|
||||
}
|
||||
|
||||
// Inject download interceptor into page context
|
||||
function interceptDownloads(settings) {
|
||||
if (!settings.showDownloadLink) return;
|
||||
|
||||
const injectScript = () => {
|
||||
const script = document.createElement('script');
|
||||
script.textContent = `
|
||||
(function() {
|
||||
console.log('[DoubleDouble Tools] Injecting window.open interceptor into page context');
|
||||
|
||||
const originalWindowOpen = window.open;
|
||||
let isIntercepting = false;
|
||||
|
||||
window.open = function(url, target, ...rest) {
|
||||
console.log('[DoubleDouble Tools] window.open called:', url, target);
|
||||
|
||||
// Check if this is a download from statusHandoff (target="_self" and url starts with ./)
|
||||
if (!isIntercepting && target === '_self' && typeof url === 'string' && url.startsWith('./')) {
|
||||
console.log('[DoubleDouble Tools] Intercepted download:', url);
|
||||
isIntercepting = true;
|
||||
|
||||
// Dispatch custom event to show modal
|
||||
const fullUrl = new URL(url, window.location.href).href;
|
||||
window.dispatchEvent(new CustomEvent('dd-tools-show-download', { detail: fullUrl }));
|
||||
|
||||
setTimeout(() => { isIntercepting = false; }, 100);
|
||||
return null;
|
||||
}
|
||||
|
||||
return originalWindowOpen.call(this, url, target, ...rest);
|
||||
};
|
||||
|
||||
console.log('[DoubleDouble Tools] window.open interceptor installed');
|
||||
})();
|
||||
`;
|
||||
|
||||
(document.head || document.documentElement).appendChild(script);
|
||||
script.remove();
|
||||
};
|
||||
|
||||
// Inject immediately or wait for head to exist
|
||||
if (document.head || document.documentElement) {
|
||||
injectScript();
|
||||
} else {
|
||||
const observer = new MutationObserver(() => {
|
||||
if (document.head || document.documentElement) {
|
||||
injectScript();
|
||||
observer.disconnect();
|
||||
}
|
||||
});
|
||||
observer.observe(document, { childList: true, subtree: true });
|
||||
}
|
||||
|
||||
// Listen for the custom event to show the modal
|
||||
window.addEventListener('dd-tools-show-download', (e) => {
|
||||
console.log('[DoubleDouble Tools] Showing download modal for:', e.detail);
|
||||
showDownloadLinkModal(e.detail);
|
||||
});
|
||||
}
|
||||
|
||||
// Show download link modal
|
||||
function showDownloadLinkModal(url) {
|
||||
const modal = document.getElementById('dd-tools-download-link-display');
|
||||
const input = document.getElementById('dd-tools-download-url-input');
|
||||
|
||||
const fullUrl = new URL(url, window.location.href).href;
|
||||
input.value = fullUrl;
|
||||
modal.classList.add('active');
|
||||
}
|
||||
|
||||
// Copy link to clipboard
|
||||
function copyLinkToClipboard(url) {
|
||||
GM_setClipboard(url);
|
||||
|
||||
// Visual feedback
|
||||
const button = document.getElementById('dd-tools-copy-link');
|
||||
const originalText = button.textContent;
|
||||
button.textContent = 'Copied!';
|
||||
button.style.background = '#5cb85c';
|
||||
|
||||
setTimeout(() => {
|
||||
button.textContent = originalText;
|
||||
button.style.background = '';
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// Apply functional settings to page controls
|
||||
function applyFunctionalSettings(settings) {
|
||||
const externalCheckbox = document.getElementById('external');
|
||||
const siteSelect = document.getElementById('site');
|
||||
const privateCheckbox = document.getElementById('private');
|
||||
const formatSelect = document.getElementById('format');
|
||||
const metadataCheckbox = document.getElementById('metadata');
|
||||
|
||||
if (externalCheckbox) externalCheckbox.checked = settings.uploadExternal;
|
||||
if (siteSelect) siteSelect.value = settings.uploadService;
|
||||
if (privateCheckbox) privateCheckbox.checked = settings.hideDownload;
|
||||
if (formatSelect) formatSelect.value = settings.spotifyFormat;
|
||||
if (metadataCheckbox) metadataCheckbox.checked = settings.spotifyMetadata;
|
||||
}
|
||||
|
||||
// Create settings UI
|
||||
function createSettingsUI() {
|
||||
const settings = getSettings();
|
||||
|
||||
// Settings icon
|
||||
const icon = document.createElement('button');
|
||||
icon.id = 'dd-tools-settings-icon';
|
||||
icon.innerHTML = '⚙️';
|
||||
icon.title = 'DoubleDouble Tools Settings';
|
||||
icon.addEventListener('click', () => {
|
||||
document.getElementById('dd-tools-modal').classList.add('active');
|
||||
});
|
||||
document.body.appendChild(icon);
|
||||
|
||||
// Settings modal
|
||||
const modal = document.createElement('div');
|
||||
modal.id = 'dd-tools-modal';
|
||||
modal.innerHTML = `
|
||||
<div id="dd-tools-modal-content">
|
||||
<h2>DoubleDouble Tools Settings</h2>
|
||||
|
||||
<div class="dd-tools-section">
|
||||
<h3>Functional Settings</h3>
|
||||
|
||||
<div class="dd-tools-option">
|
||||
<input type="checkbox" id="dd-setting-upload-external" ${settings.uploadExternal ? 'checked' : ''}>
|
||||
<label for="dd-setting-upload-external">Upload to external service</label>
|
||||
</div>
|
||||
|
||||
<div class="dd-tools-option">
|
||||
<label for="dd-setting-upload-service">Upload service:</label>
|
||||
<select id="dd-setting-upload-service">
|
||||
<option value="pdrain" ${settings.uploadService === 'pdrain' ? 'selected' : ''}>pixeldrain.com</option>
|
||||
<option value="litterbox" ${settings.uploadService === 'litterbox' ? 'selected' : ''}>litterbox.catbox.moe</option>
|
||||
<option value="sendcm" ${settings.uploadService === 'sendcm' ? 'selected' : ''}>send.cm</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="dd-tools-option">
|
||||
<input type="checkbox" id="dd-setting-hide-download" ${settings.hideDownload ? 'checked' : ''}>
|
||||
<label for="dd-setting-hide-download">Hide my download from "Recently Downloaded"</label>
|
||||
</div>
|
||||
|
||||
<div class="dd-tools-option">
|
||||
<label for="dd-setting-spotify-format">Spotify format:</label>
|
||||
<select id="dd-setting-spotify-format">
|
||||
<option value="ogg" ${settings.spotifyFormat === 'ogg' ? 'selected' : ''}>OGG 320kbps</option>
|
||||
<option value="mp3" ${settings.spotifyFormat === 'mp3' ? 'selected' : ''}>MP3 320kbps</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="dd-tools-option">
|
||||
<input type="checkbox" id="dd-setting-spotify-metadata" ${settings.spotifyMetadata ? 'checked' : ''}>
|
||||
<label for="dd-setting-spotify-metadata">Add metadata (Spotify)</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dd-tools-section">
|
||||
<h3>Cosmetic Settings</h3>
|
||||
|
||||
<div class="dd-tools-option">
|
||||
<input type="checkbox" id="dd-setting-hide-qqdl" ${settings.hideQQDL ? 'checked' : ''}>
|
||||
<label for="dd-setting-hide-qqdl">Hide QQDL notice</label>
|
||||
</div>
|
||||
|
||||
<div class="dd-tools-option">
|
||||
<input type="checkbox" id="dd-setting-hide-recent" ${settings.hideRecent ? 'checked' : ''}>
|
||||
<label for="dd-setting-hide-recent">Hide "Recently Downloaded" (blocks requests)</label>
|
||||
</div>
|
||||
|
||||
<div class="dd-tools-option">
|
||||
<input type="checkbox" id="dd-setting-hide-footer" ${settings.hideFooter ? 'checked' : ''}>
|
||||
<label for="dd-setting-hide-footer">Hide footer</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dd-tools-section">
|
||||
<h3>Advanced Settings</h3>
|
||||
|
||||
<div class="dd-tools-option">
|
||||
<label for="dd-setting-server-choice">Server choice:</label>
|
||||
<select id="dd-setting-server-choice">
|
||||
<option value="auto" ${settings.serverChoice === 'auto' ? 'selected' : ''}>Auto (no redirect)</option>
|
||||
<option value="eu" ${settings.serverChoice === 'eu' ? 'selected' : ''}>EU Server</option>
|
||||
<option value="us" ${settings.serverChoice === 'us' ? 'selected' : ''}>US Server</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="dd-tools-option">
|
||||
<input type="checkbox" id="dd-setting-show-download-link" ${settings.showDownloadLink ? 'checked' : ''}>
|
||||
<label for="dd-setting-show-download-link">Show download link instead of auto-download</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button id="dd-tools-close">Close & Save</button>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(modal);
|
||||
|
||||
// Close modal on background click
|
||||
modal.addEventListener('click', (e) => {
|
||||
if (e.target === modal) {
|
||||
saveSettingsFromUI();
|
||||
modal.classList.remove('active');
|
||||
}
|
||||
});
|
||||
|
||||
// Close button
|
||||
document.getElementById('dd-tools-close').addEventListener('click', () => {
|
||||
saveSettingsFromUI();
|
||||
modal.classList.remove('active');
|
||||
// Reload to apply settings
|
||||
location.reload();
|
||||
});
|
||||
|
||||
// Download link display modal
|
||||
const downloadModal = document.createElement('div');
|
||||
downloadModal.id = 'dd-tools-download-link-display';
|
||||
downloadModal.innerHTML = `
|
||||
<h3>Download Ready</h3>
|
||||
<p>Your download link:</p>
|
||||
<input type="text" id="dd-tools-download-url-input" readonly>
|
||||
<div>
|
||||
<button id="dd-tools-download-now">Download Now</button>
|
||||
<button id="dd-tools-copy-link">Copy Link</button>
|
||||
<button id="dd-tools-download-close" class="secondary">Close</button>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(downloadModal);
|
||||
|
||||
// Download button
|
||||
document.getElementById('dd-tools-download-now').addEventListener('click', () => {
|
||||
const url = document.getElementById('dd-tools-download-url-input').value;
|
||||
window.location.href = url;
|
||||
downloadModal.classList.remove('active');
|
||||
});
|
||||
|
||||
// Copy link button
|
||||
document.getElementById('dd-tools-copy-link').addEventListener('click', () => {
|
||||
const url = document.getElementById('dd-tools-download-url-input').value;
|
||||
copyLinkToClipboard(url);
|
||||
});
|
||||
|
||||
// Close download modal
|
||||
document.getElementById('dd-tools-download-close').addEventListener('click', () => {
|
||||
downloadModal.classList.remove('active');
|
||||
});
|
||||
}
|
||||
|
||||
// Save settings from UI
|
||||
function saveSettingsFromUI() {
|
||||
const newSettings = {
|
||||
uploadExternal: document.getElementById('dd-setting-upload-external').checked,
|
||||
uploadService: document.getElementById('dd-setting-upload-service').value,
|
||||
hideDownload: document.getElementById('dd-setting-hide-download').checked,
|
||||
spotifyFormat: document.getElementById('dd-setting-spotify-format').value,
|
||||
spotifyMetadata: document.getElementById('dd-setting-spotify-metadata').checked,
|
||||
hideQQDL: document.getElementById('dd-setting-hide-qqdl').checked,
|
||||
hideRecent: document.getElementById('dd-setting-hide-recent').checked,
|
||||
hideFooter: document.getElementById('dd-setting-hide-footer').checked,
|
||||
serverChoice: document.getElementById('dd-setting-server-choice').value,
|
||||
showDownloadLink: document.getElementById('dd-setting-show-download-link').checked
|
||||
};
|
||||
saveSettings(newSettings);
|
||||
}
|
||||
|
||||
// Initialize
|
||||
function init() {
|
||||
try {
|
||||
const settings = getSettings();
|
||||
|
||||
// Apply settings that need to run early (before DOM is ready)
|
||||
handleServerRedirect(settings);
|
||||
blockRecentRequests(settings);
|
||||
interceptDownloads(settings);
|
||||
applyCosmetics(settings);
|
||||
|
||||
// Wait for DOM to be ready before creating UI
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
try {
|
||||
createSettingsUI();
|
||||
applyFunctionalSettings(settings);
|
||||
} catch (e) {
|
||||
console.error('[DoubleDouble Tools] Error creating UI:', e);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
createSettingsUI();
|
||||
applyFunctionalSettings(settings);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[DoubleDouble Tools] Error during initialization:', e);
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
})();
|
||||
Reference in New Issue
Block a user