@substrate-system/blur-hash 0.0.35 → 0.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/decode-dimensions.cjs +37 -0
- package/dist/decode-dimensions.cjs.map +7 -0
- package/dist/decode-dimensions.d.ts +21 -0
- package/dist/decode-dimensions.d.ts.map +1 -0
- package/dist/decode-dimensions.js +18 -0
- package/dist/decode-dimensions.js.map +7 -0
- package/dist/decode-dimensions.min.js +2 -0
- package/dist/decode-dimensions.min.js.map +7 -0
- package/dist/html.cjs +6 -4
- package/dist/html.cjs.map +2 -2
- package/dist/html.d.ts.map +1 -1
- package/dist/html.js +6 -4
- package/dist/html.js.map +2 -2
- package/dist/html.min.js +12 -14
- package/dist/html.min.js.map +4 -4
- package/dist/index.cjs +34 -14
- package/dist/index.cjs.map +2 -2
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -14
- package/dist/index.js.map +2 -2
- package/dist/index.min.js +8 -10
- package/dist/index.min.js.map +4 -4
- package/dist/meta.json +42 -8
- package/dist/style.css +27 -28
- package/dist/style.min.css +1 -2
- package/package.json +10 -10
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var decode_dimensions_exports = {};
|
|
21
|
+
__export(decode_dimensions_exports, {
|
|
22
|
+
decodeDimensions: () => decodeDimensions
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(decode_dimensions_exports);
|
|
25
|
+
function decodeDimensions(width, height, cap = 32) {
|
|
26
|
+
const longEdge = Math.max(width, height);
|
|
27
|
+
if (longEdge <= cap) {
|
|
28
|
+
return { width, height };
|
|
29
|
+
}
|
|
30
|
+
const scale = cap / longEdge;
|
|
31
|
+
return {
|
|
32
|
+
width: Math.max(1, Math.round(width * scale)),
|
|
33
|
+
height: Math.max(1, Math.round(height * scale))
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
__name(decodeDimensions, "decodeDimensions");
|
|
37
|
+
//# sourceMappingURL=decode-dimensions.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/decode-dimensions.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Compute the resolution to decode a BlurHash placeholder at.\n *\n * A placeholder is a low-frequency blur, and decode cost is\n * O(width * height * componentsX * componentsY). Decoding above a small\n * size wastes work with no visible benefit, because the canvas is stretched\n * to fill its host via CSS (`blur-hash canvas { width:100%; height:100% }`).\n *\n * This caps the long edge to `cap` pixels, preserves the aspect ratio, floors\n * each edge at 1px, and never upscales a source that is already small.\n *\n * @param width The layout/source width in pixels.\n * @param height The layout/source height in pixels.\n * @param cap Maximum pixels on the long edge. Default 32.\n * @returns The decode dimensions to pass to `decode` and `createImageData`.\n */\nexport function decodeDimensions (\n width:number,\n height:number,\n cap:number = 32\n):{ width:number; height:number } {\n const longEdge = Math.max(width, height)\n\n // Never upscale: a source at or below the cap decodes as-is.\n if (longEdge <= cap) {\n return { width, height }\n }\n\n const scale = cap / longEdge\n return {\n width: Math.max(1, Math.round(width * scale)),\n height: Math.max(1, Math.round(height * scale))\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBO,SAAS,iBACZ,OACA,QACA,MAAa,IACiB;AAC9B,QAAM,WAAW,KAAK,IAAI,OAAO,MAAM;AAGvC,MAAI,YAAY,KAAK;AACjB,WAAO,EAAE,OAAO,OAAO;AAAA,EAC3B;AAEA,QAAM,QAAQ,MAAM;AACpB,SAAO;AAAA,IACH,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,KAAK,CAAC;AAAA,IAC5C,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,KAAK,CAAC;AAAA,EAClD;AACJ;AAjBgB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute the resolution to decode a BlurHash placeholder at.
|
|
3
|
+
*
|
|
4
|
+
* A placeholder is a low-frequency blur, and decode cost is
|
|
5
|
+
* O(width * height * componentsX * componentsY). Decoding above a small
|
|
6
|
+
* size wastes work with no visible benefit, because the canvas is stretched
|
|
7
|
+
* to fill its host via CSS (`blur-hash canvas { width:100%; height:100% }`).
|
|
8
|
+
*
|
|
9
|
+
* This caps the long edge to `cap` pixels, preserves the aspect ratio, floors
|
|
10
|
+
* each edge at 1px, and never upscales a source that is already small.
|
|
11
|
+
*
|
|
12
|
+
* @param width The layout/source width in pixels.
|
|
13
|
+
* @param height The layout/source height in pixels.
|
|
14
|
+
* @param cap Maximum pixels on the long edge. Default 32.
|
|
15
|
+
* @returns The decode dimensions to pass to `decode` and `createImageData`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function decodeDimensions(width: number, height: number, cap?: number): {
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=decode-dimensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decode-dimensions.d.ts","sourceRoot":"","sources":["../src/decode-dimensions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC5B,KAAK,EAAC,MAAM,EACZ,MAAM,EAAC,MAAM,EACb,GAAG,GAAC,MAAW,GACjB;IAAE,KAAK,EAAC,MAAM,CAAC;IAAC,MAAM,EAAC,MAAM,CAAA;CAAE,CAahC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
function decodeDimensions(width, height, cap = 32) {
|
|
4
|
+
const longEdge = Math.max(width, height);
|
|
5
|
+
if (longEdge <= cap) {
|
|
6
|
+
return { width, height };
|
|
7
|
+
}
|
|
8
|
+
const scale = cap / longEdge;
|
|
9
|
+
return {
|
|
10
|
+
width: Math.max(1, Math.round(width * scale)),
|
|
11
|
+
height: Math.max(1, Math.round(height * scale))
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
__name(decodeDimensions, "decodeDimensions");
|
|
15
|
+
export {
|
|
16
|
+
decodeDimensions
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=decode-dimensions.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/decode-dimensions.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Compute the resolution to decode a BlurHash placeholder at.\n *\n * A placeholder is a low-frequency blur, and decode cost is\n * O(width * height * componentsX * componentsY). Decoding above a small\n * size wastes work with no visible benefit, because the canvas is stretched\n * to fill its host via CSS (`blur-hash canvas { width:100%; height:100% }`).\n *\n * This caps the long edge to `cap` pixels, preserves the aspect ratio, floors\n * each edge at 1px, and never upscales a source that is already small.\n *\n * @param width The layout/source width in pixels.\n * @param height The layout/source height in pixels.\n * @param cap Maximum pixels on the long edge. Default 32.\n * @returns The decode dimensions to pass to `decode` and `createImageData`.\n */\nexport function decodeDimensions (\n width:number,\n height:number,\n cap:number = 32\n):{ width:number; height:number } {\n const longEdge = Math.max(width, height)\n\n // Never upscale: a source at or below the cap decodes as-is.\n if (longEdge <= cap) {\n return { width, height }\n }\n\n const scale = cap / longEdge\n return {\n width: Math.max(1, Math.round(width * scale)),\n height: Math.max(1, Math.round(height * scale))\n }\n}\n"],
|
|
5
|
+
"mappings": ";;AAgBO,SAAS,iBACZ,OACA,QACA,MAAa,IACiB;AAC9B,QAAM,WAAW,KAAK,IAAI,OAAO,MAAM;AAGvC,MAAI,YAAY,KAAK;AACjB,WAAO,EAAE,OAAO,OAAO;AAAA,EAC3B;AAEA,QAAM,QAAQ,MAAM;AACpB,SAAO;AAAA,IACH,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,KAAK,CAAC;AAAA,IAC5C,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,KAAK,CAAC;AAAA,EAClD;AACJ;AAjBgB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var o=Object.defineProperty;var m=(n,e)=>o(n,"name",{value:e,configurable:!0});function b(n,e,r=32){let t=Math.max(n,e);if(t<=r)return{width:n,height:e};let u=r/t;return{width:Math.max(1,Math.round(n*u)),height:Math.max(1,Math.round(e*u))}}m(b,"decodeDimensions");export{b as decodeDimensions};
|
|
2
|
+
//# sourceMappingURL=decode-dimensions.min.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/decode-dimensions.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Compute the resolution to decode a BlurHash placeholder at.\n *\n * A placeholder is a low-frequency blur, and decode cost is\n * O(width * height * componentsX * componentsY). Decoding above a small\n * size wastes work with no visible benefit, because the canvas is stretched\n * to fill its host via CSS (`blur-hash canvas { width:100%; height:100% }`).\n *\n * This caps the long edge to `cap` pixels, preserves the aspect ratio, floors\n * each edge at 1px, and never upscales a source that is already small.\n *\n * @param width The layout/source width in pixels.\n * @param height The layout/source height in pixels.\n * @param cap Maximum pixels on the long edge. Default 32.\n * @returns The decode dimensions to pass to `decode` and `createImageData`.\n */\nexport function decodeDimensions (\n width:number,\n height:number,\n cap:number = 32\n):{ width:number; height:number } {\n const longEdge = Math.max(width, height)\n\n // Never upscale: a source at or below the cap decodes as-is.\n if (longEdge <= cap) {\n return { width, height }\n }\n\n const scale = cap / longEdge\n return {\n width: Math.max(1, Math.round(width * scale)),\n height: Math.max(1, Math.round(height * scale))\n }\n}\n"],
|
|
5
|
+
"mappings": "+EAgBO,SAASA,EACZC,EACAC,EACAC,EAAa,GACiB,CAC9B,IAAMC,EAAW,KAAK,IAAIH,EAAOC,CAAM,EAGvC,GAAIE,GAAYD,EACZ,MAAO,CAAE,MAAAF,EAAO,OAAAC,CAAO,EAG3B,IAAMG,EAAQF,EAAMC,EACpB,MAAO,CACH,MAAO,KAAK,IAAI,EAAG,KAAK,MAAMH,EAAQI,CAAK,CAAC,EAC5C,OAAQ,KAAK,IAAI,EAAG,KAAK,MAAMH,EAASG,CAAK,CAAC,CAClD,CACJ,CAjBgBC,EAAAN,EAAA",
|
|
6
|
+
"names": ["decodeDimensions", "width", "height", "cap", "longEdge", "scale", "__name"]
|
|
7
|
+
}
|
package/dist/html.cjs
CHANGED
|
@@ -24,6 +24,7 @@ __export(html_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(html_exports);
|
|
26
26
|
var import_attributes = require("@substrate-system/web-component/attributes");
|
|
27
|
+
var import_decode_dimensions = require("./decode-dimensions.js");
|
|
27
28
|
function render(attrs) {
|
|
28
29
|
const {
|
|
29
30
|
width,
|
|
@@ -38,13 +39,14 @@ function render(attrs) {
|
|
|
38
39
|
src
|
|
39
40
|
} = attrs;
|
|
40
41
|
if (!placeholder) throw new Error("not placeholder");
|
|
42
|
+
const decodeWidth = typeof width === "string" ? parseInt(width, 10) : width;
|
|
43
|
+
const decodeHeight = typeof height === "string" ? parseInt(height, 10) : height;
|
|
44
|
+
const decodeSize = (0, import_decode_dimensions.decodeDimensions)(decodeWidth, decodeHeight);
|
|
41
45
|
const htmlString = `<canvas
|
|
42
46
|
alt="${alt}"
|
|
43
|
-
width=${width}
|
|
44
|
-
height=${height}
|
|
47
|
+
width=${decodeSize.width}
|
|
48
|
+
height=${decodeSize.height}
|
|
45
49
|
class="blurry"
|
|
46
|
-
width=${width}
|
|
47
|
-
height=${height}
|
|
48
50
|
></canvas>
|
|
49
51
|
|
|
50
52
|
<img class="blurry"
|
package/dist/html.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/html.ts"],
|
|
4
|
-
"sourcesContent": ["import { toAttributes } from '@substrate-system/web-component/attributes'\nimport type { ImgAttrs } from './index.js'\n\nexport type SSRAttrs = ImgAttrs & { classes?:string }\n\nexport function render (attrs:SSRAttrs) {\n const {\n width,\n height,\n alt,\n contentVisibility,\n placeholder,\n decoding,\n loading,\n srcset,\n sizes,\n src\n } = attrs\n\n if (!placeholder) throw new Error('not placeholder')\n\n const htmlString = `<canvas\n alt=\"${alt}\"\n width=${width}\n height=${height}\n class=\"blurry\"\n
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAA6B;
|
|
4
|
+
"sourcesContent": ["import { toAttributes } from '@substrate-system/web-component/attributes'\nimport type { ImgAttrs } from './index.js'\nimport { decodeDimensions } from './decode-dimensions.js'\n\nexport type SSRAttrs = ImgAttrs & { classes?:string }\n\nexport function render (attrs:SSRAttrs) {\n const {\n width,\n height,\n alt,\n contentVisibility,\n placeholder,\n decoding,\n loading,\n srcset,\n sizes,\n src\n } = attrs\n\n if (!placeholder) throw new Error('not placeholder')\n\n const decodeWidth = typeof width === 'string' ? parseInt(width, 10) : width\n const decodeHeight = typeof height === 'string' ?\n parseInt(height, 10) :\n height\n const decodeSize = decodeDimensions(decodeWidth, decodeHeight)\n\n const htmlString = `<canvas\n alt=\"${alt}\"\n width=${decodeSize.width}\n height=${decodeSize.height}\n class=\"blurry\"\n ></canvas>\n\n <img class=\"blurry\"\n alt=\"${alt}\"\n content-visibility=\"${contentVisibility || 'auto'}\"\n decoding=\"${decoding || 'async'}\"\n loading=\"${loading || 'lazy'}\"\n ${srcset ? `srcset=\"${srcset}\"` : ''}\n ${sizes ? `sizes=\"${sizes}\"` : ''}\n src=\"${src}\"\n />`\n\n const attributeString = toAttributes(attrs)\n\n // running in node?\n return typeof window === 'undefined' ?\n `<blur-hash ${attributeString}>\n ${htmlString}\n </blur-hash>` :\n htmlString\n}\n\nexport const outerHTML = (attrs:SSRAttrs) => {\n return `<blur-hash>${render(attrs)}</blur-hash>`\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAA6B;AAE7B,+BAAiC;AAI1B,SAAS,OAAQ,OAAgB;AACpC,QAAM;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ,IAAI;AAEJ,MAAI,CAAC,YAAa,OAAM,IAAI,MAAM,iBAAiB;AAEnD,QAAM,cAAc,OAAO,UAAU,WAAW,SAAS,OAAO,EAAE,IAAI;AACtE,QAAM,eAAe,OAAO,WAAW,WACnC,SAAS,QAAQ,EAAE,IACnB;AACJ,QAAM,iBAAa,2CAAiB,aAAa,YAAY;AAE7D,QAAM,aAAa;AAAA,eACR,GAAG;AAAA,gBACF,WAAW,KAAK;AAAA,iBACf,WAAW,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,eAKnB,GAAG;AAAA,8BACY,qBAAqB,MAAM;AAAA,oBACrC,YAAY,OAAO;AAAA,mBACpB,WAAW,MAAM;AAAA,UAC1B,SAAS,WAAW,MAAM,MAAM,EAAE;AAAA,UAClC,QAAQ,UAAU,KAAK,MAAM,EAAE;AAAA,eAC1B,GAAG;AAAA;AAGd,QAAM,sBAAkB,gCAAa,KAAK;AAG1C,SAAO,OAAO,WAAW,cACrB,cAAc,eAAe;AAAA,cACvB,UAAU;AAAA,wBAEhB;AACR;AA/CgB;AAiDT,MAAM,YAAY,wBAAC,UAAmB;AACzC,SAAO,cAAc,OAAO,KAAK,CAAC;AACtC,GAFyB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/html.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAG1C,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG;IAAE,OAAO,CAAC,EAAC,MAAM,CAAA;CAAE,CAAA;AAErD,wBAAgB,MAAM,CAAE,KAAK,EAAC,QAAQ,UA+CrC;AAED,eAAO,MAAM,SAAS,GAAI,OAAM,QAAQ,WAEvC,CAAA"}
|
package/dist/html.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
import { toAttributes } from "@substrate-system/web-component/attributes";
|
|
4
|
+
import { decodeDimensions } from "./decode-dimensions.js";
|
|
4
5
|
function render(attrs) {
|
|
5
6
|
const {
|
|
6
7
|
width,
|
|
@@ -15,13 +16,14 @@ function render(attrs) {
|
|
|
15
16
|
src
|
|
16
17
|
} = attrs;
|
|
17
18
|
if (!placeholder) throw new Error("not placeholder");
|
|
19
|
+
const decodeWidth = typeof width === "string" ? parseInt(width, 10) : width;
|
|
20
|
+
const decodeHeight = typeof height === "string" ? parseInt(height, 10) : height;
|
|
21
|
+
const decodeSize = decodeDimensions(decodeWidth, decodeHeight);
|
|
18
22
|
const htmlString = `<canvas
|
|
19
23
|
alt="${alt}"
|
|
20
|
-
width=${width}
|
|
21
|
-
height=${height}
|
|
24
|
+
width=${decodeSize.width}
|
|
25
|
+
height=${decodeSize.height}
|
|
22
26
|
class="blurry"
|
|
23
|
-
width=${width}
|
|
24
|
-
height=${height}
|
|
25
27
|
></canvas>
|
|
26
28
|
|
|
27
29
|
<img class="blurry"
|
package/dist/html.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/html.ts"],
|
|
4
|
-
"sourcesContent": ["import { toAttributes } from '@substrate-system/web-component/attributes'\nimport type { ImgAttrs } from './index.js'\n\nexport type SSRAttrs = ImgAttrs & { classes?:string }\n\nexport function render (attrs:SSRAttrs) {\n const {\n width,\n height,\n alt,\n contentVisibility,\n placeholder,\n decoding,\n loading,\n srcset,\n sizes,\n src\n } = attrs\n\n if (!placeholder) throw new Error('not placeholder')\n\n const htmlString = `<canvas\n alt=\"${alt}\"\n width=${width}\n height=${height}\n class=\"blurry\"\n
|
|
5
|
-
"mappings": ";;AAAA,SAAS,oBAAoB;
|
|
4
|
+
"sourcesContent": ["import { toAttributes } from '@substrate-system/web-component/attributes'\nimport type { ImgAttrs } from './index.js'\nimport { decodeDimensions } from './decode-dimensions.js'\n\nexport type SSRAttrs = ImgAttrs & { classes?:string }\n\nexport function render (attrs:SSRAttrs) {\n const {\n width,\n height,\n alt,\n contentVisibility,\n placeholder,\n decoding,\n loading,\n srcset,\n sizes,\n src\n } = attrs\n\n if (!placeholder) throw new Error('not placeholder')\n\n const decodeWidth = typeof width === 'string' ? parseInt(width, 10) : width\n const decodeHeight = typeof height === 'string' ?\n parseInt(height, 10) :\n height\n const decodeSize = decodeDimensions(decodeWidth, decodeHeight)\n\n const htmlString = `<canvas\n alt=\"${alt}\"\n width=${decodeSize.width}\n height=${decodeSize.height}\n class=\"blurry\"\n ></canvas>\n\n <img class=\"blurry\"\n alt=\"${alt}\"\n content-visibility=\"${contentVisibility || 'auto'}\"\n decoding=\"${decoding || 'async'}\"\n loading=\"${loading || 'lazy'}\"\n ${srcset ? `srcset=\"${srcset}\"` : ''}\n ${sizes ? `sizes=\"${sizes}\"` : ''}\n src=\"${src}\"\n />`\n\n const attributeString = toAttributes(attrs)\n\n // running in node?\n return typeof window === 'undefined' ?\n `<blur-hash ${attributeString}>\n ${htmlString}\n </blur-hash>` :\n htmlString\n}\n\nexport const outerHTML = (attrs:SSRAttrs) => {\n return `<blur-hash>${render(attrs)}</blur-hash>`\n}\n"],
|
|
5
|
+
"mappings": ";;AAAA,SAAS,oBAAoB;AAE7B,SAAS,wBAAwB;AAI1B,SAAS,OAAQ,OAAgB;AACpC,QAAM;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ,IAAI;AAEJ,MAAI,CAAC,YAAa,OAAM,IAAI,MAAM,iBAAiB;AAEnD,QAAM,cAAc,OAAO,UAAU,WAAW,SAAS,OAAO,EAAE,IAAI;AACtE,QAAM,eAAe,OAAO,WAAW,WACnC,SAAS,QAAQ,EAAE,IACnB;AACJ,QAAM,aAAa,iBAAiB,aAAa,YAAY;AAE7D,QAAM,aAAa;AAAA,eACR,GAAG;AAAA,gBACF,WAAW,KAAK;AAAA,iBACf,WAAW,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,eAKnB,GAAG;AAAA,8BACY,qBAAqB,MAAM;AAAA,oBACrC,YAAY,OAAO;AAAA,mBACpB,WAAW,MAAM;AAAA,UAC1B,SAAS,WAAW,MAAM,MAAM,EAAE;AAAA,UAClC,QAAQ,UAAU,KAAK,MAAM,EAAE;AAAA,eAC1B,GAAG;AAAA;AAGd,QAAM,kBAAkB,aAAa,KAAK;AAG1C,SAAO,OAAO,WAAW,cACrB,cAAc,eAAe;AAAA,cACvB,UAAU;AAAA,wBAEhB;AACR;AA/CgB;AAiDT,MAAM,YAAY,wBAAC,UAAmB;AACzC,SAAO,cAAc,OAAO,KAAK,CAAC;AACtC,GAFyB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/html.min.js
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
var
|
|
1
|
+
var y=Object.defineProperty;var o=(r,t)=>y(r,"name",{value:t,configurable:!0});var A=Object.defineProperty,x=o((r,t)=>A(r,"name",{value:t,configurable:!0}),"__name");function s(r){return Object.keys(r).reduce((t,n)=>{let e=r[n];return e?typeof e=="boolean"?e?(t+` ${n}`).trim():t:Array.isArray(e)?t+` ${n}="${e.join(" ")}"`:(t+` ${n}="${e}"`).trim():t},"")}o(s,"toAttributes");x(s,"toAttributes");function h(r,t,n=32){let e=Math.max(r,t);if(e<=n)return{width:r,height:t};let i=n/e;return{width:Math.max(1,Math.round(r*i)),height:Math.max(1,Math.round(t*i))}}o(h,"decodeDimensions");function S(r){let{width:t,height:n,alt:e,contentVisibility:i,placeholder:l,decoding:m,loading:b,srcset:u,sizes:a,src:f}=r;if(!l)throw new Error("not placeholder");let $=typeof t=="string"?parseInt(t,10):t,g=typeof n=="string"?parseInt(n,10):n,d=h($,g),c=`<canvas
|
|
2
2
|
alt="${e}"
|
|
3
|
-
width=${
|
|
4
|
-
height=${
|
|
3
|
+
width=${d.width}
|
|
4
|
+
height=${d.height}
|
|
5
5
|
class="blurry"
|
|
6
|
-
width=${t}
|
|
7
|
-
height=${i}
|
|
8
6
|
></canvas>
|
|
9
7
|
|
|
10
8
|
<img class="blurry"
|
|
11
9
|
alt="${e}"
|
|
12
|
-
content-visibility="${
|
|
13
|
-
decoding="${
|
|
14
|
-
loading="${
|
|
15
|
-
${
|
|
16
|
-
${
|
|
17
|
-
src="${
|
|
18
|
-
/>`,
|
|
19
|
-
${
|
|
20
|
-
</blur-hash>`:
|
|
10
|
+
content-visibility="${i||"auto"}"
|
|
11
|
+
decoding="${m||"async"}"
|
|
12
|
+
loading="${b||"lazy"}"
|
|
13
|
+
${u?`srcset="${u}"`:""}
|
|
14
|
+
${a?`sizes="${a}"`:""}
|
|
15
|
+
src="${f}"
|
|
16
|
+
/>`,p=s(r);return typeof window>"u"?`<blur-hash ${p}>
|
|
17
|
+
${c}
|
|
18
|
+
</blur-hash>`:c}o(S,"render");var R=o(r=>`<blur-hash>${S(r)}</blur-hash>`,"outerHTML");export{R as outerHTML,S as render};
|
|
21
19
|
//# sourceMappingURL=html.min.js.map
|
package/dist/html.min.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../node_modules/@substrate-system/web-component/src/attributes.ts", "../src/html.ts"],
|
|
4
|
-
"sourcesContent": ["export type Attrs = Record<string, undefined|null|string|number|boolean|(string|number)[]>\n\n/**\n * Transform an object into an HTML attributes string. The object should be\n * like `{ attributeName: value }`.\n *\n * @param attrs An object for the attributes.\n * @returns {string} A string suitable for use as HTML attributes.\n */\nexport function toAttributes (attrs:Attrs):string {\n return Object.keys(attrs).reduce((acc, k) => {\n const value = attrs[k]\n if (!value) return acc\n\n if (typeof value === 'boolean') {\n if (value) return (acc + ` ${k}`).trim()\n return acc\n }\n\n if (Array.isArray(value)) {\n return (acc + ` ${k}=\"${value.join(' ')}\"`)\n }\n\n return (acc + ` ${k}=\"${value}\"`).trim()\n }, '')\n}\n", "import { toAttributes } from '@substrate-system/web-component/attributes'\nimport type { ImgAttrs } from './index.js'\n\nexport type SSRAttrs = ImgAttrs & { classes?:string }\n\nexport function render (attrs:SSRAttrs) {\n const {\n width,\n height,\n alt,\n contentVisibility,\n placeholder,\n decoding,\n loading,\n srcset,\n sizes,\n src\n } = attrs\n\n if (!placeholder) throw new Error('not placeholder')\n\n const htmlString = `<canvas\n alt=\"${alt}\"\n width=${width}\n height=${height}\n class=\"blurry\"\n
|
|
5
|
-
"mappings": "sKASO,SAASA,EAAcC,EAAoB,CAC9C,OAAO,OAAO,KAAKA,CAAK,EAAE,OAAO,CAACC,EAAKC,IAAM,CACzC,IAAMC,EAAQH,EAAME,CAAC,EACrB,OAAKC,EAED,OAAOA,GAAU,UACbA,GAAeF,EAAM,IAAIC,CAAC,IAAI,KAAK,EAChCD,EAGP,MAAM,QAAQE,CAAK,EACXF,EAAM,IAAIC,CAAC,KAAKC,EAAM,KAAK,GAAG,CAAC,KAGnCF,EAAM,IAAIC,CAAC,KAAKC,CAAK,KAAK,KAAK,EAXpBF,CAYvB,EAAG,EAAE,CACT,CAhBgBG,EAAAL,EAAA,gBAAAK,EAAAL,EAAA,cAAA,
|
|
6
|
-
"names": ["toAttributes", "attrs", "acc", "k", "value", "__name", "render", "attrs", "width", "height", "alt", "contentVisibility", "placeholder", "decoding", "loading", "srcset", "sizes", "src", "htmlString", "attributeString", "toAttributes", "__name", "outerHTML"]
|
|
3
|
+
"sources": ["../node_modules/@substrate-system/web-component/src/attributes.ts", "../src/decode-dimensions.ts", "../src/html.ts"],
|
|
4
|
+
"sourcesContent": ["export type Attrs = Record<string, undefined|null|string|number|boolean|(string|number)[]>\n\n/**\n * Transform an object into an HTML attributes string. The object should be\n * like `{ attributeName: value }`.\n *\n * @param attrs An object for the attributes.\n * @returns {string} A string suitable for use as HTML attributes.\n */\nexport function toAttributes (attrs:Attrs):string {\n return Object.keys(attrs).reduce((acc, k) => {\n const value = attrs[k]\n if (!value) return acc\n\n if (typeof value === 'boolean') {\n if (value) return (acc + ` ${k}`).trim()\n return acc\n }\n\n if (Array.isArray(value)) {\n return (acc + ` ${k}=\"${value.join(' ')}\"`)\n }\n\n return (acc + ` ${k}=\"${value}\"`).trim()\n }, '')\n}\n", "/**\n * Compute the resolution to decode a BlurHash placeholder at.\n *\n * A placeholder is a low-frequency blur, and decode cost is\n * O(width * height * componentsX * componentsY). Decoding above a small\n * size wastes work with no visible benefit, because the canvas is stretched\n * to fill its host via CSS (`blur-hash canvas { width:100%; height:100% }`).\n *\n * This caps the long edge to `cap` pixels, preserves the aspect ratio, floors\n * each edge at 1px, and never upscales a source that is already small.\n *\n * @param width The layout/source width in pixels.\n * @param height The layout/source height in pixels.\n * @param cap Maximum pixels on the long edge. Default 32.\n * @returns The decode dimensions to pass to `decode` and `createImageData`.\n */\nexport function decodeDimensions (\n width:number,\n height:number,\n cap:number = 32\n):{ width:number; height:number } {\n const longEdge = Math.max(width, height)\n\n // Never upscale: a source at or below the cap decodes as-is.\n if (longEdge <= cap) {\n return { width, height }\n }\n\n const scale = cap / longEdge\n return {\n width: Math.max(1, Math.round(width * scale)),\n height: Math.max(1, Math.round(height * scale))\n }\n}\n", "import { toAttributes } from '@substrate-system/web-component/attributes'\nimport type { ImgAttrs } from './index.js'\nimport { decodeDimensions } from './decode-dimensions.js'\n\nexport type SSRAttrs = ImgAttrs & { classes?:string }\n\nexport function render (attrs:SSRAttrs) {\n const {\n width,\n height,\n alt,\n contentVisibility,\n placeholder,\n decoding,\n loading,\n srcset,\n sizes,\n src\n } = attrs\n\n if (!placeholder) throw new Error('not placeholder')\n\n const decodeWidth = typeof width === 'string' ? parseInt(width, 10) : width\n const decodeHeight = typeof height === 'string' ?\n parseInt(height, 10) :\n height\n const decodeSize = decodeDimensions(decodeWidth, decodeHeight)\n\n const htmlString = `<canvas\n alt=\"${alt}\"\n width=${decodeSize.width}\n height=${decodeSize.height}\n class=\"blurry\"\n ></canvas>\n\n <img class=\"blurry\"\n alt=\"${alt}\"\n content-visibility=\"${contentVisibility || 'auto'}\"\n decoding=\"${decoding || 'async'}\"\n loading=\"${loading || 'lazy'}\"\n ${srcset ? `srcset=\"${srcset}\"` : ''}\n ${sizes ? `sizes=\"${sizes}\"` : ''}\n src=\"${src}\"\n />`\n\n const attributeString = toAttributes(attrs)\n\n // running in node?\n return typeof window === 'undefined' ?\n `<blur-hash ${attributeString}>\n ${htmlString}\n </blur-hash>` :\n htmlString\n}\n\nexport const outerHTML = (attrs:SSRAttrs) => {\n return `<blur-hash>${render(attrs)}</blur-hash>`\n}\n"],
|
|
5
|
+
"mappings": "sKASO,SAASA,EAAcC,EAAoB,CAC9C,OAAO,OAAO,KAAKA,CAAK,EAAE,OAAO,CAACC,EAAKC,IAAM,CACzC,IAAMC,EAAQH,EAAME,CAAC,EACrB,OAAKC,EAED,OAAOA,GAAU,UACbA,GAAeF,EAAM,IAAIC,CAAC,IAAI,KAAK,EAChCD,EAGP,MAAM,QAAQE,CAAK,EACXF,EAAM,IAAIC,CAAC,KAAKC,EAAM,KAAK,GAAG,CAAC,KAGnCF,EAAM,IAAIC,CAAC,KAAKC,CAAK,KAAK,KAAK,EAXpBF,CAYvB,EAAG,EAAE,CACT,CAhBgBG,EAAAL,EAAA,gBAAAK,EAAAL,EAAA,cAAA,ECOT,SAASM,EACZC,EACAC,EACAC,EAAa,GACiB,CAC9B,IAAMC,EAAW,KAAK,IAAIH,EAAOC,CAAM,EAGvC,GAAIE,GAAYD,EACZ,MAAO,CAAE,MAAAF,EAAO,OAAAC,CAAO,EAG3B,IAAMG,EAAQF,EAAMC,EACpB,MAAO,CACH,MAAO,KAAK,IAAI,EAAG,KAAK,MAAMH,EAAQI,CAAK,CAAC,EAC5C,OAAQ,KAAK,IAAI,EAAG,KAAK,MAAMH,EAASG,CAAK,CAAC,CAClD,CACJ,CAjBgBC,EAAAN,EAAA,oBCVT,SAASO,EAAQC,EAAgB,CACpC,GAAM,CACF,MAAAC,EACA,OAAAC,EACA,IAAAC,EACA,kBAAAC,EACA,YAAAC,EACA,SAAAC,EACA,QAAAC,EACA,OAAAC,EACA,MAAAC,EACA,IAAAC,CACJ,EAAIV,EAEJ,GAAI,CAACK,EAAa,MAAM,IAAI,MAAM,iBAAiB,EAEnD,IAAMM,EAAc,OAAOV,GAAU,SAAW,SAASA,EAAO,EAAE,EAAIA,EAChEW,EAAe,OAAOV,GAAW,SACnC,SAASA,EAAQ,EAAE,EACnBA,EACEW,EAAaC,EAAiBH,EAAaC,CAAY,EAEvDG,EAAa;AAAA,eACRZ,CAAG;AAAA,gBACFU,EAAW,KAAK;AAAA,iBACfA,EAAW,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,eAKnBV,CAAG;AAAA,8BACYC,GAAqB,MAAM;AAAA,oBACrCE,GAAY,OAAO;AAAA,mBACpBC,GAAW,MAAM;AAAA,UAC1BC,EAAS,WAAWA,CAAM,IAAM,EAAE;AAAA,UAClCC,EAAQ,UAAUA,CAAK,IAAM,EAAE;AAAA,eAC1BC,CAAG;AAAA,QAGRM,EAAkBC,EAAajB,CAAK,EAG1C,OAAO,OAAO,OAAW,IACrB,cAAcgB,CAAe;AAAA,cACvBD,CAAU;AAAA,sBAEhBA,CACR,CA/CgBG,EAAAnB,EAAA,UAiDT,IAAMoB,EAAYD,EAAClB,GACf,cAAcD,EAAOC,CAAK,CAAC,eADb",
|
|
6
|
+
"names": ["toAttributes", "attrs", "acc", "k", "value", "__name", "decodeDimensions", "width", "height", "cap", "longEdge", "scale", "__name", "render", "attrs", "width", "height", "alt", "contentVisibility", "placeholder", "decoding", "loading", "srcset", "sizes", "src", "decodeWidth", "decodeHeight", "decodeSize", "decodeDimensions", "htmlString", "attributeString", "toAttributes", "__name", "outerHTML"]
|
|
7
7
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -25,11 +25,13 @@ module.exports = __toCommonJS(index_exports);
|
|
|
25
25
|
var import_web_component = require("@substrate-system/web-component");
|
|
26
26
|
var import_blurhash = require("blurhash");
|
|
27
27
|
var import_html = require("./html.js");
|
|
28
|
+
var import_decode_dimensions = require("./decode-dimensions.js");
|
|
28
29
|
class BlurHash extends import_web_component.WebComponent.create("blur-hash") {
|
|
29
30
|
static {
|
|
30
31
|
__name(this, "BlurHash");
|
|
31
32
|
}
|
|
32
33
|
time;
|
|
34
|
+
rafId = null;
|
|
33
35
|
constructor() {
|
|
34
36
|
super();
|
|
35
37
|
const w = this.getAttribute("width");
|
|
@@ -50,16 +52,11 @@ class BlurHash extends import_web_component.WebComponent.create("blur-hash") {
|
|
|
50
52
|
reset(attrs) {
|
|
51
53
|
if (attrs.width) this.style.width = "" + attrs.width;
|
|
52
54
|
if (attrs.height) this.style.height = "" + attrs.height;
|
|
53
|
-
const width = attrs.width ? typeof attrs.width === "string" ? parseInt(attrs.width) : attrs.width : parseInt(this.style.width);
|
|
54
|
-
const height = attrs.height ? typeof attrs.height === "string" ? parseInt(attrs.height) : attrs.height : parseInt(this.style.height);
|
|
55
|
+
const width = attrs.width ? typeof attrs.width === "string" ? parseInt(attrs.width, 10) : attrs.width : parseInt(this.style.width, 10);
|
|
56
|
+
const height = attrs.height ? typeof attrs.height === "string" ? parseInt(attrs.height, 10) : attrs.height : parseInt(this.style.height, 10);
|
|
55
57
|
this.innerHTML = BlurHash.html(Object.assign(attrs, { width, height }));
|
|
56
58
|
const { placeholder, src: newSrc } = attrs;
|
|
57
|
-
|
|
58
|
-
const canvas = this.querySelector("canvas");
|
|
59
|
-
const ctx = canvas.getContext("2d");
|
|
60
|
-
const imageData = ctx.createImageData(width, height);
|
|
61
|
-
imageData.data.set(pixels);
|
|
62
|
-
ctx.putImageData(imageData, 0, 0);
|
|
59
|
+
this.scheduleDecode(placeholder, width, height);
|
|
63
60
|
this.setAttribute("src", newSrc);
|
|
64
61
|
this.setAttribute("placeholder", placeholder);
|
|
65
62
|
const img = this.querySelector("img");
|
|
@@ -67,6 +64,34 @@ class BlurHash extends import_web_component.WebComponent.create("blur-hash") {
|
|
|
67
64
|
if (attrs.sizes) img.setAttribute("sizes", attrs.sizes);
|
|
68
65
|
this.sharpen();
|
|
69
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Decode the placeholder and paint it to the canvas on the next frame.
|
|
69
|
+
* Cancels any pending frame first, so a rapid re-call (e.g. a second
|
|
70
|
+
* `reset`) never leaves a stale decode running. Bails if the element has
|
|
71
|
+
* detached before the frame fires.
|
|
72
|
+
*/
|
|
73
|
+
scheduleDecode(placeholder, width, height) {
|
|
74
|
+
if (this.rafId !== null) cancelAnimationFrame(this.rafId);
|
|
75
|
+
const { width: dw, height: dh } = (0, import_decode_dimensions.decodeDimensions)(width, height);
|
|
76
|
+
this.rafId = requestAnimationFrame(() => {
|
|
77
|
+
this.rafId = null;
|
|
78
|
+
if (!this.isConnected) return;
|
|
79
|
+
const canvas = this.querySelector("canvas");
|
|
80
|
+
if (!canvas) return;
|
|
81
|
+
const ctx = canvas.getContext("2d");
|
|
82
|
+
if (!ctx) return;
|
|
83
|
+
const pixels = (0, import_blurhash.decode)(placeholder, dw, dh);
|
|
84
|
+
const imageData = ctx.createImageData(dw, dh);
|
|
85
|
+
imageData.data.set(pixels);
|
|
86
|
+
ctx.putImageData(imageData, 0, 0);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
disconnectedCallback() {
|
|
90
|
+
if (this.rafId !== null) {
|
|
91
|
+
cancelAnimationFrame(this.rafId);
|
|
92
|
+
this.rafId = null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
70
95
|
sharpen() {
|
|
71
96
|
const img = this.qs("img");
|
|
72
97
|
if (img.complete && img.naturalWidth > 0) {
|
|
@@ -89,12 +114,7 @@ class BlurHash extends import_web_component.WebComponent.create("blur-hash") {
|
|
|
89
114
|
if (!this.innerHTML) {
|
|
90
115
|
this.innerHTML = this.render();
|
|
91
116
|
}
|
|
92
|
-
|
|
93
|
-
const canvas = this.querySelector("canvas");
|
|
94
|
-
const ctx = canvas.getContext("2d");
|
|
95
|
-
const imageData = ctx.createImageData(width, height);
|
|
96
|
-
imageData.data.set(pixels);
|
|
97
|
-
ctx.putImageData(imageData, 0, 0);
|
|
117
|
+
this.scheduleDecode(placeholder, width, height);
|
|
98
118
|
this.sharpen();
|
|
99
119
|
}
|
|
100
120
|
static html(attrs) {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { WebComponent } from '@substrate-system/web-component'\nimport { decode } from 'blurhash'\nimport { render } from './html.js'\n\n// for docuement.querySelector\ndeclare global {\n interface HTMLElementTagNameMap {\n 'blur-hash': BlurHash\n }\n}\n\nexport type ImgAttrs = {\n alt:string;\n width:string|number;\n height:string|number;\n placeholder:string;\n src:string;\n srcset?:string|null;\n sizes?:string|null;\n time?:number;\n contentVisibility?:'visible'|'auto'|'hidden'|null;\n decoding?:'sync'|'async'|'auto'|null;\n loading?:'lazy'|'eager'|'auto'|null;\n}\n\nexport class BlurHash extends WebComponent.create('blur-hash') {\n time:number\n\n constructor () {\n super()\n const w = this.getAttribute('width')\n const h = this.getAttribute('height')\n const time = this.getAttribute('time')\n this.time = time ? parseInt(time) : 800\n\n this.style.width = '' + w\n this.style.height = '' + h\n\n document.body.style.setProperty('--blur-hash-time',\n time ? '.' + (parseInt(time) / 1000 + 's') : '0.8s')\n }\n\n /**\n * Change the image, and do the blur-up thing again.\n * Will use the existing width & height if they are not passed in.\n */\n reset (attrs:(Omit<Omit<ImgAttrs, 'width'>, 'height'> & {\n width?:string|number;\n height?:string|number;\n })):void {\n if (attrs.width) this.style.width = '' + attrs.width\n if (attrs.height) this.style.height = '' + attrs.height\n\n const width = (attrs.width ?\n (typeof attrs.width === 'string' ? parseInt(attrs.width) : attrs.width) :\n parseInt(this.style.width))\n const height = (attrs.height ?\n (typeof attrs.height === 'string' ? parseInt(attrs.height) : attrs.height) :\n parseInt(this.style.height))\n\n this.innerHTML = BlurHash.html(Object.assign(attrs, { width, height }))\n\n const { placeholder, src: newSrc } = attrs\n\n
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAA6B;AAC7B,sBAAuB;AACvB,kBAAuB;
|
|
4
|
+
"sourcesContent": ["import { WebComponent } from '@substrate-system/web-component'\nimport { decode } from 'blurhash'\nimport { render } from './html.js'\nimport { decodeDimensions } from './decode-dimensions.js'\n\n// for docuement.querySelector\ndeclare global {\n interface HTMLElementTagNameMap {\n 'blur-hash': BlurHash\n }\n}\n\nexport type ImgAttrs = {\n alt:string;\n width:string|number;\n height:string|number;\n placeholder:string;\n src:string;\n srcset?:string|null;\n sizes?:string|null;\n time?:number;\n contentVisibility?:'visible'|'auto'|'hidden'|null;\n decoding?:'sync'|'async'|'auto'|null;\n loading?:'lazy'|'eager'|'auto'|null;\n}\n\nexport class BlurHash extends WebComponent.create('blur-hash') {\n time:number\n rafId:number|null = null\n\n constructor () {\n super()\n const w = this.getAttribute('width')\n const h = this.getAttribute('height')\n const time = this.getAttribute('time')\n this.time = time ? parseInt(time) : 800\n\n this.style.width = '' + w\n this.style.height = '' + h\n\n document.body.style.setProperty('--blur-hash-time',\n time ? '.' + (parseInt(time) / 1000 + 's') : '0.8s')\n }\n\n /**\n * Change the image, and do the blur-up thing again.\n * Will use the existing width & height if they are not passed in.\n */\n reset (attrs:(Omit<Omit<ImgAttrs, 'width'>, 'height'> & {\n width?:string|number;\n height?:string|number;\n })):void {\n if (attrs.width) this.style.width = '' + attrs.width\n if (attrs.height) this.style.height = '' + attrs.height\n\n const width = (attrs.width ?\n (typeof attrs.width === 'string' ? parseInt(attrs.width, 10) : attrs.width) :\n parseInt(this.style.width, 10))\n const height = (attrs.height ?\n (typeof attrs.height === 'string' ? parseInt(attrs.height, 10) : attrs.height) :\n parseInt(this.style.height, 10))\n\n this.innerHTML = BlurHash.html(Object.assign(attrs, { width, height }))\n\n const { placeholder, src: newSrc } = attrs\n\n this.scheduleDecode(placeholder, width, height)\n\n this.setAttribute('src', newSrc)\n this.setAttribute('placeholder', placeholder)\n\n const img = this.querySelector('img')!\n if (attrs.srcset) img.setAttribute('srcset', attrs.srcset)\n if (attrs.sizes) img.setAttribute('sizes', attrs.sizes)\n\n this.sharpen()\n }\n\n /**\n * Decode the placeholder and paint it to the canvas on the next frame.\n * Cancels any pending frame first, so a rapid re-call (e.g. a second\n * `reset`) never leaves a stale decode running. Bails if the element has\n * detached before the frame fires.\n */\n scheduleDecode (placeholder:string, width:number, height:number):void {\n if (this.rafId !== null) cancelAnimationFrame(this.rafId)\n\n const { width: dw, height: dh } = decodeDimensions(width, height)\n\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null\n if (!this.isConnected) return\n const canvas = this.querySelector<HTMLCanvasElement>('canvas')\n if (!canvas) return\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n const pixels = decode(placeholder, dw, dh)\n const imageData = ctx.createImageData(dw, dh)\n imageData.data.set(pixels)\n ctx.putImageData(imageData, 0, 0)\n })\n }\n\n disconnectedCallback ():void {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n }\n\n sharpen () {\n const img = this.qs('img')!\n if (img.complete && img.naturalWidth > 0) {\n img.classList.remove('blurry')\n img.classList.add('sharp')\n } else {\n img.addEventListener('load', () => {\n img.classList.remove('blurry')\n img.classList.add('sharp')\n })\n }\n }\n\n connectedCallback () {\n const width = parseInt(this.getAttribute('width') ?? '')\n const height = parseInt(this.getAttribute('height') ?? '')\n const placeholder = this.getAttribute('placeholder')\n if (!placeholder) throw new Error('Missing placeholder')\n if (!width) throw new Error('Missing width')\n if (!height) throw new Error('Missing height')\n\n // don't render again if we dont have to\n if (!this.innerHTML) {\n this.innerHTML = this.render()\n }\n\n this.scheduleDecode(placeholder, width, height)\n this.sharpen()\n }\n\n static html (attrs:ImgAttrs & { classes?:string }) {\n return render(attrs)\n }\n\n /**\n * Use the attributes to create HTML.\n */\n render ():string {\n const srcset = this.getAttribute('srcset')\n const width = this.getAttribute('width')\n const height = this.getAttribute('height')\n const time = this.getAttribute('time')\n const classes = this.classList.toString()\n const placeholder = this.getAttribute('placeholder')\n this.time = time ? parseInt(time) : 800\n const src = this.getAttribute('src')\n const alt = this.getAttribute('alt')\n if (!placeholder) throw new Error('not placeholder')\n if (!width || !height) throw new Error('not width or not height')\n if (!src) throw new Error('Not src')\n if (!alt) throw new Error('Not alt')\n\n return BlurHash.html({ classes, srcset, width, height, src, alt, placeholder })\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ declare const BlurHash_base: typeof WebComponent & {
|
|
|
25
25
|
};
|
|
26
26
|
export declare class BlurHash extends BlurHash_base {
|
|
27
27
|
time: number;
|
|
28
|
+
rafId: number | null;
|
|
28
29
|
constructor();
|
|
29
30
|
/**
|
|
30
31
|
* Change the image, and do the blur-up thing again.
|
|
@@ -34,6 +35,14 @@ export declare class BlurHash extends BlurHash_base {
|
|
|
34
35
|
width?: string | number;
|
|
35
36
|
height?: string | number;
|
|
36
37
|
})): void;
|
|
38
|
+
/**
|
|
39
|
+
* Decode the placeholder and paint it to the canvas on the next frame.
|
|
40
|
+
* Cancels any pending frame first, so a rapid re-call (e.g. a second
|
|
41
|
+
* `reset`) never leaves a stale decode running. Bails if the element has
|
|
42
|
+
* detached before the frame fires.
|
|
43
|
+
*/
|
|
44
|
+
scheduleDecode(placeholder: string, width: number, height: number): void;
|
|
45
|
+
disconnectedCallback(): void;
|
|
37
46
|
sharpen(): void;
|
|
38
47
|
connectedCallback(): void;
|
|
39
48
|
static html(attrs: ImgAttrs & {
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AAM9D,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,WAAW,EAAE,QAAQ,CAAA;KACxB;CACJ;AAED,MAAM,MAAM,QAAQ,GAAG;IACnB,GAAG,EAAC,MAAM,CAAC;IACX,KAAK,EAAC,MAAM,GAAC,MAAM,CAAC;IACpB,MAAM,EAAC,MAAM,GAAC,MAAM,CAAC;IACrB,WAAW,EAAC,MAAM,CAAC;IACnB,GAAG,EAAC,MAAM,CAAC;IACX,MAAM,CAAC,EAAC,MAAM,GAAC,IAAI,CAAC;IACpB,KAAK,CAAC,EAAC,MAAM,GAAC,IAAI,CAAC;IACnB,IAAI,CAAC,EAAC,MAAM,CAAC;IACb,iBAAiB,CAAC,EAAC,SAAS,GAAC,MAAM,GAAC,QAAQ,GAAC,IAAI,CAAC;IAClD,QAAQ,CAAC,EAAC,MAAM,GAAC,OAAO,GAAC,MAAM,GAAC,IAAI,CAAC;IACrC,OAAO,CAAC,EAAC,MAAM,GAAC,OAAO,GAAC,MAAM,GAAC,IAAI,CAAC;CACvC,CAAA;;;;;;;AAED,qBAAa,QAAS,SAAQ,aAAgC;IAC1D,IAAI,EAAC,MAAM,CAAA;IACX,KAAK,EAAC,MAAM,GAAC,IAAI,CAAO;;IAgBxB;;;OAGG;IACH,KAAK,CAAE,KAAK,EAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,GAAG;QACpD,KAAK,CAAC,EAAC,MAAM,GAAC,MAAM,CAAC;QACrB,MAAM,CAAC,EAAC,MAAM,GAAC,MAAM,CAAC;KACzB,CAAC,GAAE,IAAI;IA2BR;;;;;OAKG;IACH,cAAc,CAAE,WAAW,EAAC,MAAM,EAAE,KAAK,EAAC,MAAM,EAAE,MAAM,EAAC,MAAM,GAAE,IAAI;IAmBrE,oBAAoB,IAAI,IAAI;IAO5B,OAAO;IAaP,iBAAiB;IAiBjB,MAAM,CAAC,IAAI,CAAE,KAAK,EAAC,QAAQ,GAAG;QAAE,OAAO,CAAC,EAAC,MAAM,CAAA;KAAE;IAIjD;;OAEG;IACH,MAAM,IAAI,MAAM;CAiBnB"}
|
package/dist/index.js
CHANGED
|
@@ -3,11 +3,13 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
3
3
|
import { WebComponent } from "@substrate-system/web-component";
|
|
4
4
|
import { decode } from "blurhash";
|
|
5
5
|
import { render } from "./html.js";
|
|
6
|
+
import { decodeDimensions } from "./decode-dimensions.js";
|
|
6
7
|
class BlurHash extends WebComponent.create("blur-hash") {
|
|
7
8
|
static {
|
|
8
9
|
__name(this, "BlurHash");
|
|
9
10
|
}
|
|
10
11
|
time;
|
|
12
|
+
rafId = null;
|
|
11
13
|
constructor() {
|
|
12
14
|
super();
|
|
13
15
|
const w = this.getAttribute("width");
|
|
@@ -28,16 +30,11 @@ class BlurHash extends WebComponent.create("blur-hash") {
|
|
|
28
30
|
reset(attrs) {
|
|
29
31
|
if (attrs.width) this.style.width = "" + attrs.width;
|
|
30
32
|
if (attrs.height) this.style.height = "" + attrs.height;
|
|
31
|
-
const width = attrs.width ? typeof attrs.width === "string" ? parseInt(attrs.width) : attrs.width : parseInt(this.style.width);
|
|
32
|
-
const height = attrs.height ? typeof attrs.height === "string" ? parseInt(attrs.height) : attrs.height : parseInt(this.style.height);
|
|
33
|
+
const width = attrs.width ? typeof attrs.width === "string" ? parseInt(attrs.width, 10) : attrs.width : parseInt(this.style.width, 10);
|
|
34
|
+
const height = attrs.height ? typeof attrs.height === "string" ? parseInt(attrs.height, 10) : attrs.height : parseInt(this.style.height, 10);
|
|
33
35
|
this.innerHTML = BlurHash.html(Object.assign(attrs, { width, height }));
|
|
34
36
|
const { placeholder, src: newSrc } = attrs;
|
|
35
|
-
|
|
36
|
-
const canvas = this.querySelector("canvas");
|
|
37
|
-
const ctx = canvas.getContext("2d");
|
|
38
|
-
const imageData = ctx.createImageData(width, height);
|
|
39
|
-
imageData.data.set(pixels);
|
|
40
|
-
ctx.putImageData(imageData, 0, 0);
|
|
37
|
+
this.scheduleDecode(placeholder, width, height);
|
|
41
38
|
this.setAttribute("src", newSrc);
|
|
42
39
|
this.setAttribute("placeholder", placeholder);
|
|
43
40
|
const img = this.querySelector("img");
|
|
@@ -45,6 +42,34 @@ class BlurHash extends WebComponent.create("blur-hash") {
|
|
|
45
42
|
if (attrs.sizes) img.setAttribute("sizes", attrs.sizes);
|
|
46
43
|
this.sharpen();
|
|
47
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Decode the placeholder and paint it to the canvas on the next frame.
|
|
47
|
+
* Cancels any pending frame first, so a rapid re-call (e.g. a second
|
|
48
|
+
* `reset`) never leaves a stale decode running. Bails if the element has
|
|
49
|
+
* detached before the frame fires.
|
|
50
|
+
*/
|
|
51
|
+
scheduleDecode(placeholder, width, height) {
|
|
52
|
+
if (this.rafId !== null) cancelAnimationFrame(this.rafId);
|
|
53
|
+
const { width: dw, height: dh } = decodeDimensions(width, height);
|
|
54
|
+
this.rafId = requestAnimationFrame(() => {
|
|
55
|
+
this.rafId = null;
|
|
56
|
+
if (!this.isConnected) return;
|
|
57
|
+
const canvas = this.querySelector("canvas");
|
|
58
|
+
if (!canvas) return;
|
|
59
|
+
const ctx = canvas.getContext("2d");
|
|
60
|
+
if (!ctx) return;
|
|
61
|
+
const pixels = decode(placeholder, dw, dh);
|
|
62
|
+
const imageData = ctx.createImageData(dw, dh);
|
|
63
|
+
imageData.data.set(pixels);
|
|
64
|
+
ctx.putImageData(imageData, 0, 0);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
disconnectedCallback() {
|
|
68
|
+
if (this.rafId !== null) {
|
|
69
|
+
cancelAnimationFrame(this.rafId);
|
|
70
|
+
this.rafId = null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
48
73
|
sharpen() {
|
|
49
74
|
const img = this.qs("img");
|
|
50
75
|
if (img.complete && img.naturalWidth > 0) {
|
|
@@ -67,12 +92,7 @@ class BlurHash extends WebComponent.create("blur-hash") {
|
|
|
67
92
|
if (!this.innerHTML) {
|
|
68
93
|
this.innerHTML = this.render();
|
|
69
94
|
}
|
|
70
|
-
|
|
71
|
-
const canvas = this.querySelector("canvas");
|
|
72
|
-
const ctx = canvas.getContext("2d");
|
|
73
|
-
const imageData = ctx.createImageData(width, height);
|
|
74
|
-
imageData.data.set(pixels);
|
|
75
|
-
ctx.putImageData(imageData, 0, 0);
|
|
95
|
+
this.scheduleDecode(placeholder, width, height);
|
|
76
96
|
this.sharpen();
|
|
77
97
|
}
|
|
78
98
|
static html(attrs) {
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { WebComponent } from '@substrate-system/web-component'\nimport { decode } from 'blurhash'\nimport { render } from './html.js'\n\n// for docuement.querySelector\ndeclare global {\n interface HTMLElementTagNameMap {\n 'blur-hash': BlurHash\n }\n}\n\nexport type ImgAttrs = {\n alt:string;\n width:string|number;\n height:string|number;\n placeholder:string;\n src:string;\n srcset?:string|null;\n sizes?:string|null;\n time?:number;\n contentVisibility?:'visible'|'auto'|'hidden'|null;\n decoding?:'sync'|'async'|'auto'|null;\n loading?:'lazy'|'eager'|'auto'|null;\n}\n\nexport class BlurHash extends WebComponent.create('blur-hash') {\n time:number\n\n constructor () {\n super()\n const w = this.getAttribute('width')\n const h = this.getAttribute('height')\n const time = this.getAttribute('time')\n this.time = time ? parseInt(time) : 800\n\n this.style.width = '' + w\n this.style.height = '' + h\n\n document.body.style.setProperty('--blur-hash-time',\n time ? '.' + (parseInt(time) / 1000 + 's') : '0.8s')\n }\n\n /**\n * Change the image, and do the blur-up thing again.\n * Will use the existing width & height if they are not passed in.\n */\n reset (attrs:(Omit<Omit<ImgAttrs, 'width'>, 'height'> & {\n width?:string|number;\n height?:string|number;\n })):void {\n if (attrs.width) this.style.width = '' + attrs.width\n if (attrs.height) this.style.height = '' + attrs.height\n\n const width = (attrs.width ?\n (typeof attrs.width === 'string' ? parseInt(attrs.width) : attrs.width) :\n parseInt(this.style.width))\n const height = (attrs.height ?\n (typeof attrs.height === 'string' ? parseInt(attrs.height) : attrs.height) :\n parseInt(this.style.height))\n\n this.innerHTML = BlurHash.html(Object.assign(attrs, { width, height }))\n\n const { placeholder, src: newSrc } = attrs\n\n
|
|
5
|
-
"mappings": ";;AAAA,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AACvB,SAAS,cAAc;
|
|
4
|
+
"sourcesContent": ["import { WebComponent } from '@substrate-system/web-component'\nimport { decode } from 'blurhash'\nimport { render } from './html.js'\nimport { decodeDimensions } from './decode-dimensions.js'\n\n// for docuement.querySelector\ndeclare global {\n interface HTMLElementTagNameMap {\n 'blur-hash': BlurHash\n }\n}\n\nexport type ImgAttrs = {\n alt:string;\n width:string|number;\n height:string|number;\n placeholder:string;\n src:string;\n srcset?:string|null;\n sizes?:string|null;\n time?:number;\n contentVisibility?:'visible'|'auto'|'hidden'|null;\n decoding?:'sync'|'async'|'auto'|null;\n loading?:'lazy'|'eager'|'auto'|null;\n}\n\nexport class BlurHash extends WebComponent.create('blur-hash') {\n time:number\n rafId:number|null = null\n\n constructor () {\n super()\n const w = this.getAttribute('width')\n const h = this.getAttribute('height')\n const time = this.getAttribute('time')\n this.time = time ? parseInt(time) : 800\n\n this.style.width = '' + w\n this.style.height = '' + h\n\n document.body.style.setProperty('--blur-hash-time',\n time ? '.' + (parseInt(time) / 1000 + 's') : '0.8s')\n }\n\n /**\n * Change the image, and do the blur-up thing again.\n * Will use the existing width & height if they are not passed in.\n */\n reset (attrs:(Omit<Omit<ImgAttrs, 'width'>, 'height'> & {\n width?:string|number;\n height?:string|number;\n })):void {\n if (attrs.width) this.style.width = '' + attrs.width\n if (attrs.height) this.style.height = '' + attrs.height\n\n const width = (attrs.width ?\n (typeof attrs.width === 'string' ? parseInt(attrs.width, 10) : attrs.width) :\n parseInt(this.style.width, 10))\n const height = (attrs.height ?\n (typeof attrs.height === 'string' ? parseInt(attrs.height, 10) : attrs.height) :\n parseInt(this.style.height, 10))\n\n this.innerHTML = BlurHash.html(Object.assign(attrs, { width, height }))\n\n const { placeholder, src: newSrc } = attrs\n\n this.scheduleDecode(placeholder, width, height)\n\n this.setAttribute('src', newSrc)\n this.setAttribute('placeholder', placeholder)\n\n const img = this.querySelector('img')!\n if (attrs.srcset) img.setAttribute('srcset', attrs.srcset)\n if (attrs.sizes) img.setAttribute('sizes', attrs.sizes)\n\n this.sharpen()\n }\n\n /**\n * Decode the placeholder and paint it to the canvas on the next frame.\n * Cancels any pending frame first, so a rapid re-call (e.g. a second\n * `reset`) never leaves a stale decode running. Bails if the element has\n * detached before the frame fires.\n */\n scheduleDecode (placeholder:string, width:number, height:number):void {\n if (this.rafId !== null) cancelAnimationFrame(this.rafId)\n\n const { width: dw, height: dh } = decodeDimensions(width, height)\n\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null\n if (!this.isConnected) return\n const canvas = this.querySelector<HTMLCanvasElement>('canvas')\n if (!canvas) return\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n const pixels = decode(placeholder, dw, dh)\n const imageData = ctx.createImageData(dw, dh)\n imageData.data.set(pixels)\n ctx.putImageData(imageData, 0, 0)\n })\n }\n\n disconnectedCallback ():void {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n }\n\n sharpen () {\n const img = this.qs('img')!\n if (img.complete && img.naturalWidth > 0) {\n img.classList.remove('blurry')\n img.classList.add('sharp')\n } else {\n img.addEventListener('load', () => {\n img.classList.remove('blurry')\n img.classList.add('sharp')\n })\n }\n }\n\n connectedCallback () {\n const width = parseInt(this.getAttribute('width') ?? '')\n const height = parseInt(this.getAttribute('height') ?? '')\n const placeholder = this.getAttribute('placeholder')\n if (!placeholder) throw new Error('Missing placeholder')\n if (!width) throw new Error('Missing width')\n if (!height) throw new Error('Missing height')\n\n // don't render again if we dont have to\n if (!this.innerHTML) {\n this.innerHTML = this.render()\n }\n\n this.scheduleDecode(placeholder, width, height)\n this.sharpen()\n }\n\n static html (attrs:ImgAttrs & { classes?:string }) {\n return render(attrs)\n }\n\n /**\n * Use the attributes to create HTML.\n */\n render ():string {\n const srcset = this.getAttribute('srcset')\n const width = this.getAttribute('width')\n const height = this.getAttribute('height')\n const time = this.getAttribute('time')\n const classes = this.classList.toString()\n const placeholder = this.getAttribute('placeholder')\n this.time = time ? parseInt(time) : 800\n const src = this.getAttribute('src')\n const alt = this.getAttribute('alt')\n if (!placeholder) throw new Error('not placeholder')\n if (!width || !height) throw new Error('not width or not height')\n if (!src) throw new Error('Not src')\n if (!alt) throw new Error('Not alt')\n\n return BlurHash.html({ classes, srcset, width, height, src, alt, placeholder })\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/index.min.js
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
var j=Object.defineProperty;var
|
|
1
|
+
var j=Object.defineProperty;var s=(e,t)=>j(e,"name",{value:t,configurable:!0});var V=Object.defineProperty,k=s((e,t)=>V(e,"name",{value:t,configurable:!0}),"__name");function v(e){return Object.keys(e).reduce((t,r)=>{let i=e[r];return i?typeof i=="boolean"?i?(t+` ${r}`).trim():t:Array.isArray(i)?t+` ${r}="${i.join(" ")}"`:(t+` ${r}="${i}"`).trim():t},"")}s(v,"toAttributes");k(v,"toAttributes");var F=Object.defineProperty,I=s((e,t)=>F(e,"name",{value:t,configurable:!0}),"__name");function S(e){return document.createElement(e).constructor!==window.HTMLElement}s(S,"isRegistered");I(S,"isRegistered");function B(e,t){window&&"customElements"in window&&(S(e)||window.customElements.define(e,t))}s(B,"define");I(B,"define");var nt=document.querySelector.bind(document),st=document.querySelectorAll.bind(document);function $(e,t){return e.matches||(e=e.parentElement),e.matches(t)?e:e.closest(t)}s($,"match");I($,"match");var U=Object.defineProperty,b=s((e,t)=>U(e,"name",{value:t,configurable:!0}),"__name"),E=class e extends window.HTMLElement{static{s(this,"WebComponent")}static{b(this,"WebComponent")}static TAG="";TAG="";static match(t){return $(t,this.TAG)}_globalWildcardListeners=new Set;_namespacedWildcardListeners=new Set;static create(t){let r=class extends e{static{s(this,"CreatedClass")}static{b(this,"CreatedClass")}static TAG=t;TAG=t;render(){throw new Error("`render` should be implemented by children")}};return r.define=function(){return e.define.call(this)},r.event=function(i){return e.event.call(this,i)},r}static define(){z(this.TAG,this)}async attributeChangedCallback(t,r,i){let n=this[`handleChange_${t}`];n&&await n.call(this,r,i)}addEventListener(t,r,i){t===e.event.call(this,"*")?this._namespacedWildcardListeners.add({listener:r,options:i}):t==="*"?r&&this._globalWildcardListeners.add({listener:r,options:i}):super.addEventListener(t,r,i)}_notifyNamespacedWildcardListeners(t){if(this._namespacedWildcardListeners.size===0)return;let r=this.TAG;!r||!t.type.startsWith(`${r}:`)||this._namespacedWildcardListeners.forEach(({listener:i})=>{try{typeof i=="function"?i.call(this,t):i&&typeof i.handleEvent=="function"&&i.handleEvent(t)}catch(n){console.error("Error in namespaced wildcard event listener:",n)}})}_notifyGlobalWildcardListeners(t){this._globalWildcardListeners.size!==0&&this._globalWildcardListeners.forEach(({listener:r})=>{try{typeof r=="function"?r.call(this,t):r&&typeof r.handleEvent=="function"&&r.handleEvent(t)}catch(i){console.error("Error in global wildcard event listener:",i)}})}connectedCallback(){this.render()}qs(t){return this.querySelector(t)}qsa(t){return this.querySelectorAll(t)}static event(t){return C(this.TAG,t)}emit(t,r={}){if(t==="*")throw new Error('Do not emit the literal "*"');let{bubbles:i=!0,cancelable:n=!0,detail:l}=r,o=`${this.TAG}:${t}`,c=new CustomEvent(o,{bubbles:i,cancelable:n,detail:l}),h=this.dispatchEvent(c);return this._notifyNamespacedWildcardListeners(c),h}dispatchEvent(t){let r=super.dispatchEvent(t);return this._notifyGlobalWildcardListeners(t),r}dispatch(t,r={}){let i=new CustomEvent(t,{bubbles:r.bubbles===void 0?!0:r.bubbles,cancelable:r.cancelable===void 0?!0:r.cancelable,detail:r.detail});return this.dispatchEvent(i)}on(t,r,i){let n=e.event.call(this,t);this.addEventListener(n,r,i)}removeEventListener(t,r,i){if(t===e.event.call(this,"*")){if(r&&this._namespacedWildcardListeners){for(let n of this._namespacedWildcardListeners)if(n.listener===r){this._namespacedWildcardListeners.delete(n);break}}}else if(t==="*"){if(r&&this._globalWildcardListeners){for(let n of this._globalWildcardListeners)if(n.listener===r){this._globalWildcardListeners.delete(n);break}}}else super.removeEventListener(t,r,i)}};function C(e,t){return`${e}:${t}`}s(C,"eventName");b(C,"eventName");function q(e){return document.createElement(e).constructor!==window.HTMLElement}s(q,"isRegistered");b(q,"isRegistered");function z(e,t){window&&"customElements"in window&&(q(e)||window.customElements.define(e,t))}s(z,"define");b(z,"define");var J=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","#","$","%","*","+",",","-",".",":",";","=","?","@","[","]","^","_","{","|","}","~"],p=s(e=>{let t=0;for(let r=0;r<e.length;r++){let i=e[r],n=J.indexOf(i);t=t*83+n}return t},"x");var _=s(e=>{let t=e/255;return t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)},"f"),W=s(e=>{let t=Math.max(0,Math.min(1,e));return t<=.0031308?Math.trunc(t*12.92*255+.5):Math.trunc((1.055*Math.pow(t,.4166666666666667)-.055)*255+.5)},"h"),K=s(e=>e<0?-1:1,"F"),T=s((e,t)=>K(e)*Math.pow(Math.abs(e),t),"M"),G=class extends Error{static{s(this,"d")}constructor(e){super(e),this.name="ValidationError",this.message=e}},Q=s(e=>{if(!e||e.length<6)throw new G("The blurhash string must be at least 6 characters");let t=p(e[0]),r=Math.floor(t/9)+1,i=t%9+1;if(e.length!==4+2*i*r)throw new G(`blurhash length mismatch: length is ${e.length} but it should be ${4+2*i*r}`)},"C");var X=s(e=>{let t=e>>16,r=e>>8&255,i=e&255;return[_(t),_(r),_(i)]},"z"),Y=s((e,t)=>{let r=Math.floor(e/361),i=Math.floor(e/19)%19,n=e%19;return[T((r-9)/9,2)*t,T((i-9)/9,2)*t,T((n-9)/9,2)*t]},"L"),Z=s((e,t,r,i)=>{Q(e),i=i|1;let n=p(e[0]),l=Math.floor(n/9)+1,o=n%9+1,c=(p(e[1])+1)/166,h=new Array(o*l);for(let a=0;a<h.length;a++)if(a===0){let d=p(e.substring(2,6));h[a]=X(d)}else{let d=p(e.substring(4+a*2,6+a*2));h[a]=Y(d,c*i)}let u=t*4,m=new Uint8ClampedArray(u*r);for(let a=0;a<r;a++)for(let d=0;d<t;d++){let f=0,g=0,w=0;for(let M=0;M<l;M++)for(let y=0;y<o;y++){let L=Math.cos(Math.PI*d*y/t)*Math.cos(Math.PI*a*M/r),x=h[y+M*o];f+=x[0]*L,g+=x[1]*L,w+=x[2]*L}let N=W(f),O=W(g),R=W(w);m[4*d+0+a*u]=N,m[4*d+1+a*u]=O,m[4*d+2+a*u]=R,m[4*d+3+a*u]=255}return m},"U"),H=Z;function A(e,t,r=32){let i=Math.max(e,t);if(i<=r)return{width:e,height:t};let n=r/i;return{width:Math.max(1,Math.round(e*n)),height:Math.max(1,Math.round(t*n))}}s(A,"decodeDimensions");function P(e){let{width:t,height:r,alt:i,contentVisibility:n,placeholder:l,decoding:o,loading:c,srcset:h,sizes:u,src:m}=e;if(!l)throw new Error("not placeholder");let a=typeof t=="string"?parseInt(t,10):t,d=typeof r=="string"?parseInt(r,10):r,f=A(a,d),g=`<canvas
|
|
2
2
|
alt="${i}"
|
|
3
|
-
width=${
|
|
4
|
-
height=${
|
|
3
|
+
width=${f.width}
|
|
4
|
+
height=${f.height}
|
|
5
5
|
class="blurry"
|
|
6
|
-
width=${t}
|
|
7
|
-
height=${r}
|
|
8
6
|
></canvas>
|
|
9
7
|
|
|
10
8
|
<img class="blurry"
|
|
11
9
|
alt="${i}"
|
|
12
|
-
content-visibility="${
|
|
10
|
+
content-visibility="${n||"auto"}"
|
|
13
11
|
decoding="${o||"async"}"
|
|
14
|
-
loading="${
|
|
12
|
+
loading="${c||"lazy"}"
|
|
15
13
|
${h?`srcset="${h}"`:""}
|
|
16
14
|
${u?`sizes="${u}"`:""}
|
|
17
15
|
src="${m}"
|
|
18
|
-
/>`,
|
|
19
|
-
${
|
|
20
|
-
</blur-hash>`:
|
|
16
|
+
/>`,w=v(e);return typeof window>"u"?`<blur-hash ${w}>
|
|
17
|
+
${g}
|
|
18
|
+
</blur-hash>`:g}s(P,"render");var D=class e extends E.create("blur-hash"){static{s(this,"BlurHash")}time;rafId=null;constructor(){super();let t=this.getAttribute("width"),r=this.getAttribute("height"),i=this.getAttribute("time");this.time=i?parseInt(i):800,this.style.width=""+t,this.style.height=""+r,document.body.style.setProperty("--blur-hash-time",i?"."+(parseInt(i)/1e3+"s"):"0.8s")}reset(t){t.width&&(this.style.width=""+t.width),t.height&&(this.style.height=""+t.height);let r=t.width?typeof t.width=="string"?parseInt(t.width,10):t.width:parseInt(this.style.width,10),i=t.height?typeof t.height=="string"?parseInt(t.height,10):t.height:parseInt(this.style.height,10);this.innerHTML=e.html(Object.assign(t,{width:r,height:i}));let{placeholder:n,src:l}=t;this.scheduleDecode(n,r,i),this.setAttribute("src",l),this.setAttribute("placeholder",n);let o=this.querySelector("img");t.srcset&&o.setAttribute("srcset",t.srcset),t.sizes&&o.setAttribute("sizes",t.sizes),this.sharpen()}scheduleDecode(t,r,i){this.rafId!==null&&cancelAnimationFrame(this.rafId);let{width:n,height:l}=A(r,i);this.rafId=requestAnimationFrame(()=>{if(this.rafId=null,!this.isConnected)return;let o=this.querySelector("canvas");if(!o)return;let c=o.getContext("2d");if(!c)return;let h=H(t,n,l),u=c.createImageData(n,l);u.data.set(h),c.putImageData(u,0,0)})}disconnectedCallback(){this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null)}sharpen(){let t=this.qs("img");t.complete&&t.naturalWidth>0?(t.classList.remove("blurry"),t.classList.add("sharp")):t.addEventListener("load",()=>{t.classList.remove("blurry"),t.classList.add("sharp")})}connectedCallback(){let t=parseInt(this.getAttribute("width")??""),r=parseInt(this.getAttribute("height")??""),i=this.getAttribute("placeholder");if(!i)throw new Error("Missing placeholder");if(!t)throw new Error("Missing width");if(!r)throw new Error("Missing height");this.innerHTML||(this.innerHTML=this.render()),this.scheduleDecode(i,t,r),this.sharpen()}static html(t){return P(t)}render(){let t=this.getAttribute("srcset"),r=this.getAttribute("width"),i=this.getAttribute("height"),n=this.getAttribute("time"),l=this.classList.toString(),o=this.getAttribute("placeholder");this.time=n?parseInt(n):800;let c=this.getAttribute("src"),h=this.getAttribute("alt");if(!o)throw new Error("not placeholder");if(!r||!i)throw new Error("not width or not height");if(!c)throw new Error("Not src");if(!h)throw new Error("Not alt");return e.html({classes:l,srcset:t,width:r,height:i,src:c,alt:h,placeholder:o})}};export{D as BlurHash};
|
|
21
19
|
//# sourceMappingURL=index.min.js.map
|
package/dist/index.min.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../node_modules/@substrate-system/web-component/src/attributes.ts", "../node_modules/@substrate-system/web-component/src/util.ts", "../node_modules/@substrate-system/web-component/src/index.ts", "../node_modules/blurhash/src/base83.ts", "../node_modules/blurhash/src/utils.ts", "../node_modules/blurhash/src/error.ts", "../node_modules/blurhash/src/decode.ts", "../node_modules/blurhash/src/encode.ts", "../src/html.ts", "../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["export type Attrs = Record<string, undefined|null|string|number|boolean|(string|number)[]>\n\n/**\n * Transform an object into an HTML attributes string. The object should be\n * like `{ attributeName: value }`.\n *\n * @param attrs An object for the attributes.\n * @returns {string} A string suitable for use as HTML attributes.\n */\nexport function toAttributes (attrs:Attrs):string {\n return Object.keys(attrs).reduce((acc, k) => {\n const value = attrs[k]\n if (!value) return acc\n\n if (typeof value === 'boolean') {\n if (value) return (acc + ` ${k}`).trim()\n return acc\n }\n\n if (Array.isArray(value)) {\n return (acc + ` ${k}=\"${value.join(' ')}\"`)\n }\n\n return (acc + ` ${k}=\"${value}\"`).trim()\n }, '')\n}\n", "export { toAttributes } from './attributes.js'\n\n/**\n * Check if the given tag name has been registered.\n *\n * @see {@link https://stackoverflow.com/a/28210364 stackoverflow}\n * @param {string} elName The custom element tag name.\n * @returns {boolean} True if the given name has been registered already.\n */\nexport function isRegistered (elName:string):boolean {\n return document.createElement(elName).constructor !== window.HTMLElement\n}\n\nexport function define (name:string, element:CustomElementConstructor) {\n if (!window) return\n if (!('customElements' in window)) return\n\n if (!isRegistered(name)) {\n window.customElements.define(name, element)\n }\n}\n\nexport const qs = document.querySelector.bind(document)\nexport const qsa = document.querySelectorAll.bind(document)\n\n/**\n * Get the closes parent element matching the given selector.\n * @param el Element to start from\n * @param s Selector for an element\n * @returns {HTMLElement|null} The closes parent element that matches.\n */\nexport function match (el:HTMLElement, s:string):HTMLElement|null {\n if (!el.matches) el = el.parentElement!\n return el.matches(s) ? el : el.closest(s)\n}\n", "import { match as _match } from './util.js'\n\ninterface WildcardListenerEntry {\n listener:EventListenerOrEventListenerObject\n options?:boolean|AddEventListenerOptions\n}\n\nexport abstract class WebComponent extends window.HTMLElement {\n static TAG:string = ''\n TAG:string = ''\n\n static match (el:HTMLElement):HTMLElement|null {\n return _match(el, this.TAG)\n }\n\n /**\n * Store global wildcard listeners (listen to all events)\n * Triggered by ALL events dispatched through this element\n * @private\n */\n private _globalWildcardListeners:Set<WildcardListenerEntry> = new Set()\n\n /**\n * Store namespaced wildcard listeners (listen to 'component-name:*')\n * Triggered by events from emit() that match this component's namespace\n * @private\n */\n private _namespacedWildcardListeners:Set<WildcardListenerEntry> = new Set()\n\n static create (elementName:string):typeof WebComponent & {\n new (...args:any[]):WebComponent;\n TAG:string;\n define: typeof WebComponent.define;\n event: typeof WebComponent.event;\n } {\n const CreatedClass = class extends WebComponent {\n static TAG = elementName\n TAG = elementName\n render () {\n throw new Error('`render` should be implemented by children')\n }\n }\n\n // Copy static methods with proper binding\n CreatedClass.define = function () {\n return WebComponent.define.call(this)\n }\n CreatedClass.event = function (evType:string) {\n return WebComponent.event.call(this, evType)\n }\n\n return CreatedClass\n }\n\n static define<T extends {\n new (...args:any[]):WebComponent;\n TAG:string;\n }>(this:T) {\n define(this.TAG, this)\n }\n\n /**\n * Runs when the value of an attribute is changed.\n *\n * Depends on `static observedAttributes`.\n *\n * Should name methods like `handleChange_disabled`.\n *\n * @param {string} name The attribute name\n * @param {string} oldValue The old attribute value\n * @param {string} newValue The new attribute value\n */\n async attributeChangedCallback (\n name:string,\n oldValue:string,\n newValue:string\n ):Promise<void> {\n const handler = this[`handleChange_${name}`]\n if (handler) {\n await handler.call(this, oldValue, newValue)\n }\n }\n\n /**\n * Enhanced addEventListener that supports wildcards:\n * - Component.event('*') - Listen to all namespaced events for this\n * component (e.g., 'my-component:*')\n * - '*' - Listen to ALL events (namespaced and non-namespaced, including\n * normal DOM events)\n *\n * @param type - Event type, Component.event('*') for namespaced wildcard,\n * or '*' for global wildcard\n * @param listener - Event listener function or object\n * @param options - Event listener options\n */\n addEventListener (\n type:string,\n listener:EventListenerOrEventListenerObject,\n options?:boolean|AddEventListenerOptions\n ): void {\n if (type === WebComponent.event.call(this, '*')) {\n // Handle namespaced wildcard listener (component-name:*)\n this._namespacedWildcardListeners.add({ listener, options })\n } else if (type === '*') {\n // Handle global wildcard listener (all events)\n if (listener) {\n this._globalWildcardListeners.add({ listener, options })\n }\n } else {\n // Normal event listener - delegate to native implementation\n super.addEventListener(type, listener, options)\n }\n }\n\n /**\n * Notify namespaced wildcard listeners of an event\n * Only fires for events that match this component's namespace\n *\n * @param event - The event to dispatch to namespaced wildcard listeners\n * @private\n */\n private _notifyNamespacedWildcardListeners (event: Event): void {\n if (this._namespacedWildcardListeners.size === 0) {\n return\n }\n\n const componentName = this.TAG\n\n // Only trigger for events in this component's namespace\n if (!componentName || !event.type.startsWith(`${componentName}:`)) {\n return\n }\n\n // Call each namespaced wildcard listener\n this._namespacedWildcardListeners.forEach(({ listener }) => {\n try {\n if (typeof listener === 'function') {\n listener.call(this, event)\n } else if (listener && typeof listener.handleEvent === 'function') {\n listener.handleEvent(event)\n }\n } catch (error) {\n // Log errors but don't let one listener break others\n console.error(\n 'Error in namespaced wildcard event listener:',\n error\n )\n }\n })\n }\n\n /**\n * Notify global wildcard listeners of an event\n * Fires for ALL events dispatched through this element\n *\n * @param event - The event to dispatch to global wildcard listeners\n * @private\n */\n private _notifyGlobalWildcardListeners (event: Event): void {\n if (this._globalWildcardListeners.size === 0) {\n return\n }\n\n // Call each global wildcard listener\n this._globalWildcardListeners.forEach(({ listener }) => {\n try {\n if (typeof listener === 'function') {\n listener.call(this, event)\n } else if (listener && typeof listener.handleEvent === 'function') {\n listener.handleEvent(event)\n }\n } catch (error) {\n // Log errors but don't let one listener break others\n console.error('Error in global wildcard event listener:', error)\n }\n })\n }\n\n connectedCallback () {\n this.render()\n }\n\n abstract render ():any\n\n qs<K extends keyof HTMLElementTagNameMap>(\n selector:K\n ):HTMLElementTagNameMap[K]|null;\n\n qs<E extends Element = Element>(selector:string):E|null;\n qs (selector:string):Element|null {\n return this.querySelector(selector)\n }\n\n qsa<K extends keyof HTMLElementTagNameMap>(\n selector:K\n ):HTMLElementTagNameMap[K]|null;\n\n qsa<E extends Element = Element>(selector:string):E|null;\n qsa (selector:string):NodeListOf<Element> {\n return this.querySelectorAll(selector)\n }\n\n /**\n * Take a non-namepsaced event name, return namespace event name.\n *\n * @param {string} evType The non-namespace event name\n * @returns {string} Namespaced event name, eg, `my-component:click`\n */\n static event (evType:string):string {\n return eventName(this.TAG, evType)\n }\n\n /**\n * Emit a namespaced event.\n *\n * @param type (non-namespaced) event type string\n * @param opts `bubbles`, `detail`, and `cancelable`. Default is\n * `{ bubbles: true, cancelable: true }`\n * @returns {boolean}\n */\n emit<T = any> (type:string, opts:Partial<{\n bubbles:boolean,\n cancelable:boolean,\n detail:CustomEvent<T>['detail']\n }> = {}):boolean {\n if (type === '*') throw new Error('Do not emit the literal \"*\"')\n\n const { bubbles = true, cancelable = true, detail } = opts\n const namespacedType = `${this.TAG}:${type}`\n\n const event = new CustomEvent(namespacedType, {\n bubbles,\n cancelable,\n detail\n })\n\n // This will trigger both specific listeners and global wildcard\n // listeners (**)\n const result = this.dispatchEvent(event)\n\n // Notify namespaced wildcard listeners (*)\n this._notifyNamespacedWildcardListeners(event)\n\n return result\n }\n\n /**\n * Override dispatchEvent to notify global wildcard listeners\n * This ensures that '**' listeners catch ALL events\n *\n * @param event - The event to dispatch\n * @returns true if the event was not cancelled\n */\n dispatchEvent (event: Event): boolean {\n const result = super.dispatchEvent(event)\n\n // Notify global wildcard listeners for ALL events\n this._notifyGlobalWildcardListeners(event)\n\n return result\n }\n\n /**\n * Create and emit an event, no namespacing.\n */\n dispatch<T> (type:string, opts:Partial<{\n bubbles:boolean,\n cancelable:boolean,\n detail:CustomEvent<T>['detail']\n }> = {}):boolean {\n const event = new CustomEvent(type, {\n bubbles: (opts.bubbles === undefined) ? true : opts.bubbles,\n cancelable: (opts.cancelable === undefined) ? true : opts.cancelable,\n detail: opts.detail\n })\n\n return this.dispatchEvent(event)\n }\n\n /**\n * Listen for namespaced events.\n */\n on<T extends Event = Event> (\n evName:string,\n handler:(ev:T)=>any,\n options?:boolean|AddEventListenerOptions\n ):void;\n\n on (\n evName:string,\n handler:EventListenerObject,\n options?:boolean|AddEventListenerOptions\n ):void;\n\n on (\n evName:string,\n handler:((ev:Event)=>any)|EventListenerObject,\n options?:boolean|AddEventListenerOptions\n ):void {\n const fullEvName = WebComponent.event.call(this, evName)\n this.addEventListener(fullEvName, handler as EventListenerOrEventListenerObject, options)\n }\n\n /**\n * Enhanced removeEventListener that supports wildcards:\n * - Component.event('*') - Remove namespaced wildcard listener\n * - '*' - Remove global wildcard listener\n *\n * @param type - Event type, Component.event('*') for namespaced, or '*'\n * for global\n * @param listener - Event listener function or object to remove\n * @param options - Event listener options\n */\n removeEventListener (\n type:string,\n listener:EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions\n ): void {\n if (type === WebComponent.event.call(this, '*')) {\n // Remove namespaced wildcard listener\n if (listener && this._namespacedWildcardListeners) {\n for (const entry of this._namespacedWildcardListeners) {\n if (entry.listener === listener) {\n this._namespacedWildcardListeners.delete(entry)\n break\n }\n }\n }\n } else if (type === '*') {\n // Remove global wildcard listener\n if (listener && this._globalWildcardListeners) {\n for (const entry of this._globalWildcardListeners) {\n if (entry.listener === listener) {\n this._globalWildcardListeners.delete(entry)\n break\n }\n }\n }\n } else {\n // Normal event listener - delegate to native implementation\n super.removeEventListener(type, listener, options)\n }\n }\n}\n\nfunction eventName (namespace:string, evType:string) {\n return `${namespace}:${evType}`\n}\n\n/**\n * Check if the given tag name has been registered.\n *\n * @see {@link https://stackoverflow.com/a/28210364 stackoverflow}\n * @param {string} elName The custom element tag name.\n * @returns {boolean} True if the given name has been registered already.\n */\nexport function isRegistered (elName:string):boolean {\n return document.createElement(elName).constructor !== window.HTMLElement\n}\n\nexport function define (name:string, element:CustomElementConstructor) {\n if (!window) return\n if (!('customElements' in window)) return\n\n if (!isRegistered(name)) {\n window.customElements.define(name, element)\n }\n}\n", "const digitCharacters = [\n \"0\",\n \"1\",\n \"2\",\n \"3\",\n \"4\",\n \"5\",\n \"6\",\n \"7\",\n \"8\",\n \"9\",\n \"A\",\n \"B\",\n \"C\",\n \"D\",\n \"E\",\n \"F\",\n \"G\",\n \"H\",\n \"I\",\n \"J\",\n \"K\",\n \"L\",\n \"M\",\n \"N\",\n \"O\",\n \"P\",\n \"Q\",\n \"R\",\n \"S\",\n \"T\",\n \"U\",\n \"V\",\n \"W\",\n \"X\",\n \"Y\",\n \"Z\",\n \"a\",\n \"b\",\n \"c\",\n \"d\",\n \"e\",\n \"f\",\n \"g\",\n \"h\",\n \"i\",\n \"j\",\n \"k\",\n \"l\",\n \"m\",\n \"n\",\n \"o\",\n \"p\",\n \"q\",\n \"r\",\n \"s\",\n \"t\",\n \"u\",\n \"v\",\n \"w\",\n \"x\",\n \"y\",\n \"z\",\n \"#\",\n \"$\",\n \"%\",\n \"*\",\n \"+\",\n \",\",\n \"-\",\n \".\",\n \":\",\n \";\",\n \"=\",\n \"?\",\n \"@\",\n \"[\",\n \"]\",\n \"^\",\n \"_\",\n \"{\",\n \"|\",\n \"}\",\n \"~\",\n];\n\nexport const decode83 = (str: String) => {\n let value = 0;\n for (let i = 0; i < str.length; i++) {\n const c = str[i];\n const digit = digitCharacters.indexOf(c);\n value = value * 83 + digit;\n }\n return value;\n};\n\nexport const encode83 = (n: number, length: number): string => {\n var result = \"\";\n for (let i = 1; i <= length; i++) {\n let digit = (Math.floor(n) / Math.pow(83, length - i)) % 83;\n result += digitCharacters[Math.floor(digit)];\n }\n return result;\n};\n", "export const sRGBToLinear = (value: number) => {\n let v = value / 255;\n if (v <= 0.04045) {\n return v / 12.92;\n } else {\n return Math.pow((v + 0.055) / 1.055, 2.4);\n }\n};\n\nexport const linearTosRGB = (value: number) => {\n let v = Math.max(0, Math.min(1, value));\n if (v <= 0.0031308) {\n return Math.trunc(v * 12.92 * 255 + 0.5);\n } else {\n return Math.trunc((1.055 * Math.pow(v, 1 / 2.4) - 0.055) * 255 + 0.5);\n }\n};\n\nexport const sign = (n: number) => (n < 0 ? -1 : 1);\n\nexport const signPow = (val: number, exp: number) =>\n sign(val) * Math.pow(Math.abs(val), exp);\n", "export class ValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ValidationError\";\n this.message = message;\n }\n}\n", "import { decode83 } from \"./base83\";\nimport { sRGBToLinear, signPow, linearTosRGB } from \"./utils\";\nimport { ValidationError } from \"./error\";\n\n/**\n * Returns an error message if invalid or undefined if valid\n * @param blurhash\n */\nconst validateBlurhash = (blurhash: string) => {\n if (!blurhash || blurhash.length < 6) {\n throw new ValidationError(\n \"The blurhash string must be at least 6 characters\"\n );\n }\n\n const sizeFlag = decode83(blurhash[0]);\n const numY = Math.floor(sizeFlag / 9) + 1;\n const numX = (sizeFlag % 9) + 1;\n\n if (blurhash.length !== 4 + 2 * numX * numY) {\n throw new ValidationError(\n `blurhash length mismatch: length is ${\n blurhash.length\n } but it should be ${4 + 2 * numX * numY}`\n );\n }\n};\n\nexport const isBlurhashValid = (\n blurhash: string\n): { result: boolean; errorReason?: string } => {\n try {\n validateBlurhash(blurhash);\n } catch (error) {\n return { result: false, errorReason: error.message };\n }\n\n return { result: true };\n};\n\nconst decodeDC = (value: number) => {\n const intR = value >> 16;\n const intG = (value >> 8) & 255;\n const intB = value & 255;\n return [sRGBToLinear(intR), sRGBToLinear(intG), sRGBToLinear(intB)];\n};\n\nconst decodeAC = (value: number, maximumValue: number) => {\n const quantR = Math.floor(value / (19 * 19));\n const quantG = Math.floor(value / 19) % 19;\n const quantB = value % 19;\n\n const rgb = [\n signPow((quantR - 9) / 9, 2.0) * maximumValue,\n signPow((quantG - 9) / 9, 2.0) * maximumValue,\n signPow((quantB - 9) / 9, 2.0) * maximumValue,\n ];\n\n return rgb;\n};\n\nconst decode = (\n blurhash: string,\n width: number,\n height: number,\n punch?: number\n) => {\n validateBlurhash(blurhash);\n\n punch = punch | 1;\n\n const sizeFlag = decode83(blurhash[0]);\n const numY = Math.floor(sizeFlag / 9) + 1;\n const numX = (sizeFlag % 9) + 1;\n\n const quantisedMaximumValue = decode83(blurhash[1]);\n const maximumValue = (quantisedMaximumValue + 1) / 166;\n\n const colors = new Array(numX * numY);\n\n for (let i = 0; i < colors.length; i++) {\n if (i === 0) {\n const value = decode83(blurhash.substring(2, 6));\n colors[i] = decodeDC(value);\n } else {\n const value = decode83(blurhash.substring(4 + i * 2, 6 + i * 2));\n colors[i] = decodeAC(value, maximumValue * punch);\n }\n }\n\n const bytesPerRow = width * 4;\n const pixels = new Uint8ClampedArray(bytesPerRow * height);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n let r = 0;\n let g = 0;\n let b = 0;\n\n for (let j = 0; j < numY; j++) {\n for (let i = 0; i < numX; i++) {\n const basis =\n Math.cos((Math.PI * x * i) / width) *\n Math.cos((Math.PI * y * j) / height);\n let color = colors[i + j * numX];\n r += color[0] * basis;\n g += color[1] * basis;\n b += color[2] * basis;\n }\n }\n\n let intR = linearTosRGB(r);\n let intG = linearTosRGB(g);\n let intB = linearTosRGB(b);\n\n pixels[4 * x + 0 + y * bytesPerRow] = intR;\n pixels[4 * x + 1 + y * bytesPerRow] = intG;\n pixels[4 * x + 2 + y * bytesPerRow] = intB;\n pixels[4 * x + 3 + y * bytesPerRow] = 255; // alpha\n }\n }\n return pixels;\n};\n\nexport default decode;\n", "import { encode83 } from \"./base83\";\nimport { sRGBToLinear, signPow, linearTosRGB } from \"./utils\";\nimport { ValidationError } from \"./error\";\n\ntype NumberTriplet = [number, number, number];\n\nconst bytesPerPixel = 4;\n\nconst multiplyBasisFunction = (\n pixels: Uint8ClampedArray,\n width: number,\n height: number,\n basisFunction: (i: number, j: number) => number\n): NumberTriplet => {\n let r = 0;\n let g = 0;\n let b = 0;\n const bytesPerRow = width * bytesPerPixel;\n\n for (let x = 0; x < width; x++) {\n const bytesPerPixelX = bytesPerPixel * x;\n\n for (let y = 0; y < height; y++) {\n const basePixelIndex = bytesPerPixelX + y * bytesPerRow;\n const basis = basisFunction(x, y);\n r +=\n basis * sRGBToLinear(pixels[basePixelIndex]);\n g +=\n basis * sRGBToLinear(pixels[basePixelIndex + 1]);\n b +=\n basis * sRGBToLinear(pixels[basePixelIndex + 2]);\n }\n }\n\n let scale = 1 / (width * height);\n\n return [r * scale, g * scale, b * scale];\n};\n\nconst encodeDC = (value: NumberTriplet): number => {\n const roundedR = linearTosRGB(value[0]);\n const roundedG = linearTosRGB(value[1]);\n const roundedB = linearTosRGB(value[2]);\n return (roundedR << 16) + (roundedG << 8) + roundedB;\n};\n\nconst encodeAC = (value: NumberTriplet, maximumValue: number): number => {\n let quantR = Math.floor(\n Math.max(\n 0,\n Math.min(18, Math.floor(signPow(value[0] / maximumValue, 0.5) * 9 + 9.5))\n )\n );\n let quantG = Math.floor(\n Math.max(\n 0,\n Math.min(18, Math.floor(signPow(value[1] / maximumValue, 0.5) * 9 + 9.5))\n )\n );\n let quantB = Math.floor(\n Math.max(\n 0,\n Math.min(18, Math.floor(signPow(value[2] / maximumValue, 0.5) * 9 + 9.5))\n )\n );\n\n return quantR * 19 * 19 + quantG * 19 + quantB;\n};\n\nconst encode = (\n pixels: Uint8ClampedArray,\n width: number,\n height: number,\n componentX: number,\n componentY: number\n): string => {\n if (componentX < 1 || componentX > 9 || componentY < 1 || componentY > 9) {\n throw new ValidationError(\"BlurHash must have between 1 and 9 components\");\n }\n if (width * height * 4 !== pixels.length) {\n throw new ValidationError(\"Width and height must match the pixels array\");\n }\n\n let factors: Array<[number, number, number]> = [];\n for (let y = 0; y < componentY; y++) {\n for (let x = 0; x < componentX; x++) {\n const normalisation = x == 0 && y == 0 ? 1 : 2;\n const factor = multiplyBasisFunction(\n pixels,\n width,\n height,\n (i: number, j: number) =>\n normalisation *\n Math.cos((Math.PI * x * i) / width) *\n Math.cos((Math.PI * y * j) / height)\n );\n factors.push(factor);\n }\n }\n\n const dc = factors[0];\n const ac = factors.slice(1);\n\n let hash = \"\";\n\n let sizeFlag = componentX - 1 + (componentY - 1) * 9;\n hash += encode83(sizeFlag, 1);\n\n let maximumValue: number;\n if (ac.length > 0) {\n let actualMaximumValue = Math.max(...ac.map((val) => Math.max(...val)));\n let quantisedMaximumValue = Math.floor(\n Math.max(0, Math.min(82, Math.floor(actualMaximumValue * 166 - 0.5)))\n );\n maximumValue = (quantisedMaximumValue + 1) / 166;\n hash += encode83(quantisedMaximumValue, 1);\n } else {\n maximumValue = 1;\n hash += encode83(0, 1);\n }\n\n hash += encode83(encodeDC(dc), 4);\n\n ac.forEach((factor) => {\n hash += encode83(encodeAC(factor, maximumValue), 2);\n });\n\n return hash;\n};\n\nexport default encode;\n", "import { toAttributes } from '@substrate-system/web-component/attributes'\nimport type { ImgAttrs } from './index.js'\n\nexport type SSRAttrs = ImgAttrs & { classes?:string }\n\nexport function render (attrs:SSRAttrs) {\n const {\n width,\n height,\n alt,\n contentVisibility,\n placeholder,\n decoding,\n loading,\n srcset,\n sizes,\n src\n } = attrs\n\n if (!placeholder) throw new Error('not placeholder')\n\n const htmlString = `<canvas\n alt=\"${alt}\"\n width=${width}\n height=${height}\n class=\"blurry\"\n width=${width}\n height=${height}\n ></canvas>\n\n <img class=\"blurry\"\n alt=\"${alt}\"\n content-visibility=\"${contentVisibility || 'auto'}\"\n decoding=\"${decoding || 'async'}\"\n loading=\"${loading || 'lazy'}\"\n ${srcset ? `srcset=\"${srcset}\"` : ''}\n ${sizes ? `sizes=\"${sizes}\"` : ''}\n src=\"${src}\"\n />`\n\n const attributeString = toAttributes(attrs)\n\n // running in node?\n return typeof window === 'undefined' ?\n `<blur-hash ${attributeString}>\n ${htmlString}\n </blur-hash>` :\n htmlString\n}\n\nexport const outerHTML = (attrs:SSRAttrs) => {\n return `<blur-hash>${render(attrs)}</blur-hash>`\n}\n", "import { WebComponent } from '@substrate-system/web-component'\nimport { decode } from 'blurhash'\nimport { render } from './html.js'\n\n// for docuement.querySelector\ndeclare global {\n interface HTMLElementTagNameMap {\n 'blur-hash': BlurHash\n }\n}\n\nexport type ImgAttrs = {\n alt:string;\n width:string|number;\n height:string|number;\n placeholder:string;\n src:string;\n srcset?:string|null;\n sizes?:string|null;\n time?:number;\n contentVisibility?:'visible'|'auto'|'hidden'|null;\n decoding?:'sync'|'async'|'auto'|null;\n loading?:'lazy'|'eager'|'auto'|null;\n}\n\nexport class BlurHash extends WebComponent.create('blur-hash') {\n time:number\n\n constructor () {\n super()\n const w = this.getAttribute('width')\n const h = this.getAttribute('height')\n const time = this.getAttribute('time')\n this.time = time ? parseInt(time) : 800\n\n this.style.width = '' + w\n this.style.height = '' + h\n\n document.body.style.setProperty('--blur-hash-time',\n time ? '.' + (parseInt(time) / 1000 + 's') : '0.8s')\n }\n\n /**\n * Change the image, and do the blur-up thing again.\n * Will use the existing width & height if they are not passed in.\n */\n reset (attrs:(Omit<Omit<ImgAttrs, 'width'>, 'height'> & {\n width?:string|number;\n height?:string|number;\n })):void {\n if (attrs.width) this.style.width = '' + attrs.width\n if (attrs.height) this.style.height = '' + attrs.height\n\n const width = (attrs.width ?\n (typeof attrs.width === 'string' ? parseInt(attrs.width) : attrs.width) :\n parseInt(this.style.width))\n const height = (attrs.height ?\n (typeof attrs.height === 'string' ? parseInt(attrs.height) : attrs.height) :\n parseInt(this.style.height))\n\n this.innerHTML = BlurHash.html(Object.assign(attrs, { width, height }))\n\n const { placeholder, src: newSrc } = attrs\n\n const pixels = decode(placeholder, width, height)\n const canvas = this.querySelector('canvas') as HTMLCanvasElement\n const ctx = canvas.getContext('2d')!\n const imageData = ctx.createImageData(width, height)\n imageData.data.set(pixels)\n ctx.putImageData(imageData, 0, 0)\n\n this.setAttribute('src', newSrc)\n this.setAttribute('placeholder', placeholder)\n\n const img = this.querySelector('img')!\n if (attrs.srcset) img.setAttribute('srcset', attrs.srcset)\n if (attrs.sizes) img.setAttribute('sizes', attrs.sizes)\n\n this.sharpen()\n }\n\n sharpen () {\n const img = this.qs('img')!\n if (img.complete && img.naturalWidth > 0) {\n img.classList.remove('blurry')\n img.classList.add('sharp')\n } else {\n img.addEventListener('load', () => {\n img.classList.remove('blurry')\n img.classList.add('sharp')\n })\n }\n }\n\n connectedCallback () {\n const width = parseInt(this.getAttribute('width') ?? '')\n const height = parseInt(this.getAttribute('height') ?? '')\n const placeholder = this.getAttribute('placeholder')\n if (!placeholder) throw new Error('Missing placeholder')\n if (!width) throw new Error('Missing width')\n if (!height) throw new Error('Missing height')\n\n // don't render again if we dont have to\n if (!this.innerHTML) {\n this.innerHTML = this.render()\n }\n\n const pixels = decode(placeholder, width, height)\n const canvas = this.querySelector('canvas') as HTMLCanvasElement\n const ctx = canvas.getContext('2d')!\n const imageData = ctx.createImageData(width, height)\n imageData.data.set(pixels)\n ctx.putImageData(imageData, 0, 0)\n\n this.sharpen()\n }\n\n static html (attrs:ImgAttrs & { classes?:string }) {\n return render(attrs)\n }\n\n /**\n * Use the attributes to create HTML.\n */\n render ():string {\n const srcset = this.getAttribute('srcset')\n const width = this.getAttribute('width')\n const height = this.getAttribute('height')\n const time = this.getAttribute('time')\n const classes = this.classList.toString()\n const placeholder = this.getAttribute('placeholder')\n this.time = time ? parseInt(time) : 800\n const src = this.getAttribute('src')\n const alt = this.getAttribute('alt')\n if (!placeholder) throw new Error('not placeholder')\n if (!width || !height) throw new Error('not width or not height')\n if (!src) throw new Error('Not src')\n if (!alt) throw new Error('Not alt')\n\n return BlurHash.html({ classes, srcset, width, height, src, alt, placeholder })\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["toAttributes", "attrs", "acc", "k", "value", "__name", "isRegistered", "elName", "__name", "define", "name", "element", "qs", "qsa", "match", "el", "s", "WebComponent", "_WebComponent", "__name", "el", "match", "elementName", "CreatedClass", "evType", "define", "name", "oldValue", "newValue", "handler", "type", "listener", "options", "event", "componentName", "error", "selector", "eventName", "opts", "bubbles", "cancelable", "detail", "namespacedType", "result", "evName", "fullEvName", "entry", "namespace", "isRegistered", "elName", "element", "q", "x", "__name", "t", "e", "n", "l", "f", "__name", "t", "e", "h", "F", "M", "d", "C", "x", "n", "z", "__name", "t", "e", "n", "f", "L", "l", "M", "U", "C", "x", "m", "b", "i", "u", "o", "a", "c", "s", "y", "B", "R", "w", "P", "G", "T", "V", "h", "I", "E", "j", "render", "attrs", "width", "height", "alt", "contentVisibility", "placeholder", "decoding", "loading", "srcset", "sizes", "src", "htmlString", "attributeString", "toAttributes", "__name", "BlurHash", "_BlurHash", "WebComponent", "__name", "w", "h", "time", "attrs", "width", "height", "placeholder", "newSrc", "
|
|
3
|
+
"sources": ["../node_modules/@substrate-system/web-component/src/attributes.ts", "../node_modules/@substrate-system/web-component/src/util.ts", "../node_modules/@substrate-system/web-component/src/index.ts", "../node_modules/blurhash/src/base83.ts", "../node_modules/blurhash/src/utils.ts", "../node_modules/blurhash/src/error.ts", "../node_modules/blurhash/src/decode.ts", "../node_modules/blurhash/src/encode.ts", "../src/decode-dimensions.ts", "../src/html.ts", "../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["export type Attrs = Record<string, undefined|null|string|number|boolean|(string|number)[]>\n\n/**\n * Transform an object into an HTML attributes string. The object should be\n * like `{ attributeName: value }`.\n *\n * @param attrs An object for the attributes.\n * @returns {string} A string suitable for use as HTML attributes.\n */\nexport function toAttributes (attrs:Attrs):string {\n return Object.keys(attrs).reduce((acc, k) => {\n const value = attrs[k]\n if (!value) return acc\n\n if (typeof value === 'boolean') {\n if (value) return (acc + ` ${k}`).trim()\n return acc\n }\n\n if (Array.isArray(value)) {\n return (acc + ` ${k}=\"${value.join(' ')}\"`)\n }\n\n return (acc + ` ${k}=\"${value}\"`).trim()\n }, '')\n}\n", "export { toAttributes } from './attributes.js'\n\n/**\n * Check if the given tag name has been registered.\n *\n * @see {@link https://stackoverflow.com/a/28210364 stackoverflow}\n * @param {string} elName The custom element tag name.\n * @returns {boolean} True if the given name has been registered already.\n */\nexport function isRegistered (elName:string):boolean {\n return document.createElement(elName).constructor !== window.HTMLElement\n}\n\nexport function define (name:string, element:CustomElementConstructor) {\n if (!window) return\n if (!('customElements' in window)) return\n\n if (!isRegistered(name)) {\n window.customElements.define(name, element)\n }\n}\n\nexport const qs = document.querySelector.bind(document)\nexport const qsa = document.querySelectorAll.bind(document)\n\n/**\n * Get the closes parent element matching the given selector.\n * @param el Element to start from\n * @param s Selector for an element\n * @returns {HTMLElement|null} The closes parent element that matches.\n */\nexport function match (el:HTMLElement, s:string):HTMLElement|null {\n if (!el.matches) el = el.parentElement!\n return el.matches(s) ? el : el.closest(s)\n}\n", "import { match as _match } from './util.js'\n\ninterface WildcardListenerEntry {\n listener:EventListenerOrEventListenerObject\n options?:boolean|AddEventListenerOptions\n}\n\nexport abstract class WebComponent extends window.HTMLElement {\n static TAG:string = ''\n TAG:string = ''\n\n static match (el:HTMLElement):HTMLElement|null {\n return _match(el, this.TAG)\n }\n\n /**\n * Store global wildcard listeners (listen to all events)\n * Triggered by ALL events dispatched through this element\n * @private\n */\n private _globalWildcardListeners:Set<WildcardListenerEntry> = new Set()\n\n /**\n * Store namespaced wildcard listeners (listen to 'component-name:*')\n * Triggered by events from emit() that match this component's namespace\n * @private\n */\n private _namespacedWildcardListeners:Set<WildcardListenerEntry> = new Set()\n\n static create (elementName:string):typeof WebComponent & {\n new (...args:any[]):WebComponent;\n TAG:string;\n define: typeof WebComponent.define;\n event: typeof WebComponent.event;\n } {\n const CreatedClass = class extends WebComponent {\n static TAG = elementName\n TAG = elementName\n render () {\n throw new Error('`render` should be implemented by children')\n }\n }\n\n // Copy static methods with proper binding\n CreatedClass.define = function () {\n return WebComponent.define.call(this)\n }\n CreatedClass.event = function (evType:string) {\n return WebComponent.event.call(this, evType)\n }\n\n return CreatedClass\n }\n\n static define<T extends {\n new (...args:any[]):WebComponent;\n TAG:string;\n }>(this:T) {\n define(this.TAG, this)\n }\n\n /**\n * Runs when the value of an attribute is changed.\n *\n * Depends on `static observedAttributes`.\n *\n * Should name methods like `handleChange_disabled`.\n *\n * @param {string} name The attribute name\n * @param {string} oldValue The old attribute value\n * @param {string} newValue The new attribute value\n */\n async attributeChangedCallback (\n name:string,\n oldValue:string,\n newValue:string\n ):Promise<void> {\n const handler = this[`handleChange_${name}`]\n if (handler) {\n await handler.call(this, oldValue, newValue)\n }\n }\n\n /**\n * Enhanced addEventListener that supports wildcards:\n * - Component.event('*') - Listen to all namespaced events for this\n * component (e.g., 'my-component:*')\n * - '*' - Listen to ALL events (namespaced and non-namespaced, including\n * normal DOM events)\n *\n * @param type - Event type, Component.event('*') for namespaced wildcard,\n * or '*' for global wildcard\n * @param listener - Event listener function or object\n * @param options - Event listener options\n */\n addEventListener (\n type:string,\n listener:EventListenerOrEventListenerObject,\n options?:boolean|AddEventListenerOptions\n ): void {\n if (type === WebComponent.event.call(this, '*')) {\n // Handle namespaced wildcard listener (component-name:*)\n this._namespacedWildcardListeners.add({ listener, options })\n } else if (type === '*') {\n // Handle global wildcard listener (all events)\n if (listener) {\n this._globalWildcardListeners.add({ listener, options })\n }\n } else {\n // Normal event listener - delegate to native implementation\n super.addEventListener(type, listener, options)\n }\n }\n\n /**\n * Notify namespaced wildcard listeners of an event\n * Only fires for events that match this component's namespace\n *\n * @param event - The event to dispatch to namespaced wildcard listeners\n * @private\n */\n private _notifyNamespacedWildcardListeners (event: Event): void {\n if (this._namespacedWildcardListeners.size === 0) {\n return\n }\n\n const componentName = this.TAG\n\n // Only trigger for events in this component's namespace\n if (!componentName || !event.type.startsWith(`${componentName}:`)) {\n return\n }\n\n // Call each namespaced wildcard listener\n this._namespacedWildcardListeners.forEach(({ listener }) => {\n try {\n if (typeof listener === 'function') {\n listener.call(this, event)\n } else if (listener && typeof listener.handleEvent === 'function') {\n listener.handleEvent(event)\n }\n } catch (error) {\n // Log errors but don't let one listener break others\n console.error(\n 'Error in namespaced wildcard event listener:',\n error\n )\n }\n })\n }\n\n /**\n * Notify global wildcard listeners of an event\n * Fires for ALL events dispatched through this element\n *\n * @param event - The event to dispatch to global wildcard listeners\n * @private\n */\n private _notifyGlobalWildcardListeners (event: Event): void {\n if (this._globalWildcardListeners.size === 0) {\n return\n }\n\n // Call each global wildcard listener\n this._globalWildcardListeners.forEach(({ listener }) => {\n try {\n if (typeof listener === 'function') {\n listener.call(this, event)\n } else if (listener && typeof listener.handleEvent === 'function') {\n listener.handleEvent(event)\n }\n } catch (error) {\n // Log errors but don't let one listener break others\n console.error('Error in global wildcard event listener:', error)\n }\n })\n }\n\n connectedCallback () {\n this.render()\n }\n\n abstract render ():any\n\n qs<K extends keyof HTMLElementTagNameMap>(\n selector:K\n ):HTMLElementTagNameMap[K]|null;\n\n qs<E extends Element = Element>(selector:string):E|null;\n qs (selector:string):Element|null {\n return this.querySelector(selector)\n }\n\n qsa<K extends keyof HTMLElementTagNameMap>(\n selector:K\n ):HTMLElementTagNameMap[K]|null;\n\n qsa<E extends Element = Element>(selector:string):E|null;\n qsa (selector:string):NodeListOf<Element> {\n return this.querySelectorAll(selector)\n }\n\n /**\n * Take a non-namepsaced event name, return namespace event name.\n *\n * @param {string} evType The non-namespace event name\n * @returns {string} Namespaced event name, eg, `my-component:click`\n */\n static event (evType:string):string {\n return eventName(this.TAG, evType)\n }\n\n /**\n * Emit a namespaced event.\n *\n * @param type (non-namespaced) event type string\n * @param opts `bubbles`, `detail`, and `cancelable`. Default is\n * `{ bubbles: true, cancelable: true }`\n * @returns {boolean}\n */\n emit<T = any> (type:string, opts:Partial<{\n bubbles:boolean,\n cancelable:boolean,\n detail:CustomEvent<T>['detail']\n }> = {}):boolean {\n if (type === '*') throw new Error('Do not emit the literal \"*\"')\n\n const { bubbles = true, cancelable = true, detail } = opts\n const namespacedType = `${this.TAG}:${type}`\n\n const event = new CustomEvent(namespacedType, {\n bubbles,\n cancelable,\n detail\n })\n\n // This will trigger both specific listeners and global wildcard\n // listeners (**)\n const result = this.dispatchEvent(event)\n\n // Notify namespaced wildcard listeners (*)\n this._notifyNamespacedWildcardListeners(event)\n\n return result\n }\n\n /**\n * Override dispatchEvent to notify global wildcard listeners\n * This ensures that '**' listeners catch ALL events\n *\n * @param event - The event to dispatch\n * @returns true if the event was not cancelled\n */\n dispatchEvent (event: Event): boolean {\n const result = super.dispatchEvent(event)\n\n // Notify global wildcard listeners for ALL events\n this._notifyGlobalWildcardListeners(event)\n\n return result\n }\n\n /**\n * Create and emit an event, no namespacing.\n */\n dispatch<T> (type:string, opts:Partial<{\n bubbles:boolean,\n cancelable:boolean,\n detail:CustomEvent<T>['detail']\n }> = {}):boolean {\n const event = new CustomEvent(type, {\n bubbles: (opts.bubbles === undefined) ? true : opts.bubbles,\n cancelable: (opts.cancelable === undefined) ? true : opts.cancelable,\n detail: opts.detail\n })\n\n return this.dispatchEvent(event)\n }\n\n /**\n * Listen for namespaced events.\n */\n on<T extends Event = Event> (\n evName:string,\n handler:(ev:T)=>any,\n options?:boolean|AddEventListenerOptions\n ):void;\n\n on (\n evName:string,\n handler:EventListenerObject,\n options?:boolean|AddEventListenerOptions\n ):void;\n\n on (\n evName:string,\n handler:((ev:Event)=>any)|EventListenerObject,\n options?:boolean|AddEventListenerOptions\n ):void {\n const fullEvName = WebComponent.event.call(this, evName)\n this.addEventListener(fullEvName, handler as EventListenerOrEventListenerObject, options)\n }\n\n /**\n * Enhanced removeEventListener that supports wildcards:\n * - Component.event('*') - Remove namespaced wildcard listener\n * - '*' - Remove global wildcard listener\n *\n * @param type - Event type, Component.event('*') for namespaced, or '*'\n * for global\n * @param listener - Event listener function or object to remove\n * @param options - Event listener options\n */\n removeEventListener (\n type:string,\n listener:EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions\n ): void {\n if (type === WebComponent.event.call(this, '*')) {\n // Remove namespaced wildcard listener\n if (listener && this._namespacedWildcardListeners) {\n for (const entry of this._namespacedWildcardListeners) {\n if (entry.listener === listener) {\n this._namespacedWildcardListeners.delete(entry)\n break\n }\n }\n }\n } else if (type === '*') {\n // Remove global wildcard listener\n if (listener && this._globalWildcardListeners) {\n for (const entry of this._globalWildcardListeners) {\n if (entry.listener === listener) {\n this._globalWildcardListeners.delete(entry)\n break\n }\n }\n }\n } else {\n // Normal event listener - delegate to native implementation\n super.removeEventListener(type, listener, options)\n }\n }\n}\n\nfunction eventName (namespace:string, evType:string) {\n return `${namespace}:${evType}`\n}\n\n/**\n * Check if the given tag name has been registered.\n *\n * @see {@link https://stackoverflow.com/a/28210364 stackoverflow}\n * @param {string} elName The custom element tag name.\n * @returns {boolean} True if the given name has been registered already.\n */\nexport function isRegistered (elName:string):boolean {\n return document.createElement(elName).constructor !== window.HTMLElement\n}\n\nexport function define (name:string, element:CustomElementConstructor) {\n if (!window) return\n if (!('customElements' in window)) return\n\n if (!isRegistered(name)) {\n window.customElements.define(name, element)\n }\n}\n", "const digitCharacters = [\n \"0\",\n \"1\",\n \"2\",\n \"3\",\n \"4\",\n \"5\",\n \"6\",\n \"7\",\n \"8\",\n \"9\",\n \"A\",\n \"B\",\n \"C\",\n \"D\",\n \"E\",\n \"F\",\n \"G\",\n \"H\",\n \"I\",\n \"J\",\n \"K\",\n \"L\",\n \"M\",\n \"N\",\n \"O\",\n \"P\",\n \"Q\",\n \"R\",\n \"S\",\n \"T\",\n \"U\",\n \"V\",\n \"W\",\n \"X\",\n \"Y\",\n \"Z\",\n \"a\",\n \"b\",\n \"c\",\n \"d\",\n \"e\",\n \"f\",\n \"g\",\n \"h\",\n \"i\",\n \"j\",\n \"k\",\n \"l\",\n \"m\",\n \"n\",\n \"o\",\n \"p\",\n \"q\",\n \"r\",\n \"s\",\n \"t\",\n \"u\",\n \"v\",\n \"w\",\n \"x\",\n \"y\",\n \"z\",\n \"#\",\n \"$\",\n \"%\",\n \"*\",\n \"+\",\n \",\",\n \"-\",\n \".\",\n \":\",\n \";\",\n \"=\",\n \"?\",\n \"@\",\n \"[\",\n \"]\",\n \"^\",\n \"_\",\n \"{\",\n \"|\",\n \"}\",\n \"~\",\n];\n\nexport const decode83 = (str: String) => {\n let value = 0;\n for (let i = 0; i < str.length; i++) {\n const c = str[i];\n const digit = digitCharacters.indexOf(c);\n value = value * 83 + digit;\n }\n return value;\n};\n\nexport const encode83 = (n: number, length: number): string => {\n var result = \"\";\n for (let i = 1; i <= length; i++) {\n let digit = (Math.floor(n) / Math.pow(83, length - i)) % 83;\n result += digitCharacters[Math.floor(digit)];\n }\n return result;\n};\n", "export const sRGBToLinear = (value: number) => {\n let v = value / 255;\n if (v <= 0.04045) {\n return v / 12.92;\n } else {\n return Math.pow((v + 0.055) / 1.055, 2.4);\n }\n};\n\nexport const linearTosRGB = (value: number) => {\n let v = Math.max(0, Math.min(1, value));\n if (v <= 0.0031308) {\n return Math.trunc(v * 12.92 * 255 + 0.5);\n } else {\n return Math.trunc((1.055 * Math.pow(v, 1 / 2.4) - 0.055) * 255 + 0.5);\n }\n};\n\nexport const sign = (n: number) => (n < 0 ? -1 : 1);\n\nexport const signPow = (val: number, exp: number) =>\n sign(val) * Math.pow(Math.abs(val), exp);\n", "export class ValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ValidationError\";\n this.message = message;\n }\n}\n", "import { decode83 } from \"./base83\";\nimport { sRGBToLinear, signPow, linearTosRGB } from \"./utils\";\nimport { ValidationError } from \"./error\";\n\n/**\n * Returns an error message if invalid or undefined if valid\n * @param blurhash\n */\nconst validateBlurhash = (blurhash: string) => {\n if (!blurhash || blurhash.length < 6) {\n throw new ValidationError(\n \"The blurhash string must be at least 6 characters\"\n );\n }\n\n const sizeFlag = decode83(blurhash[0]);\n const numY = Math.floor(sizeFlag / 9) + 1;\n const numX = (sizeFlag % 9) + 1;\n\n if (blurhash.length !== 4 + 2 * numX * numY) {\n throw new ValidationError(\n `blurhash length mismatch: length is ${\n blurhash.length\n } but it should be ${4 + 2 * numX * numY}`\n );\n }\n};\n\nexport const isBlurhashValid = (\n blurhash: string\n): { result: boolean; errorReason?: string } => {\n try {\n validateBlurhash(blurhash);\n } catch (error) {\n return { result: false, errorReason: error.message };\n }\n\n return { result: true };\n};\n\nconst decodeDC = (value: number) => {\n const intR = value >> 16;\n const intG = (value >> 8) & 255;\n const intB = value & 255;\n return [sRGBToLinear(intR), sRGBToLinear(intG), sRGBToLinear(intB)];\n};\n\nconst decodeAC = (value: number, maximumValue: number) => {\n const quantR = Math.floor(value / (19 * 19));\n const quantG = Math.floor(value / 19) % 19;\n const quantB = value % 19;\n\n const rgb = [\n signPow((quantR - 9) / 9, 2.0) * maximumValue,\n signPow((quantG - 9) / 9, 2.0) * maximumValue,\n signPow((quantB - 9) / 9, 2.0) * maximumValue,\n ];\n\n return rgb;\n};\n\nconst decode = (\n blurhash: string,\n width: number,\n height: number,\n punch?: number\n) => {\n validateBlurhash(blurhash);\n\n punch = punch | 1;\n\n const sizeFlag = decode83(blurhash[0]);\n const numY = Math.floor(sizeFlag / 9) + 1;\n const numX = (sizeFlag % 9) + 1;\n\n const quantisedMaximumValue = decode83(blurhash[1]);\n const maximumValue = (quantisedMaximumValue + 1) / 166;\n\n const colors = new Array(numX * numY);\n\n for (let i = 0; i < colors.length; i++) {\n if (i === 0) {\n const value = decode83(blurhash.substring(2, 6));\n colors[i] = decodeDC(value);\n } else {\n const value = decode83(blurhash.substring(4 + i * 2, 6 + i * 2));\n colors[i] = decodeAC(value, maximumValue * punch);\n }\n }\n\n const bytesPerRow = width * 4;\n const pixels = new Uint8ClampedArray(bytesPerRow * height);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n let r = 0;\n let g = 0;\n let b = 0;\n\n for (let j = 0; j < numY; j++) {\n for (let i = 0; i < numX; i++) {\n const basis =\n Math.cos((Math.PI * x * i) / width) *\n Math.cos((Math.PI * y * j) / height);\n let color = colors[i + j * numX];\n r += color[0] * basis;\n g += color[1] * basis;\n b += color[2] * basis;\n }\n }\n\n let intR = linearTosRGB(r);\n let intG = linearTosRGB(g);\n let intB = linearTosRGB(b);\n\n pixels[4 * x + 0 + y * bytesPerRow] = intR;\n pixels[4 * x + 1 + y * bytesPerRow] = intG;\n pixels[4 * x + 2 + y * bytesPerRow] = intB;\n pixels[4 * x + 3 + y * bytesPerRow] = 255; // alpha\n }\n }\n return pixels;\n};\n\nexport default decode;\n", "import { encode83 } from \"./base83\";\nimport { sRGBToLinear, signPow, linearTosRGB } from \"./utils\";\nimport { ValidationError } from \"./error\";\n\ntype NumberTriplet = [number, number, number];\n\nconst bytesPerPixel = 4;\n\nconst multiplyBasisFunction = (\n pixels: Uint8ClampedArray,\n width: number,\n height: number,\n basisFunction: (i: number, j: number) => number\n): NumberTriplet => {\n let r = 0;\n let g = 0;\n let b = 0;\n const bytesPerRow = width * bytesPerPixel;\n\n for (let x = 0; x < width; x++) {\n const bytesPerPixelX = bytesPerPixel * x;\n\n for (let y = 0; y < height; y++) {\n const basePixelIndex = bytesPerPixelX + y * bytesPerRow;\n const basis = basisFunction(x, y);\n r +=\n basis * sRGBToLinear(pixels[basePixelIndex]);\n g +=\n basis * sRGBToLinear(pixels[basePixelIndex + 1]);\n b +=\n basis * sRGBToLinear(pixels[basePixelIndex + 2]);\n }\n }\n\n let scale = 1 / (width * height);\n\n return [r * scale, g * scale, b * scale];\n};\n\nconst encodeDC = (value: NumberTriplet): number => {\n const roundedR = linearTosRGB(value[0]);\n const roundedG = linearTosRGB(value[1]);\n const roundedB = linearTosRGB(value[2]);\n return (roundedR << 16) + (roundedG << 8) + roundedB;\n};\n\nconst encodeAC = (value: NumberTriplet, maximumValue: number): number => {\n let quantR = Math.floor(\n Math.max(\n 0,\n Math.min(18, Math.floor(signPow(value[0] / maximumValue, 0.5) * 9 + 9.5))\n )\n );\n let quantG = Math.floor(\n Math.max(\n 0,\n Math.min(18, Math.floor(signPow(value[1] / maximumValue, 0.5) * 9 + 9.5))\n )\n );\n let quantB = Math.floor(\n Math.max(\n 0,\n Math.min(18, Math.floor(signPow(value[2] / maximumValue, 0.5) * 9 + 9.5))\n )\n );\n\n return quantR * 19 * 19 + quantG * 19 + quantB;\n};\n\nconst encode = (\n pixels: Uint8ClampedArray,\n width: number,\n height: number,\n componentX: number,\n componentY: number\n): string => {\n if (componentX < 1 || componentX > 9 || componentY < 1 || componentY > 9) {\n throw new ValidationError(\"BlurHash must have between 1 and 9 components\");\n }\n if (width * height * 4 !== pixels.length) {\n throw new ValidationError(\"Width and height must match the pixels array\");\n }\n\n let factors: Array<[number, number, number]> = [];\n for (let y = 0; y < componentY; y++) {\n for (let x = 0; x < componentX; x++) {\n const normalisation = x == 0 && y == 0 ? 1 : 2;\n const factor = multiplyBasisFunction(\n pixels,\n width,\n height,\n (i: number, j: number) =>\n normalisation *\n Math.cos((Math.PI * x * i) / width) *\n Math.cos((Math.PI * y * j) / height)\n );\n factors.push(factor);\n }\n }\n\n const dc = factors[0];\n const ac = factors.slice(1);\n\n let hash = \"\";\n\n let sizeFlag = componentX - 1 + (componentY - 1) * 9;\n hash += encode83(sizeFlag, 1);\n\n let maximumValue: number;\n if (ac.length > 0) {\n let actualMaximumValue = Math.max(...ac.map((val) => Math.max(...val)));\n let quantisedMaximumValue = Math.floor(\n Math.max(0, Math.min(82, Math.floor(actualMaximumValue * 166 - 0.5)))\n );\n maximumValue = (quantisedMaximumValue + 1) / 166;\n hash += encode83(quantisedMaximumValue, 1);\n } else {\n maximumValue = 1;\n hash += encode83(0, 1);\n }\n\n hash += encode83(encodeDC(dc), 4);\n\n ac.forEach((factor) => {\n hash += encode83(encodeAC(factor, maximumValue), 2);\n });\n\n return hash;\n};\n\nexport default encode;\n", "/**\n * Compute the resolution to decode a BlurHash placeholder at.\n *\n * A placeholder is a low-frequency blur, and decode cost is\n * O(width * height * componentsX * componentsY). Decoding above a small\n * size wastes work with no visible benefit, because the canvas is stretched\n * to fill its host via CSS (`blur-hash canvas { width:100%; height:100% }`).\n *\n * This caps the long edge to `cap` pixels, preserves the aspect ratio, floors\n * each edge at 1px, and never upscales a source that is already small.\n *\n * @param width The layout/source width in pixels.\n * @param height The layout/source height in pixels.\n * @param cap Maximum pixels on the long edge. Default 32.\n * @returns The decode dimensions to pass to `decode` and `createImageData`.\n */\nexport function decodeDimensions (\n width:number,\n height:number,\n cap:number = 32\n):{ width:number; height:number } {\n const longEdge = Math.max(width, height)\n\n // Never upscale: a source at or below the cap decodes as-is.\n if (longEdge <= cap) {\n return { width, height }\n }\n\n const scale = cap / longEdge\n return {\n width: Math.max(1, Math.round(width * scale)),\n height: Math.max(1, Math.round(height * scale))\n }\n}\n", "import { toAttributes } from '@substrate-system/web-component/attributes'\nimport type { ImgAttrs } from './index.js'\nimport { decodeDimensions } from './decode-dimensions.js'\n\nexport type SSRAttrs = ImgAttrs & { classes?:string }\n\nexport function render (attrs:SSRAttrs) {\n const {\n width,\n height,\n alt,\n contentVisibility,\n placeholder,\n decoding,\n loading,\n srcset,\n sizes,\n src\n } = attrs\n\n if (!placeholder) throw new Error('not placeholder')\n\n const decodeWidth = typeof width === 'string' ? parseInt(width, 10) : width\n const decodeHeight = typeof height === 'string' ?\n parseInt(height, 10) :\n height\n const decodeSize = decodeDimensions(decodeWidth, decodeHeight)\n\n const htmlString = `<canvas\n alt=\"${alt}\"\n width=${decodeSize.width}\n height=${decodeSize.height}\n class=\"blurry\"\n ></canvas>\n\n <img class=\"blurry\"\n alt=\"${alt}\"\n content-visibility=\"${contentVisibility || 'auto'}\"\n decoding=\"${decoding || 'async'}\"\n loading=\"${loading || 'lazy'}\"\n ${srcset ? `srcset=\"${srcset}\"` : ''}\n ${sizes ? `sizes=\"${sizes}\"` : ''}\n src=\"${src}\"\n />`\n\n const attributeString = toAttributes(attrs)\n\n // running in node?\n return typeof window === 'undefined' ?\n `<blur-hash ${attributeString}>\n ${htmlString}\n </blur-hash>` :\n htmlString\n}\n\nexport const outerHTML = (attrs:SSRAttrs) => {\n return `<blur-hash>${render(attrs)}</blur-hash>`\n}\n", "import { WebComponent } from '@substrate-system/web-component'\nimport { decode } from 'blurhash'\nimport { render } from './html.js'\nimport { decodeDimensions } from './decode-dimensions.js'\n\n// for docuement.querySelector\ndeclare global {\n interface HTMLElementTagNameMap {\n 'blur-hash': BlurHash\n }\n}\n\nexport type ImgAttrs = {\n alt:string;\n width:string|number;\n height:string|number;\n placeholder:string;\n src:string;\n srcset?:string|null;\n sizes?:string|null;\n time?:number;\n contentVisibility?:'visible'|'auto'|'hidden'|null;\n decoding?:'sync'|'async'|'auto'|null;\n loading?:'lazy'|'eager'|'auto'|null;\n}\n\nexport class BlurHash extends WebComponent.create('blur-hash') {\n time:number\n rafId:number|null = null\n\n constructor () {\n super()\n const w = this.getAttribute('width')\n const h = this.getAttribute('height')\n const time = this.getAttribute('time')\n this.time = time ? parseInt(time) : 800\n\n this.style.width = '' + w\n this.style.height = '' + h\n\n document.body.style.setProperty('--blur-hash-time',\n time ? '.' + (parseInt(time) / 1000 + 's') : '0.8s')\n }\n\n /**\n * Change the image, and do the blur-up thing again.\n * Will use the existing width & height if they are not passed in.\n */\n reset (attrs:(Omit<Omit<ImgAttrs, 'width'>, 'height'> & {\n width?:string|number;\n height?:string|number;\n })):void {\n if (attrs.width) this.style.width = '' + attrs.width\n if (attrs.height) this.style.height = '' + attrs.height\n\n const width = (attrs.width ?\n (typeof attrs.width === 'string' ? parseInt(attrs.width, 10) : attrs.width) :\n parseInt(this.style.width, 10))\n const height = (attrs.height ?\n (typeof attrs.height === 'string' ? parseInt(attrs.height, 10) : attrs.height) :\n parseInt(this.style.height, 10))\n\n this.innerHTML = BlurHash.html(Object.assign(attrs, { width, height }))\n\n const { placeholder, src: newSrc } = attrs\n\n this.scheduleDecode(placeholder, width, height)\n\n this.setAttribute('src', newSrc)\n this.setAttribute('placeholder', placeholder)\n\n const img = this.querySelector('img')!\n if (attrs.srcset) img.setAttribute('srcset', attrs.srcset)\n if (attrs.sizes) img.setAttribute('sizes', attrs.sizes)\n\n this.sharpen()\n }\n\n /**\n * Decode the placeholder and paint it to the canvas on the next frame.\n * Cancels any pending frame first, so a rapid re-call (e.g. a second\n * `reset`) never leaves a stale decode running. Bails if the element has\n * detached before the frame fires.\n */\n scheduleDecode (placeholder:string, width:number, height:number):void {\n if (this.rafId !== null) cancelAnimationFrame(this.rafId)\n\n const { width: dw, height: dh } = decodeDimensions(width, height)\n\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null\n if (!this.isConnected) return\n const canvas = this.querySelector<HTMLCanvasElement>('canvas')\n if (!canvas) return\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n const pixels = decode(placeholder, dw, dh)\n const imageData = ctx.createImageData(dw, dh)\n imageData.data.set(pixels)\n ctx.putImageData(imageData, 0, 0)\n })\n }\n\n disconnectedCallback ():void {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n }\n\n sharpen () {\n const img = this.qs('img')!\n if (img.complete && img.naturalWidth > 0) {\n img.classList.remove('blurry')\n img.classList.add('sharp')\n } else {\n img.addEventListener('load', () => {\n img.classList.remove('blurry')\n img.classList.add('sharp')\n })\n }\n }\n\n connectedCallback () {\n const width = parseInt(this.getAttribute('width') ?? '')\n const height = parseInt(this.getAttribute('height') ?? '')\n const placeholder = this.getAttribute('placeholder')\n if (!placeholder) throw new Error('Missing placeholder')\n if (!width) throw new Error('Missing width')\n if (!height) throw new Error('Missing height')\n\n // don't render again if we dont have to\n if (!this.innerHTML) {\n this.innerHTML = this.render()\n }\n\n this.scheduleDecode(placeholder, width, height)\n this.sharpen()\n }\n\n static html (attrs:ImgAttrs & { classes?:string }) {\n return render(attrs)\n }\n\n /**\n * Use the attributes to create HTML.\n */\n render ():string {\n const srcset = this.getAttribute('srcset')\n const width = this.getAttribute('width')\n const height = this.getAttribute('height')\n const time = this.getAttribute('time')\n const classes = this.classList.toString()\n const placeholder = this.getAttribute('placeholder')\n this.time = time ? parseInt(time) : 800\n const src = this.getAttribute('src')\n const alt = this.getAttribute('alt')\n if (!placeholder) throw new Error('not placeholder')\n if (!width || !height) throw new Error('not width or not height')\n if (!src) throw new Error('Not src')\n if (!alt) throw new Error('Not alt')\n\n return BlurHash.html({ classes, srcset, width, height, src, alt, placeholder })\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["toAttributes", "attrs", "acc", "k", "value", "__name", "isRegistered", "elName", "__name", "define", "name", "element", "qs", "qsa", "match", "el", "s", "WebComponent", "_WebComponent", "__name", "el", "match", "elementName", "CreatedClass", "evType", "define", "name", "oldValue", "newValue", "handler", "type", "listener", "options", "event", "componentName", "error", "selector", "eventName", "opts", "bubbles", "cancelable", "detail", "namespacedType", "result", "evName", "fullEvName", "entry", "namespace", "isRegistered", "elName", "element", "q", "x", "__name", "t", "e", "n", "l", "f", "__name", "t", "e", "h", "F", "M", "d", "C", "x", "n", "z", "__name", "t", "e", "n", "f", "L", "l", "M", "U", "C", "x", "m", "b", "i", "u", "o", "a", "c", "s", "y", "B", "R", "w", "P", "G", "T", "V", "h", "I", "E", "j", "decodeDimensions", "width", "height", "cap", "longEdge", "scale", "__name", "render", "attrs", "width", "height", "alt", "contentVisibility", "placeholder", "decoding", "loading", "srcset", "sizes", "src", "decodeWidth", "decodeHeight", "decodeSize", "decodeDimensions", "htmlString", "attributeString", "toAttributes", "__name", "BlurHash", "_BlurHash", "WebComponent", "__name", "w", "h", "time", "attrs", "width", "height", "placeholder", "newSrc", "img", "dw", "dh", "decodeDimensions", "canvas", "ctx", "pixels", "j", "imageData", "render", "srcset", "classes", "src", "alt"]
|
|
7
7
|
}
|
package/dist/meta.json
CHANGED
|
@@ -1,22 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"inputs": {
|
|
3
|
+
"src/decode-dimensions.ts": {
|
|
4
|
+
"bytes": 1232,
|
|
5
|
+
"imports": [],
|
|
6
|
+
"format": "esm"
|
|
7
|
+
},
|
|
3
8
|
"src/html.ts": {
|
|
4
|
-
"bytes":
|
|
9
|
+
"bytes": 1573,
|
|
5
10
|
"imports": [],
|
|
6
11
|
"format": "esm"
|
|
7
12
|
},
|
|
8
13
|
"src/index.ts": {
|
|
9
|
-
"bytes":
|
|
14
|
+
"bytes": 5564,
|
|
10
15
|
"imports": [],
|
|
11
16
|
"format": "esm"
|
|
12
17
|
}
|
|
13
18
|
},
|
|
14
19
|
"outputs": {
|
|
20
|
+
"dist/decode-dimensions.js.map": {
|
|
21
|
+
"imports": [],
|
|
22
|
+
"exports": [],
|
|
23
|
+
"inputs": {},
|
|
24
|
+
"bytes": 1689
|
|
25
|
+
},
|
|
26
|
+
"dist/decode-dimensions.js": {
|
|
27
|
+
"imports": [],
|
|
28
|
+
"exports": [
|
|
29
|
+
"decodeDimensions"
|
|
30
|
+
],
|
|
31
|
+
"entryPoint": "src/decode-dimensions.ts",
|
|
32
|
+
"inputs": {
|
|
33
|
+
"src/decode-dimensions.ts": {
|
|
34
|
+
"bytesInOutput": 355
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"bytes": 561
|
|
38
|
+
},
|
|
15
39
|
"dist/html.js.map": {
|
|
16
40
|
"imports": [],
|
|
17
41
|
"exports": [],
|
|
18
42
|
"inputs": {},
|
|
19
|
-
"bytes":
|
|
43
|
+
"bytes": 2569
|
|
20
44
|
},
|
|
21
45
|
"dist/html.js": {
|
|
22
46
|
"imports": [
|
|
@@ -24,6 +48,11 @@
|
|
|
24
48
|
"path": "@substrate-system/web-component/attributes",
|
|
25
49
|
"kind": "import-statement",
|
|
26
50
|
"external": true
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"path": "./decode-dimensions.js",
|
|
54
|
+
"kind": "import-statement",
|
|
55
|
+
"external": true
|
|
27
56
|
}
|
|
28
57
|
],
|
|
29
58
|
"exports": [
|
|
@@ -33,16 +62,16 @@
|
|
|
33
62
|
"entryPoint": "src/html.ts",
|
|
34
63
|
"inputs": {
|
|
35
64
|
"src/html.ts": {
|
|
36
|
-
"bytesInOutput":
|
|
65
|
+
"bytesInOutput": 1394
|
|
37
66
|
}
|
|
38
67
|
},
|
|
39
|
-
"bytes":
|
|
68
|
+
"bytes": 1590
|
|
40
69
|
},
|
|
41
70
|
"dist/index.js.map": {
|
|
42
71
|
"imports": [],
|
|
43
72
|
"exports": [],
|
|
44
73
|
"inputs": {},
|
|
45
|
-
"bytes":
|
|
74
|
+
"bytes": 8871
|
|
46
75
|
},
|
|
47
76
|
"dist/index.js": {
|
|
48
77
|
"imports": [
|
|
@@ -60,6 +89,11 @@
|
|
|
60
89
|
"path": "./html.js",
|
|
61
90
|
"kind": "import-statement",
|
|
62
91
|
"external": true
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"path": "./decode-dimensions.js",
|
|
95
|
+
"kind": "import-statement",
|
|
96
|
+
"external": true
|
|
63
97
|
}
|
|
64
98
|
],
|
|
65
99
|
"exports": [
|
|
@@ -68,10 +102,10 @@
|
|
|
68
102
|
"entryPoint": "src/index.ts",
|
|
69
103
|
"inputs": {
|
|
70
104
|
"src/index.ts": {
|
|
71
|
-
"bytesInOutput":
|
|
105
|
+
"bytesInOutput": 4447
|
|
72
106
|
}
|
|
73
107
|
},
|
|
74
|
-
"bytes":
|
|
108
|
+
"bytes": 4633
|
|
75
109
|
}
|
|
76
110
|
}
|
|
77
111
|
}
|
package/dist/style.css
CHANGED
|
@@ -1,39 +1,38 @@
|
|
|
1
1
|
blur-hash {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
display: block;
|
|
3
|
+
overflow: hidden;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
blur-hash canvas {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
transition: opacity var(--blur-hash-time, .8s);
|
|
8
|
+
opacity: var(--blur-hash-opacity, .4);
|
|
9
|
+
width: 100%;
|
|
10
|
+
height: 100%;
|
|
11
|
+
}
|
|
12
12
|
|
|
13
13
|
blur-hash img {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
transition: opacity var(--blur-hash-time, .8s);
|
|
15
|
+
object-fit: cover;
|
|
16
|
+
position: relative;
|
|
17
|
+
top: -100%;
|
|
18
|
+
}
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
blur-hash img.blurry {
|
|
21
|
+
opacity: 0;
|
|
22
|
+
filter: blur(30px);
|
|
23
|
+
}
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
blur-hash img.sharp {
|
|
26
|
+
opacity: 1;
|
|
27
|
+
animation: sharpen var(--blur-hash-time, .8s) both;
|
|
28
|
+
}
|
|
29
29
|
|
|
30
30
|
@keyframes sharpen {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
to {
|
|
35
|
-
filter: blur(0px)
|
|
36
|
-
}
|
|
37
|
-
}
|
|
31
|
+
from {
|
|
32
|
+
filter: blur(30px);
|
|
33
|
+
}
|
|
38
34
|
|
|
39
|
-
|
|
35
|
+
to {
|
|
36
|
+
filter: blur();
|
|
37
|
+
}
|
|
38
|
+
}
|
package/dist/style.min.css
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
blur-hash{display:block;overflow:hidden}blur-hash canvas{
|
|
2
|
-
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9pbmRleC5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsVUFFSSxhQUFjLENBRGQsZUEwQkosQ0F2QkksaUJBR0ksV0FBWSxDQURaLG1DQUFzQyxDQUV0QyxVQUNKLENBRUEsK0JBTkksNENBcUJKLENBZkEsY0FJSSxnQkFBaUIsQ0FIakIsaUJBQWtCLENBQ2xCLFNBYUosQ0FUSSwwQkFFSSxpQkFBa0IsQ0FEbEIsU0FFSixDQUVBLHlCQUVJLGdEQUFtRCxDQURuRCxTQUVKLENBSVIsbUJBQ0ksR0FDSSxpQkFDSixDQUNBLEdBQ0ksY0FDSixDQUNKIiwiZmlsZSI6InNyYy9pbmRleC5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyJibHVyLWhhc2gge1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgZGlzcGxheTogYmxvY2s7XG5cbiAgICAmIGNhbnZhcyB7XG4gICAgICAgIHRyYW5zaXRpb246IG9wYWNpdHkgdmFyKC0tYmx1ci1oYXNoLXRpbWUsIDAuOHMpO1xuICAgICAgICBvcGFjaXR5OiB2YXIoLS1ibHVyLWhhc2gtb3BhY2l0eSwgMC40KTtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICB9XG5cbiAgICAmIGltZyB7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgdG9wOiAtMTAwJTtcbiAgICAgICAgdHJhbnNpdGlvbjogb3BhY2l0eSB2YXIoLS1ibHVyLWhhc2gtdGltZSwgMC44cyk7XG4gICAgICAgIG9iamVjdC1maXQ6IGNvdmVyO1xuXG4gICAgICAgICYuYmx1cnJ5IHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDA7XG4gICAgICAgICAgICBmaWx0ZXI6IGJsdXIoMzBweCk7XG4gICAgICAgIH1cblxuICAgICAgICAmLnNoYXJwIHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgICAgICBhbmltYXRpb246IHNoYXJwZW4gdmFyKC0tYmx1ci1oYXNoLXRpbWUsIDAuOHMpIGJvdGg7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbkBrZXlmcmFtZXMgc2hhcnBlbiB7XG4gICAgZnJvbSB7XG4gICAgICAgIGZpbHRlcjogYmx1cigzMHB4KTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBmaWx0ZXI6IGJsdXIoMHB4KVxuICAgIH1cbn1cbiJdfQ== */
|
|
1
|
+
blur-hash{display:block;overflow:hidden}blur-hash canvas{transition:opacity var(--blur-hash-time,.8s);opacity:var(--blur-hash-opacity,.4);width:100%;height:100%}blur-hash img{transition:opacity var(--blur-hash-time,.8s);object-fit:cover;position:relative;top:-100%}blur-hash img.blurry{opacity:0;filter:blur(30px)}blur-hash img.sharp{opacity:1;animation:sharpen var(--blur-hash-time,.8s) both}@keyframes sharpen{0%{filter:blur(30px)}to{filter:blur()}}
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@substrate-system/blur-hash",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.37",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A blurry placeholder image web component",
|
|
6
|
+
"browserslist": ">= 0.25%",
|
|
6
7
|
"main": "dist/index.js",
|
|
7
8
|
"bin": {
|
|
8
9
|
"blur": "dist/bin/index.js"
|
|
@@ -41,8 +42,8 @@
|
|
|
41
42
|
"test-api": "esbuild ./test/api.ts --format=esm --platform=node > test/api.js && esbuild ./bin/index.ts --platform=node > bin/index.js && node ./test/api.js | tap-spec",
|
|
42
43
|
"test-ssr": "esbuild ./test/ssr.ts --bundle --platform=node | node --input-type=module | tap-spec",
|
|
43
44
|
"test-tape-run": "cat test/index.html | tape-run --input=html --static=test | tap-spec",
|
|
44
|
-
"build-css": "
|
|
45
|
-
"build-css:min": "
|
|
45
|
+
"build-css": "lightningcss --browserslist src/index.css -o dist/style.css",
|
|
46
|
+
"build-css:min": "lightningcss --browserslist --minify src/index.css -o dist/style.min.css",
|
|
46
47
|
"build-cjs": "esbuild src/*.ts --format=cjs --keep-names --tsconfig=tsconfig.build.json --outdir=./dist --out-extension:.js=.cjs --sourcemap",
|
|
47
48
|
"build-esm": "esbuild src/*.ts --format=esm --metafile=dist/meta.json --keep-names --tsconfig=tsconfig.build.json --outdir=./dist --sourcemap && tsc --emitDeclarationOnly --project tsconfig.build.json --outDir dist",
|
|
48
49
|
"build-esm:min": "esbuild ./src/*.ts --format=esm --keep-names --bundle --tsconfig=tsconfig.build.json --minify --out-extension:.js=.min.js --outdir=./dist --sourcemap",
|
|
@@ -58,7 +59,7 @@
|
|
|
58
59
|
"prepublishOnly": "npm run build"
|
|
59
60
|
},
|
|
60
61
|
"dependencies": {
|
|
61
|
-
"@substrate-system/web-component": "^0.0.
|
|
62
|
+
"@substrate-system/web-component": "^0.0.51",
|
|
62
63
|
"blurhash": "^2.0.5",
|
|
63
64
|
"image-size": "^2.0.2",
|
|
64
65
|
"inkjet": "^3.0.0",
|
|
@@ -72,19 +73,18 @@
|
|
|
72
73
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
73
74
|
"@typescript-eslint/parser": "^8.0.0",
|
|
74
75
|
"auto-changelog": "^2.4.0",
|
|
75
|
-
"
|
|
76
|
+
"browserslist": "^4.24.0",
|
|
76
77
|
"esbuild": "^0.27.2",
|
|
77
78
|
"eslint": "^8.57.0",
|
|
78
79
|
"eslint-config-standard": "^17.1.0",
|
|
80
|
+
"lightningcss": "^1.32.0",
|
|
81
|
+
"lightningcss-cli": "^1.32.0",
|
|
79
82
|
"markdown-toc": "^1.2.0",
|
|
80
|
-
"postcss": "^8.4.38",
|
|
81
|
-
"postcss-cli": "^11.0.0",
|
|
82
|
-
"postcss-nesting": "^14.0.0",
|
|
83
83
|
"tap-spec": "^5.0.0",
|
|
84
84
|
"tape-run": "^11.0.0",
|
|
85
85
|
"typedoc": "^0.28.1",
|
|
86
|
-
"typescript": "^
|
|
87
|
-
"vite": "^
|
|
86
|
+
"typescript": "^6.0.2",
|
|
87
|
+
"vite": "^8.0.5"
|
|
88
88
|
},
|
|
89
89
|
"author": "nichoth <nichoth@nichoth.com> (https://nichoth.com)",
|
|
90
90
|
"license": "SEE LICENSE IN LICENSE",
|