-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbookmarklet.js
More file actions
5 lines (4 loc) · 5.36 KB
/
Copy pathbookmarklet.js
File metadata and controls
5 lines (4 loc) · 5.36 KB
1
2
3
4
5
// This is the minified build of scanner.js.
// Don't edit this by hand — change scanner.js and re-minify.
// To install: copy the line below, create a bookmark, paste it as the URL.
javascript:!function(){const e=document.getElementById("a11y-motion-panel");e&&e.remove();const n=[];function t(e,t){if(!(e instanceof CSSStyleRule))return;const o=e.style,i=e.selectorText,r=o.animation&&""!==o.animation,d=o.transition&&""!==o.transition&&"none"!==o.transition;!r&&!d||t||n.push({type:r?"animation":"transition",selector:i,value:r?o.animation:o.transition})}Array.from(document.styleSheets).forEach(e=>{try{Array.from(e.cssRules||[]).forEach(e=>{if(e instanceof CSSMediaRule){const n=(e.conditionText||e.media.mediaText).includes("prefers-reduced-motion");return void Array.from(e.cssRules||[]).forEach(e=>{t(e,n)})}t(e,!1)})}catch(e){console.warn("Could not read stylesheet rules:",e)}}),Array.from(document.querySelectorAll("img")).filter(e=>e.src&&e.src.toLowerCase().includes(".gif")).forEach(e=>{n.push({type:"gif",selector:e.alt?`img[alt="${e.alt}"]`:"img (no alt)",value:e.src})});const o=n.filter(e=>"animation"===e.type).length,i=n.filter(e=>"transition"===e.type).length,r=n.filter(e=>"gif"===e.type).length,d=n.length,a=0===d?"#22c55e":d<5?"#f59e0b":"#ef4444",s=0===d?"All Clear":`${d} Violation${d>1?"s":""} Found`,l=document.createElement("div");function p(e,n){return e.length>n?e.slice(0,n)+"...":e}l.id="a11y-motion-panel",l.style.cssText="\n position: fixed;\n top: 16px;\n right: 16px;\n width: 340px;\n max-height: 80vh;\n overflow-y: auto;\n background: #0f172a;\n color: #e2e8f0;\n font-family: 'Courier New', monospace;\n font-size: 13px;\n border-radius: 10px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.5);\n z-index: 999999;\n border: 1px solid #334155;\n line-height: 1.5;\n ",l.innerHTML=`\n <div style="padding:14px 16px;border-bottom:1px solid #334155;display:flex;justify-content:space-between;align-items:center;">\n <div>\n <div style="font-weight:bold;font-size:14px;color:#f8fafc;">Motion Scanner</div>\n <div style="font-size:11px;color:#b3becd;">WCAG 2.3.3 — prefers-reduced-motion</div>\n </div>\n <button id="a11y-close-btn" style="background:#334155;border:none;color:#b3becd;width:26px;height:26px;border-radius:50%;cursor:pointer;font-size:14px;">x</button>\n </div>\n\n <div style="padding:12px 16px;border-bottom:1px solid #1e293b;">\n <div style="color:${a};font-size:15px;font-weight:bold;margin-bottom:8px;">${s}</div>\n <div style="display:flex;gap:12px;flex-wrap:wrap;">\n <span style="background:#1e293b;padding:3px 8px;border-radius:4px;font-size:11px;">\n Animations: <b style="color:#f472b6;">${o}</b>\n </span>\n <span style="background:#1e293b;padding:3px 8px;border-radius:4px;font-size:11px;">\n Transitions: <b style="color:#60a5fa;">${i}</b>\n </span>\n <span style="background:#1e293b;padding:3px 8px;border-radius:4px;font-size:11px;">\n GIFs: <b style="color:#34d399;">${r}</b>\n </span>\n </div>\n </div>\n\n <div style="padding:12px 16px;">\n ${0===d?'<div style="color:#b3becd;font-size:12px;">\n No unprotected animations found. This page respects motion preferences.\n </div>':n.slice(0,20).map(e=>`\n <div style="margin-bottom:10px;padding:8px;background:#1e293b;border-radius:6px;border-left:3px solid ${"animation"===e.type?"#f472b6":"transition"===e.type?"#60a5fa":"#34d399"};">\n <div style="font-size:11px;color:#b3becd;text-transform:uppercase;letter-spacing:.5px;">${e.type}</div>\n <div style="color:#fbbf24;font-size:11px;word-break:break-all;">${p(e.selector,60)}</div>\n <div style="color:#b3becd;font-size:10px;word-break:break-all;">${p(e.value,80)}</div>\n </div>\n `).join("")}\n ${d>20?`<div style="color:#94a3b8;font-size:11px;text-align:center;">...and ${d-20} more</div>`:""}\n </div>\n\n <div style="padding:10px 16px;border-top:1px solid #1e293b;">\n <button id="a11y-toggle-btn" style="width:100%;padding:8px;background:#7c3aed;color:#ede9fe;border:none;border-radius:6px;font-family:'Courier New',monospace;font-size:12px;cursor:pointer;margin-bottom:8px;">\n Suppress All Animations\n </button>\n <div style="font-size:10px;color:#94a3b8;">\n Scanned ${document.styleSheets.length} stylesheet(s) · ${document.querySelectorAll("*").length} elements\n </div>\n </div>\n `,document.body.appendChild(l),document.getElementById("a11y-close-btn").addEventListener("click",()=>{l.remove()});let c=!1;const b="a11y-kill-switch";document.getElementById("a11y-toggle-btn").addEventListener("click",()=>{const e=document.getElementById("a11y-toggle-btn");if(c){const n=document.getElementById(b);n&&n.remove(),c=!1,e.textContent="Suppress All Animations",e.style.background="#7c3aed",e.style.color="#ede9fe"}else{const n=document.createElement("style");n.id=b,n.textContent="\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n scroll-behavior: auto !important;\n }\n ",document.head.appendChild(n),c=!0,e.textContent="Re-enable Animations",e.style.background="#166534",e.style.color="#86efac"}})}();