Skip to content

Commit 34de61c

Browse files
committed
feat: temp add unsafe-svg directive till upstream PR merged
1 parent 63b9d83 commit 34de61c

File tree

1 file changed

+63
-0
lines changed
  • packages/uikit-workshop/src/scripts/lit-components/pl-icon

1 file changed

+63
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* @license
3+
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
4+
* This code may only be used under the BSD style license found at
5+
* http://polymer.github.io/LICENSE.txt
6+
* The complete set of authors may be found at
7+
* http://polymer.github.io/AUTHORS.txt
8+
* The complete set of contributors may be found at
9+
* http://polymer.github.io/CONTRIBUTORS.txt
10+
* Code distributed by Google as part of the polymer project is also
11+
* subject to an additional IP rights grant found at
12+
* http://polymer.github.io/PATENTS.txt
13+
*/
14+
15+
import { reparentNodes } from 'lit-html/lib/dom.js';
16+
import { isPrimitive } from 'lit-html/lib/parts.js';
17+
import { directive, NodePart, Part } from 'lit-html/lit-html.js';
18+
19+
interface PreviousValue {
20+
readonly value: unknown;
21+
readonly fragment: DocumentFragment;
22+
}
23+
24+
// For each part, remember the value that was last rendered to the part by the
25+
// unsafeSVG directive, and the DocumentFragment that was last set as a value.
26+
// The DocumentFragment is used as a unique key to check if the last value
27+
// rendered to the part was with unsafeSVG. If not, we'll always re-render the
28+
// value passed to unsafeSVG.
29+
const previousValues = new WeakMap<NodePart, PreviousValue>();
30+
31+
/**
32+
* Renders the result as SVG, rather than text.
33+
*
34+
* Note, this is unsafe to use with any user-provided input that hasn't been
35+
* sanitized or escaped, as it may lead to cross-site-scripting
36+
* vulnerabilities.
37+
*/
38+
export const unsafeSVG = directive((value: unknown) => (part: Part): void => {
39+
if (!(part instanceof NodePart)) {
40+
throw new Error('unsafeSVG can only be used in text bindings');
41+
}
42+
43+
const previousValue = previousValues.get(part);
44+
45+
if (
46+
previousValue !== undefined &&
47+
isPrimitive(value) &&
48+
value === previousValue.value &&
49+
part.value === previousValue.fragment
50+
) {
51+
return;
52+
}
53+
54+
const template = document.createElement('template');
55+
template.innerHTML = `<svg>${value}</svg>`;
56+
const content = template.content;
57+
const svgElement = content.firstElementChild!;
58+
content.removeChild(svgElement);
59+
reparentNodes(content, svgElement.firstChild);
60+
const fragment = document.importNode(content, true);
61+
part.setValue(fragment);
62+
previousValues.set(part, { value, fragment });
63+
});

0 commit comments

Comments
 (0)