mirror of
https://github.com/iconify/iconify.git
synced 2024-11-08 14:20:57 +00:00
feat: support require-trusted-types-for policy
This commit is contained in:
parent
7bec9456c8
commit
39868cf79c
@ -4,7 +4,11 @@
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite App</title>
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="require-trusted-types-for 'script';"
|
||||
/>
|
||||
<title>React Demo</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
@ -2,7 +2,7 @@
|
||||
"name": "@iconify/react",
|
||||
"description": "Iconify icon component for React.",
|
||||
"author": "Vjacheslav Trushkin",
|
||||
"version": "4.1.0",
|
||||
"version": "4.1.1",
|
||||
"license": "MIT",
|
||||
"bugs": "https://github.com/iconify/iconify/issues",
|
||||
"homepage": "https://iconify.design/",
|
||||
|
@ -8,6 +8,7 @@ import { iconToSVG } from '@iconify/utils/lib/svg/build';
|
||||
import { replaceIDs } from '@iconify/utils/lib/svg/id';
|
||||
import { iconToHTML } from '@iconify/utils/lib/svg/html';
|
||||
import { svgToURL } from '@iconify/utils/lib/svg/url';
|
||||
import { cleanUpInnerHTML } from '@iconify/utils/lib/svg/inner-html';
|
||||
import type {
|
||||
IconifyIconCustomisations,
|
||||
IconifyRenderMode,
|
||||
@ -48,7 +49,7 @@ const propsToAdd: Record<string, string> = {
|
||||
Size: '100% 100%',
|
||||
};
|
||||
const propsToAddTo: Record<string, Record<string, string>> = {
|
||||
webkitMask: monotoneProps,
|
||||
WebkitMask: monotoneProps,
|
||||
mask: monotoneProps,
|
||||
background: coloredProps,
|
||||
};
|
||||
@ -202,9 +203,11 @@ export const render = (
|
||||
|
||||
// Add icon stuff
|
||||
componentProps.dangerouslySetInnerHTML = {
|
||||
__html: replaceIDs(
|
||||
__html: cleanUpInnerHTML(
|
||||
replaceIDs(
|
||||
item.body,
|
||||
id ? () => id + 'ID' + localCounter++ : 'iconifyReact'
|
||||
)
|
||||
),
|
||||
};
|
||||
return React.createElement('svg', componentProps);
|
||||
|
@ -21,13 +21,13 @@ Iconify SVG framework is designed to be as easy to use as possible.
|
||||
Add this line to your page to load Iconify SVG framework (you can add it to `<head>` section of the page or before `</body>`):
|
||||
|
||||
```html
|
||||
<script src="https://code.iconify.design/3/3.1.0/iconify.min.js"></script>
|
||||
<script src="https://code.iconify.design/3/3.1.1/iconify.min.js"></script>
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/@iconify/iconify@3.1.0/dist/iconify.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@iconify/iconify@3.1.1/dist/iconify.min.js"></script>
|
||||
```
|
||||
|
||||
or, if you are building a project with something like WebPack or Rollup, you can include the script by installing `@iconify/iconify` as a dependency and importing it in your project:
|
||||
|
@ -3,6 +3,10 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="require-trusted-types-for 'script';"
|
||||
/>
|
||||
<title>Iconify Demo: Usage</title>
|
||||
<style>
|
||||
html,
|
||||
|
@ -2,7 +2,7 @@
|
||||
"name": "@iconify/iconify",
|
||||
"description": "Unified SVG framework with over 100,000 icons to choose from",
|
||||
"author": "Vjacheslav Trushkin <cyberalien@gmail.com> (https://iconify.design)",
|
||||
"version": "3.1.0",
|
||||
"version": "3.1.1",
|
||||
"license": "MIT",
|
||||
"main": "./dist/iconify.min.js",
|
||||
"types": "./dist/iconify.d.ts",
|
||||
|
@ -2,6 +2,7 @@ import type { IconifyIcon } from '@iconify/utils/lib/icon/defaults';
|
||||
import { iconToSVG } from '@iconify/utils/lib/svg/build';
|
||||
import { replaceIDs } from '@iconify/utils/lib/svg/id';
|
||||
import { iconToHTML } from '@iconify/utils/lib/svg/html';
|
||||
import { cleanUpInnerHTML } from '@iconify/utils/lib/svg/inner-html';
|
||||
import {
|
||||
elementDataProperty,
|
||||
IconifyElement,
|
||||
@ -40,7 +41,7 @@ export function renderInlineSVG(
|
||||
'role': 'img',
|
||||
...renderData.attributes,
|
||||
});
|
||||
span.innerHTML = html;
|
||||
span.innerHTML = cleanUpInnerHTML(html);
|
||||
|
||||
// Get SVG element
|
||||
const svg = span.childNodes[0] as IconifyElement;
|
||||
|
@ -20,13 +20,13 @@ Iconify Icon web component renders icons.
|
||||
Add this line to your page to load IconifyIcon (you can add it to `<head>` section of the page or before `</body>`):
|
||||
|
||||
```html
|
||||
<script src="https://code.iconify.design/iconify-icon/1.0.7/iconify-icon.min.js"></script>
|
||||
<script src="https://code.iconify.design/iconify-icon/1.0.8/iconify-icon.min.js"></script>
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/iconify-icon@1.0.7/dist/iconify-icon.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/iconify-icon@1.0.8/dist/iconify-icon.min.js"></script>
|
||||
```
|
||||
|
||||
or, if you are building a project with a bundler, you can include the script by installing `iconify-icon` as a dependency and importing it in your project:
|
||||
|
@ -3,6 +3,10 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="require-trusted-types-for 'script';"
|
||||
/>
|
||||
<title>Iconify Icon Demo: Usage</title>
|
||||
<style>
|
||||
html,
|
||||
|
@ -2,7 +2,7 @@
|
||||
"name": "iconify-icon",
|
||||
"description": "Icon web component that loads icon data on demand. Over 150,000 icons to choose from",
|
||||
"author": "Vjacheslav Trushkin <cyberalien@gmail.com> (https://iconify.design)",
|
||||
"version": "1.0.7",
|
||||
"version": "1.0.8",
|
||||
"license": "MIT",
|
||||
"main": "./dist/iconify-icon.cjs",
|
||||
"types": "./dist/iconify-icon.d.ts",
|
||||
|
@ -1,5 +1,6 @@
|
||||
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';
|
||||
import { iconToHTML } from '@iconify/utils/lib/svg/html';
|
||||
import { cleanUpInnerHTML } from '@iconify/utils/lib/svg/inner-html';
|
||||
|
||||
/**
|
||||
* Render node as <svg>
|
||||
@ -21,6 +22,7 @@ export function renderSVG(data: IconifyIconBuildResult): Element {
|
||||
}
|
||||
|
||||
// Generate SVG
|
||||
node.innerHTML = iconToHTML(data.body, attr);
|
||||
const html = iconToHTML(data.body, attr);
|
||||
node.innerHTML = cleanUpInnerHTML(html);
|
||||
return node.firstChild as HTMLElement;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
"name": "@iconify-icon/react",
|
||||
"description": "React wrapper for Iconify Icon web component",
|
||||
"author": "Vjacheslav Trushkin",
|
||||
"version": "1.0.7",
|
||||
"version": "1.0.8",
|
||||
"license": "MIT",
|
||||
"bugs": "https://github.com/iconify/iconify/issues",
|
||||
"homepage": "https://iconify.design/",
|
||||
|
@ -3,7 +3,7 @@
|
||||
"type": "module",
|
||||
"description": "SolidJS wrapper for Iconify Icon web component",
|
||||
"author": "Vjacheslav Trushkin",
|
||||
"version": "1.0.7",
|
||||
"version": "1.0.8",
|
||||
"license": "MIT",
|
||||
"bugs": "https://github.com/iconify/iconify/issues",
|
||||
"homepage": "https://iconify.design/",
|
||||
|
@ -352,6 +352,11 @@
|
||||
"import": "./lib/svg/id.mjs",
|
||||
"types": "./lib/svg/id.d.ts"
|
||||
},
|
||||
"./lib/svg/inner-html": {
|
||||
"require": "./lib/svg/inner-html.cjs",
|
||||
"import": "./lib/svg/inner-html.mjs",
|
||||
"types": "./lib/svg/inner-html.d.ts"
|
||||
},
|
||||
"./lib/svg/size": {
|
||||
"require": "./lib/svg/size.cjs",
|
||||
"import": "./lib/svg/size.mjs",
|
||||
|
@ -59,6 +59,7 @@ export { encodeSvgForCss } from './svg/encode-svg-for-css';
|
||||
export { trimSVG } from './svg/trim';
|
||||
export { iconToHTML } from './svg/html';
|
||||
export { svgToURL, svgToData } from './svg/url';
|
||||
export { cleanUpInnerHTML } from './svg/inner-html';
|
||||
|
||||
// Colors
|
||||
export { colorKeywords } from './colors/keywords';
|
||||
|
36
packages/utils/src/svg/inner-html.ts
Normal file
36
packages/utils/src/svg/inner-html.ts
Normal file
@ -0,0 +1,36 @@
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-nocheck
|
||||
interface Policy {
|
||||
createHTML: (s: string) => string;
|
||||
}
|
||||
|
||||
let policy: undefined | null | Policy;
|
||||
|
||||
/**
|
||||
* Attempt to create policy
|
||||
*/
|
||||
function createPolicy() {
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
||||
policy = window.trustedTypes.createPolicy('iconify', {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
createHTML: (s) => s,
|
||||
}) as Policy;
|
||||
} catch (err) {
|
||||
policy = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up value for innerHTML assignment
|
||||
*
|
||||
* This code doesn't actually clean up anything.
|
||||
* It is intended be used with Iconify icon data, which has already been validated
|
||||
*/
|
||||
export function cleanUpInnerHTML(html: string): string {
|
||||
if (policy === undefined) {
|
||||
createPolicy();
|
||||
}
|
||||
|
||||
return policy ? (policy.createHTML(html) as unknown as string) : html;
|
||||
}
|
Loading…
Reference in New Issue
Block a user