MCPcopy Create free account
hub / github.com/hoothin/UserScripts / ImageSizeFetcher

Class ImageSizeFetcher

Picviewer CE+/dist.user.js:12058–12177  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

12056 } else GM_fetch = fetch;
12057
12058 class ImageSizeFetcher {
12059 constructor(gmXhr, config = {}) {
12060 if (!gmXhr) throw new Error("GM_xmlhttpRequest is required");
12061 this.gmXhr = gmXhr;
12062 this.cache = new Map();
12063 this.queue = [];
12064 this.activeCount = 0;
12065 this.concurrency = config.concurrency || 3;
12066 this.timeout = config.timeout || 5000;
12067 }
12068
12069 async getSize(url, options = {}) {
12070 const { force = false, strategy = 'auto' } = options;
12071 if (!url) return null;
12072
12073 if (!force && this.cache.has(url)) {
12074 return this.cache.get(url);
12075 }
12076
12077 if (url.startsWith('data:')) {
12078 const size = this._calculateBase64Size(url);
12079 this.cache.set(url, size);
12080 return size;
12081 }
12082
12083 if (url.startsWith('blob:')) {
12084 return this._getBlobSize(url);
12085 }
12086
12087 if (strategy === 'local-only' || strategy === 'auto') {
12088 const perfSize = this._getFromPerformance(url);
12089 if (perfSize !== null) {
12090 this.cache.set(url, perfSize);
12091 return perfSize;
12092 }
12093 if (strategy === 'local-only') return null;
12094 }
12095
12096 return this._scheduleRequest(url);
12097 }
12098
12099 _calculateBase64Size(dataUrl) {
12100 const base64Str = dataUrl.split(',')[1];
12101 if (!base64Str) return 0;
12102 const len = base64Str.length;
12103 const padding = (base64Str.match(/=/g) || []).length;
12104 return (len * 3 / 4) - padding;
12105 }
12106
12107 async _getBlobSize(blobUrl) {
12108 try {
12109 const response = await fetch(blobUrl);
12110 const blob = await response.blob();
12111 return blob.size;
12112 } catch (e) {
12113 console.error('Blob fetch failed', e);
12114 return null;
12115 }

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected