2
0
mirror of https://github.com/iconify/iconify.git synced 2024-11-08 06:15:24 +00:00

feat: support require-trusted-types-for policy

This commit is contained in:
Vjacheslav Trushkin 2023-06-22 11:50:27 +03:00
parent 7bec9456c8
commit 39868cf79c
16 changed files with 85 additions and 25 deletions

View File

@ -1,13 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<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>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
<head>
<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" />
<meta
http-equiv="Content-Security-Policy"
content="require-trusted-types-for 'script';"
/>
<title>React Demo</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

View File

@ -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/",

View File

@ -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(
item.body,
id ? () => id + 'ID' + localCounter++ : 'iconifyReact'
__html: cleanUpInnerHTML(
replaceIDs(
item.body,
id ? () => id + 'ID' + localCounter++ : 'iconifyReact'
)
),
};
return React.createElement('svg', componentProps);

View File

@ -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:

View File

@ -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,

View File

@ -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",

View File

@ -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;

View File

@ -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:

View File

@ -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,

View File

@ -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",

View File

@ -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;
}

View File

@ -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/",

View File

@ -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/",

View File

@ -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",

View File

@ -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';

View 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;
}