Skip to content
This repository was archived by the owner on Jan 9, 2025. It is now read-only.

Commit 1e02b01

Browse files
committed
Move setCspTrustedPolicy into TemplateResult class
1 parent 0e40021 commit 1e02b01

File tree

8 files changed

+37
-39
lines changed

8 files changed

+37
-39
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,10 @@ render(html`<div>${until(request, timeout, loading)}</div>`)
248248
249249
### CSP Trusted Types
250250
251-
You can call `setCSPTrustedTypesPolicy(policy: TrustedTypePolicy | Promise<TrustedTypePolicy> | null)` from JavaScript to set a [CSP trusted types policy](https://web.dev/trusted-types/), which can perform (synchronous) filtering or rejection of the rendered template:
251+
You can call `TemplateResult.setCSPTrustedTypesPolicy(policy: TrustedTypePolicy | Promise<TrustedTypePolicy> | null)` from JavaScript to set a [CSP trusted types policy](https://web.dev/trusted-types/), which can perform (synchronous) filtering or rejection of the rendered template:
252252
253253
```ts
254-
import {setCspTrustedTypePolicy} from "@github/jtml";
254+
import {TemplateResult} from "@github/jtml";
255255
import DOMPurify from "dompurify"; // Using https://github.com/cure53/DOMPurify
256256
257257
// This policy removes all HTML markup except links.
@@ -264,11 +264,11 @@ const policy = trustedTypes.createPolicy("links-only", {
264264
});
265265
},
266266
});
267-
setCSPTrustedTypesPolicy(policy);
267+
TemplateResult.setCSPTrustedTypesPolicy(policy);
268268
```
269269
270270
Note that:
271271
272272
- Only a single policy can be set, shared by all `render` and `unsafeHTML` calls.
273-
- You should call `setCSPTrustedTypesPolicy()` ahead of any other call of `@github/jtml` in your code.
273+
- You should call `TemplateResult.setCSPTrustedTypesPolicy()` ahead of any other call of `@github/jtml` in your code.
274274
- Not all browsers [support the trusted types API in JavaScript](https://caniuse.com/mdn-api_trustedtypes). You may want to use the [recommended tinyfill](https://github.com/w3c/trusted-types#tinyfill) to construct a policy without causing issues in other browsers.

src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,3 @@ export {html} from './html.js'
55
export {isDirective, directive} from './directive.js'
66
export {until} from './until.js'
77
export {unsafeHTML} from './unsafe-html.js'
8-
export {setCSPTrustedTypesPolicy} from './trusted-types.js'

src/template-result.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,41 @@
11
import {TemplateInstance, NodeTemplatePart} from '@github/template-parts'
22
import type {TemplateTypeInit} from '@github/template-parts'
3-
import {getCSPTrustedTypesPolicy} from './trusted-types.js'
43

54
const templates = new WeakMap<TemplateStringsArray, HTMLTemplateElement>()
65
const renderedTemplates = new WeakMap<Node | NodeTemplatePart, HTMLTemplateElement>()
76
const renderedTemplateInstances = new WeakMap<Node | NodeTemplatePart, TemplateInstance>()
87

8+
interface CSPTrustedHTMLToStringable {
9+
toString: () => string
10+
}
11+
12+
interface CSPTrustedTypesPolicy {
13+
createHTML: (s: string) => CSPTrustedHTMLToStringable
14+
}
15+
916
export class TemplateResult {
1017
constructor(
1118
public readonly strings: TemplateStringsArray,
1219
public readonly values: unknown[],
1320
public processor: TemplateTypeInit
1421
) {}
1522

23+
static cspTrustedTypesPolicy: CSPTrustedTypesPolicy | null = null
24+
25+
static setCSPTrustedTypesPolicy(policy: CSPTrustedTypesPolicy | null) {
26+
TemplateResult.cspTrustedTypesPolicy = policy
27+
}
28+
1629
get template(): HTMLTemplateElement {
1730
if (templates.has(this.strings)) {
1831
return templates.get(this.strings)!
1932
} else {
2033
const template = document.createElement('template')
2134
const end = this.strings.length - 1
2235
const html = this.strings.reduce((str, cur, i) => str + cur + (i < end ? `{{ ${i} }}` : ''), '')
23-
const trustedHtml = getCSPTrustedTypesPolicy() ? (getCSPTrustedTypesPolicy()?.createHTML(html) as string) : html
36+
const trustedHtml = TemplateResult.cspTrustedTypesPolicy
37+
? (TemplateResult.cspTrustedTypesPolicy.createHTML(html) as string)
38+
: html
2439
template.innerHTML = trustedHtml
2540
templates.set(this.strings, template)
2641
return template

src/trusted-types.ts

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +0,0 @@
1-
interface CSPTrustedHTMLToStringable {
2-
toString: () => string
3-
}
4-
5-
interface CSPTrustedTypesPolicy {
6-
createHTML: (s: string) => CSPTrustedHTMLToStringable
7-
}
8-
9-
let cspTrustedTypesPolicy: CSPTrustedTypesPolicy | null = null
10-
11-
export function getCSPTrustedTypesPolicy() {
12-
return cspTrustedTypesPolicy
13-
}
14-
15-
export function setCSPTrustedTypesPolicy(policy: CSPTrustedTypesPolicy | null) {
16-
cspTrustedTypesPolicy = policy
17-
}

src/unsafe-html.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import {directive} from './directive.js'
22
import {NodeTemplatePart} from '@github/template-parts'
33
import type {TemplatePart} from '@github/template-parts'
4-
import {getCSPTrustedTypesPolicy} from './trusted-types.js'
4+
import {TemplateResult} from './template-result.js'
55

66
export const unsafeHTML = directive((value: string) => (part: TemplatePart) => {
77
if (!(part instanceof NodeTemplatePart)) return
88
const template = document.createElement('template')
9-
const trustedValue = getCSPTrustedTypesPolicy() ? (getCSPTrustedTypesPolicy()?.createHTML(value) as string) : value
9+
const trustedValue = TemplateResult.cspTrustedTypesPolicy
10+
? (TemplateResult.cspTrustedTypesPolicy.createHTML(value) as string)
11+
: value
1012
template.innerHTML = trustedValue
1113
const fragment = document.importNode(template.content, true)
1214
part.replace(...fragment.childNodes)

test/render.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {expect} from 'chai'
2-
import {html, render, setCSPTrustedTypesPolicy} from '../lib/index.js'
2+
import {html, render, TemplateResult} from '../lib/index.js'
33
import type {TemplateResult} from '../lib/index.js'
44

55
describe('render', () => {
@@ -9,7 +9,7 @@ describe('render', () => {
99
})
1010

1111
afterEach(() => {
12-
setCSPTrustedTypesPolicy(null)
12+
TemplateResult.setCSPTrustedTypesPolicy(null)
1313
})
1414

1515
it('memoizes by TemplateResult#template, updating old templates with new values', () => {
@@ -64,7 +64,7 @@ describe('render', () => {
6464
it('respects a Trusted Types Policy if it is set', () => {
6565
let policyCalled = false
6666
const rewrittenFragment = '<div id="bar"></div>'
67-
setCSPTrustedTypesPolicy({
67+
TemplateResult.setCSPTrustedTypesPolicy({
6868
createHTML: (_html: string) => {
6969
policyCalled = true
7070
return rewrittenFragment

test/trusted-types.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import {expect} from 'chai'
2-
import {setCSPTrustedTypesPolicy} from '../lib/index.js'
3-
import {getCSPTrustedTypesPolicy} from '../lib/trusted-types.js'
2+
import {TemplateResult} from '../lib/index.js'
43

54
describe('trusted types', () => {
65
after(() => {
7-
setCSPTrustedTypesPolicy(null)
6+
TemplateResult.setCSPTrustedTypesPolicy(null)
87
})
98

109
it('can set a CSP Trusted Types policy', () => {
@@ -13,8 +12,8 @@ describe('trusted types', () => {
1312
return htmlText
1413
}
1514
}
16-
expect(getCSPTrustedTypesPolicy()).to.equal(null)
17-
setCSPTrustedTypesPolicy(dummyPolicy)
18-
expect(getCSPTrustedTypesPolicy()).to.equal(dummyPolicy)
15+
expect(TemplateResult.cspTrustedTypesPolicy).to.equal(null)
16+
TemplateResult.setCSPTrustedTypesPolicy(dummyPolicy)
17+
expect(TemplateResult.cspTrustedTypesPolicy).to.equal(dummyPolicy)
1918
})
2019
})

test/unsafe-html.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import {expect} from 'chai'
2-
import {html, render, setCSPTrustedTypesPolicy, unsafeHTML} from '../lib/index.js'
2+
import {html, render, TemplateResult, unsafeHTML} from '../lib/index.js'
33

44
describe('unsafeHTML', () => {
55
beforeEach(() => {
6-
setCSPTrustedTypesPolicy(null)
6+
TemplateResult.setCSPTrustedTypesPolicy(null)
77
})
88
afterEach(() => {
9-
setCSPTrustedTypesPolicy(null)
9+
TemplateResult.setCSPTrustedTypesPolicy(null)
1010
})
1111
it('renders basic text', async () => {
1212
const surface = document.createElement('section')
@@ -40,7 +40,7 @@ describe('unsafeHTML', () => {
4040
it('respects trusted types', async () => {
4141
let policyCalled = false
4242
const rewrittenFragment = '<div id="bar">This has been rewritten by Trusted Types.</div>'
43-
setCSPTrustedTypesPolicy({
43+
TemplateResult.setCSPTrustedTypesPolicy({
4444
createHTML: (_html: string) => {
4545
policyCalled = true
4646
return rewrittenFragment

0 commit comments

Comments
 (0)