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" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<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>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"name": "@iconify/react",
|
"name": "@iconify/react",
|
||||||
"description": "Iconify icon component for React.",
|
"description": "Iconify icon component for React.",
|
||||||
"author": "Vjacheslav Trushkin",
|
"author": "Vjacheslav Trushkin",
|
||||||
"version": "4.1.0",
|
"version": "4.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": "https://github.com/iconify/iconify/issues",
|
"bugs": "https://github.com/iconify/iconify/issues",
|
||||||
"homepage": "https://iconify.design/",
|
"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 { replaceIDs } from '@iconify/utils/lib/svg/id';
|
||||||
import { iconToHTML } from '@iconify/utils/lib/svg/html';
|
import { iconToHTML } from '@iconify/utils/lib/svg/html';
|
||||||
import { svgToURL } from '@iconify/utils/lib/svg/url';
|
import { svgToURL } from '@iconify/utils/lib/svg/url';
|
||||||
|
import { cleanUpInnerHTML } from '@iconify/utils/lib/svg/inner-html';
|
||||||
import type {
|
import type {
|
||||||
IconifyIconCustomisations,
|
IconifyIconCustomisations,
|
||||||
IconifyRenderMode,
|
IconifyRenderMode,
|
||||||
@ -48,7 +49,7 @@ const propsToAdd: Record<string, string> = {
|
|||||||
Size: '100% 100%',
|
Size: '100% 100%',
|
||||||
};
|
};
|
||||||
const propsToAddTo: Record<string, Record<string, string>> = {
|
const propsToAddTo: Record<string, Record<string, string>> = {
|
||||||
webkitMask: monotoneProps,
|
WebkitMask: monotoneProps,
|
||||||
mask: monotoneProps,
|
mask: monotoneProps,
|
||||||
background: coloredProps,
|
background: coloredProps,
|
||||||
};
|
};
|
||||||
@ -202,9 +203,11 @@ export const render = (
|
|||||||
|
|
||||||
// Add icon stuff
|
// Add icon stuff
|
||||||
componentProps.dangerouslySetInnerHTML = {
|
componentProps.dangerouslySetInnerHTML = {
|
||||||
__html: replaceIDs(
|
__html: cleanUpInnerHTML(
|
||||||
|
replaceIDs(
|
||||||
item.body,
|
item.body,
|
||||||
id ? () => id + 'ID' + localCounter++ : 'iconifyReact'
|
id ? () => id + 'ID' + localCounter++ : 'iconifyReact'
|
||||||
|
)
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
return React.createElement('svg', componentProps);
|
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>`):
|
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
|
```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
|
or
|
||||||
|
|
||||||
```html
|
```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:
|
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>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<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>
|
<title>Iconify Demo: Usage</title>
|
||||||
<style>
|
<style>
|
||||||
html,
|
html,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"name": "@iconify/iconify",
|
"name": "@iconify/iconify",
|
||||||
"description": "Unified SVG framework with over 100,000 icons to choose from",
|
"description": "Unified SVG framework with over 100,000 icons to choose from",
|
||||||
"author": "Vjacheslav Trushkin <cyberalien@gmail.com> (https://iconify.design)",
|
"author": "Vjacheslav Trushkin <cyberalien@gmail.com> (https://iconify.design)",
|
||||||
"version": "3.1.0",
|
"version": "3.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/iconify.min.js",
|
"main": "./dist/iconify.min.js",
|
||||||
"types": "./dist/iconify.d.ts",
|
"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 { iconToSVG } from '@iconify/utils/lib/svg/build';
|
||||||
import { replaceIDs } from '@iconify/utils/lib/svg/id';
|
import { replaceIDs } from '@iconify/utils/lib/svg/id';
|
||||||
import { iconToHTML } from '@iconify/utils/lib/svg/html';
|
import { iconToHTML } from '@iconify/utils/lib/svg/html';
|
||||||
|
import { cleanUpInnerHTML } from '@iconify/utils/lib/svg/inner-html';
|
||||||
import {
|
import {
|
||||||
elementDataProperty,
|
elementDataProperty,
|
||||||
IconifyElement,
|
IconifyElement,
|
||||||
@ -40,7 +41,7 @@ export function renderInlineSVG(
|
|||||||
'role': 'img',
|
'role': 'img',
|
||||||
...renderData.attributes,
|
...renderData.attributes,
|
||||||
});
|
});
|
||||||
span.innerHTML = html;
|
span.innerHTML = cleanUpInnerHTML(html);
|
||||||
|
|
||||||
// Get SVG element
|
// Get SVG element
|
||||||
const svg = span.childNodes[0] as IconifyElement;
|
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>`):
|
Add this line to your page to load IconifyIcon (you can add it to `<head>` section of the page or before `</body>`):
|
||||||
|
|
||||||
```html
|
```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
|
or
|
||||||
|
|
||||||
```html
|
```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:
|
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>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<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>
|
<title>Iconify Icon Demo: Usage</title>
|
||||||
<style>
|
<style>
|
||||||
html,
|
html,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"name": "iconify-icon",
|
"name": "iconify-icon",
|
||||||
"description": "Icon web component that loads icon data on demand. Over 150,000 icons to choose from",
|
"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)",
|
"author": "Vjacheslav Trushkin <cyberalien@gmail.com> (https://iconify.design)",
|
||||||
"version": "1.0.7",
|
"version": "1.0.8",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/iconify-icon.cjs",
|
"main": "./dist/iconify-icon.cjs",
|
||||||
"types": "./dist/iconify-icon.d.ts",
|
"types": "./dist/iconify-icon.d.ts",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';
|
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';
|
||||||
import { iconToHTML } from '@iconify/utils/lib/svg/html';
|
import { iconToHTML } from '@iconify/utils/lib/svg/html';
|
||||||
|
import { cleanUpInnerHTML } from '@iconify/utils/lib/svg/inner-html';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render node as <svg>
|
* Render node as <svg>
|
||||||
@ -21,6 +22,7 @@ export function renderSVG(data: IconifyIconBuildResult): Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate SVG
|
// Generate SVG
|
||||||
node.innerHTML = iconToHTML(data.body, attr);
|
const html = iconToHTML(data.body, attr);
|
||||||
|
node.innerHTML = cleanUpInnerHTML(html);
|
||||||
return node.firstChild as HTMLElement;
|
return node.firstChild as HTMLElement;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"name": "@iconify-icon/react",
|
"name": "@iconify-icon/react",
|
||||||
"description": "React wrapper for Iconify Icon web component",
|
"description": "React wrapper for Iconify Icon web component",
|
||||||
"author": "Vjacheslav Trushkin",
|
"author": "Vjacheslav Trushkin",
|
||||||
"version": "1.0.7",
|
"version": "1.0.8",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": "https://github.com/iconify/iconify/issues",
|
"bugs": "https://github.com/iconify/iconify/issues",
|
||||||
"homepage": "https://iconify.design/",
|
"homepage": "https://iconify.design/",
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "SolidJS wrapper for Iconify Icon web component",
|
"description": "SolidJS wrapper for Iconify Icon web component",
|
||||||
"author": "Vjacheslav Trushkin",
|
"author": "Vjacheslav Trushkin",
|
||||||
"version": "1.0.7",
|
"version": "1.0.8",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": "https://github.com/iconify/iconify/issues",
|
"bugs": "https://github.com/iconify/iconify/issues",
|
||||||
"homepage": "https://iconify.design/",
|
"homepage": "https://iconify.design/",
|
||||||
|
@ -352,6 +352,11 @@
|
|||||||
"import": "./lib/svg/id.mjs",
|
"import": "./lib/svg/id.mjs",
|
||||||
"types": "./lib/svg/id.d.ts"
|
"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": {
|
"./lib/svg/size": {
|
||||||
"require": "./lib/svg/size.cjs",
|
"require": "./lib/svg/size.cjs",
|
||||||
"import": "./lib/svg/size.mjs",
|
"import": "./lib/svg/size.mjs",
|
||||||
|
@ -59,6 +59,7 @@ export { encodeSvgForCss } from './svg/encode-svg-for-css';
|
|||||||
export { trimSVG } from './svg/trim';
|
export { trimSVG } from './svg/trim';
|
||||||
export { iconToHTML } from './svg/html';
|
export { iconToHTML } from './svg/html';
|
||||||
export { svgToURL, svgToData } from './svg/url';
|
export { svgToURL, svgToData } from './svg/url';
|
||||||
|
export { cleanUpInnerHTML } from './svg/inner-html';
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
export { colorKeywords } from './colors/keywords';
|
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