diff options
-rw-r--r-- | chame/htmlparser.nim | 9 | ||||
-rw-r--r-- | chame/minidom.nim | 32 | ||||
-rw-r--r-- | chame/utils/twtstr.nim | 9 | ||||
-rw-r--r-- | tests/shared/tree_common.nim | 25 | ||||
-rw-r--r-- | tests/tree.nim | 9 |
5 files changed, 61 insertions, 23 deletions
diff --git a/chame/htmlparser.nim b/chame/htmlparser.nim index 330961ee..f3a0d9d4 100644 --- a/chame/htmlparser.nim +++ b/chame/htmlparser.nim @@ -1075,7 +1075,9 @@ func isHTMLIntegrationPoint[Handle, Atom](parser: HTML5Parser[Handle, Atom], if localName == parser.atomMap[ATOM_ANNOTATION_XML]: let i = token.findAttr(parser.atomMap[ATOM_ENCODING]) if i != -1: - return token.attrs[i].value in ["text/html", "application/xhtml+xml"] + let value = token.attrs[i].value + return value.equalsIgnoreCase("text/html") or + value.equalsIgnoreCase("application/xhtml+xml") elif namespace == Namespace.SVG: let elements = [ parser.atomMap[ATOM_FOREIGNOBJECT], @@ -2484,7 +2486,7 @@ proc processInHTMLContent[Handle, Atom](parser: var HTML5Parser[Handle, Atom], else: clear_the_stack_back_to_a_table_row_context pop_current_node - parser.insertionMode = IN_BODY + parser.insertionMode = IN_TABLE_BODY reprocess token ) ("</body>", "</caption>", "</col>", "</colgroup>", "</html>", "</td>", @@ -2808,6 +2810,7 @@ proc processInForeignContent(parser: var HTML5Parser, token: Token) = parser.insertCharacter(token.s) parser.framesetOk = false ) + TokenType.COMMENT => (block: parser.insertComment(token)) TokenType.DOCTYPE => (block: parse_error UNEXPECTED_DOCTYPE) ("<b>", "<big>", "<blockquote>", "<body>", "<br>", "<center>", "<code>", "<dd>", "<div>", "<dl>", "<dt>", "<em>", "<embed>", "<h1>", "<h2>", @@ -2884,7 +2887,7 @@ proc constructTree[Handle, Atom](parser: var HTML5Parser[Handle, Atom]) = if ismmlip and token.t in CharacterToken or ismmlip and token.t == START_TAG and token.tagname notin mmlnoatoms or namespace == Namespace.MATHML and localName == annotationXml and - token.tagtype == TAG_SVG or + token.t == START_TAG and token.tagtype == TAG_SVG or ishtmlip and token.t == START_TAG or ishtmlip and token.t in CharacterToken: parser.processInHTMLContent(token, parser.insertionMode) diff --git a/chame/minidom.nim b/chame/minidom.nim index 1261c6c6..02860d50 100644 --- a/chame/minidom.nim +++ b/chame/minidom.nim @@ -123,6 +123,11 @@ type attrs*: seq[Attribute] document*: Document + DocumentFragment* = ref object of Node + + HTMLTemplateElement* = ref object of Element + content*: DocumentFragment + type MiniDOMBuilder* = ref object of DOMBuilder[Node, MAtom] document*: Document @@ -188,9 +193,13 @@ proc getDocument(builder: DOMBuilder[Node, MAtom]): Node = proc getAtomFactory(builder: DOMBuilder[Node, MAtom]): AtomFactory[MAtom] = return MiniDOMBuilder(builder).factory -proc getParentNode(builder: DOMBuilder[Node, MAtom], handle: Node): Option[Node] = +proc getParentNode(builder: DOMBuilder[Node, MAtom], handle: Node): + Option[Node] = return option(handle.parentNode) +proc getTemplateContent(builder: DOMBuilder[Node, MAtom], handle: Node): Node = + return HTMLTemplateElement(handle).content + proc getLocalName(builder: DOMBuilder[Node, MAtom], handle: Node): MAtom = return Element(handle).localName @@ -200,14 +209,17 @@ proc getNamespace(builder: DOMBuilder[Node, MAtom], handle: Node): Namespace = proc createElement(builder: DOMBuilder[Node, MAtom], localName: MAtom, namespace: Namespace, attrs: seq[Attribute]): Node = let builder = cast[MiniDOMBuilder](builder) - let element = Element( - nodeType: ELEMENT_NODE, - localName: localName, - namespace: namespace, - document: builder.document, - attrs: attrs - ) - assert element.document != nil and element.document.factory != nil + let element = if localName.toTagType() == TAG_TEMPLATE: + HTMLTemplateElement( + content: DocumentFragment() + ) + else: + Element() + element.nodeType = ELEMENT_NODE + element.localName = localName + element.namespace = namespace + element.document = builder.document + element.attrs = attrs for attr in element.attrs.mitems: attr.value = attr.value.toValidUTF8() return element @@ -359,6 +371,7 @@ proc initMiniDOMBuilder*(builder: MiniDOMBuilder) = builder.getDocument = getDocument builder.getAtomFactory = getAtomFactory builder.getParentNode = getParentNode + builder.getTemplateContent = getTemplateContent builder.getLocalName = getLocalName builder.getNamespace = getNamespace builder.createElement = createElement @@ -419,7 +432,6 @@ proc parseHTMLFragment*(inputStream: Stream, element: Element, namespace: HTML, document: document ) - assert root.document != nil and root.document.factory != nil let rootToken = Token[MAtom](t: START_TAG, tagname: htmlAtom) document.childList = @[Node(root)] var opts = opts diff --git a/chame/utils/twtstr.nim b/chame/utils/twtstr.nim index d2af5dfe..970a3cdf 100644 --- a/chame/utils/twtstr.nim +++ b/chame/utils/twtstr.nim @@ -34,6 +34,15 @@ func until*(s: string, c: set[char]): string = func until*(s: string, c: char): string = s.until({c}) +func after*(s: string, c: set[char]): string = + var i = 0 + while i < s.len: + if s[i] in c: + return s.substr(i + 1) + inc i + +func after*(s: string, c: char): string = s.after({c}) + func isSurrogate*(u: uint32): bool = u in 0xD800u32..0xDFFFu32 func isNonCharacter*(u: uint32): bool = u in 0xFDD0u32..0xFDEFu32 or diff --git a/tests/shared/tree_common.nim b/tests/shared/tree_common.nim index e1f1ad28..a5033750 100644 --- a/tests/shared/tree_common.nim +++ b/tests/shared/tree_common.nim @@ -7,6 +7,7 @@ import std/unittest import test1 import chame/htmlparser import chame/minidom +import chame/utils/twtstr type TCError = object @@ -189,17 +190,22 @@ proc parseTestDocument(ctx: var TCTestParser): Document = elif nameStr.startsWith("math "): nameStr = nameStr.substr("math ".len) namespace = Namespace.MATHML - let element = Element( - nodeType: ELEMENT_NODE, - namespace: namespace, - localName: ctx.factory.strToAtom(nameStr), - document: result - ) + let element = if nameStr == "template": + HTMLTemplateElement() + else: + Element() + element.nodeType = ELEMENT_NODE + element.localName = ctx.factory.strToAtom(nameStr) + element.namespace = namespace + element.document = result top.childList.add(element) stack.add(element) indent += 2 elif str == "content": - assert false, "todo" + let fragment = DocumentFragment() + HTMLTemplateElement(top).content = fragment + stack.add(fragment) + indent += 2 elif str[0] == '"': let text = Text(nodeType: TEXT_NODE) top.childList.add(text) @@ -210,8 +216,7 @@ proc parseTestDocument(ctx: var TCTestParser): Document = text.data = str.substr(1, str.high - 1) else: assert '=' in str - let ss = str.split('=') - var name = ss[0] + var name = str.until('=') var prefix = NO_PREFIX var ns = NO_NAMESPACE if name.startsWith("xml "): @@ -227,7 +232,7 @@ proc parseTestDocument(ctx: var TCTestParser): Document = prefix = PREFIX_XLINK name = name.substr("xlink ".len) let na = ctx.factory.strToAtom(name) - let value = ss[1][1..^2] + let value = str.after('=')[1..^2] Element(top).attrs.add((prefix, ns, na, value)) while indent > 1: pop_node diff --git a/tests/tree.nim b/tests/tree.nim index ea269367..17c53d34 100644 --- a/tests/tree.nim +++ b/tests/tree.nim @@ -94,3 +94,12 @@ test "tests16.dat": test "tests17.dat": runTests("tests17.dat") + +test "tests18.dat": + runTests("tests18.dat") + +test "tests19.dat": + runTests("tests19.dat") + +test "tests20.dat": + runTests("tests20.dat") |