]>
git.proxmox.com Git - proxmox-widget-toolkit.git/blob - src/Parser.js
1 // NOTE: just relays parsing to markedjs parser
2 Ext
.define('Proxmox.Markdown', {
3 alternateClassName
: 'Px.Markdown', // just trying out something, do NOT copy this line
6 // transforms HTML to a DOM tree and recursively descends and HTML-encodes every branch with a
7 // "bad" node.type and drops "bad" attributes from the remaining nodes.
8 // "bad" means anything which can do XSS or break the layout of the outer page
9 sanitizeHTML: function(input
) {
13 let _isHTTPLike
= value
=> value
.match(/^\s*https?:/i); // URL's protocol ends with :
15 _sanitize
= (node
) => {
16 if (node
.nodeType
=== 3) return;
17 if (node
.nodeType
!== 1 ||
18 /^(script|style|form|select|option|optgroup|map|area|canvas|textarea|applet|font|iframe|audio|video|object|embed|svg)$/i.test(node
.tagName
)
20 // could do node.remove() instead, but it's nicer UX if we keep the (encoded!) html
21 node
.outerHTML
= Ext
.String
.htmlEncode(node
.outerHTML
);
24 for (let i
=node
.attributes
.length
; i
--;) {
25 const name
= node
.attributes
[i
].name
;
26 const value
= node
.attributes
[i
].value
;
27 // TODO: we may want to also disallow class and id attrs
29 !/^(class|id|name|href|src|alt|align|valign|disabled|checked|start|type)$/i.test(name
)
31 node
.attributes
.removeNamedItem(name
);
32 } else if ((name
=== 'href' || name
=== 'src') && !_isHTTPLike(value
)) {
34 let url
= new URL(value
, window
.location
.origin
);
35 if (_isHTTPLike(url
.protocol
) || (node
.tagName
=== 'img' && url
.protocol
=== 'data:')) {
36 node
.attributes
[i
].value
= url
.href
;
38 node
.attributes
.removeNamedItem(name
);
41 node
.attributes
[i
].removeNamedItem(name
);
45 for (let i
=node
.childNodes
.length
; i
--;) _sanitize(node
.childNodes
[i
]);
48 const doc
= new DOMParser().parseFromString(`<!DOCTYPE html><html><body>${input}`, 'text/html');
53 return doc
.body
.innerHTML
;
56 parse: function(markdown
) {
58 let unsafeHTML
= marked(markdown
);
60 return `<div class="pmx-md">${this.sanitizeHTML(unsafeHTML)}</div>`;