@visulima/html 1.0.1 → 1.0.2

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/CHANGELOG.md CHANGED
@@ -1,3 +1,5 @@
1
+ ## @visulima/html [1.0.2](https://github.com/visulima/visulima/compare/%40visulima%2Fhtml%401.0.1...%40visulima%2Fhtml%401.0.2) (2026-08-02)
2
+
1
3
  ## @visulima/html [1.0.1](https://github.com/visulima/visulima/compare/%40visulima%2Fhtml%401.0.0...%40visulima%2Fhtml%401.0.1) (2026-07-15)
2
4
 
3
5
  ## @visulima/html 1.0.0 (2026-07-03)
package/dist/css.d.ts CHANGED
@@ -1,38 +1,38 @@
1
1
  import { Properties } from 'csstype';
2
2
  /**
3
- * The standard CSS properties type from `csstype`.
4
- */
3
+ * The standard CSS properties type from `csstype`.
4
+ */
5
5
  type CSSProperties = Properties;
6
6
  /**
7
- * Flexible CSS properties type that allows autocomplete for property names
8
- * while accepting string, number, null, or undefined values.
9
- */
10
- type FlexibleCSSProperties = { [K in keyof Properties]?: Properties[K] | string | number | null | undefined };
7
+ * Flexible CSS properties type that allows autocomplete for property names
8
+ * while accepting string, number, null, or undefined values.
9
+ */
10
+ type FlexibleCSSProperties = { [K in keyof Properties]?: Properties[K] | string | number | null | undefined; };
11
11
  /**
12
- * Template tag function for CSS that returns a minified one-line CSS string.
13
- * Template strings are used as-is, but interpolated values are escaped by default.
14
- * Whitespace and newlines outside of quoted strings are collapsed into single spaces;
15
- * whitespace inside single-/double-quoted values (e.g. `content: "a b"`) is preserved.
16
- * @param strings Template literal strings
17
- * @param values Template literal values (escaped by default)
18
- * @returns A minified one-line CSS string
19
- * @example
20
- * css`:where(.UnderlineNav-actions ul) { animation: 1ms rgh-selector-observer; }`
21
- * // Returns: ":where(.UnderlineNav-actions ul) { animation: 1ms rgh-selector-observer; }"
22
- */
12
+ * Template tag function for CSS that returns a minified one-line CSS string.
13
+ * Template strings are used as-is, but interpolated values are escaped by default.
14
+ * Whitespace and newlines outside of quoted strings are collapsed into single spaces;
15
+ * whitespace inside single-/double-quoted values (e.g. `content: "a b"`) is preserved.
16
+ * @param strings Template literal strings
17
+ * @param values Template literal values (escaped by default)
18
+ * @returns A minified one-line CSS string
19
+ * @example
20
+ * css`:where(.UnderlineNav-actions ul) { animation: 1ms rgh-selector-observer; }`
21
+ * // Returns: ":where(.UnderlineNav-actions ul) { animation: 1ms rgh-selector-observer; }"
22
+ */
23
23
  declare function css(strings: TemplateStringsArray, ...values: unknown[]): string;
24
24
  /**
25
- * Function overload for CSS with escaping control.
26
- * Supports both string and object inputs.
27
- * @param value The CSS string or object to process
28
- * @param shouldEscape If true, escapes CSS. If false, returns CSS as-is.
29
- * @returns The processed CSS string
30
- * @example
31
- * css(':where(.UnderlineNav-actions ul) { animation: 1ms rgh-selector-observer; }', true)
32
- * @example
33
- * css({ padding: "1px" }, true)
34
- * @example
35
- * css({ margin: 20, padding: 10 }, false)
36
- */
25
+ * Function overload for CSS with escaping control.
26
+ * Supports both string and object inputs.
27
+ * @param value The CSS string or object to process
28
+ * @param shouldEscape If true, escapes CSS. If false, returns CSS as-is.
29
+ * @returns The processed CSS string
30
+ * @example
31
+ * css(':where(.UnderlineNav-actions ul) { animation: 1ms rgh-selector-observer; }', true)
32
+ * @example
33
+ * css({ padding: "1px" }, true)
34
+ * @example
35
+ * css({ margin: 20, padding: 10 }, false)
36
+ */
37
37
  declare function css(value: string | FlexibleCSSProperties | Properties, shouldEscape?: boolean): string;
38
38
  export { type CSSProperties, type FlexibleCSSProperties, css as default };
package/dist/css.js CHANGED
@@ -1,2 +1,2 @@
1
- import{escapeCss as f}from"./packem_shared/escapeCss-BtzOEJZW.js";const l=new Map,u=t=>{const e=l.get(t);if(e!==void 0)return e;let r;if(t.startsWith("--"))r=t;else{const n=t.replaceAll(/([A-Z])/g,"-$1").toLowerCase();r=n.startsWith("ms-")?`-ms-${n.slice(3)}`:n}return l.set(t,r),r},g=t=>{const e=[];return Object.entries(t).forEach(([r,n])=>{n!=null&&e.push(`${u(r)}: ${String(n)};`)}),e.join(" ")},p=new Set([" "," ",`
2
- `,"\r","\f","\v"]),h=t=>{let e="",r,n=!1;for(let i=0;i<t.length;i+=1){const s=t[i];if(r!==void 0){e+=s,s==="\\"&&i+1<t.length?(i+=1,e+=t[i]):s===r&&(r=void 0);continue}if(s==='"'||s==="'")r=s,n=!1;else if(p.has(s)){if(n)continue;n=!0,e+=" ";continue}else n=!1;e+=s}return e.trim()};function m(t,...e){if(Array.isArray(t)&&"raw"in t){const s=t;let o=s[0]??"";for(const[c,a]of e.entries())o+=f(String(a??"")),o+=s[c+1]??"";return h(o)}const r=t,n=e[0],i=typeof r=="string"?r:g(r);return n===!0?f(i):i}export{m as default};
1
+ import{escapeCss as f}from"./packem_shared/escapeCss-BtzOEJZW.js";const a=new Map,g=1e3,h=t=>{if(t.startsWith("--"))return t;const e=a.get(t);if(e!==void 0)return e;const n=t.replaceAll(/([A-Z])/g,"-$1").toLowerCase(),s=n.startsWith("ms-")?`-ms-${n.slice(3)}`:n;return a.size<g&&a.set(t,s),s},p=t=>{const e=[];return Object.entries(t).forEach(([n,s])=>{s!=null&&e.push(`${h(n)}: ${String(s)};`)}),e.join(" ")},l=new Set([" "," ",`
2
+ `,"\r","\f","\v"]),d=t=>{let e,n=!1,s=!1,i="";for(let o=0;o<t.length;o+=1){const r=t[o];if(e!==void 0){r==="\\"&&o+1<t.length?(i+=r+t[o+1],o+=1):(r===e&&(e=void 0),i+=r);continue}if(n){r==="*"&&t[o+1]==="/"?(i+="*/",o+=1,n=!1,s=!1):l.has(r)?(s||(i+=" "),s=!0):(i+=r,s=!1);continue}r==="/"&&t[o+1]==="*"?(i+="/*",o+=1,n=!0,s=!1):r==='"'||r==="'"?(e=r,i+=r,s=!1):l.has(r)?(s||(i+=" "),s=!0):(i+=r,s=!1)}return i.trim()};function v(t,...e){if(Array.isArray(t)&&"raw"in t){const o=t;let r=o[0]??"";for(const[u,c]of e.entries())r+=f(String(c??"")),r+=o[u+1]??"";return d(r)}const n=t,s=e[0],i=typeof n=="string"?n:p(n);return s===!0?f(i):i}export{v as default};
package/dist/escape.d.ts CHANGED
@@ -1,20 +1,20 @@
1
1
  export { escapeCss } from '@std/html/unstable-escape-css';
2
2
  export { escapeJs } from '@std/html/unstable-escape-js';
3
3
  /**
4
- * Escapes HTML special characters in a string.
5
- * Optimized for performance with minimal allocations.
6
- * @param value The value to escape. Will be converted to string.
7
- * @param isAttribute If true, also escapes double quotes (for HTML attributes).
8
- * @returns The escaped string.
9
- * @example
10
- * escapeHtml('<script>alert("xss")<\/script>');
11
- * // => '&lt;script>alert("xss")&lt;/script>'
12
- * @example
13
- * escapeHtml('<div>', true);
14
- * // => '&lt;div>'
15
- * @example
16
- * escapeHtml('value="test"', true);
17
- * // => 'value=&quot;test&quot;'
18
- */
4
+ * Escapes HTML special characters in a string.
5
+ * Optimized for performance with minimal allocations.
6
+ * @param value The value to escape. Will be converted to string.
7
+ * @param isAttribute If true, also escapes double quotes (for HTML attributes).
8
+ * @returns The escaped string.
9
+ * @example
10
+ * escapeHtml('<script>alert("xss")<\/script>');
11
+ * // => '&lt;script>alert("xss")&lt;/script>'
12
+ * @example
13
+ * escapeHtml('<div>', true);
14
+ * // => '&lt;div>'
15
+ * @example
16
+ * escapeHtml('value="test"', true);
17
+ * // => 'value=&quot;test&quot;'
18
+ */
19
19
  declare const escapeHtml: (value: unknown, isAttribute?: boolean) => string;
20
20
  export { escapeHtml };
package/dist/html.d.ts CHANGED
@@ -1,58 +1,59 @@
1
1
  /**
2
- * Branded wrapper produced by {@link html.raw}. Values wrapped in this marker are
3
- * interpolated into the `html` tagged template (or composed via arrays) verbatim,
4
- * without escaping. Use it only for HTML you already trust.
5
- */
2
+ * Branded wrapper produced by {@link html.raw}. Values wrapped in this marker are
3
+ * interpolated into the `html` tagged template (or composed via arrays) verbatim,
4
+ * without escaping. Use it only for HTML you already trust.
5
+ */
6
+ declare const RAW_BRAND: unique symbol;
6
7
  interface RawHtml {
7
8
  /** Internal brand used to detect trusted fragments. */
8
- readonly __isRawHtml: true;
9
+ readonly [RAW_BRAND]: true;
9
10
  /** The trusted HTML payload. */
10
11
  readonly value: string;
11
12
  }
12
13
  /**
13
- * Type guard that detects a {@link RawHtml} marker (including nested fragments
14
- * produced by the `html` tag, which are themselves marked as raw).
15
- * @param value The value to test.
16
- * @returns `true` when the value is a trusted raw HTML fragment.
17
- */
14
+ * Type guard that detects a {@link RawHtml} marker (including nested fragments
15
+ * produced by the `html` tag, which are themselves marked as raw).
16
+ * @param value The value to test.
17
+ * @returns `true` when the value is a trusted raw HTML fragment.
18
+ */
18
19
  declare const isRawHtml: (value: unknown) => value is RawHtml;
19
20
  /**
20
- * Template tag function for HTML that escapes interpolated values to prevent XSS.
21
- * Template strings are used as-is, but all interpolated values are HTML-escaped.
22
- *
23
- * Interpolated arrays are flattened and joined with an empty string (no commas), and
24
- * values wrapped with {@link html.raw} are inlined without escaping, enabling fragment
25
- * composition. Because the tag returns a plain string, nested fragments must be wrapped
26
- * with `html.raw` to avoid double-escaping.
27
- * @param strings Template literal strings
28
- * @param values Template literal values (escaped unless wrapped with {@link html.raw})
29
- * @returns The HTML string with interpolated values escaped
30
- * @example
31
- * html`<div>Hello</div>`
32
- * // => '<div>Hello</div>'
33
- * @example
34
- * html`<div>${'<script>alert("xss")<\/script>'}</div>`
35
- * // => '<div>&lt;script>alert("xss")&lt;/script></div>'
36
- * @example
37
- * html`<ul>${items.map((i) => html.raw(html`<li>${i}</li>`))}</ul>`
38
- * // => '<ul><li>a</li><li>b</li></ul>'
39
- */
21
+ * Template tag function for HTML that escapes interpolated values to prevent XSS.
22
+ * Template strings are used as-is, but all interpolated values are HTML-escaped.
23
+ *
24
+ * Interpolated arrays are flattened and joined with an empty string (no commas), and
25
+ * values wrapped with {@link html.raw} are inlined without escaping, enabling fragment
26
+ * composition. Because the tag returns a plain string, nested fragments must be wrapped
27
+ * with `html.raw` to avoid double-escaping.
28
+ * @param strings Template literal strings
29
+ * @param values Template literal values (escaped unless wrapped with {@link html.raw})
30
+ * @returns The HTML string with interpolated values escaped
31
+ * @example
32
+ * html`<div>Hello</div>`
33
+ * // => '<div>Hello</div>'
34
+ * @example
35
+ * html`<div>${'<script>alert("xss")<\/script>'}</div>`
36
+ * // => '<div>&lt;script>alert("xss")&lt;/script></div>'
37
+ * @example
38
+ * html`<ul>${items.map((i) => html.raw(html`<li>${i}</li>`))}</ul>`
39
+ * // => '<ul><li>a</li><li>b</li></ul>'
40
+ */
40
41
  declare function html(strings: TemplateStringsArray, ...values: unknown[]): string;
41
42
  /**
42
- * Function overload for HTML with explicit escaping control.
43
- *
44
- * Escapes by default (attribute-safe), matching the template-tag form. Pass
45
- * `shouldEscape: false` to opt out and return the input verbatim — only do this
46
- * for HTML you already trust or have sanitized, since it disables XSS protection.
47
- * @param value The HTML string to process
48
- * @param shouldEscape When `true`/omitted, escapes HTML. When `false`, returns the input as-is (unsafe for untrusted input).
49
- * @returns The processed HTML string
50
- * @example
51
- * html('<script>alert("xss")<\/script>')
52
- * // => '&lt;script>alert(&quot;xss&quot;)&lt;/script>'
53
- * @example
54
- * html('<div></div>', false)
55
- * // => '<div></div>'
56
- */
43
+ * Function overload for HTML with explicit escaping control.
44
+ *
45
+ * Escapes by default (attribute-safe), matching the template-tag form. Pass
46
+ * `shouldEscape: false` to opt out and return the input verbatim — only do this
47
+ * for HTML you already trust or have sanitized, since it disables XSS protection.
48
+ * @param value The HTML string to process
49
+ * @param shouldEscape When `true`/omitted, escapes HTML. When `false`, returns the input as-is (unsafe for untrusted input).
50
+ * @returns The processed HTML string
51
+ * @example
52
+ * html('<script>alert("xss")<\/script>')
53
+ * // => '&lt;script>alert(&quot;xss&quot;)&lt;/script>'
54
+ * @example
55
+ * html('<div></div>', false)
56
+ * // => '<div></div>'
57
+ */
57
58
  declare function html(value: string, shouldEscape?: boolean): string;
58
59
  export { type RawHtml, html as default, isRawHtml };
package/dist/html.js CHANGED
@@ -1 +1 @@
1
- import o from"./packem_shared/escapeHtml-CiWsYlrs.js";const u="__isRawHtml",l=r=>typeof r=="object"&&r!==null&&r[u]===!0,s=r=>{if(l(r))return r.value;if(Array.isArray(r)){let e="";for(const t of r)e+=s(t);return e}return o(r,!0)};function c(r,...e){if(Array.isArray(r)&&"raw"in r){const n=r;let a=n[0]??"";for(const[f,i]of e.entries())a+=s(i),a+=n[f+1]??"";return a}const t=r;return e[0]===!1?t:o(t,!0)}c.raw=r=>({[u]:!0,value:r});export{c as default,l as isRawHtml};
1
+ import u from"./packem_shared/escapeHtml-CiWsYlrs.js";const n=Symbol("visulima.rawHtml"),s=r=>typeof r=="object"&&r!==null&&r[n]===!0,f=r=>{if(s(r))return r.value;if(Array.isArray(r)){let e="";for(const o of r)e+=f(o);return e}return u(r,!0)};function c(r,...e){if(Array.isArray(r)&&"raw"in r){const t=r;let a=t[0]??"";for(const[i,l]of e.entries())a+=f(l),a+=t[i+1]??"";return a}const o=r;return e[0]===!1?o:u(o,!0)}c.raw=r=>({[n]:!0,value:r});export{c as default,s as isRawHtml};
package/dist/index.d.ts CHANGED
@@ -22,20 +22,11 @@ interface DecodeOptions extends CommonOptions {
22
22
  scope?: DecodeScope;
23
23
  }
24
24
  /** Encodes all the necessary (specified by `level`) characters in the text */
25
- declare function encode(text: string | undefined | null, {
26
- mode,
27
- numeric,
28
- level
29
- }?: EncodeOptions): string;
25
+ declare function encode(text: string | undefined | null, { mode, numeric, level }?: EncodeOptions): string;
30
26
  /** Decodes a single entity */
31
- declare function decodeEntity(entity: string | undefined | null, {
32
- level
33
- }?: CommonOptions): string;
27
+ declare function decodeEntity(entity: string | undefined | null, { level }?: CommonOptions): string;
34
28
  /** Decodes all entities in the text */
35
- declare function decode(text: string | undefined | null, {
36
- level,
37
- scope
38
- }?: DecodeOptions): string;
29
+ declare function decode(text: string | undefined | null, { level, scope }?: DecodeOptions): string;
39
30
  type HtmlTags = 'a' | 'abbr' | 'address' | 'area' | 'article' | 'aside' | 'audio' | 'b' | 'base' | 'bdi' | 'bdo' | 'blockquote' | 'body' | 'br' | 'button' | 'canvas' | 'caption' | 'cite' | 'code' | 'col' | 'colgroup' | 'data' | 'datalist' | 'dd' | 'del' | 'details' | 'dfn' | 'dialog' | 'div' | 'dl' | 'dt' | 'em' | 'embed' | 'fieldset' | 'figcaption' | 'figure' | 'footer' | 'form' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'head' | 'header' | 'hgroup' | 'hr' | 'html' | 'i' | 'iframe' | 'img' | 'input' | 'ins' | 'kbd' | 'label' | 'legend' | 'li' | 'link' | 'main' | 'map' | 'mark' | 'math' | 'menu' | 'meta' | 'meter' | 'nav' | 'noscript' | 'object' | 'ol' | 'optgroup' | 'option' | 'output' | 'p' | 'picture' | 'pre' | 'progress' | 'q' | 'rp' | 'rt' | 'ruby' | 's' | 'samp' | 'script' | 'search' | 'section' | 'select' | 'selectedcontent' | 'slot' | 'small' | 'source' | 'span' | 'strong' | 'style' | 'sub' | 'summary' | 'sup' | 'svg' | 'table' | 'tbody' | 'td' | 'template' | 'textarea' | 'tfoot' | 'th' | 'thead' | 'time' | 'title' | 'tr' | 'track' | 'u' | 'ul' | 'var' | 'video' | 'wbr';
40
31
  type VoidHtmlTags = 'area' | 'base' | 'br' | 'col' | 'embed' | 'hr' | 'img' | 'input' | 'link' | 'meta' | 'source' | 'track' | 'wbr';
41
32
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@visulima/html",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Functions for HTML, such as escaping or unescaping HTML entities",
5
5
  "keywords": [
6
6
  "css",