Merge pull request #50 from DarkKirb/fix-pleroma-fe-jxl-polyfill
Fix the pleroma-fe jxl polyfill patch
This commit is contained in:
commit
55703ca8f5
1 changed files with 89 additions and 5 deletions
|
@ -92,21 +92,105 @@ index 19a7e186..54a9c4af 100644
|
|||
"engines": {
|
||||
"node": ">= 16.0.0",
|
||||
diff --git a/src/App.js b/src/App.js
|
||||
index d4b3b41a..ee75815b 100644
|
||||
index d4b3b41a..ef67a6a4 100644
|
||||
--- a/src/App.js
|
||||
+++ b/src/App.js
|
||||
@@ -53,6 +53,11 @@ export default {
|
||||
@@ -53,6 +53,9 @@ export default {
|
||||
unmounted () {
|
||||
window.removeEventListener('resize', this.updateMobileState)
|
||||
},
|
||||
+ mounted() {
|
||||
+ let jxlPolyfill = document.createElement("script");
|
||||
+ jxlPolyfill.setAttribute("src", "/node_modules/jxl.js/jxl.js");
|
||||
+ document.head.appendChild(jxlPolyfill);
|
||||
+ import("./lib/jxl.js").then(jxl => jxl.startPolyfill());
|
||||
+ },
|
||||
computed: {
|
||||
classes () {
|
||||
return [
|
||||
diff --git a/src/lib/jxl.js b/src/lib/jxl.js
|
||||
new file mode 100644
|
||||
index 00000000..568b5293
|
||||
--- /dev/null
|
||||
+++ b/src/lib/jxl.js
|
||||
@@ -0,0 +1,80 @@
|
||||
+const config = {
|
||||
+ useCache: true
|
||||
+};
|
||||
+
|
||||
+let cache, workers = {};
|
||||
+
|
||||
+function imgDataToDataURL(img, imgData, isCSS) {
|
||||
+ const jxlSrc = img.dataset.jxlSrc;
|
||||
+ if (imgData instanceof Blob) {
|
||||
+ const dataURL = URL.createObjectURL(imgData);
|
||||
+ if (isCSS)
|
||||
+ img.style.backgroundImage = 'url("' + dataURL + '")';
|
||||
+ else
|
||||
+ img.src = dataURL;
|
||||
+ } else if ('OffscreenCanvas' in window) {
|
||||
+ const canvas = new OffscreenCanvas(imgData.width, imgData.height);
|
||||
+ workers[jxlSrc].postMessage({ canvas, imgData }, [canvas]);
|
||||
+ workers[jxlSrc].addEventListener('message', m => {
|
||||
+ if (m.data.url && m.data.blob) {
|
||||
+ if (isCSS)
|
||||
+ img.style.backgroundImage = 'url("' + m.data.url + '")';
|
||||
+ else
|
||||
+ img.src = m.data.url;
|
||||
+ config.useCache && cache && cache.put(jxlSrc, new Response(m.data.blob));
|
||||
+ }
|
||||
+ });
|
||||
+ } else {
|
||||
+ const canvas = document.createElement('canvas');
|
||||
+ canvas.width = imgData.width;
|
||||
+ canvas.height = imgData.height;
|
||||
+ canvas.getContext('2d').putImageData(imgData, 0, 0);
|
||||
+ canvas.toBlob(blob => {
|
||||
+ const dataURL = URL.createObjectURL(blob);
|
||||
+ if (isCSS)
|
||||
+ img.style.backgroundImage = 'url("' + dataURL + '")';
|
||||
+ else
|
||||
+ img.src = dataURL;
|
||||
+ config.useCache && cache && cache.put(jxlSrc, new Response(blob));
|
||||
+ }, 'image/jpeg');
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+async function decode(img, isCSS) {
|
||||
+ const jxlSrc = img.dataset.jxlSrc = isCSS ? getComputedStyle(img).backgroundImage.slice(5, -2) : img.currentSrc;
|
||||
+ img.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='; // blank 1x1 image
|
||||
+ if (config.useCache) {
|
||||
+ try {
|
||||
+ cache = cache || await caches.open('jxl');
|
||||
+ } catch (e) { }
|
||||
+ const cachedImg = cache && await cache.match(jxlSrc);
|
||||
+ if (cachedImg) {
|
||||
+ const cachedImgData = await cachedImg.blob();
|
||||
+ requestAnimationFrame(() => imgDataToDataURL(img, cachedImgData, isCSS));
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ const res = await fetch(jxlSrc);
|
||||
+ const image = await res.arrayBuffer();
|
||||
+ workers[jxlSrc] = new Worker('/node_modules/jxl.js/jxl_dec.js');
|
||||
+ workers[jxlSrc].postMessage({ jxlSrc, image });
|
||||
+ workers[jxlSrc].addEventListener('message', m => m.data.imgData && requestAnimationFrame(() => imgDataToDataURL(img, m.data.imgData, isCSS)));
|
||||
+}
|
||||
+
|
||||
+function handleElement(el) {
|
||||
+ if (el instanceof HTMLImageElement && el.src.endsWith('.jxl')) {
|
||||
+ decode(el, false);
|
||||
+ return;
|
||||
+ } else if (el instanceof Element && getComputedStyle(el).backgroundImage.endsWith('.jxl)'))
|
||||
+ decode(el, true);
|
||||
+ el.childNodes.forEach(handleElement);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+export function startPolyfill() {
|
||||
+ new MutationObserver(mutations => mutations.forEach(mutation => {
|
||||
+ mutation.addedNodes.forEach(handleElement);
|
||||
+ })).observe(document.documentElement, { subtree: true, childList: true });
|
||||
+ handleElement(document.documentElement); // Run the polyfill once on the full DOM
|
||||
+}
|
||||
diff --git a/yarn.lock b/yarn.lock
|
||||
index bbceba0b..92cfd7cd 100644
|
||||
--- a/yarn.lock
|
||||
|
|
Reference in a new issue