1
0
Fork 0

fix(react-components): Avoid use of dangerouslySetInnerHTML in Defs

This commit is contained in:
joostdecock 2023-06-08 20:29:52 +02:00
parent 159d4e4066
commit 50f7df93bb
4 changed files with 172 additions and 38 deletions

View file

@ -134,6 +134,8 @@ plugintest:
'@freesewing/plugin-svgattr': *freesewing
'@freesewing/plugin-theme': *freesewing
react-components:
_:
html-react-parser: "^4.0.0"
peer:
react: '>=14'
rehype-jargon:

View file

@ -39,7 +39,9 @@
"peerDependencies": {
"react": ">=14"
},
"dependencies": {},
"dependencies": {
"html-react-parser": "^4.0.0"
},
"devDependencies": {},
"files": [
"dist/*",

View file

@ -1,29 +1,110 @@
// eslint-disable-next-line no-unused-vars
import React from 'react'
import sanitize from 'html-react-parser'
const style = ` style="fill: none; stroke: currentColor;" `
const grids = {
imperial: `<pattern id="grid" height="25.4" width="25.4" patternUnits="userSpaceOnUse" key="grid"><path class="gridline lg imperial" d="M 0 0 L 0 25.4 L 25.4 25.4" ${style} /><path class="gridline lg imperial" d="M 12.7 0 L 12.7 25.4 M 0 12.7 L 25.4 12.7" ${style} /><path class="gridline sm imperial" d="M 3.175 0 L 3.175 25.4 M 6.32 0 L 6.35 25.4 M 9.525 0 L 9.525 25.4 M 15.875 0 L 15.875 25.4 M 19.05 0 L 19.05 25.4 M 22.225 0 L 22.225 25.4" ${style} /><path class="gridline sm imperial" d="M 0 3.175 L 25.4 3.175 M 0 6.32 L 25.4 6.35 M 0 9.525 L 25.4 9.525 M 0 15.875 L 25.4 15.875 M 0 19.05 L 25.4 19.05 M 0 22.225 L 25.4 22.225" ${style} /></pattern>`,
metric: `<pattern id="grid" height="100" width="100" patternUnits="userSpaceOnUse" key="grid"><path class="gridline lg metric" d="M 0 0 L 0 100 L 100 100" ${style} /><path class="gridline metric" d="M 50 0 L 50 100 M 0 50 L 100 50" ${style} /><path class="gridline sm metric" d="M 10 0 L 10 100 M 20 0 L 20 100 M 30 0 L 30 100 M 40 0 L 40 100 M 60 0 L 60 100 M 70 0 L 70 100 M 80 0 L 80 100 M 90 0 L 90 100" ${style} /><path class="gridline sm metric" d="M 0 10 L 100 10 M 0 20 L 100 20 M 0 30 L 100 30 M 0 40 L 100 40 M 0 60 L 100 60 M 0 70 L 100 70 M 0 80 L 100 80 M 0 90 L 100 90" ${style} /><path class="gridline xs metric" d="M 5 0 L 5 100 M 15 0 L 15 100 M 25 0 L 25 100 M 35 0 L 35 100 M 45 0 L 45 100 M 55 0 L 55 100 M 65 0 L 65 100 M 75 0 L 75 100 M 85 0 L 85 100 M 95 0 L 95 100" ${style} /><path class="gridline xs metric" d="M 0 5 L 100 5 M 0 15 L 100 15 M 0 25 L 100 25 M 0 35 L 100 35 M 0 45 L 100 45 M 0 55 L 100 55 M 0 65 L 100 65 M 0 75 L 100 75 M 0 85 L 100 85 M 0 95 L 100 95" ${style} /></pattern>`,
}
const style = { fill: 'none', stroke: 'currentColor' }
export const Defs = (props) => {
const StackDefs = ({ stacks }) =>
Object.keys(stacks).map((stackName) => {
const part = stacks[stackName].parts[0]
let anchor = { x: 0, y: 0 }
if (typeof part.points.gridAnchor !== 'undefined') anchor = part.points.gridAnchor
else if (typeof part.points.anchor !== 'undefined') anchor = part.points.anchor
if (isNaN(anchor.x)) anchor.x = 0
if (isNaN(anchor.y)) anchor.y = 0
return (
<pattern
id={`grid-${stackName}`}
key={`grid-${stackName}`}
xlinkHref="#grid"
x={anchor.x}
y={anchor.y}
/>
)
})
const MetricPaperlessDefs = ({ stacks }) => (
<>
<pattern id="grid" height="100" width="100" patternUnits="userSpaceOnUse" key="grid">
<path style={style} className="gridline lg metric" d="M 0 0 L 0 100 L 100 100" />
<path style={style} className="gridline metric" d="M 50 0 L 50 100 M 0 50 L 100 50" />
<path
style={style}
className="gridline sm metric"
d="M 10 0 L 10 100 M 20 0 L 20 100 M 30 0 L 30 100 M 40 0 L 40 100 M 60 0 L 60 100 M 70 0 L 70 100 M 80 0 L 80 100 M 90 0 L 90 100"
/>
<path
style={style}
className="gridline sm metric"
d="M 0 10 L 100 10 M 0 20 L 100 20 M 0 30 L 100 30 M 0 40 L 100 40 M 0 60 L 100 60 M 0 70 L 100 70 M 0 80 L 100 80 M 0 90 L 100 90"
/>
<path
style={style}
className="gridline xs metric"
d="M 5 0 L 5 100 M 15 0 L 15 100 M 25 0 L 25 100 M 35 0 L 35 100 M 45 0 L 45 100 M 55 0 L 55 100 M 65 0 L 65 100 M 75 0 L 75 100 M 85 0 L 85 100 M 95 0 L 95 100"
/>
<path
style={style}
className="gridline xs metric"
d="M 0 5 L 100 5 M 0 15 L 100 15 M 0 25 L 100 25 M 0 35 L 100 35 M 0 45 L 100 45 M 0 55 L 100 55 M 0 65 L 100 65 M 0 75 L 100 75 M 0 85 L 100 85 M 0 95 L 100 95"
/>
</pattern>
<StackDefs stacks={stacks} />
</>
)
const ImperialPaperlessDefs = ({ stacks }) => (
<>
<pattern id="grid" height="25.4" width="25.4" patternUnits="userSpaceOnUse" key="grid">
<path style={style} className="gridline lg imperial" d="M 0 0 L 0 25.4 L 25.4 25.4" />
<path
style={style}
className="gridline lg imperial"
d="M 12.7 0 L 12.7 25.4 M 0 12.7 L 25.4 12.7"
/>
<path
style={style}
className="gridline sm imperial"
d="M 3.175 0 L 3.175 25.4 M 6.32 0 L 6.35 25.4 M 9.525 0 L 9.525 25.4 M 15.875 0 L 15.875 25.4 M 19.05 0 L 19.05 25.4 M 22.225 0 L 22.225 25.4"
/>
<path
style={style}
className="gridline sm imperial"
d="M 0 3.175 L 25.4 3.175 M 0 6.32 L 25.4 6.35 M 0 9.525 L 25.4 9.525 M 0 15.875 L 25.4 15.875 M 0 19.05 L 25.4 19.05 M 0 22.225 L 25.4 22.225"
/>
</pattern>
<StackDefs stacks={stacks} />
</>
)
const PaperlessDefs = ({ units = 'metric', stacks }) =>
units === 'imperial' ? (
<ImperialPaperlessDefs stacks={stacks} />
) : (
<MetricPaperlessDefs stacks={stacks} />
)
export const _Defs = (props) => {
if (!props.svg) return null
let defs = props.svg.defs.forSvg
if (props.settings[0].paperless) {
defs += grids[props.settings[0].units || 'metric']
for (let stack in props.stacks) {
const part = props.stacks[stack].parts[0]
let anchor = { x: 0, y: 0 }
if (typeof part.points.gridAnchor !== 'undefined') anchor = part.points.gridAnchor
else if (typeof part.points.anchor !== 'undefined') anchor = part.points.anchor
if (isNaN(anchor.x)) anchor.x = 0
if (isNaN(anchor.y)) anchor.y = 0
defs += `<pattern id="grid-${stack}" key="grid-${stack}" xlink:href="#grid" x="${anchor.x}" y="${anchor.y}" />`
}
}
return <defs dangerouslySetInnerHTML={{ __html: defs }} />
return (
<>
{props.svg.defs.forSvg ? sanitize(props.svg.defs.forSvg) : null}
{props.settings[0].paperless ? (
<PaperlessDefs units={props.settings[0]?.units} stacks={props.stacks} />
) : null}
</>
)
}
export const Defs = (props) =>
props.svg ? (
<defs>
{props.svg.defs.forSvg ? sanitize(props.svg.defs.forSvg) : null}
{props.settings[0].paperless ? (
<PaperlessDefs units={props.settings[0]?.units} stacks={props.stacks} />
) : null}
</defs>
) : null

View file

@ -7689,6 +7689,13 @@ domhandler@2.3:
dependencies:
domelementtype "1"
domhandler@5.0.3, domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
dependencies:
domelementtype "^2.3.0"
domhandler@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-3.3.0.tgz#6db7ea46e4617eb15cf875df68b2b8524ce0037a"
@ -7703,13 +7710,6 @@ domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.2.2:
dependencies:
domelementtype "^2.2.0"
domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
dependencies:
domelementtype "^2.3.0"
dompurify@2.4.5:
version "2.4.5"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.5.tgz#0e89a27601f0bad978f9a924e7a05d5d2cccdd87"
@ -7741,6 +7741,15 @@ domutils@^3.0.1:
domelementtype "^2.3.0"
domhandler "^5.0.1"
domutils@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e"
integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==
dependencies:
dom-serializer "^2.0.0"
domelementtype "^2.3.0"
domhandler "^5.0.3"
dot-prop@6.0.1, dot-prop@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083"
@ -7992,7 +8001,7 @@ entities@^3.0.1:
resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4"
integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==
entities@^4.2.0, entities@^4.4.0:
entities@^4.2.0, entities@^4.4.0, entities@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
@ -10284,6 +10293,14 @@ html-crush@^4.0.0, html-crush@^4.2.0:
string-range-expander "^2.1.0"
test-mixer "^2.1.0"
html-dom-parser@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/html-dom-parser/-/html-dom-parser-4.0.0.tgz#dc382fbbc9306f8c9b5aae4e3f2822e113a48709"
integrity sha512-TUa3wIwi80f5NF8CVWzkopBVqVAtlawUzJoLwVLHns0XSJGynss4jiY0mTWpiDOsuyw+afP+ujjMgRh9CoZcXw==
dependencies:
domhandler "5.0.3"
htmlparser2 "9.0.0"
html-encoding-sniffer@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9"
@ -10303,6 +10320,16 @@ html-parse-stringify@^3.0.1:
dependencies:
void-elements "3.1.0"
html-react-parser@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/html-react-parser/-/html-react-parser-4.0.0.tgz#a727be4539ad85b133a5071f97b8c2f835a55bdf"
integrity sha512-OzlOavs9lLyBxoRiXbXfODIX/nSShukMtdx3+WSMjon/FF1gJZRq0rBELoR5OswfbN56C0oKpAii7i3yzO/uVQ==
dependencies:
domhandler "5.0.3"
html-dom-parser "4.0.0"
react-property "2.0.0"
style-to-js "1.1.3"
html-to-text@^9.0.5:
version "9.0.5"
resolved "https://registry.yarnpkg.com/html-to-text/-/html-to-text-9.0.5.tgz#6149a0f618ae7a0db8085dca9bbf96d32bb8368d"
@ -10335,6 +10362,16 @@ htmlparser2@3.8.x:
entities "1.0"
readable-stream "1.1"
htmlparser2@9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-9.0.0.tgz#e431142b7eeb1d91672742dea48af8ac7140cddb"
integrity sha512-uxbSI98wmFT/G4P2zXx4OVx04qWUmyFPrD2/CNepa2Zo3GPNaCaaxElDgwUrwYWkK1nr9fft0Ya8dws8coDLLQ==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.3"
domutils "^3.1.0"
entities "^4.5.0"
htmlparser2@^5.0.0, htmlparser2@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-5.0.1.tgz#7daa6fc3e35d6107ac95a4fc08781f091664f6e7"
@ -16445,6 +16482,11 @@ react-markdown@8.0.7:
unist-util-visit "^4.0.0"
vfile "^5.0.0"
react-property@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/react-property/-/react-property-2.0.0.tgz#2156ba9d85fa4741faf1918b38efc1eae3c6a136"
integrity sha512-kzmNjIgU32mO4mmH5+iUyrqlpFQhF8K2k7eZ4fdLSOPFrD1XgEuSBv9LDEgxRXTMBqMd8ppT0x6TIzqE5pdGdw==
react-refractor@^2.1.6, react-refractor@^2.1.7:
version "2.1.7"
resolved "https://registry.yarnpkg.com/react-refractor/-/react-refractor-2.1.7.tgz#a7752bb774abed2735e37945aa211a1e1059b976"
@ -18863,6 +18905,20 @@ style-mod@^4.0.0:
resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.0.3.tgz#136c4abc905f82a866a18b39df4dc08ec762b1ad"
integrity sha512-78Jv8kYJdjbvRwwijtCevYADfsI0lGzYJe4mMFdceO8l75DFFDoqBhR1jVDicDRRaX4//g1u9wKeo+ztc2h1Rw==
style-to-js@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/style-to-js/-/style-to-js-1.1.3.tgz#2012d75dc89bf400edc29c545ed61c8626b00184"
integrity sha512-zKI5gN/zb7LS/Vm0eUwjmjrXWw8IMtyA8aPBJZdYiQTXj4+wQ3IucOLIOnF7zCHxvW8UhIGh/uZh/t9zEHXNTQ==
dependencies:
style-to-object "0.4.1"
style-to-object@0.4.1, style-to-object@^0.4.0, style-to-object@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.1.tgz#53cf856f7cf7f172d72939d9679556469ba5de37"
integrity sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw==
dependencies:
inline-style-parser "0.1.1"
style-to-object@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46"
@ -18870,13 +18926,6 @@ style-to-object@^0.3.0:
dependencies:
inline-style-parser "0.1.1"
style-to-object@^0.4.0, style-to-object@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.1.tgz#53cf856f7cf7f172d72939d9679556469ba5de37"
integrity sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw==
dependencies:
inline-style-parser "0.1.1"
styled-components@5.3.10:
version "5.3.10"
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.10.tgz#42f7245f58fe960362a63f543dda23c0ac107c0f"