@localnerve/web-component-build 3.4.0-rc.2 → 3.4.0-rc.4

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/README.md CHANGED
@@ -11,6 +11,7 @@ The parts are processed and written to an output directory, then exposed to a ca
11
11
 
12
12
  * [Why This Exists](#why-this-exists)
13
13
  * [Processing Possibilities](#processing-map)
14
+ * [Trusted Types Helpers](#trusted-types-helpers)
14
15
  * [Usage](#usage)
15
16
  * [API](#api)
16
17
  * [Options](#options-object-optional)
@@ -42,6 +43,40 @@ The following is a table of _some_ of the possible input, processing, and output
42
43
 
43
44
  > By default, html minification minifies any css found therein.
44
45
 
46
+ ## Trusted Types Helpers
47
+
48
+ In addition to `build`, this package exports a small set of browser runtime helpers so that web components can be authored to work **with** and **without** [Trusted Types](https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types) enforcement (CSP `require-trusted-types-for 'script'`).
49
+
50
+ ```
51
+ export { escapeHtml, getTrustedPolicy, trustedHtml }
52
+ ```
53
+
54
+ The idea: a component registers **its own named policy** for the static, author-controlled markup it injects into sinks (`innerHTML`, etc.), escapes any user-influenced values before composing them, and falls back to plain-string passthrough in browsers (or builds) that do not enforce Trusted Types. Import these helpers directly into your component source — they are small, dependency-free, and get tree-shaken/inlined into the final bundle at build time (a consuming component does **not** need a runtime dependency on this package).
55
+
56
+ ### escapeHtml(input)
57
+ Applies the industry-standard 6-character escape — `& < > " ' \`` → `&amp; &lt; &gt; &quot; &#x27; &#x60;` — for safe interpolation into HTML markup. Escaping quotes and the backtick (not just `&lt;/&gt;`) is what makes the result safe to reuse inside an **attribute value**, not only element content (matches `he.escape`). `null`/`undefined` yield `''`. Use it for any user-influenced value before composing it into markup.
58
+ ```js
59
+ import { escapeHtml } from '@localnerve/web-component-build';
60
+ const html = `<li>${escapeHtml(key)}: ${escapeHtml(value)}</li>`;
61
+ // safe to interpolate into text OR a quoted attribute value
62
+ ```
63
+
64
+ ### getTrustedPolicy(name, hooks)
65
+ Gets (creating once) a named Trusted Type policy. A name may only be created once without the CSP `allow-duplicates` keyword, so repeated calls reuse the instance. Returns `null` when Trusted Types is unavailable (passthrough mode). The default hooks are pass-through `createHTML`/`createScriptURL`, appropriate for author-controlled content that has already been escaped where needed.
66
+ ```js
67
+ import { getTrustedPolicy } from '@localnerve/web-component-build';
68
+ const policy = getTrustedPolicy('my-component'); // null if TT unavailable
69
+ ```
70
+
71
+ ### trustedHtml(policyName, html)
72
+ Converts author-controlled (or pre-escaped) markup into a value safe to pass to an HTML injection sink under Trusted Types enforcement. Returns a `TrustedHTML` when enforced, otherwise the input string unchanged (passthrough for dev builds / browsers without Trusted Types).
73
+ ```js
74
+ import { trustedHtml } from '@localnerve/web-component-build';
75
+ shadowRoot.innerHTML = trustedHtml('my-component', '<div>…static template…</div>');
76
+ ```
77
+
78
+ > The policy name must be allowlisted in the site's CSP `trusted-types` directive, e.g. `trusted-types default my-component;`. A build step can compute that allowlist from your sources — see [`@localnerve/trusted-types-rules`](https://github.com/localnerve/trusted-types-rules#readme). See [editable-object](https://github.com/localnerve/editable-object#trusted-types) for a complete, real-world example of a component built on these helpers.
79
+
45
80
  ## Usage
46
81
 
47
82
  ```javascript
package/index.js CHANGED
@@ -7,4 +7,4 @@
7
7
  * Copyrights licensed under the BSD License. See the accompanying LICENSE file for terms.
8
8
  */
9
9
  export { build, build as default } from './lib/index.js';
10
- export * as browser from './lib/browser/index.js';
10
+ export { escapeHtml, getTrustedPolicy, trustedHtml } from './lib/browser/index.js';
@@ -27,7 +27,12 @@ const policies = new Map();
27
27
 
28
28
  /**
29
29
  * Escape a value for safe interpolation into HTML markup (text or attribute).
30
- *
30
+ *
31
+ * Applies the industry-standard escape of all six characters that can break
32
+ * out of a text or attribute context: & < > " ' and backtick. Escaping quotes
33
+ * and the backtick (not just &lt;/&gt;) is what makes the result safe to reuse
34
+ * inside an attribute value, not only element content.
35
+ *
31
36
  * @param {Any} input - The value to escape
32
37
  * @returns {String} The escaped string. null/undefined yield ''.
33
38
  */
@@ -38,7 +43,8 @@ export function escapeHtml (input) {
38
43
  .replace(/</g, '&lt;')
39
44
  .replace(/>/g, '&gt;')
40
45
  .replace(/"/g, '&quot;')
41
- .replace(/'/g, '&#39;');
46
+ .replace(/'/g, '&#x27;')
47
+ .replace(/`/g, '&#x60;');
42
48
  }
43
49
 
44
50
  /**
package/package.json CHANGED
@@ -1,13 +1,21 @@
1
1
  {
2
2
  "name": "@localnerve/web-component-build",
3
- "version": "3.4.0-rc.2",
3
+ "version": "3.4.0-rc.4",
4
4
  "description": "A library to help build web components",
5
5
  "main": "index.js",
6
6
  "type": "module",
7
7
  "exports": {
8
- "import": "./index.js",
9
- "default": "./index.js"
8
+ ".": {
9
+ "browser": "./lib/browser/index.js",
10
+ "import": "./index.js",
11
+ "default": "./index.js"
12
+ },
13
+ "./browser": {
14
+ "import": "./lib/browser/index.js",
15
+ "default": "./lib/browser/index.js"
16
+ }
10
17
  },
18
+ "browser": "./lib/browser/index.js",
11
19
  "scripts": {
12
20
  "lint": "eslint .",
13
21
  "pretest": "node -e \"const fs=require('fs');fs.rmSync('./coverage',{recursive:true,force:true});fs.mkdirSync('./coverage',{recursive:true})\"",