changes for interactive plantuml

pull/2754/head
Bharat Rajagopalan 5 years ago
parent 9e257080a2
commit 1f9f708909

@ -32,6 +32,59 @@ module.exports = {
allowedAttrs.push('allow')
}
//Changes to keep interactive plantuml object tag
//only allow specific attributes for plantuml object node
allowedTags.push('object')
allowedAttrs.push('data')
allowedAttrs.push('type')
allowedAttrs.push('style')
allowedAttrs.push('class')
allowedAttrs.push('alt')
DOMPurify.addHook('uponSanitizeElement', (node, data) => {
// keep object node only if it is
// authorised plantuml using the configured plantuml server
// force attribute values to configured params
// insert the plantuml inside the object as text for search
let isPumlNode=false
if (data.tagName === 'object') {
//console.log ("Found object node - validating")
//remove node if it doesn't conform to plantuml structure
if (!( 'data' in node.attributes
&& 'class' in node.attributes
&& 'style' in node.attributes
&& 'type' in node.attributes
&& 'alt' in node.attributes)
) {
//console.log ("Attribute mismatch - removing object node")
return node.parentNode.removeChild(node)
}
dataAttribute = node.getAttribute ('data')
//only allow configured plantuml server and image format in url
if (dataAttribute
&& dataAttribute.startsWith(`${pumlServer}/${pumlImageFormat}`)
) {
//console.log ("Plantuml node found - setting atribute values")
isPumlNode=true
node.setAttribute ('type', `${pumlObjectType}`)
node.setAttribute ('style', `${pumlObjectStyle}`)
node.setAttribute ('class', `${pumlObjectClass}`)
node.setAttribute ('alt', '')
}
//if not a plantuml node, then sanitise it
if (!isPumlNode) {
console.log ("Removing unknown object node")
return node.parentNode.removeChild(node)
}
}
})
//End changes to keep interactive plantuml object tag
input = DOMPurify.sanitize(input, {
ADD_ATTR: allowedAttrs,
ADD_TAGS: allowedTags

@ -114,14 +114,74 @@ module.exports = {
const zippedCode = encode64(zlib.deflateRawSync('@startuml\n' + contents + '\n@enduml').toString('binary'))
token = state.push('uml_diagram', 'img', 0)
// alt is constructed from children. No point in populating it here.
token.attrs = [ [ 'src', `${server}/${imageFormat}/${zippedCode}` ], [ 'alt', '' ], ['class', 'uml-diagram prefetch-candidate'] ]
token.block = true
token.children = altToken
token.info = params
token.map = [ startLine, nextLine ]
token.markup = markup
//Interactive plantuml changes start here
//Global variables that will be used in html-security
pumlImageFormat = imageFormat
pumlServer = server
pumlObjectType = 'image/svg+xml'
pumlObjectStyle = 'max-width:100%;height:auto'
pumlObjectClass = 'uml-diagram prefetch-candidate'
if (imageFormat === 'png') {
//non-interactive and not searchable - use the img tag
token = state.push('uml_diagram', 'img', 0)
// alt is constructed from children. No point in populating it here.
token.attrs = [ [ 'src' , `${server}/${imageFormat}/${zippedCode}` ],
[ 'alt' , '' ],
['class', `${pumlObjectClass}` ]
]
token.block = true
token.children = altToken
token.info = params
token.map = [ startLine, nextLine ]
token.markup = markup
}
else if (imageFormat === 'svg') {
// render svg interactively with object tag
/* <object data=<plantumlserver>/<format>/plantuml
alt='' class='uml-diagram prefetch-candidate'
style='max-width:100%;height:auto' type='image/svg+xml' > */
token = state.push('uml_diagram_obj', 'object', 0)
token.attrs = [ [ 'data' , `${server}/${imageFormat}/${zippedCode}`],
[ 'alt' , '' ],
[ 'class', `${pumlObjectClass}` ],
[ 'style', `${pumlObjectStyle}` ],
[ 'type', `${pumlObjectType}` ]
]
token.block = true
token.children = altToken
token.info = params
token.map = [ startLine, nextLine ]
token.markup = markup
//backup img node for object render failure
//void element - doesn't need to be closed in html
/* <img src=data=<plantumlserver>/<format>/plantuml alt=''
class='uml-diagram prefetch-candidate'
type='image/svg+xml'> */
token = state.push('uml_diagram_img', 'img', 0)
// alt is constructed from children. No point in populating it here.
token.attrs = [ [ 'src' , `${server}/${imageFormat}/${zippedCode}` ],
[ 'alt' , '' ],
['class', `${pumlObjectClass}`]
]
token.block = true
token.children = altToken
token.info = params
token.map = [ startLine, nextLine ]
token.markup = markup
//add puml source in object node for wikijs search index
//as wikijs will not index svg content from object tag
//i.e. like <object ...>@startuml...@enduml</object>
token = state.push ('text', '', 0)
token.content = contents
//close object tag - </object>
token = state.push('uml_diagram_close', 'object', -1)
}
//Interactive plantuml changes end here
state.line = nextLine + (autoClosed ? 1 : 0)

Loading…
Cancel
Save