[mocks] Add some support for parsing SVG using the DOMParser API and innerHTML
This commit is contained in:
parent
f58da124e5
commit
fdd34f9726
3 changed files with 148 additions and 28 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
/*
|
||||
Known limitations:
|
||||
|
||||
- the innerHTML setter and the DOMParser only support a small subset of the true HTML/XML syntax.
|
||||
- `option.selected` can't be set/read when the option doesn't have a `select` parent
|
||||
- `element.attributes` is just a map of attribute names => Attr objects stubs
|
||||
- ...
|
||||
|
|
@ -183,9 +183,43 @@ module.exports = function(options) {
|
|||
res.unshift(declList)
|
||||
return res
|
||||
}
|
||||
|
||||
function parseMarkup(value, root, voidElements, xmlns) {
|
||||
var depth = 0, stack = [root]
|
||||
value.replace(/<([a-z0-9\-]+?)((?:\s+?[^=]+?=(?:"[^"]*?"|'[^']*?'|[^\s>]*))*?)(\s*\/)?>|<\/([a-z0-9\-]+?)>|([^<]+)/g, function(match, startTag, attrs, selfClosed, endTag, text) {
|
||||
if (startTag) {
|
||||
var element = xmlns == null ? $window.document.createElement(startTag) : $window.document.createElementNS(xmlns, startTag)
|
||||
attrs.replace(/\s+?([^=]+?)=(?:"([^"]*?)"|'([^']*?)'|([^\s>]*))/g, function(match, key, doubleQuoted, singleQuoted, unquoted) {
|
||||
var keyParts = key.split(":")
|
||||
var name = keyParts.pop()
|
||||
var ns = keyParts[0]
|
||||
var value = doubleQuoted || singleQuoted || unquoted || ""
|
||||
if (ns != null) element.setAttributeNS(ns, name, value)
|
||||
else element.setAttribute(name, value)
|
||||
})
|
||||
stack[depth].appendChild(element)
|
||||
if (!selfClosed && voidElements.indexOf(startTag.toLowerCase()) < 0) stack[++depth] = element
|
||||
}
|
||||
else if (endTag) {
|
||||
depth--
|
||||
}
|
||||
else if (text) {
|
||||
stack[depth].appendChild($window.document.createTextNode(text)) // FIXME handle html entities
|
||||
}
|
||||
})
|
||||
}
|
||||
function DOMParser() {}
|
||||
DOMParser.prototype.parseFromString = function(src, mime) {
|
||||
if (mime !== "image/svg+xml") throw new Error("The DOMParser mock only supports the \"image/svg+xml\" MIME type")
|
||||
var match = src.match(/^<svg xmlns="http:\/\/www\.w3\.org\/2000\/svg">(.*)<\/svg>$/)
|
||||
if (!match) throw new Error("Please provide a bare SVG tag with the xmlns as only attribute")
|
||||
var value = match[1]
|
||||
var root = $window.document.createElementNS("http://www.w3.org/2000/svg", "svg")
|
||||
parseMarkup(value, root, [], "http://www.w3.org/2000/svg")
|
||||
return {documentElement: root}
|
||||
}
|
||||
var activeElement
|
||||
var $window = {
|
||||
DOMParser: DOMParser,
|
||||
document: {
|
||||
createElement: function(tag) {
|
||||
var cssText = ""
|
||||
|
|
@ -244,30 +278,18 @@ module.exports = function(options) {
|
|||
if (value !== "") this.appendChild($window.document.createTextNode(value))
|
||||
},
|
||||
set innerHTML(value) {
|
||||
var voidElements = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"]
|
||||
while (this.firstChild) this.removeChild(this.firstChild)
|
||||
|
||||
var stack = [this], depth = 0, voidElements = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"]
|
||||
value.replace(/<([a-z0-9\-]+?)((?:\s+?[^=]+?=(?:"[^"]*?"|'[^']*?'|[^\s>]*))*?)(\s*\/)?>|<\/([a-z0-9\-]+?)>|([^<]+)/g, function(match, startTag, attrs, selfClosed, endTag, text) {
|
||||
if (startTag) {
|
||||
var element = $window.document.createElement(startTag)
|
||||
attrs.replace(/\s+?([^=]+?)=(?:"([^"]*?)"|'([^']*?)'|([^\s>]*))/g, function(match, key, doubleQuoted, singleQuoted, unquoted) {
|
||||
var keyParts = key.split(":")
|
||||
var name = keyParts.pop()
|
||||
var ns = keyParts[0]
|
||||
var value = doubleQuoted || singleQuoted || unquoted || ""
|
||||
if (ns != null) element.setAttributeNS(ns, name, value)
|
||||
else element.setAttribute(name, value)
|
||||
})
|
||||
stack[depth].appendChild(element)
|
||||
if (!selfClosed && voidElements.indexOf(startTag.toLowerCase()) < 0) stack[++depth] = element
|
||||
}
|
||||
else if (endTag) {
|
||||
depth--
|
||||
}
|
||||
else if (text) {
|
||||
stack[depth].appendChild($window.document.createTextNode(text)) // FIXME handle html entities
|
||||
}
|
||||
})
|
||||
var match = value.match(/^<svg xmlns="http:\/\/www\.w3\.org\/2000\/svg">(.*)<\/svg>$/), root, ns
|
||||
if (match) {
|
||||
var value = match[1]
|
||||
root = $window.document.createElementNS("http://www.w3.org/2000/svg", "svg")
|
||||
ns = "http://www.w3.org/2000/svg"
|
||||
this.appendChild(root)
|
||||
} else {
|
||||
root = this
|
||||
}
|
||||
parseMarkup(value, root, voidElements, ns)
|
||||
},
|
||||
get style() {
|
||||
return style
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue