diff options
author | elioat <elioat@tilde.institute> | 2025-03-15 23:06:25 -0400 |
---|---|---|
committer | elioat <elioat@tilde.institute> | 2025-03-15 23:06:25 -0400 |
commit | bcefc8e807950bf536c13e8b58fa39c65e3b7e8e (patch) | |
tree | 333187bfcdf39483904ea205b9776ee9cb0ac78b | |
parent | a78e5d4db2d220b0f19280c4723539d9c1d564c0 (diff) | |
download | tour-bcefc8e807950bf536c13e8b58fa39c65e3b7e8e.tar.gz |
*
-rw-r--r-- | html/immoral/bookmarklet.js | 203 |
1 files changed, 164 insertions, 39 deletions
diff --git a/html/immoral/bookmarklet.js b/html/immoral/bookmarklet.js index a7b929b..5f79370 100644 --- a/html/immoral/bookmarklet.js +++ b/html/immoral/bookmarklet.js @@ -6,23 +6,77 @@ } window.immoralFontVacuum = true; + // Create a logging collector + const logCollector = { + logs: [], + group: function(label) { + this.logs.push(`\n### ${label}`); + }, + groupEnd: function() { + this.logs.push(`### End Group\n`); + }, + log: function(...args) { + this.logs.push(args.map(arg => + typeof arg === 'object' ? JSON.stringify(arg, null, 2) : arg + ).join(' ')); + }, + warn: function(...args) { + this.logs.push(`⚠️ ${args.map(arg => + typeof arg === 'object' ? JSON.stringify(arg, null, 2) : arg + ).join(' ')}`); + }, + error: function(...args) { + this.logs.push(`❌ ${args.map(arg => + typeof arg === 'object' ? JSON.stringify(arg, null, 2) : arg + ).join(' ')}`); + }, + getReport: function() { + return `Font Vacuum Report +================== +Time: ${new Date().toISOString()} +URL: ${window.location.href} + +${this.logs.join('\n')}`; + } + }; + + // Create an isolated container for our styles + const styleRoot = document.createElement('div'); + styleRoot.className = 'fv-root'; + styleRoot.style.all = 'initial'; // Reset all styles + const style = document.createElement('style'); style.textContent = ` + .fv-root { + font: 16px system-ui, -apple-system, sans-serif; + color: #333333; + line-height: 1.4; + box-sizing: border-box; + } + + .fv-root * { + box-sizing: inherit; + font-family: inherit; + line-height: inherit; + color: inherit; + } + .fv-container { position: fixed; top: 20px; right: 20px; width: 400px; max-height: 90vh; - color: #333333; background: #f5f5f5; border: 2px solid #333; border-radius: 8px; z-index: 999999; overflow-y: auto; - font-family: system-ui, -apple-system, sans-serif; box-shadow: 0 4px 12px rgba(0,0,0,0.15); + display: flex; + flex-direction: column; } + .fv-header { padding: 1rem; background: #333333; @@ -31,7 +85,10 @@ justify-content: space-between; align-items: center; cursor: move; + user-select: none; + flex-shrink: 0; } + .fv-close { background: none; border: none; @@ -39,21 +96,66 @@ cursor: pointer; font-size: 1.5rem; padding: 0; + margin: 0; } + .fv-content { padding: 1rem; + overflow-y: auto; + flex-grow: 1; + } + + .fv-footer { + padding: 0.75rem 1rem; + background: #333333; + color: #f5f5f5; + display: flex; + justify-content: flex-end; + align-items: center; + flex-shrink: 0; + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + } + + .fv-footer-button { + background: #555; + color: #f5f5f5; + border: none; + padding: 0.5rem 1rem; + border-radius: 4px; + cursor: pointer; + font-size: 0.9em; + display: flex; + align-items: center; + gap: 0.5rem; } + + .fv-footer-button:hover { + background: #666; + } + .fv-font-item { margin-bottom: 1rem; padding: 1rem; border: 1px solid #ddd; border-radius: 4px; + background: #ffffff; } + + .fv-font-item h3 { + margin: 0 0 1rem 0; + padding: 0; + font-size: 1.1em; + font-weight: 600; + } + .fv-preview { margin: 1rem 0; padding: 1rem; border: 1px dashed #333; + background: #ffffff; } + .fv-button { background: #333; color: #f5f5f5; @@ -62,19 +164,24 @@ border-radius: 4px; cursor: pointer; margin: 0.25rem 0.5rem 0.25rem 0; + font-size: 0.9em; } + .fv-button:last-child { margin-right: 0; } + .fv-button:hover { background: #444; } `; - document.head.appendChild(style); + styleRoot.appendChild(style); + document.body.appendChild(styleRoot); // Create UI container const container = document.createElement('div'); container.className = 'fv-container'; + styleRoot.appendChild(container); // Make the container draggable let isDragging = false; @@ -123,7 +230,7 @@ // Add close button functionality header.querySelector('.fv-close').addEventListener('click', () => { - document.body.removeChild(container); + document.body.removeChild(styleRoot); window.immoralFontVacuum = false; }); @@ -193,17 +300,16 @@ // Function to find all fonts on the page function findFonts() { const fonts = new Map(); - console.group('Font Vacuum: Scanning Stylesheets'); + logCollector.group('Font Vacuum: Scanning Stylesheets'); - // Log total number of stylesheets - console.log(`Found ${document.styleSheets.length} stylesheets`); + logCollector.log(`Found ${document.styleSheets.length} stylesheets`); for (const sheet of document.styleSheets) { try { const baseUrl = sheet.href; - console.group(`Stylesheet: ${baseUrl || 'inline'}`); + logCollector.group(`Stylesheet: ${baseUrl || 'inline'}`); const cssRules = sheet.cssRules || sheet.rules; - console.log(`- Rules found: ${cssRules.length}`); + logCollector.log(`- Rules found: ${cssRules.length}`); let cssText = ''; let fontFaceCount = 0; @@ -213,12 +319,12 @@ } cssText += rule.cssText + '\n'; } - console.log(`- @font-face rules found: ${fontFaceCount}`); + logCollector.log(`- @font-face rules found: ${fontFaceCount}`); const fontUrls = extractFontUrls(cssText, baseUrl); - console.log(`- Font URLs extracted: ${fontUrls.length}`); + logCollector.log(`- Font URLs extracted: ${fontUrls.length}`); fontUrls.forEach(font => { - console.log(` • ${font.family}: ${font.url}`); + logCollector.log(` • ${font.family}: ${font.url}`); if (!fonts.has(font.family)) { fonts.set(font.family, { variants: [], @@ -227,10 +333,10 @@ } fonts.get(font.family).variants.push(font); }); - console.groupEnd(); + logCollector.groupEnd(); } catch (e) { - console.warn(`Could not access stylesheet:`, sheet.href, e); - console.groupEnd(); + logCollector.warn(`Could not access stylesheet:`, sheet.href, e); + logCollector.groupEnd(); } } @@ -240,7 +346,7 @@ cssRule: data.cssRule })); - console.log('Final Results:', { + logCollector.log('Final Results:', { totalFamilies: results.length, families: results.map(f => ({ family: f.family, @@ -248,17 +354,17 @@ urls: f.variants.map(v => v.url) })) }); - console.groupEnd(); + logCollector.groupEnd(); return results; } async function downloadFont(url, filename) { try { - console.group(`Font Vacuum: Downloading ${filename} from ${url}`); + logCollector.group(`Font Vacuum: Downloading ${filename} from ${url}`); // Try to get the font from an already loaded stylesheet first - console.log('Searching for existing font-face rule...'); + logCollector.log('Searching for existing font-face rule...'); const existingFontRule = Array.from(document.styleSheets) .flatMap(sheet => { try { @@ -272,11 +378,11 @@ rule.cssText.includes(url) ); - console.log('Existing font-face rule found:', !!existingFontRule); + logCollector.log('Existing font-face rule found:', !!existingFontRule); let response; if (existingFontRule) { - console.log('Attempting to fetch using existing rule credentials...'); + logCollector.log('Attempting to fetch using existing rule credentials...'); const fontBlob = await fetch(url, { mode: 'cors', credentials: 'include', @@ -286,7 +392,7 @@ }).then(r => r.blob()); response = new Response(fontBlob); } else { - console.log('No existing rule found, attempting direct fetch...'); + logCollector.log('No existing rule found, attempting direct fetch...'); response = await fetch(url, { mode: 'cors', credentials: 'include', @@ -300,9 +406,9 @@ throw new Error(`Network response was not ok. Status: ${response.status}`); } - console.log('Font fetched successfully, preparing download...'); + logCollector.log('Font fetched successfully, preparing download...'); const blob = await response.blob(); - console.log('Font blob size:', blob.size, 'bytes'); + logCollector.log('Font blob size:', blob.size, 'bytes'); const objectUrl = URL.createObjectURL(blob); const link = document.createElement('a'); @@ -313,12 +419,12 @@ document.body.removeChild(link); setTimeout(() => URL.revokeObjectURL(objectUrl), 100); - console.log('Download initiated successfully'); - console.groupEnd(); + logCollector.log('Download initiated successfully'); + logCollector.groupEnd(); return true; } catch (error) { - console.error('Error downloading font:', error); - console.groupEnd(); + logCollector.error('Error downloading font:', error); + logCollector.groupEnd(); alert(`Error downloading font: ${error.message}\n\nTroubleshooting tips:\n1. Check the console for detailed logs\n2. Try using your browser's developer tools Network tab to find and download the font file directly\n3. Some sites may block direct font downloads`); return false; } @@ -326,7 +432,7 @@ async function previewFont(url, fontFamily) { try { - console.group(`Font Vacuum: Previewing ${fontFamily} from ${url}`); + logCollector.group(`Font Vacuum: Previewing ${fontFamily} from ${url}`); const existingFontRule = Array.from(document.styleSheets) .flatMap(sheet => { @@ -342,12 +448,12 @@ ); if (existingFontRule) { - console.log('Using existing font-face rule for preview'); - console.groupEnd(); + logCollector.log('Using existing font-face rule for preview'); + logCollector.groupEnd(); return true; } - console.log('No existing rule found, attempting to load font...'); + logCollector.log('No existing rule found, attempting to load font...'); const response = await fetch(url, { mode: 'cors', credentials: 'include', @@ -361,7 +467,7 @@ } const blob = await response.blob(); - console.log('Font blob size:', blob.size, 'bytes'); + logCollector.log('Font blob size:', blob.size, 'bytes'); const fontUrl = URL.createObjectURL(blob); const fontFace = new FontFace(fontFamily, `url(${fontUrl})`, { @@ -374,12 +480,12 @@ document.fonts.add(loadedFont); URL.revokeObjectURL(fontUrl); - console.log('Font loaded successfully'); - console.groupEnd(); + logCollector.log('Font loaded successfully'); + logCollector.groupEnd(); return true; } catch (error) { - console.error('Error loading font:', error); - console.groupEnd(); + logCollector.error('Error loading font:', error); + logCollector.groupEnd(); return false; } } @@ -402,7 +508,7 @@ // Preview section const preview = document.createElement('div'); preview.className = 'fv-preview'; - preview.innerHTML = 'Society for me my misery<br>Since Gift of Thee --'; + preview.innerHTML = '0123456789<br><br>Society for me my misery<br>Since Gift of Thee --<br><br>The quick brown fox jumps over the lazy dog!?'; fontItem.appendChild(preview); // Download buttons for unique files @@ -445,7 +551,26 @@ }); } + // Create footer with debug button + const footer = document.createElement('div'); + footer.className = 'fv-footer'; + + const reportBtn = document.createElement('button'); + reportBtn.className = 'fv-footer-button'; + reportBtn.innerHTML = '<span>📋</span><span>Copy Debug Report</span>'; + reportBtn.addEventListener('click', () => { + const report = logCollector.getReport(); + navigator.clipboard.writeText(report).then(() => { + reportBtn.innerHTML = '<span>✅</span><span>Report Copied!</span>'; + setTimeout(() => { + reportBtn.innerHTML = '<span>📋</span><span>Copy Debug Report</span>'; + }, 2000); + }); + }); + + footer.appendChild(reportBtn); container.appendChild(header); container.appendChild(content); - document.body.appendChild(container); + container.appendChild(footer); + styleRoot.appendChild(container); })(); \ No newline at end of file |