nix-packages/akkoma/akkoma-fe/jxl-polyfill.patch
2023-08-05 16:25:06 +01:00

377 lines
14 KiB
Diff

diff --git a/build/build.js b/build/build.js
index b3c9aad4..c4df034f 100644
--- a/build/build.js
+++ b/build/build.js
@@ -23,6 +23,9 @@ rm('-rf', assetsPath)
mkdir('-p', assetsPath)
cp('-R', 'static/*', assetsPath)
+sed('-i', /'jxl_dec.js/, "'/node_modules/jxl.js/jxl_dec.js", 'node_modules/jxl.js/jxl.js')
+sed('-i', /"jxl_dec.wasm/, '"/node_modules/jxl.js/jxl_dec.wasm', 'node_modules/jxl.js/jxl_dec.js')
+
webpack(webpackConfig, function (err, stats) {
spinner.stop()
if (err) throw err
diff --git a/build/dev-server.js b/build/dev-server.js
index 5acd0fed..ef275509 100644
--- a/build/dev-server.js
+++ b/build/dev-server.js
@@ -5,11 +5,15 @@ var path = require('path')
var express = require('express')
var webpack = require('webpack')
var opn = require('opn')
+require('shelljs/global')
var proxyMiddleware = require('http-proxy-middleware')
var webpackConfig = process.env.NODE_ENV === 'testing'
? require('./webpack.prod.conf')
: require('./webpack.dev.conf')
+sed('-i', /'jxl_dec.js/, "'/node_modules/jxl.js/jxl_dec.js", 'node_modules/jxl.js/jxl.js')
+sed('-i', /"jxl_dec.wasm/, '"/node_modules/jxl.js/jxl_dec.wasm', 'node_modules/jxl.js/jxl_dec.js')
+
// default port where dev server listens for incoming traffic
var port = process.env.PORT || config.dev.port
// Define HTTP proxies to your custom API backend
diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js
index 2a3db96e..665eaa21 100644
--- a/build/webpack.base.conf.js
+++ b/build/webpack.base.conf.js
@@ -2,6 +2,8 @@ var path = require('path')
var config = require('../config')
var utils = require('./utils')
var projectRoot = path.resolve(__dirname, '../')
+const CopyPlugin = require("copy-webpack-plugin");
+const WriteFilePlugin = require("write-file-webpack-plugin");
var { VueLoaderPlugin } = require('vue-loader')
var env = process.env.NODE_ENV
@@ -118,6 +120,14 @@ module.exports = {
]
},
plugins: [
- new VueLoaderPlugin()
+ new VueLoaderPlugin(),
+ new CopyPlugin({
+ patterns: [
+ {
+ from: "node_modules/jxl.js/jxl*"
+ }
+ ]
+ }),
+ new WriteFilePlugin()
]
}
diff --git a/package.json b/package.json
index 19a7e186..54a9c4af 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
"diff": "3.5.0",
"escape-html": "1.0.3",
"js-cookie": "^3.0.1",
+ "jxl.js": "^1.0.0",
"localforage": "1.10.0",
"parse-link-header": "^2.0.0",
"phoenix": "1.6.2",
@@ -63,6 +64,7 @@
"chalk": "1.1.3",
"chromedriver": "^107.0.3",
"connect-history-api-fallback": "^2.0.0",
+ "copy-webpack-plugin": "^11.0.0",
"cross-spawn": "^7.0.3",
"css-loader": "^6.7.2",
"custom-event-polyfill": "^1.0.7",
@@ -124,7 +126,8 @@
"webpack-dev-middleware": "^5.3.3",
"webpack-hot-middleware": "^2.25.1",
"webpack-merge": "^5.8.0",
- "workbox-webpack-plugin": "^6.5.4"
+ "workbox-webpack-plugin": "^6.5.4",
+ "write-file-webpack-plugin": "^4.5.1"
},
"engines": {
"node": ">= 16.0.0",
diff --git a/src/App.js b/src/App.js
index d4b3b41a..ef67a6a4 100644
--- a/src/App.js
+++ b/src/App.js
@@ -53,6 +53,9 @@ export default {
unmounted () {
window.removeEventListener('resize', this.updateMobileState)
},
+ mounted() {
+ 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
+++ b/yarn.lock
@@ -2732,7 +2732,7 @@ chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
-chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0:
+chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.0:
version "2.4.2"
resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@@ -2994,6 +2994,18 @@ cookie@0.4.2, cookie@~0.4.1:
resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz"
integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
+copy-webpack-plugin@^11.0.0:
+ version "11.0.0"
+ resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz#96d4dbdb5f73d02dd72d0528d1958721ab72e04a"
+ integrity sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==
+ dependencies:
+ fast-glob "^3.2.11"
+ glob-parent "^6.0.1"
+ globby "^13.1.1"
+ normalize-path "^3.0.0"
+ schema-utils "^4.0.0"
+ serialize-javascript "^6.0.0"
+
core-js-compat@^3.20.2, core-js-compat@^3.21.0:
version "3.24.1"
resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.24.1.tgz"
@@ -3187,7 +3199,7 @@ debug@4.3.1:
dependencies:
ms "2.1.2"
-debug@^3.2.7:
+debug@^3.1.0, debug@^3.2.7:
version "3.2.7"
resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
@@ -4006,7 +4018,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
-fast-glob@^3.2.12:
+fast-glob@^3.2.11, fast-glob@^3.2.12:
version "3.2.12"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80"
integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==
@@ -4084,6 +4096,11 @@ filelist@^1.0.1:
dependencies:
minimatch "^5.0.1"
+filesize@^3.6.1:
+ version "3.6.1"
+ resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317"
+ integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==
+
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz"
@@ -4343,6 +4360,13 @@ glob-parent@^5.1.2, glob-parent@~5.1.2:
dependencies:
is-glob "^4.0.1"
+glob-parent@^6.0.1:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
+ integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
+ dependencies:
+ is-glob "^4.0.3"
+
glob-to-regexp@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
@@ -4440,6 +4464,17 @@ globby@^11.1.0:
merge2 "^1.4.1"
slash "^3.0.0"
+globby@^13.1.1:
+ version "13.1.2"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-13.1.2.tgz#29047105582427ab6eca4f905200667b056da515"
+ integrity sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==
+ dependencies:
+ dir-glob "^3.0.1"
+ fast-glob "^3.2.11"
+ ignore "^5.2.0"
+ merge2 "^1.4.1"
+ slash "^4.0.0"
+
globjoin@^0.1.4:
version "0.1.4"
resolved "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz"
@@ -4452,7 +4487,7 @@ gonzales-pe@^4.3.0:
dependencies:
minimist "^1.2.5"
-graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
+graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
version "4.2.10"
resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
@@ -5314,6 +5349,11 @@ jsonpointer@^5.0.0:
resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559"
integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==
+jxl.js@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/jxl.js/-/jxl.js-1.0.0.tgz#e2c78e5c135d7d272c0d36f86b7f79de6f4b40b3"
+ integrity sha512-1br2vK02/9nYAbIEdrt7Qe6uRk5e+S0TGoRxUlxnGpXJYARfhFAfFHHArcQYjU4WMPNjLPci4oXBNsEUFVdEEQ==
+
karma-coverage@1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/karma-coverage/-/karma-coverage-1.1.2.tgz"
@@ -5679,7 +5719,7 @@ lodash.truncate@^4.4.2:
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==
-lodash@4.17.21, lodash@^4.17.0, lodash@^4.17.10, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4:
+lodash@4.17.21, lodash@^4.17.0, lodash@^4.17.10, lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -6007,6 +6047,11 @@ mocha@3.5.3:
mkdirp "0.5.1"
supports-color "3.1.2"
+moment@^2.22.1:
+ version "2.29.4"
+ resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
+ integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
+
ms@0.7.1:
version "0.7.1"
resolved "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
@@ -7414,6 +7459,11 @@ slash@^3.0.0:
resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
+slash@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7"
+ integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==
+
slice-ansi@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b"
@@ -8661,6 +8711,15 @@ wrappy@1:
resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
+write-file-atomic@^2.3.0:
+ version "2.4.3"
+ resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481"
+ integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==
+ dependencies:
+ graceful-fs "^4.1.11"
+ imurmurhash "^0.1.4"
+ signal-exit "^3.0.2"
+
write-file-atomic@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd"
@@ -8669,6 +8728,19 @@ write-file-atomic@^4.0.2:
imurmurhash "^0.1.4"
signal-exit "^3.0.7"
+write-file-webpack-plugin@^4.5.1:
+ version "4.5.1"
+ resolved "https://registry.yarnpkg.com/write-file-webpack-plugin/-/write-file-webpack-plugin-4.5.1.tgz#aeeb68889194da5ec8a864667d46da9e00ee92d5"
+ integrity sha512-AZ7qJUvhTCBiOtG21aFJUcNuLVo2FFM6JMGKvaUGAH+QDqQAp2iG0nq3GcuXmJOFQR2JjpjhyYkyPrbFKhdjNQ==
+ dependencies:
+ chalk "^2.4.0"
+ debug "^3.1.0"
+ filesize "^3.6.1"
+ lodash "^4.17.13"
+ mkdirp "^0.5.1"
+ moment "^2.22.1"
+ write-file-atomic "^2.3.0"
+
ws@~8.2.3:
version "8.2.3"
resolved "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz"