|
|
|
@ -106,11 +106,29 @@ img.ProseMirror-separator {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`)
|
|
|
|
`)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const DROP_ATTRS = [
|
|
|
|
|
|
|
|
'srcdoc', 'xlink:href', 'srcset', 'action', 'formaction', 'poster',
|
|
|
|
|
|
|
|
'background', 'data', 'cite', 'ping', 'longdesc', 'manifest', 'profile'
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const SAFE_URL_REGEXP = /^(?:https?:\/\/|data:image\/|blob:|mailto:|tel:|\{)/i
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function isSafeAttr (name, value) {
|
|
|
|
|
|
|
|
const lowerName = name.toLowerCase()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (lowerName.startsWith('on') || DROP_ATTRS.includes(lowerName)) return false
|
|
|
|
|
|
|
|
if ((lowerName === 'href' || lowerName === 'src') && !SAFE_URL_REGEXP.test(value.trim())) return false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function collectDomAttrs (dom) {
|
|
|
|
function collectDomAttrs (dom) {
|
|
|
|
const attrs = {}
|
|
|
|
const attrs = {}
|
|
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < dom.attributes.length; i++) {
|
|
|
|
for (let i = 0; i < dom.attributes.length; i++) {
|
|
|
|
attrs[dom.attributes[i].name] = dom.attributes[i].value
|
|
|
|
const { name, value } = dom.attributes[i]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (isSafeAttr(name, value)) attrs[name] = value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return { htmlAttrs: attrs }
|
|
|
|
return { htmlAttrs: attrs }
|
|
|
|
|