summaryrefslogtreecommitdiffstats
path: root/parser
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /parser
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'parser')
-rw-r--r--parser/expat/COPYING22
-rw-r--r--parser/expat/expat_config.h155
-rw-r--r--parser/expat/lib/ascii.h85
-rw-r--r--parser/expat/lib/asciitab.h36
-rw-r--r--parser/expat/lib/expat.h1018
-rw-r--r--parser/expat/lib/expat_external.h121
-rw-r--r--parser/expat/lib/iasciitab.h37
-rw-r--r--parser/expat/lib/internal.h73
-rw-r--r--parser/expat/lib/latin1tab.h36
-rw-r--r--parser/expat/lib/moz.build20
-rw-r--r--parser/expat/lib/moz_extensions.c160
-rw-r--r--parser/expat/lib/nametab.h150
-rw-r--r--parser/expat/lib/utf8tab.h37
-rw-r--r--parser/expat/lib/xmlparse.c6512
-rw-r--r--parser/expat/lib/xmlrole.c1330
-rw-r--r--parser/expat/lib/xmlrole.h114
-rw-r--r--parser/expat/lib/xmltok.c1658
-rw-r--r--parser/expat/lib/xmltok.h316
-rw-r--r--parser/expat/lib/xmltok_impl.c1779
-rw-r--r--parser/expat/lib/xmltok_impl.h46
-rw-r--r--parser/expat/lib/xmltok_ns.c106
-rw-r--r--parser/expat/moz.build12
-rw-r--r--parser/html/jArray.h120
-rw-r--r--parser/html/java/Makefile59
-rw-r--r--parser/html/java/README.txt46
-rw-r--r--parser/html/java/manifest.txt2
-rw-r--r--parser/html/java/named-character-references.html7
-rw-r--r--parser/html/javasrc/AttributeName.java2473
-rw-r--r--parser/html/javasrc/ElementName.java1609
-rw-r--r--parser/html/javasrc/HtmlAttributes.java618
-rw-r--r--parser/html/javasrc/MetaScanner.java854
-rw-r--r--parser/html/javasrc/Portability.java150
-rw-r--r--parser/html/javasrc/README.txt6
-rw-r--r--parser/html/javasrc/StackNode.java295
-rw-r--r--parser/html/javasrc/StateSnapshot.java204
-rw-r--r--parser/html/javasrc/Tokenizer.java7067
-rw-r--r--parser/html/javasrc/TreeBuilder.java6558
-rw-r--r--parser/html/javasrc/UTF16Buffer.java151
-rw-r--r--parser/html/moz.build104
-rw-r--r--parser/html/nsAHtml5TreeBuilderState.h50
-rw-r--r--parser/html/nsAHtml5TreeOpSink.h24
-rw-r--r--parser/html/nsHtml5ArrayCopy.h78
-rw-r--r--parser/html/nsHtml5Atom.cpp91
-rw-r--r--parser/html/nsHtml5Atom.h28
-rw-r--r--parser/html/nsHtml5AtomList.h1074
-rw-r--r--parser/html/nsHtml5AtomTable.cpp56
-rw-r--r--parser/html/nsHtml5AtomTable.h107
-rw-r--r--parser/html/nsHtml5Atoms.cpp36
-rw-r--r--parser/html/nsHtml5Atoms.h30
-rw-r--r--parser/html/nsHtml5AttributeName.cpp2585
-rw-r--r--parser/html/nsHtml5AttributeName.h692
-rw-r--r--parser/html/nsHtml5ByteReadable.h33
-rw-r--r--parser/html/nsHtml5DependentUTF16Buffer.cpp33
-rw-r--r--parser/html/nsHtml5DependentUTF16Buffer.h31
-rw-r--r--parser/html/nsHtml5DocumentBuilder.cpp120
-rw-r--r--parser/html/nsHtml5DocumentBuilder.h130
-rw-r--r--parser/html/nsHtml5DocumentMode.h14
-rw-r--r--parser/html/nsHtml5ElementName.cpp1743
-rw-r--r--parser/html/nsHtml5ElementName.h499
-rw-r--r--parser/html/nsHtml5Highlighter.cpp802
-rw-r--r--parser/html/nsHtml5Highlighter.h413
-rw-r--r--parser/html/nsHtml5HtmlAttributes.cpp269
-rw-r--r--parser/html/nsHtml5HtmlAttributes.h97
-rw-r--r--parser/html/nsHtml5Macros.h32
-rw-r--r--parser/html/nsHtml5MetaScanner.cpp812
-rw-r--r--parser/html/nsHtml5MetaScanner.h142
-rw-r--r--parser/html/nsHtml5MetaScannerCppSupplement.h45
-rw-r--r--parser/html/nsHtml5MetaScannerHSupplement.h12
-rw-r--r--parser/html/nsHtml5Module.cpp137
-rw-r--r--parser/html/nsHtml5Module.h28
-rw-r--r--parser/html/nsHtml5NamedCharacters.cpp141
-rw-r--r--parser/html/nsHtml5NamedCharacters.h52
-rw-r--r--parser/html/nsHtml5NamedCharactersAccel.cpp313
-rw-r--r--parser/html/nsHtml5NamedCharactersAccel.h24
-rw-r--r--parser/html/nsHtml5NamedCharactersInclude.h2266
-rw-r--r--parser/html/nsHtml5OplessBuilder.cpp49
-rw-r--r--parser/html/nsHtml5OplessBuilder.h35
-rw-r--r--parser/html/nsHtml5OwningUTF16Buffer.cpp86
-rw-r--r--parser/html/nsHtml5OwningUTF16Buffer.h58
-rw-r--r--parser/html/nsHtml5Parser.cpp754
-rw-r--r--parser/html/nsHtml5Parser.h362
-rw-r--r--parser/html/nsHtml5PlainTextUtils.cpp40
-rw-r--r--parser/html/nsHtml5PlainTextUtils.h16
-rw-r--r--parser/html/nsHtml5Portability.cpp157
-rw-r--r--parser/html/nsHtml5Portability.h82
-rw-r--r--parser/html/nsHtml5RefPtr.h449
-rw-r--r--parser/html/nsHtml5ReleasableAttributeName.cpp34
-rw-r--r--parser/html/nsHtml5ReleasableAttributeName.h21
-rw-r--r--parser/html/nsHtml5ReleasableElementName.cpp30
-rw-r--r--parser/html/nsHtml5ReleasableElementName.h19
-rw-r--r--parser/html/nsHtml5SVGLoadDispatcher.cpp40
-rw-r--r--parser/html/nsHtml5SVGLoadDispatcher.h21
-rw-r--r--parser/html/nsHtml5Speculation.cpp36
-rw-r--r--parser/html/nsHtml5Speculation.h75
-rw-r--r--parser/html/nsHtml5SpeculativeLoad.cpp88
-rw-r--r--parser/html/nsHtml5SpeculativeLoad.h263
-rw-r--r--parser/html/nsHtml5StackNode.cpp229
-rw-r--r--parser/html/nsHtml5StackNode.h103
-rw-r--r--parser/html/nsHtml5StateSnapshot.cpp182
-rw-r--r--parser/html/nsHtml5StateSnapshot.h96
-rw-r--r--parser/html/nsHtml5StreamListener.cpp82
-rw-r--r--parser/html/nsHtml5StreamListener.h55
-rw-r--r--parser/html/nsHtml5StreamParser.cpp1722
-rw-r--r--parser/html/nsHtml5StreamParser.h579
-rw-r--r--parser/html/nsHtml5StringParser.cpp130
-rw-r--r--parser/html/nsHtml5StringParser.h88
-rw-r--r--parser/html/nsHtml5Tokenizer.cpp4116
-rw-r--r--parser/html/nsHtml5Tokenizer.h387
-rw-r--r--parser/html/nsHtml5TokenizerCppSupplement.h585
-rw-r--r--parser/html/nsHtml5TokenizerHSupplement.h148
-rw-r--r--parser/html/nsHtml5TokenizerLoopPolicies.h47
-rw-r--r--parser/html/nsHtml5TreeBuilder.cpp4520
-rw-r--r--parser/html/nsHtml5TreeBuilder.h384
-rw-r--r--parser/html/nsHtml5TreeBuilderCppSupplement.h1685
-rw-r--r--parser/html/nsHtml5TreeBuilderHSupplement.h248
-rw-r--r--parser/html/nsHtml5TreeOpExecutor.cpp1085
-rw-r--r--parser/html/nsHtml5TreeOpExecutor.h306
-rw-r--r--parser/html/nsHtml5TreeOpStage.cpp56
-rw-r--r--parser/html/nsHtml5TreeOpStage.h54
-rw-r--r--parser/html/nsHtml5TreeOperation.cpp995
-rw-r--r--parser/html/nsHtml5TreeOperation.h513
-rw-r--r--parser/html/nsHtml5UTF16Buffer.cpp119
-rw-r--r--parser/html/nsHtml5UTF16Buffer.h82
-rw-r--r--parser/html/nsHtml5UTF16BufferCppSupplement.h36
-rw-r--r--parser/html/nsHtml5UTF16BufferHSupplement.h17
-rw-r--r--parser/html/nsHtml5ViewSourceUtils.cpp53
-rw-r--r--parser/html/nsHtml5ViewSourceUtils.h17
-rw-r--r--parser/html/nsIContentHandle.h5
-rw-r--r--parser/html/nsIParserUtils.idl130
-rw-r--r--parser/html/nsIScriptableUnescapeHTML.idl54
-rw-r--r--parser/html/nsParserUtils.cpp232
-rw-r--r--parser/html/nsParserUtils.h23
-rw-r--r--parser/htmlparser/CNavDTD.cpp91
-rw-r--r--parser/htmlparser/CNavDTD.h36
-rw-r--r--parser/htmlparser/CParserContext.cpp86
-rw-r--r--parser/htmlparser/CParserContext.h70
-rw-r--r--parser/htmlparser/moz.build53
-rw-r--r--parser/htmlparser/nsElementTable.cpp623
-rw-r--r--parser/htmlparser/nsElementTable.h92
-rw-r--r--parser/htmlparser/nsExpatDriver.cpp1398
-rw-r--r--parser/htmlparser/nsExpatDriver.h142
-rw-r--r--parser/htmlparser/nsHTMLEntities.cpp205
-rw-r--r--parser/htmlparser/nsHTMLEntities.h35
-rw-r--r--parser/htmlparser/nsHTMLEntityList.h303
-rw-r--r--parser/htmlparser/nsHTMLTagList.h186
-rw-r--r--parser/htmlparser/nsHTMLTags.cpp265
-rw-r--r--parser/htmlparser/nsHTMLTags.h94
-rw-r--r--parser/htmlparser/nsHTMLTokenizer.cpp60
-rw-r--r--parser/htmlparser/nsHTMLTokenizer.h35
-rw-r--r--parser/htmlparser/nsIContentSink.h132
-rw-r--r--parser/htmlparser/nsIDTD.h136
-rw-r--r--parser/htmlparser/nsIExpatSink.idl109
-rw-r--r--parser/htmlparser/nsIExtendedExpatSink.idl72
-rw-r--r--parser/htmlparser/nsIFragmentContentSink.h77
-rw-r--r--parser/htmlparser/nsIHTMLContentSink.h89
-rw-r--r--parser/htmlparser/nsIParser.h273
-rw-r--r--parser/htmlparser/nsIParserService.h98
-rw-r--r--parser/htmlparser/nsITokenizer.h44
-rw-r--r--parser/htmlparser/nsParser.cpp1600
-rw-r--r--parser/htmlparser/nsParser.h398
-rw-r--r--parser/htmlparser/nsParserBase.h20
-rw-r--r--parser/htmlparser/nsParserCIID.h39
-rw-r--r--parser/htmlparser/nsParserConstants.h39
-rw-r--r--parser/htmlparser/nsParserModule.cpp107
-rw-r--r--parser/htmlparser/nsParserMsgUtils.cpp65
-rw-r--r--parser/htmlparser/nsParserMsgUtils.h21
-rw-r--r--parser/htmlparser/nsParserService.cpp99
-rw-r--r--parser/htmlparser/nsParserService.h58
-rw-r--r--parser/htmlparser/nsScanner.cpp409
-rw-r--r--parser/htmlparser/nsScanner.h190
-rw-r--r--parser/htmlparser/nsScannerString.cpp650
-rw-r--r--parser/htmlparser/nsScannerString.h604
-rw-r--r--parser/htmlparser/nsToken.h19
-rw-r--r--parser/htmlparser/tests/crashtests/121591-1.html22
-rw-r--r--parser/htmlparser/tests/crashtests/147179-1.html7
-rw-r--r--parser/htmlparser/tests/crashtests/151956-1.html18
-rw-r--r--parser/htmlparser/tests/crashtests/152444-1.html15
-rw-r--r--parser/htmlparser/tests/crashtests/185073-1.html15
-rw-r--r--parser/htmlparser/tests/crashtests/188474-1.html13
-rw-r--r--parser/htmlparser/tests/crashtests/194329-1.html15
-rw-r--r--parser/htmlparser/tests/crashtests/197052-1.html1
-rw-r--r--parser/htmlparser/tests/crashtests/220542-1.html2
-rw-r--r--parser/htmlparser/tests/crashtests/253979-1.html4
-rw-r--r--parser/htmlparser/tests/crashtests/269095-1.html1
-rw-r--r--parser/htmlparser/tests/crashtests/286733-1.html4
-rw-r--r--parser/htmlparser/tests/crashtests/286733-2.html4
-rw-r--r--parser/htmlparser/tests/crashtests/299036-1.html2
-rw-r--r--parser/htmlparser/tests/crashtests/30885-1.html17
-rw-r--r--parser/htmlparser/tests/crashtests/30956-1.html10
-rw-r--r--parser/htmlparser/tests/crashtests/31392-1.html15
-rw-r--r--parser/htmlparser/tests/crashtests/31694-1.html8
-rw-r--r--parser/htmlparser/tests/crashtests/31940-1.html15
-rw-r--r--parser/htmlparser/tests/crashtests/32613-1.html18
-rw-r--r--parser/htmlparser/tests/crashtests/328751-1.html9
-rw-r--r--parser/htmlparser/tests/crashtests/34168-1.html1
-rw-r--r--parser/htmlparser/tests/crashtests/34168-1.xml6
-rw-r--r--parser/htmlparser/tests/crashtests/408939-1.html139
-rw-r--r--parser/htmlparser/tests/crashtests/41427-1.html1
-rw-r--r--parser/htmlparser/tests/crashtests/423373-1.html1
-rw-r--r--parser/htmlparser/tests/crashtests/44178-1.html8
-rw-r--r--parser/htmlparser/tests/crashtests/445171-1-inner.svg5
-rw-r--r--parser/htmlparser/tests/crashtests/445171-1.html9
-rw-r--r--parser/htmlparser/tests/crashtests/46495-1.html5
-rw-r--r--parser/htmlparser/tests/crashtests/468538-1.xhtml15
-rw-r--r--parser/htmlparser/tests/crashtests/50134-1.html8
-rw-r--r--parser/htmlparser/tests/crashtests/502103.html1
-rw-r--r--parser/htmlparser/tests/crashtests/502869-iframe.html9
-rw-r--r--parser/htmlparser/tests/crashtests/502869.html18
-rw-r--r--parser/htmlparser/tests/crashtests/50994-1.html12
-rw-r--r--parser/htmlparser/tests/crashtests/515278-1.html3
-rw-r--r--parser/htmlparser/tests/crashtests/515533-1-inner.html12
-rw-r--r--parser/htmlparser/tests/crashtests/515533-1.html1
-rw-r--r--parser/htmlparser/tests/crashtests/515816-1.html11
-rw-r--r--parser/htmlparser/tests/crashtests/522326-1.html1
-rw-r--r--parser/htmlparser/tests/crashtests/525229-1.html7
-rw-r--r--parser/htmlparser/tests/crashtests/536097-1.html1
-rw-r--r--parser/htmlparser/tests/crashtests/555462-iframe.html3
-rw-r--r--parser/htmlparser/tests/crashtests/555462.html21
-rw-r--r--parser/htmlparser/tests/crashtests/563514-1.html10
-rw-r--r--parser/htmlparser/tests/crashtests/574884-1.html1
-rw-r--r--parser/htmlparser/tests/crashtests/574884-2.html1
-rw-r--r--parser/htmlparser/tests/crashtests/58455-1.html15
-rw-r--r--parser/htmlparser/tests/crashtests/591330-1.html284
-rw-r--r--parser/htmlparser/tests/crashtests/60110-1.html22
-rw-r--r--parser/htmlparser/tests/crashtests/650501-1.xhtml22
-rw-r--r--parser/htmlparser/tests/crashtests/696651-1.html11
-rw-r--r--parser/htmlparser/tests/crashtests/699347-1.xml1
-rw-r--r--parser/htmlparser/tests/crashtests/721313-1.html2
-rw-r--r--parser/htmlparser/tests/crashtests/73331-1.html27
-rw-r--r--parser/htmlparser/tests/crashtests/742414-1.html4
-rw-r--r--parser/htmlparser/tests/crashtests/92647-1.html33
-rw-r--r--parser/htmlparser/tests/crashtests/92788-1.html20
-rw-r--r--parser/htmlparser/tests/crashtests/981279-1.html15
-rw-r--r--parser/htmlparser/tests/crashtests/982285-1.html19
-rw-r--r--parser/htmlparser/tests/crashtests/crashtests.list57
-rw-r--r--parser/htmlparser/tests/mochitest/blue.pngbin0 -> 2745 bytes
-rw-r--r--parser/htmlparser/tests/mochitest/browser.ini6
-rw-r--r--parser/htmlparser/tests/mochitest/browser_viewsource.js22
-rw-r--r--parser/htmlparser/tests/mochitest/bug_502091_iframe.html17
-rw-r--r--parser/htmlparser/tests/mochitest/dir_bug534293/file_bug534293.sjs14
-rw-r--r--parser/htmlparser/tests/mochitest/file_async_bug1104732.sjs14
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug102699.sjs15
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug534293-slow.sjs14
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug534293.sjs14
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug543062.sjs32
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug568470-script.sjs16
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug568470.sjs21
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug594730-1.html3
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug594730-2.html3
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug594730-3.html3
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug594730-4.html3
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug594730-5.html3
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug594730-6.html3
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug594730-7.html3
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug594730-8.html3
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug594730-9.html5
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug642908.sjs16
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug655682.sjs37
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug672453_bomless_utf16.htmlbin0 -> 354 bytes
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html1
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html^headers^2
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug672453_late_meta.html1028
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug672453_meta_non_superset.html1
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug672453_meta_restart.html1028
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug672453_meta_unsupported.html1
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug672453_meta_userdefined.html1
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug672453_meta_utf16.html1
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug672453_not_declared.html1
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug688580.js4
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug716579-16.htmlbin0 -> 82 bytes
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug716579-16.html^headers^1
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug716579-16.xhtmlbin0 -> 214 bytes
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug716579-16.xhtml^headers^1
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug716579-8.html3
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug716579-8.html^headers^1
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml7
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml^headers^1
-rw-r--r--parser/htmlparser/tests/mochitest/file_bug717180.html1
-rw-r--r--parser/htmlparser/tests/mochitest/file_defer_bug1104732.js3
-rw-r--r--parser/htmlparser/tests/mochitest/file_img_picture_preload.html167
-rw-r--r--parser/htmlparser/tests/mochitest/file_img_picture_preload.sjs28
-rw-r--r--parser/htmlparser/tests/mochitest/file_viewsource.html18
-rw-r--r--parser/htmlparser/tests/mochitest/html5_tree_construction_exceptions.js11
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/README.md104
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/adoption01.dat337
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/adoption02.dat99
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/comments01.dat178
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/doctype01.dat424
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/domjs-unsafe.datbin0 -> 9884 bytes
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/entities01.dat792
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/entities02.dat283
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/foreign-fragment.dat550
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/html5lib_license.txt21
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/html5lib_upstream.txt11
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/html5test-com.dat291
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/inbody01.dat54
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/isindex.dat67
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/main-element.dat44
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/pending-spec-changes-plain-text-unsafe.datbin0 -> 816 bytes
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/pending-spec-changes.dat46
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/plain-text-unsafe.datbin0 -> 7925 bytes
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/ruby.dat298
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/scriptdata01.dat352
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/scripted/adoption01.dat15
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/scripted/ark.dat26
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/scripted/webkit01.dat28
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tables01.dat286
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/template.dat1418
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests1.dat1959
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests10.dat847
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests11.dat482
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests12.dat62
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests14.dat75
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests15.dat216
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests16.dat2374
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests17.dat180
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests18.dat322
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests19.dat1523
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests2.dat770
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests20.dat516
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests21.dat305
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests22.dat190
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests23.dat168
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests24.dat79
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests25.dat220
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests26.dat411
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests3.dat306
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests4.dat58
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests5.dat197
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests6.dat662
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests7.dat402
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests8.dat149
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests9.dat473
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests_innerHTML_1.dat902
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/tricky01.dat334
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/webkit01.dat705
-rw-r--r--parser/htmlparser/tests/mochitest/html5lib_tree_construction/webkit02.dat116
-rw-r--r--parser/htmlparser/tests/mochitest/iframe_bug599584.html16
-rw-r--r--parser/htmlparser/tests/mochitest/invalidchar.xml4
-rw-r--r--parser/htmlparser/tests/mochitest/mochitest.ini149
-rw-r--r--parser/htmlparser/tests/mochitest/parser_datreader.js207
-rw-r--r--parser/htmlparser/tests/mochitest/parser_web_testrunner.js141
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug102699.html75
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug1104732.html59
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug1209658.html35
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug174351.html31
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug213517.html30
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug339350.xhtml60
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug358797.html31
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug396568.html47
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug418464.html43
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug460437.xhtml39
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug502091.html37
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug534293.html22
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug543062.html26
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug552938-2.html38
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug552938.html33
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug563322.xhtml33
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug566879.html61
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug568470.html51
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug594730.html32
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug599584.html43
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug613662.html132
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug613662.xhtml137
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug639362.html29
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug642908.html32
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug645115.html32
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug655682.html80
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug667533.html28
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug672453.html100
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug688580.html64
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug688580.xhtml62
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug709083.html30
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug715112.html49
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug715739.html72
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug716579.html44
-rw-r--r--parser/htmlparser/tests/mochitest/test_bug717180.html44
-rw-r--r--parser/htmlparser/tests/mochitest/test_compatmode.html93
-rw-r--r--parser/htmlparser/tests/mochitest/test_html5_tree_construction.html60
-rw-r--r--parser/htmlparser/tests/mochitest/test_html5_tree_construction_part2.html60
-rw-r--r--parser/htmlparser/tests/mochitest/test_img_picture_preload.html87
-rw-r--r--parser/htmlparser/tests/mochitest/test_xml_mislabeled.html62
-rw-r--r--parser/htmlparser/tests/reftest/bug482921-1-ref.html27
-rw-r--r--parser/htmlparser/tests/reftest/bug482921-1.html24
-rw-r--r--parser/htmlparser/tests/reftest/bug482921-2-ref.html28
-rw-r--r--parser/htmlparser/tests/reftest/bug482921-2.xhtml25
-rw-r--r--parser/htmlparser/tests/reftest/bug535530-1-ref.html2
-rw-r--r--parser/htmlparser/tests/reftest/bug535530-1.html14
-rw-r--r--parser/htmlparser/tests/reftest/bug535530-2-ref.html17
-rw-r--r--parser/htmlparser/tests/reftest/bug535530-2.html14
-rw-r--r--parser/htmlparser/tests/reftest/bug566280-1-ref.html2
-rw-r--r--parser/htmlparser/tests/reftest/bug566280-1.htmlbin0 -> 19 bytes
-rw-r--r--parser/htmlparser/tests/reftest/bug569229-1-ref.xml2
-rw-r--r--parser/htmlparser/tests/reftest/bug569229-1.xml6
-rw-r--r--parser/htmlparser/tests/reftest/bug577418-1-ref.html6
-rw-r--r--parser/htmlparser/tests/reftest/bug577418-1.html15
-rw-r--r--parser/htmlparser/tests/reftest/bug582788-1-ref.html11
-rw-r--r--parser/htmlparser/tests/reftest/bug582788-1.html11
-rw-r--r--parser/htmlparser/tests/reftest/bug582940-1-ref.html16
-rw-r--r--parser/htmlparser/tests/reftest/bug582940-1.html16
-rw-r--r--parser/htmlparser/tests/reftest/bug592656-1-ref.html9
-rw-r--r--parser/htmlparser/tests/reftest/bug592656-1.html32
-rw-r--r--parser/htmlparser/tests/reftest/bug599320-1-ref.html17
-rw-r--r--parser/htmlparser/tests/reftest/bug599320-1.htmlbin0 -> 616 bytes
-rw-r--r--parser/htmlparser/tests/reftest/bug608373-1-ref.html9
-rw-r--r--parser/htmlparser/tests/reftest/bug608373-1.html14
-rw-r--r--parser/htmlparser/tests/reftest/bug659763-1-ref.html2
-rw-r--r--parser/htmlparser/tests/reftest/bug659763-1.html9
-rw-r--r--parser/htmlparser/tests/reftest/bug659763-2-ref.html2
-rw-r--r--parser/htmlparser/tests/reftest/bug659763-2.html9
-rw-r--r--parser/htmlparser/tests/reftest/bug659763-3-ref.html2
-rw-r--r--parser/htmlparser/tests/reftest/bug659763-3.html9
-rw-r--r--parser/htmlparser/tests/reftest/bug659763-4-ref.html2
-rw-r--r--parser/htmlparser/tests/reftest/bug659763-4.html9
-rw-r--r--parser/htmlparser/tests/reftest/bug659763-5-ref.html2
-rw-r--r--parser/htmlparser/tests/reftest/bug659763-5.html9
-rw-r--r--parser/htmlparser/tests/reftest/bug659763-6-ref.html2
-rw-r--r--parser/htmlparser/tests/reftest/bug659763-6.html9
-rw-r--r--parser/htmlparser/tests/reftest/bug673094-1-ref.html9
-rw-r--r--parser/htmlparser/tests/reftest/bug673094-1.html9
-rw-r--r--parser/htmlparser/tests/reftest/bug696651-1-ref.html1
-rw-r--r--parser/htmlparser/tests/reftest/bug696651-1.html2
-rw-r--r--parser/htmlparser/tests/reftest/bug696651-2-ref.html1
-rw-r--r--parser/htmlparser/tests/reftest/bug696651-2.html6
-rw-r--r--parser/htmlparser/tests/reftest/bug696651-external.js1
-rw-r--r--parser/htmlparser/tests/reftest/bug700260-1-ref.html3
-rw-r--r--parser/htmlparser/tests/reftest/bug700260-1.html3
-rw-r--r--parser/htmlparser/tests/reftest/bug704667-1-ref.html4
-rw-r--r--parser/htmlparser/tests/reftest/bug704667-1.html1
-rw-r--r--parser/htmlparser/tests/reftest/bug731234-1-ref.html30
-rw-r--r--parser/htmlparser/tests/reftest/bug731234-1.html27
-rw-r--r--parser/htmlparser/tests/reftest/bug820508-1-ref.html6
-rw-r--r--parser/htmlparser/tests/reftest/bug820508-1.html6
-rw-r--r--parser/htmlparser/tests/reftest/bug910588-1-ref.html2
-rw-r--r--parser/htmlparser/tests/reftest/bug910588-1.html1
-rw-r--r--parser/htmlparser/tests/reftest/frame582940-ref.html51
-rw-r--r--parser/htmlparser/tests/reftest/frame582940.html51
-rw-r--r--parser/htmlparser/tests/reftest/frame599320-1-ref.html15
-rw-r--r--parser/htmlparser/tests/reftest/frame599320-1.html1092
-rw-r--r--parser/htmlparser/tests/reftest/reftest-stylo.list26
-rw-r--r--parser/htmlparser/tests/reftest/reftest.list26
-rw-r--r--parser/moz.build12
-rw-r--r--parser/nsCharsetSource.h26
-rw-r--r--parser/xml/moz.build36
-rw-r--r--parser/xml/nsIMozSAXXMLDeclarationHandler.idl15
-rw-r--r--parser/xml/nsISAXAttributes.idl150
-rw-r--r--parser/xml/nsISAXContentHandler.idl225
-rw-r--r--parser/xml/nsISAXDTDHandler.idl77
-rw-r--r--parser/xml/nsISAXErrorHandler.idl95
-rw-r--r--parser/xml/nsISAXLexicalHandler.idl118
-rw-r--r--parser/xml/nsISAXLocator.idl89
-rw-r--r--parser/xml/nsISAXMutableAttributes.idl127
-rw-r--r--parser/xml/nsISAXXMLFilter.idl29
-rw-r--r--parser/xml/nsISAXXMLReader.idl207
-rw-r--r--parser/xml/nsSAXAttributes.cpp332
-rw-r--r--parser/xml/nsSAXAttributes.h43
-rw-r--r--parser/xml/nsSAXLocator.cpp47
-rw-r--r--parser/xml/nsSAXLocator.h39
-rw-r--r--parser/xml/nsSAXXMLReader.cpp719
-rw-r--r--parser/xml/nsSAXXMLReader.h105
-rw-r--r--parser/xml/test/moz.build8
-rw-r--r--parser/xml/test/unit/CC-BY-LICENSE59
-rw-r--r--parser/xml/test/unit/results.js844
-rw-r--r--parser/xml/test/unit/test_namespace_support.js52
-rw-r--r--parser/xml/test/unit/test_parser.js167
-rw-r--r--parser/xml/test/unit/test_sanitizer.js21
-rw-r--r--parser/xml/test/unit/test_xml_declaration.js82
-rw-r--r--parser/xml/test/unit/xpcshell.ini9
468 files changed, 110675 insertions, 0 deletions
diff --git a/parser/expat/COPYING b/parser/expat/COPYING
new file mode 100644
index 000000000..dcb450642
--- /dev/null
+++ b/parser/expat/COPYING
@@ -0,0 +1,22 @@
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+ and Clark Cooper
+Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/parser/expat/expat_config.h b/parser/expat/expat_config.h
new file mode 100644
index 000000000..1f4de5ac4
--- /dev/null
+++ b/parser/expat/expat_config.h
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef __expat_config_h__
+#define __expat_config_h__
+
+#define MOZ_UNICODE
+#include "nspr.h"
+
+#ifdef IS_LITTLE_ENDIAN
+#define BYTEORDER 1234
+#else
+#define BYTEORDER 4321
+#endif /* IS_LITTLE_ENDIAN */
+
+#if PR_BYTES_PER_INT != 4
+#define int int32_t
+#endif /* PR_BYTES_PER_INT != 4 */
+
+/* Other Mozilla code relies on memmove already, so we assume it's available */
+#define HAVE_MEMMOVE 1
+
+#define XMLCALL
+#define XML_STATIC
+#define XMLIMPORT
+
+#define XML_UNICODE
+typedef char XML_LChar;
+/*
+ * The char16_t type is only usable in C++ code, so we need this ugly hack to
+ * select a binary compatible C type for the expat C code to use.
+ */
+#ifdef __cplusplus
+typedef char16_t XML_Char;
+#define XML_T(x) (char16_t)x
+#else
+#include <stdint.h>
+typedef uint16_t XML_Char;
+#define XML_T(x) (uint16_t)x
+#endif
+
+#define XML_DTD
+#define XML_NS
+
+/* avoid conflicts with system version of libexpat */
+
+/* expat.h */
+#define XML_SetElementDeclHandler MOZ_XML_SetElementDeclHandler
+#define XML_SetAttlistDeclHandler MOZ_XML_SetAttlistDeclHandler
+#define XML_SetXmlDeclHandler MOZ_XML_SetXmlDeclHandler
+#define XML_ParserCreate MOZ_XML_ParserCreate
+#define XML_ParserCreateNS MOZ_XML_ParserCreateNS
+#define XML_ParserCreate_MM MOZ_XML_ParserCreate_MM
+#define XML_ParserReset MOZ_XML_ParserReset
+#define XML_SetEntityDeclHandler MOZ_XML_SetEntityDeclHandler
+#define XML_SetElementHandler MOZ_XML_SetElementHandler
+#define XML_SetStartElementHandler MOZ_XML_SetStartElementHandler
+#define XML_SetEndElementHandler MOZ_XML_SetEndElementHandler
+#define XML_SetCharacterDataHandler MOZ_XML_SetCharacterDataHandler
+#ifndef __VMS
+#define XML_SetProcessingInstructionHandler MOZ_XML_SetProcessingInstructionHandler
+#else
+#define XML_SetProcessingInstrHandler MOZ_XML_SetProcessingInstrHandler
+#endif
+#define XML_SetCommentHandler MOZ_XML_SetCommentHandler
+#define XML_SetCdataSectionHandler MOZ_XML_SetCdataSectionHandler
+#define XML_SetStartCdataSectionHandler MOZ_XML_SetStartCdataSectionHandler
+#define XML_SetEndCdataSectionHandler MOZ_XML_SetEndCdataSectionHandler
+#define XML_SetDefaultHandler MOZ_XML_SetDefaultHandler
+#define XML_SetDefaultHandlerExpand MOZ_XML_SetDefaultHandlerExpand
+#define XML_SetDoctypeDeclHandler MOZ_XML_SetDoctypeDeclHandler
+#define XML_SetStartDoctypeDeclHandler MOZ_XML_SetStartDoctypeDeclHandler
+#define XML_SetEndDoctypeDeclHandler MOZ_XML_SetEndDoctypeDeclHandler
+#ifndef __VMS
+#define XML_SetUnparsedEntityDeclHandler MOZ_XML_SetUnparsedEntityDeclHandler
+#else
+#define XML_SetUnparsedEntDeclHandler MOZ_XML_SetUnparsedEntDeclHandler
+#endif
+#define XML_SetNotationDeclHandler MOZ_XML_SetNotationDeclHandler
+#define XML_SetNamespaceDeclHandler MOZ_XML_SetNamespaceDeclHandler
+#ifndef __VMS
+#define XML_SetStartNamespaceDeclHandler MOZ_XML_SetStartNamespaceDeclHandler
+#else
+#define XML_SetStartNamespcDeclHandler MOZ_XML_SetStartNamespcDeclHandler
+#endif
+#define XML_SetEndNamespaceDeclHandler MOZ_XML_SetEndNamespaceDeclHandler
+#define XML_SetNotStandaloneHandler MOZ_XML_SetNotStandaloneHandler
+#define XML_SetExternalEntityRefHandler MOZ_XML_SetExternalEntityRefHandler
+#ifndef __VMS
+#define XML_SetExternalEntityRefHandlerArg MOZ_XML_SetExternalEntityRefHandlerArg
+#else
+#define XML_SetExternalEntRefHandlerArg MOZ_XML_SetExternalEntRefHandlerArg
+#endif
+#define XML_SetSkippedEntityHandler MOZ_XML_SetSkippedEntityHandler
+#define XML_SetUnknownEncodingHandler MOZ_XML_SetUnknownEncodingHandler
+#define XML_DefaultCurrent MOZ_XML_DefaultCurrent
+#define XML_SetReturnNSTriplet MOZ_XML_SetReturnNSTriplet
+#define XML_SetUserData MOZ_XML_SetUserData
+#define XML_SetEncoding MOZ_XML_SetEncoding
+#define XML_UseParserAsHandlerArg MOZ_XML_UseParserAsHandlerArg
+#define XML_UseForeignDTD MOZ_XML_UseForeignDTD
+#define XML_SetBase MOZ_XML_SetBase
+#define XML_GetBase MOZ_XML_GetBase
+#define XML_GetSpecifiedAttributeCount MOZ_XML_GetSpecifiedAttributeCount
+#define XML_GetIdAttributeIndex MOZ_XML_GetIdAttributeIndex
+#define XML_Parse MOZ_XML_Parse
+#define XML_GetBuffer MOZ_XML_GetBuffer
+#define XML_ParseBuffer MOZ_XML_ParseBuffer
+#define XML_StopParser MOZ_XML_StopParser
+#define XML_ResumeParser MOZ_XML_ResumeParser
+#define XML_GetParsingStatus MOZ_XML_GetParsingStatus
+#define XML_ExternalEntityParserCreate MOZ_XML_ExternalEntityParserCreate
+#define XML_SetParamEntityParsing MOZ_XML_SetParamEntityParsing
+#define XML_GetErrorCode MOZ_XML_GetErrorCode
+#define XML_GetCurrentLineNumber MOZ_XML_GetCurrentLineNumber
+#define XML_GetCurrentColumnNumber MOZ_XML_GetCurrentColumnNumber
+#define XML_GetCurrentByteIndex MOZ_XML_GetCurrentByteIndex
+#define XML_GetCurrentByteCount MOZ_XML_GetCurrentByteCount
+#define XML_GetInputContext MOZ_XML_GetInputContext
+#define XML_FreeContentModel MOZ_XML_FreeContentModel
+#define XML_MemMalloc MOZ_XML_MemMalloc
+#define XML_MemRealloc MOZ_XML_MemRealloc
+#define XML_MemFree MOZ_XML_MemFree
+#define XML_ParserFree MOZ_XML_ParserFree
+#define XML_ErrorString MOZ_XML_ErrorString
+#define XML_ExpatVersion MOZ_XML_ExpatVersion
+#define XML_ExpatVersionInfo MOZ_XML_ExpatVersionInfo
+#define XML_GetFeatureList MOZ_XML_GetFeatureList
+
+/* xmlrole.h */
+#define XmlPrologStateInit MOZ_XmlPrologStateInit
+#ifndef __VMS
+#define XmlPrologStateInitExternalEntity MOZ_XmlPrologStateInitExternalEntity
+#else
+#define XmlPrologStateInitExternalEnt MOZ_XmlPrologStateInitExternalEnt
+#endif
+
+/* xmltok.h */
+#define XmlParseXmlDecl MOZ_XmlParseXmlDecl
+#define XmlParseXmlDeclNS MOZ_XmlParseXmlDeclNS
+#define XmlInitEncoding MOZ_XmlInitEncoding
+#define XmlInitEncodingNS MOZ_XmlInitEncodingNS
+#define XmlGetUtf8InternalEncoding MOZ_XmlGetUtf8InternalEncoding
+#define XmlGetUtf16InternalEncoding MOZ_XmlGetUtf16InternalEncoding
+#define XmlGetUtf8InternalEncodingNS MOZ_XmlGetUtf8InternalEncodingNS
+#define XmlGetUtf16InternalEncodingNS MOZ_XmlGetUtf16InternalEncodingNS
+#define XmlUtf8Encode MOZ_XmlUtf8Encode
+#define XmlUtf16Encode MOZ_XmlUtf16Encode
+#define XmlSizeOfUnknownEncoding MOZ_XmlSizeOfUnknownEncoding
+#define XmlInitUnknownEncoding MOZ_XmlInitUnknownEncoding
+#define XmlInitUnknownEncodingNS MOZ_XmlInitUnknownEncodingNS
+
+#endif /* __expat_config_h__ */
diff --git a/parser/expat/lib/ascii.h b/parser/expat/lib/ascii.h
new file mode 100644
index 000000000..337e5bb7e
--- /dev/null
+++ b/parser/expat/lib/ascii.h
@@ -0,0 +1,85 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#define ASCII_A 0x41
+#define ASCII_B 0x42
+#define ASCII_C 0x43
+#define ASCII_D 0x44
+#define ASCII_E 0x45
+#define ASCII_F 0x46
+#define ASCII_G 0x47
+#define ASCII_H 0x48
+#define ASCII_I 0x49
+#define ASCII_J 0x4A
+#define ASCII_K 0x4B
+#define ASCII_L 0x4C
+#define ASCII_M 0x4D
+#define ASCII_N 0x4E
+#define ASCII_O 0x4F
+#define ASCII_P 0x50
+#define ASCII_Q 0x51
+#define ASCII_R 0x52
+#define ASCII_S 0x53
+#define ASCII_T 0x54
+#define ASCII_U 0x55
+#define ASCII_V 0x56
+#define ASCII_W 0x57
+#define ASCII_X 0x58
+#define ASCII_Y 0x59
+#define ASCII_Z 0x5A
+
+#define ASCII_a 0x61
+#define ASCII_b 0x62
+#define ASCII_c 0x63
+#define ASCII_d 0x64
+#define ASCII_e 0x65
+#define ASCII_f 0x66
+#define ASCII_g 0x67
+#define ASCII_h 0x68
+#define ASCII_i 0x69
+#define ASCII_j 0x6A
+#define ASCII_k 0x6B
+#define ASCII_l 0x6C
+#define ASCII_m 0x6D
+#define ASCII_n 0x6E
+#define ASCII_o 0x6F
+#define ASCII_p 0x70
+#define ASCII_q 0x71
+#define ASCII_r 0x72
+#define ASCII_s 0x73
+#define ASCII_t 0x74
+#define ASCII_u 0x75
+#define ASCII_v 0x76
+#define ASCII_w 0x77
+#define ASCII_x 0x78
+#define ASCII_y 0x79
+#define ASCII_z 0x7A
+
+#define ASCII_0 0x30
+#define ASCII_1 0x31
+#define ASCII_2 0x32
+#define ASCII_3 0x33
+#define ASCII_4 0x34
+#define ASCII_5 0x35
+#define ASCII_6 0x36
+#define ASCII_7 0x37
+#define ASCII_8 0x38
+#define ASCII_9 0x39
+
+#define ASCII_TAB 0x09
+#define ASCII_SPACE 0x20
+#define ASCII_EXCL 0x21
+#define ASCII_QUOT 0x22
+#define ASCII_AMP 0x26
+#define ASCII_APOS 0x27
+#define ASCII_MINUS 0x2D
+#define ASCII_PERIOD 0x2E
+#define ASCII_COLON 0x3A
+#define ASCII_SEMI 0x3B
+#define ASCII_LT 0x3C
+#define ASCII_EQUALS 0x3D
+#define ASCII_GT 0x3E
+#define ASCII_LSQB 0x5B
+#define ASCII_RSQB 0x5D
+#define ASCII_UNDERSCORE 0x5F
diff --git a/parser/expat/lib/asciitab.h b/parser/expat/lib/asciitab.h
new file mode 100644
index 000000000..79a15c28c
--- /dev/null
+++ b/parser/expat/lib/asciitab.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
+/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/parser/expat/lib/expat.h b/parser/expat/lib/expat.h
new file mode 100644
index 000000000..43391f5f1
--- /dev/null
+++ b/parser/expat/lib/expat.h
@@ -0,0 +1,1018 @@
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#ifndef Expat_INCLUDED
+#define Expat_INCLUDED 1
+
+#ifdef __VMS
+/* 0 1 2 3 0 1 2 3
+ 1234567890123456789012345678901 1234567890123456789012345678901 */
+#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler
+#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler
+#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler
+#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg
+#endif
+
+#include <stdlib.h>
+#include "expat_external.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct XML_ParserStruct;
+typedef struct XML_ParserStruct *XML_Parser;
+
+/* Should this be defined using stdbool.h when C99 is available? */
+typedef unsigned char XML_Bool;
+#define XML_TRUE ((XML_Bool) 1)
+#define XML_FALSE ((XML_Bool) 0)
+
+/* The XML_Status enum gives the possible return values for several
+ API functions. The preprocessor #defines are included so this
+ stanza can be added to code that still needs to support older
+ versions of Expat 1.95.x:
+
+ #ifndef XML_STATUS_OK
+ #define XML_STATUS_OK 1
+ #define XML_STATUS_ERROR 0
+ #endif
+
+ Otherwise, the #define hackery is quite ugly and would have been
+ dropped.
+*/
+enum XML_Status {
+ XML_STATUS_ERROR = 0,
+#define XML_STATUS_ERROR XML_STATUS_ERROR
+ XML_STATUS_OK = 1,
+#define XML_STATUS_OK XML_STATUS_OK
+ XML_STATUS_SUSPENDED = 2
+#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED
+};
+
+enum XML_Error {
+ XML_ERROR_NONE,
+ XML_ERROR_NO_MEMORY,
+ XML_ERROR_SYNTAX,
+ XML_ERROR_NO_ELEMENTS,
+ XML_ERROR_INVALID_TOKEN,
+ XML_ERROR_UNCLOSED_TOKEN,
+ XML_ERROR_PARTIAL_CHAR,
+ XML_ERROR_TAG_MISMATCH,
+ XML_ERROR_DUPLICATE_ATTRIBUTE,
+ XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
+ XML_ERROR_PARAM_ENTITY_REF,
+ XML_ERROR_UNDEFINED_ENTITY,
+ XML_ERROR_RECURSIVE_ENTITY_REF,
+ XML_ERROR_ASYNC_ENTITY,
+ XML_ERROR_BAD_CHAR_REF,
+ XML_ERROR_BINARY_ENTITY_REF,
+ XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
+ XML_ERROR_MISPLACED_XML_PI,
+ XML_ERROR_UNKNOWN_ENCODING,
+ XML_ERROR_INCORRECT_ENCODING,
+ XML_ERROR_UNCLOSED_CDATA_SECTION,
+ XML_ERROR_EXTERNAL_ENTITY_HANDLING,
+ XML_ERROR_NOT_STANDALONE,
+ XML_ERROR_UNEXPECTED_STATE,
+ XML_ERROR_ENTITY_DECLARED_IN_PE,
+ XML_ERROR_FEATURE_REQUIRES_XML_DTD,
+ XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING,
+ /* Added in 1.95.7. */
+ XML_ERROR_UNBOUND_PREFIX,
+ /* Added in 1.95.8. */
+ XML_ERROR_UNDECLARING_PREFIX,
+ XML_ERROR_INCOMPLETE_PE,
+ XML_ERROR_XML_DECL,
+ XML_ERROR_TEXT_DECL,
+ XML_ERROR_PUBLICID,
+ XML_ERROR_SUSPENDED,
+ XML_ERROR_NOT_SUSPENDED,
+ XML_ERROR_ABORTED,
+ XML_ERROR_FINISHED,
+ XML_ERROR_SUSPEND_PE,
+ /* Added in 2.0. */
+ XML_ERROR_RESERVED_PREFIX_XML,
+ XML_ERROR_RESERVED_PREFIX_XMLNS,
+ XML_ERROR_RESERVED_NAMESPACE_URI
+};
+
+enum XML_Content_Type {
+ XML_CTYPE_EMPTY = 1,
+ XML_CTYPE_ANY,
+ XML_CTYPE_MIXED,
+ XML_CTYPE_NAME,
+ XML_CTYPE_CHOICE,
+ XML_CTYPE_SEQ
+};
+
+enum XML_Content_Quant {
+ XML_CQUANT_NONE,
+ XML_CQUANT_OPT,
+ XML_CQUANT_REP,
+ XML_CQUANT_PLUS
+};
+
+/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be
+ XML_CQUANT_NONE, and the other fields will be zero or NULL.
+ If type == XML_CTYPE_MIXED, then quant will be NONE or REP and
+ numchildren will contain number of elements that may be mixed in
+ and children point to an array of XML_Content cells that will be
+ all of XML_CTYPE_NAME type with no quantification.
+
+ If type == XML_CTYPE_NAME, then the name points to the name, and
+ the numchildren field will be zero and children will be NULL. The
+ quant fields indicates any quantifiers placed on the name.
+
+ CHOICE and SEQ will have name NULL, the number of children in
+ numchildren and children will point, recursively, to an array
+ of XML_Content cells.
+
+ The EMPTY, ANY, and MIXED types will only occur at top level.
+*/
+
+typedef struct XML_cp XML_Content;
+
+struct XML_cp {
+ enum XML_Content_Type type;
+ enum XML_Content_Quant quant;
+ XML_Char * name;
+ unsigned int numchildren;
+ XML_Content * children;
+};
+
+
+/* This is called for an element declaration. See above for
+ description of the model argument. It's the caller's responsibility
+ to free model when finished with it.
+*/
+typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData,
+ const XML_Char *name,
+ XML_Content *model);
+
+XMLPARSEAPI(void)
+XML_SetElementDeclHandler(XML_Parser parser,
+ XML_ElementDeclHandler eldecl);
+
+/* The Attlist declaration handler is called for *each* attribute. So
+ a single Attlist declaration with multiple attributes declared will
+ generate multiple calls to this handler. The "default" parameter
+ may be NULL in the case of the "#IMPLIED" or "#REQUIRED"
+ keyword. The "isrequired" parameter will be true and the default
+ value will be NULL in the case of "#REQUIRED". If "isrequired" is
+ true and default is non-NULL, then this is a "#FIXED" default.
+*/
+typedef void (XMLCALL *XML_AttlistDeclHandler) (
+ void *userData,
+ const XML_Char *elname,
+ const XML_Char *attname,
+ const XML_Char *att_type,
+ const XML_Char *dflt,
+ int isrequired);
+
+XMLPARSEAPI(void)
+XML_SetAttlistDeclHandler(XML_Parser parser,
+ XML_AttlistDeclHandler attdecl);
+
+/* The XML declaration handler is called for *both* XML declarations
+ and text declarations. The way to distinguish is that the version
+ parameter will be NULL for text declarations. The encoding
+ parameter may be NULL for XML declarations. The standalone
+ parameter will be -1, 0, or 1 indicating respectively that there
+ was no standalone parameter in the declaration, that it was given
+ as no, or that it was given as yes.
+*/
+typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData,
+ const XML_Char *version,
+ const XML_Char *encoding,
+ int standalone);
+
+XMLPARSEAPI(void)
+XML_SetXmlDeclHandler(XML_Parser parser,
+ XML_XmlDeclHandler xmldecl);
+
+
+typedef struct {
+ void *(*malloc_fcn)(size_t size);
+ void *(*realloc_fcn)(void *ptr, size_t size);
+ void (*free_fcn)(void *ptr);
+} XML_Memory_Handling_Suite;
+
+/* Constructs a new parser; encoding is the encoding specified by the
+ external protocol or NULL if there is none specified.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreate(const XML_Char *encoding);
+
+/* Constructs a new parser and namespace processor. Element type
+ names and attribute names that belong to a namespace will be
+ expanded; unprefixed attribute names are never expanded; unprefixed
+ element type names are expanded only if there is a default
+ namespace. The expanded name is the concatenation of the namespace
+ URI, the namespace separator character, and the local part of the
+ name. If the namespace separator is '\0' then the namespace URI
+ and the local part will be concatenated without any separator.
+ It is a programming error to use the separator '\0' with namespace
+ triplets (see XML_SetReturnNSTriplet).
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
+
+
+/* Constructs a new parser using the memory management suite referred to
+ by memsuite. If memsuite is NULL, then use the standard library memory
+ suite. If namespaceSeparator is non-NULL it creates a parser with
+ namespace processing as described above. The character pointed at
+ will serve as the namespace separator.
+
+ All further memory operations used for the created parser will come from
+ the given suite.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreate_MM(const XML_Char *encoding,
+ const XML_Memory_Handling_Suite *memsuite,
+ const XML_Char *namespaceSeparator);
+
+/* Prepare a parser object to be re-used. This is particularly
+ valuable when memory allocation overhead is disproportionatly high,
+ such as when a large number of small documnents need to be parsed.
+ All handlers are cleared from the parser, except for the
+ unknownEncodingHandler. The parser's external state is re-initialized
+ except for the values of ns and ns_triplets.
+
+ Added in Expat 1.95.3.
+*/
+XMLPARSEAPI(XML_Bool)
+XML_ParserReset(XML_Parser parser, const XML_Char *encoding);
+
+/* atts is array of name/value pairs, terminated by 0;
+ names and values are 0 terminated.
+*/
+typedef void (XMLCALL *XML_StartElementHandler) (void *userData,
+ const XML_Char *name,
+ const XML_Char **atts);
+
+typedef void (XMLCALL *XML_EndElementHandler) (void *userData,
+ const XML_Char *name);
+
+
+/* s is not 0 terminated. */
+typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData,
+ const XML_Char *s,
+ int len);
+
+/* target and data are 0 terminated */
+typedef void (XMLCALL *XML_ProcessingInstructionHandler) (
+ void *userData,
+ const XML_Char *target,
+ const XML_Char *data);
+
+/* data is 0 terminated */
+typedef void (XMLCALL *XML_CommentHandler) (void *userData,
+ const XML_Char *data);
+
+typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData);
+typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData);
+
+/* This is called for any characters in the XML document for which
+ there is no applicable handler. This includes both characters that
+ are part of markup which is of a kind that is not reported
+ (comments, markup declarations), or characters that are part of a
+ construct which could be reported but for which no handler has been
+ supplied. The characters are passed exactly as they were in the XML
+ document except that they will be encoded in UTF-8 or UTF-16.
+ Line boundaries are not normalized. Note that a byte order mark
+ character is not passed to the default handler. There are no
+ guarantees about how characters are divided between calls to the
+ default handler: for example, a comment might be split between
+ multiple calls.
+*/
+typedef void (XMLCALL *XML_DefaultHandler) (void *userData,
+ const XML_Char *s,
+ int len);
+
+/* This is called for the start of the DOCTYPE declaration, before
+ any DTD or internal subset is parsed.
+*/
+typedef void (XMLCALL *XML_StartDoctypeDeclHandler) (
+ void *userData,
+ const XML_Char *doctypeName,
+ const XML_Char *sysid,
+ const XML_Char *pubid,
+ int has_internal_subset);
+
+/* This is called for the start of the DOCTYPE declaration when the
+ closing > is encountered, but after processing any external
+ subset.
+*/
+typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
+
+/* This is called for entity declarations. The is_parameter_entity
+ argument will be non-zero if the entity is a parameter entity, zero
+ otherwise.
+
+ For internal entities (<!ENTITY foo "bar">), value will
+ be non-NULL and systemId, publicID, and notationName will be NULL.
+ The value string is NOT nul-terminated; the length is provided in
+ the value_length argument. Since it is legal to have zero-length
+ values, do not use this argument to test for internal entities.
+
+ For external entities, value will be NULL and systemId will be
+ non-NULL. The publicId argument will be NULL unless a public
+ identifier was provided. The notationName argument will have a
+ non-NULL value only for unparsed entity declarations.
+
+ Note that is_parameter_entity can't be changed to XML_Bool, since
+ that would break binary compatibility.
+*/
+typedef void (XMLCALL *XML_EntityDeclHandler) (
+ void *userData,
+ const XML_Char *entityName,
+ int is_parameter_entity,
+ const XML_Char *value,
+ int value_length,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId,
+ const XML_Char *notationName);
+
+XMLPARSEAPI(void)
+XML_SetEntityDeclHandler(XML_Parser parser,
+ XML_EntityDeclHandler handler);
+
+/* OBSOLETE -- OBSOLETE -- OBSOLETE
+ This handler has been superseded by the EntityDeclHandler above.
+ It is provided here for backward compatibility.
+
+ This is called for a declaration of an unparsed (NDATA) entity.
+ The base argument is whatever was set by XML_SetBase. The
+ entityName, systemId and notationName arguments will never be
+ NULL. The other arguments may be.
+*/
+typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) (
+ void *userData,
+ const XML_Char *entityName,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId,
+ const XML_Char *notationName);
+
+/* This is called for a declaration of notation. The base argument is
+ whatever was set by XML_SetBase. The notationName will never be
+ NULL. The other arguments can be.
+*/
+typedef void (XMLCALL *XML_NotationDeclHandler) (
+ void *userData,
+ const XML_Char *notationName,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId);
+
+/* When namespace processing is enabled, these are called once for
+ each namespace declaration. The call to the start and end element
+ handlers occur between the calls to the start and end namespace
+ declaration handlers. For an xmlns attribute, prefix will be
+ NULL. For an xmlns="" attribute, uri will be NULL.
+*/
+typedef void (XMLCALL *XML_StartNamespaceDeclHandler) (
+ void *userData,
+ const XML_Char *prefix,
+ const XML_Char *uri);
+
+typedef void (XMLCALL *XML_EndNamespaceDeclHandler) (
+ void *userData,
+ const XML_Char *prefix);
+
+/* This is called if the document is not standalone, that is, it has an
+ external subset or a reference to a parameter entity, but does not
+ have standalone="yes". If this handler returns XML_STATUS_ERROR,
+ then processing will not continue, and the parser will return a
+ XML_ERROR_NOT_STANDALONE error.
+ If parameter entity parsing is enabled, then in addition to the
+ conditions above this handler will only be called if the referenced
+ entity was actually read.
+*/
+typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData);
+
+/* This is called for a reference to an external parsed general
+ entity. The referenced entity is not automatically parsed. The
+ application can parse it immediately or later using
+ XML_ExternalEntityParserCreate.
+
+ The parser argument is the parser parsing the entity containing the
+ reference; it can be passed as the parser argument to
+ XML_ExternalEntityParserCreate. The systemId argument is the
+ system identifier as specified in the entity declaration; it will
+ not be NULL.
+
+ The base argument is the system identifier that should be used as
+ the base for resolving systemId if systemId was relative; this is
+ set by XML_SetBase; it may be NULL.
+
+ The publicId argument is the public identifier as specified in the
+ entity declaration, or NULL if none was specified; the whitespace
+ in the public identifier will have been normalized as required by
+ the XML spec.
+
+ The context argument specifies the parsing context in the format
+ expected by the context argument to XML_ExternalEntityParserCreate;
+ context is valid only until the handler returns, so if the
+ referenced entity is to be parsed later, it must be copied.
+ context is NULL only when the entity is a parameter entity.
+
+ The handler should return XML_STATUS_ERROR if processing should not
+ continue because of a fatal error in the handling of the external
+ entity. In this case the calling parser will return an
+ XML_ERROR_EXTERNAL_ENTITY_HANDLING error.
+
+ Note that unlike other handlers the first argument is the parser,
+ not userData.
+*/
+typedef int (XMLCALL *XML_ExternalEntityRefHandler) (
+ XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId);
+
+/* This is called in two situations:
+ 1) An entity reference is encountered for which no declaration
+ has been read *and* this is not an error.
+ 2) An internal entity reference is read, but not expanded, because
+ XML_SetDefaultHandler has been called.
+ Note: skipped parameter entities in declarations and skipped general
+ entities in attribute values cannot be reported, because
+ the event would be out of sync with the reporting of the
+ declarations or attribute values
+*/
+typedef void (XMLCALL *XML_SkippedEntityHandler) (
+ void *userData,
+ const XML_Char *entityName,
+ int is_parameter_entity);
+
+/* This structure is filled in by the XML_UnknownEncodingHandler to
+ provide information to the parser about encodings that are unknown
+ to the parser.
+
+ The map[b] member gives information about byte sequences whose
+ first byte is b.
+
+ If map[b] is c where c is >= 0, then b by itself encodes the
+ Unicode scalar value c.
+
+ If map[b] is -1, then the byte sequence is malformed.
+
+ If map[b] is -n, where n >= 2, then b is the first byte of an
+ n-byte sequence that encodes a single Unicode scalar value.
+
+ The data member will be passed as the first argument to the convert
+ function.
+
+ The convert function is used to convert multibyte sequences; s will
+ point to a n-byte sequence where map[(unsigned char)*s] == -n. The
+ convert function must return the Unicode scalar value represented
+ by this byte sequence or -1 if the byte sequence is malformed.
+
+ The convert function may be NULL if the encoding is a single-byte
+ encoding, that is if map[b] >= -1 for all bytes b.
+
+ When the parser is finished with the encoding, then if release is
+ not NULL, it will call release passing it the data member; once
+ release has been called, the convert function will not be called
+ again.
+
+ Expat places certain restrictions on the encodings that are supported
+ using this mechanism.
+
+ 1. Every ASCII character that can appear in a well-formed XML document,
+ other than the characters
+
+ $@\^`{}~
+
+ must be represented by a single byte, and that byte must be the
+ same byte that represents that character in ASCII.
+
+ 2. No character may require more than 4 bytes to encode.
+
+ 3. All characters encoded must have Unicode scalar values <=
+ 0xFFFF, (i.e., characters that would be encoded by surrogates in
+ UTF-16 are not allowed). Note that this restriction doesn't
+ apply to the built-in support for UTF-8 and UTF-16.
+
+ 4. No Unicode character may be encoded by more than one distinct
+ sequence of bytes.
+*/
+typedef struct {
+ int map[256];
+ void *data;
+ int (XMLCALL *convert)(void *data, const char *s);
+ void (XMLCALL *release)(void *data);
+} XML_Encoding;
+
+/* This is called for an encoding that is unknown to the parser.
+
+ The encodingHandlerData argument is that which was passed as the
+ second argument to XML_SetUnknownEncodingHandler.
+
+ The name argument gives the name of the encoding as specified in
+ the encoding declaration.
+
+ If the callback can provide information about the encoding, it must
+ fill in the XML_Encoding structure, and return XML_STATUS_OK.
+ Otherwise it must return XML_STATUS_ERROR.
+
+ If info does not describe a suitable encoding, then the parser will
+ return an XML_UNKNOWN_ENCODING error.
+*/
+typedef int (XMLCALL *XML_UnknownEncodingHandler) (
+ void *encodingHandlerData,
+ const XML_Char *name,
+ XML_Encoding *info);
+
+XMLPARSEAPI(void)
+XML_SetElementHandler(XML_Parser parser,
+ XML_StartElementHandler start,
+ XML_EndElementHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartElementHandler(XML_Parser parser,
+ XML_StartElementHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetEndElementHandler(XML_Parser parser,
+ XML_EndElementHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetCharacterDataHandler(XML_Parser parser,
+ XML_CharacterDataHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetProcessingInstructionHandler(XML_Parser parser,
+ XML_ProcessingInstructionHandler handler);
+XMLPARSEAPI(void)
+XML_SetCommentHandler(XML_Parser parser,
+ XML_CommentHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetCdataSectionHandler(XML_Parser parser,
+ XML_StartCdataSectionHandler start,
+ XML_EndCdataSectionHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartCdataSectionHandler(XML_Parser parser,
+ XML_StartCdataSectionHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndCdataSectionHandler(XML_Parser parser,
+ XML_EndCdataSectionHandler end);
+
+/* This sets the default handler and also inhibits expansion of
+ internal entities. These entity references will be passed to the
+ default handler, or to the skipped entity handler, if one is set.
+*/
+XMLPARSEAPI(void)
+XML_SetDefaultHandler(XML_Parser parser,
+ XML_DefaultHandler handler);
+
+/* This sets the default handler but does not inhibit expansion of
+ internal entities. The entity reference will not be passed to the
+ default handler.
+*/
+XMLPARSEAPI(void)
+XML_SetDefaultHandlerExpand(XML_Parser parser,
+ XML_DefaultHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetDoctypeDeclHandler(XML_Parser parser,
+ XML_StartDoctypeDeclHandler start,
+ XML_EndDoctypeDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+ XML_StartDoctypeDeclHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndDoctypeDeclHandler(XML_Parser parser,
+ XML_EndDoctypeDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+ XML_UnparsedEntityDeclHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetNotationDeclHandler(XML_Parser parser,
+ XML_NotationDeclHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetNamespaceDeclHandler(XML_Parser parser,
+ XML_StartNamespaceDeclHandler start,
+ XML_EndNamespaceDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+ XML_StartNamespaceDeclHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+ XML_EndNamespaceDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetNotStandaloneHandler(XML_Parser parser,
+ XML_NotStandaloneHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetExternalEntityRefHandler(XML_Parser parser,
+ XML_ExternalEntityRefHandler handler);
+
+/* If a non-NULL value for arg is specified here, then it will be
+ passed as the first argument to the external entity ref handler
+ instead of the parser object.
+*/
+XMLPARSEAPI(void)
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser,
+ void *arg);
+
+XMLPARSEAPI(void)
+XML_SetSkippedEntityHandler(XML_Parser parser,
+ XML_SkippedEntityHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetUnknownEncodingHandler(XML_Parser parser,
+ XML_UnknownEncodingHandler handler,
+ void *encodingHandlerData);
+
+/* This can be called within a handler for a start element, end
+ element, processing instruction or character data. It causes the
+ corresponding markup to be passed to the default handler.
+*/
+XMLPARSEAPI(void)
+XML_DefaultCurrent(XML_Parser parser);
+
+/* If do_nst is non-zero, and namespace processing is in effect, and
+ a name has a prefix (i.e. an explicit namespace qualifier) then
+ that name is returned as a triplet in a single string separated by
+ the separator character specified when the parser was created: URI
+ + sep + local_name + sep + prefix.
+
+ If do_nst is zero, then namespace information is returned in the
+ default manner (URI + sep + local_name) whether or not the name
+ has a prefix.
+
+ Note: Calling XML_SetReturnNSTriplet after XML_Parse or
+ XML_ParseBuffer has no effect.
+*/
+
+XMLPARSEAPI(void)
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst);
+
+/* This value is passed as the userData argument to callbacks. */
+XMLPARSEAPI(void)
+XML_SetUserData(XML_Parser parser, void *userData);
+
+/* Returns the last value set by XML_SetUserData or NULL. */
+#define XML_GetUserData(parser) (*(void **)(parser))
+
+/* This is equivalent to supplying an encoding argument to
+ XML_ParserCreate. On success XML_SetEncoding returns non-zero,
+ zero otherwise.
+ Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer
+ has no effect and returns XML_STATUS_ERROR.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
+
+/* If this function is called, then the parser will be passed as the
+ first argument to callbacks instead of userData. The userData will
+ still be accessible using XML_GetUserData.
+*/
+XMLPARSEAPI(void)
+XML_UseParserAsHandlerArg(XML_Parser parser);
+
+/* If useDTD == XML_TRUE is passed to this function, then the parser
+ will assume that there is an external subset, even if none is
+ specified in the document. In such a case the parser will call the
+ externalEntityRefHandler with a value of NULL for the systemId
+ argument (the publicId and context arguments will be NULL as well).
+ Note: For the purpose of checking WFC: Entity Declared, passing
+ useDTD == XML_TRUE will make the parser behave as if the document
+ had a DTD with an external subset.
+ Note: If this function is called, then this must be done before
+ the first call to XML_Parse or XML_ParseBuffer, since it will
+ have no effect after that. Returns
+ XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.
+ Note: If the document does not have a DOCTYPE declaration at all,
+ then startDoctypeDeclHandler and endDoctypeDeclHandler will not
+ be called, despite an external subset being parsed.
+ Note: If XML_DTD is not defined when Expat is compiled, returns
+ XML_ERROR_FEATURE_REQUIRES_XML_DTD.
+*/
+XMLPARSEAPI(enum XML_Error)
+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
+
+
+/* Sets the base to be used for resolving relative URIs in system
+ identifiers in declarations. Resolving relative identifiers is
+ left to the application: this value will be passed through as the
+ base argument to the XML_ExternalEntityRefHandler,
+ XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base
+ argument will be copied. Returns XML_STATUS_ERROR if out of memory,
+ XML_STATUS_OK otherwise.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_SetBase(XML_Parser parser, const XML_Char *base);
+
+XMLPARSEAPI(const XML_Char *)
+XML_GetBase(XML_Parser parser);
+
+/* Returns the number of the attribute/value pairs passed in last call
+ to the XML_StartElementHandler that were specified in the start-tag
+ rather than defaulted. Each attribute/value pair counts as 2; thus
+ this correspondds to an index into the atts array passed to the
+ XML_StartElementHandler.
+*/
+XMLPARSEAPI(int)
+XML_GetSpecifiedAttributeCount(XML_Parser parser);
+
+/* Returns the index of the ID attribute passed in the last call to
+ XML_StartElementHandler, or -1 if there is no ID attribute. Each
+ attribute/value pair counts as 2; thus this correspondds to an
+ index into the atts array passed to the XML_StartElementHandler.
+*/
+XMLPARSEAPI(int)
+XML_GetIdAttributeIndex(XML_Parser parser);
+
+/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is
+ detected. The last call to XML_Parse must have isFinal true; len
+ may be zero for this call (or any other).
+
+ Though the return values for these functions has always been
+ described as a Boolean value, the implementation, at least for the
+ 1.95.x series, has always returned exactly one of the XML_Status
+ values.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
+
+XMLPARSEAPI(void *)
+XML_GetBuffer(XML_Parser parser, int len);
+
+XMLPARSEAPI(enum XML_Status)
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
+
+/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return.
+ Must be called from within a call-back handler, except when aborting
+ (resumable = 0) an already suspended parser. Some call-backs may
+ still follow because they would otherwise get lost. Examples:
+ - endElementHandler() for empty elements when stopped in
+ startElementHandler(),
+ - endNameSpaceDeclHandler() when stopped in endElementHandler(),
+ and possibly others.
+
+ Can be called from most handlers, including DTD related call-backs,
+ except when parsing an external parameter entity and resumable != 0.
+ Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise.
+ Possible error codes:
+ - XML_ERROR_SUSPENDED: when suspending an already suspended parser.
+ - XML_ERROR_FINISHED: when the parser has already finished.
+ - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE.
+
+ When resumable != 0 (true) then parsing is suspended, that is,
+ XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED.
+ Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer()
+ return XML_STATUS_ERROR with error code XML_ERROR_ABORTED.
+
+ *Note*:
+ This will be applied to the current parser instance only, that is, if
+ there is a parent parser then it will continue parsing when the
+ externalEntityRefHandler() returns. It is up to the implementation of
+ the externalEntityRefHandler() to call XML_StopParser() on the parent
+ parser (recursively), if one wants to stop parsing altogether.
+
+ When suspended, parsing can be resumed by calling XML_ResumeParser().
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_StopParser(XML_Parser parser, XML_Bool resumable);
+
+/* Resumes parsing after it has been suspended with XML_StopParser().
+ Must not be called from within a handler call-back. Returns same
+ status codes as XML_Parse() or XML_ParseBuffer().
+ Additional error code XML_ERROR_NOT_SUSPENDED possible.
+
+ *Note*:
+ This must be called on the most deeply nested child parser instance
+ first, and on its parent parser only after the child parser has finished,
+ to be applied recursively until the document entity's parser is restarted.
+ That is, the parent parser will not resume by itself and it is up to the
+ application to call XML_ResumeParser() on it at the appropriate moment.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_ResumeParser(XML_Parser parser);
+
+enum XML_Parsing {
+ XML_INITIALIZED,
+ XML_PARSING,
+ XML_FINISHED,
+ XML_SUSPENDED
+};
+
+typedef struct {
+ enum XML_Parsing parsing;
+ XML_Bool finalBuffer;
+} XML_ParsingStatus;
+
+/* Returns status of parser with respect to being initialized, parsing,
+ finished, or suspended and processing the final buffer.
+ XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus,
+ XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED
+*/
+XMLPARSEAPI(void)
+XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status);
+
+/* Creates an XML_Parser object that can parse an external general
+ entity; context is a '\0'-terminated string specifying the parse
+ context; encoding is a '\0'-terminated string giving the name of
+ the externally specified encoding, or NULL if there is no
+ externally specified encoding. The context string consists of a
+ sequence of tokens separated by formfeeds (\f); a token consisting
+ of a name specifies that the general entity of the name is open; a
+ token of the form prefix=uri specifies the namespace for a
+ particular prefix; a token of the form =uri specifies the default
+ namespace. This can be called at any point after the first call to
+ an ExternalEntityRefHandler so longer as the parser has not yet
+ been freed. The new parser is completely independent and may
+ safely be used in a separate thread. The handlers and userData are
+ initialized from the parser argument. Returns NULL if out of memory.
+ Otherwise returns a new XML_Parser object.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ExternalEntityParserCreate(XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *encoding);
+
+enum XML_ParamEntityParsing {
+ XML_PARAM_ENTITY_PARSING_NEVER,
+ XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
+ XML_PARAM_ENTITY_PARSING_ALWAYS
+};
+
+/* Controls parsing of parameter entities (including the external DTD
+ subset). If parsing of parameter entities is enabled, then
+ references to external parameter entities (including the external
+ DTD subset) will be passed to the handler set with
+ XML_SetExternalEntityRefHandler. The context passed will be 0.
+
+ Unlike external general entities, external parameter entities can
+ only be parsed synchronously. If the external parameter entity is
+ to be parsed, it must be parsed during the call to the external
+ entity ref handler: the complete sequence of
+ XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and
+ XML_ParserFree calls must be made during this call. After
+ XML_ExternalEntityParserCreate has been called to create the parser
+ for the external parameter entity (context must be 0 for this
+ call), it is illegal to make any calls on the old parser until
+ XML_ParserFree has been called on the newly created parser.
+ If the library has been compiled without support for parameter
+ entity parsing (ie without XML_DTD being defined), then
+ XML_SetParamEntityParsing will return 0 if parsing of parameter
+ entities is requested; otherwise it will return non-zero.
+ Note: If XML_SetParamEntityParsing is called after XML_Parse or
+ XML_ParseBuffer, then it has no effect and will always return 0.
+*/
+XMLPARSEAPI(int)
+XML_SetParamEntityParsing(XML_Parser parser,
+ enum XML_ParamEntityParsing parsing);
+
+/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
+ XML_GetErrorCode returns information about the error.
+*/
+XMLPARSEAPI(enum XML_Error)
+XML_GetErrorCode(XML_Parser parser);
+
+/* These functions return information about the current parse
+ location. They may be called from any callback called to report
+ some parse event; in this case the location is the location of the
+ first of the sequence of characters that generated the event. When
+ called from callbacks generated by declarations in the document
+ prologue, the location identified isn't as neatly defined, but will
+ be within the relevant markup. When called outside of the callback
+ functions, the position indicated will be just past the last parse
+ event (regardless of whether there was an associated callback).
+
+ They may also be called after returning from a call to XML_Parse
+ or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then
+ the location is the location of the character at which the error
+ was detected; otherwise the location is the location of the last
+ parse event, as described above.
+*/
+XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
+XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
+XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser);
+
+/* Return the number of bytes in the current event.
+ Returns 0 if the event is in an internal entity.
+*/
+XMLPARSEAPI(int)
+XML_GetCurrentByteCount(XML_Parser parser);
+
+/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets
+ the integer pointed to by offset to the offset within this buffer
+ of the current parse position, and sets the integer pointed to by size
+ to the size of this buffer (the number of input bytes). Otherwise
+ returns a NULL pointer. Also returns a NULL pointer if a parse isn't
+ active.
+
+ NOTE: The character pointer returned should not be used outside
+ the handler that makes the call.
+*/
+XMLPARSEAPI(const char *)
+XML_GetInputContext(XML_Parser parser,
+ int *offset,
+ int *size);
+
+/* For backwards compatibility with previous versions. */
+#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
+#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
+#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
+
+/* Frees the content model passed to the element declaration handler */
+XMLPARSEAPI(void)
+XML_FreeContentModel(XML_Parser parser, XML_Content *model);
+
+/* Exposing the memory handling functions used in Expat */
+XMLPARSEAPI(void *)
+XML_MemMalloc(XML_Parser parser, size_t size);
+
+XMLPARSEAPI(void *)
+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);
+
+XMLPARSEAPI(void)
+XML_MemFree(XML_Parser parser, void *ptr);
+
+/* Frees memory used by the parser. */
+XMLPARSEAPI(void)
+XML_ParserFree(XML_Parser parser);
+
+/* Returns a string describing the error. */
+XMLPARSEAPI(const XML_LChar *)
+XML_ErrorString(enum XML_Error code);
+
+/* Return a string containing the version number of this expat */
+XMLPARSEAPI(const XML_LChar *)
+XML_ExpatVersion(void);
+
+typedef struct {
+ int major;
+ int minor;
+ int micro;
+} XML_Expat_Version;
+
+/* Return an XML_Expat_Version structure containing numeric version
+ number information for this version of expat.
+*/
+XMLPARSEAPI(XML_Expat_Version)
+XML_ExpatVersionInfo(void);
+
+/* Added in Expat 1.95.5. */
+enum XML_FeatureEnum {
+ XML_FEATURE_END = 0,
+ XML_FEATURE_UNICODE,
+ XML_FEATURE_UNICODE_WCHAR_T,
+ XML_FEATURE_DTD,
+ XML_FEATURE_CONTEXT_BYTES,
+ XML_FEATURE_MIN_SIZE,
+ XML_FEATURE_SIZEOF_XML_CHAR,
+ XML_FEATURE_SIZEOF_XML_LCHAR,
+ XML_FEATURE_NS
+ /* Additional features must be added to the end of this enum. */
+};
+
+typedef struct {
+ enum XML_FeatureEnum feature;
+ const XML_LChar *name;
+ long int value;
+} XML_Feature;
+
+XMLPARSEAPI(const XML_Feature *)
+XML_GetFeatureList(void);
+
+
+/* Expat follows the GNU/Linux convention of odd number minor version for
+ beta/development releases and even number minor version for stable
+ releases. Micro is bumped with each release, and set to 0 with each
+ change to major or minor version.
+*/
+#define XML_MAJOR_VERSION 2
+#define XML_MINOR_VERSION 0
+#define XML_MICRO_VERSION 0
+
+/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
+XMLPARSEAPI(const XML_Char*)
+MOZ_XML_GetMismatchedTag(XML_Parser parser);
+/* END MOZILLA CHANGE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not Expat_INCLUDED */
diff --git a/parser/expat/lib/expat_external.h b/parser/expat/lib/expat_external.h
new file mode 100644
index 000000000..70c630bc9
--- /dev/null
+++ b/parser/expat/lib/expat_external.h
@@ -0,0 +1,121 @@
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#ifndef Expat_External_INCLUDED
+#define Expat_External_INCLUDED 1
+
+/* External API definitions */
+
+#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
+#define XML_USE_MSC_EXTENSIONS 1
+#endif
+
+/* Expat tries very hard to make the API boundary very specifically
+ defined. There are two macros defined to control this boundary;
+ each of these can be defined before including this header to
+ achieve some different behavior, but doing so it not recommended or
+ tested frequently.
+
+ XMLCALL - The calling convention to use for all calls across the
+ "library boundary." This will default to cdecl, and
+ try really hard to tell the compiler that's what we
+ want.
+
+ XMLIMPORT - Whatever magic is needed to note that a function is
+ to be imported from a dynamically loaded library
+ (.dll, .so, or .sl, depending on your platform).
+
+ The XMLCALL macro was added in Expat 1.95.7. The only one which is
+ expected to be directly useful in client code is XMLCALL.
+
+ Note that on at least some Unix versions, the Expat library must be
+ compiled with the cdecl calling convention as the default since
+ system headers may assume the cdecl convention.
+*/
+#ifndef XMLCALL
+#if defined(XML_USE_MSC_EXTENSIONS)
+#define XMLCALL __cdecl
+#elif defined(__GNUC__) && defined(__i386)
+#define XMLCALL __attribute__((cdecl))
+#else
+/* For any platform which uses this definition and supports more than
+ one calling convention, we need to extend this definition to
+ declare the convention used on that platform, if it's possible to
+ do so.
+
+ If this is the case for your platform, please file a bug report
+ with information on how to identify your platform via the C
+ pre-processor and how to specify the same calling convention as the
+ platform's malloc() implementation.
+*/
+#define XMLCALL
+#endif
+#endif /* not defined XMLCALL */
+
+
+#if !defined(XML_STATIC) && !defined(XMLIMPORT)
+#ifndef XML_BUILDING_EXPAT
+/* using Expat from an application */
+
+#ifdef XML_USE_MSC_EXTENSIONS
+#define XMLIMPORT __declspec(dllimport)
+#endif
+
+#endif
+#endif /* not defined XML_STATIC */
+
+
+/* If we didn't define it above, define it away: */
+#ifndef XMLIMPORT
+#define XMLIMPORT
+#endif
+
+
+#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef XML_UNICODE_WCHAR_T
+#define XML_UNICODE
+#endif
+
+/* BEGIN MOZILLA CHANGE (typedef XML_Char to char16_t) */
+#if 0
+
+#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
+#ifdef XML_UNICODE_WCHAR_T
+typedef wchar_t XML_Char;
+typedef wchar_t XML_LChar;
+#else
+typedef unsigned short XML_Char;
+typedef char XML_LChar;
+#endif /* XML_UNICODE_WCHAR_T */
+#else /* Information is UTF-8 encoded. */
+typedef char XML_Char;
+typedef char XML_LChar;
+#endif /* XML_UNICODE */
+
+#endif
+/* END MOZILLA CHANGE */
+
+#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
+#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
+typedef __int64 XML_Index;
+typedef unsigned __int64 XML_Size;
+#else
+typedef long long XML_Index;
+typedef unsigned long long XML_Size;
+#endif
+#else
+typedef long XML_Index;
+typedef unsigned long XML_Size;
+#endif /* XML_LARGE_SIZE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not Expat_External_INCLUDED */
diff --git a/parser/expat/lib/iasciitab.h b/parser/expat/lib/iasciitab.h
new file mode 100644
index 000000000..24a1d5ccc
--- /dev/null
+++ b/parser/expat/lib/iasciitab.h
@@ -0,0 +1,37 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
+/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
+/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/parser/expat/lib/internal.h b/parser/expat/lib/internal.h
new file mode 100644
index 000000000..19351814b
--- /dev/null
+++ b/parser/expat/lib/internal.h
@@ -0,0 +1,73 @@
+/* internal.h
+
+ Internal definitions used by Expat. This is not needed to compile
+ client code.
+
+ The following calling convention macros are defined for frequently
+ called functions:
+
+ FASTCALL - Used for those internal functions that have a simple
+ body and a low number of arguments and local variables.
+
+ PTRCALL - Used for functions called though function pointers.
+
+ PTRFASTCALL - Like PTRCALL, but for low number of arguments.
+
+ inline - Used for selected internal functions for which inlining
+ may improve performance on some platforms.
+
+ Note: Use of these macros is based on judgment, not hard rules,
+ and therefore subject to change.
+*/
+
+#if defined(__GNUC__) && defined(__i386__)
+/* We'll use this version by default only where we know it helps.
+
+ regparm() generates warnings on Solaris boxes. See SF bug #692878.
+
+ Instability reported with egcs on a RedHat Linux 7.3.
+ Let's comment out:
+ #define FASTCALL __attribute__((stdcall, regparm(3)))
+ and let's try this:
+*/
+#define FASTCALL __attribute__((regparm(3)))
+#define PTRFASTCALL __attribute__((regparm(3)))
+#endif
+
+/* Using __fastcall seems to have an unexpected negative effect under
+ MS VC++, especially for function pointers, so we won't use it for
+ now on that platform. It may be reconsidered for a future release
+ if it can be made more effective.
+ Likely reason: __fastcall on Windows is like stdcall, therefore
+ the compiler cannot perform stack optimizations for call clusters.
+*/
+
+/* Make sure all of these are defined if they aren't already. */
+
+#ifndef FASTCALL
+#define FASTCALL
+#endif
+
+#ifndef PTRCALL
+#define PTRCALL
+#endif
+
+#ifndef PTRFASTCALL
+#define PTRFASTCALL
+#endif
+
+#ifndef XML_MIN_SIZE
+#if !defined(__cplusplus) && !defined(inline)
+#ifdef __GNUC__
+#define inline __inline
+#endif /* __GNUC__ */
+#endif
+#endif /* XML_MIN_SIZE */
+
+#ifdef __cplusplus
+#define inline inline
+#else
+#ifndef inline
+#define inline
+#endif
+#endif
diff --git a/parser/expat/lib/latin1tab.h b/parser/expat/lib/latin1tab.h
new file mode 100644
index 000000000..53c25d76b
--- /dev/null
+++ b/parser/expat/lib/latin1tab.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
+/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
diff --git a/parser/expat/lib/moz.build b/parser/expat/lib/moz.build
new file mode 100644
index 000000000..15b3b3c73
--- /dev/null
+++ b/parser/expat/lib/moz.build
@@ -0,0 +1,20 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+EXPORTS += [
+ 'expat.h',
+ 'expat_external.h',
+]
+
+SOURCES += [
+ 'xmlparse.c',
+ 'xmlrole.c',
+ 'xmltok.c',
+]
+
+FINAL_LIBRARY = 'gkmedias'
+
+DEFINES['HAVE_EXPAT_CONFIG_H'] = True
diff --git a/parser/expat/lib/moz_extensions.c b/parser/expat/lib/moz_extensions.c
new file mode 100644
index 000000000..37b9e7f71
--- /dev/null
+++ b/parser/expat/lib/moz_extensions.c
@@ -0,0 +1,160 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifdef IS_LITTLE_ENDIAN
+
+#define PREFIX(ident) little2_ ## ident
+#define BYTE_TYPE(p) LITTLE2_BYTE_TYPE(XmlGetUtf16InternalEncodingNS(), p)
+#define IS_NAME_CHAR_MINBPC(p) LITTLE2_IS_NAME_CHAR_MINBPC(0, p)
+#define IS_NMSTRT_CHAR_MINBPC(p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(0, p)
+
+#else
+
+#define PREFIX(ident) big2_ ## ident
+#define BYTE_TYPE(p) BIG2_BYTE_TYPE(XmlGetUtf16InternalEncodingNS(), p)
+#define IS_NAME_CHAR_MINBPC(p) BIG2_IS_NAME_CHAR_MINBPC(0, p)
+#define IS_NMSTRT_CHAR_MINBPC(p) BIG2_IS_NMSTRT_CHAR_MINBPC(0, p)
+
+#endif
+
+#define MOZ_EXPAT_VALID_QNAME (0)
+#define MOZ_EXPAT_EMPTY_QNAME (1 << 0)
+#define MOZ_EXPAT_INVALID_CHARACTER (1 << 1)
+#define MOZ_EXPAT_MALFORMED (1 << 2)
+
+int MOZ_XMLCheckQName(const char* ptr, const char* end, int ns_aware,
+ const char** colon)
+{
+ int result = MOZ_EXPAT_VALID_QNAME;
+ int nmstrt = 1;
+ *colon = 0;
+ if (ptr == end) {
+ return MOZ_EXPAT_EMPTY_QNAME;
+ }
+ do {
+ switch (BYTE_TYPE(ptr)) {
+ case BT_COLON:
+ /* We're namespace-aware and either first or last character is a colon
+ or we've already seen a colon. */
+ if (ns_aware && (nmstrt || *colon || ptr + 2 == end)) {
+ return MOZ_EXPAT_MALFORMED;
+ }
+ *colon = ptr;
+ nmstrt = ns_aware; /* e.g. "a:0" should be valid if !ns_aware */
+ break;
+ case BT_NONASCII:
+ if (!IS_NAME_CHAR_MINBPC(ptr) ||
+ (nmstrt && !*colon && !IS_NMSTRT_CHAR_MINBPC(ptr))) {
+ return MOZ_EXPAT_INVALID_CHARACTER;
+ }
+ if (nmstrt && *colon && !IS_NMSTRT_CHAR_MINBPC(ptr)) {
+ /* If a non-starting character like a number is right after the colon,
+ this is a namespace error, not invalid character */
+ return MOZ_EXPAT_MALFORMED;
+ }
+ nmstrt = 0;
+ break;
+ case BT_NMSTRT:
+ case BT_HEX:
+ nmstrt = 0;
+ break;
+ case BT_DIGIT:
+ case BT_NAME:
+ case BT_MINUS:
+ if (nmstrt) {
+ return MOZ_EXPAT_INVALID_CHARACTER;
+ }
+ break;
+ default:
+ return MOZ_EXPAT_INVALID_CHARACTER;
+ }
+ ptr += 2;
+ } while (ptr != end);
+ return result;
+}
+
+int MOZ_XMLIsLetter(const char* ptr)
+{
+ switch (BYTE_TYPE(ptr)) {
+ case BT_NONASCII:
+ if (!IS_NMSTRT_CHAR_MINBPC(ptr)) {
+ return 0;
+ }
+ /* fall through */
+ case BT_NMSTRT:
+ case BT_HEX:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+int MOZ_XMLIsNCNameChar(const char* ptr)
+{
+ switch (BYTE_TYPE(ptr)) {
+ case BT_NONASCII:
+ if (!IS_NAME_CHAR_MINBPC(ptr)) {
+ return 0;
+ }
+ /* fall through */
+ case BT_NMSTRT:
+ case BT_HEX:
+ case BT_DIGIT:
+ case BT_NAME:
+ case BT_MINUS:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+int MOZ_XMLTranslateEntity(const char* ptr, const char* end, const char** next,
+ XML_Char* result)
+{
+ // Can we assert here somehow?
+ // MOZ_ASSERT(*ptr == '&');
+
+ const ENCODING* enc = XmlGetUtf16InternalEncodingNS();
+ /* scanRef expects to be pointed to the char after the '&'. */
+ int tok = PREFIX(scanRef)(enc, ptr + enc->minBytesPerChar, end, next);
+ if (tok <= XML_TOK_INVALID) {
+ return 0;
+ }
+
+ if (tok == XML_TOK_CHAR_REF) {
+ /* XmlCharRefNumber expects to be pointed to the '&'. */
+ int n = XmlCharRefNumber(enc, ptr);
+
+ /* We could get away with just < 0, but better safe than sorry. */
+ if (n <= 0) {
+ return 0;
+ }
+
+ return XmlUtf16Encode(n, (unsigned short*)result);
+ }
+
+ if (tok == XML_TOK_ENTITY_REF) {
+ /* XmlPredefinedEntityName expects to be pointed to the char after '&'.
+
+ *next points to after the semicolon, so the entity ends at
+ *next - enc->minBytesPerChar. */
+ XML_Char ch =
+ (XML_Char)XmlPredefinedEntityName(enc, ptr + enc->minBytesPerChar,
+ *next - enc->minBytesPerChar);
+ if (!ch) {
+ return 0;
+ }
+
+ *result = ch;
+ return 1;
+ }
+
+ return 0;
+}
+
+#undef PREFIX
+#undef BYTE_TYPE
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR_MINBPC
diff --git a/parser/expat/lib/nametab.h b/parser/expat/lib/nametab.h
new file mode 100644
index 000000000..b05e62c77
--- /dev/null
+++ b/parser/expat/lib/nametab.h
@@ -0,0 +1,150 @@
+static const unsigned namingBitmap[] = {
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
+0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
+0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
+0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
+0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
+0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
+0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
+0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
+0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
+0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
+0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
+0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
+0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
+0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
+0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
+0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
+0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
+0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
+0x40000000, 0xF580C900, 0x00000007, 0x02010800,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
+0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
+0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
+0x00000000, 0x00004C40, 0x00000000, 0x00000000,
+0x00000007, 0x00000000, 0x00000000, 0x00000000,
+0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
+0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
+0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
+0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
+0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
+0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
+0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
+0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
+0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
+0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
+0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
+0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
+0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
+0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
+0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
+0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
+0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
+0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
+0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
+0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
+0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
+0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
+0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
+};
+static const unsigned char nmstrtPages[] = {
+0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
+0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static const unsigned char namePages[] = {
+0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
+0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
+0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/parser/expat/lib/utf8tab.h b/parser/expat/lib/utf8tab.h
new file mode 100644
index 000000000..7bb3e7760
--- /dev/null
+++ b/parser/expat/lib/utf8tab.h
@@ -0,0 +1,37 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+
+/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
+/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
diff --git a/parser/expat/lib/xmlparse.c b/parser/expat/lib/xmlparse.c
new file mode 100644
index 000000000..93a817764
--- /dev/null
+++ b/parser/expat/lib/xmlparse.c
@@ -0,0 +1,6512 @@
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#include <stddef.h>
+#include <string.h> /* memset(), memcpy() */
+#include <assert.h>
+
+#define XML_BUILDING_EXPAT 1
+
+#ifdef COMPILED_FROM_DSP
+#include "winconfig.h"
+#elif defined(MACOS_CLASSIC)
+#include "macconfig.h"
+#elif defined(__amigaos4__)
+#include "amigaconfig.h"
+#elif defined(HAVE_EXPAT_CONFIG_H)
+#include <expat_config.h>
+#endif /* ndef COMPILED_FROM_DSP */
+
+#include "expat.h"
+
+#ifdef XML_UNICODE
+#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
+#define XmlConvert XmlUtf16Convert
+#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
+#define XmlEncode XmlUtf16Encode
+
+/* Using pointer subtraction to convert to integer type. */
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
+typedef unsigned short ICHAR;
+#else
+#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
+#define XmlConvert XmlUtf8Convert
+#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
+#define XmlEncode XmlUtf8Encode
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
+typedef char ICHAR;
+#endif
+
+
+#ifndef XML_NS
+
+#define XmlInitEncodingNS XmlInitEncoding
+#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
+#undef XmlGetInternalEncodingNS
+#define XmlGetInternalEncodingNS XmlGetInternalEncoding
+#define XmlParseXmlDeclNS XmlParseXmlDecl
+
+#endif
+
+/* BEGIN MOZILLA CHANGE (typedef XML_Char to char16_t) */
+#if 0
+
+#ifdef XML_UNICODE
+
+#ifdef XML_UNICODE_WCHAR_T
+#define XML_T(x) (const wchar_t)x
+#define XML_L(x) L ## x
+#else
+#define XML_T(x) (const unsigned short)x
+#define XML_L(x) x
+#endif
+
+#else
+
+#define XML_T(x) x
+#define XML_L(x) x
+
+#endif
+
+#endif
+/* END MOZILLA CHANGE */
+
+/* Round up n to be a multiple of sz, where sz is a power of 2. */
+#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
+
+/* Handle the case where memmove() doesn't exist. */
+#ifndef HAVE_MEMMOVE
+#ifdef HAVE_BCOPY
+#define memmove(d,s,l) bcopy((s),(d),(l))
+#else
+#error memmove does not exist on this platform, nor is a substitute available
+#endif /* HAVE_BCOPY */
+#endif /* HAVE_MEMMOVE */
+
+#include "internal.h"
+#include "xmltok.h"
+#include "xmlrole.h"
+
+typedef const XML_Char *KEY;
+
+typedef struct {
+ KEY name;
+} NAMED;
+
+typedef struct {
+ NAMED **v;
+ unsigned char power;
+ size_t size;
+ size_t used;
+ const XML_Memory_Handling_Suite *mem;
+} HASH_TABLE;
+
+/* Basic character hash algorithm, taken from Python's string hash:
+ h = h * 1000003 ^ character, the constant being a prime number.
+
+*/
+#ifdef XML_UNICODE
+#define CHAR_HASH(h, c) \
+ (((h) * 0xF4243) ^ (unsigned short)(c))
+#else
+#define CHAR_HASH(h, c) \
+ (((h) * 0xF4243) ^ (unsigned char)(c))
+#endif
+
+/* For probing (after a collision) we need a step size relative prime
+ to the hash table size, which is a power of 2. We use double-hashing,
+ since we can calculate a second hash value cheaply by taking those bits
+ of the first hash value that were discarded (masked out) when the table
+ index was calculated: index = hash & mask, where mask = table->size - 1.
+ We limit the maximum step size to table->size / 4 (mask >> 2) and make
+ it odd, since odd numbers are always relative prime to a power of 2.
+*/
+#define SECOND_HASH(hash, mask, power) \
+ ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
+#define PROBE_STEP(hash, mask, power) \
+ ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
+
+typedef struct {
+ NAMED **p;
+ NAMED **end;
+} HASH_TABLE_ITER;
+
+#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
+#define INIT_DATA_BUF_SIZE 1024
+#define INIT_ATTS_SIZE 16
+#define INIT_ATTS_VERSION 0xFFFFFFFF
+/* BEGIN MOZILLA CHANGE (Avoid slop in poolGrow() allocations) */
+#define INIT_BLOCK_SIZE ((int)(1024 - (offsetof(BLOCK, s) / sizeof(XML_Char))))
+/* END MOZILLA CHANGE */
+#define INIT_BUFFER_SIZE 1024
+
+#define EXPAND_SPARE 24
+
+typedef struct binding {
+ struct prefix *prefix;
+ struct binding *nextTagBinding;
+ struct binding *prevPrefixBinding;
+ const struct attribute_id *attId;
+ XML_Char *uri;
+ int uriLen;
+ int uriAlloc;
+} BINDING;
+
+typedef struct prefix {
+ const XML_Char *name;
+ BINDING *binding;
+} PREFIX;
+
+typedef struct {
+ const XML_Char *str;
+ const XML_Char *localPart;
+ const XML_Char *prefix;
+ int strLen;
+ int uriLen;
+ int prefixLen;
+} TAG_NAME;
+
+/* TAG represents an open element.
+ The name of the element is stored in both the document and API
+ encodings. The memory buffer 'buf' is a separately-allocated
+ memory area which stores the name. During the XML_Parse()/
+ XMLParseBuffer() when the element is open, the memory for the 'raw'
+ version of the name (in the document encoding) is shared with the
+ document buffer. If the element is open across calls to
+ XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
+ contain the 'raw' name as well.
+
+ A parser re-uses these structures, maintaining a list of allocated
+ TAG objects in a free list.
+*/
+typedef struct tag {
+ struct tag *parent; /* parent of this element */
+ const char *rawName; /* tagName in the original encoding */
+ int rawNameLength;
+ TAG_NAME name; /* tagName in the API encoding */
+ char *buf; /* buffer for name components */
+ char *bufEnd; /* end of the buffer */
+ BINDING *bindings;
+} TAG;
+
+typedef struct {
+ const XML_Char *name;
+ const XML_Char *textPtr;
+ int textLen; /* length in XML_Chars */
+ int processed; /* # of processed bytes - when suspended */
+ const XML_Char *systemId;
+ const XML_Char *base;
+ const XML_Char *publicId;
+ const XML_Char *notation;
+ XML_Bool open;
+ XML_Bool is_param;
+ XML_Bool is_internal; /* true if declared in internal subset outside PE */
+} ENTITY;
+
+typedef struct {
+ enum XML_Content_Type type;
+ enum XML_Content_Quant quant;
+ const XML_Char * name;
+ int firstchild;
+ int lastchild;
+ int childcnt;
+ int nextsib;
+} CONTENT_SCAFFOLD;
+
+#define INIT_SCAFFOLD_ELEMENTS 32
+
+typedef struct block {
+ struct block *next;
+ int size;
+ XML_Char s[1];
+} BLOCK;
+
+typedef struct {
+ BLOCK *blocks;
+ BLOCK *freeBlocks;
+ const XML_Char *end;
+ XML_Char *ptr;
+ XML_Char *start;
+ const XML_Memory_Handling_Suite *mem;
+} STRING_POOL;
+
+/* The XML_Char before the name is used to determine whether
+ an attribute has been specified. */
+typedef struct attribute_id {
+ XML_Char *name;
+ PREFIX *prefix;
+ XML_Bool maybeTokenized;
+ XML_Bool xmlns;
+} ATTRIBUTE_ID;
+
+typedef struct {
+ const ATTRIBUTE_ID *id;
+ XML_Bool isCdata;
+ const XML_Char *value;
+} DEFAULT_ATTRIBUTE;
+
+typedef struct {
+ unsigned long version;
+ unsigned long hash;
+ const XML_Char *uriName;
+} NS_ATT;
+
+typedef struct {
+ const XML_Char *name;
+ PREFIX *prefix;
+ const ATTRIBUTE_ID *idAtt;
+ int nDefaultAtts;
+ int allocDefaultAtts;
+ DEFAULT_ATTRIBUTE *defaultAtts;
+} ELEMENT_TYPE;
+
+typedef struct {
+ HASH_TABLE generalEntities;
+ HASH_TABLE elementTypes;
+ HASH_TABLE attributeIds;
+ HASH_TABLE prefixes;
+ STRING_POOL pool;
+ STRING_POOL entityValuePool;
+ /* false once a parameter entity reference has been skipped */
+ XML_Bool keepProcessing;
+ /* true once an internal or external PE reference has been encountered;
+ this includes the reference to an external subset */
+ XML_Bool hasParamEntityRefs;
+ XML_Bool standalone;
+#ifdef XML_DTD
+ /* indicates if external PE has been read */
+ XML_Bool paramEntityRead;
+ HASH_TABLE paramEntities;
+#endif /* XML_DTD */
+ PREFIX defaultPrefix;
+ /* === scaffolding for building content model === */
+ XML_Bool in_eldecl;
+ CONTENT_SCAFFOLD *scaffold;
+ unsigned contentStringLen;
+ unsigned scaffSize;
+ unsigned scaffCount;
+ int scaffLevel;
+ int *scaffIndex;
+} DTD;
+
+typedef struct open_internal_entity {
+ const char *internalEventPtr;
+ const char *internalEventEndPtr;
+ struct open_internal_entity *next;
+ ENTITY *entity;
+ int startTagLevel;
+ XML_Bool betweenDecl; /* WFC: PE Between Declarations */
+} OPEN_INTERNAL_ENTITY;
+
+typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr);
+
+static Processor prologProcessor;
+static Processor prologInitProcessor;
+static Processor contentProcessor;
+static Processor cdataSectionProcessor;
+#ifdef XML_DTD
+static Processor ignoreSectionProcessor;
+static Processor externalParEntProcessor;
+static Processor externalParEntInitProcessor;
+static Processor entityValueProcessor;
+static Processor entityValueInitProcessor;
+#endif /* XML_DTD */
+static Processor epilogProcessor;
+static Processor errorProcessor;
+static Processor externalEntityInitProcessor;
+static Processor externalEntityInitProcessor2;
+static Processor externalEntityInitProcessor3;
+static Processor externalEntityContentProcessor;
+static Processor internalEntityProcessor;
+
+static enum XML_Error
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
+static enum XML_Error
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
+ const char *s, const char *next);
+static enum XML_Error
+initializeEncoding(XML_Parser parser);
+static enum XML_Error
+doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
+ const char *end, int tok, const char *next, const char **nextPtr,
+ XML_Bool haveMore);
+static enum XML_Error
+processInternalEntity(XML_Parser parser, ENTITY *entity,
+ XML_Bool betweenDecl);
+static enum XML_Error
+doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
+ const char *start, const char *end, const char **endPtr,
+ XML_Bool haveMore);
+static enum XML_Error
+doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
+ const char *end, const char **nextPtr, XML_Bool haveMore);
+#ifdef XML_DTD
+static enum XML_Error
+doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
+ const char *end, const char **nextPtr, XML_Bool haveMore);
+#endif /* XML_DTD */
+
+static enum XML_Error
+storeAtts(XML_Parser parser, const ENCODING *, const char *s,
+ TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
+static enum XML_Error
+addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
+ const XML_Char *uri, BINDING **bindingsPtr);
+static int
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
+ XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
+static enum XML_Error
+storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
+ const char *, const char *, STRING_POOL *);
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
+ const char *, const char *, STRING_POOL *);
+static ATTRIBUTE_ID *
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
+ const char *end);
+static int
+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
+static enum XML_Error
+storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
+ const char *end);
+static int
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
+ const char *start, const char *end);
+static int
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
+ const char *end);
+static void
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
+ const char *end);
+
+static const XML_Char * getContext(XML_Parser parser);
+static XML_Bool
+setContext(XML_Parser parser, const XML_Char *context);
+
+static void FASTCALL normalizePublicId(XML_Char *s);
+
+static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
+/* BEGIN MOZILLA CHANGE (unused API) */
+/* do not call if parentParser != NULL */
+//static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
+/* END MOZILLA CHANGE */
+static void
+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
+static int
+dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
+static int
+copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
+
+static NAMED *
+lookup(HASH_TABLE *table, KEY name, size_t createSize);
+static void FASTCALL
+hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
+/* BEGIN MOZILLA CHANGE (unused API) */
+//static void FASTCALL hashTableClear(HASH_TABLE *);
+/* END MOZILLA CHANGE */
+static void FASTCALL hashTableDestroy(HASH_TABLE *);
+static void FASTCALL
+hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
+static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
+
+static void FASTCALL
+poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
+static void FASTCALL poolClear(STRING_POOL *);
+static void FASTCALL poolDestroy(STRING_POOL *);
+static XML_Char *
+poolAppend(STRING_POOL *pool, const ENCODING *enc,
+ const char *ptr, const char *end);
+static XML_Char *
+poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+ const char *ptr, const char *end);
+static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
+static const XML_Char * FASTCALL
+poolCopyString(STRING_POOL *pool, const XML_Char *s);
+static const XML_Char *
+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
+static const XML_Char * FASTCALL
+poolAppendString(STRING_POOL *pool, const XML_Char *s);
+
+static int FASTCALL nextScaffoldPart(XML_Parser parser);
+static XML_Content * build_model(XML_Parser parser);
+static ELEMENT_TYPE *
+getElementType(XML_Parser parser, const ENCODING *enc,
+ const char *ptr, const char *end);
+
+static XML_Parser
+parserCreate(const XML_Char *encodingName,
+ const XML_Memory_Handling_Suite *memsuite,
+ const XML_Char *nameSep,
+ DTD *dtd);
+static void
+parserInit(XML_Parser parser, const XML_Char *encodingName);
+
+#define poolStart(pool) ((pool)->start)
+#define poolEnd(pool) ((pool)->ptr)
+#define poolLength(pool) ((pool)->ptr - (pool)->start)
+#define poolChop(pool) ((void)--(pool->ptr))
+#define poolLastChar(pool) (((pool)->ptr)[-1])
+#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
+#define poolFinish(pool) ((pool)->start = (pool)->ptr)
+#define poolAppendChar(pool, c) \
+ (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
+ ? 0 \
+ : ((*((pool)->ptr)++ = c), 1))
+
+struct XML_ParserStruct {
+ /* The first member must be userData so that the XML_GetUserData
+ macro works. */
+ void *m_userData;
+ void *m_handlerArg;
+ char *m_buffer;
+ const XML_Memory_Handling_Suite m_mem;
+ /* first character to be parsed */
+ const char *m_bufferPtr;
+ /* past last character to be parsed */
+ char *m_bufferEnd;
+ /* allocated end of buffer */
+ const char *m_bufferLim;
+ XML_Index m_parseEndByteIndex;
+ const char *m_parseEndPtr;
+ XML_Char *m_dataBuf;
+ XML_Char *m_dataBufEnd;
+ XML_StartElementHandler m_startElementHandler;
+ XML_EndElementHandler m_endElementHandler;
+ XML_CharacterDataHandler m_characterDataHandler;
+ XML_ProcessingInstructionHandler m_processingInstructionHandler;
+ XML_CommentHandler m_commentHandler;
+ XML_StartCdataSectionHandler m_startCdataSectionHandler;
+ XML_EndCdataSectionHandler m_endCdataSectionHandler;
+ XML_DefaultHandler m_defaultHandler;
+ XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
+ XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
+ XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
+ XML_NotationDeclHandler m_notationDeclHandler;
+ XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
+ XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
+ XML_NotStandaloneHandler m_notStandaloneHandler;
+ XML_ExternalEntityRefHandler m_externalEntityRefHandler;
+ XML_Parser m_externalEntityRefHandlerArg;
+ XML_SkippedEntityHandler m_skippedEntityHandler;
+ XML_UnknownEncodingHandler m_unknownEncodingHandler;
+ XML_ElementDeclHandler m_elementDeclHandler;
+ XML_AttlistDeclHandler m_attlistDeclHandler;
+ XML_EntityDeclHandler m_entityDeclHandler;
+ XML_XmlDeclHandler m_xmlDeclHandler;
+ const ENCODING *m_encoding;
+ INIT_ENCODING m_initEncoding;
+ const ENCODING *m_internalEncoding;
+ const XML_Char *m_protocolEncodingName;
+ XML_Bool m_ns;
+ XML_Bool m_ns_triplets;
+ void *m_unknownEncodingMem;
+ void *m_unknownEncodingData;
+ void *m_unknownEncodingHandlerData;
+ void (XMLCALL *m_unknownEncodingRelease)(void *);
+ PROLOG_STATE m_prologState;
+ Processor *m_processor;
+ enum XML_Error m_errorCode;
+ const char *m_eventPtr;
+ const char *m_eventEndPtr;
+ const char *m_positionPtr;
+ OPEN_INTERNAL_ENTITY *m_openInternalEntities;
+ OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
+ XML_Bool m_defaultExpandInternalEntities;
+ int m_tagLevel;
+ ENTITY *m_declEntity;
+ const XML_Char *m_doctypeName;
+ const XML_Char *m_doctypeSysid;
+ const XML_Char *m_doctypePubid;
+ const XML_Char *m_declAttributeType;
+ const XML_Char *m_declNotationName;
+ const XML_Char *m_declNotationPublicId;
+ ELEMENT_TYPE *m_declElementType;
+ ATTRIBUTE_ID *m_declAttributeId;
+ XML_Bool m_declAttributeIsCdata;
+ XML_Bool m_declAttributeIsId;
+ DTD *m_dtd;
+ const XML_Char *m_curBase;
+ TAG *m_tagStack;
+ TAG *m_freeTagList;
+ BINDING *m_inheritedBindings;
+ BINDING *m_freeBindingList;
+ int m_attsSize;
+ int m_nSpecifiedAtts;
+ int m_idAttIndex;
+ ATTRIBUTE *m_atts;
+ NS_ATT *m_nsAtts;
+ unsigned long m_nsAttsVersion;
+ unsigned char m_nsAttsPower;
+ POSITION m_position;
+ STRING_POOL m_tempPool;
+ STRING_POOL m_temp2Pool;
+ char *m_groupConnector;
+ unsigned int m_groupSize;
+ XML_Char m_namespaceSeparator;
+ XML_Parser m_parentParser;
+ XML_ParsingStatus m_parsingStatus;
+#ifdef XML_DTD
+ XML_Bool m_isParamEntity;
+ XML_Bool m_useForeignDTD;
+ enum XML_ParamEntityParsing m_paramEntityParsing;
+#endif
+/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
+ const XML_Char* m_mismatch;
+/* END MOZILLA CHANGE */
+};
+
+#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
+#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
+#define FREE(p) (parser->m_mem.free_fcn((p)))
+
+#define userData (parser->m_userData)
+#define handlerArg (parser->m_handlerArg)
+#define startElementHandler (parser->m_startElementHandler)
+#define endElementHandler (parser->m_endElementHandler)
+#define characterDataHandler (parser->m_characterDataHandler)
+#define processingInstructionHandler \
+ (parser->m_processingInstructionHandler)
+#define commentHandler (parser->m_commentHandler)
+#define startCdataSectionHandler \
+ (parser->m_startCdataSectionHandler)
+#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
+#define defaultHandler (parser->m_defaultHandler)
+#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
+#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
+#define unparsedEntityDeclHandler \
+ (parser->m_unparsedEntityDeclHandler)
+#define notationDeclHandler (parser->m_notationDeclHandler)
+#define startNamespaceDeclHandler \
+ (parser->m_startNamespaceDeclHandler)
+#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
+#define notStandaloneHandler (parser->m_notStandaloneHandler)
+#define externalEntityRefHandler \
+ (parser->m_externalEntityRefHandler)
+#define externalEntityRefHandlerArg \
+ (parser->m_externalEntityRefHandlerArg)
+#define internalEntityRefHandler \
+ (parser->m_internalEntityRefHandler)
+#define skippedEntityHandler (parser->m_skippedEntityHandler)
+#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
+#define elementDeclHandler (parser->m_elementDeclHandler)
+#define attlistDeclHandler (parser->m_attlistDeclHandler)
+#define entityDeclHandler (parser->m_entityDeclHandler)
+#define xmlDeclHandler (parser->m_xmlDeclHandler)
+#define encoding (parser->m_encoding)
+#define initEncoding (parser->m_initEncoding)
+#define internalEncoding (parser->m_internalEncoding)
+#define unknownEncodingMem (parser->m_unknownEncodingMem)
+#define unknownEncodingData (parser->m_unknownEncodingData)
+#define unknownEncodingHandlerData \
+ (parser->m_unknownEncodingHandlerData)
+#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
+#define protocolEncodingName (parser->m_protocolEncodingName)
+#define ns (parser->m_ns)
+#define ns_triplets (parser->m_ns_triplets)
+#define prologState (parser->m_prologState)
+#define processor (parser->m_processor)
+#define errorCode (parser->m_errorCode)
+#define eventPtr (parser->m_eventPtr)
+#define eventEndPtr (parser->m_eventEndPtr)
+#define positionPtr (parser->m_positionPtr)
+#define position (parser->m_position)
+#define openInternalEntities (parser->m_openInternalEntities)
+#define freeInternalEntities (parser->m_freeInternalEntities)
+#define defaultExpandInternalEntities \
+ (parser->m_defaultExpandInternalEntities)
+#define tagLevel (parser->m_tagLevel)
+#define buffer (parser->m_buffer)
+#define bufferPtr (parser->m_bufferPtr)
+#define bufferEnd (parser->m_bufferEnd)
+#define parseEndByteIndex (parser->m_parseEndByteIndex)
+#define parseEndPtr (parser->m_parseEndPtr)
+#define bufferLim (parser->m_bufferLim)
+#define dataBuf (parser->m_dataBuf)
+#define dataBufEnd (parser->m_dataBufEnd)
+#define _dtd (parser->m_dtd)
+#define curBase (parser->m_curBase)
+#define declEntity (parser->m_declEntity)
+#define doctypeName (parser->m_doctypeName)
+#define doctypeSysid (parser->m_doctypeSysid)
+#define doctypePubid (parser->m_doctypePubid)
+#define declAttributeType (parser->m_declAttributeType)
+#define declNotationName (parser->m_declNotationName)
+#define declNotationPublicId (parser->m_declNotationPublicId)
+#define declElementType (parser->m_declElementType)
+#define declAttributeId (parser->m_declAttributeId)
+#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
+#define declAttributeIsId (parser->m_declAttributeIsId)
+#define freeTagList (parser->m_freeTagList)
+#define freeBindingList (parser->m_freeBindingList)
+#define inheritedBindings (parser->m_inheritedBindings)
+#define tagStack (parser->m_tagStack)
+#define atts (parser->m_atts)
+#define attsSize (parser->m_attsSize)
+#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
+#define idAttIndex (parser->m_idAttIndex)
+#define nsAtts (parser->m_nsAtts)
+#define nsAttsVersion (parser->m_nsAttsVersion)
+#define nsAttsPower (parser->m_nsAttsPower)
+#define tempPool (parser->m_tempPool)
+#define temp2Pool (parser->m_temp2Pool)
+#define groupConnector (parser->m_groupConnector)
+#define groupSize (parser->m_groupSize)
+#define namespaceSeparator (parser->m_namespaceSeparator)
+#define parentParser (parser->m_parentParser)
+#define ps_parsing (parser->m_parsingStatus.parsing)
+#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
+#ifdef XML_DTD
+#define isParamEntity (parser->m_isParamEntity)
+#define useForeignDTD (parser->m_useForeignDTD)
+#define paramEntityParsing (parser->m_paramEntityParsing)
+#endif /* XML_DTD */
+/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
+#define mismatch (parser->m_mismatch)
+/* END MOZILLA CHANGE */
+
+/* BEGIN MOZILLA CHANGE (unused API) */
+#if 0
+XML_Parser XMLCALL
+XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
+{
+ XML_Char tmp[2];
+ *tmp = nsSep;
+ return XML_ParserCreate_MM(encodingName, NULL, tmp);
+}
+#endif
+/* END MOZILLA CHANGE */
+
+static const XML_Char implicitContext[] = {
+ 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
+ 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
+ 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
+ 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
+};
+
+XML_Parser XMLCALL
+XML_ParserCreate_MM(const XML_Char *encodingName,
+ const XML_Memory_Handling_Suite *memsuite,
+ const XML_Char *nameSep)
+{
+ XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
+ if (parser != NULL && ns) {
+ /* implicit context only set for root parser, since child
+ parsers (i.e. external entity parsers) will inherit it
+ */
+ if (!setContext(parser, implicitContext)) {
+ XML_ParserFree(parser);
+ return NULL;
+ }
+ }
+ return parser;
+}
+
+static XML_Parser
+parserCreate(const XML_Char *encodingName,
+ const XML_Memory_Handling_Suite *memsuite,
+ const XML_Char *nameSep,
+ DTD *dtd)
+{
+ XML_Parser parser;
+
+ if (memsuite) {
+ XML_Memory_Handling_Suite *mtemp;
+ parser = (XML_Parser)
+ memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
+ if (parser != NULL) {
+ mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
+ mtemp->malloc_fcn = memsuite->malloc_fcn;
+ mtemp->realloc_fcn = memsuite->realloc_fcn;
+ mtemp->free_fcn = memsuite->free_fcn;
+ }
+ }
+ else {
+ XML_Memory_Handling_Suite *mtemp;
+ parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
+ if (parser != NULL) {
+ mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
+ mtemp->malloc_fcn = malloc;
+ mtemp->realloc_fcn = realloc;
+ mtemp->free_fcn = free;
+ }
+ }
+
+ if (!parser)
+ return parser;
+
+ buffer = NULL;
+ bufferLim = NULL;
+
+ attsSize = INIT_ATTS_SIZE;
+ atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
+ if (atts == NULL) {
+ FREE(parser);
+ return NULL;
+ }
+ dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
+ if (dataBuf == NULL) {
+ FREE(atts);
+ FREE(parser);
+ return NULL;
+ }
+ dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
+
+ if (dtd)
+ _dtd = dtd;
+ else {
+ _dtd = dtdCreate(&parser->m_mem);
+ if (_dtd == NULL) {
+ FREE(dataBuf);
+ FREE(atts);
+ FREE(parser);
+ return NULL;
+ }
+ }
+
+ freeBindingList = NULL;
+ freeTagList = NULL;
+ freeInternalEntities = NULL;
+
+ groupSize = 0;
+ groupConnector = NULL;
+
+ unknownEncodingHandler = NULL;
+ unknownEncodingHandlerData = NULL;
+
+ namespaceSeparator = '!';
+ ns = XML_FALSE;
+ ns_triplets = XML_FALSE;
+
+ nsAtts = NULL;
+ nsAttsVersion = 0;
+ nsAttsPower = 0;
+
+ poolInit(&tempPool, &(parser->m_mem));
+ poolInit(&temp2Pool, &(parser->m_mem));
+ parserInit(parser, encodingName);
+
+ if (encodingName && !protocolEncodingName) {
+ XML_ParserFree(parser);
+ return NULL;
+ }
+
+ if (nameSep) {
+ ns = XML_TRUE;
+ internalEncoding = XmlGetInternalEncodingNS();
+ namespaceSeparator = *nameSep;
+ }
+ else {
+ internalEncoding = XmlGetInternalEncoding();
+ }
+
+/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
+ mismatch = NULL;
+/* END MOZILLA CHANGE */
+
+ return parser;
+}
+
+static void
+parserInit(XML_Parser parser, const XML_Char *encodingName)
+{
+ processor = prologInitProcessor;
+ XmlPrologStateInit(&prologState);
+ protocolEncodingName = (encodingName != NULL
+ ? poolCopyString(&tempPool, encodingName)
+ : NULL);
+ curBase = NULL;
+ XmlInitEncoding(&initEncoding, &encoding, 0);
+ userData = NULL;
+ handlerArg = NULL;
+ startElementHandler = NULL;
+ endElementHandler = NULL;
+ characterDataHandler = NULL;
+ processingInstructionHandler = NULL;
+ commentHandler = NULL;
+ startCdataSectionHandler = NULL;
+ endCdataSectionHandler = NULL;
+ defaultHandler = NULL;
+ startDoctypeDeclHandler = NULL;
+ endDoctypeDeclHandler = NULL;
+ unparsedEntityDeclHandler = NULL;
+ notationDeclHandler = NULL;
+ startNamespaceDeclHandler = NULL;
+ endNamespaceDeclHandler = NULL;
+ notStandaloneHandler = NULL;
+ externalEntityRefHandler = NULL;
+ externalEntityRefHandlerArg = parser;
+ skippedEntityHandler = NULL;
+ elementDeclHandler = NULL;
+ attlistDeclHandler = NULL;
+ entityDeclHandler = NULL;
+ xmlDeclHandler = NULL;
+ bufferPtr = buffer;
+ bufferEnd = buffer;
+ parseEndByteIndex = 0;
+ parseEndPtr = NULL;
+ declElementType = NULL;
+ declAttributeId = NULL;
+ declEntity = NULL;
+ doctypeName = NULL;
+ doctypeSysid = NULL;
+ doctypePubid = NULL;
+ declAttributeType = NULL;
+ declNotationName = NULL;
+ declNotationPublicId = NULL;
+ declAttributeIsCdata = XML_FALSE;
+ declAttributeIsId = XML_FALSE;
+ memset(&position, 0, sizeof(POSITION));
+ errorCode = XML_ERROR_NONE;
+ eventPtr = NULL;
+ eventEndPtr = NULL;
+ positionPtr = NULL;
+ openInternalEntities = NULL;
+ defaultExpandInternalEntities = XML_TRUE;
+ tagLevel = 0;
+ tagStack = NULL;
+ inheritedBindings = NULL;
+ nSpecifiedAtts = 0;
+ unknownEncodingMem = NULL;
+ unknownEncodingRelease = NULL;
+ unknownEncodingData = NULL;
+ parentParser = NULL;
+ ps_parsing = XML_INITIALIZED;
+#ifdef XML_DTD
+ isParamEntity = XML_FALSE;
+ useForeignDTD = XML_FALSE;
+ paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+}
+
+/* BEGIN MOZILLA CHANGE (unused API) */
+#if 0
+/* moves list of bindings to freeBindingList */
+static void FASTCALL
+moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
+{
+ while (bindings) {
+ BINDING *b = bindings;
+ bindings = bindings->nextTagBinding;
+ b->nextTagBinding = freeBindingList;
+ freeBindingList = b;
+ }
+}
+
+XML_Bool XMLCALL
+XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
+{
+ TAG *tStk;
+ OPEN_INTERNAL_ENTITY *openEntityList;
+ if (parentParser)
+ return XML_FALSE;
+ /* move tagStack to freeTagList */
+ tStk = tagStack;
+ while (tStk) {
+ TAG *tag = tStk;
+ tStk = tStk->parent;
+ tag->parent = freeTagList;
+ moveToFreeBindingList(parser, tag->bindings);
+ tag->bindings = NULL;
+ freeTagList = tag;
+ }
+ /* move openInternalEntities to freeInternalEntities */
+ openEntityList = openInternalEntities;
+ while (openEntityList) {
+ OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
+ openEntityList = openEntity->next;
+ openEntity->next = freeInternalEntities;
+ freeInternalEntities = openEntity;
+ }
+ moveToFreeBindingList(parser, inheritedBindings);
+ FREE(unknownEncodingMem);
+ if (unknownEncodingRelease)
+ unknownEncodingRelease(unknownEncodingData);
+ poolClear(&tempPool);
+ poolClear(&temp2Pool);
+ parserInit(parser, encodingName);
+ dtdReset(_dtd, &parser->m_mem);
+ return setContext(parser, implicitContext);
+}
+
+enum XML_Status XMLCALL
+XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+ /* Block after XML_Parse()/XML_ParseBuffer() has been called.
+ XXX There's no way for the caller to determine which of the
+ XXX possible error cases caused the XML_STATUS_ERROR return.
+ */
+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+ return XML_STATUS_ERROR;
+ if (encodingName == NULL)
+ protocolEncodingName = NULL;
+ else {
+ protocolEncodingName = poolCopyString(&tempPool, encodingName);
+ if (!protocolEncodingName)
+ return XML_STATUS_ERROR;
+ }
+ return XML_STATUS_OK;
+}
+#endif
+/* END MOZILLA CHANGE */
+
+XML_Parser XMLCALL
+XML_ExternalEntityParserCreate(XML_Parser oldParser,
+ const XML_Char *context,
+ const XML_Char *encodingName)
+{
+ XML_Parser parser = oldParser;
+ DTD *newDtd = NULL;
+ DTD *oldDtd = _dtd;
+ XML_StartElementHandler oldStartElementHandler = startElementHandler;
+ XML_EndElementHandler oldEndElementHandler = endElementHandler;
+ XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
+ XML_ProcessingInstructionHandler oldProcessingInstructionHandler
+ = processingInstructionHandler;
+ XML_CommentHandler oldCommentHandler = commentHandler;
+ XML_StartCdataSectionHandler oldStartCdataSectionHandler
+ = startCdataSectionHandler;
+ XML_EndCdataSectionHandler oldEndCdataSectionHandler
+ = endCdataSectionHandler;
+ XML_DefaultHandler oldDefaultHandler = defaultHandler;
+ XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
+ = unparsedEntityDeclHandler;
+ XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
+ XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
+ = startNamespaceDeclHandler;
+ XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
+ = endNamespaceDeclHandler;
+ XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
+ XML_ExternalEntityRefHandler oldExternalEntityRefHandler
+ = externalEntityRefHandler;
+ XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
+ XML_UnknownEncodingHandler oldUnknownEncodingHandler
+ = unknownEncodingHandler;
+ XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
+ XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
+ XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
+ XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
+ ELEMENT_TYPE * oldDeclElementType = declElementType;
+
+ void *oldUserData = userData;
+ void *oldHandlerArg = handlerArg;
+ XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
+ XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+#ifdef XML_DTD
+ enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
+ int oldInEntityValue = prologState.inEntityValue;
+#endif
+ XML_Bool oldns_triplets = ns_triplets;
+
+#ifdef XML_DTD
+ if (!context)
+ newDtd = oldDtd;
+#endif /* XML_DTD */
+
+ /* Note that the magical uses of the pre-processor to make field
+ access look more like C++ require that `parser' be overwritten
+ here. This makes this function more painful to follow than it
+ would be otherwise.
+ */
+ if (ns) {
+ XML_Char tmp[2];
+ *tmp = namespaceSeparator;
+ parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
+ }
+ else {
+ parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
+ }
+
+ if (!parser)
+ return NULL;
+
+ startElementHandler = oldStartElementHandler;
+ endElementHandler = oldEndElementHandler;
+ characterDataHandler = oldCharacterDataHandler;
+ processingInstructionHandler = oldProcessingInstructionHandler;
+ commentHandler = oldCommentHandler;
+ startCdataSectionHandler = oldStartCdataSectionHandler;
+ endCdataSectionHandler = oldEndCdataSectionHandler;
+ defaultHandler = oldDefaultHandler;
+ unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
+ notationDeclHandler = oldNotationDeclHandler;
+ startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
+ endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
+ notStandaloneHandler = oldNotStandaloneHandler;
+ externalEntityRefHandler = oldExternalEntityRefHandler;
+ skippedEntityHandler = oldSkippedEntityHandler;
+ unknownEncodingHandler = oldUnknownEncodingHandler;
+ elementDeclHandler = oldElementDeclHandler;
+ attlistDeclHandler = oldAttlistDeclHandler;
+ entityDeclHandler = oldEntityDeclHandler;
+ xmlDeclHandler = oldXmlDeclHandler;
+ declElementType = oldDeclElementType;
+ userData = oldUserData;
+ if (oldUserData == oldHandlerArg)
+ handlerArg = userData;
+ else
+ handlerArg = parser;
+ if (oldExternalEntityRefHandlerArg != oldParser)
+ externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
+ defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
+ ns_triplets = oldns_triplets;
+ parentParser = oldParser;
+#ifdef XML_DTD
+ paramEntityParsing = oldParamEntityParsing;
+ prologState.inEntityValue = oldInEntityValue;
+ if (context) {
+#endif /* XML_DTD */
+ if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
+ || !setContext(parser, context)) {
+ XML_ParserFree(parser);
+ return NULL;
+ }
+ processor = externalEntityInitProcessor;
+#ifdef XML_DTD
+ }
+ else {
+ /* The DTD instance referenced by _dtd is shared between the document's
+ root parser and external PE parsers, therefore one does not need to
+ call setContext. In addition, one also *must* not call setContext,
+ because this would overwrite existing prefix->binding pointers in
+ _dtd with ones that get destroyed with the external PE parser.
+ This would leave those prefixes with dangling pointers.
+ */
+ isParamEntity = XML_TRUE;
+ XmlPrologStateInitExternalEntity(&prologState);
+ processor = externalParEntInitProcessor;
+ }
+#endif /* XML_DTD */
+ return parser;
+}
+
+static void FASTCALL
+destroyBindings(BINDING *bindings, XML_Parser parser)
+{
+ for (;;) {
+ BINDING *b = bindings;
+ if (!b)
+ break;
+ bindings = b->nextTagBinding;
+ FREE(b->uri);
+ FREE(b);
+ }
+}
+
+void XMLCALL
+XML_ParserFree(XML_Parser parser)
+{
+ TAG *tagList;
+ OPEN_INTERNAL_ENTITY *entityList;
+ if (parser == NULL)
+ return;
+ /* free tagStack and freeTagList */
+ tagList = tagStack;
+ for (;;) {
+ TAG *p;
+ if (tagList == NULL) {
+ if (freeTagList == NULL)
+ break;
+ tagList = freeTagList;
+ freeTagList = NULL;
+ }
+ p = tagList;
+ tagList = tagList->parent;
+ FREE(p->buf);
+ destroyBindings(p->bindings, parser);
+ FREE(p);
+ }
+ /* free openInternalEntities and freeInternalEntities */
+ entityList = openInternalEntities;
+ for (;;) {
+ OPEN_INTERNAL_ENTITY *openEntity;
+ if (entityList == NULL) {
+ if (freeInternalEntities == NULL)
+ break;
+ entityList = freeInternalEntities;
+ freeInternalEntities = NULL;
+ }
+ openEntity = entityList;
+ entityList = entityList->next;
+ FREE(openEntity);
+ }
+
+ destroyBindings(freeBindingList, parser);
+ destroyBindings(inheritedBindings, parser);
+ poolDestroy(&tempPool);
+ poolDestroy(&temp2Pool);
+#ifdef XML_DTD
+ /* external parameter entity parsers share the DTD structure
+ parser->m_dtd with the root parser, so we must not destroy it
+ */
+ if (!isParamEntity && _dtd)
+#else
+ if (_dtd)
+#endif /* XML_DTD */
+ dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
+ FREE((void *)atts);
+ FREE(groupConnector);
+ FREE(buffer);
+ FREE(dataBuf);
+ FREE(nsAtts);
+ FREE(unknownEncodingMem);
+ if (unknownEncodingRelease)
+ unknownEncodingRelease(unknownEncodingData);
+ FREE(parser);
+}
+
+void XMLCALL
+XML_UseParserAsHandlerArg(XML_Parser parser)
+{
+ handlerArg = parser;
+}
+
+/* BEGIN MOZILLA CHANGE (unused API) */
+#if 0
+enum XML_Error XMLCALL
+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
+{
+#ifdef XML_DTD
+ /* block after XML_Parse()/XML_ParseBuffer() has been called */
+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+ return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
+ useForeignDTD = useDTD;
+ return XML_ERROR_NONE;
+#else
+ return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
+#endif
+}
+#endif
+/* END MOZILLA CHANGE */
+
+void XMLCALL
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
+{
+ /* block after XML_Parse()/XML_ParseBuffer() has been called */
+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+ return;
+ ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
+}
+
+void XMLCALL
+XML_SetUserData(XML_Parser parser, void *p)
+{
+ if (handlerArg == userData)
+ handlerArg = userData = p;
+ else
+ userData = p;
+}
+
+enum XML_Status XMLCALL
+XML_SetBase(XML_Parser parser, const XML_Char *p)
+{
+ if (p) {
+ p = poolCopyString(&_dtd->pool, p);
+ if (!p)
+ return XML_STATUS_ERROR;
+ curBase = p;
+ }
+ else
+ curBase = NULL;
+ return XML_STATUS_OK;
+}
+
+const XML_Char * XMLCALL
+XML_GetBase(XML_Parser parser)
+{
+ return curBase;
+}
+
+int XMLCALL
+XML_GetSpecifiedAttributeCount(XML_Parser parser)
+{
+ return nSpecifiedAtts;
+}
+
+int XMLCALL
+XML_GetIdAttributeIndex(XML_Parser parser)
+{
+ return idAttIndex;
+}
+
+void XMLCALL
+XML_SetElementHandler(XML_Parser parser,
+ XML_StartElementHandler start,
+ XML_EndElementHandler end)
+{
+ startElementHandler = start;
+ endElementHandler = end;
+}
+
+/* BEGIN MOZILLA CHANGE (unused API) */
+#if 0
+void XMLCALL
+XML_SetStartElementHandler(XML_Parser parser,
+ XML_StartElementHandler start) {
+ startElementHandler = start;
+}
+
+void XMLCALL
+XML_SetEndElementHandler(XML_Parser parser,
+ XML_EndElementHandler end) {
+ endElementHandler = end;
+}
+#endif
+/* END MOZILLA CHANGE */
+
+void XMLCALL
+XML_SetCharacterDataHandler(XML_Parser parser,
+ XML_CharacterDataHandler handler)
+{
+ characterDataHandler = handler;
+}
+
+void XMLCALL
+XML_SetProcessingInstructionHandler(XML_Parser parser,
+ XML_ProcessingInstructionHandler handler)
+{
+ processingInstructionHandler = handler;
+}
+
+void XMLCALL
+XML_SetCommentHandler(XML_Parser parser,
+ XML_CommentHandler handler)
+{
+ commentHandler = handler;
+}
+
+void XMLCALL
+XML_SetCdataSectionHandler(XML_Parser parser,
+ XML_StartCdataSectionHandler start,
+ XML_EndCdataSectionHandler end)
+{
+ startCdataSectionHandler = start;
+ endCdataSectionHandler = end;
+}
+
+/* BEGIN MOZILLA CHANGE (unused API) */
+#if 0
+void XMLCALL
+XML_SetStartCdataSectionHandler(XML_Parser parser,
+ XML_StartCdataSectionHandler start) {
+ startCdataSectionHandler = start;
+}
+
+void XMLCALL
+XML_SetEndCdataSectionHandler(XML_Parser parser,
+ XML_EndCdataSectionHandler end) {
+ endCdataSectionHandler = end;
+}
+
+void XMLCALL
+XML_SetDefaultHandler(XML_Parser parser,
+ XML_DefaultHandler handler)
+{
+ defaultHandler = handler;
+ defaultExpandInternalEntities = XML_FALSE;
+}
+#endif
+/* END MOZILLA CHANGE */
+
+void XMLCALL
+XML_SetDefaultHandlerExpand(XML_Parser parser,
+ XML_DefaultHandler handler)
+{
+ defaultHandler = handler;
+ defaultExpandInternalEntities = XML_TRUE;
+}
+
+void XMLCALL
+XML_SetDoctypeDeclHandler(XML_Parser parser,
+ XML_StartDoctypeDeclHandler start,
+ XML_EndDoctypeDeclHandler end)
+{
+ startDoctypeDeclHandler = start;
+ endDoctypeDeclHandler = end;
+}
+
+/* BEGIN MOZILLA CHANGE (unused API) */
+#if 0
+void XMLCALL
+XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+ XML_StartDoctypeDeclHandler start) {
+ startDoctypeDeclHandler = start;
+}
+
+void XMLCALL
+XML_SetEndDoctypeDeclHandler(XML_Parser parser,
+ XML_EndDoctypeDeclHandler end) {
+ endDoctypeDeclHandler = end;
+}
+#endif
+/* END MOZILLA CHANGE */
+
+void XMLCALL
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+ XML_UnparsedEntityDeclHandler handler)
+{
+ unparsedEntityDeclHandler = handler;
+}
+
+void XMLCALL
+XML_SetNotationDeclHandler(XML_Parser parser,
+ XML_NotationDeclHandler handler)
+{
+ notationDeclHandler = handler;
+}
+
+void XMLCALL
+XML_SetNamespaceDeclHandler(XML_Parser parser,
+ XML_StartNamespaceDeclHandler start,
+ XML_EndNamespaceDeclHandler end)
+{
+ startNamespaceDeclHandler = start;
+ endNamespaceDeclHandler = end;
+}
+
+
+/* BEGIN MOZILLA CHANGE (unused API) */
+#if 0
+void XMLCALL
+XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+ XML_StartNamespaceDeclHandler start) {
+ startNamespaceDeclHandler = start;
+}
+
+void XMLCALL
+XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+ XML_EndNamespaceDeclHandler end) {
+ endNamespaceDeclHandler = end;
+}
+
+void XMLCALL
+XML_SetNotStandaloneHandler(XML_Parser parser,
+ XML_NotStandaloneHandler handler)
+{
+ notStandaloneHandler = handler;
+}
+#endif
+/* END MOZILLA CHANGE */
+
+void XMLCALL
+XML_SetExternalEntityRefHandler(XML_Parser parser,
+ XML_ExternalEntityRefHandler handler)
+{
+ externalEntityRefHandler = handler;
+}
+
+void XMLCALL
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
+{
+ if (arg)
+ externalEntityRefHandlerArg = (XML_Parser)arg;
+ else
+ externalEntityRefHandlerArg = parser;
+}
+
+/* BEGIN MOZILLA CHANGE (unused API) */
+#if 0
+void XMLCALL
+XML_SetSkippedEntityHandler(XML_Parser parser,
+ XML_SkippedEntityHandler handler)
+{
+ skippedEntityHandler = handler;
+}
+
+void XMLCALL
+XML_SetUnknownEncodingHandler(XML_Parser parser,
+ XML_UnknownEncodingHandler handler,
+ void *data)
+{
+ unknownEncodingHandler = handler;
+ unknownEncodingHandlerData = data;
+}
+
+void XMLCALL
+XML_SetElementDeclHandler(XML_Parser parser,
+ XML_ElementDeclHandler eldecl)
+{
+ elementDeclHandler = eldecl;
+}
+
+void XMLCALL
+XML_SetAttlistDeclHandler(XML_Parser parser,
+ XML_AttlistDeclHandler attdecl)
+{
+ attlistDeclHandler = attdecl;
+}
+
+void XMLCALL
+XML_SetEntityDeclHandler(XML_Parser parser,
+ XML_EntityDeclHandler handler)
+{
+ entityDeclHandler = handler;
+}
+#endif
+/* END MOZILLA CHANGE */
+
+void XMLCALL
+XML_SetXmlDeclHandler(XML_Parser parser,
+ XML_XmlDeclHandler handler) {
+ xmlDeclHandler = handler;
+}
+
+int XMLCALL
+XML_SetParamEntityParsing(XML_Parser parser,
+ enum XML_ParamEntityParsing peParsing)
+{
+ /* block after XML_Parse()/XML_ParseBuffer() has been called */
+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+ return 0;
+#ifdef XML_DTD
+ paramEntityParsing = peParsing;
+ return 1;
+#else
+ return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+}
+
+enum XML_Status XMLCALL
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
+{
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ errorCode = XML_ERROR_SUSPENDED;
+ return XML_STATUS_ERROR;
+ case XML_FINISHED:
+ errorCode = XML_ERROR_FINISHED;
+ return XML_STATUS_ERROR;
+ default:
+ ps_parsing = XML_PARSING;
+ }
+
+ if (len == 0) {
+ ps_finalBuffer = (XML_Bool)isFinal;
+ if (!isFinal)
+ return XML_STATUS_OK;
+ positionPtr = bufferPtr;
+ parseEndPtr = bufferEnd;
+
+ /* If data are left over from last buffer, and we now know that these
+ data are the final chunk of input, then we have to check them again
+ to detect errors based on that fact.
+ */
+ errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
+
+ if (errorCode == XML_ERROR_NONE) {
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
+ positionPtr = bufferPtr;
+ return XML_STATUS_SUSPENDED;
+ case XML_INITIALIZED:
+ case XML_PARSING:
+ ps_parsing = XML_FINISHED;
+ /* fall through */
+ default:
+ return XML_STATUS_OK;
+ }
+ }
+ eventEndPtr = eventPtr;
+ processor = errorProcessor;
+ return XML_STATUS_ERROR;
+ }
+#ifndef XML_CONTEXT_BYTES
+ else if (bufferPtr == bufferEnd) {
+ const char *end;
+ int nLeftOver;
+/* BEGIN MOZILLA CHANGE (|result| has type XML_Status, not XML_Error) */
+ enum XML_Status result;
+/* END MOZILLA CHANGE */
+ parseEndByteIndex += len;
+ positionPtr = s;
+ ps_finalBuffer = (XML_Bool)isFinal;
+
+ errorCode = processor(parser, s, parseEndPtr = s + len, &end);
+
+ if (errorCode != XML_ERROR_NONE) {
+ eventEndPtr = eventPtr;
+ processor = errorProcessor;
+ return XML_STATUS_ERROR;
+ }
+ else {
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ result = XML_STATUS_SUSPENDED;
+ break;
+ case XML_INITIALIZED:
+ case XML_PARSING:
+/* BEGIN MOZILLA CHANGE (always initialize result) */
+#if 0
+ result = XML_STATUS_OK;
+ if (isFinal) {
+ ps_parsing = XML_FINISHED;
+ return result;
+ }
+#else
+ if (isFinal) {
+ ps_parsing = XML_FINISHED;
+ return XML_STATUS_OK;
+ }
+ /* fall through */
+ default:
+ result = XML_STATUS_OK;
+#endif
+/* END MOZILLA CHANGE */
+ }
+ }
+
+ XmlUpdatePosition(encoding, positionPtr, end, &position);
+ nLeftOver = s + len - end;
+ if (nLeftOver) {
+ if (buffer == NULL || nLeftOver > bufferLim - buffer) {
+/* BEGIN MOZILLA CHANGE (check for overflow) */
+#if 0
+ /* FIXME avoid integer overflow */
+ char *temp;
+ temp = (buffer == NULL
+ ? (char *)MALLOC(len * 2)
+ : (char *)REALLOC(buffer, len * 2));
+ if (temp == NULL) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return XML_STATUS_ERROR;
+ }
+ buffer = temp;
+ if (!buffer) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ eventPtr = eventEndPtr = NULL;
+ processor = errorProcessor;
+ return XML_STATUS_ERROR;
+ }
+ bufferLim = buffer + len * 2;
+#else
+ char *temp;
+ int newLen = len * 2;
+ if (newLen < 0) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return XML_STATUS_ERROR;
+ }
+ temp = (buffer == NULL
+ ? (char *)MALLOC(newLen)
+ : (char *)REALLOC(buffer, newLen));
+ if (temp == NULL) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return XML_STATUS_ERROR;
+ }
+ buffer = temp;
+ if (!buffer) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ eventPtr = eventEndPtr = NULL;
+ processor = errorProcessor;
+ return XML_STATUS_ERROR;
+ }
+ bufferLim = buffer + newLen;
+#endif
+/* END MOZILLA CHANGE */
+ }
+ memcpy(buffer, end, nLeftOver);
+ }
+ bufferPtr = buffer;
+ bufferEnd = buffer + nLeftOver;
+ positionPtr = bufferPtr;
+ parseEndPtr = bufferEnd;
+ eventPtr = bufferPtr;
+ eventEndPtr = bufferPtr;
+ return result;
+ }
+#endif /* not defined XML_CONTEXT_BYTES */
+ else {
+ void *buff = XML_GetBuffer(parser, len);
+ if (buff == NULL)
+ return XML_STATUS_ERROR;
+ else {
+ memcpy(buff, s, len);
+ return XML_ParseBuffer(parser, len, isFinal);
+ }
+ }
+}
+
+enum XML_Status XMLCALL
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
+{
+ const char *start;
+ enum XML_Status result = XML_STATUS_OK;
+
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ errorCode = XML_ERROR_SUSPENDED;
+ return XML_STATUS_ERROR;
+ case XML_FINISHED:
+ errorCode = XML_ERROR_FINISHED;
+ return XML_STATUS_ERROR;
+ default:
+ ps_parsing = XML_PARSING;
+ }
+
+ start = bufferPtr;
+ positionPtr = start;
+ bufferEnd += len;
+ parseEndPtr = bufferEnd;
+ parseEndByteIndex += len;
+ ps_finalBuffer = (XML_Bool)isFinal;
+
+ errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
+
+ if (errorCode != XML_ERROR_NONE) {
+ eventEndPtr = eventPtr;
+ processor = errorProcessor;
+ return XML_STATUS_ERROR;
+ }
+ else {
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ result = XML_STATUS_SUSPENDED;
+ break;
+ case XML_INITIALIZED:
+ case XML_PARSING:
+ if (isFinal) {
+ ps_parsing = XML_FINISHED;
+ return result;
+ }
+ default: ; /* should not happen */
+ }
+ }
+
+ XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
+ positionPtr = bufferPtr;
+ return result;
+}
+
+void * XMLCALL
+XML_GetBuffer(XML_Parser parser, int len)
+{
+/* BEGIN MOZILLA CHANGE (sanity check len) */
+ if (len < 0) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return NULL;
+ }
+/* END MOZILLA CHANGE */
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ errorCode = XML_ERROR_SUSPENDED;
+ return NULL;
+ case XML_FINISHED:
+ errorCode = XML_ERROR_FINISHED;
+ return NULL;
+ default: ;
+ }
+
+ if (len > bufferLim - bufferEnd) {
+ int neededSize = len + (int)(bufferEnd - bufferPtr);
+/* BEGIN MOZILLA CHANGE (sanity check neededSize) */
+ if (neededSize < 0) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return NULL;
+ }
+/* END MOZILLA CHANGE */
+#ifdef XML_CONTEXT_BYTES
+ int keep = (int)(bufferPtr - buffer);
+
+ if (keep > XML_CONTEXT_BYTES)
+ keep = XML_CONTEXT_BYTES;
+ neededSize += keep;
+#endif /* defined XML_CONTEXT_BYTES */
+ if (neededSize <= bufferLim - buffer) {
+#ifdef XML_CONTEXT_BYTES
+ if (keep < bufferPtr - buffer) {
+ int offset = (int)(bufferPtr - buffer) - keep;
+ memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
+ bufferEnd -= offset;
+ bufferPtr -= offset;
+ }
+#else
+ memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
+ bufferEnd = buffer + (bufferEnd - bufferPtr);
+ bufferPtr = buffer;
+#endif /* not defined XML_CONTEXT_BYTES */
+ }
+ else {
+ char *newBuf;
+ int bufferSize = (int)(bufferLim - bufferPtr);
+ if (bufferSize == 0)
+ bufferSize = INIT_BUFFER_SIZE;
+ do {
+ bufferSize *= 2;
+/* BEGIN MOZILLA CHANGE (prevent infinite loop on overflow) */
+ } while (bufferSize < neededSize && bufferSize > 0);
+/* END MOZILLA CHANGE */
+/* BEGIN MOZILLA CHANGE (sanity check bufferSize) */
+ if (bufferSize <= 0) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return NULL;
+ }
+/* END MOZILLA CHANGE */
+ newBuf = (char *)MALLOC(bufferSize);
+ if (newBuf == 0) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return NULL;
+ }
+ bufferLim = newBuf + bufferSize;
+#ifdef XML_CONTEXT_BYTES
+ if (bufferPtr) {
+ int keep = (int)(bufferPtr - buffer);
+ if (keep > XML_CONTEXT_BYTES)
+ keep = XML_CONTEXT_BYTES;
+ memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
+ FREE(buffer);
+ buffer = newBuf;
+ bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
+ bufferPtr = buffer + keep;
+ }
+ else {
+ bufferEnd = newBuf + (bufferEnd - bufferPtr);
+ bufferPtr = buffer = newBuf;
+ }
+#else
+ if (bufferPtr) {
+ memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
+ FREE(buffer);
+ }
+ bufferEnd = newBuf + (bufferEnd - bufferPtr);
+ bufferPtr = buffer = newBuf;
+#endif /* not defined XML_CONTEXT_BYTES */
+ }
+ }
+ return bufferEnd;
+}
+
+enum XML_Status XMLCALL
+XML_StopParser(XML_Parser parser, XML_Bool resumable)
+{
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ if (resumable) {
+ errorCode = XML_ERROR_SUSPENDED;
+ return XML_STATUS_ERROR;
+ }
+ ps_parsing = XML_FINISHED;
+ break;
+ case XML_FINISHED:
+ errorCode = XML_ERROR_FINISHED;
+ return XML_STATUS_ERROR;
+ default:
+ if (resumable) {
+#ifdef XML_DTD
+ if (isParamEntity) {
+ errorCode = XML_ERROR_SUSPEND_PE;
+ return XML_STATUS_ERROR;
+ }
+#endif
+ ps_parsing = XML_SUSPENDED;
+ }
+ else
+ ps_parsing = XML_FINISHED;
+ }
+ return XML_STATUS_OK;
+}
+
+enum XML_Status XMLCALL
+XML_ResumeParser(XML_Parser parser)
+{
+ enum XML_Status result = XML_STATUS_OK;
+
+ if (ps_parsing != XML_SUSPENDED) {
+ errorCode = XML_ERROR_NOT_SUSPENDED;
+ return XML_STATUS_ERROR;
+ }
+ ps_parsing = XML_PARSING;
+
+ errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
+
+ if (errorCode != XML_ERROR_NONE) {
+ eventEndPtr = eventPtr;
+ processor = errorProcessor;
+ return XML_STATUS_ERROR;
+ }
+ else {
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ result = XML_STATUS_SUSPENDED;
+ break;
+ case XML_INITIALIZED:
+ case XML_PARSING:
+ if (ps_finalBuffer) {
+ ps_parsing = XML_FINISHED;
+ return result;
+ }
+ default: ;
+ }
+ }
+
+ XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
+ positionPtr = bufferPtr;
+/* BEGIN MOZILLA CHANGE (always set eventPtr/eventEndPtr) */
+ eventPtr = bufferPtr;
+ eventEndPtr = bufferPtr;
+/* END MOZILLA CHANGE */
+ return result;
+}
+
+void XMLCALL
+XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
+{
+ assert(status != NULL);
+ *status = parser->m_parsingStatus;
+}
+
+enum XML_Error XMLCALL
+XML_GetErrorCode(XML_Parser parser)
+{
+ return errorCode;
+}
+
+XML_Index XMLCALL
+XML_GetCurrentByteIndex(XML_Parser parser)
+{
+ if (eventPtr)
+ return parseEndByteIndex - (parseEndPtr - eventPtr);
+/* BEGIN MOZILLA CHANGE (fix XML_GetCurrentByteIndex) */
+#if 0
+ return -1;
+#else
+ return parseEndByteIndex;
+#endif
+/* END MOZILLA CHANGE */
+}
+
+/* BEGIN MOZILLA CHANGE (unused API) */
+#if 0
+int XMLCALL
+XML_GetCurrentByteCount(XML_Parser parser)
+{
+ if (eventEndPtr && eventPtr)
+ return (int)(eventEndPtr - eventPtr);
+ return 0;
+}
+
+const char * XMLCALL
+XML_GetInputContext(XML_Parser parser, int *offset, int *size)
+{
+#ifdef XML_CONTEXT_BYTES
+ if (eventPtr && buffer) {
+ *offset = (int)(eventPtr - buffer);
+ *size = (int)(bufferEnd - buffer);
+ return buffer;
+ }
+#endif /* defined XML_CONTEXT_BYTES */
+ return (char *) 0;
+}
+#endif
+/* END MOZILLA CHANGE */
+
+XML_Size XMLCALL
+XML_GetCurrentLineNumber(XML_Parser parser)
+{
+ if (eventPtr && eventPtr >= positionPtr) {
+ XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+ positionPtr = eventPtr;
+ }
+ return position.lineNumber + 1;
+}
+
+XML_Size XMLCALL
+XML_GetCurrentColumnNumber(XML_Parser parser)
+{
+ if (eventPtr && eventPtr >= positionPtr) {
+ XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+ positionPtr = eventPtr;
+ }
+ return position.columnNumber;
+}
+
+/* BEGIN MOZILLA CHANGE (unused API) */
+#if 0
+void XMLCALL
+XML_FreeContentModel(XML_Parser parser, XML_Content *model)
+{
+ FREE(model);
+}
+
+void * XMLCALL
+XML_MemMalloc(XML_Parser parser, size_t size)
+{
+ return MALLOC(size);
+}
+
+void * XMLCALL
+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
+{
+ return REALLOC(ptr, size);
+}
+
+void XMLCALL
+XML_MemFree(XML_Parser parser, void *ptr)
+{
+ FREE(ptr);
+}
+
+void XMLCALL
+XML_DefaultCurrent(XML_Parser parser)
+{
+ if (defaultHandler) {
+ if (openInternalEntities)
+ reportDefault(parser,
+ internalEncoding,
+ openInternalEntities->internalEventPtr,
+ openInternalEntities->internalEventEndPtr);
+ else
+ reportDefault(parser, encoding, eventPtr, eventEndPtr);
+ }
+}
+
+const XML_LChar * XMLCALL
+XML_ExpatVersion(void) {
+
+ /* V1 is used to string-ize the version number. However, it would
+ string-ize the actual version macro *names* unless we get them
+ substituted before being passed to V1. CPP is defined to expand
+ a macro, then rescan for more expansions. Thus, we use V2 to expand
+ the version macros, then CPP will expand the resulting V1() macro
+ with the correct numerals. */
+ /* ### I'm assuming cpp is portable in this respect... */
+
+#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
+#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
+
+ return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
+
+#undef V1
+#undef V2
+}
+
+XML_Expat_Version XMLCALL
+XML_ExpatVersionInfo(void)
+{
+ XML_Expat_Version version;
+
+ version.major = XML_MAJOR_VERSION;
+ version.minor = XML_MINOR_VERSION;
+ version.micro = XML_MICRO_VERSION;
+
+ return version;
+}
+
+const XML_Feature * XMLCALL
+XML_GetFeatureList(void)
+{
+ static const XML_Feature features[] = {
+ {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
+ sizeof(XML_Char)},
+ {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
+ sizeof(XML_LChar)},
+#ifdef XML_UNICODE
+ {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
+#endif
+#ifdef XML_UNICODE_WCHAR_T
+ {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
+#endif
+#ifdef XML_DTD
+ {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
+#endif
+#ifdef XML_CONTEXT_BYTES
+ {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
+ XML_CONTEXT_BYTES},
+#endif
+#ifdef XML_MIN_SIZE
+ {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
+#endif
+#ifdef XML_NS
+ {XML_FEATURE_NS, XML_L("XML_NS"), 0},
+#endif
+ {XML_FEATURE_END, NULL, 0}
+ };
+
+ return features;
+}
+#endif
+/* END MOZILLA CHANGE */
+
+/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
+const XML_Char * XMLCALL
+MOZ_XML_GetMismatchedTag(XML_Parser parser)
+{
+ return mismatch;
+}
+/* END MOZILLA CHANGE */
+
+/* Initially tag->rawName always points into the parse buffer;
+ for those TAG instances opened while the current parse buffer was
+ processed, and not yet closed, we need to store tag->rawName in a more
+ permanent location, since the parse buffer is about to be discarded.
+*/
+static XML_Bool
+storeRawNames(XML_Parser parser)
+{
+ TAG *tag = tagStack;
+ while (tag) {
+ int bufSize;
+ int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
+ char *rawNameBuf = tag->buf + nameLen;
+ /* Stop if already stored. Since tagStack is a stack, we can stop
+ at the first entry that has already been copied; everything
+ below it in the stack is already been accounted for in a
+ previous call to this function.
+ */
+ if (tag->rawName == rawNameBuf)
+ break;
+ /* For re-use purposes we need to ensure that the
+ size of tag->buf is a multiple of sizeof(XML_Char).
+ */
+ bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
+ if (bufSize > tag->bufEnd - tag->buf) {
+ char *temp = (char *)REALLOC(tag->buf, bufSize);
+ if (temp == NULL)
+ return XML_FALSE;
+ /* if tag->name.str points to tag->buf (only when namespace
+ processing is off) then we have to update it
+ */
+ if (tag->name.str == (XML_Char *)tag->buf)
+ tag->name.str = (XML_Char *)temp;
+ /* if tag->name.localPart is set (when namespace processing is on)
+ then update it as well, since it will always point into tag->buf
+ */
+ if (tag->name.localPart)
+ tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
+ (XML_Char *)tag->buf);
+ tag->buf = temp;
+ tag->bufEnd = temp + bufSize;
+ rawNameBuf = temp + nameLen;
+ }
+ memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
+ tag->rawName = rawNameBuf;
+ tag = tag->parent;
+ }
+ return XML_TRUE;
+}
+
+static enum XML_Error PTRCALL
+contentProcessor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ enum XML_Error result = doContent(parser, 0, encoding, start, end,
+ endPtr, (XML_Bool)!ps_finalBuffer);
+ if (result == XML_ERROR_NONE) {
+ if (!storeRawNames(parser))
+ return XML_ERROR_NO_MEMORY;
+ }
+ return result;
+}
+
+static enum XML_Error PTRCALL
+externalEntityInitProcessor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ enum XML_Error result = initializeEncoding(parser);
+ if (result != XML_ERROR_NONE)
+ return result;
+ processor = externalEntityInitProcessor2;
+ return externalEntityInitProcessor2(parser, start, end, endPtr);
+}
+
+static enum XML_Error PTRCALL
+externalEntityInitProcessor2(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ const char *next = start; /* XmlContentTok doesn't always set the last arg */
+ int tok = XmlContentTok(encoding, start, end, &next);
+ switch (tok) {
+ case XML_TOK_BOM:
+ /* If we are at the end of the buffer, this would cause the next stage,
+ i.e. externalEntityInitProcessor3, to pass control directly to
+ doContent (by detecting XML_TOK_NONE) without processing any xml text
+ declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
+ */
+ if (next == end && !ps_finalBuffer) {
+ *endPtr = next;
+ return XML_ERROR_NONE;
+ }
+ start = next;
+ break;
+ case XML_TOK_PARTIAL:
+ if (!ps_finalBuffer) {
+ *endPtr = start;
+ return XML_ERROR_NONE;
+ }
+ eventPtr = start;
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (!ps_finalBuffer) {
+ *endPtr = start;
+ return XML_ERROR_NONE;
+ }
+ eventPtr = start;
+ return XML_ERROR_PARTIAL_CHAR;
+ }
+ processor = externalEntityInitProcessor3;
+ return externalEntityInitProcessor3(parser, start, end, endPtr);
+}
+
+static enum XML_Error PTRCALL
+externalEntityInitProcessor3(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ int tok;
+ const char *next = start; /* XmlContentTok doesn't always set the last arg */
+ eventPtr = start;
+ tok = XmlContentTok(encoding, start, end, &next);
+ eventEndPtr = next;
+
+ switch (tok) {
+ case XML_TOK_XML_DECL:
+ {
+ enum XML_Error result;
+ result = processXmlDecl(parser, 1, start, next);
+ if (result != XML_ERROR_NONE)
+ return result;
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ *endPtr = next;
+ return XML_ERROR_NONE;
+ case XML_FINISHED:
+ return XML_ERROR_ABORTED;
+ default:
+ start = next;
+ }
+ }
+ break;
+ case XML_TOK_PARTIAL:
+ if (!ps_finalBuffer) {
+ *endPtr = start;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (!ps_finalBuffer) {
+ *endPtr = start;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_PARTIAL_CHAR;
+ }
+ processor = externalEntityContentProcessor;
+ tagLevel = 1;
+ return externalEntityContentProcessor(parser, start, end, endPtr);
+}
+
+static enum XML_Error PTRCALL
+externalEntityContentProcessor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ enum XML_Error result = doContent(parser, 1, encoding, start, end,
+ endPtr, (XML_Bool)!ps_finalBuffer);
+ if (result == XML_ERROR_NONE) {
+ if (!storeRawNames(parser))
+ return XML_ERROR_NO_MEMORY;
+ }
+ return result;
+}
+
+static enum XML_Error
+doContent(XML_Parser parser,
+ int startTagLevel,
+ const ENCODING *enc,
+ const char *s,
+ const char *end,
+ const char **nextPtr,
+ XML_Bool haveMore)
+{
+ /* save one level of indirection */
+ DTD * const dtd = _dtd;
+
+ const char **eventPP;
+ const char **eventEndPP;
+ if (enc == encoding) {
+ eventPP = &eventPtr;
+ eventEndPP = &eventEndPtr;
+ }
+ else {
+ eventPP = &(openInternalEntities->internalEventPtr);
+ eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ }
+ *eventPP = s;
+
+ for (;;) {
+ const char *next = s; /* XmlContentTok doesn't always set the last arg */
+ int tok = XmlContentTok(enc, s, end, &next);
+ *eventEndPP = next;
+ switch (tok) {
+ case XML_TOK_TRAILING_CR:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ *eventEndPP = end;
+ if (characterDataHandler) {
+ XML_Char c = 0xA;
+ characterDataHandler(handlerArg, &c, 1);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, end);
+ /* We are at the end of the final buffer, should we check for
+ XML_SUSPENDED, XML_FINISHED?
+ */
+ if (startTagLevel == 0)
+ return XML_ERROR_NO_ELEMENTS;
+ if (tagLevel != startTagLevel)
+ return XML_ERROR_ASYNC_ENTITY;
+ *nextPtr = end;
+ return XML_ERROR_NONE;
+ case XML_TOK_NONE:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ if (startTagLevel > 0) {
+ if (tagLevel != startTagLevel)
+ return XML_ERROR_ASYNC_ENTITY;
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_NO_ELEMENTS;
+ case XML_TOK_INVALID:
+ *eventPP = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_ENTITY_REF:
+ {
+ const XML_Char *name;
+ ENTITY *entity;
+ XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (ch) {
+ if (characterDataHandler)
+ characterDataHandler(handlerArg, &ch, 1);
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ }
+ name = poolStoreString(&dtd->pool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
+ poolDiscard(&dtd->pool);
+ /* First, determine if a check for an existing declaration is needed;
+ if yes, check that the entity exists, and that it is internal,
+ otherwise call the skipped entity or default handler.
+ */
+ if (!dtd->hasParamEntityRefs || dtd->standalone) {
+ if (!entity)
+ return XML_ERROR_UNDEFINED_ENTITY;
+ else if (!entity->is_internal)
+ return XML_ERROR_ENTITY_DECLARED_IN_PE;
+ }
+ else if (!entity) {
+ if (skippedEntityHandler)
+ skippedEntityHandler(handlerArg, name, 0);
+/* BEGIN MOZILLA CHANGE (http://bugzilla.mozilla.org/show_bug.cgi?id=35984) */
+#if 0
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+#else
+ return XML_ERROR_UNDEFINED_ENTITY;
+#endif
+/* END MOZILLA CHANGE */
+ }
+ if (entity->open)
+ return XML_ERROR_RECURSIVE_ENTITY_REF;
+ if (entity->notation)
+ return XML_ERROR_BINARY_ENTITY_REF;
+ if (entity->textPtr) {
+ enum XML_Error result;
+ if (!defaultExpandInternalEntities) {
+ if (skippedEntityHandler)
+ skippedEntityHandler(handlerArg, entity->name, 0);
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ }
+ result = processInternalEntity(parser, entity, XML_FALSE);
+ if (result != XML_ERROR_NONE)
+ return result;
+ }
+ else if (externalEntityRefHandler) {
+ const XML_Char *context;
+ entity->open = XML_TRUE;
+ context = getContext(parser);
+ entity->open = XML_FALSE;
+ if (!context)
+ return XML_ERROR_NO_MEMORY;
+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+ context,
+ entity->base,
+ entity->systemId,
+ entity->publicId))
+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+ poolDiscard(&tempPool);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ }
+ case XML_TOK_START_TAG_NO_ATTS:
+ /* fall through */
+ case XML_TOK_START_TAG_WITH_ATTS:
+ {
+ TAG *tag;
+ enum XML_Error result;
+ XML_Char *toPtr;
+ if (freeTagList) {
+ tag = freeTagList;
+ freeTagList = freeTagList->parent;
+ }
+ else {
+ tag = (TAG *)MALLOC(sizeof(TAG));
+ if (!tag)
+ return XML_ERROR_NO_MEMORY;
+ tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
+ if (!tag->buf) {
+ FREE(tag);
+ return XML_ERROR_NO_MEMORY;
+ }
+ tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
+ }
+ tag->bindings = NULL;
+ tag->parent = tagStack;
+ tagStack = tag;
+ tag->name.localPart = NULL;
+ tag->name.prefix = NULL;
+ tag->rawName = s + enc->minBytesPerChar;
+ tag->rawNameLength = XmlNameLength(enc, tag->rawName);
+ ++tagLevel;
+ {
+ const char *rawNameEnd = tag->rawName + tag->rawNameLength;
+ const char *fromPtr = tag->rawName;
+ toPtr = (XML_Char *)tag->buf;
+ for (;;) {
+ int bufSize;
+ int convLen;
+ XmlConvert(enc,
+ &fromPtr, rawNameEnd,
+ (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
+ convLen = (int)(toPtr - (XML_Char *)tag->buf);
+ if (fromPtr == rawNameEnd) {
+ tag->name.strLen = convLen;
+ break;
+ }
+ bufSize = (int)(tag->bufEnd - tag->buf) << 1;
+ {
+ char *temp = (char *)REALLOC(tag->buf, bufSize);
+ if (temp == NULL)
+ return XML_ERROR_NO_MEMORY;
+ tag->buf = temp;
+ tag->bufEnd = temp + bufSize;
+ toPtr = (XML_Char *)temp + convLen;
+ }
+ }
+ }
+ tag->name.str = (XML_Char *)tag->buf;
+ *toPtr = XML_T('\0');
+ result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
+ if (result)
+ return result;
+ if (startElementHandler)
+ startElementHandler(handlerArg, tag->name.str,
+ (const XML_Char **)atts);
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ poolClear(&tempPool);
+ break;
+ }
+ case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
+ /* fall through */
+ case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
+ {
+ const char *rawName = s + enc->minBytesPerChar;
+ enum XML_Error result;
+ BINDING *bindings = NULL;
+ XML_Bool noElmHandlers = XML_TRUE;
+ TAG_NAME name;
+ name.str = poolStoreString(&tempPool, enc, rawName,
+ rawName + XmlNameLength(enc, rawName));
+ if (!name.str)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ result = storeAtts(parser, enc, s, &name, &bindings);
+ if (result)
+ return result;
+ poolFinish(&tempPool);
+ if (startElementHandler) {
+ startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
+ noElmHandlers = XML_FALSE;
+ }
+ if (endElementHandler) {
+ if (startElementHandler)
+ *eventPP = *eventEndPP;
+ endElementHandler(handlerArg, name.str);
+ noElmHandlers = XML_FALSE;
+ }
+ if (noElmHandlers && defaultHandler)
+ reportDefault(parser, enc, s, next);
+ poolClear(&tempPool);
+ while (bindings) {
+ BINDING *b = bindings;
+ if (endNamespaceDeclHandler)
+ endNamespaceDeclHandler(handlerArg, b->prefix->name);
+ bindings = bindings->nextTagBinding;
+ b->nextTagBinding = freeBindingList;
+ freeBindingList = b;
+ b->prefix->binding = b->prevPrefixBinding;
+ }
+ }
+ if (tagLevel == 0)
+ return epilogProcessor(parser, next, end, nextPtr);
+ break;
+ case XML_TOK_END_TAG:
+ if (tagLevel == startTagLevel)
+ return XML_ERROR_ASYNC_ENTITY;
+ else {
+ int len;
+ const char *rawName;
+ TAG *tag = tagStack;
+ tagStack = tag->parent;
+ tag->parent = freeTagList;
+ freeTagList = tag;
+ rawName = s + enc->minBytesPerChar*2;
+ len = XmlNameLength(enc, rawName);
+ if (len != tag->rawNameLength
+ || memcmp(tag->rawName, rawName, len) != 0) {
+/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
+ /* This code is copied from the |if (endElementHandler)| block below */
+ const XML_Char *localPart;
+ const XML_Char *prefix;
+ XML_Char *uri;
+ localPart = tag->name.localPart;
+ if (ns && localPart) {
+ /* localPart and prefix may have been overwritten in
+ tag->name.str, since this points to the binding->uri
+ buffer which gets re-used; so we have to add them again
+ */
+ uri = (XML_Char *)tag->name.str + tag->name.uriLen;
+ /* don't need to check for space - already done in storeAtts() */
+ while (*localPart) *uri++ = *localPart++;
+ prefix = (XML_Char *)tag->name.prefix;
+ if (ns_triplets && prefix) {
+ *uri++ = namespaceSeparator;
+ while (*prefix) *uri++ = *prefix++;
+ }
+ *uri = XML_T('\0');
+ }
+ mismatch = tag->name.str;
+/* END MOZILLA CHANGE */
+ *eventPP = rawName;
+ return XML_ERROR_TAG_MISMATCH;
+ }
+ --tagLevel;
+ if (endElementHandler) {
+ const XML_Char *localPart;
+ const XML_Char *prefix;
+ XML_Char *uri;
+ localPart = tag->name.localPart;
+ if (ns && localPart) {
+ /* localPart and prefix may have been overwritten in
+ tag->name.str, since this points to the binding->uri
+ buffer which gets re-used; so we have to add them again
+ */
+ uri = (XML_Char *)tag->name.str + tag->name.uriLen;
+ /* don't need to check for space - already done in storeAtts() */
+ while (*localPart) *uri++ = *localPart++;
+ prefix = (XML_Char *)tag->name.prefix;
+ if (ns_triplets && prefix) {
+ *uri++ = namespaceSeparator;
+ while (*prefix) *uri++ = *prefix++;
+ }
+ *uri = XML_T('\0');
+ }
+ endElementHandler(handlerArg, tag->name.str);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ while (tag->bindings) {
+ BINDING *b = tag->bindings;
+ if (endNamespaceDeclHandler)
+ endNamespaceDeclHandler(handlerArg, b->prefix->name);
+ tag->bindings = tag->bindings->nextTagBinding;
+ b->nextTagBinding = freeBindingList;
+ freeBindingList = b;
+ b->prefix->binding = b->prevPrefixBinding;
+ }
+ if (tagLevel == 0)
+ return epilogProcessor(parser, next, end, nextPtr);
+ }
+ break;
+ case XML_TOK_CHAR_REF:
+ {
+ int n = XmlCharRefNumber(enc, s);
+ if (n < 0)
+ return XML_ERROR_BAD_CHAR_REF;
+ if (characterDataHandler) {
+ XML_Char buf[XML_ENCODE_MAX];
+ characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ }
+ break;
+ case XML_TOK_XML_DECL:
+ return XML_ERROR_MISPLACED_XML_PI;
+ case XML_TOK_DATA_NEWLINE:
+ if (characterDataHandler) {
+ XML_Char c = 0xA;
+ characterDataHandler(handlerArg, &c, 1);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ case XML_TOK_CDATA_SECT_OPEN:
+ {
+ enum XML_Error result;
+ if (startCdataSectionHandler)
+ startCdataSectionHandler(handlerArg);
+#if 0
+ /* Suppose you doing a transformation on a document that involves
+ changing only the character data. You set up a defaultHandler
+ and a characterDataHandler. The defaultHandler simply copies
+ characters through. The characterDataHandler does the
+ transformation and writes the characters out escaping them as
+ necessary. This case will fail to work if we leave out the
+ following two lines (because & and < inside CDATA sections will
+ be incorrectly escaped).
+
+ However, now we have a start/endCdataSectionHandler, so it seems
+ easier to let the user deal with this.
+ */
+ else if (characterDataHandler)
+ characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
+ if (result != XML_ERROR_NONE)
+ return result;
+ else if (!next) {
+ processor = cdataSectionProcessor;
+ return result;
+ }
+ }
+ break;
+ case XML_TOK_TRAILING_RSQB:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ if (characterDataHandler) {
+ if (MUST_CONVERT(enc, s)) {
+ ICHAR *dataPtr = (ICHAR *)dataBuf;
+ XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+ characterDataHandler(handlerArg, dataBuf,
+ (int)(dataPtr - (ICHAR *)dataBuf));
+ }
+ else
+ characterDataHandler(handlerArg,
+ (XML_Char *)s,
+ (int)((XML_Char *)end - (XML_Char *)s));
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, end);
+ /* We are at the end of the final buffer, should we check for
+ XML_SUSPENDED, XML_FINISHED?
+ */
+ if (startTagLevel == 0) {
+ *eventPP = end;
+ return XML_ERROR_NO_ELEMENTS;
+ }
+ if (tagLevel != startTagLevel) {
+ *eventPP = end;
+ return XML_ERROR_ASYNC_ENTITY;
+ }
+ *nextPtr = end;
+ return XML_ERROR_NONE;
+ case XML_TOK_DATA_CHARS:
+ if (characterDataHandler) {
+ if (MUST_CONVERT(enc, s)) {
+ for (;;) {
+ ICHAR *dataPtr = (ICHAR *)dataBuf;
+ XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+ *eventEndPP = s;
+ characterDataHandler(handlerArg, dataBuf,
+ (int)(dataPtr - (ICHAR *)dataBuf));
+ if (s == next)
+ break;
+ *eventPP = s;
+ }
+ }
+ else
+ characterDataHandler(handlerArg,
+ (XML_Char *)s,
+ (int)((XML_Char *)next - (XML_Char *)s));
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ case XML_TOK_PI:
+ if (!reportProcessingInstruction(parser, enc, s, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_COMMENT:
+ if (!reportComment(parser, enc, s, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ default:
+ if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ }
+ *eventPP = s = next;
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ *nextPtr = next;
+ return XML_ERROR_NONE;
+ case XML_FINISHED:
+ return XML_ERROR_ABORTED;
+ default: ;
+ }
+ }
+ /* not reached */
+}
+
+/* Precondition: all arguments must be non-NULL;
+ Purpose:
+ - normalize attributes
+ - check attributes for well-formedness
+ - generate namespace aware attribute names (URI, prefix)
+ - build list of attributes for startElementHandler
+ - default attributes
+ - process namespace declarations (check and report them)
+ - generate namespace aware element name (URI, prefix)
+*/
+static enum XML_Error
+storeAtts(XML_Parser parser, const ENCODING *enc,
+ const char *attStr, TAG_NAME *tagNamePtr,
+ BINDING **bindingsPtr)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ ELEMENT_TYPE *elementType;
+ int nDefaultAtts;
+ const XML_Char **appAtts; /* the attribute list for the application */
+ int attIndex = 0;
+ int prefixLen;
+ int i;
+ int n;
+ XML_Char *uri;
+ int nPrefixes = 0;
+/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
+ int nXMLNSDeclarations = 0;
+/* END MOZILLA CHANGE */
+ BINDING *binding;
+ const XML_Char *localPart;
+
+ /* lookup the element type name */
+ elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
+ if (!elementType) {
+ const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
+ sizeof(ELEMENT_TYPE));
+ if (!elementType)
+ return XML_ERROR_NO_MEMORY;
+ if (ns && !setElementTypePrefix(parser, elementType))
+ return XML_ERROR_NO_MEMORY;
+ }
+ nDefaultAtts = elementType->nDefaultAtts;
+
+ /* get the attributes from the tokenizer */
+ n = XmlGetAttributes(enc, attStr, attsSize, atts);
+ if (n + nDefaultAtts > attsSize) {
+ int oldAttsSize = attsSize;
+ ATTRIBUTE *temp;
+ attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
+ temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
+ if (temp == NULL)
+ return XML_ERROR_NO_MEMORY;
+ atts = temp;
+ if (n > oldAttsSize)
+ XmlGetAttributes(enc, attStr, n, atts);
+ }
+
+ appAtts = (const XML_Char **)atts;
+ for (i = 0; i < n; i++) {
+ /* add the name and value to the attribute list */
+ ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
+ atts[i].name
+ + XmlNameLength(enc, atts[i].name));
+ if (!attId)
+ return XML_ERROR_NO_MEMORY;
+ /* Detect duplicate attributes by their QNames. This does not work when
+ namespace processing is turned on and different prefixes for the same
+ namespace are used. For this case we have a check further down.
+ */
+ if ((attId->name)[-1]) {
+ if (enc == encoding)
+ eventPtr = atts[i].name;
+ return XML_ERROR_DUPLICATE_ATTRIBUTE;
+ }
+ (attId->name)[-1] = 1;
+ appAtts[attIndex++] = attId->name;
+ if (!atts[i].normalized) {
+ enum XML_Error result;
+ XML_Bool isCdata = XML_TRUE;
+
+ /* figure out whether declared as other than CDATA */
+ if (attId->maybeTokenized) {
+ int j;
+ for (j = 0; j < nDefaultAtts; j++) {
+ if (attId == elementType->defaultAtts[j].id) {
+ isCdata = elementType->defaultAtts[j].isCdata;
+ break;
+ }
+ }
+ }
+
+ /* normalize the attribute value */
+ result = storeAttributeValue(parser, enc, isCdata,
+ atts[i].valuePtr, atts[i].valueEnd,
+ &tempPool);
+ if (result)
+ return result;
+ appAtts[attIndex] = poolStart(&tempPool);
+ poolFinish(&tempPool);
+ }
+ else {
+ /* the value did not need normalizing */
+ appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
+ atts[i].valueEnd);
+ if (appAtts[attIndex] == 0)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ }
+ /* handle prefixed attribute names */
+ if (attId->prefix) {
+ if (attId->xmlns) {
+ /* deal with namespace declarations here */
+ enum XML_Error result = addBinding(parser, attId->prefix, attId,
+ appAtts[attIndex], bindingsPtr);
+ if (result)
+ return result;
+/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
+#if 0
+ --attIndex;
+#else
+ attIndex++;
+ nXMLNSDeclarations++;
+ (attId->name)[-1] = 3;
+#endif
+/* END MOZILLA CHANGE */
+ }
+ else {
+ /* deal with other prefixed names later */
+ attIndex++;
+ nPrefixes++;
+ (attId->name)[-1] = 2;
+ }
+ }
+ else
+ attIndex++;
+ }
+
+ /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
+ nSpecifiedAtts = attIndex;
+ if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
+ for (i = 0; i < attIndex; i += 2)
+ if (appAtts[i] == elementType->idAtt->name) {
+ idAttIndex = i;
+ break;
+ }
+ }
+ else
+ idAttIndex = -1;
+
+ /* do attribute defaulting */
+ for (i = 0; i < nDefaultAtts; i++) {
+ const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
+ if (!(da->id->name)[-1] && da->value) {
+ if (da->id->prefix) {
+ if (da->id->xmlns) {
+ enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
+ da->value, bindingsPtr);
+ if (result)
+ return result;
+/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
+ (da->id->name)[-1] = 3;
+ nXMLNSDeclarations++;
+ appAtts[attIndex++] = da->id->name;
+ appAtts[attIndex++] = da->value;
+/* END MOZILLA CHANGE */
+ }
+ else {
+ (da->id->name)[-1] = 2;
+ nPrefixes++;
+ appAtts[attIndex++] = da->id->name;
+ appAtts[attIndex++] = da->value;
+ }
+ }
+ else {
+ (da->id->name)[-1] = 1;
+ appAtts[attIndex++] = da->id->name;
+ appAtts[attIndex++] = da->value;
+ }
+ }
+ }
+ appAtts[attIndex] = 0;
+
+ /* expand prefixed attribute names, check for duplicates,
+ and clear flags that say whether attributes were specified */
+ i = 0;
+/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
+#if 0
+ if (nPrefixes) {
+#else
+ if (nPrefixes || nXMLNSDeclarations) {
+#endif
+/* END MOZILLA CHANGE */
+ int j; /* hash table index */
+ unsigned long version = nsAttsVersion;
+ int nsAttsSize = (int)1 << nsAttsPower;
+/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
+ if (nPrefixes) {
+/* END MOZILLA CHANGE */
+ /* size of hash table must be at least 2 * (# of prefixed attributes) */
+ if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
+ NS_ATT *temp;
+ /* hash table size must also be a power of 2 and >= 8 */
+ while (nPrefixes >> nsAttsPower++);
+ if (nsAttsPower < 3)
+ nsAttsPower = 3;
+ nsAttsSize = (int)1 << nsAttsPower;
+ temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
+ if (!temp)
+ return XML_ERROR_NO_MEMORY;
+ nsAtts = temp;
+ version = 0; /* force re-initialization of nsAtts hash table */
+ }
+ /* using a version flag saves us from initializing nsAtts every time */
+ if (!version) { /* initialize version flags when version wraps around */
+ version = INIT_ATTS_VERSION;
+ for (j = nsAttsSize; j != 0; )
+ nsAtts[--j].version = version;
+ }
+ nsAttsVersion = --version;
+/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
+ }
+/* END MOZILLA CHANGE */
+
+ /* expand prefixed names and check for duplicates */
+ for (; i < attIndex; i += 2) {
+ const XML_Char *s = appAtts[i];
+ if (s[-1] == 2) { /* prefixed */
+ ATTRIBUTE_ID *id;
+ const BINDING *b;
+ unsigned long uriHash = 0;
+ ((XML_Char *)s)[-1] = 0; /* clear flag */
+ id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
+ b = id->prefix->binding;
+ if (!b)
+ return XML_ERROR_UNBOUND_PREFIX;
+
+ /* as we expand the name we also calculate its hash value */
+ for (j = 0; j < b->uriLen; j++) {
+ const XML_Char c = b->uri[j];
+ if (!poolAppendChar(&tempPool, c))
+ return XML_ERROR_NO_MEMORY;
+ uriHash = CHAR_HASH(uriHash, c);
+ }
+ while (*s++ != XML_T(':'))
+ ;
+ do { /* copies null terminator */
+ const XML_Char c = *s;
+ if (!poolAppendChar(&tempPool, *s))
+ return XML_ERROR_NO_MEMORY;
+ uriHash = CHAR_HASH(uriHash, c);
+ } while (*s++);
+
+ { /* Check hash table for duplicate of expanded name (uriName).
+ Derived from code in lookup(HASH_TABLE *table, ...).
+ */
+ unsigned char step = 0;
+ unsigned long mask = nsAttsSize - 1;
+ j = uriHash & mask; /* index into hash table */
+ while (nsAtts[j].version == version) {
+ /* for speed we compare stored hash values first */
+ if (uriHash == nsAtts[j].hash) {
+ const XML_Char *s1 = poolStart(&tempPool);
+ const XML_Char *s2 = nsAtts[j].uriName;
+ /* s1 is null terminated, but not s2 */
+ for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
+ if (*s1 == 0)
+ return XML_ERROR_DUPLICATE_ATTRIBUTE;
+ }
+ if (!step)
+ step = PROBE_STEP(uriHash, mask, nsAttsPower);
+ j < step ? (j += nsAttsSize - step) : (j -= step);
+ }
+ }
+
+ if (ns_triplets) { /* append namespace separator and prefix */
+ tempPool.ptr[-1] = namespaceSeparator;
+ s = b->prefix->name;
+ do {
+ if (!poolAppendChar(&tempPool, *s))
+ return XML_ERROR_NO_MEMORY;
+ } while (*s++);
+ }
+
+ /* store expanded name in attribute list */
+ s = poolStart(&tempPool);
+ poolFinish(&tempPool);
+ appAtts[i] = s;
+
+ /* fill empty slot with new version, uriName and hash value */
+ nsAtts[j].version = version;
+ nsAtts[j].hash = uriHash;
+ nsAtts[j].uriName = s;
+
+/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
+#if 0
+ if (!--nPrefixes)
+#else
+ if (!--nPrefixes && !nXMLNSDeclarations) {
+#endif
+/* END MOZILLA CHANGE */
+ i += 2;
+ break;
+ }
+ }
+/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
+ else if (s[-1] == 3) { /* xmlns attribute */
+ static const XML_Char xmlnsNamespace[] = {
+ 'h', 't', 't', 'p', ':', '/', '/',
+ 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
+ '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
+ };
+ static const XML_Char xmlnsPrefix[] = {
+ 'x', 'm', 'l', 'n', 's', '\0'
+ };
+
+ ((XML_Char *)s)[-1] = 0; /* clear flag */
+ if (!poolAppendString(&tempPool, xmlnsNamespace)
+ || !poolAppendChar(&tempPool, namespaceSeparator))
+ return XML_ERROR_NO_MEMORY;
+ s += sizeof(xmlnsPrefix) / sizeof(xmlnsPrefix[0]) - 1;
+ if (*s == XML_T(':')) {
+ ++s;
+ do { /* copies null terminator */
+ if (!poolAppendChar(&tempPool, *s))
+ return XML_ERROR_NO_MEMORY;
+ } while (*s++);
+ if (ns_triplets) { /* append namespace separator and prefix */
+ tempPool.ptr[-1] = namespaceSeparator;
+ if (!poolAppendString(&tempPool, xmlnsPrefix)
+ || !poolAppendChar(&tempPool, '\0'))
+ return XML_ERROR_NO_MEMORY;
+ }
+ }
+ else {
+ /* xlmns attribute without a prefix. */
+ if (!poolAppendString(&tempPool, xmlnsPrefix)
+ || !poolAppendChar(&tempPool, '\0'))
+ return XML_ERROR_NO_MEMORY;
+ }
+
+ /* store expanded name in attribute list */
+ s = poolStart(&tempPool);
+ poolFinish(&tempPool);
+ appAtts[i] = s;
+
+ if (!--nXMLNSDeclarations && !nPrefixes) {
+ i += 2;
+ break;
+ }
+ }
+/* END MOZILLA CHANGE */
+ else /* not prefixed */
+ ((XML_Char *)s)[-1] = 0; /* clear flag */
+ }
+ }
+ /* clear flags for the remaining attributes */
+ for (; i < attIndex; i += 2)
+ ((XML_Char *)(appAtts[i]))[-1] = 0;
+ for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
+ binding->attId->name[-1] = 0;
+
+ if (!ns)
+ return XML_ERROR_NONE;
+
+ /* expand the element type name */
+ if (elementType->prefix) {
+ binding = elementType->prefix->binding;
+ if (!binding)
+ return XML_ERROR_UNBOUND_PREFIX;
+ localPart = tagNamePtr->str;
+ while (*localPart++ != XML_T(':'))
+ ;
+ }
+ else if (dtd->defaultPrefix.binding) {
+ binding = dtd->defaultPrefix.binding;
+ localPart = tagNamePtr->str;
+ }
+ else
+ return XML_ERROR_NONE;
+ prefixLen = 0;
+ if (ns_triplets && binding->prefix->name) {
+ for (; binding->prefix->name[prefixLen++];)
+ ; /* prefixLen includes null terminator */
+ }
+ tagNamePtr->localPart = localPart;
+ tagNamePtr->uriLen = binding->uriLen;
+ tagNamePtr->prefix = binding->prefix->name;
+ tagNamePtr->prefixLen = prefixLen;
+ for (i = 0; localPart[i++];)
+ ; /* i includes null terminator */
+ n = i + binding->uriLen + prefixLen;
+ if (n > binding->uriAlloc) {
+ TAG *p;
+ uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
+ if (!uri)
+ return XML_ERROR_NO_MEMORY;
+ binding->uriAlloc = n + EXPAND_SPARE;
+ memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
+ for (p = tagStack; p; p = p->parent)
+ if (p->name.str == binding->uri)
+ p->name.str = uri;
+ FREE(binding->uri);
+ binding->uri = uri;
+ }
+ /* if namespaceSeparator != '\0' then uri includes it already */
+ uri = binding->uri + binding->uriLen;
+ memcpy(uri, localPart, i * sizeof(XML_Char));
+ /* we always have a namespace separator between localPart and prefix */
+ if (prefixLen) {
+ uri += i - 1;
+ *uri = namespaceSeparator; /* replace null terminator */
+ memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
+ }
+ tagNamePtr->str = binding->uri;
+ return XML_ERROR_NONE;
+}
+
+/* addBinding() overwrites the value of prefix->binding without checking.
+ Therefore one must keep track of the old value outside of addBinding().
+*/
+static enum XML_Error
+addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
+ const XML_Char *uri, BINDING **bindingsPtr)
+{
+ static const XML_Char xmlNamespace[] = {
+ 'h', 't', 't', 'p', ':', '/', '/',
+ 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
+ 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
+ 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
+ };
+ static const int xmlLen =
+ (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
+ static const XML_Char xmlnsNamespace[] = {
+ 'h', 't', 't', 'p', ':', '/', '/',
+ 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
+ '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
+ };
+ static const int xmlnsLen =
+ (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
+
+ XML_Bool mustBeXML = XML_FALSE;
+ XML_Bool isXML = XML_TRUE;
+ XML_Bool isXMLNS = XML_TRUE;
+
+ BINDING *b;
+ int len;
+
+ /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
+ if (*uri == XML_T('\0') && prefix->name)
+ return XML_ERROR_UNDECLARING_PREFIX;
+
+ if (prefix->name
+ && prefix->name[0] == XML_T('x')
+ && prefix->name[1] == XML_T('m')
+ && prefix->name[2] == XML_T('l')) {
+
+ /* Not allowed to bind xmlns */
+ if (prefix->name[3] == XML_T('n')
+ && prefix->name[4] == XML_T('s')
+ && prefix->name[5] == XML_T('\0'))
+ return XML_ERROR_RESERVED_PREFIX_XMLNS;
+
+ if (prefix->name[3] == XML_T('\0'))
+ mustBeXML = XML_TRUE;
+ }
+
+ for (len = 0; uri[len]; len++) {
+ if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
+ isXML = XML_FALSE;
+
+ if (!mustBeXML && isXMLNS
+ && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
+ isXMLNS = XML_FALSE;
+ }
+ isXML = isXML && len == xmlLen;
+ isXMLNS = isXMLNS && len == xmlnsLen;
+
+ if (mustBeXML != isXML)
+ return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
+ : XML_ERROR_RESERVED_NAMESPACE_URI;
+
+ if (isXMLNS)
+ return XML_ERROR_RESERVED_NAMESPACE_URI;
+
+ if (namespaceSeparator)
+ len++;
+ if (freeBindingList) {
+ b = freeBindingList;
+ if (len > b->uriAlloc) {
+ XML_Char *temp = (XML_Char *)REALLOC(b->uri,
+ sizeof(XML_Char) * (len + EXPAND_SPARE));
+ if (temp == NULL)
+ return XML_ERROR_NO_MEMORY;
+ b->uri = temp;
+ b->uriAlloc = len + EXPAND_SPARE;
+ }
+ freeBindingList = b->nextTagBinding;
+ }
+ else {
+ b = (BINDING *)MALLOC(sizeof(BINDING));
+ if (!b)
+ return XML_ERROR_NO_MEMORY;
+ b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
+ if (!b->uri) {
+ FREE(b);
+ return XML_ERROR_NO_MEMORY;
+ }
+ b->uriAlloc = len + EXPAND_SPARE;
+ }
+ b->uriLen = len;
+ memcpy(b->uri, uri, len * sizeof(XML_Char));
+ if (namespaceSeparator)
+ b->uri[len - 1] = namespaceSeparator;
+ b->prefix = prefix;
+ b->attId = attId;
+ b->prevPrefixBinding = prefix->binding;
+ /* NULL binding when default namespace undeclared */
+ if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
+ prefix->binding = NULL;
+ else
+ prefix->binding = b;
+ b->nextTagBinding = *bindingsPtr;
+ *bindingsPtr = b;
+ /* if attId == NULL then we are not starting a namespace scope */
+ if (attId && startNamespaceDeclHandler)
+ startNamespaceDeclHandler(handlerArg, prefix->name,
+ prefix->binding ? uri : 0);
+ return XML_ERROR_NONE;
+}
+
+/* The idea here is to avoid using stack for each CDATA section when
+ the whole file is parsed with one call.
+*/
+static enum XML_Error PTRCALL
+cdataSectionProcessor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ enum XML_Error result = doCdataSection(parser, encoding, &start, end,
+ endPtr, (XML_Bool)!ps_finalBuffer);
+ if (result != XML_ERROR_NONE)
+ return result;
+ if (start) {
+ if (parentParser) { /* we are parsing an external entity */
+ processor = externalEntityContentProcessor;
+ return externalEntityContentProcessor(parser, start, end, endPtr);
+ }
+ else {
+ processor = contentProcessor;
+ return contentProcessor(parser, start, end, endPtr);
+ }
+ }
+ return result;
+}
+
+/* startPtr gets set to non-null if the section is closed, and to null if
+ the section is not yet closed.
+*/
+static enum XML_Error
+doCdataSection(XML_Parser parser,
+ const ENCODING *enc,
+ const char **startPtr,
+ const char *end,
+ const char **nextPtr,
+ XML_Bool haveMore)
+{
+ const char *s = *startPtr;
+ const char **eventPP;
+ const char **eventEndPP;
+ if (enc == encoding) {
+ eventPP = &eventPtr;
+ *eventPP = s;
+ eventEndPP = &eventEndPtr;
+ }
+ else {
+ eventPP = &(openInternalEntities->internalEventPtr);
+ eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ }
+ *eventPP = s;
+ *startPtr = NULL;
+
+ for (;;) {
+ const char *next;
+ int tok = XmlCdataSectionTok(enc, s, end, &next);
+ *eventEndPP = next;
+ switch (tok) {
+ case XML_TOK_CDATA_SECT_CLOSE:
+ if (endCdataSectionHandler)
+ endCdataSectionHandler(handlerArg);
+#if 0
+ /* see comment under XML_TOK_CDATA_SECT_OPEN */
+ else if (characterDataHandler)
+ characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ *startPtr = next;
+ *nextPtr = next;
+ if (ps_parsing == XML_FINISHED)
+ return XML_ERROR_ABORTED;
+ else
+ return XML_ERROR_NONE;
+ case XML_TOK_DATA_NEWLINE:
+ if (characterDataHandler) {
+ XML_Char c = 0xA;
+ characterDataHandler(handlerArg, &c, 1);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ case XML_TOK_DATA_CHARS:
+ if (characterDataHandler) {
+ if (MUST_CONVERT(enc, s)) {
+ for (;;) {
+ ICHAR *dataPtr = (ICHAR *)dataBuf;
+ XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+ *eventEndPP = next;
+ characterDataHandler(handlerArg, dataBuf,
+ (int)(dataPtr - (ICHAR *)dataBuf));
+ if (s == next)
+ break;
+ *eventPP = s;
+ }
+ }
+ else
+ characterDataHandler(handlerArg,
+ (XML_Char *)s,
+ (int)((XML_Char *)next - (XML_Char *)s));
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ case XML_TOK_INVALID:
+ *eventPP = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_PARTIAL:
+ case XML_TOK_NONE:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_UNCLOSED_CDATA_SECTION;
+ default:
+ *eventPP = next;
+ return XML_ERROR_UNEXPECTED_STATE;
+ }
+
+ *eventPP = s = next;
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ *nextPtr = next;
+ return XML_ERROR_NONE;
+ case XML_FINISHED:
+ return XML_ERROR_ABORTED;
+ default: ;
+ }
+ }
+ /* not reached */
+}
+
+#ifdef XML_DTD
+
+/* The idea here is to avoid using stack for each IGNORE section when
+ the whole file is parsed with one call.
+*/
+static enum XML_Error PTRCALL
+ignoreSectionProcessor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
+ endPtr, (XML_Bool)!ps_finalBuffer);
+ if (result != XML_ERROR_NONE)
+ return result;
+ if (start) {
+ processor = prologProcessor;
+ return prologProcessor(parser, start, end, endPtr);
+ }
+ return result;
+}
+
+/* startPtr gets set to non-null is the section is closed, and to null
+ if the section is not yet closed.
+*/
+static enum XML_Error
+doIgnoreSection(XML_Parser parser,
+ const ENCODING *enc,
+ const char **startPtr,
+ const char *end,
+ const char **nextPtr,
+ XML_Bool haveMore)
+{
+ const char *next;
+ int tok;
+ const char *s = *startPtr;
+ const char **eventPP;
+ const char **eventEndPP;
+ if (enc == encoding) {
+ eventPP = &eventPtr;
+ *eventPP = s;
+ eventEndPP = &eventEndPtr;
+ }
+ else {
+ eventPP = &(openInternalEntities->internalEventPtr);
+ eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ }
+ *eventPP = s;
+ *startPtr = NULL;
+ tok = XmlIgnoreSectionTok(enc, s, end, &next);
+ *eventEndPP = next;
+ switch (tok) {
+ case XML_TOK_IGNORE_SECT:
+ if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ *startPtr = next;
+ *nextPtr = next;
+ if (ps_parsing == XML_FINISHED)
+ return XML_ERROR_ABORTED;
+ else
+ return XML_ERROR_NONE;
+ case XML_TOK_INVALID:
+ *eventPP = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_PARTIAL:
+ case XML_TOK_NONE:
+ if (haveMore) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
+ default:
+ *eventPP = next;
+ return XML_ERROR_UNEXPECTED_STATE;
+ }
+ /* not reached */
+}
+
+#endif /* XML_DTD */
+
+static enum XML_Error
+initializeEncoding(XML_Parser parser)
+{
+ const char *s;
+#ifdef XML_UNICODE
+ char encodingBuf[128];
+ if (!protocolEncodingName)
+ s = NULL;
+ else {
+ int i;
+ for (i = 0; protocolEncodingName[i]; i++) {
+ if (i == sizeof(encodingBuf) - 1
+ || (protocolEncodingName[i] & ~0x7f) != 0) {
+ encodingBuf[0] = '\0';
+ break;
+ }
+ encodingBuf[i] = (char)protocolEncodingName[i];
+ }
+ encodingBuf[i] = '\0';
+ s = encodingBuf;
+ }
+#else
+ s = protocolEncodingName;
+#endif
+ if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
+ return XML_ERROR_NONE;
+ return handleUnknownEncoding(parser, protocolEncodingName);
+}
+
+static enum XML_Error
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
+ const char *s, const char *next)
+{
+ const char *encodingName = NULL;
+ const XML_Char *storedEncName = NULL;
+ const ENCODING *newEncoding = NULL;
+ const char *version = NULL;
+ const char *versionend;
+ const XML_Char *storedversion = NULL;
+ int standalone = -1;
+ if (!(ns
+ ? XmlParseXmlDeclNS
+ : XmlParseXmlDecl)(isGeneralTextEntity,
+ encoding,
+ s,
+ next,
+ &eventPtr,
+ &version,
+ &versionend,
+ &encodingName,
+ &newEncoding,
+ &standalone)) {
+ if (isGeneralTextEntity)
+ return XML_ERROR_TEXT_DECL;
+ else
+ return XML_ERROR_XML_DECL;
+ }
+ if (!isGeneralTextEntity && standalone == 1) {
+ _dtd->standalone = XML_TRUE;
+#ifdef XML_DTD
+ if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
+ paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif /* XML_DTD */
+ }
+ if (xmlDeclHandler) {
+ if (encodingName != NULL) {
+ storedEncName = poolStoreString(&temp2Pool,
+ encoding,
+ encodingName,
+ encodingName
+ + XmlNameLength(encoding, encodingName));
+ if (!storedEncName)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&temp2Pool);
+ }
+ if (version) {
+ storedversion = poolStoreString(&temp2Pool,
+ encoding,
+ version,
+ versionend - encoding->minBytesPerChar);
+ if (!storedversion)
+ return XML_ERROR_NO_MEMORY;
+ }
+ xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, encoding, s, next);
+ if (protocolEncodingName == NULL) {
+ if (newEncoding) {
+ if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
+ eventPtr = encodingName;
+ return XML_ERROR_INCORRECT_ENCODING;
+ }
+ encoding = newEncoding;
+ }
+ else if (encodingName) {
+ enum XML_Error result;
+ if (!storedEncName) {
+ storedEncName = poolStoreString(
+ &temp2Pool, encoding, encodingName,
+ encodingName + XmlNameLength(encoding, encodingName));
+ if (!storedEncName)
+ return XML_ERROR_NO_MEMORY;
+ }
+ result = handleUnknownEncoding(parser, storedEncName);
+ poolClear(&temp2Pool);
+ if (result == XML_ERROR_UNKNOWN_ENCODING)
+ eventPtr = encodingName;
+ return result;
+ }
+ }
+
+ if (storedEncName || storedversion)
+ poolClear(&temp2Pool);
+
+ return XML_ERROR_NONE;
+}
+
+static enum XML_Error
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+ if (unknownEncodingHandler) {
+ XML_Encoding info;
+ int i;
+ for (i = 0; i < 256; i++)
+ info.map[i] = -1;
+ info.convert = NULL;
+ info.data = NULL;
+ info.release = NULL;
+ if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
+ &info)) {
+ ENCODING *enc;
+ unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
+ if (!unknownEncodingMem) {
+ if (info.release)
+ info.release(info.data);
+ return XML_ERROR_NO_MEMORY;
+ }
+ enc = (ns
+ ? XmlInitUnknownEncodingNS
+ : XmlInitUnknownEncoding)(unknownEncodingMem,
+ info.map,
+ info.convert,
+ info.data);
+ if (enc) {
+ unknownEncodingData = info.data;
+ unknownEncodingRelease = info.release;
+ encoding = enc;
+ return XML_ERROR_NONE;
+ }
+ }
+ if (info.release != NULL)
+ info.release(info.data);
+ }
+ return XML_ERROR_UNKNOWN_ENCODING;
+}
+
+static enum XML_Error PTRCALL
+prologInitProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ enum XML_Error result = initializeEncoding(parser);
+ if (result != XML_ERROR_NONE)
+ return result;
+ processor = prologProcessor;
+ return prologProcessor(parser, s, end, nextPtr);
+}
+
+#ifdef XML_DTD
+
+static enum XML_Error PTRCALL
+externalParEntInitProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ enum XML_Error result = initializeEncoding(parser);
+ if (result != XML_ERROR_NONE)
+ return result;
+
+ /* we know now that XML_Parse(Buffer) has been called,
+ so we consider the external parameter entity read */
+ _dtd->paramEntityRead = XML_TRUE;
+
+ if (prologState.inEntityValue) {
+ processor = entityValueInitProcessor;
+ return entityValueInitProcessor(parser, s, end, nextPtr);
+ }
+ else {
+ processor = externalParEntProcessor;
+ return externalParEntProcessor(parser, s, end, nextPtr);
+ }
+}
+
+static enum XML_Error PTRCALL
+entityValueInitProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ int tok;
+ const char *start = s;
+ const char *next = start;
+ eventPtr = start;
+
+ for (;;) {
+ tok = XmlPrologTok(encoding, start, end, &next);
+ eventEndPtr = next;
+ if (tok <= 0) {
+ if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ switch (tok) {
+ case XML_TOK_INVALID:
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_NONE: /* start == end */
+ default:
+ break;
+ }
+ /* found end of entity value - can store it now */
+ return storeEntityValue(parser, encoding, s, end);
+ }
+ else if (tok == XML_TOK_XML_DECL) {
+ enum XML_Error result;
+ result = processXmlDecl(parser, 0, start, next);
+ if (result != XML_ERROR_NONE)
+ return result;
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ *nextPtr = next;
+ return XML_ERROR_NONE;
+ case XML_FINISHED:
+ return XML_ERROR_ABORTED;
+ default:
+ *nextPtr = next;
+ }
+ /* stop scanning for text declaration - we found one */
+ processor = entityValueProcessor;
+ return entityValueProcessor(parser, next, end, nextPtr);
+ }
+ /* If we are at the end of the buffer, this would cause XmlPrologTok to
+ return XML_TOK_NONE on the next call, which would then cause the
+ function to exit with *nextPtr set to s - that is what we want for other
+ tokens, but not for the BOM - we would rather like to skip it;
+ then, when this routine is entered the next time, XmlPrologTok will
+ return XML_TOK_INVALID, since the BOM is still in the buffer
+ */
+ else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
+ *nextPtr = next;
+ return XML_ERROR_NONE;
+ }
+ start = next;
+ eventPtr = start;
+ }
+}
+
+static enum XML_Error PTRCALL
+externalParEntProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ const char *next = s;
+ int tok;
+
+ tok = XmlPrologTok(encoding, s, end, &next);
+ if (tok <= 0) {
+ if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ switch (tok) {
+ case XML_TOK_INVALID:
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_NONE: /* start == end */
+ default:
+ break;
+ }
+ }
+ /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
+ However, when parsing an external subset, doProlog will not accept a BOM
+ as valid, and report a syntax error, so we have to skip the BOM
+ */
+ else if (tok == XML_TOK_BOM) {
+ s = next;
+ tok = XmlPrologTok(encoding, s, end, &next);
+ }
+
+ processor = prologProcessor;
+ return doProlog(parser, encoding, s, end, tok, next,
+ nextPtr, (XML_Bool)!ps_finalBuffer);
+}
+
+static enum XML_Error PTRCALL
+entityValueProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ const char *start = s;
+ const char *next = s;
+ const ENCODING *enc = encoding;
+ int tok;
+
+ for (;;) {
+ tok = XmlPrologTok(enc, start, end, &next);
+ if (tok <= 0) {
+ if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ switch (tok) {
+ case XML_TOK_INVALID:
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_NONE: /* start == end */
+ default:
+ break;
+ }
+ /* found end of entity value - can store it now */
+ return storeEntityValue(parser, enc, s, end);
+ }
+ start = next;
+ }
+}
+
+#endif /* XML_DTD */
+
+static enum XML_Error PTRCALL
+prologProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ const char *next = s;
+ int tok = XmlPrologTok(encoding, s, end, &next);
+ return doProlog(parser, encoding, s, end, tok, next,
+ nextPtr, (XML_Bool)!ps_finalBuffer);
+}
+
+static enum XML_Error
+doProlog(XML_Parser parser,
+ const ENCODING *enc,
+ const char *s,
+ const char *end,
+ int tok,
+ const char *next,
+ const char **nextPtr,
+ XML_Bool haveMore)
+{
+#ifdef XML_DTD
+ static const XML_Char externalSubsetName[] = { '#' , '\0' };
+#endif /* XML_DTD */
+ static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
+ static const XML_Char atypeID[] = { 'I', 'D', '\0' };
+ static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
+ static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
+ static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
+ static const XML_Char atypeENTITIES[] =
+ { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
+ static const XML_Char atypeNMTOKEN[] = {
+ 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
+ static const XML_Char atypeNMTOKENS[] = {
+ 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
+ static const XML_Char notationPrefix[] = {
+ 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
+ static const XML_Char enumValueSep[] = { '|', '\0' };
+ static const XML_Char enumValueStart[] = { '(', '\0' };
+
+ /* save one level of indirection */
+ DTD * const dtd = _dtd;
+
+ const char **eventPP;
+ const char **eventEndPP;
+ enum XML_Content_Quant quant;
+
+ if (enc == encoding) {
+ eventPP = &eventPtr;
+ eventEndPP = &eventEndPtr;
+ }
+ else {
+ eventPP = &(openInternalEntities->internalEventPtr);
+ eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ }
+
+ for (;;) {
+ int role;
+ XML_Bool handleDefault = XML_TRUE;
+ *eventPP = s;
+ *eventEndPP = next;
+ if (tok <= 0) {
+ if (haveMore && tok != XML_TOK_INVALID) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ switch (tok) {
+ case XML_TOK_INVALID:
+ *eventPP = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_NONE:
+#ifdef XML_DTD
+ /* for internal PE NOT referenced between declarations */
+ if (enc != encoding && !openInternalEntities->betweenDecl) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ /* WFC: PE Between Declarations - must check that PE contains
+ complete markup, not only for external PEs, but also for
+ internal PEs if the reference occurs between declarations.
+ */
+ if (isParamEntity || enc != encoding) {
+ if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
+ == XML_ROLE_ERROR)
+ return XML_ERROR_INCOMPLETE_PE;
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+#endif /* XML_DTD */
+ return XML_ERROR_NO_ELEMENTS;
+ default:
+ tok = -tok;
+ next = end;
+ break;
+ }
+ }
+ role = XmlTokenRole(&prologState, tok, s, next, enc);
+ switch (role) {
+ case XML_ROLE_XML_DECL:
+ {
+ enum XML_Error result = processXmlDecl(parser, 0, s, next);
+ if (result != XML_ERROR_NONE)
+ return result;
+ enc = encoding;
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_DOCTYPE_NAME:
+ if (startDoctypeDeclHandler) {
+ doctypeName = poolStoreString(&tempPool, enc, s, next);
+ if (!doctypeName)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ doctypePubid = NULL;
+ handleDefault = XML_FALSE;
+ }
+ doctypeSysid = NULL; /* always initialize to NULL */
+ break;
+ case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
+ if (startDoctypeDeclHandler) {
+ startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
+ doctypePubid, 1);
+ doctypeName = NULL;
+ poolClear(&tempPool);
+ handleDefault = XML_FALSE;
+ }
+ break;
+#ifdef XML_DTD
+ case XML_ROLE_TEXT_DECL:
+ {
+ enum XML_Error result = processXmlDecl(parser, 1, s, next);
+ if (result != XML_ERROR_NONE)
+ return result;
+ enc = encoding;
+ handleDefault = XML_FALSE;
+ }
+ break;
+#endif /* XML_DTD */
+ case XML_ROLE_DOCTYPE_PUBLIC_ID:
+#ifdef XML_DTD
+ useForeignDTD = XML_FALSE;
+ declEntity = (ENTITY *)lookup(&dtd->paramEntities,
+ externalSubsetName,
+ sizeof(ENTITY));
+ if (!declEntity)
+ return XML_ERROR_NO_MEMORY;
+#endif /* XML_DTD */
+ dtd->hasParamEntityRefs = XML_TRUE;
+ if (startDoctypeDeclHandler) {
+ if (!XmlIsPublicId(enc, s, next, eventPP))
+ return XML_ERROR_PUBLICID;
+ doctypePubid = poolStoreString(&tempPool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!doctypePubid)
+ return XML_ERROR_NO_MEMORY;
+ normalizePublicId((XML_Char *)doctypePubid);
+ poolFinish(&tempPool);
+ handleDefault = XML_FALSE;
+ goto alreadyChecked;
+ }
+ /* fall through */
+ case XML_ROLE_ENTITY_PUBLIC_ID:
+ if (!XmlIsPublicId(enc, s, next, eventPP))
+ return XML_ERROR_PUBLICID;
+ alreadyChecked:
+ if (dtd->keepProcessing && declEntity) {
+ XML_Char *tem = poolStoreString(&dtd->pool,
+ enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!tem)
+ return XML_ERROR_NO_MEMORY;
+ normalizePublicId(tem);
+ declEntity->publicId = tem;
+ poolFinish(&dtd->pool);
+ if (entityDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_DOCTYPE_CLOSE:
+ if (doctypeName) {
+ startDoctypeDeclHandler(handlerArg, doctypeName,
+ doctypeSysid, doctypePubid, 0);
+ poolClear(&tempPool);
+ handleDefault = XML_FALSE;
+ }
+ /* doctypeSysid will be non-NULL in the case of a previous
+ XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
+ was not set, indicating an external subset
+ */
+#ifdef XML_DTD
+ if (doctypeSysid || useForeignDTD) {
+ XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
+ dtd->hasParamEntityRefs = XML_TRUE;
+ if (paramEntityParsing && externalEntityRefHandler) {
+ ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
+ externalSubsetName,
+ sizeof(ENTITY));
+ if (!entity)
+ return XML_ERROR_NO_MEMORY;
+ if (useForeignDTD)
+ entity->base = curBase;
+ dtd->paramEntityRead = XML_FALSE;
+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+ 0,
+ entity->base,
+ entity->systemId,
+ entity->publicId))
+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+ if (dtd->paramEntityRead) {
+ if (!dtd->standalone &&
+ notStandaloneHandler &&
+ !notStandaloneHandler(handlerArg))
+ return XML_ERROR_NOT_STANDALONE;
+ }
+ /* if we didn't read the foreign DTD then this means that there
+ is no external subset and we must reset dtd->hasParamEntityRefs
+ */
+ else if (!doctypeSysid)
+ dtd->hasParamEntityRefs = hadParamEntityRefs;
+ /* end of DTD - no need to update dtd->keepProcessing */
+ }
+ useForeignDTD = XML_FALSE;
+ }
+#endif /* XML_DTD */
+ if (endDoctypeDeclHandler) {
+ endDoctypeDeclHandler(handlerArg);
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_INSTANCE_START:
+#ifdef XML_DTD
+ /* if there is no DOCTYPE declaration then now is the
+ last chance to read the foreign DTD
+ */
+ if (useForeignDTD) {
+ XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
+ dtd->hasParamEntityRefs = XML_TRUE;
+ if (paramEntityParsing && externalEntityRefHandler) {
+ ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
+ externalSubsetName,
+ sizeof(ENTITY));
+ if (!entity)
+ return XML_ERROR_NO_MEMORY;
+ entity->base = curBase;
+ dtd->paramEntityRead = XML_FALSE;
+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+ 0,
+ entity->base,
+ entity->systemId,
+ entity->publicId))
+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+ if (dtd->paramEntityRead) {
+ if (!dtd->standalone &&
+ notStandaloneHandler &&
+ !notStandaloneHandler(handlerArg))
+ return XML_ERROR_NOT_STANDALONE;
+ }
+ /* if we didn't read the foreign DTD then this means that there
+ is no external subset and we must reset dtd->hasParamEntityRefs
+ */
+ else
+ dtd->hasParamEntityRefs = hadParamEntityRefs;
+ /* end of DTD - no need to update dtd->keepProcessing */
+ }
+ }
+#endif /* XML_DTD */
+ processor = contentProcessor;
+ return contentProcessor(parser, s, end, nextPtr);
+ case XML_ROLE_ATTLIST_ELEMENT_NAME:
+ declElementType = getElementType(parser, enc, s, next);
+ if (!declElementType)
+ return XML_ERROR_NO_MEMORY;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_NAME:
+ declAttributeId = getAttributeId(parser, enc, s, next);
+ if (!declAttributeId)
+ return XML_ERROR_NO_MEMORY;
+ declAttributeIsCdata = XML_FALSE;
+ declAttributeType = NULL;
+ declAttributeIsId = XML_FALSE;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
+ declAttributeIsCdata = XML_TRUE;
+ declAttributeType = atypeCDATA;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_ID:
+ declAttributeIsId = XML_TRUE;
+ declAttributeType = atypeID;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
+ declAttributeType = atypeIDREF;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
+ declAttributeType = atypeIDREFS;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
+ declAttributeType = atypeENTITY;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
+ declAttributeType = atypeENTITIES;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
+ declAttributeType = atypeNMTOKEN;
+ goto checkAttListDeclHandler;
+ case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
+ declAttributeType = atypeNMTOKENS;
+ checkAttListDeclHandler:
+ if (dtd->keepProcessing && attlistDeclHandler)
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
+ case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
+ if (dtd->keepProcessing && attlistDeclHandler) {
+ const XML_Char *prefix;
+ if (declAttributeType) {
+ prefix = enumValueSep;
+ }
+ else {
+ prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
+ ? notationPrefix
+ : enumValueStart);
+ }
+ if (!poolAppendString(&tempPool, prefix))
+ return XML_ERROR_NO_MEMORY;
+ if (!poolAppend(&tempPool, enc, s, next))
+ return XML_ERROR_NO_MEMORY;
+ declAttributeType = tempPool.start;
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
+ case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
+ if (dtd->keepProcessing) {
+ if (!defineAttribute(declElementType, declAttributeId,
+ declAttributeIsCdata, declAttributeIsId,
+ 0, parser))
+ return XML_ERROR_NO_MEMORY;
+ if (attlistDeclHandler && declAttributeType) {
+ if (*declAttributeType == XML_T('(')
+ || (*declAttributeType == XML_T('N')
+ && declAttributeType[1] == XML_T('O'))) {
+ /* Enumerated or Notation type */
+ if (!poolAppendChar(&tempPool, XML_T(')'))
+ || !poolAppendChar(&tempPool, XML_T('\0')))
+ return XML_ERROR_NO_MEMORY;
+ declAttributeType = tempPool.start;
+ poolFinish(&tempPool);
+ }
+ *eventEndPP = s;
+ attlistDeclHandler(handlerArg, declElementType->name,
+ declAttributeId->name, declAttributeType,
+ 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
+ poolClear(&tempPool);
+ handleDefault = XML_FALSE;
+ }
+ }
+ break;
+ case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
+ case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
+ if (dtd->keepProcessing) {
+ const XML_Char *attVal;
+ enum XML_Error result =
+ storeAttributeValue(parser, enc, declAttributeIsCdata,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar,
+ &dtd->pool);
+ if (result)
+ return result;
+ attVal = poolStart(&dtd->pool);
+ poolFinish(&dtd->pool);
+ /* ID attributes aren't allowed to have a default */
+ if (!defineAttribute(declElementType, declAttributeId,
+ declAttributeIsCdata, XML_FALSE, attVal, parser))
+ return XML_ERROR_NO_MEMORY;
+ if (attlistDeclHandler && declAttributeType) {
+ if (*declAttributeType == XML_T('(')
+ || (*declAttributeType == XML_T('N')
+ && declAttributeType[1] == XML_T('O'))) {
+ /* Enumerated or Notation type */
+ if (!poolAppendChar(&tempPool, XML_T(')'))
+ || !poolAppendChar(&tempPool, XML_T('\0')))
+ return XML_ERROR_NO_MEMORY;
+ declAttributeType = tempPool.start;
+ poolFinish(&tempPool);
+ }
+ *eventEndPP = s;
+ attlistDeclHandler(handlerArg, declElementType->name,
+ declAttributeId->name, declAttributeType,
+ attVal,
+ role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
+ poolClear(&tempPool);
+ handleDefault = XML_FALSE;
+ }
+ }
+ break;
+ case XML_ROLE_ENTITY_VALUE:
+ if (dtd->keepProcessing) {
+ enum XML_Error result = storeEntityValue(parser, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (declEntity) {
+ declEntity->textPtr = poolStart(&dtd->entityValuePool);
+ declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
+ poolFinish(&dtd->entityValuePool);
+ if (entityDeclHandler) {
+ *eventEndPP = s;
+ entityDeclHandler(handlerArg,
+ declEntity->name,
+ declEntity->is_param,
+ declEntity->textPtr,
+ declEntity->textLen,
+ curBase, 0, 0, 0);
+ handleDefault = XML_FALSE;
+ }
+ }
+ else
+ poolDiscard(&dtd->entityValuePool);
+ if (result != XML_ERROR_NONE)
+ return result;
+ }
+ break;
+ case XML_ROLE_DOCTYPE_SYSTEM_ID:
+#ifdef XML_DTD
+ useForeignDTD = XML_FALSE;
+#endif /* XML_DTD */
+ dtd->hasParamEntityRefs = XML_TRUE;
+ if (startDoctypeDeclHandler) {
+ doctypeSysid = poolStoreString(&tempPool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (doctypeSysid == NULL)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ handleDefault = XML_FALSE;
+ }
+#ifdef XML_DTD
+ else
+ /* use externalSubsetName to make doctypeSysid non-NULL
+ for the case where no startDoctypeDeclHandler is set */
+ doctypeSysid = externalSubsetName;
+#endif /* XML_DTD */
+ if (!dtd->standalone
+#ifdef XML_DTD
+ && !paramEntityParsing
+#endif /* XML_DTD */
+ && notStandaloneHandler
+ && !notStandaloneHandler(handlerArg))
+ return XML_ERROR_NOT_STANDALONE;
+#ifndef XML_DTD
+ break;
+#else /* XML_DTD */
+ if (!declEntity) {
+ declEntity = (ENTITY *)lookup(&dtd->paramEntities,
+ externalSubsetName,
+ sizeof(ENTITY));
+ if (!declEntity)
+ return XML_ERROR_NO_MEMORY;
+ declEntity->publicId = NULL;
+ }
+ /* fall through */
+#endif /* XML_DTD */
+ case XML_ROLE_ENTITY_SYSTEM_ID:
+ if (dtd->keepProcessing && declEntity) {
+ declEntity->systemId = poolStoreString(&dtd->pool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!declEntity->systemId)
+ return XML_ERROR_NO_MEMORY;
+ declEntity->base = curBase;
+ poolFinish(&dtd->pool);
+ if (entityDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_ENTITY_COMPLETE:
+ if (dtd->keepProcessing && declEntity && entityDeclHandler) {
+ *eventEndPP = s;
+ entityDeclHandler(handlerArg,
+ declEntity->name,
+ declEntity->is_param,
+ 0,0,
+ declEntity->base,
+ declEntity->systemId,
+ declEntity->publicId,
+ 0);
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_ENTITY_NOTATION_NAME:
+ if (dtd->keepProcessing && declEntity) {
+ declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
+ if (!declEntity->notation)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&dtd->pool);
+ if (unparsedEntityDeclHandler) {
+ *eventEndPP = s;
+ unparsedEntityDeclHandler(handlerArg,
+ declEntity->name,
+ declEntity->base,
+ declEntity->systemId,
+ declEntity->publicId,
+ declEntity->notation);
+ handleDefault = XML_FALSE;
+ }
+ else if (entityDeclHandler) {
+ *eventEndPP = s;
+ entityDeclHandler(handlerArg,
+ declEntity->name,
+ 0,0,0,
+ declEntity->base,
+ declEntity->systemId,
+ declEntity->publicId,
+ declEntity->notation);
+ handleDefault = XML_FALSE;
+ }
+ }
+ break;
+ case XML_ROLE_GENERAL_ENTITY_NAME:
+ {
+ if (XmlPredefinedEntityName(enc, s, next)) {
+ declEntity = NULL;
+ break;
+ }
+ if (dtd->keepProcessing) {
+ const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
+ sizeof(ENTITY));
+ if (!declEntity)
+ return XML_ERROR_NO_MEMORY;
+ if (declEntity->name != name) {
+ poolDiscard(&dtd->pool);
+ declEntity = NULL;
+ }
+ else {
+ poolFinish(&dtd->pool);
+ declEntity->publicId = NULL;
+ declEntity->is_param = XML_FALSE;
+ /* if we have a parent parser or are reading an internal parameter
+ entity, then the entity declaration is not considered "internal"
+ */
+ declEntity->is_internal = !(parentParser || openInternalEntities);
+ if (entityDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ }
+ else {
+ poolDiscard(&dtd->pool);
+ declEntity = NULL;
+ }
+ }
+ break;
+ case XML_ROLE_PARAM_ENTITY_NAME:
+#ifdef XML_DTD
+ if (dtd->keepProcessing) {
+ const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ declEntity = (ENTITY *)lookup(&dtd->paramEntities,
+ name, sizeof(ENTITY));
+ if (!declEntity)
+ return XML_ERROR_NO_MEMORY;
+ if (declEntity->name != name) {
+ poolDiscard(&dtd->pool);
+ declEntity = NULL;
+ }
+ else {
+ poolFinish(&dtd->pool);
+ declEntity->publicId = NULL;
+ declEntity->is_param = XML_TRUE;
+ /* if we have a parent parser or are reading an internal parameter
+ entity, then the entity declaration is not considered "internal"
+ */
+ declEntity->is_internal = !(parentParser || openInternalEntities);
+ if (entityDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ }
+ else {
+ poolDiscard(&dtd->pool);
+ declEntity = NULL;
+ }
+#else /* not XML_DTD */
+ declEntity = NULL;
+#endif /* XML_DTD */
+ break;
+ case XML_ROLE_NOTATION_NAME:
+ declNotationPublicId = NULL;
+ declNotationName = NULL;
+ if (notationDeclHandler) {
+ declNotationName = poolStoreString(&tempPool, enc, s, next);
+ if (!declNotationName)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_NOTATION_PUBLIC_ID:
+ if (!XmlIsPublicId(enc, s, next, eventPP))
+ return XML_ERROR_PUBLICID;
+ if (declNotationName) { /* means notationDeclHandler != NULL */
+ XML_Char *tem = poolStoreString(&tempPool,
+ enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!tem)
+ return XML_ERROR_NO_MEMORY;
+ normalizePublicId(tem);
+ declNotationPublicId = tem;
+ poolFinish(&tempPool);
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_NOTATION_SYSTEM_ID:
+ if (declNotationName && notationDeclHandler) {
+ const XML_Char *systemId
+ = poolStoreString(&tempPool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!systemId)
+ return XML_ERROR_NO_MEMORY;
+ *eventEndPP = s;
+ notationDeclHandler(handlerArg,
+ declNotationName,
+ curBase,
+ systemId,
+ declNotationPublicId);
+ handleDefault = XML_FALSE;
+ }
+ poolClear(&tempPool);
+ break;
+ case XML_ROLE_NOTATION_NO_SYSTEM_ID:
+ if (declNotationPublicId && notationDeclHandler) {
+ *eventEndPP = s;
+ notationDeclHandler(handlerArg,
+ declNotationName,
+ curBase,
+ 0,
+ declNotationPublicId);
+ handleDefault = XML_FALSE;
+ }
+ poolClear(&tempPool);
+ break;
+ case XML_ROLE_ERROR:
+ switch (tok) {
+ case XML_TOK_PARAM_ENTITY_REF:
+ /* PE references in internal subset are
+ not allowed within declarations. */
+ return XML_ERROR_PARAM_ENTITY_REF;
+ case XML_TOK_XML_DECL:
+ return XML_ERROR_MISPLACED_XML_PI;
+ default:
+ return XML_ERROR_SYNTAX;
+ }
+#ifdef XML_DTD
+ case XML_ROLE_IGNORE_SECT:
+ {
+ enum XML_Error result;
+ if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ handleDefault = XML_FALSE;
+ result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
+ if (result != XML_ERROR_NONE)
+ return result;
+ else if (!next) {
+ processor = ignoreSectionProcessor;
+ return result;
+ }
+ }
+ break;
+#endif /* XML_DTD */
+ case XML_ROLE_GROUP_OPEN:
+ if (prologState.level >= groupSize) {
+ if (groupSize) {
+ char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
+ if (temp == NULL)
+ return XML_ERROR_NO_MEMORY;
+ groupConnector = temp;
+ if (dtd->scaffIndex) {
+ int *temp = (int *)REALLOC(dtd->scaffIndex,
+ groupSize * sizeof(int));
+ if (temp == NULL)
+ return XML_ERROR_NO_MEMORY;
+ dtd->scaffIndex = temp;
+ }
+ }
+ else {
+ groupConnector = (char *)MALLOC(groupSize = 32);
+ if (!groupConnector)
+ return XML_ERROR_NO_MEMORY;
+ }
+ }
+ groupConnector[prologState.level] = 0;
+ if (dtd->in_eldecl) {
+ int myindex = nextScaffoldPart(parser);
+ if (myindex < 0)
+ return XML_ERROR_NO_MEMORY;
+ dtd->scaffIndex[dtd->scaffLevel] = myindex;
+ dtd->scaffLevel++;
+ dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
+ if (elementDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ break;
+ case XML_ROLE_GROUP_SEQUENCE:
+ if (groupConnector[prologState.level] == '|')
+ return XML_ERROR_SYNTAX;
+ groupConnector[prologState.level] = ',';
+ if (dtd->in_eldecl && elementDeclHandler)
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_GROUP_CHOICE:
+ if (groupConnector[prologState.level] == ',')
+ return XML_ERROR_SYNTAX;
+ if (dtd->in_eldecl
+ && !groupConnector[prologState.level]
+ && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
+ != XML_CTYPE_MIXED)
+ ) {
+ dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
+ = XML_CTYPE_CHOICE;
+ if (elementDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ groupConnector[prologState.level] = '|';
+ break;
+ case XML_ROLE_PARAM_ENTITY_REF:
+#ifdef XML_DTD
+ case XML_ROLE_INNER_PARAM_ENTITY_REF:
+ dtd->hasParamEntityRefs = XML_TRUE;
+ if (!paramEntityParsing)
+ dtd->keepProcessing = dtd->standalone;
+ else {
+ const XML_Char *name;
+ ENTITY *entity;
+ name = poolStoreString(&dtd->pool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
+ poolDiscard(&dtd->pool);
+ /* first, determine if a check for an existing declaration is needed;
+ if yes, check that the entity exists, and that it is internal,
+ otherwise call the skipped entity handler
+ */
+ if (prologState.documentEntity &&
+ (dtd->standalone
+ ? !openInternalEntities
+ : !dtd->hasParamEntityRefs)) {
+ if (!entity)
+ return XML_ERROR_UNDEFINED_ENTITY;
+ else if (!entity->is_internal)
+ return XML_ERROR_ENTITY_DECLARED_IN_PE;
+ }
+ else if (!entity) {
+ dtd->keepProcessing = dtd->standalone;
+ /* cannot report skipped entities in declarations */
+ if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
+ skippedEntityHandler(handlerArg, name, 1);
+ handleDefault = XML_FALSE;
+ }
+ break;
+ }
+ if (entity->open)
+ return XML_ERROR_RECURSIVE_ENTITY_REF;
+ if (entity->textPtr) {
+ enum XML_Error result;
+ XML_Bool betweenDecl =
+ (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
+ result = processInternalEntity(parser, entity, betweenDecl);
+ if (result != XML_ERROR_NONE)
+ return result;
+ handleDefault = XML_FALSE;
+ break;
+ }
+ if (externalEntityRefHandler) {
+ dtd->paramEntityRead = XML_FALSE;
+ entity->open = XML_TRUE;
+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+/* BEGIN MOZILLA CHANGE (http://bugzilla.mozilla.org/show_bug.cgi?id=191482) */
+#if 0
+ 0,
+#else
+ entity->name,
+#endif
+/* END MOZILLA CHANGE */
+ entity->base,
+ entity->systemId,
+ entity->publicId)) {
+ entity->open = XML_FALSE;
+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+ }
+ entity->open = XML_FALSE;
+ handleDefault = XML_FALSE;
+ if (!dtd->paramEntityRead) {
+ dtd->keepProcessing = dtd->standalone;
+ break;
+ }
+ }
+ else {
+ dtd->keepProcessing = dtd->standalone;
+ break;
+ }
+ }
+#endif /* XML_DTD */
+ if (!dtd->standalone &&
+ notStandaloneHandler &&
+ !notStandaloneHandler(handlerArg))
+ return XML_ERROR_NOT_STANDALONE;
+ break;
+
+ /* Element declaration stuff */
+
+ case XML_ROLE_ELEMENT_NAME:
+ if (elementDeclHandler) {
+ declElementType = getElementType(parser, enc, s, next);
+ if (!declElementType)
+ return XML_ERROR_NO_MEMORY;
+ dtd->scaffLevel = 0;
+ dtd->scaffCount = 0;
+ dtd->in_eldecl = XML_TRUE;
+ handleDefault = XML_FALSE;
+ }
+ break;
+
+ case XML_ROLE_CONTENT_ANY:
+ case XML_ROLE_CONTENT_EMPTY:
+ if (dtd->in_eldecl) {
+ if (elementDeclHandler) {
+ XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
+ if (!content)
+ return XML_ERROR_NO_MEMORY;
+ content->quant = XML_CQUANT_NONE;
+ content->name = NULL;
+ content->numchildren = 0;
+ content->children = NULL;
+ content->type = ((role == XML_ROLE_CONTENT_ANY) ?
+ XML_CTYPE_ANY :
+ XML_CTYPE_EMPTY);
+ *eventEndPP = s;
+ elementDeclHandler(handlerArg, declElementType->name, content);
+ handleDefault = XML_FALSE;
+ }
+ dtd->in_eldecl = XML_FALSE;
+ }
+ break;
+
+ case XML_ROLE_CONTENT_PCDATA:
+ if (dtd->in_eldecl) {
+ dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
+ = XML_CTYPE_MIXED;
+ if (elementDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ break;
+
+ case XML_ROLE_CONTENT_ELEMENT:
+ quant = XML_CQUANT_NONE;
+ goto elementContent;
+ case XML_ROLE_CONTENT_ELEMENT_OPT:
+ quant = XML_CQUANT_OPT;
+ goto elementContent;
+ case XML_ROLE_CONTENT_ELEMENT_REP:
+ quant = XML_CQUANT_REP;
+ goto elementContent;
+ case XML_ROLE_CONTENT_ELEMENT_PLUS:
+ quant = XML_CQUANT_PLUS;
+ elementContent:
+ if (dtd->in_eldecl) {
+ ELEMENT_TYPE *el;
+ const XML_Char *name;
+ int nameLen;
+ const char *nxt = (quant == XML_CQUANT_NONE
+ ? next
+ : next - enc->minBytesPerChar);
+ int myindex = nextScaffoldPart(parser);
+ if (myindex < 0)
+ return XML_ERROR_NO_MEMORY;
+ dtd->scaffold[myindex].type = XML_CTYPE_NAME;
+ dtd->scaffold[myindex].quant = quant;
+ el = getElementType(parser, enc, s, nxt);
+ if (!el)
+ return XML_ERROR_NO_MEMORY;
+ name = el->name;
+ dtd->scaffold[myindex].name = name;
+ nameLen = 0;
+ for (; name[nameLen++]; );
+ dtd->contentStringLen += nameLen;
+ if (elementDeclHandler)
+ handleDefault = XML_FALSE;
+ }
+ break;
+
+ case XML_ROLE_GROUP_CLOSE:
+ quant = XML_CQUANT_NONE;
+ goto closeGroup;
+ case XML_ROLE_GROUP_CLOSE_OPT:
+ quant = XML_CQUANT_OPT;
+ goto closeGroup;
+ case XML_ROLE_GROUP_CLOSE_REP:
+ quant = XML_CQUANT_REP;
+ goto closeGroup;
+ case XML_ROLE_GROUP_CLOSE_PLUS:
+ quant = XML_CQUANT_PLUS;
+ closeGroup:
+ if (dtd->in_eldecl) {
+ if (elementDeclHandler)
+ handleDefault = XML_FALSE;
+ dtd->scaffLevel--;
+ dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
+ if (dtd->scaffLevel == 0) {
+ if (!handleDefault) {
+ XML_Content *model = build_model(parser);
+ if (!model)
+ return XML_ERROR_NO_MEMORY;
+ *eventEndPP = s;
+ elementDeclHandler(handlerArg, declElementType->name, model);
+ }
+ dtd->in_eldecl = XML_FALSE;
+ dtd->contentStringLen = 0;
+ }
+ }
+ break;
+ /* End element declaration stuff */
+
+ case XML_ROLE_PI:
+ if (!reportProcessingInstruction(parser, enc, s, next))
+ return XML_ERROR_NO_MEMORY;
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_COMMENT:
+ if (!reportComment(parser, enc, s, next))
+ return XML_ERROR_NO_MEMORY;
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_NONE:
+ switch (tok) {
+ case XML_TOK_BOM:
+ handleDefault = XML_FALSE;
+ break;
+ }
+ break;
+ case XML_ROLE_DOCTYPE_NONE:
+ if (startDoctypeDeclHandler)
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_ENTITY_NONE:
+ if (dtd->keepProcessing && entityDeclHandler)
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_NOTATION_NONE:
+ if (notationDeclHandler)
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_ATTLIST_NONE:
+ if (dtd->keepProcessing && attlistDeclHandler)
+ handleDefault = XML_FALSE;
+ break;
+ case XML_ROLE_ELEMENT_NONE:
+ if (elementDeclHandler)
+ handleDefault = XML_FALSE;
+ break;
+ } /* end of big switch */
+
+ if (handleDefault && defaultHandler)
+ reportDefault(parser, enc, s, next);
+
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ *nextPtr = next;
+ return XML_ERROR_NONE;
+ case XML_FINISHED:
+ return XML_ERROR_ABORTED;
+ default:
+ s = next;
+ tok = XmlPrologTok(enc, s, end, &next);
+ }
+ }
+ /* not reached */
+}
+
+static enum XML_Error PTRCALL
+epilogProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ processor = epilogProcessor;
+ eventPtr = s;
+ for (;;) {
+ const char *next = NULL;
+ int tok = XmlPrologTok(encoding, s, end, &next);
+ eventEndPtr = next;
+ switch (tok) {
+ /* report partial linebreak - it might be the last token */
+ case -XML_TOK_PROLOG_S:
+ if (defaultHandler) {
+ reportDefault(parser, encoding, s, next);
+ if (ps_parsing == XML_FINISHED)
+ return XML_ERROR_ABORTED;
+ }
+ *nextPtr = next;
+ return XML_ERROR_NONE;
+ case XML_TOK_NONE:
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ case XML_TOK_PROLOG_S:
+ if (defaultHandler)
+ reportDefault(parser, encoding, s, next);
+ break;
+ case XML_TOK_PI:
+ if (!reportProcessingInstruction(parser, encoding, s, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_COMMENT:
+ if (!reportComment(parser, encoding, s, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_INVALID:
+ eventPtr = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ if (!ps_finalBuffer) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (!ps_finalBuffer) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_PARTIAL_CHAR;
+ default:
+ return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
+ }
+ eventPtr = s = next;
+ switch (ps_parsing) {
+ case XML_SUSPENDED:
+ *nextPtr = next;
+ return XML_ERROR_NONE;
+ case XML_FINISHED:
+ return XML_ERROR_ABORTED;
+ default: ;
+ }
+ }
+}
+
+static enum XML_Error
+processInternalEntity(XML_Parser parser, ENTITY *entity,
+ XML_Bool betweenDecl)
+{
+ const char *textStart, *textEnd;
+ const char *next;
+ enum XML_Error result;
+ OPEN_INTERNAL_ENTITY *openEntity;
+
+ if (freeInternalEntities) {
+ openEntity = freeInternalEntities;
+ freeInternalEntities = openEntity->next;
+ }
+ else {
+ openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
+ if (!openEntity)
+ return XML_ERROR_NO_MEMORY;
+ }
+ entity->open = XML_TRUE;
+ entity->processed = 0;
+ openEntity->next = openInternalEntities;
+ openInternalEntities = openEntity;
+ openEntity->entity = entity;
+ openEntity->startTagLevel = tagLevel;
+ openEntity->betweenDecl = betweenDecl;
+ openEntity->internalEventPtr = NULL;
+ openEntity->internalEventEndPtr = NULL;
+ textStart = (char *)entity->textPtr;
+ textEnd = (char *)(entity->textPtr + entity->textLen);
+
+#ifdef XML_DTD
+ if (entity->is_param) {
+ int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
+ result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
+ next, &next, XML_FALSE);
+ }
+ else
+#endif /* XML_DTD */
+ result = doContent(parser, tagLevel, internalEncoding, textStart,
+ textEnd, &next, XML_FALSE);
+
+ if (result == XML_ERROR_NONE) {
+ if (textEnd != next && ps_parsing == XML_SUSPENDED) {
+ entity->processed = (int)(next - textStart);
+ processor = internalEntityProcessor;
+ }
+ else {
+ entity->open = XML_FALSE;
+/* BEGIN MOZILLA CHANGE (Deal with parser interruption from nested entities) */
+#if 0
+ openInternalEntities = openEntity->next;
+#else
+ if (openInternalEntities == openEntity) {
+ openInternalEntities = openEntity->next;
+ }
+ else {
+ /* openEntity should be closed, but it contains an inner entity that is
+ still open. Remove openEntity from the openInternalEntities linked
+ list by looking for the inner entity in the list that links to
+ openEntity and fixing up its 'next' member
+ */
+ OPEN_INTERNAL_ENTITY *innerOpenEntity = openInternalEntities;
+ do {
+ if (innerOpenEntity->next == openEntity) {
+ innerOpenEntity->next = openEntity->next;
+ break;
+ }
+ } while ((innerOpenEntity = innerOpenEntity->next));
+ }
+#endif
+/* END MOZILLA CHANGE */
+ /* put openEntity back in list of free instances */
+ openEntity->next = freeInternalEntities;
+ freeInternalEntities = openEntity;
+ }
+ }
+ return result;
+}
+
+static enum XML_Error PTRCALL
+internalEntityProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ ENTITY *entity;
+ const char *textStart, *textEnd;
+ const char *next;
+ enum XML_Error result;
+ OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
+ if (!openEntity)
+ return XML_ERROR_UNEXPECTED_STATE;
+
+ entity = openEntity->entity;
+ textStart = ((char *)entity->textPtr) + entity->processed;
+ textEnd = (char *)(entity->textPtr + entity->textLen);
+
+#ifdef XML_DTD
+ if (entity->is_param) {
+ int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
+ result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
+ next, &next, XML_FALSE);
+ }
+ else
+#endif /* XML_DTD */
+ result = doContent(parser, openEntity->startTagLevel, internalEncoding,
+ textStart, textEnd, &next, XML_FALSE);
+
+ if (result != XML_ERROR_NONE)
+ return result;
+ else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
+ entity->processed = (int)(next - (char *)entity->textPtr);
+ return result;
+ }
+ else {
+ entity->open = XML_FALSE;
+ openInternalEntities = openEntity->next;
+ /* put openEntity back in list of free instances */
+ openEntity->next = freeInternalEntities;
+ freeInternalEntities = openEntity;
+ }
+
+#ifdef XML_DTD
+ if (entity->is_param) {
+ int tok;
+ processor = prologProcessor;
+ tok = XmlPrologTok(encoding, s, end, &next);
+ return doProlog(parser, encoding, s, end, tok, next, nextPtr,
+ (XML_Bool)!ps_finalBuffer);
+ }
+ else
+#endif /* XML_DTD */
+ {
+ processor = contentProcessor;
+ /* see externalEntityContentProcessor vs contentProcessor */
+ return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
+ nextPtr, (XML_Bool)!ps_finalBuffer);
+ }
+}
+
+static enum XML_Error PTRCALL
+errorProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ return errorCode;
+}
+
+static enum XML_Error
+storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
+ const char *ptr, const char *end,
+ STRING_POOL *pool)
+{
+ enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
+ end, pool);
+ if (result)
+ return result;
+ if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
+ poolChop(pool);
+ if (!poolAppendChar(pool, XML_T('\0')))
+ return XML_ERROR_NO_MEMORY;
+ return XML_ERROR_NONE;
+}
+
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
+ const char *ptr, const char *end,
+ STRING_POOL *pool)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ for (;;) {
+ const char *next;
+ int tok = XmlAttributeValueTok(enc, ptr, end, &next);
+ switch (tok) {
+ case XML_TOK_NONE:
+ return XML_ERROR_NONE;
+ case XML_TOK_INVALID:
+ if (enc == encoding)
+ eventPtr = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_CHAR_REF:
+ {
+ XML_Char buf[XML_ENCODE_MAX];
+ int i;
+ int n = XmlCharRefNumber(enc, ptr);
+ if (n < 0) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_BAD_CHAR_REF;
+ }
+ if (!isCdata
+ && n == 0x20 /* space */
+ && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+ break;
+ n = XmlEncode(n, (ICHAR *)buf);
+ if (!n) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_BAD_CHAR_REF;
+ }
+ for (i = 0; i < n; i++) {
+ if (!poolAppendChar(pool, buf[i]))
+ return XML_ERROR_NO_MEMORY;
+ }
+ }
+ break;
+ case XML_TOK_DATA_CHARS:
+ if (!poolAppend(pool, enc, ptr, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_TRAILING_CR:
+ next = ptr + enc->minBytesPerChar;
+ /* fall through */
+ case XML_TOK_ATTRIBUTE_VALUE_S:
+ case XML_TOK_DATA_NEWLINE:
+ if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+ break;
+ if (!poolAppendChar(pool, 0x20))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_ENTITY_REF:
+ {
+ const XML_Char *name;
+ ENTITY *entity;
+ char checkEntityDecl;
+ XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
+ ptr + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (ch) {
+ if (!poolAppendChar(pool, ch))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ }
+ name = poolStoreString(&temp2Pool, enc,
+ ptr + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
+ poolDiscard(&temp2Pool);
+ /* First, determine if a check for an existing declaration is needed;
+ if yes, check that the entity exists, and that it is internal.
+ */
+ if (pool == &dtd->pool) /* are we called from prolog? */
+ checkEntityDecl =
+#ifdef XML_DTD
+ prologState.documentEntity &&
+#endif /* XML_DTD */
+ (dtd->standalone
+ ? !openInternalEntities
+ : !dtd->hasParamEntityRefs);
+ else /* if (pool == &tempPool): we are called from content */
+ checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
+ if (checkEntityDecl) {
+ if (!entity)
+ return XML_ERROR_UNDEFINED_ENTITY;
+ else if (!entity->is_internal)
+ return XML_ERROR_ENTITY_DECLARED_IN_PE;
+ }
+ else if (!entity) {
+ /* Cannot report skipped entity here - see comments on
+ skippedEntityHandler.
+ if (skippedEntityHandler)
+ skippedEntityHandler(handlerArg, name, 0);
+ */
+ /* Cannot call the default handler because this would be
+ out of sync with the call to the startElementHandler.
+ if ((pool == &tempPool) && defaultHandler)
+ reportDefault(parser, enc, ptr, next);
+ */
+/* BEGIN MOZILLA CHANGE (http://bugzilla.mozilla.org/show_bug.cgi?id=35984) */
+#if 0
+ break;
+#else
+ return XML_ERROR_UNDEFINED_ENTITY;
+#endif
+/* END MOZILLA CHANGE */
+ }
+ if (entity->open) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_RECURSIVE_ENTITY_REF;
+ }
+ if (entity->notation) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_BINARY_ENTITY_REF;
+ }
+ if (!entity->textPtr) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
+ }
+ else {
+ enum XML_Error result;
+ const XML_Char *textEnd = entity->textPtr + entity->textLen;
+ entity->open = XML_TRUE;
+ result = appendAttributeValue(parser, internalEncoding, isCdata,
+ (char *)entity->textPtr,
+ (char *)textEnd, pool);
+ entity->open = XML_FALSE;
+ if (result)
+ return result;
+ }
+ }
+ break;
+ default:
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_UNEXPECTED_STATE;
+ }
+ ptr = next;
+ }
+ /* not reached */
+}
+
+static enum XML_Error
+storeEntityValue(XML_Parser parser,
+ const ENCODING *enc,
+ const char *entityTextPtr,
+ const char *entityTextEnd)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ STRING_POOL *pool = &(dtd->entityValuePool);
+ enum XML_Error result = XML_ERROR_NONE;
+#ifdef XML_DTD
+ int oldInEntityValue = prologState.inEntityValue;
+ prologState.inEntityValue = 1;
+#endif /* XML_DTD */
+ /* never return Null for the value argument in EntityDeclHandler,
+ since this would indicate an external entity; therefore we
+ have to make sure that entityValuePool.start is not null */
+ if (!pool->blocks) {
+ if (!poolGrow(pool))
+ return XML_ERROR_NO_MEMORY;
+ }
+
+ for (;;) {
+ const char *next;
+ int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
+ switch (tok) {
+ case XML_TOK_PARAM_ENTITY_REF:
+#ifdef XML_DTD
+ if (isParamEntity || enc != encoding) {
+ const XML_Char *name;
+ ENTITY *entity;
+ name = poolStoreString(&tempPool, enc,
+ entityTextPtr + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!name) {
+ result = XML_ERROR_NO_MEMORY;
+ goto endEntityValue;
+ }
+ entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
+ poolDiscard(&tempPool);
+ if (!entity) {
+ /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
+ /* cannot report skipped entity here - see comments on
+ skippedEntityHandler
+ if (skippedEntityHandler)
+ skippedEntityHandler(handlerArg, name, 0);
+ */
+ dtd->keepProcessing = dtd->standalone;
+ goto endEntityValue;
+ }
+ if (entity->open) {
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ result = XML_ERROR_RECURSIVE_ENTITY_REF;
+ goto endEntityValue;
+ }
+ if (entity->systemId) {
+ if (externalEntityRefHandler) {
+ dtd->paramEntityRead = XML_FALSE;
+ entity->open = XML_TRUE;
+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+ 0,
+ entity->base,
+ entity->systemId,
+ entity->publicId)) {
+ entity->open = XML_FALSE;
+ result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+ goto endEntityValue;
+ }
+ entity->open = XML_FALSE;
+ if (!dtd->paramEntityRead)
+ dtd->keepProcessing = dtd->standalone;
+ }
+ else
+ dtd->keepProcessing = dtd->standalone;
+ }
+ else {
+ entity->open = XML_TRUE;
+ result = storeEntityValue(parser,
+ internalEncoding,
+ (char *)entity->textPtr,
+ (char *)(entity->textPtr
+ + entity->textLen));
+ entity->open = XML_FALSE;
+ if (result)
+ goto endEntityValue;
+ }
+ break;
+ }
+#endif /* XML_DTD */
+ /* In the internal subset, PE references are not legal
+ within markup declarations, e.g entity values in this case. */
+ eventPtr = entityTextPtr;
+ result = XML_ERROR_PARAM_ENTITY_REF;
+ goto endEntityValue;
+ case XML_TOK_NONE:
+ result = XML_ERROR_NONE;
+ goto endEntityValue;
+ case XML_TOK_ENTITY_REF:
+ case XML_TOK_DATA_CHARS:
+ if (!poolAppend(pool, enc, entityTextPtr, next)) {
+ result = XML_ERROR_NO_MEMORY;
+ goto endEntityValue;
+ }
+ break;
+ case XML_TOK_TRAILING_CR:
+ next = entityTextPtr + enc->minBytesPerChar;
+ /* fall through */
+ case XML_TOK_DATA_NEWLINE:
+ if (pool->end == pool->ptr && !poolGrow(pool)) {
+ result = XML_ERROR_NO_MEMORY;
+ goto endEntityValue;
+ }
+ *(pool->ptr)++ = 0xA;
+ break;
+ case XML_TOK_CHAR_REF:
+ {
+ XML_Char buf[XML_ENCODE_MAX];
+ int i;
+ int n = XmlCharRefNumber(enc, entityTextPtr);
+ if (n < 0) {
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ result = XML_ERROR_BAD_CHAR_REF;
+ goto endEntityValue;
+ }
+ n = XmlEncode(n, (ICHAR *)buf);
+ if (!n) {
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ result = XML_ERROR_BAD_CHAR_REF;
+ goto endEntityValue;
+ }
+ for (i = 0; i < n; i++) {
+ if (pool->end == pool->ptr && !poolGrow(pool)) {
+ result = XML_ERROR_NO_MEMORY;
+ goto endEntityValue;
+ }
+ *(pool->ptr)++ = buf[i];
+ }
+ }
+ break;
+ case XML_TOK_PARTIAL:
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ result = XML_ERROR_INVALID_TOKEN;
+ goto endEntityValue;
+ case XML_TOK_INVALID:
+ if (enc == encoding)
+ eventPtr = next;
+ result = XML_ERROR_INVALID_TOKEN;
+ goto endEntityValue;
+ default:
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ result = XML_ERROR_UNEXPECTED_STATE;
+ goto endEntityValue;
+ }
+ entityTextPtr = next;
+ }
+endEntityValue:
+#ifdef XML_DTD
+ prologState.inEntityValue = oldInEntityValue;
+#endif /* XML_DTD */
+ return result;
+}
+
+static void FASTCALL
+normalizeLines(XML_Char *s)
+{
+ XML_Char *p;
+ for (;; s++) {
+ if (*s == XML_T('\0'))
+ return;
+ if (*s == 0xD)
+ break;
+ }
+ p = s;
+ do {
+ if (*s == 0xD) {
+ *p++ = 0xA;
+ if (*++s == 0xA)
+ s++;
+ }
+ else
+ *p++ = *s++;
+ } while (*s);
+ *p = XML_T('\0');
+}
+
+static int
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
+ const char *start, const char *end)
+{
+ const XML_Char *target;
+ XML_Char *data;
+ const char *tem;
+ if (!processingInstructionHandler) {
+ if (defaultHandler)
+ reportDefault(parser, enc, start, end);
+ return 1;
+ }
+ start += enc->minBytesPerChar * 2;
+ tem = start + XmlNameLength(enc, start);
+ target = poolStoreString(&tempPool, enc, start, tem);
+ if (!target)
+ return 0;
+ poolFinish(&tempPool);
+ data = poolStoreString(&tempPool, enc,
+ XmlSkipS(enc, tem),
+ end - enc->minBytesPerChar*2);
+ if (!data)
+ return 0;
+ normalizeLines(data);
+ processingInstructionHandler(handlerArg, target, data);
+ poolClear(&tempPool);
+ return 1;
+}
+
+static int
+reportComment(XML_Parser parser, const ENCODING *enc,
+ const char *start, const char *end)
+{
+ XML_Char *data;
+ if (!commentHandler) {
+ if (defaultHandler)
+ reportDefault(parser, enc, start, end);
+ return 1;
+ }
+ data = poolStoreString(&tempPool,
+ enc,
+ start + enc->minBytesPerChar * 4,
+ end - enc->minBytesPerChar * 3);
+ if (!data)
+ return 0;
+ normalizeLines(data);
+ commentHandler(handlerArg, data);
+ poolClear(&tempPool);
+ return 1;
+}
+
+static void
+reportDefault(XML_Parser parser, const ENCODING *enc,
+ const char *s, const char *end)
+{
+ if (MUST_CONVERT(enc, s)) {
+ const char **eventPP;
+ const char **eventEndPP;
+ if (enc == encoding) {
+ eventPP = &eventPtr;
+ eventEndPP = &eventEndPtr;
+ }
+ else {
+ eventPP = &(openInternalEntities->internalEventPtr);
+ eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ }
+ do {
+ ICHAR *dataPtr = (ICHAR *)dataBuf;
+ XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+ *eventEndPP = s;
+ defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
+ *eventPP = s;
+ } while (s != end);
+ }
+ else
+ defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
+}
+
+
+static int
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
+ XML_Bool isId, const XML_Char *value, XML_Parser parser)
+{
+ DEFAULT_ATTRIBUTE *att;
+ if (value || isId) {
+ /* The handling of default attributes gets messed up if we have
+ a default which duplicates a non-default. */
+ int i;
+ for (i = 0; i < type->nDefaultAtts; i++)
+ if (attId == type->defaultAtts[i].id)
+ return 1;
+ if (isId && !type->idAtt && !attId->xmlns)
+ type->idAtt = attId;
+ }
+ if (type->nDefaultAtts == type->allocDefaultAtts) {
+ if (type->allocDefaultAtts == 0) {
+ type->allocDefaultAtts = 8;
+ type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
+ * sizeof(DEFAULT_ATTRIBUTE));
+ if (!type->defaultAtts)
+ return 0;
+ }
+ else {
+ DEFAULT_ATTRIBUTE *temp;
+ int count = type->allocDefaultAtts * 2;
+ temp = (DEFAULT_ATTRIBUTE *)
+ REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
+ if (temp == NULL)
+ return 0;
+ type->allocDefaultAtts = count;
+ type->defaultAtts = temp;
+ }
+ }
+ att = type->defaultAtts + type->nDefaultAtts;
+ att->id = attId;
+ att->value = value;
+ att->isCdata = isCdata;
+ if (!isCdata)
+ attId->maybeTokenized = XML_TRUE;
+ type->nDefaultAtts += 1;
+ return 1;
+}
+
+static int
+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ const XML_Char *name;
+ for (name = elementType->name; *name; name++) {
+ if (*name == XML_T(':')) {
+ PREFIX *prefix;
+ const XML_Char *s;
+ for (s = elementType->name; s != name; s++) {
+ if (!poolAppendChar(&dtd->pool, *s))
+ return 0;
+ }
+ if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+ return 0;
+ prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
+ sizeof(PREFIX));
+ if (!prefix)
+ return 0;
+ if (prefix->name == poolStart(&dtd->pool))
+ poolFinish(&dtd->pool);
+ else
+ poolDiscard(&dtd->pool);
+ elementType->prefix = prefix;
+
+ }
+ }
+ return 1;
+}
+
+static ATTRIBUTE_ID *
+getAttributeId(XML_Parser parser, const ENCODING *enc,
+ const char *start, const char *end)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ ATTRIBUTE_ID *id;
+ const XML_Char *name;
+ if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+ return NULL;
+ name = poolStoreString(&dtd->pool, enc, start, end);
+ if (!name)
+ return NULL;
+ /* skip quotation mark - its storage will be re-used (like in name[-1]) */
+ ++name;
+ id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
+ if (!id)
+ return NULL;
+ if (id->name != name)
+ poolDiscard(&dtd->pool);
+ else {
+ poolFinish(&dtd->pool);
+ if (!ns)
+ ;
+ else if (name[0] == XML_T('x')
+ && name[1] == XML_T('m')
+ && name[2] == XML_T('l')
+ && name[3] == XML_T('n')
+ && name[4] == XML_T('s')
+ && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
+ if (name[5] == XML_T('\0'))
+ id->prefix = &dtd->defaultPrefix;
+ else
+ id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
+ id->xmlns = XML_TRUE;
+ }
+ else {
+ int i;
+ for (i = 0; name[i]; i++) {
+ /* attributes without prefix are *not* in the default namespace */
+ if (name[i] == XML_T(':')) {
+ int j;
+ for (j = 0; j < i; j++) {
+ if (!poolAppendChar(&dtd->pool, name[j]))
+ return NULL;
+ }
+ if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+ return NULL;
+ id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
+ sizeof(PREFIX));
+ if (id->prefix->name == poolStart(&dtd->pool))
+ poolFinish(&dtd->pool);
+ else
+ poolDiscard(&dtd->pool);
+ break;
+ }
+ }
+ }
+ }
+ return id;
+}
+
+#define CONTEXT_SEP XML_T('\f')
+
+static const XML_Char *
+getContext(XML_Parser parser)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ HASH_TABLE_ITER iter;
+ XML_Bool needSep = XML_FALSE;
+
+ if (dtd->defaultPrefix.binding) {
+ int i;
+ int len;
+ if (!poolAppendChar(&tempPool, XML_T('=')))
+ return NULL;
+ len = dtd->defaultPrefix.binding->uriLen;
+ if (namespaceSeparator)
+ len--;
+ for (i = 0; i < len; i++)
+ if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
+ return NULL;
+ needSep = XML_TRUE;
+ }
+
+ hashTableIterInit(&iter, &(dtd->prefixes));
+ for (;;) {
+ int i;
+ int len;
+ const XML_Char *s;
+ PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
+ if (!prefix)
+ break;
+ if (!prefix->binding)
+ continue;
+ if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+ return NULL;
+ for (s = prefix->name; *s; s++)
+ if (!poolAppendChar(&tempPool, *s))
+ return NULL;
+ if (!poolAppendChar(&tempPool, XML_T('=')))
+ return NULL;
+ len = prefix->binding->uriLen;
+ if (namespaceSeparator)
+ len--;
+ for (i = 0; i < len; i++)
+ if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
+ return NULL;
+ needSep = XML_TRUE;
+ }
+
+
+ hashTableIterInit(&iter, &(dtd->generalEntities));
+ for (;;) {
+ const XML_Char *s;
+ ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
+ if (!e)
+ break;
+ if (!e->open)
+ continue;
+ if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+ return NULL;
+ for (s = e->name; *s; s++)
+ if (!poolAppendChar(&tempPool, *s))
+ return 0;
+ needSep = XML_TRUE;
+ }
+
+ if (!poolAppendChar(&tempPool, XML_T('\0')))
+ return NULL;
+ return tempPool.start;
+}
+
+static XML_Bool
+setContext(XML_Parser parser, const XML_Char *context)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ const XML_Char *s = context;
+
+ while (*context != XML_T('\0')) {
+ if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
+ ENTITY *e;
+ if (!poolAppendChar(&tempPool, XML_T('\0')))
+ return XML_FALSE;
+ e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
+ if (e)
+ e->open = XML_TRUE;
+ if (*s != XML_T('\0'))
+ s++;
+ context = s;
+ poolDiscard(&tempPool);
+ }
+ else if (*s == XML_T('=')) {
+ PREFIX *prefix;
+ if (poolLength(&tempPool) == 0)
+ prefix = &dtd->defaultPrefix;
+ else {
+ if (!poolAppendChar(&tempPool, XML_T('\0')))
+ return XML_FALSE;
+ prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
+ sizeof(PREFIX));
+ if (!prefix)
+ return XML_FALSE;
+ if (prefix->name == poolStart(&tempPool)) {
+ prefix->name = poolCopyString(&dtd->pool, prefix->name);
+ if (!prefix->name)
+ return XML_FALSE;
+ }
+ poolDiscard(&tempPool);
+ }
+ for (context = s + 1;
+ *context != CONTEXT_SEP && *context != XML_T('\0');
+ context++)
+ if (!poolAppendChar(&tempPool, *context))
+ return XML_FALSE;
+ if (!poolAppendChar(&tempPool, XML_T('\0')))
+ return XML_FALSE;
+ if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
+ &inheritedBindings) != XML_ERROR_NONE)
+ return XML_FALSE;
+ poolDiscard(&tempPool);
+ if (*context != XML_T('\0'))
+ ++context;
+ s = context;
+ }
+ else {
+ if (!poolAppendChar(&tempPool, *s))
+ return XML_FALSE;
+ s++;
+ }
+ }
+ return XML_TRUE;
+}
+
+static void FASTCALL
+normalizePublicId(XML_Char *publicId)
+{
+ XML_Char *p = publicId;
+ XML_Char *s;
+ for (s = publicId; *s; s++) {
+ switch (*s) {
+ case 0x20:
+ case 0xD:
+ case 0xA:
+ if (p != publicId && p[-1] != 0x20)
+ *p++ = 0x20;
+ break;
+ default:
+ *p++ = *s;
+ }
+ }
+ if (p != publicId && p[-1] == 0x20)
+ --p;
+ *p = XML_T('\0');
+}
+
+static DTD *
+dtdCreate(const XML_Memory_Handling_Suite *ms)
+{
+ DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
+ if (p == NULL)
+ return p;
+ poolInit(&(p->pool), ms);
+ poolInit(&(p->entityValuePool), ms);
+ hashTableInit(&(p->generalEntities), ms);
+ hashTableInit(&(p->elementTypes), ms);
+ hashTableInit(&(p->attributeIds), ms);
+ hashTableInit(&(p->prefixes), ms);
+#ifdef XML_DTD
+ p->paramEntityRead = XML_FALSE;
+ hashTableInit(&(p->paramEntities), ms);
+#endif /* XML_DTD */
+ p->defaultPrefix.name = NULL;
+ p->defaultPrefix.binding = NULL;
+
+ p->in_eldecl = XML_FALSE;
+ p->scaffIndex = NULL;
+ p->scaffold = NULL;
+ p->scaffLevel = 0;
+ p->scaffSize = 0;
+ p->scaffCount = 0;
+ p->contentStringLen = 0;
+
+ p->keepProcessing = XML_TRUE;
+ p->hasParamEntityRefs = XML_FALSE;
+ p->standalone = XML_FALSE;
+ return p;
+}
+
+/* BEGIN MOZILLA CHANGE (unused API) */
+#if 0
+static void
+dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
+{
+ HASH_TABLE_ITER iter;
+ hashTableIterInit(&iter, &(p->elementTypes));
+ for (;;) {
+ ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+ if (!e)
+ break;
+ if (e->allocDefaultAtts != 0)
+ ms->free_fcn(e->defaultAtts);
+ }
+ hashTableClear(&(p->generalEntities));
+#ifdef XML_DTD
+ p->paramEntityRead = XML_FALSE;
+ hashTableClear(&(p->paramEntities));
+#endif /* XML_DTD */
+ hashTableClear(&(p->elementTypes));
+ hashTableClear(&(p->attributeIds));
+ hashTableClear(&(p->prefixes));
+ poolClear(&(p->pool));
+ poolClear(&(p->entityValuePool));
+ p->defaultPrefix.name = NULL;
+ p->defaultPrefix.binding = NULL;
+
+ p->in_eldecl = XML_FALSE;
+
+ ms->free_fcn(p->scaffIndex);
+ p->scaffIndex = NULL;
+ ms->free_fcn(p->scaffold);
+ p->scaffold = NULL;
+
+ p->scaffLevel = 0;
+ p->scaffSize = 0;
+ p->scaffCount = 0;
+ p->contentStringLen = 0;
+
+ p->keepProcessing = XML_TRUE;
+ p->hasParamEntityRefs = XML_FALSE;
+ p->standalone = XML_FALSE;
+}
+#endif
+/* END MOZILLA CHANGE */
+
+static void
+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
+{
+ HASH_TABLE_ITER iter;
+ hashTableIterInit(&iter, &(p->elementTypes));
+ for (;;) {
+ ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+ if (!e)
+ break;
+ if (e->allocDefaultAtts != 0)
+ ms->free_fcn(e->defaultAtts);
+ }
+ hashTableDestroy(&(p->generalEntities));
+#ifdef XML_DTD
+ hashTableDestroy(&(p->paramEntities));
+#endif /* XML_DTD */
+ hashTableDestroy(&(p->elementTypes));
+ hashTableDestroy(&(p->attributeIds));
+ hashTableDestroy(&(p->prefixes));
+ poolDestroy(&(p->pool));
+ poolDestroy(&(p->entityValuePool));
+ if (isDocEntity) {
+ ms->free_fcn(p->scaffIndex);
+ ms->free_fcn(p->scaffold);
+ }
+ ms->free_fcn(p);
+}
+
+/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
+ The new DTD has already been initialized.
+*/
+static int
+dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
+{
+ HASH_TABLE_ITER iter;
+
+ /* Copy the prefix table. */
+
+ hashTableIterInit(&iter, &(oldDtd->prefixes));
+ for (;;) {
+ const XML_Char *name;
+ const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
+ if (!oldP)
+ break;
+ name = poolCopyString(&(newDtd->pool), oldP->name);
+ if (!name)
+ return 0;
+ if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
+ return 0;
+ }
+
+ hashTableIterInit(&iter, &(oldDtd->attributeIds));
+
+ /* Copy the attribute id table. */
+
+ for (;;) {
+ ATTRIBUTE_ID *newA;
+ const XML_Char *name;
+ const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
+
+ if (!oldA)
+ break;
+ /* Remember to allocate the scratch byte before the name. */
+ if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
+ return 0;
+ name = poolCopyString(&(newDtd->pool), oldA->name);
+ if (!name)
+ return 0;
+ ++name;
+ newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
+ sizeof(ATTRIBUTE_ID));
+ if (!newA)
+ return 0;
+ newA->maybeTokenized = oldA->maybeTokenized;
+ if (oldA->prefix) {
+ newA->xmlns = oldA->xmlns;
+ if (oldA->prefix == &oldDtd->defaultPrefix)
+ newA->prefix = &newDtd->defaultPrefix;
+ else
+ newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
+ oldA->prefix->name, 0);
+ }
+ }
+
+ /* Copy the element type table. */
+
+ hashTableIterInit(&iter, &(oldDtd->elementTypes));
+
+ for (;;) {
+ int i;
+ ELEMENT_TYPE *newE;
+ const XML_Char *name;
+ const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+ if (!oldE)
+ break;
+ name = poolCopyString(&(newDtd->pool), oldE->name);
+ if (!name)
+ return 0;
+ newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
+ sizeof(ELEMENT_TYPE));
+ if (!newE)
+ return 0;
+ if (oldE->nDefaultAtts) {
+ newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
+ ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+ if (!newE->defaultAtts) {
+ ms->free_fcn(newE);
+ return 0;
+ }
+ }
+ if (oldE->idAtt)
+ newE->idAtt = (ATTRIBUTE_ID *)
+ lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
+ newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
+ if (oldE->prefix)
+ newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
+ oldE->prefix->name, 0);
+ for (i = 0; i < newE->nDefaultAtts; i++) {
+ newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
+ lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
+ newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
+ if (oldE->defaultAtts[i].value) {
+ newE->defaultAtts[i].value
+ = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
+ if (!newE->defaultAtts[i].value)
+ return 0;
+ }
+ else
+ newE->defaultAtts[i].value = NULL;
+ }
+ }
+
+ /* Copy the entity tables. */
+ if (!copyEntityTable(&(newDtd->generalEntities),
+ &(newDtd->pool),
+ &(oldDtd->generalEntities)))
+ return 0;
+
+#ifdef XML_DTD
+ if (!copyEntityTable(&(newDtd->paramEntities),
+ &(newDtd->pool),
+ &(oldDtd->paramEntities)))
+ return 0;
+ newDtd->paramEntityRead = oldDtd->paramEntityRead;
+#endif /* XML_DTD */
+
+ newDtd->keepProcessing = oldDtd->keepProcessing;
+ newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
+ newDtd->standalone = oldDtd->standalone;
+
+ /* Don't want deep copying for scaffolding */
+ newDtd->in_eldecl = oldDtd->in_eldecl;
+ newDtd->scaffold = oldDtd->scaffold;
+ newDtd->contentStringLen = oldDtd->contentStringLen;
+ newDtd->scaffSize = oldDtd->scaffSize;
+ newDtd->scaffLevel = oldDtd->scaffLevel;
+ newDtd->scaffIndex = oldDtd->scaffIndex;
+
+ return 1;
+} /* End dtdCopy */
+
+static int
+copyEntityTable(HASH_TABLE *newTable,
+ STRING_POOL *newPool,
+ const HASH_TABLE *oldTable)
+{
+ HASH_TABLE_ITER iter;
+ const XML_Char *cachedOldBase = NULL;
+ const XML_Char *cachedNewBase = NULL;
+
+ hashTableIterInit(&iter, oldTable);
+
+ for (;;) {
+ ENTITY *newE;
+ const XML_Char *name;
+ const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
+ if (!oldE)
+ break;
+ name = poolCopyString(newPool, oldE->name);
+ if (!name)
+ return 0;
+ newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
+ if (!newE)
+ return 0;
+ if (oldE->systemId) {
+ const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
+ if (!tem)
+ return 0;
+ newE->systemId = tem;
+ if (oldE->base) {
+ if (oldE->base == cachedOldBase)
+ newE->base = cachedNewBase;
+ else {
+ cachedOldBase = oldE->base;
+ tem = poolCopyString(newPool, cachedOldBase);
+ if (!tem)
+ return 0;
+ cachedNewBase = newE->base = tem;
+ }
+ }
+ if (oldE->publicId) {
+ tem = poolCopyString(newPool, oldE->publicId);
+ if (!tem)
+ return 0;
+ newE->publicId = tem;
+ }
+ }
+ else {
+ const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
+ oldE->textLen);
+ if (!tem)
+ return 0;
+ newE->textPtr = tem;
+ newE->textLen = oldE->textLen;
+ }
+ if (oldE->notation) {
+ const XML_Char *tem = poolCopyString(newPool, oldE->notation);
+ if (!tem)
+ return 0;
+ newE->notation = tem;
+ }
+ newE->is_param = oldE->is_param;
+ newE->is_internal = oldE->is_internal;
+ }
+ return 1;
+}
+
+#define INIT_POWER 6
+
+static XML_Bool FASTCALL
+keyeq(KEY s1, KEY s2)
+{
+ for (; *s1 == *s2; s1++, s2++)
+ if (*s1 == 0)
+ return XML_TRUE;
+ return XML_FALSE;
+}
+
+static unsigned long FASTCALL
+hash(KEY s)
+{
+ unsigned long h = 0;
+ while (*s)
+ h = CHAR_HASH(h, *s++);
+ return h;
+}
+
+static NAMED *
+lookup(HASH_TABLE *table, KEY name, size_t createSize)
+{
+ size_t i;
+ if (table->size == 0) {
+ size_t tsize;
+ if (!createSize)
+ return NULL;
+ table->power = INIT_POWER;
+ /* table->size is a power of 2 */
+ table->size = (size_t)1 << INIT_POWER;
+ tsize = table->size * sizeof(NAMED *);
+ table->v = (NAMED **)table->mem->malloc_fcn(tsize);
+ if (!table->v) {
+ table->size = 0;
+ return NULL;
+ }
+ memset(table->v, 0, tsize);
+ i = hash(name) & ((unsigned long)table->size - 1);
+ }
+ else {
+ unsigned long h = hash(name);
+ unsigned long mask = (unsigned long)table->size - 1;
+ unsigned char step = 0;
+ i = h & mask;
+ while (table->v[i]) {
+ if (keyeq(name, table->v[i]->name))
+ return table->v[i];
+ if (!step)
+ step = PROBE_STEP(h, mask, table->power);
+ i < step ? (i += table->size - step) : (i -= step);
+ }
+ if (!createSize)
+ return NULL;
+
+ /* check for overflow (table is half full) */
+ if (table->used >> (table->power - 1)) {
+ unsigned char newPower = table->power + 1;
+ size_t newSize = (size_t)1 << newPower;
+ unsigned long newMask = (unsigned long)newSize - 1;
+ size_t tsize = newSize * sizeof(NAMED *);
+ NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
+ if (!newV)
+ return NULL;
+ memset(newV, 0, tsize);
+ for (i = 0; i < table->size; i++)
+ if (table->v[i]) {
+ unsigned long newHash = hash(table->v[i]->name);
+ size_t j = newHash & newMask;
+ step = 0;
+ while (newV[j]) {
+ if (!step)
+ step = PROBE_STEP(newHash, newMask, newPower);
+ j < step ? (j += newSize - step) : (j -= step);
+ }
+ newV[j] = table->v[i];
+ }
+ table->mem->free_fcn(table->v);
+ table->v = newV;
+ table->power = newPower;
+ table->size = newSize;
+ i = h & newMask;
+ step = 0;
+ while (table->v[i]) {
+ if (!step)
+ step = PROBE_STEP(h, newMask, newPower);
+ i < step ? (i += newSize - step) : (i -= step);
+ }
+ }
+ }
+ table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
+ if (!table->v[i])
+ return NULL;
+ memset(table->v[i], 0, createSize);
+ table->v[i]->name = name;
+ (table->used)++;
+ return table->v[i];
+}
+
+/* BEGIN MOZILLA CHANGE (unused API) */
+#if 0
+static void FASTCALL
+hashTableClear(HASH_TABLE *table)
+{
+ size_t i;
+ for (i = 0; i < table->size; i++) {
+ table->mem->free_fcn(table->v[i]);
+ table->v[i] = NULL;
+ }
+ table->used = 0;
+}
+#endif
+/* END MOZILLA CHANGE */
+
+static void FASTCALL
+hashTableDestroy(HASH_TABLE *table)
+{
+ size_t i;
+ for (i = 0; i < table->size; i++)
+ table->mem->free_fcn(table->v[i]);
+ table->mem->free_fcn(table->v);
+}
+
+static void FASTCALL
+hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
+{
+ p->power = 0;
+ p->size = 0;
+ p->used = 0;
+ p->v = NULL;
+ p->mem = ms;
+}
+
+static void FASTCALL
+hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
+{
+ iter->p = table->v;
+ iter->end = iter->p + table->size;
+}
+
+static NAMED * FASTCALL
+hashTableIterNext(HASH_TABLE_ITER *iter)
+{
+ while (iter->p != iter->end) {
+ NAMED *tem = *(iter->p)++;
+ if (tem)
+ return tem;
+ }
+ return NULL;
+}
+
+static void FASTCALL
+poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
+{
+ pool->blocks = NULL;
+ pool->freeBlocks = NULL;
+ pool->start = NULL;
+ pool->ptr = NULL;
+ pool->end = NULL;
+ pool->mem = ms;
+}
+
+static void FASTCALL
+poolClear(STRING_POOL *pool)
+{
+ if (!pool->freeBlocks)
+ pool->freeBlocks = pool->blocks;
+ else {
+ BLOCK *p = pool->blocks;
+ while (p) {
+ BLOCK *tem = p->next;
+ p->next = pool->freeBlocks;
+ pool->freeBlocks = p;
+ p = tem;
+ }
+ }
+ pool->blocks = NULL;
+ pool->start = NULL;
+ pool->ptr = NULL;
+ pool->end = NULL;
+}
+
+static void FASTCALL
+poolDestroy(STRING_POOL *pool)
+{
+ BLOCK *p = pool->blocks;
+ while (p) {
+ BLOCK *tem = p->next;
+ pool->mem->free_fcn(p);
+ p = tem;
+ }
+ p = pool->freeBlocks;
+ while (p) {
+ BLOCK *tem = p->next;
+ pool->mem->free_fcn(p);
+ p = tem;
+ }
+}
+
+static XML_Char *
+poolAppend(STRING_POOL *pool, const ENCODING *enc,
+ const char *ptr, const char *end)
+{
+ if (!pool->ptr && !poolGrow(pool))
+ return NULL;
+ for (;;) {
+ XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
+ if (ptr == end)
+ break;
+ if (!poolGrow(pool))
+ return NULL;
+ }
+ return pool->start;
+}
+
+static const XML_Char * FASTCALL
+poolCopyString(STRING_POOL *pool, const XML_Char *s)
+{
+ do {
+ if (!poolAppendChar(pool, *s))
+ return NULL;
+ } while (*s++);
+ s = pool->start;
+ poolFinish(pool);
+ return s;
+}
+
+static const XML_Char *
+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
+{
+ if (!pool->ptr && !poolGrow(pool))
+ return NULL;
+ for (; n > 0; --n, s++) {
+ if (!poolAppendChar(pool, *s))
+ return NULL;
+ }
+ s = pool->start;
+ poolFinish(pool);
+ return s;
+}
+
+static const XML_Char * FASTCALL
+poolAppendString(STRING_POOL *pool, const XML_Char *s)
+{
+ while (*s) {
+ if (!poolAppendChar(pool, *s))
+ return NULL;
+ s++;
+ }
+ return pool->start;
+}
+
+static XML_Char *
+poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+ const char *ptr, const char *end)
+{
+ if (!poolAppend(pool, enc, ptr, end))
+ return NULL;
+ if (pool->ptr == pool->end && !poolGrow(pool))
+ return NULL;
+ *(pool->ptr)++ = 0;
+ return pool->start;
+}
+
+static XML_Bool FASTCALL
+poolGrow(STRING_POOL *pool)
+{
+ if (pool->freeBlocks) {
+ if (pool->start == 0) {
+ pool->blocks = pool->freeBlocks;
+ pool->freeBlocks = pool->freeBlocks->next;
+ pool->blocks->next = NULL;
+ pool->start = pool->blocks->s;
+ pool->end = pool->start + pool->blocks->size;
+ pool->ptr = pool->start;
+ return XML_TRUE;
+ }
+ if (pool->end - pool->start < pool->freeBlocks->size) {
+ BLOCK *tem = pool->freeBlocks->next;
+ pool->freeBlocks->next = pool->blocks;
+ pool->blocks = pool->freeBlocks;
+ pool->freeBlocks = tem;
+ memcpy(pool->blocks->s, pool->start,
+ (pool->end - pool->start) * sizeof(XML_Char));
+ pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+ pool->start = pool->blocks->s;
+ pool->end = pool->start + pool->blocks->size;
+ return XML_TRUE;
+ }
+ }
+ if (pool->blocks && pool->start == pool->blocks->s) {
+ int blockSize = (int)(pool->end - pool->start)*2;
+ if (blockSize < 0)
+ return XML_FALSE;
+
+ pool->blocks = (BLOCK *)
+ pool->mem->realloc_fcn(pool->blocks,
+ (offsetof(BLOCK, s)
+ + blockSize * sizeof(XML_Char)));
+ if (pool->blocks == NULL)
+ return XML_FALSE;
+ pool->blocks->size = blockSize;
+ pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+ pool->start = pool->blocks->s;
+ pool->end = pool->start + blockSize;
+ }
+ else {
+ BLOCK *tem;
+ int blockSize = (int)(pool->end - pool->start);
+ if (blockSize < 0)
+ return XML_FALSE;
+
+ if (blockSize < INIT_BLOCK_SIZE)
+ blockSize = INIT_BLOCK_SIZE;
+ else
+ blockSize *= 2;
+
+ if (blockSize < 0)
+ return XML_FALSE;
+
+ tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
+ + blockSize * sizeof(XML_Char));
+ if (!tem)
+ return XML_FALSE;
+ tem->size = blockSize;
+ tem->next = pool->blocks;
+ pool->blocks = tem;
+ if (pool->ptr != pool->start)
+ memcpy(tem->s, pool->start,
+ (pool->ptr - pool->start) * sizeof(XML_Char));
+ pool->ptr = tem->s + (pool->ptr - pool->start);
+ pool->start = tem->s;
+ pool->end = tem->s + blockSize;
+ }
+ return XML_TRUE;
+}
+
+static int FASTCALL
+nextScaffoldPart(XML_Parser parser)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ CONTENT_SCAFFOLD * me;
+ int next;
+
+ if (!dtd->scaffIndex) {
+ dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
+ if (!dtd->scaffIndex)
+ return -1;
+ dtd->scaffIndex[0] = 0;
+ }
+
+ if (dtd->scaffCount >= dtd->scaffSize) {
+ CONTENT_SCAFFOLD *temp;
+ if (dtd->scaffold) {
+ temp = (CONTENT_SCAFFOLD *)
+ REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
+ if (temp == NULL)
+ return -1;
+ dtd->scaffSize *= 2;
+ }
+ else {
+ temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
+ * sizeof(CONTENT_SCAFFOLD));
+ if (temp == NULL)
+ return -1;
+ dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
+ }
+ dtd->scaffold = temp;
+ }
+ next = dtd->scaffCount++;
+ me = &dtd->scaffold[next];
+ if (dtd->scaffLevel) {
+ CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
+ if (parent->lastchild) {
+ dtd->scaffold[parent->lastchild].nextsib = next;
+ }
+ if (!parent->childcnt)
+ parent->firstchild = next;
+ parent->lastchild = next;
+ parent->childcnt++;
+ }
+ me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
+ return next;
+}
+
+static void
+build_node(XML_Parser parser,
+ int src_node,
+ XML_Content *dest,
+ XML_Content **contpos,
+ XML_Char **strpos)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ dest->type = dtd->scaffold[src_node].type;
+ dest->quant = dtd->scaffold[src_node].quant;
+ if (dest->type == XML_CTYPE_NAME) {
+ const XML_Char *src;
+ dest->name = *strpos;
+ src = dtd->scaffold[src_node].name;
+ for (;;) {
+ *(*strpos)++ = *src;
+ if (!*src)
+ break;
+ src++;
+ }
+ dest->numchildren = 0;
+ dest->children = NULL;
+ }
+ else {
+ unsigned int i;
+ int cn;
+ dest->numchildren = dtd->scaffold[src_node].childcnt;
+ dest->children = *contpos;
+ *contpos += dest->numchildren;
+ for (i = 0, cn = dtd->scaffold[src_node].firstchild;
+ i < dest->numchildren;
+ i++, cn = dtd->scaffold[cn].nextsib) {
+ build_node(parser, cn, &(dest->children[i]), contpos, strpos);
+ }
+ dest->name = NULL;
+ }
+}
+
+static XML_Content *
+build_model (XML_Parser parser)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ XML_Content *ret;
+ XML_Content *cpos;
+ XML_Char * str;
+ int allocsize = (dtd->scaffCount * sizeof(XML_Content)
+ + (dtd->contentStringLen * sizeof(XML_Char)));
+
+ ret = (XML_Content *)MALLOC(allocsize);
+ if (!ret)
+ return NULL;
+
+ str = (XML_Char *) (&ret[dtd->scaffCount]);
+ cpos = &ret[1];
+
+ build_node(parser, 0, ret, &cpos, &str);
+ return ret;
+}
+
+static ELEMENT_TYPE *
+getElementType(XML_Parser parser,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end)
+{
+ DTD * const dtd = _dtd; /* save one level of indirection */
+ const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
+ ELEMENT_TYPE *ret;
+
+ if (!name)
+ return NULL;
+ ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
+ if (!ret)
+ return NULL;
+ if (ret->name != name)
+ poolDiscard(&dtd->pool);
+ else {
+ poolFinish(&dtd->pool);
+ if (!setElementTypePrefix(parser, ret))
+ return NULL;
+ }
+ return ret;
+}
diff --git a/parser/expat/lib/xmlrole.c b/parser/expat/lib/xmlrole.c
new file mode 100644
index 000000000..3782f1ec4
--- /dev/null
+++ b/parser/expat/lib/xmlrole.c
@@ -0,0 +1,1330 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#include <stddef.h>
+
+#ifdef COMPILED_FROM_DSP
+#include "winconfig.h"
+#elif defined(MACOS_CLASSIC)
+#include "macconfig.h"
+#elif defined(__amigaos4__)
+#include "amigaconfig.h"
+#else
+#ifdef HAVE_EXPAT_CONFIG_H
+#include <expat_config.h>
+#endif
+#endif /* ndef COMPILED_FROM_DSP */
+
+#include "expat_external.h"
+#include "internal.h"
+#include "xmlrole.h"
+#include "ascii.h"
+
+/* Doesn't check:
+
+ that ,| are not mixed in a model group
+ content of literals
+
+*/
+
+static const char KW_ANY[] = {
+ ASCII_A, ASCII_N, ASCII_Y, '\0' };
+static const char KW_ATTLIST[] = {
+ ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' };
+static const char KW_CDATA[] = {
+ ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_DOCTYPE[] = {
+ ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' };
+static const char KW_ELEMENT[] = {
+ ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' };
+static const char KW_EMPTY[] = {
+ ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' };
+static const char KW_ENTITIES[] = {
+ ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S,
+ '\0' };
+static const char KW_ENTITY[] = {
+ ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
+static const char KW_FIXED[] = {
+ ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' };
+static const char KW_ID[] = {
+ ASCII_I, ASCII_D, '\0' };
+static const char KW_IDREF[] = {
+ ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
+static const char KW_IDREFS[] = {
+ ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
+static const char KW_IGNORE[] = {
+ ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' };
+static const char KW_IMPLIED[] = {
+ ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' };
+static const char KW_INCLUDE[] = {
+ ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' };
+static const char KW_NDATA[] = {
+ ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_NMTOKEN[] = {
+ ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
+static const char KW_NMTOKENS[] = {
+ ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S,
+ '\0' };
+static const char KW_NOTATION[] =
+ { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N,
+ '\0' };
+static const char KW_PCDATA[] = {
+ ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_PUBLIC[] = {
+ ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' };
+static const char KW_REQUIRED[] = {
+ ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D,
+ '\0' };
+static const char KW_SYSTEM[] = {
+ ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' };
+
+#ifndef MIN_BYTES_PER_CHAR
+#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
+#endif
+
+#ifdef XML_DTD
+#define setTopLevel(state) \
+ ((state)->handler = ((state)->documentEntity \
+ ? internalSubset \
+ : externalSubset1))
+#else /* not XML_DTD */
+#define setTopLevel(state) ((state)->handler = internalSubset)
+#endif /* not XML_DTD */
+
+typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc);
+
+static PROLOG_HANDLER
+ prolog0, prolog1, prolog2,
+ doctype0, doctype1, doctype2, doctype3, doctype4, doctype5,
+ internalSubset,
+ entity0, entity1, entity2, entity3, entity4, entity5, entity6,
+ entity7, entity8, entity9, entity10,
+ notation0, notation1, notation2, notation3, notation4,
+ attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6,
+ attlist7, attlist8, attlist9,
+ element0, element1, element2, element3, element4, element5, element6,
+ element7,
+#ifdef XML_DTD
+ externalSubset0, externalSubset1,
+ condSect0, condSect1, condSect2,
+#endif /* XML_DTD */
+ declClose,
+ error;
+
+static int FASTCALL common(PROLOG_STATE *state, int tok);
+
+static int PTRCALL
+prolog0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ state->handler = prolog1;
+ return XML_ROLE_NONE;
+ case XML_TOK_XML_DECL:
+ state->handler = prolog1;
+ return XML_ROLE_XML_DECL;
+ case XML_TOK_PI:
+ state->handler = prolog1;
+ return XML_ROLE_PI;
+ case XML_TOK_COMMENT:
+ state->handler = prolog1;
+ return XML_ROLE_COMMENT;
+ case XML_TOK_BOM:
+ return XML_ROLE_NONE;
+ case XML_TOK_DECL_OPEN:
+ if (!XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_DOCTYPE))
+ break;
+ state->handler = doctype0;
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_INSTANCE_START:
+ state->handler = error;
+ return XML_ROLE_INSTANCE_START;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+prolog1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_PI:
+ return XML_ROLE_PI;
+ case XML_TOK_COMMENT:
+ return XML_ROLE_COMMENT;
+ case XML_TOK_BOM:
+ return XML_ROLE_NONE;
+ case XML_TOK_DECL_OPEN:
+ if (!XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_DOCTYPE))
+ break;
+ state->handler = doctype0;
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_INSTANCE_START:
+ state->handler = error;
+ return XML_ROLE_INSTANCE_START;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+prolog2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_PI:
+ return XML_ROLE_PI;
+ case XML_TOK_COMMENT:
+ return XML_ROLE_COMMENT;
+ case XML_TOK_INSTANCE_START:
+ state->handler = error;
+ return XML_ROLE_INSTANCE_START;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+doctype0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = doctype1;
+ return XML_ROLE_DOCTYPE_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+doctype1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_OPEN_BRACKET:
+ state->handler = internalSubset;
+ return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
+ case XML_TOK_DECL_CLOSE:
+ state->handler = prolog2;
+ return XML_ROLE_DOCTYPE_CLOSE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+ state->handler = doctype3;
+ return XML_ROLE_DOCTYPE_NONE;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+ state->handler = doctype2;
+ return XML_ROLE_DOCTYPE_NONE;
+ }
+ break;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+doctype2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = doctype3;
+ return XML_ROLE_DOCTYPE_PUBLIC_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+doctype3(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = doctype4;
+ return XML_ROLE_DOCTYPE_SYSTEM_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+doctype4(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_OPEN_BRACKET:
+ state->handler = internalSubset;
+ return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
+ case XML_TOK_DECL_CLOSE:
+ state->handler = prolog2;
+ return XML_ROLE_DOCTYPE_CLOSE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+doctype5(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_DECL_CLOSE:
+ state->handler = prolog2;
+ return XML_ROLE_DOCTYPE_CLOSE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+internalSubset(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_DECL_OPEN:
+ if (XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_ENTITY)) {
+ state->handler = entity0;
+ return XML_ROLE_ENTITY_NONE;
+ }
+ if (XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_ATTLIST)) {
+ state->handler = attlist0;
+ return XML_ROLE_ATTLIST_NONE;
+ }
+ if (XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_ELEMENT)) {
+ state->handler = element0;
+ return XML_ROLE_ELEMENT_NONE;
+ }
+ if (XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_NOTATION)) {
+ state->handler = notation0;
+ return XML_ROLE_NOTATION_NONE;
+ }
+ break;
+ case XML_TOK_PI:
+ return XML_ROLE_PI;
+ case XML_TOK_COMMENT:
+ return XML_ROLE_COMMENT;
+ case XML_TOK_PARAM_ENTITY_REF:
+ return XML_ROLE_PARAM_ENTITY_REF;
+ case XML_TOK_CLOSE_BRACKET:
+ state->handler = doctype5;
+ return XML_ROLE_DOCTYPE_NONE;
+ case XML_TOK_NONE:
+ return XML_ROLE_NONE;
+ }
+ return common(state, tok);
+}
+
+#ifdef XML_DTD
+
+static int PTRCALL
+externalSubset0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ state->handler = externalSubset1;
+ if (tok == XML_TOK_XML_DECL)
+ return XML_ROLE_TEXT_DECL;
+ return externalSubset1(state, tok, ptr, end, enc);
+}
+
+static int PTRCALL
+externalSubset1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_COND_SECT_OPEN:
+ state->handler = condSect0;
+ return XML_ROLE_NONE;
+ case XML_TOK_COND_SECT_CLOSE:
+ if (state->includeLevel == 0)
+ break;
+ state->includeLevel -= 1;
+ return XML_ROLE_NONE;
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_CLOSE_BRACKET:
+ break;
+ case XML_TOK_NONE:
+ if (state->includeLevel)
+ break;
+ return XML_ROLE_NONE;
+ default:
+ return internalSubset(state, tok, ptr, end, enc);
+ }
+ return common(state, tok);
+}
+
+#endif /* XML_DTD */
+
+static int PTRCALL
+entity0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_PERCENT:
+ state->handler = entity1;
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_NAME:
+ state->handler = entity2;
+ return XML_ROLE_GENERAL_ENTITY_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_NAME:
+ state->handler = entity7;
+ return XML_ROLE_PARAM_ENTITY_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+ state->handler = entity4;
+ return XML_ROLE_ENTITY_NONE;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+ state->handler = entity3;
+ return XML_ROLE_ENTITY_NONE;
+ }
+ break;
+ case XML_TOK_LITERAL:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ENTITY_NONE;
+ return XML_ROLE_ENTITY_VALUE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity3(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = entity4;
+ return XML_ROLE_ENTITY_PUBLIC_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity4(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = entity5;
+ return XML_ROLE_ENTITY_SYSTEM_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity5(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_DECL_CLOSE:
+ setTopLevel(state);
+ return XML_ROLE_ENTITY_COMPLETE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) {
+ state->handler = entity6;
+ return XML_ROLE_ENTITY_NONE;
+ }
+ break;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity6(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_NAME:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ENTITY_NONE;
+ return XML_ROLE_ENTITY_NOTATION_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity7(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+ state->handler = entity9;
+ return XML_ROLE_ENTITY_NONE;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+ state->handler = entity8;
+ return XML_ROLE_ENTITY_NONE;
+ }
+ break;
+ case XML_TOK_LITERAL:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ENTITY_NONE;
+ return XML_ROLE_ENTITY_VALUE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity8(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = entity9;
+ return XML_ROLE_ENTITY_PUBLIC_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity9(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = entity10;
+ return XML_ROLE_ENTITY_SYSTEM_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+entity10(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ENTITY_NONE;
+ case XML_TOK_DECL_CLOSE:
+ setTopLevel(state);
+ return XML_ROLE_ENTITY_COMPLETE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+notation0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NOTATION_NONE;
+ case XML_TOK_NAME:
+ state->handler = notation1;
+ return XML_ROLE_NOTATION_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+notation1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NOTATION_NONE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+ state->handler = notation3;
+ return XML_ROLE_NOTATION_NONE;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+ state->handler = notation2;
+ return XML_ROLE_NOTATION_NONE;
+ }
+ break;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+notation2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NOTATION_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = notation4;
+ return XML_ROLE_NOTATION_PUBLIC_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+notation3(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NOTATION_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_NOTATION_NONE;
+ return XML_ROLE_NOTATION_SYSTEM_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+notation4(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NOTATION_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_NOTATION_NONE;
+ return XML_ROLE_NOTATION_SYSTEM_ID;
+ case XML_TOK_DECL_CLOSE:
+ setTopLevel(state);
+ return XML_ROLE_NOTATION_NO_SYSTEM_ID;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = attlist1;
+ return XML_ROLE_ATTLIST_ELEMENT_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_DECL_CLOSE:
+ setTopLevel(state);
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = attlist2;
+ return XML_ROLE_ATTRIBUTE_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_NAME:
+ {
+ static const char * const types[] = {
+ KW_CDATA,
+ KW_ID,
+ KW_IDREF,
+ KW_IDREFS,
+ KW_ENTITY,
+ KW_ENTITIES,
+ KW_NMTOKEN,
+ KW_NMTOKENS,
+ };
+ int i;
+ for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)
+ if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
+ state->handler = attlist8;
+ return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
+ }
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) {
+ state->handler = attlist5;
+ return XML_ROLE_ATTLIST_NONE;
+ }
+ break;
+ case XML_TOK_OPEN_PAREN:
+ state->handler = attlist3;
+ return XML_ROLE_ATTLIST_NONE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist3(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_NMTOKEN:
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = attlist4;
+ return XML_ROLE_ATTRIBUTE_ENUM_VALUE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist4(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_CLOSE_PAREN:
+ state->handler = attlist8;
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_OR:
+ state->handler = attlist3;
+ return XML_ROLE_ATTLIST_NONE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist5(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_OPEN_PAREN:
+ state->handler = attlist6;
+ return XML_ROLE_ATTLIST_NONE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist6(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_NAME:
+ state->handler = attlist7;
+ return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist7(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_CLOSE_PAREN:
+ state->handler = attlist8;
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_OR:
+ state->handler = attlist6;
+ return XML_ROLE_ATTLIST_NONE;
+ }
+ return common(state, tok);
+}
+
+/* default value */
+static int PTRCALL
+attlist8(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_POUND_NAME:
+ if (XmlNameMatchesAscii(enc,
+ ptr + MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_IMPLIED)) {
+ state->handler = attlist1;
+ return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
+ }
+ if (XmlNameMatchesAscii(enc,
+ ptr + MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_REQUIRED)) {
+ state->handler = attlist1;
+ return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
+ }
+ if (XmlNameMatchesAscii(enc,
+ ptr + MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_FIXED)) {
+ state->handler = attlist9;
+ return XML_ROLE_ATTLIST_NONE;
+ }
+ break;
+ case XML_TOK_LITERAL:
+ state->handler = attlist1;
+ return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+attlist9(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ATTLIST_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = attlist1;
+ return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = element1;
+ return XML_ROLE_ELEMENT_NAME;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) {
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ return XML_ROLE_CONTENT_EMPTY;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) {
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ return XML_ROLE_CONTENT_ANY;
+ }
+ break;
+ case XML_TOK_OPEN_PAREN:
+ state->handler = element2;
+ state->level = 1;
+ return XML_ROLE_GROUP_OPEN;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_POUND_NAME:
+ if (XmlNameMatchesAscii(enc,
+ ptr + MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_PCDATA)) {
+ state->handler = element3;
+ return XML_ROLE_CONTENT_PCDATA;
+ }
+ break;
+ case XML_TOK_OPEN_PAREN:
+ state->level = 2;
+ state->handler = element6;
+ return XML_ROLE_GROUP_OPEN;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT;
+ case XML_TOK_NAME_QUESTION:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_OPT;
+ case XML_TOK_NAME_ASTERISK:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_REP;
+ case XML_TOK_NAME_PLUS:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_PLUS;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element3(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_CLOSE_PAREN:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ return XML_ROLE_GROUP_CLOSE;
+ case XML_TOK_CLOSE_PAREN_ASTERISK:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ return XML_ROLE_GROUP_CLOSE_REP;
+ case XML_TOK_OR:
+ state->handler = element4;
+ return XML_ROLE_ELEMENT_NONE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element4(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = element5;
+ return XML_ROLE_CONTENT_ELEMENT;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element5(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_CLOSE_PAREN_ASTERISK:
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ return XML_ROLE_GROUP_CLOSE_REP;
+ case XML_TOK_OR:
+ state->handler = element4;
+ return XML_ROLE_ELEMENT_NONE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element6(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_OPEN_PAREN:
+ state->level += 1;
+ return XML_ROLE_GROUP_OPEN;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT;
+ case XML_TOK_NAME_QUESTION:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_OPT;
+ case XML_TOK_NAME_ASTERISK:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_REP;
+ case XML_TOK_NAME_PLUS:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_PLUS;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+element7(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_ELEMENT_NONE;
+ case XML_TOK_CLOSE_PAREN:
+ state->level -= 1;
+ if (state->level == 0) {
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ }
+ return XML_ROLE_GROUP_CLOSE;
+ case XML_TOK_CLOSE_PAREN_ASTERISK:
+ state->level -= 1;
+ if (state->level == 0) {
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ }
+ return XML_ROLE_GROUP_CLOSE_REP;
+ case XML_TOK_CLOSE_PAREN_QUESTION:
+ state->level -= 1;
+ if (state->level == 0) {
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ }
+ return XML_ROLE_GROUP_CLOSE_OPT;
+ case XML_TOK_CLOSE_PAREN_PLUS:
+ state->level -= 1;
+ if (state->level == 0) {
+ state->handler = declClose;
+ state->role_none = XML_ROLE_ELEMENT_NONE;
+ }
+ return XML_ROLE_GROUP_CLOSE_PLUS;
+ case XML_TOK_COMMA:
+ state->handler = element6;
+ return XML_ROLE_GROUP_SEQUENCE;
+ case XML_TOK_OR:
+ state->handler = element6;
+ return XML_ROLE_GROUP_CHOICE;
+ }
+ return common(state, tok);
+}
+
+#ifdef XML_DTD
+
+static int PTRCALL
+condSect0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) {
+ state->handler = condSect1;
+ return XML_ROLE_NONE;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) {
+ state->handler = condSect2;
+ return XML_ROLE_NONE;
+ }
+ break;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+condSect1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_OPEN_BRACKET:
+ state->handler = externalSubset1;
+ state->includeLevel += 1;
+ return XML_ROLE_NONE;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+condSect2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_OPEN_BRACKET:
+ state->handler = externalSubset1;
+ return XML_ROLE_IGNORE_SECT;
+ }
+ return common(state, tok);
+}
+
+#endif /* XML_DTD */
+
+static int PTRCALL
+declClose(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return state->role_none;
+ case XML_TOK_DECL_CLOSE:
+ setTopLevel(state);
+ return state->role_none;
+ }
+ return common(state, tok);
+}
+
+static int PTRCALL
+error(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ return XML_ROLE_NONE;
+}
+
+static int FASTCALL
+common(PROLOG_STATE *state, int tok)
+{
+#ifdef XML_DTD
+ if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
+ return XML_ROLE_INNER_PARAM_ENTITY_REF;
+#endif
+ state->handler = error;
+ return XML_ROLE_ERROR;
+}
+
+void
+XmlPrologStateInit(PROLOG_STATE *state)
+{
+ state->handler = prolog0;
+#ifdef XML_DTD
+ state->documentEntity = 1;
+ state->includeLevel = 0;
+ state->inEntityValue = 0;
+#endif /* XML_DTD */
+}
+
+#ifdef XML_DTD
+
+void
+XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
+{
+ state->handler = externalSubset0;
+ state->documentEntity = 0;
+ state->includeLevel = 0;
+}
+
+#endif /* XML_DTD */
diff --git a/parser/expat/lib/xmlrole.h b/parser/expat/lib/xmlrole.h
new file mode 100644
index 000000000..4dd9f06f9
--- /dev/null
+++ b/parser/expat/lib/xmlrole.h
@@ -0,0 +1,114 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#ifndef XmlRole_INCLUDED
+#define XmlRole_INCLUDED 1
+
+#ifdef __VMS
+/* 0 1 2 3 0 1 2 3
+ 1234567890123456789012345678901 1234567890123456789012345678901 */
+#define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt
+#endif
+
+#include "xmltok.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ XML_ROLE_ERROR = -1,
+ XML_ROLE_NONE = 0,
+ XML_ROLE_XML_DECL,
+ XML_ROLE_INSTANCE_START,
+ XML_ROLE_DOCTYPE_NONE,
+ XML_ROLE_DOCTYPE_NAME,
+ XML_ROLE_DOCTYPE_SYSTEM_ID,
+ XML_ROLE_DOCTYPE_PUBLIC_ID,
+ XML_ROLE_DOCTYPE_INTERNAL_SUBSET,
+ XML_ROLE_DOCTYPE_CLOSE,
+ XML_ROLE_GENERAL_ENTITY_NAME,
+ XML_ROLE_PARAM_ENTITY_NAME,
+ XML_ROLE_ENTITY_NONE,
+ XML_ROLE_ENTITY_VALUE,
+ XML_ROLE_ENTITY_SYSTEM_ID,
+ XML_ROLE_ENTITY_PUBLIC_ID,
+ XML_ROLE_ENTITY_COMPLETE,
+ XML_ROLE_ENTITY_NOTATION_NAME,
+ XML_ROLE_NOTATION_NONE,
+ XML_ROLE_NOTATION_NAME,
+ XML_ROLE_NOTATION_SYSTEM_ID,
+ XML_ROLE_NOTATION_NO_SYSTEM_ID,
+ XML_ROLE_NOTATION_PUBLIC_ID,
+ XML_ROLE_ATTRIBUTE_NAME,
+ XML_ROLE_ATTRIBUTE_TYPE_CDATA,
+ XML_ROLE_ATTRIBUTE_TYPE_ID,
+ XML_ROLE_ATTRIBUTE_TYPE_IDREF,
+ XML_ROLE_ATTRIBUTE_TYPE_IDREFS,
+ XML_ROLE_ATTRIBUTE_TYPE_ENTITY,
+ XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,
+ XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,
+ XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
+ XML_ROLE_ATTRIBUTE_ENUM_VALUE,
+ XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
+ XML_ROLE_ATTLIST_NONE,
+ XML_ROLE_ATTLIST_ELEMENT_NAME,
+ XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
+ XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
+ XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
+ XML_ROLE_FIXED_ATTRIBUTE_VALUE,
+ XML_ROLE_ELEMENT_NONE,
+ XML_ROLE_ELEMENT_NAME,
+ XML_ROLE_CONTENT_ANY,
+ XML_ROLE_CONTENT_EMPTY,
+ XML_ROLE_CONTENT_PCDATA,
+ XML_ROLE_GROUP_OPEN,
+ XML_ROLE_GROUP_CLOSE,
+ XML_ROLE_GROUP_CLOSE_REP,
+ XML_ROLE_GROUP_CLOSE_OPT,
+ XML_ROLE_GROUP_CLOSE_PLUS,
+ XML_ROLE_GROUP_CHOICE,
+ XML_ROLE_GROUP_SEQUENCE,
+ XML_ROLE_CONTENT_ELEMENT,
+ XML_ROLE_CONTENT_ELEMENT_REP,
+ XML_ROLE_CONTENT_ELEMENT_OPT,
+ XML_ROLE_CONTENT_ELEMENT_PLUS,
+ XML_ROLE_PI,
+ XML_ROLE_COMMENT,
+#ifdef XML_DTD
+ XML_ROLE_TEXT_DECL,
+ XML_ROLE_IGNORE_SECT,
+ XML_ROLE_INNER_PARAM_ENTITY_REF,
+#endif /* XML_DTD */
+ XML_ROLE_PARAM_ENTITY_REF
+};
+
+typedef struct prolog_state {
+ int (PTRCALL *handler) (struct prolog_state *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc);
+ unsigned level;
+ int role_none;
+#ifdef XML_DTD
+ unsigned includeLevel;
+ int documentEntity;
+ int inEntityValue;
+#endif /* XML_DTD */
+} PROLOG_STATE;
+
+void XmlPrologStateInit(PROLOG_STATE *);
+#ifdef XML_DTD
+void XmlPrologStateInitExternalEntity(PROLOG_STATE *);
+#endif /* XML_DTD */
+
+#define XmlTokenRole(state, tok, ptr, end, enc) \
+ (((state)->handler)(state, tok, ptr, end, enc))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlRole_INCLUDED */
diff --git a/parser/expat/lib/xmltok.c b/parser/expat/lib/xmltok.c
new file mode 100644
index 000000000..37c9be121
--- /dev/null
+++ b/parser/expat/lib/xmltok.c
@@ -0,0 +1,1658 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#include <stddef.h>
+
+#ifdef COMPILED_FROM_DSP
+#include "winconfig.h"
+#elif defined(MACOS_CLASSIC)
+#include "macconfig.h"
+#elif defined(__amigaos4__)
+#include "amigaconfig.h"
+#else
+#ifdef HAVE_EXPAT_CONFIG_H
+#include <expat_config.h>
+#endif
+#endif /* ndef COMPILED_FROM_DSP */
+
+#include "expat_external.h"
+#include "internal.h"
+#include "xmltok.h"
+#include "nametab.h"
+
+#ifdef XML_DTD
+#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
+#else
+#define IGNORE_SECTION_TOK_VTABLE /* as nothing */
+#endif
+
+#define VTABLE1 \
+ { PREFIX(prologTok), PREFIX(contentTok), \
+ PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \
+ { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \
+ PREFIX(sameName), \
+ PREFIX(nameMatchesAscii), \
+ PREFIX(nameLength), \
+ PREFIX(skipS), \
+ PREFIX(getAtts), \
+ PREFIX(charRefNumber), \
+ PREFIX(predefinedEntityName), \
+ PREFIX(updatePosition), \
+ PREFIX(isPublicId)
+
+#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
+
+#define UCS2_GET_NAMING(pages, hi, lo) \
+ (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
+
+/* A 2 byte UTF-8 representation splits the characters 11 bits between
+ the bottom 5 and 6 bits of the bytes. We need 8 bits to index into
+ pages, 3 bits to add to that index and 5 bits to generate the mask.
+*/
+#define UTF8_GET_NAMING2(pages, byte) \
+ (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
+ + ((((byte)[0]) & 3) << 1) \
+ + ((((byte)[1]) >> 5) & 1)] \
+ & (1 << (((byte)[1]) & 0x1F)))
+
+/* A 3 byte UTF-8 representation splits the characters 16 bits between
+ the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index
+ into pages, 3 bits to add to that index and 5 bits to generate the
+ mask.
+*/
+#define UTF8_GET_NAMING3(pages, byte) \
+ (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
+ + ((((byte)[1]) >> 2) & 0xF)] \
+ << 3) \
+ + ((((byte)[1]) & 3) << 1) \
+ + ((((byte)[2]) >> 5) & 1)] \
+ & (1 << (((byte)[2]) & 0x1F)))
+
+#define UTF8_GET_NAMING(pages, p, n) \
+ ((n) == 2 \
+ ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
+ : ((n) == 3 \
+ ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
+ : 0))
+
+/* Detection of invalid UTF-8 sequences is based on Table 3.1B
+ of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/
+ with the additional restriction of not allowing the Unicode
+ code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE).
+ Implementation details:
+ (A & 0x80) == 0 means A < 0x80
+ and
+ (A & 0xC0) == 0xC0 means A > 0xBF
+*/
+
+#define UTF8_INVALID2(p) \
+ ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0)
+
+#define UTF8_INVALID3(p) \
+ (((p)[2] & 0x80) == 0 \
+ || \
+ ((*p) == 0xEF && (p)[1] == 0xBF \
+ ? \
+ (p)[2] > 0xBD \
+ : \
+ ((p)[2] & 0xC0) == 0xC0) \
+ || \
+ ((*p) == 0xE0 \
+ ? \
+ (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \
+ : \
+ ((p)[1] & 0x80) == 0 \
+ || \
+ ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
+
+#define UTF8_INVALID4(p) \
+ (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 \
+ || \
+ ((p)[2] & 0x80) == 0 || ((p)[2] & 0xC0) == 0xC0 \
+ || \
+ ((*p) == 0xF0 \
+ ? \
+ (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \
+ : \
+ ((p)[1] & 0x80) == 0 \
+ || \
+ ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
+
+static int PTRFASTCALL
+isNever(const ENCODING *enc, const char *p)
+{
+ return 0;
+}
+
+static int PTRFASTCALL
+utf8_isName2(const ENCODING *enc, const char *p)
+{
+ return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
+}
+
+static int PTRFASTCALL
+utf8_isName3(const ENCODING *enc, const char *p)
+{
+ return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
+}
+
+#define utf8_isName4 isNever
+
+static int PTRFASTCALL
+utf8_isNmstrt2(const ENCODING *enc, const char *p)
+{
+ return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
+}
+
+static int PTRFASTCALL
+utf8_isNmstrt3(const ENCODING *enc, const char *p)
+{
+ return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
+}
+
+#define utf8_isNmstrt4 isNever
+
+static int PTRFASTCALL
+utf8_isInvalid2(const ENCODING *enc, const char *p)
+{
+ return UTF8_INVALID2((const unsigned char *)p);
+}
+
+static int PTRFASTCALL
+utf8_isInvalid3(const ENCODING *enc, const char *p)
+{
+ return UTF8_INVALID3((const unsigned char *)p);
+}
+
+static int PTRFASTCALL
+utf8_isInvalid4(const ENCODING *enc, const char *p)
+{
+ return UTF8_INVALID4((const unsigned char *)p);
+}
+
+struct normal_encoding {
+ ENCODING enc;
+ unsigned char type[256];
+#ifdef XML_MIN_SIZE
+ int (PTRFASTCALL *byteType)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isNameMin)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *);
+ int (PTRFASTCALL *byteToAscii)(const ENCODING *, const char *);
+ int (PTRCALL *charMatches)(const ENCODING *, const char *, int);
+#endif /* XML_MIN_SIZE */
+ int (PTRFASTCALL *isName2)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isName3)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isName4)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isInvalid2)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isInvalid3)(const ENCODING *, const char *);
+ int (PTRFASTCALL *isInvalid4)(const ENCODING *, const char *);
+};
+
+#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *) (enc))
+
+#ifdef XML_MIN_SIZE
+
+#define STANDARD_VTABLE(E) \
+ E ## byteType, \
+ E ## isNameMin, \
+ E ## isNmstrtMin, \
+ E ## byteToAscii, \
+ E ## charMatches,
+
+#else
+
+#define STANDARD_VTABLE(E) /* as nothing */
+
+#endif
+
+#define NORMAL_VTABLE(E) \
+ E ## isName2, \
+ E ## isName3, \
+ E ## isName4, \
+ E ## isNmstrt2, \
+ E ## isNmstrt3, \
+ E ## isNmstrt4, \
+ E ## isInvalid2, \
+ E ## isInvalid3, \
+ E ## isInvalid4
+
+static int FASTCALL checkCharRefNumber(int);
+
+#include "xmltok_impl.h"
+#include "ascii.h"
+
+#ifdef XML_MIN_SIZE
+#define sb_isNameMin isNever
+#define sb_isNmstrtMin isNever
+#endif
+
+#ifdef XML_MIN_SIZE
+#define MINBPC(enc) ((enc)->minBytesPerChar)
+#else
+/* minimum bytes per character */
+#define MINBPC(enc) 1
+#endif
+
+#define SB_BYTE_TYPE(enc, p) \
+ (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
+
+#ifdef XML_MIN_SIZE
+static int PTRFASTCALL
+sb_byteType(const ENCODING *enc, const char *p)
+{
+ return SB_BYTE_TYPE(enc, p);
+}
+#define BYTE_TYPE(enc, p) \
+ (AS_NORMAL_ENCODING(enc)->byteType(enc, p))
+#else
+#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
+#endif
+
+#ifdef XML_MIN_SIZE
+#define BYTE_TO_ASCII(enc, p) \
+ (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))
+static int PTRFASTCALL
+sb_byteToAscii(const ENCODING *enc, const char *p)
+{
+ return *p;
+}
+#else
+#define BYTE_TO_ASCII(enc, p) (*(p))
+#endif
+
+#define IS_NAME_CHAR(enc, p, n) \
+ (AS_NORMAL_ENCODING(enc)->isName ## n(enc, p))
+#define IS_NMSTRT_CHAR(enc, p, n) \
+ (AS_NORMAL_ENCODING(enc)->isNmstrt ## n(enc, p))
+#define IS_INVALID_CHAR(enc, p, n) \
+ (AS_NORMAL_ENCODING(enc)->isInvalid ## n(enc, p))
+
+#ifdef XML_MIN_SIZE
+#define IS_NAME_CHAR_MINBPC(enc, p) \
+ (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p))
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
+ (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p))
+#else
+#define IS_NAME_CHAR_MINBPC(enc, p) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
+#endif
+
+#ifdef XML_MIN_SIZE
+#define CHAR_MATCHES(enc, p, c) \
+ (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))
+static int PTRCALL
+sb_charMatches(const ENCODING *enc, const char *p, int c)
+{
+ return *p == c;
+}
+#else
+/* c is an ASCII character */
+#define CHAR_MATCHES(enc, p, c) (*(p) == c)
+#endif
+
+#define PREFIX(ident) normal_ ## ident
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */
+ UTF8_cval1 = 0x00,
+ UTF8_cval2 = 0xc0,
+ UTF8_cval3 = 0xe0,
+ UTF8_cval4 = 0xf0
+};
+
+static void PTRCALL
+utf8_toUtf8(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ char **toP, const char *toLim)
+{
+ char *to;
+ const char *from;
+ if (fromLim - *fromP > toLim - *toP) {
+ /* Avoid copying partial characters. */
+ for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
+ if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
+ break;
+ }
+ for (to = *toP, from = *fromP; from != fromLim; from++, to++)
+ *to = *from;
+ *fromP = from;
+ *toP = to;
+}
+
+static void PTRCALL
+utf8_toUtf16(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ unsigned short **toP, const unsigned short *toLim)
+{
+ unsigned short *to = *toP;
+ const char *from = *fromP;
+ while (from != fromLim && to != toLim) {
+ switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
+ case BT_LEAD2:
+ *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
+ from += 2;
+ break;
+ case BT_LEAD3:
+ *to++ = (unsigned short)(((from[0] & 0xf) << 12)
+ | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
+ from += 3;
+ break;
+ case BT_LEAD4:
+ {
+ unsigned long n;
+ if (to + 1 == toLim)
+ goto after;
+ n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
+ | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
+ n -= 0x10000;
+ to[0] = (unsigned short)((n >> 10) | 0xD800);
+ to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
+ to += 2;
+ from += 4;
+ }
+ break;
+ default:
+ *to++ = *from++;
+ break;
+ }
+ }
+after:
+ *fromP = from;
+ *toP = to;
+}
+
+#ifdef XML_NS
+static const struct normal_encoding utf8_encoding_ns = {
+ { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+ {
+#include "asciitab.h"
+#include "utf8tab.h"
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+#endif
+
+static const struct normal_encoding utf8_encoding = {
+ { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "utf8tab.h"
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_utf8_encoding_ns = {
+ { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+ {
+#include "iasciitab.h"
+#include "utf8tab.h"
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+#endif
+
+static const struct normal_encoding internal_utf8_encoding = {
+ { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "utf8tab.h"
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+static void PTRCALL
+latin1_toUtf8(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ char **toP, const char *toLim)
+{
+ for (;;) {
+ unsigned char c;
+ if (*fromP == fromLim)
+ break;
+ c = (unsigned char)**fromP;
+ if (c & 0x80) {
+ if (toLim - *toP < 2)
+ break;
+ *(*toP)++ = (char)((c >> 6) | UTF8_cval2);
+ *(*toP)++ = (char)((c & 0x3f) | 0x80);
+ (*fromP)++;
+ }
+ else {
+ if (*toP == toLim)
+ break;
+ *(*toP)++ = *(*fromP)++;
+ }
+ }
+}
+
+static void PTRCALL
+latin1_toUtf16(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ unsigned short **toP, const unsigned short *toLim)
+{
+ while (*fromP != fromLim && *toP != toLim)
+ *(*toP)++ = (unsigned char)*(*fromP)++;
+}
+
+#ifdef XML_NS
+
+static const struct normal_encoding latin1_encoding_ns = {
+ { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
+ {
+#include "asciitab.h"
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(sb_)
+};
+
+#endif
+
+static const struct normal_encoding latin1_encoding = {
+ { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(sb_)
+};
+
+static void PTRCALL
+ascii_toUtf8(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ char **toP, const char *toLim)
+{
+ while (*fromP != fromLim && *toP != toLim)
+ *(*toP)++ = *(*fromP)++;
+}
+
+#ifdef XML_NS
+
+static const struct normal_encoding ascii_encoding_ns = {
+ { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
+ {
+#include "asciitab.h"
+/* BT_NONXML == 0 */
+ },
+ STANDARD_VTABLE(sb_)
+};
+
+#endif
+
+static const struct normal_encoding ascii_encoding = {
+ { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+/* BT_NONXML == 0 */
+ },
+ STANDARD_VTABLE(sb_)
+};
+
+static int PTRFASTCALL
+unicode_byte_type(char hi, char lo)
+{
+ switch ((unsigned char)hi) {
+ case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+ return BT_LEAD4;
+ case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+ return BT_TRAIL;
+ case 0xFF:
+ switch ((unsigned char)lo) {
+ case 0xFF:
+ case 0xFE:
+ return BT_NONXML;
+ }
+ break;
+ }
+ return BT_NONASCII;
+}
+
+#define DEFINE_UTF16_TO_UTF8(E) \
+static void PTRCALL \
+E ## toUtf8(const ENCODING *enc, \
+ const char **fromP, const char *fromLim, \
+ char **toP, const char *toLim) \
+{ \
+ const char *from; \
+ for (from = *fromP; from != fromLim; from += 2) { \
+ int plane; \
+ unsigned char lo2; \
+ unsigned char lo = GET_LO(from); \
+ unsigned char hi = GET_HI(from); \
+ switch (hi) { \
+ case 0: \
+ if (lo < 0x80) { \
+ if (*toP == toLim) { \
+ *fromP = from; \
+ return; \
+ } \
+ *(*toP)++ = lo; \
+ break; \
+ } \
+ /* fall through */ \
+ case 0x1: case 0x2: case 0x3: \
+ case 0x4: case 0x5: case 0x6: case 0x7: \
+ if (toLim - *toP < 2) { \
+ *fromP = from; \
+ return; \
+ } \
+ *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \
+ *(*toP)++ = ((lo & 0x3f) | 0x80); \
+ break; \
+ default: \
+ if (toLim - *toP < 3) { \
+ *fromP = from; \
+ return; \
+ } \
+ /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
+ *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
+ *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
+ *(*toP)++ = ((lo & 0x3f) | 0x80); \
+ break; \
+ case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
+ if (toLim - *toP < 4) { \
+ *fromP = from; \
+ return; \
+ } \
+ plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
+ *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
+ *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
+ from += 2; \
+ lo2 = GET_LO(from); \
+ *(*toP)++ = (((lo & 0x3) << 4) \
+ | ((GET_HI(from) & 0x3) << 2) \
+ | (lo2 >> 6) \
+ | 0x80); \
+ *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
+ break; \
+ } \
+ } \
+ *fromP = from; \
+}
+
+#define DEFINE_UTF16_TO_UTF16(E) \
+static void PTRCALL \
+E ## toUtf16(const ENCODING *enc, \
+ const char **fromP, const char *fromLim, \
+ unsigned short **toP, const unsigned short *toLim) \
+{ \
+ /* Avoid copying first half only of surrogate */ \
+ if (fromLim - *fromP > ((toLim - *toP) << 1) \
+ && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \
+ fromLim -= 2; \
+ for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \
+ *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
+}
+
+#define SET2(ptr, ch) \
+ (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
+#define GET_LO(ptr) ((unsigned char)(ptr)[0])
+#define GET_HI(ptr) ((unsigned char)(ptr)[1])
+
+DEFINE_UTF16_TO_UTF8(little2_)
+DEFINE_UTF16_TO_UTF16(little2_)
+
+#undef SET2
+#undef GET_LO
+#undef GET_HI
+
+#define SET2(ptr, ch) \
+ (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
+#define GET_LO(ptr) ((unsigned char)(ptr)[1])
+#define GET_HI(ptr) ((unsigned char)(ptr)[0])
+
+DEFINE_UTF16_TO_UTF8(big2_)
+DEFINE_UTF16_TO_UTF16(big2_)
+
+#undef SET2
+#undef GET_LO
+#undef GET_HI
+
+#define LITTLE2_BYTE_TYPE(enc, p) \
+ ((p)[1] == 0 \
+ ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
+ : unicode_byte_type((p)[1], (p)[0]))
+#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)
+#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)
+#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \
+ UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
+#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+ UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
+
+#ifdef XML_MIN_SIZE
+
+static int PTRFASTCALL
+little2_byteType(const ENCODING *enc, const char *p)
+{
+ return LITTLE2_BYTE_TYPE(enc, p);
+}
+
+static int PTRFASTCALL
+little2_byteToAscii(const ENCODING *enc, const char *p)
+{
+ return LITTLE2_BYTE_TO_ASCII(enc, p);
+}
+
+static int PTRCALL
+little2_charMatches(const ENCODING *enc, const char *p, int c)
+{
+ return LITTLE2_CHAR_MATCHES(enc, p, c);
+}
+
+static int PTRFASTCALL
+little2_isNameMin(const ENCODING *enc, const char *p)
+{
+ return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
+}
+
+static int PTRFASTCALL
+little2_isNmstrtMin(const ENCODING *enc, const char *p)
+{
+ return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+}
+
+#undef VTABLE
+#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
+
+#else /* not XML_MIN_SIZE */
+
+#undef PREFIX
+#define PREFIX(ident) little2_ ## ident
+#define MINBPC(enc) 2
+/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
+#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
+#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p)
+#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)
+#define IS_NAME_CHAR(enc, p, n) 0
+#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)
+#define IS_NMSTRT_CHAR(enc, p, n) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p)
+
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+#endif /* not XML_MIN_SIZE */
+
+#ifdef XML_NS
+
+static const struct normal_encoding little2_encoding_ns = {
+ { VTABLE, 2, 0,
+#if BYTEORDER == 1234
+ 1
+#else
+ 0
+#endif
+ },
+ {
+#include "asciitab.h"
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+static const struct normal_encoding little2_encoding = {
+ { VTABLE, 2, 0,
+#if BYTEORDER == 1234
+ 1
+#else
+ 0
+#endif
+ },
+ {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(little2_)
+};
+
+#if BYTEORDER != 4321
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_little2_encoding_ns = {
+ { VTABLE, 2, 0, 1 },
+ {
+#include "iasciitab.h"
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+static const struct normal_encoding internal_little2_encoding = {
+ { VTABLE, 2, 0, 1 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+
+#define BIG2_BYTE_TYPE(enc, p) \
+ ((p)[0] == 0 \
+ ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
+ : unicode_byte_type((p)[0], (p)[1]))
+#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
+#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
+#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \
+ UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
+#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+ UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
+
+#ifdef XML_MIN_SIZE
+
+static int PTRFASTCALL
+big2_byteType(const ENCODING *enc, const char *p)
+{
+ return BIG2_BYTE_TYPE(enc, p);
+}
+
+static int PTRFASTCALL
+big2_byteToAscii(const ENCODING *enc, const char *p)
+{
+ return BIG2_BYTE_TO_ASCII(enc, p);
+}
+
+static int PTRCALL
+big2_charMatches(const ENCODING *enc, const char *p, int c)
+{
+ return BIG2_CHAR_MATCHES(enc, p, c);
+}
+
+static int PTRFASTCALL
+big2_isNameMin(const ENCODING *enc, const char *p)
+{
+ return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
+}
+
+static int PTRFASTCALL
+big2_isNmstrtMin(const ENCODING *enc, const char *p)
+{
+ return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+}
+
+#undef VTABLE
+#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
+
+#else /* not XML_MIN_SIZE */
+
+#undef PREFIX
+#define PREFIX(ident) big2_ ## ident
+#define MINBPC(enc) 2
+/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
+#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
+#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p)
+#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)
+#define IS_NAME_CHAR(enc, p, n) 0
+#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)
+#define IS_NMSTRT_CHAR(enc, p, n) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p)
+
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+#endif /* not XML_MIN_SIZE */
+
+#ifdef XML_NS
+
+static const struct normal_encoding big2_encoding_ns = {
+ { VTABLE, 2, 0,
+#if BYTEORDER == 4321
+ 1
+#else
+ 0
+#endif
+ },
+ {
+#include "asciitab.h"
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+static const struct normal_encoding big2_encoding = {
+ { VTABLE, 2, 0,
+#if BYTEORDER == 4321
+ 1
+#else
+ 0
+#endif
+ },
+ {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(big2_)
+};
+
+#if BYTEORDER != 1234
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_big2_encoding_ns = {
+ { VTABLE, 2, 0, 1 },
+ {
+#include "iasciitab.h"
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+static const struct normal_encoding internal_big2_encoding = {
+ { VTABLE, 2, 0, 1 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+#undef PREFIX
+
+static int FASTCALL
+streqci(const char *s1, const char *s2)
+{
+ for (;;) {
+ char c1 = *s1++;
+ char c2 = *s2++;
+ if (ASCII_a <= c1 && c1 <= ASCII_z)
+ c1 += ASCII_A - ASCII_a;
+ if (ASCII_a <= c2 && c2 <= ASCII_z)
+ c2 += ASCII_A - ASCII_a;
+ if (c1 != c2)
+ return 0;
+ if (!c1)
+ break;
+ }
+ return 1;
+}
+
+static void PTRCALL
+initUpdatePosition(const ENCODING *enc, const char *ptr,
+ const char *end, POSITION *pos)
+{
+ normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
+}
+
+static int
+toAscii(const ENCODING *enc, const char *ptr, const char *end)
+{
+ char buf[1];
+ char *p = buf;
+ XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
+ if (p == buf)
+ return -1;
+ else
+ return buf[0];
+}
+
+static int FASTCALL
+isSpace(int c)
+{
+ switch (c) {
+ case 0x20:
+ case 0xD:
+ case 0xA:
+ case 0x9:
+ return 1;
+ }
+ return 0;
+}
+
+/* Return 1 if there's just optional white space or there's an S
+ followed by name=val.
+*/
+static int
+parsePseudoAttribute(const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **namePtr,
+ const char **nameEndPtr,
+ const char **valPtr,
+ const char **nextTokPtr)
+{
+ int c;
+ char open;
+ if (ptr == end) {
+ *namePtr = NULL;
+ return 1;
+ }
+ if (!isSpace(toAscii(enc, ptr, end))) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ do {
+ ptr += enc->minBytesPerChar;
+ } while (isSpace(toAscii(enc, ptr, end)));
+ if (ptr == end) {
+ *namePtr = NULL;
+ return 1;
+ }
+ *namePtr = ptr;
+ for (;;) {
+ c = toAscii(enc, ptr, end);
+ if (c == -1) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ if (c == ASCII_EQUALS) {
+ *nameEndPtr = ptr;
+ break;
+ }
+ if (isSpace(c)) {
+ *nameEndPtr = ptr;
+ do {
+ ptr += enc->minBytesPerChar;
+ } while (isSpace(c = toAscii(enc, ptr, end)));
+ if (c != ASCII_EQUALS) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ break;
+ }
+ ptr += enc->minBytesPerChar;
+ }
+ if (ptr == *namePtr) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ ptr += enc->minBytesPerChar;
+ c = toAscii(enc, ptr, end);
+ while (isSpace(c)) {
+ ptr += enc->minBytesPerChar;
+ c = toAscii(enc, ptr, end);
+ }
+ if (c != ASCII_QUOT && c != ASCII_APOS) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ open = (char)c;
+ ptr += enc->minBytesPerChar;
+ *valPtr = ptr;
+ for (;; ptr += enc->minBytesPerChar) {
+ c = toAscii(enc, ptr, end);
+ if (c == open)
+ break;
+ if (!(ASCII_a <= c && c <= ASCII_z)
+ && !(ASCII_A <= c && c <= ASCII_Z)
+ && !(ASCII_0 <= c && c <= ASCII_9)
+ && c != ASCII_PERIOD
+ && c != ASCII_MINUS
+ && c != ASCII_UNDERSCORE) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ }
+ *nextTokPtr = ptr + enc->minBytesPerChar;
+ return 1;
+}
+
+static const char KW_version[] = {
+ ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'
+};
+
+static const char KW_encoding[] = {
+ ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0'
+};
+
+static const char KW_standalone[] = {
+ ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o,
+ ASCII_n, ASCII_e, '\0'
+};
+
+static const char KW_yes[] = {
+ ASCII_y, ASCII_e, ASCII_s, '\0'
+};
+
+static const char KW_no[] = {
+ ASCII_n, ASCII_o, '\0'
+};
+
+/* BEGIN MOZILLA CHANGE (http://bugzilla.mozilla.org/show_bug.cgi?id=62157) */
+static const char KW_XML_1_0[] = {
+ ASCII_1, ASCII_PERIOD, ASCII_0, '\0'
+};
+/* END MOZILLA CHANGE */
+
+static int
+doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
+ const char *,
+ const char *),
+ int isGeneralTextEntity,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **badPtr,
+ const char **versionPtr,
+ const char **versionEndPtr,
+ const char **encodingName,
+ const ENCODING **encoding,
+ int *standalone)
+{
+ const char *val = NULL;
+ const char *name = NULL;
+ const char *nameEnd = NULL;
+ ptr += 5 * enc->minBytesPerChar;
+ end -= 2 * enc->minBytesPerChar;
+ if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)
+ || !name) {
+ *badPtr = ptr;
+ return 0;
+ }
+ if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
+ if (!isGeneralTextEntity) {
+ *badPtr = name;
+ return 0;
+ }
+ }
+ else {
+ if (versionPtr)
+ *versionPtr = val;
+ if (versionEndPtr)
+ *versionEndPtr = ptr;
+/* BEGIN MOZILLA CHANGE (http://bugzilla.mozilla.org/show_bug.cgi?id=62157) */
+ /* Anything else but a version="1.0" is invalid for us, until we support later versions. */
+ if (!XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_XML_1_0)) {
+ *badPtr = val;
+ return 0;
+ }
+/* END MOZILLA CHANGE */
+ if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+ *badPtr = ptr;
+ return 0;
+ }
+ if (!name) {
+ if (isGeneralTextEntity) {
+ /* a TextDecl must have an EncodingDecl */
+ *badPtr = ptr;
+ return 0;
+ }
+ return 1;
+ }
+ }
+ if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {
+ int c = toAscii(enc, val, end);
+ if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) {
+ *badPtr = val;
+ return 0;
+ }
+ if (encodingName)
+ *encodingName = val;
+ if (encoding)
+ *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
+ if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+ *badPtr = ptr;
+ return 0;
+ }
+ if (!name)
+ return 1;
+ }
+ if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone)
+ || isGeneralTextEntity) {
+ *badPtr = name;
+ return 0;
+ }
+ if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {
+ if (standalone)
+ *standalone = 1;
+ }
+ else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
+ if (standalone)
+ *standalone = 0;
+ }
+ else {
+ *badPtr = val;
+ return 0;
+ }
+ while (isSpace(toAscii(enc, ptr, end)))
+ ptr += enc->minBytesPerChar;
+ if (ptr != end) {
+ *badPtr = ptr;
+ return 0;
+ }
+ return 1;
+}
+
+static int FASTCALL
+checkCharRefNumber(int result)
+{
+ switch (result >> 8) {
+ case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+ case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+ return -1;
+ case 0:
+ if (latin1_encoding.type[result] == BT_NONXML)
+ return -1;
+ break;
+ case 0xFF:
+ if (result == 0xFFFE || result == 0xFFFF)
+ return -1;
+ break;
+ }
+ return result;
+}
+
+int FASTCALL
+XmlUtf8Encode(int c, char *buf)
+{
+ enum {
+ /* minN is minimum legal resulting value for N byte sequence */
+ min2 = 0x80,
+ min3 = 0x800,
+ min4 = 0x10000
+ };
+
+ if (c < 0)
+ return 0;
+ if (c < min2) {
+ buf[0] = (char)(c | UTF8_cval1);
+ return 1;
+ }
+ if (c < min3) {
+ buf[0] = (char)((c >> 6) | UTF8_cval2);
+ buf[1] = (char)((c & 0x3f) | 0x80);
+ return 2;
+ }
+ if (c < min4) {
+ buf[0] = (char)((c >> 12) | UTF8_cval3);
+ buf[1] = (char)(((c >> 6) & 0x3f) | 0x80);
+ buf[2] = (char)((c & 0x3f) | 0x80);
+ return 3;
+ }
+ if (c < 0x110000) {
+ buf[0] = (char)((c >> 18) | UTF8_cval4);
+ buf[1] = (char)(((c >> 12) & 0x3f) | 0x80);
+ buf[2] = (char)(((c >> 6) & 0x3f) | 0x80);
+ buf[3] = (char)((c & 0x3f) | 0x80);
+ return 4;
+ }
+ return 0;
+}
+
+int FASTCALL
+XmlUtf16Encode(int charNum, unsigned short *buf)
+{
+ if (charNum < 0)
+ return 0;
+ if (charNum < 0x10000) {
+ buf[0] = (unsigned short)charNum;
+ return 1;
+ }
+ if (charNum < 0x110000) {
+ charNum -= 0x10000;
+ buf[0] = (unsigned short)((charNum >> 10) + 0xD800);
+ buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00);
+ return 2;
+ }
+ return 0;
+}
+
+struct unknown_encoding {
+ struct normal_encoding normal;
+ CONVERTER convert;
+ void *userData;
+ unsigned short utf16[256];
+ char utf8[256][4];
+};
+
+#define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *) (enc))
+
+int
+XmlSizeOfUnknownEncoding(void)
+{
+ return sizeof(struct unknown_encoding);
+}
+
+static int PTRFASTCALL
+unknown_isName(const ENCODING *enc, const char *p)
+{
+ const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+ int c = uenc->convert(uenc->userData, p);
+ if (c & ~0xFFFF)
+ return 0;
+ return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
+}
+
+static int PTRFASTCALL
+unknown_isNmstrt(const ENCODING *enc, const char *p)
+{
+ const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+ int c = uenc->convert(uenc->userData, p);
+ if (c & ~0xFFFF)
+ return 0;
+ return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
+}
+
+static int PTRFASTCALL
+unknown_isInvalid(const ENCODING *enc, const char *p)
+{
+ const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+ int c = uenc->convert(uenc->userData, p);
+ return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
+}
+
+static void PTRCALL
+unknown_toUtf8(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ char **toP, const char *toLim)
+{
+ const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+ char buf[XML_UTF8_ENCODE_MAX];
+ for (;;) {
+ const char *utf8;
+ int n;
+ if (*fromP == fromLim)
+ break;
+ utf8 = uenc->utf8[(unsigned char)**fromP];
+ n = *utf8++;
+ if (n == 0) {
+ int c = uenc->convert(uenc->userData, *fromP);
+ n = XmlUtf8Encode(c, buf);
+ if (n > toLim - *toP)
+ break;
+ utf8 = buf;
+ *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
+ - (BT_LEAD2 - 2));
+ }
+ else {
+ if (n > toLim - *toP)
+ break;
+ (*fromP)++;
+ }
+ do {
+ *(*toP)++ = *utf8++;
+ } while (--n != 0);
+ }
+}
+
+static void PTRCALL
+unknown_toUtf16(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ unsigned short **toP, const unsigned short *toLim)
+{
+ const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+ while (*fromP != fromLim && *toP != toLim) {
+ unsigned short c = uenc->utf16[(unsigned char)**fromP];
+ if (c == 0) {
+ c = (unsigned short)
+ uenc->convert(uenc->userData, *fromP);
+ *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
+ - (BT_LEAD2 - 2));
+ }
+ else
+ (*fromP)++;
+ *(*toP)++ = c;
+ }
+}
+
+ENCODING *
+XmlInitUnknownEncoding(void *mem,
+ int *table,
+ CONVERTER convert,
+ void *userData)
+{
+ int i;
+ struct unknown_encoding *e = (struct unknown_encoding *)mem;
+ for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
+ ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
+ for (i = 0; i < 128; i++)
+ if (latin1_encoding.type[i] != BT_OTHER
+ && latin1_encoding.type[i] != BT_NONXML
+ && table[i] != i)
+ return 0;
+ for (i = 0; i < 256; i++) {
+ int c = table[i];
+ if (c == -1) {
+ e->normal.type[i] = BT_MALFORM;
+ /* This shouldn't really get used. */
+ e->utf16[i] = 0xFFFF;
+ e->utf8[i][0] = 1;
+ e->utf8[i][1] = 0;
+ }
+ else if (c < 0) {
+ if (c < -4)
+ return 0;
+ e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
+ e->utf8[i][0] = 0;
+ e->utf16[i] = 0;
+ }
+ else if (c < 0x80) {
+ if (latin1_encoding.type[c] != BT_OTHER
+ && latin1_encoding.type[c] != BT_NONXML
+ && c != i)
+ return 0;
+ e->normal.type[i] = latin1_encoding.type[c];
+ e->utf8[i][0] = 1;
+ e->utf8[i][1] = (char)c;
+ e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c);
+ }
+ else if (checkCharRefNumber(c) < 0) {
+ e->normal.type[i] = BT_NONXML;
+ /* This shouldn't really get used. */
+ e->utf16[i] = 0xFFFF;
+ e->utf8[i][0] = 1;
+ e->utf8[i][1] = 0;
+ }
+ else {
+ if (c > 0xFFFF)
+ return 0;
+ if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
+ e->normal.type[i] = BT_NMSTRT;
+ else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
+ e->normal.type[i] = BT_NAME;
+ else
+ e->normal.type[i] = BT_OTHER;
+ e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
+ e->utf16[i] = (unsigned short)c;
+ }
+ }
+ e->userData = userData;
+ e->convert = convert;
+ if (convert) {
+ e->normal.isName2 = unknown_isName;
+ e->normal.isName3 = unknown_isName;
+ e->normal.isName4 = unknown_isName;
+ e->normal.isNmstrt2 = unknown_isNmstrt;
+ e->normal.isNmstrt3 = unknown_isNmstrt;
+ e->normal.isNmstrt4 = unknown_isNmstrt;
+ e->normal.isInvalid2 = unknown_isInvalid;
+ e->normal.isInvalid3 = unknown_isInvalid;
+ e->normal.isInvalid4 = unknown_isInvalid;
+ }
+ e->normal.enc.utf8Convert = unknown_toUtf8;
+ e->normal.enc.utf16Convert = unknown_toUtf16;
+ return &(e->normal.enc);
+}
+
+/* If this enumeration is changed, getEncodingIndex and encodings
+must also be changed. */
+enum {
+ UNKNOWN_ENC = -1,
+ ISO_8859_1_ENC = 0,
+ US_ASCII_ENC,
+ UTF_8_ENC,
+ UTF_16_ENC,
+ UTF_16BE_ENC,
+ UTF_16LE_ENC,
+ /* must match encodingNames up to here */
+ NO_ENC
+};
+
+static const char KW_ISO_8859_1[] = {
+ ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9,
+ ASCII_MINUS, ASCII_1, '\0'
+};
+static const char KW_US_ASCII[] = {
+ ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I,
+ '\0'
+};
+static const char KW_UTF_8[] = {
+ ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'
+};
+static const char KW_UTF_16[] = {
+ ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'
+};
+static const char KW_UTF_16BE[] = {
+ ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E,
+ '\0'
+};
+static const char KW_UTF_16LE[] = {
+ ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E,
+ '\0'
+};
+
+static int FASTCALL
+getEncodingIndex(const char *name)
+{
+ static const char * const encodingNames[] = {
+ KW_ISO_8859_1,
+ KW_US_ASCII,
+ KW_UTF_8,
+ KW_UTF_16,
+ KW_UTF_16BE,
+ KW_UTF_16LE,
+ };
+ int i;
+ if (name == NULL)
+ return NO_ENC;
+ for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++)
+ if (streqci(name, encodingNames[i]))
+ return i;
+ return UNKNOWN_ENC;
+}
+
+/* For binary compatibility, we store the index of the encoding
+ specified at initialization in the isUtf16 member.
+*/
+
+#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)
+#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i)
+
+/* This is what detects the encoding. encodingTable maps from
+ encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of
+ the external (protocol) specified encoding; state is
+ XML_CONTENT_STATE if we're parsing an external text entity, and
+ XML_PROLOG_STATE otherwise.
+*/
+
+
+static int
+initScan(const ENCODING * const *encodingTable,
+ const INIT_ENCODING *enc,
+ int state,
+ const char *ptr,
+ const char *end,
+ const char **nextTokPtr)
+{
+ const ENCODING **encPtr;
+
+ if (ptr == end)
+ return XML_TOK_NONE;
+ encPtr = enc->encPtr;
+ if (ptr + 1 == end) {
+ /* only a single byte available for auto-detection */
+#ifndef XML_DTD /* FIXME */
+ /* a well-formed document entity must have more than one byte */
+ if (state != XML_CONTENT_STATE)
+ return XML_TOK_PARTIAL;
+#endif
+ /* so we're parsing an external text entity... */
+ /* if UTF-16 was externally specified, then we need at least 2 bytes */
+ switch (INIT_ENC_INDEX(enc)) {
+ case UTF_16_ENC:
+ case UTF_16LE_ENC:
+ case UTF_16BE_ENC:
+ return XML_TOK_PARTIAL;
+ }
+ switch ((unsigned char)*ptr) {
+ case 0xFE:
+ case 0xFF:
+ case 0xEF: /* possibly first byte of UTF-8 BOM */
+ if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+ && state == XML_CONTENT_STATE)
+ break;
+ /* fall through */
+ case 0x00:
+ case 0x3C:
+ return XML_TOK_PARTIAL;
+ }
+ }
+ else {
+ switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
+ case 0xFEFF:
+ if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+ && state == XML_CONTENT_STATE)
+ break;
+ *nextTokPtr = ptr + 2;
+ *encPtr = encodingTable[UTF_16BE_ENC];
+ return XML_TOK_BOM;
+ /* 00 3C is handled in the default case */
+ case 0x3C00:
+ if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
+ || INIT_ENC_INDEX(enc) == UTF_16_ENC)
+ && state == XML_CONTENT_STATE)
+ break;
+ *encPtr = encodingTable[UTF_16LE_ENC];
+ return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+ case 0xFFFE:
+ if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+ && state == XML_CONTENT_STATE)
+ break;
+ *nextTokPtr = ptr + 2;
+ *encPtr = encodingTable[UTF_16LE_ENC];
+ return XML_TOK_BOM;
+ case 0xEFBB:
+ /* Maybe a UTF-8 BOM (EF BB BF) */
+ /* If there's an explicitly specified (external) encoding
+ of ISO-8859-1 or some flavour of UTF-16
+ and this is an external text entity,
+ don't look for the BOM,
+ because it might be a legal data.
+ */
+ if (state == XML_CONTENT_STATE) {
+ int e = INIT_ENC_INDEX(enc);
+ if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC
+ || e == UTF_16LE_ENC || e == UTF_16_ENC)
+ break;
+ }
+ if (ptr + 2 == end)
+ return XML_TOK_PARTIAL;
+ if ((unsigned char)ptr[2] == 0xBF) {
+ *nextTokPtr = ptr + 3;
+ *encPtr = encodingTable[UTF_8_ENC];
+ return XML_TOK_BOM;
+ }
+ break;
+ default:
+ if (ptr[0] == '\0') {
+ /* 0 isn't a legal data character. Furthermore a document
+ entity can only start with ASCII characters. So the only
+ way this can fail to be big-endian UTF-16 if it it's an
+ external parsed general entity that's labelled as
+ UTF-16LE.
+ */
+ if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
+ break;
+ *encPtr = encodingTable[UTF_16BE_ENC];
+ return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+ }
+ else if (ptr[1] == '\0') {
+ /* We could recover here in the case:
+ - parsing an external entity
+ - second byte is 0
+ - no externally specified encoding
+ - no encoding declaration
+ by assuming UTF-16LE. But we don't, because this would mean when
+ presented just with a single byte, we couldn't reliably determine
+ whether we needed further bytes.
+ */
+ if (state == XML_CONTENT_STATE)
+ break;
+ *encPtr = encodingTable[UTF_16LE_ENC];
+ return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+ }
+ break;
+ }
+ }
+ *encPtr = encodingTable[INIT_ENC_INDEX(enc)];
+ return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+}
+
+
+#define NS(x) x
+#define ns(x) x
+#include "xmltok_ns.c"
+#undef NS
+#undef ns
+
+#ifdef XML_NS
+
+#define NS(x) x ## NS
+#define ns(x) x ## _ns
+
+#include "xmltok_ns.c"
+
+#undef NS
+#undef ns
+
+ENCODING *
+XmlInitUnknownEncodingNS(void *mem,
+ int *table,
+ CONVERTER convert,
+ void *userData)
+{
+ ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
+ if (enc)
+ ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
+ return enc;
+}
+
+#endif /* XML_NS */
+
+/* BEGIN MOZILLA CHANGE (Mozilla extensions for QName checking) */
+#ifdef MOZILLA_CLIENT
+#include "moz_extensions.c"
+#endif /* MOZILLA_CLIENT */
+/* END MOZILLA CHANGE */
diff --git a/parser/expat/lib/xmltok.h b/parser/expat/lib/xmltok.h
new file mode 100644
index 000000000..ca867aa6b
--- /dev/null
+++ b/parser/expat/lib/xmltok.h
@@ -0,0 +1,316 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#ifndef XmlTok_INCLUDED
+#define XmlTok_INCLUDED 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The following token may be returned by XmlContentTok */
+#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be
+ start of illegal ]]> sequence */
+/* The following tokens may be returned by both XmlPrologTok and
+ XmlContentTok.
+*/
+#define XML_TOK_NONE -4 /* The string to be scanned is empty */
+#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
+ might be part of CRLF sequence */
+#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
+#define XML_TOK_PARTIAL -1 /* only part of a token */
+#define XML_TOK_INVALID 0
+
+/* The following tokens are returned by XmlContentTok; some are also
+ returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok.
+*/
+#define XML_TOK_START_TAG_WITH_ATTS 1
+#define XML_TOK_START_TAG_NO_ATTS 2
+#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
+#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
+#define XML_TOK_END_TAG 5
+#define XML_TOK_DATA_CHARS 6
+#define XML_TOK_DATA_NEWLINE 7
+#define XML_TOK_CDATA_SECT_OPEN 8
+#define XML_TOK_ENTITY_REF 9
+#define XML_TOK_CHAR_REF 10 /* numeric character reference */
+
+/* The following tokens may be returned by both XmlPrologTok and
+ XmlContentTok.
+*/
+#define XML_TOK_PI 11 /* processing instruction */
+#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
+#define XML_TOK_COMMENT 13
+#define XML_TOK_BOM 14 /* Byte order mark */
+
+/* The following tokens are returned only by XmlPrologTok */
+#define XML_TOK_PROLOG_S 15
+#define XML_TOK_DECL_OPEN 16 /* <!foo */
+#define XML_TOK_DECL_CLOSE 17 /* > */
+#define XML_TOK_NAME 18
+#define XML_TOK_NMTOKEN 19
+#define XML_TOK_POUND_NAME 20 /* #name */
+#define XML_TOK_OR 21 /* | */
+#define XML_TOK_PERCENT 22
+#define XML_TOK_OPEN_PAREN 23
+#define XML_TOK_CLOSE_PAREN 24
+#define XML_TOK_OPEN_BRACKET 25
+#define XML_TOK_CLOSE_BRACKET 26
+#define XML_TOK_LITERAL 27
+#define XML_TOK_PARAM_ENTITY_REF 28
+#define XML_TOK_INSTANCE_START 29
+
+/* The following occur only in element type declarations */
+#define XML_TOK_NAME_QUESTION 30 /* name? */
+#define XML_TOK_NAME_ASTERISK 31 /* name* */
+#define XML_TOK_NAME_PLUS 32 /* name+ */
+#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
+#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
+#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
+#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
+#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
+#define XML_TOK_COMMA 38
+
+/* The following token is returned only by XmlAttributeValueTok */
+#define XML_TOK_ATTRIBUTE_VALUE_S 39
+
+/* The following token is returned only by XmlCdataSectionTok */
+#define XML_TOK_CDATA_SECT_CLOSE 40
+
+/* With namespace processing this is returned by XmlPrologTok for a
+ name with a colon.
+*/
+#define XML_TOK_PREFIXED_NAME 41
+
+#ifdef XML_DTD
+#define XML_TOK_IGNORE_SECT 42
+#endif /* XML_DTD */
+
+#ifdef XML_DTD
+#define XML_N_STATES 4
+#else /* not XML_DTD */
+#define XML_N_STATES 3
+#endif /* not XML_DTD */
+
+#define XML_PROLOG_STATE 0
+#define XML_CONTENT_STATE 1
+#define XML_CDATA_SECTION_STATE 2
+#ifdef XML_DTD
+#define XML_IGNORE_SECTION_STATE 3
+#endif /* XML_DTD */
+
+#define XML_N_LITERAL_TYPES 2
+#define XML_ATTRIBUTE_VALUE_LITERAL 0
+#define XML_ENTITY_VALUE_LITERAL 1
+
+/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
+#define XML_UTF8_ENCODE_MAX 4
+/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
+#define XML_UTF16_ENCODE_MAX 2
+
+typedef struct position {
+ /* first line and first column are 0 not 1 */
+ XML_Size lineNumber;
+ XML_Size columnNumber;
+} POSITION;
+
+typedef struct {
+ const char *name;
+ const char *valuePtr;
+ const char *valueEnd;
+ char normalized;
+} ATTRIBUTE;
+
+struct encoding;
+typedef struct encoding ENCODING;
+
+typedef int (PTRCALL *SCANNER)(const ENCODING *,
+ const char *,
+ const char *,
+ const char **);
+
+struct encoding {
+ SCANNER scanners[XML_N_STATES];
+ SCANNER literalScanners[XML_N_LITERAL_TYPES];
+ int (PTRCALL *sameName)(const ENCODING *,
+ const char *,
+ const char *);
+ int (PTRCALL *nameMatchesAscii)(const ENCODING *,
+ const char *,
+ const char *,
+ const char *);
+ int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);
+ const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
+ int (PTRCALL *getAtts)(const ENCODING *enc,
+ const char *ptr,
+ int attsMax,
+ ATTRIBUTE *atts);
+ int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
+ int (PTRCALL *predefinedEntityName)(const ENCODING *,
+ const char *,
+ const char *);
+ void (PTRCALL *updatePosition)(const ENCODING *,
+ const char *ptr,
+ const char *end,
+ POSITION *);
+ int (PTRCALL *isPublicId)(const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **badPtr);
+ void (PTRCALL *utf8Convert)(const ENCODING *enc,
+ const char **fromP,
+ const char *fromLim,
+ char **toP,
+ const char *toLim);
+ void (PTRCALL *utf16Convert)(const ENCODING *enc,
+ const char **fromP,
+ const char *fromLim,
+ unsigned short **toP,
+ const unsigned short *toLim);
+ int minBytesPerChar;
+ char isUtf8;
+ char isUtf16;
+};
+
+/* Scan the string starting at ptr until the end of the next complete
+ token, but do not scan past eptr. Return an integer giving the
+ type of token.
+
+ Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
+
+ Return XML_TOK_PARTIAL when the string does not contain a complete
+ token; nextTokPtr will not be set.
+
+ Return XML_TOK_INVALID when the string does not start a valid
+ token; nextTokPtr will be set to point to the character which made
+ the token invalid.
+
+ Otherwise the string starts with a valid token; nextTokPtr will be
+ set to point to the character following the end of that token.
+
+ Each data character counts as a single token, but adjacent data
+ characters may be returned together. Similarly for characters in
+ the prolog outside literals, comments and processing instructions.
+*/
+
+
+#define XmlTok(enc, state, ptr, end, nextTokPtr) \
+ (((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
+
+#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
+
+#define XmlContentTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
+
+#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
+
+#ifdef XML_DTD
+
+#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
+
+#endif /* XML_DTD */
+
+/* This is used for performing a 2nd-level tokenization on the content
+ of a literal that has already been returned by XmlTok.
+*/
+#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
+ (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
+
+#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
+ XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
+
+#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
+ XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
+
+#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
+
+#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
+ (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
+
+#define XmlNameLength(enc, ptr) \
+ (((enc)->nameLength)(enc, ptr))
+
+#define XmlSkipS(enc, ptr) \
+ (((enc)->skipS)(enc, ptr))
+
+#define XmlGetAttributes(enc, ptr, attsMax, atts) \
+ (((enc)->getAtts)(enc, ptr, attsMax, atts))
+
+#define XmlCharRefNumber(enc, ptr) \
+ (((enc)->charRefNumber)(enc, ptr))
+
+#define XmlPredefinedEntityName(enc, ptr, end) \
+ (((enc)->predefinedEntityName)(enc, ptr, end))
+
+#define XmlUpdatePosition(enc, ptr, end, pos) \
+ (((enc)->updatePosition)(enc, ptr, end, pos))
+
+#define XmlIsPublicId(enc, ptr, end, badPtr) \
+ (((enc)->isPublicId)(enc, ptr, end, badPtr))
+
+#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
+ (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
+
+#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
+ (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
+
+typedef struct {
+ ENCODING initEnc;
+ const ENCODING **encPtr;
+} INIT_ENCODING;
+
+int XmlParseXmlDecl(int isGeneralTextEntity,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **badPtr,
+ const char **versionPtr,
+ const char **versionEndPtr,
+ const char **encodingNamePtr,
+ const ENCODING **namedEncodingPtr,
+ int *standalonePtr);
+
+int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING *XmlGetUtf8InternalEncoding(void);
+const ENCODING *XmlGetUtf16InternalEncoding(void);
+int FASTCALL XmlUtf8Encode(int charNumber, char *buf);
+int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf);
+int XmlSizeOfUnknownEncoding(void);
+
+
+typedef int (XMLCALL *CONVERTER) (void *userData, const char *p);
+
+ENCODING *
+XmlInitUnknownEncoding(void *mem,
+ int *table,
+ CONVERTER convert,
+ void *userData);
+
+int XmlParseXmlDeclNS(int isGeneralTextEntity,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **badPtr,
+ const char **versionPtr,
+ const char **versionEndPtr,
+ const char **encodingNamePtr,
+ const ENCODING **namedEncodingPtr,
+ int *standalonePtr);
+
+int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING *XmlGetUtf8InternalEncodingNS(void);
+const ENCODING *XmlGetUtf16InternalEncodingNS(void);
+ENCODING *
+XmlInitUnknownEncodingNS(void *mem,
+ int *table,
+ CONVERTER convert,
+ void *userData);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlTok_INCLUDED */
diff --git a/parser/expat/lib/xmltok_impl.c b/parser/expat/lib/xmltok_impl.c
new file mode 100644
index 000000000..0ee57abb1
--- /dev/null
+++ b/parser/expat/lib/xmltok_impl.c
@@ -0,0 +1,1779 @@
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#ifndef IS_INVALID_CHAR
+#define IS_INVALID_CHAR(enc, ptr, n) (0)
+#endif
+
+#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (IS_INVALID_CHAR(enc, ptr, n)) { \
+ *(nextTokPtr) = (ptr); \
+ return XML_TOK_INVALID; \
+ } \
+ ptr += n; \
+ break;
+
+#define INVALID_CASES(ptr, nextTokPtr) \
+ INVALID_LEAD_CASE(2, ptr, nextTokPtr) \
+ INVALID_LEAD_CASE(3, ptr, nextTokPtr) \
+ INVALID_LEAD_CASE(4, ptr, nextTokPtr) \
+ case BT_NONXML: \
+ case BT_MALFORM: \
+ case BT_TRAIL: \
+ *(nextTokPtr) = (ptr); \
+ return XML_TOK_INVALID;
+
+#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (!IS_NAME_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ ptr += n; \
+ break;
+
+#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \
+ case BT_NONASCII: \
+ if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ case BT_NMSTRT: \
+ case BT_HEX: \
+ case BT_DIGIT: \
+ case BT_NAME: \
+ case BT_MINUS: \
+ ptr += MINBPC(enc); \
+ break; \
+ CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \
+ CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \
+ CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
+
+#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ ptr += n; \
+ break;
+
+#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
+ case BT_NONASCII: \
+ if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ case BT_NMSTRT: \
+ case BT_HEX: \
+ ptr += MINBPC(enc); \
+ break; \
+ CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
+ CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
+ CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
+
+#ifndef PREFIX
+#define PREFIX(ident) ident
+#endif
+
+/* ptr points to character following "<!-" */
+
+static int PTRCALL
+PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ if (ptr != end) {
+ if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ ptr += MINBPC(enc);
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ INVALID_CASES(ptr, nextTokPtr)
+ case BT_MINUS:
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_COMMENT;
+ }
+ break;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "<!" */
+
+static int PTRCALL
+PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_MINUS:
+ return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_LSQB:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_COND_SECT_OPEN;
+ case BT_NMSTRT:
+ case BT_HEX:
+ ptr += MINBPC(enc);
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_PERCNT:
+ if (ptr + MINBPC(enc) == end)
+ return XML_TOK_PARTIAL;
+ /* don't allow <!ENTITY% foo "whatever"> */
+ switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
+ case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ /* fall through */
+ case BT_S: case BT_CR: case BT_LF:
+ *nextTokPtr = ptr;
+ return XML_TOK_DECL_OPEN;
+ case BT_NMSTRT:
+ case BT_HEX:
+ ptr += MINBPC(enc);
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+static int PTRCALL
+PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr,
+ const char *end, int *tokPtr)
+{
+ int upper = 0;
+ *tokPtr = XML_TOK_PI;
+ if (end - ptr != MINBPC(enc)*3)
+ return 1;
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case ASCII_x:
+ break;
+ case ASCII_X:
+ upper = 1;
+ break;
+ default:
+ return 1;
+ }
+ ptr += MINBPC(enc);
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case ASCII_m:
+ break;
+ case ASCII_M:
+ upper = 1;
+ break;
+ default:
+ return 1;
+ }
+ ptr += MINBPC(enc);
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case ASCII_l:
+ break;
+ case ASCII_L:
+ upper = 1;
+ break;
+ default:
+ return 1;
+ }
+ if (upper)
+ return 0;
+ *tokPtr = XML_TOK_XML_DECL;
+ return 1;
+}
+
+/* ptr points to character following "<?" */
+
+static int PTRCALL
+PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ int tok;
+ const char *target = ptr;
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_S: case BT_CR: case BT_LF:
+ if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ ptr += MINBPC(enc);
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ INVALID_CASES(ptr, nextTokPtr)
+ case BT_QUEST:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ *nextTokPtr = ptr + MINBPC(enc);
+ return tok;
+ }
+ break;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ return XML_TOK_PARTIAL;
+ case BT_QUEST:
+ if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ *nextTokPtr = ptr + MINBPC(enc);
+ return tok;
+ }
+ /* fall through */
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+static int PTRCALL
+PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A,
+ ASCII_T, ASCII_A, ASCII_LSQB };
+ int i;
+ /* CDATA[ */
+ if (end - ptr < 6 * MINBPC(enc))
+ return XML_TOK_PARTIAL;
+ for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
+ if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_CDATA_SECT_OPEN;
+}
+
+static int PTRCALL
+PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_NONE;
+ if (MINBPC(enc) > 1) {
+ size_t n = end - ptr;
+ if (n & (MINBPC(enc) - 1)) {
+ n &= ~(MINBPC(enc) - 1);
+ if (n == 0)
+ return XML_TOK_PARTIAL;
+ end = ptr + n;
+ }
+ }
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_RSQB:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+ break;
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ ptr -= MINBPC(enc);
+ break;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CDATA_SECT_CLOSE;
+ case BT_CR:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (BYTE_TYPE(enc, ptr) == BT_LF)
+ ptr += MINBPC(enc);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_NEWLINE;
+ case BT_LF:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_DATA_NEWLINE;
+ INVALID_CASES(ptr, nextTokPtr)
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_DATA_CHARS; \
+ } \
+ ptr += n; \
+ break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_NONXML:
+ case BT_MALFORM:
+ case BT_TRAIL:
+ case BT_CR:
+ case BT_LF:
+ case BT_RSQB:
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+}
+
+/* ptr points to character following "</" */
+
+static int PTRCALL
+PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_S: case BT_CR: case BT_LF:
+ for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_S: case BT_CR: case BT_LF:
+ break;
+ case BT_GT:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_END_TAG;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+#ifdef XML_NS
+ case BT_COLON:
+ /* no need to check qname syntax here,
+ since end-tag must match exactly */
+ ptr += MINBPC(enc);
+ break;
+#endif
+ case BT_GT:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_END_TAG;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&#X" */
+
+static int PTRCALL
+PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ if (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_DIGIT:
+ case BT_HEX:
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_DIGIT:
+ case BT_HEX:
+ break;
+ case BT_SEMI:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CHAR_REF;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&#" */
+
+static int PTRCALL
+PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ if (ptr != end) {
+ if (CHAR_MATCHES(enc, ptr, ASCII_x))
+ return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_DIGIT:
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_DIGIT:
+ break;
+ case BT_SEMI:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CHAR_REF;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&" */
+
+static int PTRCALL
+PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_NUM:
+ return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_SEMI:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_ENTITY_REF;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following first character of attribute name */
+
+static int PTRCALL
+PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+#ifdef XML_NS
+ int hadColon = 0;
+#endif
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#ifdef XML_NS
+ case BT_COLON:
+ if (hadColon) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ hadColon = 1;
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ break;
+#endif
+ case BT_S: case BT_CR: case BT_LF:
+ for (;;) {
+ int t;
+
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ t = BYTE_TYPE(enc, ptr);
+ if (t == BT_EQUALS)
+ break;
+ switch (t) {
+ case BT_S:
+ case BT_LF:
+ case BT_CR:
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ /* fall through */
+ case BT_EQUALS:
+ {
+ int open;
+#ifdef XML_NS
+ hadColon = 0;
+#endif
+ for (;;) {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ open = BYTE_TYPE(enc, ptr);
+ if (open == BT_QUOT || open == BT_APOS)
+ break;
+ switch (open) {
+ case BT_S:
+ case BT_LF:
+ case BT_CR:
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ ptr += MINBPC(enc);
+ /* in attribute value */
+ for (;;) {
+ int t;
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ t = BYTE_TYPE(enc, ptr);
+ if (t == open)
+ break;
+ switch (t) {
+ INVALID_CASES(ptr, nextTokPtr)
+ case BT_AMP:
+ {
+ int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
+ if (tok <= 0) {
+ if (tok == XML_TOK_INVALID)
+ *nextTokPtr = ptr;
+ return tok;
+ }
+ break;
+ }
+ case BT_LT:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_S:
+ case BT_CR:
+ case BT_LF:
+ break;
+ case BT_SOL:
+ goto sol;
+ case BT_GT:
+ goto gt;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ /* ptr points to closing quote */
+ for (;;) {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_S: case BT_CR: case BT_LF:
+ continue;
+ case BT_GT:
+ gt:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_START_TAG_WITH_ATTS;
+ case BT_SOL:
+ sol:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ break;
+ }
+ break;
+ }
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "<" */
+
+static int PTRCALL
+PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+#ifdef XML_NS
+ int hadColon;
+#endif
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_EXCL:
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_MINUS:
+ return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_LSQB:
+ return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc),
+ end, nextTokPtr);
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ case BT_QUEST:
+ return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_SOL:
+ return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+#ifdef XML_NS
+ hadColon = 0;
+#endif
+ /* we have a start-tag */
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#ifdef XML_NS
+ case BT_COLON:
+ if (hadColon) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ hadColon = 1;
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ break;
+#endif
+ case BT_S: case BT_CR: case BT_LF:
+ {
+ ptr += MINBPC(enc);
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_GT:
+ goto gt;
+ case BT_SOL:
+ goto sol;
+ case BT_S: case BT_CR: case BT_LF:
+ ptr += MINBPC(enc);
+ continue;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
+ }
+ return XML_TOK_PARTIAL;
+ }
+ case BT_GT:
+ gt:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_START_TAG_NO_ATTS;
+ case BT_SOL:
+ sol:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+static int PTRCALL
+PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_NONE;
+ if (MINBPC(enc) > 1) {
+ size_t n = end - ptr;
+ if (n & (MINBPC(enc) - 1)) {
+ n &= ~(MINBPC(enc) - 1);
+ if (n == 0)
+ return XML_TOK_PARTIAL;
+ end = ptr + n;
+ }
+ }
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_LT:
+ return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_AMP:
+ return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_CR:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_TRAILING_CR;
+ if (BYTE_TYPE(enc, ptr) == BT_LF)
+ ptr += MINBPC(enc);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_NEWLINE;
+ case BT_LF:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_DATA_NEWLINE;
+ case BT_RSQB:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_TRAILING_RSQB;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+ break;
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_TRAILING_RSQB;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ ptr -= MINBPC(enc);
+ break;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ INVALID_CASES(ptr, nextTokPtr)
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_DATA_CHARS; \
+ } \
+ ptr += n; \
+ break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_RSQB:
+ if (ptr + MINBPC(enc) != end) {
+ if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
+ ptr += MINBPC(enc);
+ break;
+ }
+ if (ptr + 2*MINBPC(enc) != end) {
+ if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
+ ptr += MINBPC(enc);
+ break;
+ }
+ *nextTokPtr = ptr + 2*MINBPC(enc);
+ return XML_TOK_INVALID;
+ }
+ }
+ /* fall through */
+ case BT_AMP:
+ case BT_LT:
+ case BT_NONXML:
+ case BT_MALFORM:
+ case BT_TRAIL:
+ case BT_CR:
+ case BT_LF:
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+}
+
+/* ptr points to character following "%" */
+
+static int PTRCALL
+PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr == end)
+ return -XML_TOK_PERCENT;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
+ *nextTokPtr = ptr;
+ return XML_TOK_PERCENT;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_SEMI:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_PARAM_ENTITY_REF;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+static int PTRCALL
+PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_CR: case BT_LF: case BT_S:
+ case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
+ *nextTokPtr = ptr;
+ return XML_TOK_POUND_NAME;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return -XML_TOK_POUND_NAME;
+}
+
+static int PTRCALL
+PREFIX(scanLit)(int open, const ENCODING *enc,
+ const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ while (ptr != end) {
+ int t = BYTE_TYPE(enc, ptr);
+ switch (t) {
+ INVALID_CASES(ptr, nextTokPtr)
+ case BT_QUOT:
+ case BT_APOS:
+ ptr += MINBPC(enc);
+ if (t != open)
+ break;
+ if (ptr == end)
+ return -XML_TOK_LITERAL;
+ *nextTokPtr = ptr;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_S: case BT_CR: case BT_LF:
+ case BT_GT: case BT_PERCNT: case BT_LSQB:
+ return XML_TOK_LITERAL;
+ default:
+ return XML_TOK_INVALID;
+ }
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+static int PTRCALL
+PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ int tok;
+ if (ptr == end)
+ return XML_TOK_NONE;
+ if (MINBPC(enc) > 1) {
+ size_t n = end - ptr;
+ if (n & (MINBPC(enc) - 1)) {
+ n &= ~(MINBPC(enc) - 1);
+ if (n == 0)
+ return XML_TOK_PARTIAL;
+ end = ptr + n;
+ }
+ }
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_QUOT:
+ return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_APOS:
+ return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_LT:
+ {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_EXCL:
+ return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_QUEST:
+ return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_NMSTRT:
+ case BT_HEX:
+ case BT_NONASCII:
+ case BT_LEAD2:
+ case BT_LEAD3:
+ case BT_LEAD4:
+ *nextTokPtr = ptr - MINBPC(enc);
+ return XML_TOK_INSTANCE_START;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ case BT_CR:
+ if (ptr + MINBPC(enc) == end) {
+ *nextTokPtr = end;
+ /* indicate that this might be part of a CR/LF pair */
+ return -XML_TOK_PROLOG_S;
+ }
+ /* fall through */
+ case BT_S: case BT_LF:
+ for (;;) {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ break;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_S: case BT_LF:
+ break;
+ case BT_CR:
+ /* don't split CR/LF pair */
+ if (ptr + MINBPC(enc) != end)
+ break;
+ /* fall through */
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_PROLOG_S;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_PROLOG_S;
+ case BT_PERCNT:
+ return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_COMMA:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_COMMA;
+ case BT_LSQB:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_OPEN_BRACKET;
+ case BT_RSQB:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return -XML_TOK_CLOSE_BRACKET;
+ if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
+ if (ptr + MINBPC(enc) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
+ *nextTokPtr = ptr + 2*MINBPC(enc);
+ return XML_TOK_COND_SECT_CLOSE;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_CLOSE_BRACKET;
+ case BT_LPAR:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_OPEN_PAREN;
+ case BT_RPAR:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return -XML_TOK_CLOSE_PAREN;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_AST:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CLOSE_PAREN_ASTERISK;
+ case BT_QUEST:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CLOSE_PAREN_QUESTION;
+ case BT_PLUS:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CLOSE_PAREN_PLUS;
+ case BT_CR: case BT_LF: case BT_S:
+ case BT_GT: case BT_COMMA: case BT_VERBAR:
+ case BT_RPAR:
+ *nextTokPtr = ptr;
+ return XML_TOK_CLOSE_PAREN;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ case BT_VERBAR:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_OR;
+ case BT_GT:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_DECL_CLOSE;
+ case BT_NUM:
+ return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
+ ptr += n; \
+ tok = XML_TOK_NAME; \
+ break; \
+ } \
+ if (IS_NAME_CHAR(enc, ptr, n)) { \
+ ptr += n; \
+ tok = XML_TOK_NMTOKEN; \
+ break; \
+ } \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_NMSTRT:
+ case BT_HEX:
+ tok = XML_TOK_NAME;
+ ptr += MINBPC(enc);
+ break;
+ case BT_DIGIT:
+ case BT_NAME:
+ case BT_MINUS:
+#ifdef XML_NS
+ case BT_COLON:
+#endif
+ tok = XML_TOK_NMTOKEN;
+ ptr += MINBPC(enc);
+ break;
+ case BT_NONASCII:
+ if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {
+ ptr += MINBPC(enc);
+ tok = XML_TOK_NAME;
+ break;
+ }
+ if (IS_NAME_CHAR_MINBPC(enc, ptr)) {
+ ptr += MINBPC(enc);
+ tok = XML_TOK_NMTOKEN;
+ break;
+ }
+ /* fall through */
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_GT: case BT_RPAR: case BT_COMMA:
+ case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
+ case BT_S: case BT_CR: case BT_LF:
+ *nextTokPtr = ptr;
+ return tok;
+#ifdef XML_NS
+ case BT_COLON:
+ ptr += MINBPC(enc);
+ switch (tok) {
+ case XML_TOK_NAME:
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ tok = XML_TOK_PREFIXED_NAME;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ tok = XML_TOK_NMTOKEN;
+ break;
+ }
+ break;
+ case XML_TOK_PREFIXED_NAME:
+ tok = XML_TOK_NMTOKEN;
+ break;
+ }
+ break;
+#endif
+ case BT_PLUS:
+ if (tok == XML_TOK_NMTOKEN) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_NAME_PLUS;
+ case BT_AST:
+ if (tok == XML_TOK_NMTOKEN) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_NAME_ASTERISK;
+ case BT_QUEST:
+ if (tok == XML_TOK_NMTOKEN) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_NAME_QUESTION;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return -tok;
+}
+
+static int PTRCALL
+PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ const char *start;
+ if (ptr == end)
+ return XML_TOK_NONE;
+ start = ptr;
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: ptr += n; break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_AMP:
+ if (ptr == start)
+ return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_LT:
+ /* this is for inside entity references */
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ case BT_LF:
+ if (ptr == start) {
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_DATA_NEWLINE;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_CR:
+ if (ptr == start) {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_TRAILING_CR;
+ if (BYTE_TYPE(enc, ptr) == BT_LF)
+ ptr += MINBPC(enc);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_NEWLINE;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_S:
+ if (ptr == start) {
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_ATTRIBUTE_VALUE_S;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+}
+
+static int PTRCALL
+PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ const char *start;
+ if (ptr == end)
+ return XML_TOK_NONE;
+ start = ptr;
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: ptr += n; break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_AMP:
+ if (ptr == start)
+ return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_PERCNT:
+ if (ptr == start) {
+ int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc),
+ end, nextTokPtr);
+ return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_LF:
+ if (ptr == start) {
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_DATA_NEWLINE;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_CR:
+ if (ptr == start) {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_TRAILING_CR;
+ if (BYTE_TYPE(enc, ptr) == BT_LF)
+ ptr += MINBPC(enc);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_NEWLINE;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+}
+
+#ifdef XML_DTD
+
+static int PTRCALL
+PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **nextTokPtr)
+{
+ int level = 0;
+ if (MINBPC(enc) > 1) {
+ size_t n = end - ptr;
+ if (n & (MINBPC(enc) - 1)) {
+ n &= ~(MINBPC(enc) - 1);
+ end = ptr + n;
+ }
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ INVALID_CASES(ptr, nextTokPtr)
+ case BT_LT:
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
+ ++level;
+ ptr += MINBPC(enc);
+ }
+ }
+ break;
+ case BT_RSQB:
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ ptr += MINBPC(enc);
+ if (level == 0) {
+ *nextTokPtr = ptr;
+ return XML_TOK_IGNORE_SECT;
+ }
+ --level;
+ }
+ }
+ break;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+#endif /* XML_DTD */
+
+static int PTRCALL
+PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **badPtr)
+{
+ ptr += MINBPC(enc);
+ end -= MINBPC(enc);
+ for (; ptr != end; ptr += MINBPC(enc)) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_DIGIT:
+ case BT_HEX:
+ case BT_MINUS:
+ case BT_APOS:
+ case BT_LPAR:
+ case BT_RPAR:
+ case BT_PLUS:
+ case BT_COMMA:
+ case BT_SOL:
+ case BT_EQUALS:
+ case BT_QUEST:
+ case BT_CR:
+ case BT_LF:
+ case BT_SEMI:
+ case BT_EXCL:
+ case BT_AST:
+ case BT_PERCNT:
+ case BT_NUM:
+#ifdef XML_NS
+ case BT_COLON:
+#endif
+ break;
+ case BT_S:
+ if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {
+ *badPtr = ptr;
+ return 0;
+ }
+ break;
+ case BT_NAME:
+ case BT_NMSTRT:
+ if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
+ break;
+ default:
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case 0x24: /* $ */
+ case 0x40: /* @ */
+ break;
+ default:
+ *badPtr = ptr;
+ return 0;
+ }
+ break;
+ }
+ }
+ return 1;
+}
+
+/* This must only be called for a well-formed start-tag or empty
+ element tag. Returns the number of attributes. Pointers to the
+ first attsMax attributes are stored in atts.
+*/
+
+static int PTRCALL
+PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
+ int attsMax, ATTRIBUTE *atts)
+{
+ enum { other, inName, inValue } state = inName;
+ int nAtts = 0;
+ int open = 0; /* defined when state == inValue;
+ initialization just to shut up compilers */
+
+ for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define START_NAME \
+ if (state == other) { \
+ if (nAtts < attsMax) { \
+ atts[nAtts].name = ptr; \
+ atts[nAtts].normalized = 1; \
+ } \
+ state = inName; \
+ }
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_NONASCII:
+ case BT_NMSTRT:
+ case BT_HEX:
+ START_NAME
+ break;
+#undef START_NAME
+ case BT_QUOT:
+ if (state != inValue) {
+ if (nAtts < attsMax)
+ atts[nAtts].valuePtr = ptr + MINBPC(enc);
+ state = inValue;
+ open = BT_QUOT;
+ }
+ else if (open == BT_QUOT) {
+ state = other;
+ if (nAtts < attsMax)
+ atts[nAtts].valueEnd = ptr;
+ nAtts++;
+ }
+ break;
+ case BT_APOS:
+ if (state != inValue) {
+ if (nAtts < attsMax)
+ atts[nAtts].valuePtr = ptr + MINBPC(enc);
+ state = inValue;
+ open = BT_APOS;
+ }
+ else if (open == BT_APOS) {
+ state = other;
+ if (nAtts < attsMax)
+ atts[nAtts].valueEnd = ptr;
+ nAtts++;
+ }
+ break;
+ case BT_AMP:
+ if (nAtts < attsMax)
+ atts[nAtts].normalized = 0;
+ break;
+ case BT_S:
+ if (state == inName)
+ state = other;
+ else if (state == inValue
+ && nAtts < attsMax
+ && atts[nAtts].normalized
+ && (ptr == atts[nAtts].valuePtr
+ || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
+ || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
+ || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
+ atts[nAtts].normalized = 0;
+ break;
+ case BT_CR: case BT_LF:
+ /* This case ensures that the first attribute name is counted
+ Apart from that we could just change state on the quote. */
+ if (state == inName)
+ state = other;
+ else if (state == inValue && nAtts < attsMax)
+ atts[nAtts].normalized = 0;
+ break;
+ case BT_GT:
+ case BT_SOL:
+ if (state != inValue)
+ return nAtts;
+ break;
+ default:
+ break;
+ }
+ }
+ /* not reached */
+}
+
+static int PTRFASTCALL
+PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
+{
+ int result = 0;
+ /* skip &# */
+ ptr += 2*MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
+ for (ptr += MINBPC(enc);
+ !CHAR_MATCHES(enc, ptr, ASCII_SEMI);
+ ptr += MINBPC(enc)) {
+ int c = BYTE_TO_ASCII(enc, ptr);
+ switch (c) {
+ case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4:
+ case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9:
+ result <<= 4;
+ result |= (c - ASCII_0);
+ break;
+ case ASCII_A: case ASCII_B: case ASCII_C:
+ case ASCII_D: case ASCII_E: case ASCII_F:
+ result <<= 4;
+ result += 10 + (c - ASCII_A);
+ break;
+ case ASCII_a: case ASCII_b: case ASCII_c:
+ case ASCII_d: case ASCII_e: case ASCII_f:
+ result <<= 4;
+ result += 10 + (c - ASCII_a);
+ break;
+ }
+ if (result >= 0x110000)
+ return -1;
+ }
+ }
+ else {
+ for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
+ int c = BYTE_TO_ASCII(enc, ptr);
+ result *= 10;
+ result += (c - ASCII_0);
+ if (result >= 0x110000)
+ return -1;
+ }
+ }
+ return checkCharRefNumber(result);
+}
+
+static int PTRCALL
+PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
+ const char *end)
+{
+ switch ((end - ptr)/MINBPC(enc)) {
+ case 2:
+ if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case ASCII_l:
+ return ASCII_LT;
+ case ASCII_g:
+ return ASCII_GT;
+ }
+ }
+ break;
+ case 3:
+ if (CHAR_MATCHES(enc, ptr, ASCII_a)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_m)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_p))
+ return ASCII_AMP;
+ }
+ }
+ break;
+ case 4:
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case ASCII_q:
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_u)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_t))
+ return ASCII_QUOT;
+ }
+ }
+ break;
+ case ASCII_a:
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_p)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_s))
+ return ASCII_APOS;
+ }
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+static int PTRCALL
+PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
+{
+ for (;;) {
+ switch (BYTE_TYPE(enc, ptr1)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: \
+ if (*ptr1++ != *ptr2++) \
+ return 0;
+ LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
+#undef LEAD_CASE
+ /* fall through */
+ if (*ptr1++ != *ptr2++)
+ return 0;
+ break;
+ case BT_NONASCII:
+ case BT_NMSTRT:
+#ifdef XML_NS
+ case BT_COLON:
+#endif
+ case BT_HEX:
+ case BT_DIGIT:
+ case BT_NAME:
+ case BT_MINUS:
+ if (*ptr2++ != *ptr1++)
+ return 0;
+ if (MINBPC(enc) > 1) {
+ if (*ptr2++ != *ptr1++)
+ return 0;
+ if (MINBPC(enc) > 2) {
+ if (*ptr2++ != *ptr1++)
+ return 0;
+ if (MINBPC(enc) > 3) {
+ if (*ptr2++ != *ptr1++)
+ return 0;
+ }
+ }
+ }
+ break;
+ default:
+ if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
+ return 1;
+ switch (BYTE_TYPE(enc, ptr2)) {
+ case BT_LEAD2:
+ case BT_LEAD3:
+ case BT_LEAD4:
+ case BT_NONASCII:
+ case BT_NMSTRT:
+#ifdef XML_NS
+ case BT_COLON:
+#endif
+ case BT_HEX:
+ case BT_DIGIT:
+ case BT_NAME:
+ case BT_MINUS:
+ return 0;
+ default:
+ return 1;
+ }
+ }
+ }
+ /* not reached */
+}
+
+static int PTRCALL
+PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
+ const char *end1, const char *ptr2)
+{
+ for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
+ if (ptr1 == end1)
+ return 0;
+ if (!CHAR_MATCHES(enc, ptr1, *ptr2))
+ return 0;
+ }
+ return ptr1 == end1;
+}
+
+static int PTRFASTCALL
+PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
+{
+ const char *start = ptr;
+ for (;;) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: ptr += n; break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_NONASCII:
+ case BT_NMSTRT:
+#ifdef XML_NS
+ case BT_COLON:
+#endif
+ case BT_HEX:
+ case BT_DIGIT:
+ case BT_NAME:
+ case BT_MINUS:
+ ptr += MINBPC(enc);
+ break;
+ default:
+ return (int)(ptr - start);
+ }
+ }
+}
+
+static const char * PTRFASTCALL
+PREFIX(skipS)(const ENCODING *enc, const char *ptr)
+{
+ for (;;) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_LF:
+ case BT_CR:
+ case BT_S:
+ ptr += MINBPC(enc);
+ break;
+ default:
+ return ptr;
+ }
+ }
+}
+
+static void PTRCALL
+PREFIX(updatePosition)(const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ POSITION *pos)
+{
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: \
+ ptr += n; \
+ break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_LF:
+ pos->columnNumber = (XML_Size)-1;
+ pos->lineNumber++;
+ ptr += MINBPC(enc);
+ break;
+ case BT_CR:
+ pos->lineNumber++;
+ ptr += MINBPC(enc);
+ if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
+ ptr += MINBPC(enc);
+ pos->columnNumber = (XML_Size)-1;
+ break;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ pos->columnNumber++;
+ }
+}
+
+#undef DO_LEAD_CASE
+#undef MULTIBYTE_CASES
+#undef INVALID_CASES
+#undef CHECK_NAME_CASE
+#undef CHECK_NAME_CASES
+#undef CHECK_NMSTRT_CASE
+#undef CHECK_NMSTRT_CASES
+
diff --git a/parser/expat/lib/xmltok_impl.h b/parser/expat/lib/xmltok_impl.h
new file mode 100644
index 000000000..da0ea60a6
--- /dev/null
+++ b/parser/expat/lib/xmltok_impl.h
@@ -0,0 +1,46 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+enum {
+ BT_NONXML,
+ BT_MALFORM,
+ BT_LT,
+ BT_AMP,
+ BT_RSQB,
+ BT_LEAD2,
+ BT_LEAD3,
+ BT_LEAD4,
+ BT_TRAIL,
+ BT_CR,
+ BT_LF,
+ BT_GT,
+ BT_QUOT,
+ BT_APOS,
+ BT_EQUALS,
+ BT_QUEST,
+ BT_EXCL,
+ BT_SOL,
+ BT_SEMI,
+ BT_NUM,
+ BT_LSQB,
+ BT_S,
+ BT_NMSTRT,
+ BT_COLON,
+ BT_HEX,
+ BT_DIGIT,
+ BT_NAME,
+ BT_MINUS,
+ BT_OTHER, /* known not to be a name or name start character */
+ BT_NONASCII, /* might be a name or name start character */
+ BT_PERCNT,
+ BT_LPAR,
+ BT_RPAR,
+ BT_AST,
+ BT_PLUS,
+ BT_COMMA,
+ BT_VERBAR
+};
+
+#include <stddef.h>
diff --git a/parser/expat/lib/xmltok_ns.c b/parser/expat/lib/xmltok_ns.c
new file mode 100644
index 000000000..d2f893836
--- /dev/null
+++ b/parser/expat/lib/xmltok_ns.c
@@ -0,0 +1,106 @@
+const ENCODING *
+NS(XmlGetUtf8InternalEncoding)(void)
+{
+ return &ns(internal_utf8_encoding).enc;
+}
+
+const ENCODING *
+NS(XmlGetUtf16InternalEncoding)(void)
+{
+#if BYTEORDER == 1234
+ return &ns(internal_little2_encoding).enc;
+#elif BYTEORDER == 4321
+ return &ns(internal_big2_encoding).enc;
+#else
+ const short n = 1;
+ return (*(const char *)&n
+ ? &ns(internal_little2_encoding).enc
+ : &ns(internal_big2_encoding).enc);
+#endif
+}
+
+static const ENCODING * const NS(encodings)[] = {
+ &ns(latin1_encoding).enc,
+ &ns(ascii_encoding).enc,
+ &ns(utf8_encoding).enc,
+ &ns(big2_encoding).enc,
+ &ns(big2_encoding).enc,
+ &ns(little2_encoding).enc,
+ &ns(utf8_encoding).enc /* NO_ENC */
+};
+
+static int PTRCALL
+NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ return initScan(NS(encodings), (const INIT_ENCODING *)enc,
+ XML_PROLOG_STATE, ptr, end, nextTokPtr);
+}
+
+static int PTRCALL
+NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ return initScan(NS(encodings), (const INIT_ENCODING *)enc,
+ XML_CONTENT_STATE, ptr, end, nextTokPtr);
+}
+
+int
+NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
+ const char *name)
+{
+ int i = getEncodingIndex(name);
+ if (i == UNKNOWN_ENC)
+ return 0;
+ SET_INIT_ENC_INDEX(p, i);
+ p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
+ p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
+ p->initEnc.updatePosition = initUpdatePosition;
+ p->encPtr = encPtr;
+ *encPtr = &(p->initEnc);
+ return 1;
+}
+
+static const ENCODING *
+NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
+{
+#define ENCODING_MAX 128
+ char buf[ENCODING_MAX];
+ char *p = buf;
+ int i;
+ XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
+ if (ptr != end)
+ return 0;
+ *p = 0;
+ if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)
+ return enc;
+ i = getEncodingIndex(buf);
+ if (i == UNKNOWN_ENC)
+ return 0;
+ return NS(encodings)[i];
+}
+
+int
+NS(XmlParseXmlDecl)(int isGeneralTextEntity,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **badPtr,
+ const char **versionPtr,
+ const char **versionEndPtr,
+ const char **encodingName,
+ const ENCODING **encoding,
+ int *standalone)
+{
+ return doParseXmlDecl(NS(findEncoding),
+ isGeneralTextEntity,
+ enc,
+ ptr,
+ end,
+ badPtr,
+ versionPtr,
+ versionEndPtr,
+ encodingName,
+ encoding,
+ standalone);
+}
diff --git a/parser/expat/moz.build b/parser/expat/moz.build
new file mode 100644
index 000000000..4522eae87
--- /dev/null
+++ b/parser/expat/moz.build
@@ -0,0 +1,12 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DIRS += ['lib']
+
+EXPORTS += [
+ 'expat_config.h',
+]
+
diff --git a/parser/html/jArray.h b/parser/html/jArray.h
new file mode 100644
index 000000000..45548a077
--- /dev/null
+++ b/parser/html/jArray.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2008-2015 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef jArray_h
+#define jArray_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/BinarySearch.h"
+#include "nsDebug.h"
+
+template<class T, class L>
+struct staticJArray {
+ const T* arr;
+ const L length;
+ operator T*() { return arr; }
+ T& operator[] (L const index) {
+ MOZ_ASSERT(index >= 0, "Array access with negative index.");
+ MOZ_ASSERT(index < length, "Array index out of bounds.");
+ return ((T*)arr)[index];
+ }
+ L binarySearch(T const elem) {
+ size_t idx;
+ bool found = mozilla::BinarySearch(arr, 0, length, elem, &idx);
+ return found ? idx : -1;
+ }
+};
+
+template<class T, class L>
+struct jArray {
+ T* arr;
+ L length;
+ static jArray<T,L> newJArray(L const len) {
+ MOZ_ASSERT(len >= 0, "Negative length.");
+ jArray<T,L> newArray = { new T[size_t(len)], len };
+ return newArray;
+ }
+ static jArray<T,L> newFallibleJArray(L const len) {
+ MOZ_ASSERT(len >= 0, "Negative length.");
+ T* a = new (mozilla::fallible) T[size_t(len)];
+ jArray<T,L> newArray = { a, a ? len : 0 };
+ return newArray;
+ }
+ operator T*() { return arr; }
+ T& operator[] (L const index) {
+ MOZ_ASSERT(index >= 0, "Array access with negative index.");
+ MOZ_ASSERT(index < length, "Array index out of bounds.");
+ return arr[index];
+ }
+ void operator=(staticJArray<T,L>& other) {
+ arr = (T*)other.arr;
+ length = other.length;
+ }
+};
+
+template<class T, class L>
+class autoJArray {
+ private:
+ T* arr;
+ public:
+ L length;
+ autoJArray()
+ : arr(0)
+ , length(0)
+ {
+ }
+ MOZ_IMPLICIT autoJArray(const jArray<T,L>& other)
+ : arr(other.arr)
+ , length(other.length)
+ {
+ }
+ ~autoJArray()
+ {
+ delete[] arr;
+ }
+ operator T*() { return arr; }
+ T& operator[] (L const index) {
+ MOZ_ASSERT(index >= 0, "Array access with negative index.");
+ MOZ_ASSERT(index < length, "Array index out of bounds.");
+ return arr[index];
+ }
+ operator jArray<T,L>() {
+ // WARNING! This makes it possible to goof with buffer ownership!
+ // This is needed for the getStack and getListOfActiveFormattingElements
+ // methods to work sensibly.
+ jArray<T,L> newArray = { arr, length };
+ return newArray;
+ }
+ void operator=(const jArray<T,L>& other) {
+ delete[] arr;
+ arr = other.arr;
+ length = other.length;
+ }
+ void operator=(decltype(nullptr)) {
+ // Make assigning null to an array in Java delete the buffer in C++
+ delete[] arr;
+ arr = nullptr;
+ length = 0;
+ }
+};
+
+#endif // jArray_h
diff --git a/parser/html/java/Makefile b/parser/html/java/Makefile
new file mode 100644
index 000000000..b43523e03
--- /dev/null
+++ b/parser/html/java/Makefile
@@ -0,0 +1,59 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+libs:: translator
+
+translator:: javaparser \
+; mkdir -p htmlparser/bin && \
+ find htmlparser/translator-src/nu/validator/htmlparser -name "*.java" | \
+ xargs javac -cp javaparser.jar -g -d htmlparser/bin && \
+ jar cfm translator.jar manifest.txt -C htmlparser/bin .
+
+javaparser:: \
+; mkdir -p javaparser/bin && \
+ find javaparser/src -name "*.java" | \
+ xargs javac -encoding ISO-8859-1 -g -d javaparser/bin && \
+ jar cf javaparser.jar -C javaparser/bin .
+
+sync_javaparser:: \
+; if [ ! -d javaparser/.git ] ; \
+ then rm -rf javaparser ; \
+ git clone https://github.com/javaparser/javaparser.git ; \
+ fi ; \
+ cd javaparser ; git checkout javaparser-1.0.6 ; cd ..
+
+sync_htmlparser:: \
+; if [ -d htmlparser/.hg ] ; \
+ then cd htmlparser ; hg pull --rebase ; cd .. ; \
+ else \
+ rm -rf htmlparser ; \
+ hg clone https://hg.mozilla.org/projects/htmlparser ; \
+ fi
+
+sync:: sync_javaparser sync_htmlparser
+
+translate:: translator \
+; mkdir -p ../javasrc ; \
+ java -jar translator.jar \
+ htmlparser/src/nu/validator/htmlparser/impl \
+ .. ../nsHtml5AtomList.h
+
+translate_from_snapshot:: translator \
+; mkdir -p ../javasrc ; \
+ java -jar translator.jar \
+ ../javasrc \
+ .. ../nsHtml5AtomList.h
+
+named_characters:: translator \
+; java -cp translator.jar \
+ nu.validator.htmlparser.generator.GenerateNamedCharactersCpp \
+ named-character-references.html ../
+
+clean_javaparser:: \
+; rm -rf javaparser/bin javaparser.jar
+
+clean_htmlparser:: \
+; rm -rf htmlparser/bin translator.jar
+
+clean:: clean_javaparser clean_htmlparser
diff --git a/parser/html/java/README.txt b/parser/html/java/README.txt
new file mode 100644
index 000000000..df1bfcd4c
--- /dev/null
+++ b/parser/html/java/README.txt
@@ -0,0 +1,46 @@
+If this is your first time building the HTML5 parser, you need to execute the
+following commands (from this directory) to bootstrap the translation:
+
+ make sync # fetch remote source files and licenses
+ make translate # perform the Java-to-C++ translation from the remote
+ # sources
+ make named_characters # Generate tables for named character tokenization
+
+If you make changes to the translator or the javaparser, you can rebuild by
+retyping 'make' in this directory. If you make changes to the HTML5 Java
+implementation, you can retranslate the Java sources from the htmlparser
+repository by retyping 'make translate' in this directory.
+
+The makefile supports the following targets:
+
+sync_htmlparser:
+ Retrieves the HTML parser and Java to C++ translator sources from Mozilla's
+ htmlparser repository.
+sync_javaparser:
+ Retrieves the javaparser sources from GitHub.
+sync:
+ Runs both sync_javaparser and sync_htmlparser.
+javaparser:
+ Builds the javaparser library retrieved earlier by sync_javaparser.
+translator:
+ Runs the javaparser target and then builds the Java to C++ translator from
+ sources retrieved earlier by sync_htmlparser.
+libs:
+ The default target. Alias for translator
+translate:
+ Runs the translator target and then translates the HTML parser sources
+ retrieved by sync_htmlparser copying the Java sources to ../javasrc.
+translate_from_snapshot:
+ Runs the translator target and then translates the HTML parser sources
+ stored in ../javasrc.
+named_characters:
+ Generates data tables for named character tokenization.
+clean_javaparser:
+ Removes the build products of the javaparser target.
+clean_htmlparser:
+ Removes the build products of the translator target.
+clean:
+ Runs both clean_javaparser and clean_htmlparser.
+
+Ben Newman (23 September 2009)
+Henri Sivonen (11 August 2016)
diff --git a/parser/html/java/manifest.txt b/parser/html/java/manifest.txt
new file mode 100644
index 000000000..14cd9d081
--- /dev/null
+++ b/parser/html/java/manifest.txt
@@ -0,0 +1,2 @@
+Main-Class: nu.validator.htmlparser.cpptranslate.Main
+Class-Path: javaparser.jar
diff --git a/parser/html/java/named-character-references.html b/parser/html/java/named-character-references.html
new file mode 100644
index 000000000..c8d1e08da
--- /dev/null
+++ b/parser/html/java/named-character-references.html
@@ -0,0 +1,7 @@
+<!--
+Spec rev 4381
+-->
+
+ <table><thead><tr><th> Name </th> <th> Character </th> <tbody><tr><td> <code title="">AElig;</code> </td> <td> U+000C6 </td> <tr><td> <code title="">AElig</code> </td> <td> U+000C6 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">AMP;</code> </td> <td> U+00026 </td> <tr><td> <code title="">AMP</code> </td> <td> U+00026 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Aacute;</code> </td> <td> U+000C1 </td> <tr><td> <code title="">Aacute</code> </td> <td> U+000C1 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Abreve;</code> </td> <td> U+00102 </td> <tr><td> <code title="">Acirc;</code> </td> <td> U+000C2 </td> <tr><td> <code title="">Acirc</code> </td> <td> U+000C2 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Acy;</code> </td> <td> U+00410 </td> <tr><td> <code title="">Afr;</code> </td> <td> U+1D504 </td> <tr><td> <code title="">Agrave;</code> </td> <td> U+000C0 </td> <tr><td> <code title="">Agrave</code> </td> <td> U+000C0 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Alpha;</code> </td> <td> U+00391 </td> <tr><td> <code title="">Amacr;</code> </td> <td> U+00100 </td> <tr><td> <code title="">And;</code> </td> <td> U+02A53 </td> <tr><td> <code title="">Aogon;</code> </td> <td> U+00104 </td> <tr><td> <code title="">Aopf;</code> </td> <td> U+1D538 </td> <tr><td> <code title="">ApplyFunction;</code> </td> <td> U+02061 </td> <tr><td> <code title="">Aring;</code> </td> <td> U+000C5 </td> <tr><td> <code title="">Aring</code> </td> <td> U+000C5 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Ascr;</code> </td> <td> U+1D49C </td> <tr><td> <code title="">Assign;</code> </td> <td> U+02254 </td> <tr><td> <code title="">Atilde;</code> </td> <td> U+000C3 </td> <tr><td> <code title="">Atilde</code> </td> <td> U+000C3 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Auml;</code> </td> <td> U+000C4 </td> <tr><td> <code title="">Auml</code> </td> <td> U+000C4 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Backslash;</code> </td> <td> U+02216 </td> <tr><td> <code title="">Barv;</code> </td> <td> U+02AE7 </td> <tr><td> <code title="">Barwed;</code> </td> <td> U+02306 </td> <tr><td> <code title="">Bcy;</code> </td> <td> U+00411 </td> <tr><td> <code title="">Because;</code> </td> <td> U+02235 </td> <tr><td> <code title="">Bernoullis;</code> </td> <td> U+0212C </td> <tr><td> <code title="">Beta;</code> </td> <td> U+00392 </td> <tr><td> <code title="">Bfr;</code> </td> <td> U+1D505 </td> <tr><td> <code title="">Bopf;</code> </td> <td> U+1D539 </td> <tr><td> <code title="">Breve;</code> </td> <td> U+002D8 </td> <tr><td> <code title="">Bscr;</code> </td> <td> U+0212C </td> <tr><td> <code title="">Bumpeq;</code> </td> <td> U+0224E </td> <tr><td> <code title="">CHcy;</code> </td> <td> U+00427 </td> <tr><td> <code title="">COPY;</code> </td> <td> U+000A9 </td> <tr><td> <code title="">COPY</code> </td> <td> U+000A9 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Cacute;</code> </td> <td> U+00106 </td> <tr><td> <code title="">Cap;</code> </td> <td> U+022D2 </td> <tr><td> <code title="">CapitalDifferentialD;</code> </td> <td> U+02145 </td> <tr><td> <code title="">Cayleys;</code> </td> <td> U+0212D </td> <tr><td> <code title="">Ccaron;</code> </td> <td> U+0010C </td> <tr><td> <code title="">Ccedil;</code> </td> <td> U+000C7 </td> <tr><td> <code title="">Ccedil</code> </td> <td> U+000C7 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Ccirc;</code> </td> <td> U+00108 </td> <tr><td> <code title="">Cconint;</code> </td> <td> U+02230 </td> <tr><td> <code title="">Cdot;</code> </td> <td> U+0010A </td> <tr><td> <code title="">Cedilla;</code> </td> <td> U+000B8 </td> <tr><td> <code title="">CenterDot;</code> </td> <td> U+000B7 </td> <tr><td> <code title="">Cfr;</code> </td> <td> U+0212D </td> <tr><td> <code title="">Chi;</code> </td> <td> U+003A7 </td> <tr><td> <code title="">CircleDot;</code> </td> <td> U+02299 </td> <tr><td> <code title="">CircleMinus;</code> </td> <td> U+02296 </td> <tr><td> <code title="">CirclePlus;</code> </td> <td> U+02295 </td> <tr><td> <code title="">CircleTimes;</code> </td> <td> U+02297 </td> <tr><td> <code title="">ClockwiseContourIntegral;</code> </td> <td> U+02232 </td> <tr><td> <code title="">CloseCurlyDoubleQuote;</code> </td> <td> U+0201D </td> <tr><td> <code title="">CloseCurlyQuote;</code> </td> <td> U+02019 </td> <tr><td> <code title="">Colon;</code> </td> <td> U+02237 </td> <tr><td> <code title="">Colone;</code> </td> <td> U+02A74 </td> <tr><td> <code title="">Congruent;</code> </td> <td> U+02261 </td> <tr><td> <code title="">Conint;</code> </td> <td> U+0222F </td> <tr><td> <code title="">ContourIntegral;</code> </td> <td> U+0222E </td> <tr><td> <code title="">Copf;</code> </td> <td> U+02102 </td> <tr><td> <code title="">Coproduct;</code> </td> <td> U+02210 </td> <tr><td> <code title="">CounterClockwiseContourIntegral;</code> </td> <td> U+02233 </td> <tr><td> <code title="">Cross;</code> </td> <td> U+02A2F </td> <tr><td> <code title="">Cscr;</code> </td> <td> U+1D49E </td> <tr><td> <code title="">Cup;</code> </td> <td> U+022D3 </td> <tr><td> <code title="">CupCap;</code> </td> <td> U+0224D </td> <tr><td> <code title="">DD;</code> </td> <td> U+02145 </td> <tr><td> <code title="">DDotrahd;</code> </td> <td> U+02911 </td> <tr><td> <code title="">DJcy;</code> </td> <td> U+00402 </td> <tr><td> <code title="">DScy;</code> </td> <td> U+00405 </td> <tr><td> <code title="">DZcy;</code> </td> <td> U+0040F </td> <tr><td> <code title="">Dagger;</code> </td> <td> U+02021 </td> <tr><td> <code title="">Darr;</code> </td> <td> U+021A1 </td> <tr><td> <code title="">Dashv;</code> </td> <td> U+02AE4 </td> <tr><td> <code title="">Dcaron;</code> </td> <td> U+0010E </td> <tr><td> <code title="">Dcy;</code> </td> <td> U+00414 </td> <tr><td> <code title="">Del;</code> </td> <td> U+02207 </td> <tr><td> <code title="">Delta;</code> </td> <td> U+00394 </td> <tr><td> <code title="">Dfr;</code> </td> <td> U+1D507 </td> <tr><td> <code title="">DiacriticalAcute;</code> </td> <td> U+000B4 </td> <tr><td> <code title="">DiacriticalDot;</code> </td> <td> U+002D9 </td> <tr><td> <code title="">DiacriticalDoubleAcute;</code> </td> <td> U+002DD </td> <tr><td> <code title="">DiacriticalGrave;</code> </td> <td> U+00060 </td> <tr><td> <code title="">DiacriticalTilde;</code> </td> <td> U+002DC </td> <tr><td> <code title="">Diamond;</code> </td> <td> U+022C4 </td> <tr><td> <code title="">DifferentialD;</code> </td> <td> U+02146 </td> <tr><td> <code title="">Dopf;</code> </td> <td> U+1D53B </td> <tr><td> <code title="">Dot;</code> </td> <td> U+000A8 </td> <tr><td> <code title="">DotDot;</code> </td> <td> U+020DC </td> <tr><td> <code title="">DotEqual;</code> </td> <td> U+02250 </td> <tr><td> <code title="">DoubleContourIntegral;</code> </td> <td> U+0222F </td> <tr><td> <code title="">DoubleDot;</code> </td> <td> U+000A8 </td> <tr><td> <code title="">DoubleDownArrow;</code> </td> <td> U+021D3 </td> <tr><td> <code title="">DoubleLeftArrow;</code> </td> <td> U+021D0 </td> <tr><td> <code title="">DoubleLeftRightArrow;</code> </td> <td> U+021D4 </td> <tr><td> <code title="">DoubleLeftTee;</code> </td> <td> U+02AE4 </td> <tr><td> <code title="">DoubleLongLeftArrow;</code> </td> <td> U+027F8 </td> <tr><td> <code title="">DoubleLongLeftRightArrow;</code> </td> <td> U+027FA </td> <tr><td> <code title="">DoubleLongRightArrow;</code> </td> <td> U+027F9 </td> <tr><td> <code title="">DoubleRightArrow;</code> </td> <td> U+021D2 </td> <tr><td> <code title="">DoubleRightTee;</code> </td> <td> U+022A8 </td> <tr><td> <code title="">DoubleUpArrow;</code> </td> <td> U+021D1 </td> <tr><td> <code title="">DoubleUpDownArrow;</code> </td> <td> U+021D5 </td> <tr><td> <code title="">DoubleVerticalBar;</code> </td> <td> U+02225 </td> <tr><td> <code title="">DownArrow;</code> </td> <td> U+02193 </td> <tr><td> <code title="">DownArrowBar;</code> </td> <td> U+02913 </td> <tr><td> <code title="">DownArrowUpArrow;</code> </td> <td> U+021F5 </td> <tr><td> <code title="">DownBreve;</code> </td> <td> U+00311 </td> <tr><td> <code title="">DownLeftRightVector;</code> </td> <td> U+02950 </td> <tr><td> <code title="">DownLeftTeeVector;</code> </td> <td> U+0295E </td> <tr><td> <code title="">DownLeftVector;</code> </td> <td> U+021BD </td> <tr><td> <code title="">DownLeftVectorBar;</code> </td> <td> U+02956 </td> <tr><td> <code title="">DownRightTeeVector;</code> </td> <td> U+0295F </td> <tr><td> <code title="">DownRightVector;</code> </td> <td> U+021C1 </td> <tr><td> <code title="">DownRightVectorBar;</code> </td> <td> U+02957 </td> <tr><td> <code title="">DownTee;</code> </td> <td> U+022A4 </td> <tr><td> <code title="">DownTeeArrow;</code> </td> <td> U+021A7 </td> <tr><td> <code title="">Downarrow;</code> </td> <td> U+021D3 </td> <tr><td> <code title="">Dscr;</code> </td> <td> U+1D49F </td> <tr><td> <code title="">Dstrok;</code> </td> <td> U+00110 </td> <tr><td> <code title="">ENG;</code> </td> <td> U+0014A </td> <tr><td> <code title="">ETH;</code> </td> <td> U+000D0 </td> <tr><td> <code title="">ETH</code> </td> <td> U+000D0 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Eacute;</code> </td> <td> U+000C9 </td> <tr><td> <code title="">Eacute</code> </td> <td> U+000C9 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Ecaron;</code> </td> <td> U+0011A </td> <tr><td> <code title="">Ecirc;</code> </td> <td> U+000CA </td> <tr><td> <code title="">Ecirc</code> </td> <td> U+000CA </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Ecy;</code> </td> <td> U+0042D </td> <tr><td> <code title="">Edot;</code> </td> <td> U+00116 </td> <tr><td> <code title="">Efr;</code> </td> <td> U+1D508 </td> <tr><td> <code title="">Egrave;</code> </td> <td> U+000C8 </td> <tr><td> <code title="">Egrave</code> </td> <td> U+000C8 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Element;</code> </td> <td> U+02208 </td> <tr><td> <code title="">Emacr;</code> </td> <td> U+00112 </td> <tr><td> <code title="">EmptySmallSquare;</code> </td> <td> U+025FB </td> <tr><td> <code title="">EmptyVerySmallSquare;</code> </td> <td> U+025AB </td> <tr><td> <code title="">Eogon;</code> </td> <td> U+00118 </td> <tr><td> <code title="">Eopf;</code> </td> <td> U+1D53C </td> <tr><td> <code title="">Epsilon;</code> </td> <td> U+00395 </td> <tr><td> <code title="">Equal;</code> </td> <td> U+02A75 </td> <tr><td> <code title="">EqualTilde;</code> </td> <td> U+02242 </td> <tr><td> <code title="">Equilibrium;</code> </td> <td> U+021CC </td> <tr><td> <code title="">Escr;</code> </td> <td> U+02130 </td> <tr><td> <code title="">Esim;</code> </td> <td> U+02A73 </td> <tr><td> <code title="">Eta;</code> </td> <td> U+00397 </td> <tr><td> <code title="">Euml;</code> </td> <td> U+000CB </td> <tr><td> <code title="">Euml</code> </td> <td> U+000CB </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Exists;</code> </td> <td> U+02203 </td> <tr><td> <code title="">ExponentialE;</code> </td> <td> U+02147 </td> <tr><td> <code title="">Fcy;</code> </td> <td> U+00424 </td> <tr><td> <code title="">Ffr;</code> </td> <td> U+1D509 </td> <tr><td> <code title="">FilledSmallSquare;</code> </td> <td> U+025FC </td> <tr><td> <code title="">FilledVerySmallSquare;</code> </td> <td> U+025AA </td> <tr><td> <code title="">Fopf;</code> </td> <td> U+1D53D </td> <tr><td> <code title="">ForAll;</code> </td> <td> U+02200 </td> <tr><td> <code title="">Fouriertrf;</code> </td> <td> U+02131 </td> <tr><td> <code title="">Fscr;</code> </td> <td> U+02131 </td> <tr><td> <code title="">GJcy;</code> </td> <td> U+00403 </td> <tr><td> <code title="">GT;</code> </td> <td> U+0003E </td> <tr><td> <code title="">GT</code> </td> <td> U+0003E </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Gamma;</code> </td> <td> U+00393 </td> <tr><td> <code title="">Gammad;</code> </td> <td> U+003DC </td> <tr><td> <code title="">Gbreve;</code> </td> <td> U+0011E </td> <tr><td> <code title="">Gcedil;</code> </td> <td> U+00122 </td> <tr><td> <code title="">Gcirc;</code> </td> <td> U+0011C </td> <tr><td> <code title="">Gcy;</code> </td> <td> U+00413 </td> <tr><td> <code title="">Gdot;</code> </td> <td> U+00120 </td> <tr><td> <code title="">Gfr;</code> </td> <td> U+1D50A </td> <tr><td> <code title="">Gg;</code> </td> <td> U+022D9 </td> <tr><td> <code title="">Gopf;</code> </td> <td> U+1D53E </td> <tr><td> <code title="">GreaterEqual;</code> </td> <td> U+02265 </td> <tr><td> <code title="">GreaterEqualLess;</code> </td> <td> U+022DB </td> <tr><td> <code title="">GreaterFullEqual;</code> </td> <td> U+02267 </td> <tr><td> <code title="">GreaterGreater;</code> </td> <td> U+02AA2 </td> <tr><td> <code title="">GreaterLess;</code> </td> <td> U+02277 </td> <tr><td> <code title="">GreaterSlantEqual;</code> </td> <td> U+02A7E </td> <tr><td> <code title="">GreaterTilde;</code> </td> <td> U+02273 </td> <tr><td> <code title="">Gscr;</code> </td> <td> U+1D4A2 </td> <tr><td> <code title="">Gt;</code> </td> <td> U+0226B </td> <tr><td> <code title="">HARDcy;</code> </td> <td> U+0042A </td> <tr><td> <code title="">Hacek;</code> </td> <td> U+002C7 </td> <tr><td> <code title="">Hat;</code> </td> <td> U+0005E </td> <tr><td> <code title="">Hcirc;</code> </td> <td> U+00124 </td> <tr><td> <code title="">Hfr;</code> </td> <td> U+0210C </td> <tr><td> <code title="">HilbertSpace;</code> </td> <td> U+0210B </td> <tr><td> <code title="">Hopf;</code> </td> <td> U+0210D </td> <tr><td> <code title="">HorizontalLine;</code> </td> <td> U+02500 </td> <tr><td> <code title="">Hscr;</code> </td> <td> U+0210B </td> <tr><td> <code title="">Hstrok;</code> </td> <td> U+00126 </td> <tr><td> <code title="">HumpDownHump;</code> </td> <td> U+0224E </td> <tr><td> <code title="">HumpEqual;</code> </td> <td> U+0224F </td> <tr><td> <code title="">IEcy;</code> </td> <td> U+00415 </td> <tr><td> <code title="">IJlig;</code> </td> <td> U+00132 </td> <tr><td> <code title="">IOcy;</code> </td> <td> U+00401 </td> <tr><td> <code title="">Iacute;</code> </td> <td> U+000CD </td> <tr><td> <code title="">Iacute</code> </td> <td> U+000CD </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Icirc;</code> </td> <td> U+000CE </td> <tr><td> <code title="">Icirc</code> </td> <td> U+000CE </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Icy;</code> </td> <td> U+00418 </td> <tr><td> <code title="">Idot;</code> </td> <td> U+00130 </td> <tr><td> <code title="">Ifr;</code> </td> <td> U+02111 </td> <tr><td> <code title="">Igrave;</code> </td> <td> U+000CC </td> <tr><td> <code title="">Igrave</code> </td> <td> U+000CC </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Im;</code> </td> <td> U+02111 </td> <tr><td> <code title="">Imacr;</code> </td> <td> U+0012A </td> <tr><td> <code title="">ImaginaryI;</code> </td> <td> U+02148 </td> <tr><td> <code title="">Implies;</code> </td> <td> U+021D2 </td> <tr><td> <code title="">Int;</code> </td> <td> U+0222C </td> <tr><td> <code title="">Integral;</code> </td> <td> U+0222B </td> <tr><td> <code title="">Intersection;</code> </td> <td> U+022C2 </td> <tr><td> <code title="">InvisibleComma;</code> </td> <td> U+02063 </td> <tr><td> <code title="">InvisibleTimes;</code> </td> <td> U+02062 </td> <tr><td> <code title="">Iogon;</code> </td> <td> U+0012E </td> <tr><td> <code title="">Iopf;</code> </td> <td> U+1D540 </td> <tr><td> <code title="">Iota;</code> </td> <td> U+00399 </td> <tr><td> <code title="">Iscr;</code> </td> <td> U+02110 </td> <tr><td> <code title="">Itilde;</code> </td> <td> U+00128 </td> <tr><td> <code title="">Iukcy;</code> </td> <td> U+00406 </td> <tr><td> <code title="">Iuml;</code> </td> <td> U+000CF </td> <tr><td> <code title="">Iuml</code> </td> <td> U+000CF </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Jcirc;</code> </td> <td> U+00134 </td> <tr><td> <code title="">Jcy;</code> </td> <td> U+00419 </td> <tr><td> <code title="">Jfr;</code> </td> <td> U+1D50D </td> <tr><td> <code title="">Jopf;</code> </td> <td> U+1D541 </td> <tr><td> <code title="">Jscr;</code> </td> <td> U+1D4A5 </td> <tr><td> <code title="">Jsercy;</code> </td> <td> U+00408 </td> <tr><td> <code title="">Jukcy;</code> </td> <td> U+00404 </td> <tr><td> <code title="">KHcy;</code> </td> <td> U+00425 </td> <tr><td> <code title="">KJcy;</code> </td> <td> U+0040C </td> <tr><td> <code title="">Kappa;</code> </td> <td> U+0039A </td> <tr><td> <code title="">Kcedil;</code> </td> <td> U+00136 </td> <tr><td> <code title="">Kcy;</code> </td> <td> U+0041A </td> <tr><td> <code title="">Kfr;</code> </td> <td> U+1D50E </td> <tr><td> <code title="">Kopf;</code> </td> <td> U+1D542 </td> <tr><td> <code title="">Kscr;</code> </td> <td> U+1D4A6 </td> <tr><td> <code title="">LJcy;</code> </td> <td> U+00409 </td> <tr><td> <code title="">LT;</code> </td> <td> U+0003C </td> <tr><td> <code title="">LT</code> </td> <td> U+0003C </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Lacute;</code> </td> <td> U+00139 </td> <tr><td> <code title="">Lambda;</code> </td> <td> U+0039B </td> <tr><td> <code title="">Lang;</code> </td> <td> U+027EA </td> <tr><td> <code title="">Laplacetrf;</code> </td> <td> U+02112 </td> <tr><td> <code title="">Larr;</code> </td> <td> U+0219E </td> <tr><td> <code title="">Lcaron;</code> </td> <td> U+0013D </td> <tr><td> <code title="">Lcedil;</code> </td> <td> U+0013B </td> <tr><td> <code title="">Lcy;</code> </td> <td> U+0041B </td> <tr><td> <code title="">LeftAngleBracket;</code> </td> <td> U+027E8 </td> <tr><td> <code title="">LeftArrow;</code> </td> <td> U+02190 </td> <tr><td> <code title="">LeftArrowBar;</code> </td> <td> U+021E4 </td> <tr><td> <code title="">LeftArrowRightArrow;</code> </td> <td> U+021C6 </td> <tr><td> <code title="">LeftCeiling;</code> </td> <td> U+02308 </td> <tr><td> <code title="">LeftDoubleBracket;</code> </td> <td> U+027E6 </td> <tr><td> <code title="">LeftDownTeeVector;</code> </td> <td> U+02961 </td> <tr><td> <code title="">LeftDownVector;</code> </td> <td> U+021C3 </td> <tr><td> <code title="">LeftDownVectorBar;</code> </td> <td> U+02959 </td> <tr><td> <code title="">LeftFloor;</code> </td> <td> U+0230A </td> <tr><td> <code title="">LeftRightArrow;</code> </td> <td> U+02194 </td> <tr><td> <code title="">LeftRightVector;</code> </td> <td> U+0294E </td> <tr><td> <code title="">LeftTee;</code> </td> <td> U+022A3 </td> <tr><td> <code title="">LeftTeeArrow;</code> </td> <td> U+021A4 </td> <tr><td> <code title="">LeftTeeVector;</code> </td> <td> U+0295A </td> <tr><td> <code title="">LeftTriangle;</code> </td> <td> U+022B2 </td> <tr><td> <code title="">LeftTriangleBar;</code> </td> <td> U+029CF </td> <tr><td> <code title="">LeftTriangleEqual;</code> </td> <td> U+022B4 </td> <tr><td> <code title="">LeftUpDownVector;</code> </td> <td> U+02951 </td> <tr><td> <code title="">LeftUpTeeVector;</code> </td> <td> U+02960 </td> <tr><td> <code title="">LeftUpVector;</code> </td> <td> U+021BF </td> <tr><td> <code title="">LeftUpVectorBar;</code> </td> <td> U+02958 </td> <tr><td> <code title="">LeftVector;</code> </td> <td> U+021BC </td> <tr><td> <code title="">LeftVectorBar;</code> </td> <td> U+02952 </td> <tr><td> <code title="">Leftarrow;</code> </td> <td> U+021D0 </td> <tr><td> <code title="">Leftrightarrow;</code> </td> <td> U+021D4 </td> <tr><td> <code title="">LessEqualGreater;</code> </td> <td> U+022DA </td> <tr><td> <code title="">LessFullEqual;</code> </td> <td> U+02266 </td> <tr><td> <code title="">LessGreater;</code> </td> <td> U+02276 </td> <tr><td> <code title="">LessLess;</code> </td> <td> U+02AA1 </td> <tr><td> <code title="">LessSlantEqual;</code> </td> <td> U+02A7D </td> <tr><td> <code title="">LessTilde;</code> </td> <td> U+02272 </td> <tr><td> <code title="">Lfr;</code> </td> <td> U+1D50F </td> <tr><td> <code title="">Ll;</code> </td> <td> U+022D8 </td> <tr><td> <code title="">Lleftarrow;</code> </td> <td> U+021DA </td> <tr><td> <code title="">Lmidot;</code> </td> <td> U+0013F </td> <tr><td> <code title="">LongLeftArrow;</code> </td> <td> U+027F5 </td> <tr><td> <code title="">LongLeftRightArrow;</code> </td> <td> U+027F7 </td> <tr><td> <code title="">LongRightArrow;</code> </td> <td> U+027F6 </td> <tr><td> <code title="">Longleftarrow;</code> </td> <td> U+027F8 </td> <tr><td> <code title="">Longleftrightarrow;</code> </td> <td> U+027FA </td> <tr><td> <code title="">Longrightarrow;</code> </td> <td> U+027F9 </td> <tr><td> <code title="">Lopf;</code> </td> <td> U+1D543 </td> <tr><td> <code title="">LowerLeftArrow;</code> </td> <td> U+02199 </td> <tr><td> <code title="">LowerRightArrow;</code> </td> <td> U+02198 </td> <tr><td> <code title="">Lscr;</code> </td> <td> U+02112 </td> <tr><td> <code title="">Lsh;</code> </td> <td> U+021B0 </td> <tr><td> <code title="">Lstrok;</code> </td> <td> U+00141 </td> <tr><td> <code title="">Lt;</code> </td> <td> U+0226A </td> <tr><td> <code title="">Map;</code> </td> <td> U+02905 </td> <tr><td> <code title="">Mcy;</code> </td> <td> U+0041C </td> <tr><td> <code title="">MediumSpace;</code> </td> <td> U+0205F </td> <tr><td> <code title="">Mellintrf;</code> </td> <td> U+02133 </td> <tr><td> <code title="">Mfr;</code> </td> <td> U+1D510 </td> <tr><td> <code title="">MinusPlus;</code> </td> <td> U+02213 </td> <tr><td> <code title="">Mopf;</code> </td> <td> U+1D544 </td> <tr><td> <code title="">Mscr;</code> </td> <td> U+02133 </td> <tr><td> <code title="">Mu;</code> </td> <td> U+0039C </td> <tr><td> <code title="">NJcy;</code> </td> <td> U+0040A </td> <tr><td> <code title="">Nacute;</code> </td> <td> U+00143 </td> <tr><td> <code title="">Ncaron;</code> </td> <td> U+00147 </td> <tr><td> <code title="">Ncedil;</code> </td> <td> U+00145 </td> <tr><td> <code title="">Ncy;</code> </td> <td> U+0041D </td> <tr><td> <code title="">NegativeMediumSpace;</code> </td> <td> U+0200B </td> <tr><td> <code title="">NegativeThickSpace;</code> </td> <td> U+0200B </td> <tr><td> <code title="">NegativeThinSpace;</code> </td> <td> U+0200B </td> <tr><td> <code title="">NegativeVeryThinSpace;</code> </td> <td> U+0200B </td> <tr><td> <code title="">NestedGreaterGreater;</code> </td> <td> U+0226B </td> <tr><td> <code title="">NestedLessLess;</code> </td> <td> U+0226A </td> <tr><td> <code title="">NewLine;</code> </td> <td> U+0000A </td> <tr><td> <code title="">Nfr;</code> </td> <td> U+1D511 </td> <tr><td> <code title="">NoBreak;</code> </td> <td> U+02060 </td> <tr><td> <code title="">NonBreakingSpace;</code> </td> <td> U+000A0 </td> <tr><td> <code title="">Nopf;</code> </td> <td> U+02115 </td> <tr><td> <code title="">Not;</code> </td> <td> U+02AEC </td> <tr><td> <code title="">NotCongruent;</code> </td> <td> U+02262 </td> <tr><td> <code title="">NotCupCap;</code> </td> <td> U+0226D </td> <tr><td> <code title="">NotDoubleVerticalBar;</code> </td> <td> U+02226 </td> <tr><td> <code title="">NotElement;</code> </td> <td> U+02209 </td> <tr><td> <code title="">NotEqual;</code> </td> <td> U+02260 </td> <tr><td> <code title="">NotExists;</code> </td> <td> U+02204 </td> <tr><td> <code title="">NotGreater;</code> </td> <td> U+0226F </td> <tr><td> <code title="">NotGreaterEqual;</code> </td> <td> U+02271 </td> <tr><td> <code title="">NotGreaterLess;</code> </td> <td> U+02279 </td> <tr><td> <code title="">NotGreaterTilde;</code> </td> <td> U+02275 </td> <tr><td> <code title="">NotLeftTriangle;</code> </td> <td> U+022EA </td> <tr><td> <code title="">NotLeftTriangleEqual;</code> </td> <td> U+022EC </td> <tr><td> <code title="">NotLess;</code> </td> <td> U+0226E </td> <tr><td> <code title="">NotLessEqual;</code> </td> <td> U+02270 </td> <tr><td> <code title="">NotLessGreater;</code> </td> <td> U+02278 </td> <tr><td> <code title="">NotLessTilde;</code> </td> <td> U+02274 </td> <tr><td> <code title="">NotPrecedes;</code> </td> <td> U+02280 </td> <tr><td> <code title="">NotPrecedesSlantEqual;</code> </td> <td> U+022E0 </td> <tr><td> <code title="">NotReverseElement;</code> </td> <td> U+0220C </td> <tr><td> <code title="">NotRightTriangle;</code> </td> <td> U+022EB </td> <tr><td> <code title="">NotRightTriangleEqual;</code> </td> <td> U+022ED </td> <tr><td> <code title="">NotSquareSubsetEqual;</code> </td> <td> U+022E2 </td> <tr><td> <code title="">NotSquareSupersetEqual;</code> </td> <td> U+022E3 </td> <tr><td> <code title="">NotSubsetEqual;</code> </td> <td> U+02288 </td> <tr><td> <code title="">NotSucceeds;</code> </td> <td> U+02281 </td> <tr><td> <code title="">NotSucceedsSlantEqual;</code> </td> <td> U+022E1 </td> <tr><td> <code title="">NotSupersetEqual;</code> </td> <td> U+02289 </td> <tr><td> <code title="">NotTilde;</code> </td> <td> U+02241 </td> <tr><td> <code title="">NotTildeEqual;</code> </td> <td> U+02244 </td> <tr><td> <code title="">NotTildeFullEqual;</code> </td> <td> U+02247 </td> <tr><td> <code title="">NotTildeTilde;</code> </td> <td> U+02249 </td> <tr><td> <code title="">NotVerticalBar;</code> </td> <td> U+02224 </td> <tr><td> <code title="">Nscr;</code> </td> <td> U+1D4A9 </td> <tr><td> <code title="">Ntilde;</code> </td> <td> U+000D1 </td> <tr><td> <code title="">Ntilde</code> </td> <td> U+000D1 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Nu;</code> </td> <td> U+0039D </td> <tr><td> <code title="">OElig;</code> </td> <td> U+00152 </td> <tr><td> <code title="">Oacute;</code> </td> <td> U+000D3 </td> <tr><td> <code title="">Oacute</code> </td> <td> U+000D3 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Ocirc;</code> </td> <td> U+000D4 </td> <tr><td> <code title="">Ocirc</code> </td> <td> U+000D4 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Ocy;</code> </td> <td> U+0041E </td> <tr><td> <code title="">Odblac;</code> </td> <td> U+00150 </td> <tr><td> <code title="">Ofr;</code> </td> <td> U+1D512 </td> <tr><td> <code title="">Ograve;</code> </td> <td> U+000D2 </td> <tr><td> <code title="">Ograve</code> </td> <td> U+000D2 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Omacr;</code> </td> <td> U+0014C </td> <tr><td> <code title="">Omega;</code> </td> <td> U+003A9 </td> <tr><td> <code title="">Omicron;</code> </td> <td> U+0039F </td> <tr><td> <code title="">Oopf;</code> </td> <td> U+1D546 </td> <tr><td> <code title="">OpenCurlyDoubleQuote;</code> </td> <td> U+0201C </td> <tr><td> <code title="">OpenCurlyQuote;</code> </td> <td> U+02018 </td> <tr><td> <code title="">Or;</code> </td> <td> U+02A54 </td> <tr><td> <code title="">Oscr;</code> </td> <td> U+1D4AA </td> <tr><td> <code title="">Oslash;</code> </td> <td> U+000D8 </td> <tr><td> <code title="">Oslash</code> </td> <td> U+000D8 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Otilde;</code> </td> <td> U+000D5 </td> <tr><td> <code title="">Otilde</code> </td> <td> U+000D5 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Otimes;</code> </td> <td> U+02A37 </td> <tr><td> <code title="">Ouml;</code> </td> <td> U+000D6 </td> <tr><td> <code title="">Ouml</code> </td> <td> U+000D6 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">OverBar;</code> </td> <td> U+0203E </td> <tr><td> <code title="">OverBrace;</code> </td> <td> U+023DE </td> <tr><td> <code title="">OverBracket;</code> </td> <td> U+023B4 </td> <tr><td> <code title="">OverParenthesis;</code> </td> <td> U+023DC </td> <tr><td> <code title="">PartialD;</code> </td> <td> U+02202 </td> <tr><td> <code title="">Pcy;</code> </td> <td> U+0041F </td> <tr><td> <code title="">Pfr;</code> </td> <td> U+1D513 </td> <tr><td> <code title="">Phi;</code> </td> <td> U+003A6 </td> <tr><td> <code title="">Pi;</code> </td> <td> U+003A0 </td> <tr><td> <code title="">PlusMinus;</code> </td> <td> U+000B1 </td> <tr><td> <code title="">Poincareplane;</code> </td> <td> U+0210C </td> <tr><td> <code title="">Popf;</code> </td> <td> U+02119 </td> <tr><td> <code title="">Pr;</code> </td> <td> U+02ABB </td> <tr><td> <code title="">Precedes;</code> </td> <td> U+0227A </td> <tr><td> <code title="">PrecedesEqual;</code> </td> <td> U+02AAF </td> <tr><td> <code title="">PrecedesSlantEqual;</code> </td> <td> U+0227C </td> <tr><td> <code title="">PrecedesTilde;</code> </td> <td> U+0227E </td> <tr><td> <code title="">Prime;</code> </td> <td> U+02033 </td> <tr><td> <code title="">Product;</code> </td> <td> U+0220F </td> <tr><td> <code title="">Proportion;</code> </td> <td> U+02237 </td> <tr><td> <code title="">Proportional;</code> </td> <td> U+0221D </td> <tr><td> <code title="">Pscr;</code> </td> <td> U+1D4AB </td> <tr><td> <code title="">Psi;</code> </td> <td> U+003A8 </td> <tr><td> <code title="">QUOT;</code> </td> <td> U+00022 </td> <tr><td> <code title="">QUOT</code> </td> <td> U+00022 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Qfr;</code> </td> <td> U+1D514 </td> <tr><td> <code title="">Qopf;</code> </td> <td> U+0211A </td> <tr><td> <code title="">Qscr;</code> </td> <td> U+1D4AC </td> <tr><td> <code title="">RBarr;</code> </td> <td> U+02910 </td> <tr><td> <code title="">REG;</code> </td> <td> U+000AE </td> <tr><td> <code title="">REG</code> </td> <td> U+000AE </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Racute;</code> </td> <td> U+00154 </td> <tr><td> <code title="">Rang;</code> </td> <td> U+027EB </td> <tr><td> <code title="">Rarr;</code> </td> <td> U+021A0 </td> <tr><td> <code title="">Rarrtl;</code> </td> <td> U+02916 </td> <tr><td> <code title="">Rcaron;</code> </td> <td> U+00158 </td> <tr><td> <code title="">Rcedil;</code> </td> <td> U+00156 </td> <tr><td> <code title="">Rcy;</code> </td> <td> U+00420 </td> <tr><td> <code title="">Re;</code> </td> <td> U+0211C </td> <tr><td> <code title="">ReverseElement;</code> </td> <td> U+0220B </td> <tr><td> <code title="">ReverseEquilibrium;</code> </td> <td> U+021CB </td> <tr><td> <code title="">ReverseUpEquilibrium;</code> </td> <td> U+0296F </td> <tr><td> <code title="">Rfr;</code> </td> <td> U+0211C </td> <tr><td> <code title="">Rho;</code> </td> <td> U+003A1 </td> <tr><td> <code title="">RightAngleBracket;</code> </td> <td> U+027E9 </td> <tr><td> <code title="">RightArrow;</code> </td> <td> U+02192 </td> <tr><td> <code title="">RightArrowBar;</code> </td> <td> U+021E5 </td> <tr><td> <code title="">RightArrowLeftArrow;</code> </td> <td> U+021C4 </td> <tr><td> <code title="">RightCeiling;</code> </td> <td> U+02309 </td> <tr><td> <code title="">RightDoubleBracket;</code> </td> <td> U+027E7 </td> <tr><td> <code title="">RightDownTeeVector;</code> </td> <td> U+0295D </td> <tr><td> <code title="">RightDownVector;</code> </td> <td> U+021C2 </td> <tr><td> <code title="">RightDownVectorBar;</code> </td> <td> U+02955 </td> <tr><td> <code title="">RightFloor;</code> </td> <td> U+0230B </td> <tr><td> <code title="">RightTee;</code> </td> <td> U+022A2 </td> <tr><td> <code title="">RightTeeArrow;</code> </td> <td> U+021A6 </td> <tr><td> <code title="">RightTeeVector;</code> </td> <td> U+0295B </td> <tr><td> <code title="">RightTriangle;</code> </td> <td> U+022B3 </td> <tr><td> <code title="">RightTriangleBar;</code> </td> <td> U+029D0 </td> <tr><td> <code title="">RightTriangleEqual;</code> </td> <td> U+022B5 </td> <tr><td> <code title="">RightUpDownVector;</code> </td> <td> U+0294F </td> <tr><td> <code title="">RightUpTeeVector;</code> </td> <td> U+0295C </td> <tr><td> <code title="">RightUpVector;</code> </td> <td> U+021BE </td> <tr><td> <code title="">RightUpVectorBar;</code> </td> <td> U+02954 </td> <tr><td> <code title="">RightVector;</code> </td> <td> U+021C0 </td> <tr><td> <code title="">RightVectorBar;</code> </td> <td> U+02953 </td> <tr><td> <code title="">Rightarrow;</code> </td> <td> U+021D2 </td> <tr><td> <code title="">Ropf;</code> </td> <td> U+0211D </td> <tr><td> <code title="">RoundImplies;</code> </td> <td> U+02970 </td> <tr><td> <code title="">Rrightarrow;</code> </td> <td> U+021DB </td> <tr><td> <code title="">Rscr;</code> </td> <td> U+0211B </td> <tr><td> <code title="">Rsh;</code> </td> <td> U+021B1 </td> <tr><td> <code title="">RuleDelayed;</code> </td> <td> U+029F4 </td> <tr><td> <code title="">SHCHcy;</code> </td> <td> U+00429 </td> <tr><td> <code title="">SHcy;</code> </td> <td> U+00428 </td> <tr><td> <code title="">SOFTcy;</code> </td> <td> U+0042C </td> <tr><td> <code title="">Sacute;</code> </td> <td> U+0015A </td> <tr><td> <code title="">Sc;</code> </td> <td> U+02ABC </td> <tr><td> <code title="">Scaron;</code> </td> <td> U+00160 </td> <tr><td> <code title="">Scedil;</code> </td> <td> U+0015E </td> <tr><td> <code title="">Scirc;</code> </td> <td> U+0015C </td> <tr><td> <code title="">Scy;</code> </td> <td> U+00421 </td> <tr><td> <code title="">Sfr;</code> </td> <td> U+1D516 </td> <tr><td> <code title="">ShortDownArrow;</code> </td> <td> U+02193 </td> <tr><td> <code title="">ShortLeftArrow;</code> </td> <td> U+02190 </td> <tr><td> <code title="">ShortRightArrow;</code> </td> <td> U+02192 </td> <tr><td> <code title="">ShortUpArrow;</code> </td> <td> U+02191 </td> <tr><td> <code title="">Sigma;</code> </td> <td> U+003A3 </td> <tr><td> <code title="">SmallCircle;</code> </td> <td> U+02218 </td> <tr><td> <code title="">Sopf;</code> </td> <td> U+1D54A </td> <tr><td> <code title="">Sqrt;</code> </td> <td> U+0221A </td> <tr><td> <code title="">Square;</code> </td> <td> U+025A1 </td> <tr><td> <code title="">SquareIntersection;</code> </td> <td> U+02293 </td> <tr><td> <code title="">SquareSubset;</code> </td> <td> U+0228F </td> <tr><td> <code title="">SquareSubsetEqual;</code> </td> <td> U+02291 </td> <tr><td> <code title="">SquareSuperset;</code> </td> <td> U+02290 </td> <tr><td> <code title="">SquareSupersetEqual;</code> </td> <td> U+02292 </td> <tr><td> <code title="">SquareUnion;</code> </td> <td> U+02294 </td> <tr><td> <code title="">Sscr;</code> </td> <td> U+1D4AE </td> <tr><td> <code title="">Star;</code> </td> <td> U+022C6 </td> <tr><td> <code title="">Sub;</code> </td> <td> U+022D0 </td> <tr><td> <code title="">Subset;</code> </td> <td> U+022D0 </td> <tr><td> <code title="">SubsetEqual;</code> </td> <td> U+02286 </td> <tr><td> <code title="">Succeeds;</code> </td> <td> U+0227B </td> <tr><td> <code title="">SucceedsEqual;</code> </td> <td> U+02AB0 </td> <tr><td> <code title="">SucceedsSlantEqual;</code> </td> <td> U+0227D </td> <tr><td> <code title="">SucceedsTilde;</code> </td> <td> U+0227F </td> <tr><td> <code title="">SuchThat;</code> </td> <td> U+0220B </td> <tr><td> <code title="">Sum;</code> </td> <td> U+02211 </td> <tr><td> <code title="">Sup;</code> </td> <td> U+022D1 </td> <tr><td> <code title="">Superset;</code> </td> <td> U+02283 </td> <tr><td> <code title="">SupersetEqual;</code> </td> <td> U+02287 </td> <tr><td> <code title="">Supset;</code> </td> <td> U+022D1 </td> <tr><td> <code title="">THORN;</code> </td> <td> U+000DE </td> <tr><td> <code title="">THORN</code> </td> <td> U+000DE </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">TRADE;</code> </td> <td> U+02122 </td> <tr><td> <code title="">TSHcy;</code> </td> <td> U+0040B </td> <tr><td> <code title="">TScy;</code> </td> <td> U+00426 </td> <tr><td> <code title="">Tab;</code> </td> <td> U+00009 </td> <tr><td> <code title="">Tau;</code> </td> <td> U+003A4 </td> <tr><td> <code title="">Tcaron;</code> </td> <td> U+00164 </td> <tr><td> <code title="">Tcedil;</code> </td> <td> U+00162 </td> <tr><td> <code title="">Tcy;</code> </td> <td> U+00422 </td> <tr><td> <code title="">Tfr;</code> </td> <td> U+1D517 </td> <tr><td> <code title="">Therefore;</code> </td> <td> U+02234 </td> <tr><td> <code title="">Theta;</code> </td> <td> U+00398 </td> <tr><td> <code title="">ThinSpace;</code> </td> <td> U+02009 </td> <tr><td> <code title="">Tilde;</code> </td> <td> U+0223C </td> <tr><td> <code title="">TildeEqual;</code> </td> <td> U+02243 </td> <tr><td> <code title="">TildeFullEqual;</code> </td> <td> U+02245 </td> <tr><td> <code title="">TildeTilde;</code> </td> <td> U+02248 </td> <tr><td> <code title="">Topf;</code> </td> <td> U+1D54B </td> <tr><td> <code title="">TripleDot;</code> </td> <td> U+020DB </td> <tr><td> <code title="">Tscr;</code> </td> <td> U+1D4AF </td> <tr><td> <code title="">Tstrok;</code> </td> <td> U+00166 </td> <tr><td> <code title="">Uacute;</code> </td> <td> U+000DA </td> <tr><td> <code title="">Uacute</code> </td> <td> U+000DA </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Uarr;</code> </td> <td> U+0219F </td> <tr><td> <code title="">Uarrocir;</code> </td> <td> U+02949 </td> <tr><td> <code title="">Ubrcy;</code> </td> <td> U+0040E </td> <tr><td> <code title="">Ubreve;</code> </td> <td> U+0016C </td> <tr><td> <code title="">Ucirc;</code> </td> <td> U+000DB </td> <tr><td> <code title="">Ucirc</code> </td> <td> U+000DB </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Ucy;</code> </td> <td> U+00423 </td> <tr><td> <code title="">Udblac;</code> </td> <td> U+00170 </td> <tr><td> <code title="">Ufr;</code> </td> <td> U+1D518 </td> <tr><td> <code title="">Ugrave;</code> </td> <td> U+000D9 </td> <tr><td> <code title="">Ugrave</code> </td> <td> U+000D9 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Umacr;</code> </td> <td> U+0016A </td> <tr><td> <code title="">UnderBar;</code> </td> <td> U+0005F </td> <tr><td> <code title="">UnderBrace;</code> </td> <td> U+023DF </td> <tr><td> <code title="">UnderBracket;</code> </td> <td> U+023B5 </td> <tr><td> <code title="">UnderParenthesis;</code> </td> <td> U+023DD </td> <tr><td> <code title="">Union;</code> </td> <td> U+022C3 </td> <tr><td> <code title="">UnionPlus;</code> </td> <td> U+0228E </td> <tr><td> <code title="">Uogon;</code> </td> <td> U+00172 </td> <tr><td> <code title="">Uopf;</code> </td> <td> U+1D54C </td> <tr><td> <code title="">UpArrow;</code> </td> <td> U+02191 </td> <tr><td> <code title="">UpArrowBar;</code> </td> <td> U+02912 </td> <tr><td> <code title="">UpArrowDownArrow;</code> </td> <td> U+021C5 </td> <tr><td> <code title="">UpDownArrow;</code> </td> <td> U+02195 </td> <tr><td> <code title="">UpEquilibrium;</code> </td> <td> U+0296E </td> <tr><td> <code title="">UpTee;</code> </td> <td> U+022A5 </td> <tr><td> <code title="">UpTeeArrow;</code> </td> <td> U+021A5 </td> <tr><td> <code title="">Uparrow;</code> </td> <td> U+021D1 </td> <tr><td> <code title="">Updownarrow;</code> </td> <td> U+021D5 </td> <tr><td> <code title="">UpperLeftArrow;</code> </td> <td> U+02196 </td> <tr><td> <code title="">UpperRightArrow;</code> </td> <td> U+02197 </td> <tr><td> <code title="">Upsi;</code> </td> <td> U+003D2 </td> <tr><td> <code title="">Upsilon;</code> </td> <td> U+003A5 </td> <tr><td> <code title="">Uring;</code> </td> <td> U+0016E </td> <tr><td> <code title="">Uscr;</code> </td> <td> U+1D4B0 </td> <tr><td> <code title="">Utilde;</code> </td> <td> U+00168 </td> <tr><td> <code title="">Uuml;</code> </td> <td> U+000DC </td> <tr><td> <code title="">Uuml</code> </td> <td> U+000DC </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">VDash;</code> </td> <td> U+022AB </td> <tr><td> <code title="">Vbar;</code> </td> <td> U+02AEB </td> <tr><td> <code title="">Vcy;</code> </td> <td> U+00412 </td> <tr><td> <code title="">Vdash;</code> </td> <td> U+022A9 </td> <tr><td> <code title="">Vdashl;</code> </td> <td> U+02AE6 </td> <tr><td> <code title="">Vee;</code> </td> <td> U+022C1 </td> <tr><td> <code title="">Verbar;</code> </td> <td> U+02016 </td> <tr><td> <code title="">Vert;</code> </td> <td> U+02016 </td> <tr><td> <code title="">VerticalBar;</code> </td> <td> U+02223 </td> <tr><td> <code title="">VerticalLine;</code> </td> <td> U+0007C </td> <tr><td> <code title="">VerticalSeparator;</code> </td> <td> U+02758 </td> <tr><td> <code title="">VerticalTilde;</code> </td> <td> U+02240 </td> <tr><td> <code title="">VeryThinSpace;</code> </td> <td> U+0200A </td> <tr><td> <code title="">Vfr;</code> </td> <td> U+1D519 </td> <tr><td> <code title="">Vopf;</code> </td> <td> U+1D54D </td> <tr><td> <code title="">Vscr;</code> </td> <td> U+1D4B1 </td> <tr><td> <code title="">Vvdash;</code> </td> <td> U+022AA </td> <tr><td> <code title="">Wcirc;</code> </td> <td> U+00174 </td> <tr><td> <code title="">Wedge;</code> </td> <td> U+022C0 </td> <tr><td> <code title="">Wfr;</code> </td> <td> U+1D51A </td> <tr><td> <code title="">Wopf;</code> </td> <td> U+1D54E </td> <tr><td> <code title="">Wscr;</code> </td> <td> U+1D4B2 </td> <tr><td> <code title="">Xfr;</code> </td> <td> U+1D51B </td> <tr><td> <code title="">Xi;</code> </td> <td> U+0039E </td> <tr><td> <code title="">Xopf;</code> </td> <td> U+1D54F </td> <tr><td> <code title="">Xscr;</code> </td> <td> U+1D4B3 </td> <tr><td> <code title="">YAcy;</code> </td> <td> U+0042F </td> <tr><td> <code title="">YIcy;</code> </td> <td> U+00407 </td> <tr><td> <code title="">YUcy;</code> </td> <td> U+0042E </td> <tr><td> <code title="">Yacute;</code> </td> <td> U+000DD </td> <tr><td> <code title="">Yacute</code> </td> <td> U+000DD </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">Ycirc;</code> </td> <td> U+00176 </td> <tr><td> <code title="">Ycy;</code> </td> <td> U+0042B </td> <tr><td> <code title="">Yfr;</code> </td> <td> U+1D51C </td> <tr><td> <code title="">Yopf;</code> </td> <td> U+1D550 </td> <tr><td> <code title="">Yscr;</code> </td> <td> U+1D4B4 </td> <tr><td> <code title="">Yuml;</code> </td> <td> U+00178 </td> <tr><td> <code title="">ZHcy;</code> </td> <td> U+00416 </td> <tr><td> <code title="">Zacute;</code> </td> <td> U+00179 </td> <tr><td> <code title="">Zcaron;</code> </td> <td> U+0017D </td> <tr><td> <code title="">Zcy;</code> </td> <td> U+00417 </td> <tr><td> <code title="">Zdot;</code> </td> <td> U+0017B </td> <tr><td> <code title="">ZeroWidthSpace;</code> </td> <td> U+0200B </td> <tr><td> <code title="">Zeta;</code> </td> <td> U+00396 </td> <tr><td> <code title="">Zfr;</code> </td> <td> U+02128 </td> <tr><td> <code title="">Zopf;</code> </td> <td> U+02124 </td> <tr><td> <code title="">Zscr;</code> </td> <td> U+1D4B5 </td> <tr><td> <code title="">aacute;</code> </td> <td> U+000E1 </td> <tr><td> <code title="">aacute</code> </td> <td> U+000E1 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">abreve;</code> </td> <td> U+00103 </td> <tr><td> <code title="">ac;</code> </td> <td> U+0223E </td> <tr><td> <code title="">acd;</code> </td> <td> U+0223F </td> <tr><td> <code title="">acirc;</code> </td> <td> U+000E2 </td> <tr><td> <code title="">acirc</code> </td> <td> U+000E2 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">acute;</code> </td> <td> U+000B4 </td> <tr><td> <code title="">acute</code> </td> <td> U+000B4 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">acy;</code> </td> <td> U+00430 </td> <tr><td> <code title="">aelig;</code> </td> <td> U+000E6 </td> <tr><td> <code title="">aelig</code> </td> <td> U+000E6 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">af;</code> </td> <td> U+02061 </td> <tr><td> <code title="">afr;</code> </td> <td> U+1D51E </td> <tr><td> <code title="">agrave;</code> </td> <td> U+000E0 </td> <tr><td> <code title="">agrave</code> </td> <td> U+000E0 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">alefsym;</code> </td> <td> U+02135 </td> <tr><td> <code title="">aleph;</code> </td> <td> U+02135 </td> <tr><td> <code title="">alpha;</code> </td> <td> U+003B1 </td> <tr><td> <code title="">amacr;</code> </td> <td> U+00101 </td> <tr><td> <code title="">amalg;</code> </td> <td> U+02A3F </td> <tr><td> <code title="">amp;</code> </td> <td> U+00026 </td> <tr><td> <code title="">amp</code> </td> <td> U+00026 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">and;</code> </td> <td> U+02227 </td> <tr><td> <code title="">andand;</code> </td> <td> U+02A55 </td> <tr><td> <code title="">andd;</code> </td> <td> U+02A5C </td> <tr><td> <code title="">andslope;</code> </td> <td> U+02A58 </td> <tr><td> <code title="">andv;</code> </td> <td> U+02A5A </td> <tr><td> <code title="">ang;</code> </td> <td> U+02220 </td> <tr><td> <code title="">ange;</code> </td> <td> U+029A4 </td> <tr><td> <code title="">angle;</code> </td> <td> U+02220 </td> <tr><td> <code title="">angmsd;</code> </td> <td> U+02221 </td> <tr><td> <code title="">angmsdaa;</code> </td> <td> U+029A8 </td> <tr><td> <code title="">angmsdab;</code> </td> <td> U+029A9 </td> <tr><td> <code title="">angmsdac;</code> </td> <td> U+029AA </td> <tr><td> <code title="">angmsdad;</code> </td> <td> U+029AB </td> <tr><td> <code title="">angmsdae;</code> </td> <td> U+029AC </td> <tr><td> <code title="">angmsdaf;</code> </td> <td> U+029AD </td> <tr><td> <code title="">angmsdag;</code> </td> <td> U+029AE </td> <tr><td> <code title="">angmsdah;</code> </td> <td> U+029AF </td> <tr><td> <code title="">angrt;</code> </td> <td> U+0221F </td> <tr><td> <code title="">angrtvb;</code> </td> <td> U+022BE </td> <tr><td> <code title="">angrtvbd;</code> </td> <td> U+0299D </td> <tr><td> <code title="">angsph;</code> </td> <td> U+02222 </td> <tr><td> <code title="">angst;</code> </td> <td> U+000C5 </td> <tr><td> <code title="">angzarr;</code> </td> <td> U+0237C </td> <tr><td> <code title="">aogon;</code> </td> <td> U+00105 </td> <tr><td> <code title="">aopf;</code> </td> <td> U+1D552 </td> <tr><td> <code title="">ap;</code> </td> <td> U+02248 </td> <tr><td> <code title="">apE;</code> </td> <td> U+02A70 </td> <tr><td> <code title="">apacir;</code> </td> <td> U+02A6F </td> <tr><td> <code title="">ape;</code> </td> <td> U+0224A </td> <tr><td> <code title="">apid;</code> </td> <td> U+0224B </td> <tr><td> <code title="">apos;</code> </td> <td> U+00027 </td> <tr><td> <code title="">approx;</code> </td> <td> U+02248 </td> <tr><td> <code title="">approxeq;</code> </td> <td> U+0224A </td> <tr><td> <code title="">aring;</code> </td> <td> U+000E5 </td> <tr><td> <code title="">aring</code> </td> <td> U+000E5 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">ascr;</code> </td> <td> U+1D4B6 </td> <tr><td> <code title="">ast;</code> </td> <td> U+0002A </td> <tr><td> <code title="">asymp;</code> </td> <td> U+02248 </td> <tr><td> <code title="">asympeq;</code> </td> <td> U+0224D </td> <tr><td> <code title="">atilde;</code> </td> <td> U+000E3 </td> <tr><td> <code title="">atilde</code> </td> <td> U+000E3 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">auml;</code> </td> <td> U+000E4 </td> <tr><td> <code title="">auml</code> </td> <td> U+000E4 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">awconint;</code> </td> <td> U+02233 </td> <tr><td> <code title="">awint;</code> </td> <td> U+02A11 </td> <tr><td> <code title="">bNot;</code> </td> <td> U+02AED </td> <tr><td> <code title="">backcong;</code> </td> <td> U+0224C </td> <tr><td> <code title="">backepsilon;</code> </td> <td> U+003F6 </td> <tr><td> <code title="">backprime;</code> </td> <td> U+02035 </td> <tr><td> <code title="">backsim;</code> </td> <td> U+0223D </td> <tr><td> <code title="">backsimeq;</code> </td> <td> U+022CD </td> <tr><td> <code title="">barvee;</code> </td> <td> U+022BD </td> <tr><td> <code title="">barwed;</code> </td> <td> U+02305 </td> <tr><td> <code title="">barwedge;</code> </td> <td> U+02305 </td> <tr><td> <code title="">bbrk;</code> </td> <td> U+023B5 </td> <tr><td> <code title="">bbrktbrk;</code> </td> <td> U+023B6 </td> <tr><td> <code title="">bcong;</code> </td> <td> U+0224C </td> <tr><td> <code title="">bcy;</code> </td> <td> U+00431 </td> <tr><td> <code title="">bdquo;</code> </td> <td> U+0201E </td> <tr><td> <code title="">becaus;</code> </td> <td> U+02235 </td> <tr><td> <code title="">because;</code> </td> <td> U+02235 </td> <tr><td> <code title="">bemptyv;</code> </td> <td> U+029B0 </td> <tr><td> <code title="">bepsi;</code> </td> <td> U+003F6 </td> <tr><td> <code title="">bernou;</code> </td> <td> U+0212C </td> <tr><td> <code title="">beta;</code> </td> <td> U+003B2 </td> <tr><td> <code title="">beth;</code> </td> <td> U+02136 </td> <tr><td> <code title="">between;</code> </td> <td> U+0226C </td> <tr><td> <code title="">bfr;</code> </td> <td> U+1D51F </td> <tr><td> <code title="">bigcap;</code> </td> <td> U+022C2 </td> <tr><td> <code title="">bigcirc;</code> </td> <td> U+025EF </td> <tr><td> <code title="">bigcup;</code> </td> <td> U+022C3 </td> <tr><td> <code title="">bigodot;</code> </td> <td> U+02A00 </td> <tr><td> <code title="">bigoplus;</code> </td> <td> U+02A01 </td> <tr><td> <code title="">bigotimes;</code> </td> <td> U+02A02 </td> <tr><td> <code title="">bigsqcup;</code> </td> <td> U+02A06 </td> <tr><td> <code title="">bigstar;</code> </td> <td> U+02605 </td> <tr><td> <code title="">bigtriangledown;</code> </td> <td> U+025BD </td> <tr><td> <code title="">bigtriangleup;</code> </td> <td> U+025B3 </td> <tr><td> <code title="">biguplus;</code> </td> <td> U+02A04 </td> <tr><td> <code title="">bigvee;</code> </td> <td> U+022C1 </td> <tr><td> <code title="">bigwedge;</code> </td> <td> U+022C0 </td> <tr><td> <code title="">bkarow;</code> </td> <td> U+0290D </td> <tr><td> <code title="">blacklozenge;</code> </td> <td> U+029EB </td> <tr><td> <code title="">blacksquare;</code> </td> <td> U+025AA </td> <tr><td> <code title="">blacktriangle;</code> </td> <td> U+025B4 </td> <tr><td> <code title="">blacktriangledown;</code> </td> <td> U+025BE </td> <tr><td> <code title="">blacktriangleleft;</code> </td> <td> U+025C2 </td> <tr><td> <code title="">blacktriangleright;</code> </td> <td> U+025B8 </td> <tr><td> <code title="">blank;</code> </td> <td> U+02423 </td> <tr><td> <code title="">blk12;</code> </td> <td> U+02592 </td> <tr><td> <code title="">blk14;</code> </td> <td> U+02591 </td> <tr><td> <code title="">blk34;</code> </td> <td> U+02593 </td> <tr><td> <code title="">block;</code> </td> <td> U+02588 </td> <tr><td> <code title="">bnot;</code> </td> <td> U+02310 </td> <tr><td> <code title="">bopf;</code> </td> <td> U+1D553 </td> <tr><td> <code title="">bot;</code> </td> <td> U+022A5 </td> <tr><td> <code title="">bottom;</code> </td> <td> U+022A5 </td> <tr><td> <code title="">bowtie;</code> </td> <td> U+022C8 </td> <tr><td> <code title="">boxDL;</code> </td> <td> U+02557 </td> <tr><td> <code title="">boxDR;</code> </td> <td> U+02554 </td> <tr><td> <code title="">boxDl;</code> </td> <td> U+02556 </td> <tr><td> <code title="">boxDr;</code> </td> <td> U+02553 </td> <tr><td> <code title="">boxH;</code> </td> <td> U+02550 </td> <tr><td> <code title="">boxHD;</code> </td> <td> U+02566 </td> <tr><td> <code title="">boxHU;</code> </td> <td> U+02569 </td> <tr><td> <code title="">boxHd;</code> </td> <td> U+02564 </td> <tr><td> <code title="">boxHu;</code> </td> <td> U+02567 </td> <tr><td> <code title="">boxUL;</code> </td> <td> U+0255D </td> <tr><td> <code title="">boxUR;</code> </td> <td> U+0255A </td> <tr><td> <code title="">boxUl;</code> </td> <td> U+0255C </td> <tr><td> <code title="">boxUr;</code> </td> <td> U+02559 </td> <tr><td> <code title="">boxV;</code> </td> <td> U+02551 </td> <tr><td> <code title="">boxVH;</code> </td> <td> U+0256C </td> <tr><td> <code title="">boxVL;</code> </td> <td> U+02563 </td> <tr><td> <code title="">boxVR;</code> </td> <td> U+02560 </td> <tr><td> <code title="">boxVh;</code> </td> <td> U+0256B </td> <tr><td> <code title="">boxVl;</code> </td> <td> U+02562 </td> <tr><td> <code title="">boxVr;</code> </td> <td> U+0255F </td> <tr><td> <code title="">boxbox;</code> </td> <td> U+029C9 </td> <tr><td> <code title="">boxdL;</code> </td> <td> U+02555 </td> <tr><td> <code title="">boxdR;</code> </td> <td> U+02552 </td> <tr><td> <code title="">boxdl;</code> </td> <td> U+02510 </td> <tr><td> <code title="">boxdr;</code> </td> <td> U+0250C </td> <tr><td> <code title="">boxh;</code> </td> <td> U+02500 </td> <tr><td> <code title="">boxhD;</code> </td> <td> U+02565 </td> <tr><td> <code title="">boxhU;</code> </td> <td> U+02568 </td> <tr><td> <code title="">boxhd;</code> </td> <td> U+0252C </td> <tr><td> <code title="">boxhu;</code> </td> <td> U+02534 </td> <tr><td> <code title="">boxminus;</code> </td> <td> U+0229F </td> <tr><td> <code title="">boxplus;</code> </td> <td> U+0229E </td> <tr><td> <code title="">boxtimes;</code> </td> <td> U+022A0 </td> <tr><td> <code title="">boxuL;</code> </td> <td> U+0255B </td> <tr><td> <code title="">boxuR;</code> </td> <td> U+02558 </td> <tr><td> <code title="">boxul;</code> </td> <td> U+02518 </td> <tr><td> <code title="">boxur;</code> </td> <td> U+02514 </td> <tr><td> <code title="">boxv;</code> </td> <td> U+02502 </td> <tr><td> <code title="">boxvH;</code> </td> <td> U+0256A </td> <tr><td> <code title="">boxvL;</code> </td> <td> U+02561 </td> <tr><td> <code title="">boxvR;</code> </td> <td> U+0255E </td> <tr><td> <code title="">boxvh;</code> </td> <td> U+0253C </td> <tr><td> <code title="">boxvl;</code> </td> <td> U+02524 </td> <tr><td> <code title="">boxvr;</code> </td> <td> U+0251C </td> <tr><td> <code title="">bprime;</code> </td> <td> U+02035 </td> <tr><td> <code title="">breve;</code> </td> <td> U+002D8 </td> <tr><td> <code title="">brvbar;</code> </td> <td> U+000A6 </td> <tr><td> <code title="">brvbar</code> </td> <td> U+000A6 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">bscr;</code> </td> <td> U+1D4B7 </td> <tr><td> <code title="">bsemi;</code> </td> <td> U+0204F </td> <tr><td> <code title="">bsim;</code> </td> <td> U+0223D </td> <tr><td> <code title="">bsime;</code> </td> <td> U+022CD </td> <tr><td> <code title="">bsol;</code> </td> <td> U+0005C </td> <tr><td> <code title="">bsolb;</code> </td> <td> U+029C5 </td> <tr><td> <code title="">bsolhsub;</code> </td> <td> U+027C8 </td> <tr><td> <code title="">bull;</code> </td> <td> U+02022 </td> <tr><td> <code title="">bullet;</code> </td> <td> U+02022 </td> <tr><td> <code title="">bump;</code> </td> <td> U+0224E </td> <tr><td> <code title="">bumpE;</code> </td> <td> U+02AAE </td> <tr><td> <code title="">bumpe;</code> </td> <td> U+0224F </td> <tr><td> <code title="">bumpeq;</code> </td> <td> U+0224F </td> <tr><td> <code title="">cacute;</code> </td> <td> U+00107 </td> <tr><td> <code title="">cap;</code> </td> <td> U+02229 </td> <tr><td> <code title="">capand;</code> </td> <td> U+02A44 </td> <tr><td> <code title="">capbrcup;</code> </td> <td> U+02A49 </td> <tr><td> <code title="">capcap;</code> </td> <td> U+02A4B </td> <tr><td> <code title="">capcup;</code> </td> <td> U+02A47 </td> <tr><td> <code title="">capdot;</code> </td> <td> U+02A40 </td> <tr><td> <code title="">caret;</code> </td> <td> U+02041 </td> <tr><td> <code title="">caron;</code> </td> <td> U+002C7 </td> <tr><td> <code title="">ccaps;</code> </td> <td> U+02A4D </td> <tr><td> <code title="">ccaron;</code> </td> <td> U+0010D </td> <tr><td> <code title="">ccedil;</code> </td> <td> U+000E7 </td> <tr><td> <code title="">ccedil</code> </td> <td> U+000E7 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">ccirc;</code> </td> <td> U+00109 </td> <tr><td> <code title="">ccups;</code> </td> <td> U+02A4C </td> <tr><td> <code title="">ccupssm;</code> </td> <td> U+02A50 </td> <tr><td> <code title="">cdot;</code> </td> <td> U+0010B </td> <tr><td> <code title="">cedil;</code> </td> <td> U+000B8 </td> <tr><td> <code title="">cedil</code> </td> <td> U+000B8 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">cemptyv;</code> </td> <td> U+029B2 </td> <tr><td> <code title="">cent;</code> </td> <td> U+000A2 </td> <tr><td> <code title="">cent</code> </td> <td> U+000A2 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">centerdot;</code> </td> <td> U+000B7 </td> <tr><td> <code title="">cfr;</code> </td> <td> U+1D520 </td> <tr><td> <code title="">chcy;</code> </td> <td> U+00447 </td> <tr><td> <code title="">check;</code> </td> <td> U+02713 </td> <tr><td> <code title="">checkmark;</code> </td> <td> U+02713 </td> <tr><td> <code title="">chi;</code> </td> <td> U+003C7 </td> <tr><td> <code title="">cir;</code> </td> <td> U+025CB </td> <tr><td> <code title="">cirE;</code> </td> <td> U+029C3 </td> <tr><td> <code title="">circ;</code> </td> <td> U+002C6 </td> <tr><td> <code title="">circeq;</code> </td> <td> U+02257 </td> <tr><td> <code title="">circlearrowleft;</code> </td> <td> U+021BA </td> <tr><td> <code title="">circlearrowright;</code> </td> <td> U+021BB </td> <tr><td> <code title="">circledR;</code> </td> <td> U+000AE </td> <tr><td> <code title="">circledS;</code> </td> <td> U+024C8 </td> <tr><td> <code title="">circledast;</code> </td> <td> U+0229B </td> <tr><td> <code title="">circledcirc;</code> </td> <td> U+0229A </td> <tr><td> <code title="">circleddash;</code> </td> <td> U+0229D </td> <tr><td> <code title="">cire;</code> </td> <td> U+02257 </td> <tr><td> <code title="">cirfnint;</code> </td> <td> U+02A10 </td> <tr><td> <code title="">cirmid;</code> </td> <td> U+02AEF </td> <tr><td> <code title="">cirscir;</code> </td> <td> U+029C2 </td> <tr><td> <code title="">clubs;</code> </td> <td> U+02663 </td> <tr><td> <code title="">clubsuit;</code> </td> <td> U+02663 </td> <tr><td> <code title="">colon;</code> </td> <td> U+0003A </td> <tr><td> <code title="">colone;</code> </td> <td> U+02254 </td> <tr><td> <code title="">coloneq;</code> </td> <td> U+02254 </td> <tr><td> <code title="">comma;</code> </td> <td> U+0002C </td> <tr><td> <code title="">commat;</code> </td> <td> U+00040 </td> <tr><td> <code title="">comp;</code> </td> <td> U+02201 </td> <tr><td> <code title="">compfn;</code> </td> <td> U+02218 </td> <tr><td> <code title="">complement;</code> </td> <td> U+02201 </td> <tr><td> <code title="">complexes;</code> </td> <td> U+02102 </td> <tr><td> <code title="">cong;</code> </td> <td> U+02245 </td> <tr><td> <code title="">congdot;</code> </td> <td> U+02A6D </td> <tr><td> <code title="">conint;</code> </td> <td> U+0222E </td> <tr><td> <code title="">copf;</code> </td> <td> U+1D554 </td> <tr><td> <code title="">coprod;</code> </td> <td> U+02210 </td> <tr><td> <code title="">copy;</code> </td> <td> U+000A9 </td> <tr><td> <code title="">copy</code> </td> <td> U+000A9 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">copysr;</code> </td> <td> U+02117 </td> <tr><td> <code title="">crarr;</code> </td> <td> U+021B5 </td> <tr><td> <code title="">cross;</code> </td> <td> U+02717 </td> <tr><td> <code title="">cscr;</code> </td> <td> U+1D4B8 </td> <tr><td> <code title="">csub;</code> </td> <td> U+02ACF </td> <tr><td> <code title="">csube;</code> </td> <td> U+02AD1 </td> <tr><td> <code title="">csup;</code> </td> <td> U+02AD0 </td> <tr><td> <code title="">csupe;</code> </td> <td> U+02AD2 </td> <tr><td> <code title="">ctdot;</code> </td> <td> U+022EF </td> <tr><td> <code title="">cudarrl;</code> </td> <td> U+02938 </td> <tr><td> <code title="">cudarrr;</code> </td> <td> U+02935 </td> <tr><td> <code title="">cuepr;</code> </td> <td> U+022DE </td> <tr><td> <code title="">cuesc;</code> </td> <td> U+022DF </td> <tr><td> <code title="">cularr;</code> </td> <td> U+021B6 </td> <tr><td> <code title="">cularrp;</code> </td> <td> U+0293D </td> <tr><td> <code title="">cup;</code> </td> <td> U+0222A </td> <tr><td> <code title="">cupbrcap;</code> </td> <td> U+02A48 </td> <tr><td> <code title="">cupcap;</code> </td> <td> U+02A46 </td> <tr><td> <code title="">cupcup;</code> </td> <td> U+02A4A </td> <tr><td> <code title="">cupdot;</code> </td> <td> U+0228D </td> <tr><td> <code title="">cupor;</code> </td> <td> U+02A45 </td> <tr><td> <code title="">curarr;</code> </td> <td> U+021B7 </td> <tr><td> <code title="">curarrm;</code> </td> <td> U+0293C </td> <tr><td> <code title="">curlyeqprec;</code> </td> <td> U+022DE </td> <tr><td> <code title="">curlyeqsucc;</code> </td> <td> U+022DF </td> <tr><td> <code title="">curlyvee;</code> </td> <td> U+022CE </td> <tr><td> <code title="">curlywedge;</code> </td> <td> U+022CF </td> <tr><td> <code title="">curren;</code> </td> <td> U+000A4 </td> <tr><td> <code title="">curren</code> </td> <td> U+000A4 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">curvearrowleft;</code> </td> <td> U+021B6 </td> <tr><td> <code title="">curvearrowright;</code> </td> <td> U+021B7 </td> <tr><td> <code title="">cuvee;</code> </td> <td> U+022CE </td> <tr><td> <code title="">cuwed;</code> </td> <td> U+022CF </td> <tr><td> <code title="">cwconint;</code> </td> <td> U+02232 </td> <tr><td> <code title="">cwint;</code> </td> <td> U+02231 </td> <tr><td> <code title="">cylcty;</code> </td> <td> U+0232D </td> <tr><td> <code title="">dArr;</code> </td> <td> U+021D3 </td> <tr><td> <code title="">dHar;</code> </td> <td> U+02965 </td> <tr><td> <code title="">dagger;</code> </td> <td> U+02020 </td> <tr><td> <code title="">daleth;</code> </td> <td> U+02138 </td> <tr><td> <code title="">darr;</code> </td> <td> U+02193 </td> <tr><td> <code title="">dash;</code> </td> <td> U+02010 </td> <tr><td> <code title="">dashv;</code> </td> <td> U+022A3 </td> <tr><td> <code title="">dbkarow;</code> </td> <td> U+0290F </td> <tr><td> <code title="">dblac;</code> </td> <td> U+002DD </td> <tr><td> <code title="">dcaron;</code> </td> <td> U+0010F </td> <tr><td> <code title="">dcy;</code> </td> <td> U+00434 </td> <tr><td> <code title="">dd;</code> </td> <td> U+02146 </td> <tr><td> <code title="">ddagger;</code> </td> <td> U+02021 </td> <tr><td> <code title="">ddarr;</code> </td> <td> U+021CA </td> <tr><td> <code title="">ddotseq;</code> </td> <td> U+02A77 </td> <tr><td> <code title="">deg;</code> </td> <td> U+000B0 </td> <tr><td> <code title="">deg</code> </td> <td> U+000B0 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">delta;</code> </td> <td> U+003B4 </td> <tr><td> <code title="">demptyv;</code> </td> <td> U+029B1 </td> <tr><td> <code title="">dfisht;</code> </td> <td> U+0297F </td> <tr><td> <code title="">dfr;</code> </td> <td> U+1D521 </td> <tr><td> <code title="">dharl;</code> </td> <td> U+021C3 </td> <tr><td> <code title="">dharr;</code> </td> <td> U+021C2 </td> <tr><td> <code title="">diam;</code> </td> <td> U+022C4 </td> <tr><td> <code title="">diamond;</code> </td> <td> U+022C4 </td> <tr><td> <code title="">diamondsuit;</code> </td> <td> U+02666 </td> <tr><td> <code title="">diams;</code> </td> <td> U+02666 </td> <tr><td> <code title="">die;</code> </td> <td> U+000A8 </td> <tr><td> <code title="">digamma;</code> </td> <td> U+003DD </td> <tr><td> <code title="">disin;</code> </td> <td> U+022F2 </td> <tr><td> <code title="">div;</code> </td> <td> U+000F7 </td> <tr><td> <code title="">divide;</code> </td> <td> U+000F7 </td> <tr><td> <code title="">divide</code> </td> <td> U+000F7 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">divideontimes;</code> </td> <td> U+022C7 </td> <tr><td> <code title="">divonx;</code> </td> <td> U+022C7 </td> <tr><td> <code title="">djcy;</code> </td> <td> U+00452 </td> <tr><td> <code title="">dlcorn;</code> </td> <td> U+0231E </td> <tr><td> <code title="">dlcrop;</code> </td> <td> U+0230D </td> <tr><td> <code title="">dollar;</code> </td> <td> U+00024 </td> <tr><td> <code title="">dopf;</code> </td> <td> U+1D555 </td> <tr><td> <code title="">dot;</code> </td> <td> U+002D9 </td> <tr><td> <code title="">doteq;</code> </td> <td> U+02250 </td> <tr><td> <code title="">doteqdot;</code> </td> <td> U+02251 </td> <tr><td> <code title="">dotminus;</code> </td> <td> U+02238 </td> <tr><td> <code title="">dotplus;</code> </td> <td> U+02214 </td> <tr><td> <code title="">dotsquare;</code> </td> <td> U+022A1 </td> <tr><td> <code title="">doublebarwedge;</code> </td> <td> U+02306 </td> <tr><td> <code title="">downarrow;</code> </td> <td> U+02193 </td> <tr><td> <code title="">downdownarrows;</code> </td> <td> U+021CA </td> <tr><td> <code title="">downharpoonleft;</code> </td> <td> U+021C3 </td> <tr><td> <code title="">downharpoonright;</code> </td> <td> U+021C2 </td> <tr><td> <code title="">drbkarow;</code> </td> <td> U+02910 </td> <tr><td> <code title="">drcorn;</code> </td> <td> U+0231F </td> <tr><td> <code title="">drcrop;</code> </td> <td> U+0230C </td> <tr><td> <code title="">dscr;</code> </td> <td> U+1D4B9 </td> <tr><td> <code title="">dscy;</code> </td> <td> U+00455 </td> <tr><td> <code title="">dsol;</code> </td> <td> U+029F6 </td> <tr><td> <code title="">dstrok;</code> </td> <td> U+00111 </td> <tr><td> <code title="">dtdot;</code> </td> <td> U+022F1 </td> <tr><td> <code title="">dtri;</code> </td> <td> U+025BF </td> <tr><td> <code title="">dtrif;</code> </td> <td> U+025BE </td> <tr><td> <code title="">duarr;</code> </td> <td> U+021F5 </td> <tr><td> <code title="">duhar;</code> </td> <td> U+0296F </td> <tr><td> <code title="">dwangle;</code> </td> <td> U+029A6 </td> <tr><td> <code title="">dzcy;</code> </td> <td> U+0045F </td> <tr><td> <code title="">dzigrarr;</code> </td> <td> U+027FF </td> <tr><td> <code title="">eDDot;</code> </td> <td> U+02A77 </td> <tr><td> <code title="">eDot;</code> </td> <td> U+02251 </td> <tr><td> <code title="">eacute;</code> </td> <td> U+000E9 </td> <tr><td> <code title="">eacute</code> </td> <td> U+000E9 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">easter;</code> </td> <td> U+02A6E </td> <tr><td> <code title="">ecaron;</code> </td> <td> U+0011B </td> <tr><td> <code title="">ecir;</code> </td> <td> U+02256 </td> <tr><td> <code title="">ecirc;</code> </td> <td> U+000EA </td> <tr><td> <code title="">ecirc</code> </td> <td> U+000EA </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">ecolon;</code> </td> <td> U+02255 </td> <tr><td> <code title="">ecy;</code> </td> <td> U+0044D </td> <tr><td> <code title="">edot;</code> </td> <td> U+00117 </td> <tr><td> <code title="">ee;</code> </td> <td> U+02147 </td> <tr><td> <code title="">efDot;</code> </td> <td> U+02252 </td> <tr><td> <code title="">efr;</code> </td> <td> U+1D522 </td> <tr><td> <code title="">eg;</code> </td> <td> U+02A9A </td> <tr><td> <code title="">egrave;</code> </td> <td> U+000E8 </td> <tr><td> <code title="">egrave</code> </td> <td> U+000E8 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">egs;</code> </td> <td> U+02A96 </td> <tr><td> <code title="">egsdot;</code> </td> <td> U+02A98 </td> <tr><td> <code title="">el;</code> </td> <td> U+02A99 </td> <tr><td> <code title="">elinters;</code> </td> <td> U+023E7 </td> <tr><td> <code title="">ell;</code> </td> <td> U+02113 </td> <tr><td> <code title="">els;</code> </td> <td> U+02A95 </td> <tr><td> <code title="">elsdot;</code> </td> <td> U+02A97 </td> <tr><td> <code title="">emacr;</code> </td> <td> U+00113 </td> <tr><td> <code title="">empty;</code> </td> <td> U+02205 </td> <tr><td> <code title="">emptyset;</code> </td> <td> U+02205 </td> <tr><td> <code title="">emptyv;</code> </td> <td> U+02205 </td> <tr><td> <code title="">emsp13;</code> </td> <td> U+02004 </td> <tr><td> <code title="">emsp14;</code> </td> <td> U+02005 </td> <tr><td> <code title="">emsp;</code> </td> <td> U+02003 </td> <tr><td> <code title="">eng;</code> </td> <td> U+0014B </td> <tr><td> <code title="">ensp;</code> </td> <td> U+02002 </td> <tr><td> <code title="">eogon;</code> </td> <td> U+00119 </td> <tr><td> <code title="">eopf;</code> </td> <td> U+1D556 </td> <tr><td> <code title="">epar;</code> </td> <td> U+022D5 </td> <tr><td> <code title="">eparsl;</code> </td> <td> U+029E3 </td> <tr><td> <code title="">eplus;</code> </td> <td> U+02A71 </td> <tr><td> <code title="">epsi;</code> </td> <td> U+003B5 </td> <tr><td> <code title="">epsilon;</code> </td> <td> U+003B5 </td> <tr><td> <code title="">epsiv;</code> </td> <td> U+003F5 </td> <tr><td> <code title="">eqcirc;</code> </td> <td> U+02256 </td> <tr><td> <code title="">eqcolon;</code> </td> <td> U+02255 </td> <tr><td> <code title="">eqsim;</code> </td> <td> U+02242 </td> <tr><td> <code title="">eqslantgtr;</code> </td> <td> U+02A96 </td> <tr><td> <code title="">eqslantless;</code> </td> <td> U+02A95 </td> <tr><td> <code title="">equals;</code> </td> <td> U+0003D </td> <tr><td> <code title="">equest;</code> </td> <td> U+0225F </td> <tr><td> <code title="">equiv;</code> </td> <td> U+02261 </td> <tr><td> <code title="">equivDD;</code> </td> <td> U+02A78 </td> <tr><td> <code title="">eqvparsl;</code> </td> <td> U+029E5 </td> <tr><td> <code title="">erDot;</code> </td> <td> U+02253 </td> <tr><td> <code title="">erarr;</code> </td> <td> U+02971 </td> <tr><td> <code title="">escr;</code> </td> <td> U+0212F </td> <tr><td> <code title="">esdot;</code> </td> <td> U+02250 </td> <tr><td> <code title="">esim;</code> </td> <td> U+02242 </td> <tr><td> <code title="">eta;</code> </td> <td> U+003B7 </td> <tr><td> <code title="">eth;</code> </td> <td> U+000F0 </td> <tr><td> <code title="">eth</code> </td> <td> U+000F0 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">euml;</code> </td> <td> U+000EB </td> <tr><td> <code title="">euml</code> </td> <td> U+000EB </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">euro;</code> </td> <td> U+020AC </td> <tr><td> <code title="">excl;</code> </td> <td> U+00021 </td> <tr><td> <code title="">exist;</code> </td> <td> U+02203 </td> <tr><td> <code title="">expectation;</code> </td> <td> U+02130 </td> <tr><td> <code title="">exponentiale;</code> </td> <td> U+02147 </td> <tr><td> <code title="">fallingdotseq;</code> </td> <td> U+02252 </td> <tr><td> <code title="">fcy;</code> </td> <td> U+00444 </td> <tr><td> <code title="">female;</code> </td> <td> U+02640 </td> <tr><td> <code title="">ffilig;</code> </td> <td> U+0FB03 </td> <tr><td> <code title="">fflig;</code> </td> <td> U+0FB00 </td> <tr><td> <code title="">ffllig;</code> </td> <td> U+0FB04 </td> <tr><td> <code title="">ffr;</code> </td> <td> U+1D523 </td> <tr><td> <code title="">filig;</code> </td> <td> U+0FB01 </td> <tr><td> <code title="">flat;</code> </td> <td> U+0266D </td> <tr><td> <code title="">fllig;</code> </td> <td> U+0FB02 </td> <tr><td> <code title="">fltns;</code> </td> <td> U+025B1 </td> <tr><td> <code title="">fnof;</code> </td> <td> U+00192 </td> <tr><td> <code title="">fopf;</code> </td> <td> U+1D557 </td> <tr><td> <code title="">forall;</code> </td> <td> U+02200 </td> <tr><td> <code title="">fork;</code> </td> <td> U+022D4 </td> <tr><td> <code title="">forkv;</code> </td> <td> U+02AD9 </td> <tr><td> <code title="">fpartint;</code> </td> <td> U+02A0D </td> <tr><td> <code title="">frac12;</code> </td> <td> U+000BD </td> <tr><td> <code title="">frac12</code> </td> <td> U+000BD </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">frac13;</code> </td> <td> U+02153 </td> <tr><td> <code title="">frac14;</code> </td> <td> U+000BC </td> <tr><td> <code title="">frac14</code> </td> <td> U+000BC </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">frac15;</code> </td> <td> U+02155 </td> <tr><td> <code title="">frac16;</code> </td> <td> U+02159 </td> <tr><td> <code title="">frac18;</code> </td> <td> U+0215B </td> <tr><td> <code title="">frac23;</code> </td> <td> U+02154 </td> <tr><td> <code title="">frac25;</code> </td> <td> U+02156 </td> <tr><td> <code title="">frac34;</code> </td> <td> U+000BE </td> <tr><td> <code title="">frac34</code> </td> <td> U+000BE </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">frac35;</code> </td> <td> U+02157 </td> <tr><td> <code title="">frac38;</code> </td> <td> U+0215C </td> <tr><td> <code title="">frac45;</code> </td> <td> U+02158 </td> <tr><td> <code title="">frac56;</code> </td> <td> U+0215A </td> <tr><td> <code title="">frac58;</code> </td> <td> U+0215D </td> <tr><td> <code title="">frac78;</code> </td> <td> U+0215E </td> <tr><td> <code title="">frasl;</code> </td> <td> U+02044 </td> <tr><td> <code title="">frown;</code> </td> <td> U+02322 </td> <tr><td> <code title="">fscr;</code> </td> <td> U+1D4BB </td> <tr><td> <code title="">gE;</code> </td> <td> U+02267 </td> <tr><td> <code title="">gEl;</code> </td> <td> U+02A8C </td> <tr><td> <code title="">gacute;</code> </td> <td> U+001F5 </td> <tr><td> <code title="">gamma;</code> </td> <td> U+003B3 </td> <tr><td> <code title="">gammad;</code> </td> <td> U+003DD </td> <tr><td> <code title="">gap;</code> </td> <td> U+02A86 </td> <tr><td> <code title="">gbreve;</code> </td> <td> U+0011F </td> <tr><td> <code title="">gcirc;</code> </td> <td> U+0011D </td> <tr><td> <code title="">gcy;</code> </td> <td> U+00433 </td> <tr><td> <code title="">gdot;</code> </td> <td> U+00121 </td> <tr><td> <code title="">ge;</code> </td> <td> U+02265 </td> <tr><td> <code title="">gel;</code> </td> <td> U+022DB </td> <tr><td> <code title="">geq;</code> </td> <td> U+02265 </td> <tr><td> <code title="">geqq;</code> </td> <td> U+02267 </td> <tr><td> <code title="">geqslant;</code> </td> <td> U+02A7E </td> <tr><td> <code title="">ges;</code> </td> <td> U+02A7E </td> <tr><td> <code title="">gescc;</code> </td> <td> U+02AA9 </td> <tr><td> <code title="">gesdot;</code> </td> <td> U+02A80 </td> <tr><td> <code title="">gesdoto;</code> </td> <td> U+02A82 </td> <tr><td> <code title="">gesdotol;</code> </td> <td> U+02A84 </td> <tr><td> <code title="">gesles;</code> </td> <td> U+02A94 </td> <tr><td> <code title="">gfr;</code> </td> <td> U+1D524 </td> <tr><td> <code title="">gg;</code> </td> <td> U+0226B </td> <tr><td> <code title="">ggg;</code> </td> <td> U+022D9 </td> <tr><td> <code title="">gimel;</code> </td> <td> U+02137 </td> <tr><td> <code title="">gjcy;</code> </td> <td> U+00453 </td> <tr><td> <code title="">gl;</code> </td> <td> U+02277 </td> <tr><td> <code title="">glE;</code> </td> <td> U+02A92 </td> <tr><td> <code title="">gla;</code> </td> <td> U+02AA5 </td> <tr><td> <code title="">glj;</code> </td> <td> U+02AA4 </td> <tr><td> <code title="">gnE;</code> </td> <td> U+02269 </td> <tr><td> <code title="">gnap;</code> </td> <td> U+02A8A </td> <tr><td> <code title="">gnapprox;</code> </td> <td> U+02A8A </td> <tr><td> <code title="">gne;</code> </td> <td> U+02A88 </td> <tr><td> <code title="">gneq;</code> </td> <td> U+02A88 </td> <tr><td> <code title="">gneqq;</code> </td> <td> U+02269 </td> <tr><td> <code title="">gnsim;</code> </td> <td> U+022E7 </td> <tr><td> <code title="">gopf;</code> </td> <td> U+1D558 </td> <tr><td> <code title="">grave;</code> </td> <td> U+00060 </td> <tr><td> <code title="">gscr;</code> </td> <td> U+0210A </td> <tr><td> <code title="">gsim;</code> </td> <td> U+02273 </td> <tr><td> <code title="">gsime;</code> </td> <td> U+02A8E </td> <tr><td> <code title="">gsiml;</code> </td> <td> U+02A90 </td> <tr><td> <code title="">gt;</code> </td> <td> U+0003E </td> <tr><td> <code title="">gt</code> </td> <td> U+0003E </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">gtcc;</code> </td> <td> U+02AA7 </td> <tr><td> <code title="">gtcir;</code> </td> <td> U+02A7A </td> <tr><td> <code title="">gtdot;</code> </td> <td> U+022D7 </td> <tr><td> <code title="">gtlPar;</code> </td> <td> U+02995 </td> <tr><td> <code title="">gtquest;</code> </td> <td> U+02A7C </td> <tr><td> <code title="">gtrapprox;</code> </td> <td> U+02A86 </td> <tr><td> <code title="">gtrarr;</code> </td> <td> U+02978 </td> <tr><td> <code title="">gtrdot;</code> </td> <td> U+022D7 </td> <tr><td> <code title="">gtreqless;</code> </td> <td> U+022DB </td> <tr><td> <code title="">gtreqqless;</code> </td> <td> U+02A8C </td> <tr><td> <code title="">gtrless;</code> </td> <td> U+02277 </td> <tr><td> <code title="">gtrsim;</code> </td> <td> U+02273 </td> <tr><td> <code title="">hArr;</code> </td> <td> U+021D4 </td> <tr><td> <code title="">hairsp;</code> </td> <td> U+0200A </td> <tr><td> <code title="">half;</code> </td> <td> U+000BD </td> <tr><td> <code title="">hamilt;</code> </td> <td> U+0210B </td> <tr><td> <code title="">hardcy;</code> </td> <td> U+0044A </td> <tr><td> <code title="">harr;</code> </td> <td> U+02194 </td> <tr><td> <code title="">harrcir;</code> </td> <td> U+02948 </td> <tr><td> <code title="">harrw;</code> </td> <td> U+021AD </td> <tr><td> <code title="">hbar;</code> </td> <td> U+0210F </td> <tr><td> <code title="">hcirc;</code> </td> <td> U+00125 </td> <tr><td> <code title="">hearts;</code> </td> <td> U+02665 </td> <tr><td> <code title="">heartsuit;</code> </td> <td> U+02665 </td> <tr><td> <code title="">hellip;</code> </td> <td> U+02026 </td> <tr><td> <code title="">hercon;</code> </td> <td> U+022B9 </td> <tr><td> <code title="">hfr;</code> </td> <td> U+1D525 </td> <tr><td> <code title="">hksearow;</code> </td> <td> U+02925 </td> <tr><td> <code title="">hkswarow;</code> </td> <td> U+02926 </td> <tr><td> <code title="">hoarr;</code> </td> <td> U+021FF </td> <tr><td> <code title="">homtht;</code> </td> <td> U+0223B </td> <tr><td> <code title="">hookleftarrow;</code> </td> <td> U+021A9 </td> <tr><td> <code title="">hookrightarrow;</code> </td> <td> U+021AA </td> <tr><td> <code title="">hopf;</code> </td> <td> U+1D559 </td> <tr><td> <code title="">horbar;</code> </td> <td> U+02015 </td> <tr><td> <code title="">hscr;</code> </td> <td> U+1D4BD </td> <tr><td> <code title="">hslash;</code> </td> <td> U+0210F </td> <tr><td> <code title="">hstrok;</code> </td> <td> U+00127 </td> <tr><td> <code title="">hybull;</code> </td> <td> U+02043 </td> <tr><td> <code title="">hyphen;</code> </td> <td> U+02010 </td> <tr><td> <code title="">iacute;</code> </td> <td> U+000ED </td> <tr><td> <code title="">iacute</code> </td> <td> U+000ED </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">ic;</code> </td> <td> U+02063 </td> <tr><td> <code title="">icirc;</code> </td> <td> U+000EE </td> <tr><td> <code title="">icirc</code> </td> <td> U+000EE </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">icy;</code> </td> <td> U+00438 </td> <tr><td> <code title="">iecy;</code> </td> <td> U+00435 </td> <tr><td> <code title="">iexcl;</code> </td> <td> U+000A1 </td> <tr><td> <code title="">iexcl</code> </td> <td> U+000A1 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">iff;</code> </td> <td> U+021D4 </td> <tr><td> <code title="">ifr;</code> </td> <td> U+1D526 </td> <tr><td> <code title="">igrave;</code> </td> <td> U+000EC </td> <tr><td> <code title="">igrave</code> </td> <td> U+000EC </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">ii;</code> </td> <td> U+02148 </td> <tr><td> <code title="">iiiint;</code> </td> <td> U+02A0C </td> <tr><td> <code title="">iiint;</code> </td> <td> U+0222D </td> <tr><td> <code title="">iinfin;</code> </td> <td> U+029DC </td> <tr><td> <code title="">iiota;</code> </td> <td> U+02129 </td> <tr><td> <code title="">ijlig;</code> </td> <td> U+00133 </td> <tr><td> <code title="">imacr;</code> </td> <td> U+0012B </td> <tr><td> <code title="">image;</code> </td> <td> U+02111 </td> <tr><td> <code title="">imagline;</code> </td> <td> U+02110 </td> <tr><td> <code title="">imagpart;</code> </td> <td> U+02111 </td> <tr><td> <code title="">imath;</code> </td> <td> U+00131 </td> <tr><td> <code title="">imof;</code> </td> <td> U+022B7 </td> <tr><td> <code title="">imped;</code> </td> <td> U+001B5 </td> <tr><td> <code title="">in;</code> </td> <td> U+02208 </td> <tr><td> <code title="">incare;</code> </td> <td> U+02105 </td> <tr><td> <code title="">infin;</code> </td> <td> U+0221E </td> <tr><td> <code title="">infintie;</code> </td> <td> U+029DD </td> <tr><td> <code title="">inodot;</code> </td> <td> U+00131 </td> <tr><td> <code title="">int;</code> </td> <td> U+0222B </td> <tr><td> <code title="">intcal;</code> </td> <td> U+022BA </td> <tr><td> <code title="">integers;</code> </td> <td> U+02124 </td> <tr><td> <code title="">intercal;</code> </td> <td> U+022BA </td> <tr><td> <code title="">intlarhk;</code> </td> <td> U+02A17 </td> <tr><td> <code title="">intprod;</code> </td> <td> U+02A3C </td> <tr><td> <code title="">iocy;</code> </td> <td> U+00451 </td> <tr><td> <code title="">iogon;</code> </td> <td> U+0012F </td> <tr><td> <code title="">iopf;</code> </td> <td> U+1D55A </td> <tr><td> <code title="">iota;</code> </td> <td> U+003B9 </td> <tr><td> <code title="">iprod;</code> </td> <td> U+02A3C </td> <tr><td> <code title="">iquest;</code> </td> <td> U+000BF </td> <tr><td> <code title="">iquest</code> </td> <td> U+000BF </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">iscr;</code> </td> <td> U+1D4BE </td> <tr><td> <code title="">isin;</code> </td> <td> U+02208 </td> <tr><td> <code title="">isinE;</code> </td> <td> U+022F9 </td> <tr><td> <code title="">isindot;</code> </td> <td> U+022F5 </td> <tr><td> <code title="">isins;</code> </td> <td> U+022F4 </td> <tr><td> <code title="">isinsv;</code> </td> <td> U+022F3 </td> <tr><td> <code title="">isinv;</code> </td> <td> U+02208 </td> <tr><td> <code title="">it;</code> </td> <td> U+02062 </td> <tr><td> <code title="">itilde;</code> </td> <td> U+00129 </td> <tr><td> <code title="">iukcy;</code> </td> <td> U+00456 </td> <tr><td> <code title="">iuml;</code> </td> <td> U+000EF </td> <tr><td> <code title="">iuml</code> </td> <td> U+000EF </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">jcirc;</code> </td> <td> U+00135 </td> <tr><td> <code title="">jcy;</code> </td> <td> U+00439 </td> <tr><td> <code title="">jfr;</code> </td> <td> U+1D527 </td> <tr><td> <code title="">jmath;</code> </td> <td> U+00237 </td> <tr><td> <code title="">jopf;</code> </td> <td> U+1D55B </td> <tr><td> <code title="">jscr;</code> </td> <td> U+1D4BF </td> <tr><td> <code title="">jsercy;</code> </td> <td> U+00458 </td> <tr><td> <code title="">jukcy;</code> </td> <td> U+00454 </td> <tr><td> <code title="">kappa;</code> </td> <td> U+003BA </td> <tr><td> <code title="">kappav;</code> </td> <td> U+003F0 </td> <tr><td> <code title="">kcedil;</code> </td> <td> U+00137 </td> <tr><td> <code title="">kcy;</code> </td> <td> U+0043A </td> <tr><td> <code title="">kfr;</code> </td> <td> U+1D528 </td> <tr><td> <code title="">kgreen;</code> </td> <td> U+00138 </td> <tr><td> <code title="">khcy;</code> </td> <td> U+00445 </td> <tr><td> <code title="">kjcy;</code> </td> <td> U+0045C </td> <tr><td> <code title="">kopf;</code> </td> <td> U+1D55C </td> <tr><td> <code title="">kscr;</code> </td> <td> U+1D4C0 </td> <tr><td> <code title="">lAarr;</code> </td> <td> U+021DA </td> <tr><td> <code title="">lArr;</code> </td> <td> U+021D0 </td> <tr><td> <code title="">lAtail;</code> </td> <td> U+0291B </td> <tr><td> <code title="">lBarr;</code> </td> <td> U+0290E </td> <tr><td> <code title="">lE;</code> </td> <td> U+02266 </td> <tr><td> <code title="">lEg;</code> </td> <td> U+02A8B </td> <tr><td> <code title="">lHar;</code> </td> <td> U+02962 </td> <tr><td> <code title="">lacute;</code> </td> <td> U+0013A </td> <tr><td> <code title="">laemptyv;</code> </td> <td> U+029B4 </td> <tr><td> <code title="">lagran;</code> </td> <td> U+02112 </td> <tr><td> <code title="">lambda;</code> </td> <td> U+003BB </td> <tr><td> <code title="">lang;</code> </td> <td> U+027E8 </td> <tr><td> <code title="">langd;</code> </td> <td> U+02991 </td> <tr><td> <code title="">langle;</code> </td> <td> U+027E8 </td> <tr><td> <code title="">lap;</code> </td> <td> U+02A85 </td> <tr><td> <code title="">laquo;</code> </td> <td> U+000AB </td> <tr><td> <code title="">laquo</code> </td> <td> U+000AB </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">larr;</code> </td> <td> U+02190 </td> <tr><td> <code title="">larrb;</code> </td> <td> U+021E4 </td> <tr><td> <code title="">larrbfs;</code> </td> <td> U+0291F </td> <tr><td> <code title="">larrfs;</code> </td> <td> U+0291D </td> <tr><td> <code title="">larrhk;</code> </td> <td> U+021A9 </td> <tr><td> <code title="">larrlp;</code> </td> <td> U+021AB </td> <tr><td> <code title="">larrpl;</code> </td> <td> U+02939 </td> <tr><td> <code title="">larrsim;</code> </td> <td> U+02973 </td> <tr><td> <code title="">larrtl;</code> </td> <td> U+021A2 </td> <tr><td> <code title="">lat;</code> </td> <td> U+02AAB </td> <tr><td> <code title="">latail;</code> </td> <td> U+02919 </td> <tr><td> <code title="">late;</code> </td> <td> U+02AAD </td> <tr><td> <code title="">lbarr;</code> </td> <td> U+0290C </td> <tr><td> <code title="">lbbrk;</code> </td> <td> U+02772 </td> <tr><td> <code title="">lbrace;</code> </td> <td> U+0007B </td> <tr><td> <code title="">lbrack;</code> </td> <td> U+0005B </td> <tr><td> <code title="">lbrke;</code> </td> <td> U+0298B </td> <tr><td> <code title="">lbrksld;</code> </td> <td> U+0298F </td> <tr><td> <code title="">lbrkslu;</code> </td> <td> U+0298D </td> <tr><td> <code title="">lcaron;</code> </td> <td> U+0013E </td> <tr><td> <code title="">lcedil;</code> </td> <td> U+0013C </td> <tr><td> <code title="">lceil;</code> </td> <td> U+02308 </td> <tr><td> <code title="">lcub;</code> </td> <td> U+0007B </td> <tr><td> <code title="">lcy;</code> </td> <td> U+0043B </td> <tr><td> <code title="">ldca;</code> </td> <td> U+02936 </td> <tr><td> <code title="">ldquo;</code> </td> <td> U+0201C </td> <tr><td> <code title="">ldquor;</code> </td> <td> U+0201E </td> <tr><td> <code title="">ldrdhar;</code> </td> <td> U+02967 </td> <tr><td> <code title="">ldrushar;</code> </td> <td> U+0294B </td> <tr><td> <code title="">ldsh;</code> </td> <td> U+021B2 </td> <tr><td> <code title="">le;</code> </td> <td> U+02264 </td> <tr><td> <code title="">leftarrow;</code> </td> <td> U+02190 </td> <tr><td> <code title="">leftarrowtail;</code> </td> <td> U+021A2 </td> <tr><td> <code title="">leftharpoondown;</code> </td> <td> U+021BD </td> <tr><td> <code title="">leftharpoonup;</code> </td> <td> U+021BC </td> <tr><td> <code title="">leftleftarrows;</code> </td> <td> U+021C7 </td> <tr><td> <code title="">leftrightarrow;</code> </td> <td> U+02194 </td> <tr><td> <code title="">leftrightarrows;</code> </td> <td> U+021C6 </td> <tr><td> <code title="">leftrightharpoons;</code> </td> <td> U+021CB </td> <tr><td> <code title="">leftrightsquigarrow;</code> </td> <td> U+021AD </td> <tr><td> <code title="">leftthreetimes;</code> </td> <td> U+022CB </td> <tr><td> <code title="">leg;</code> </td> <td> U+022DA </td> <tr><td> <code title="">leq;</code> </td> <td> U+02264 </td> <tr><td> <code title="">leqq;</code> </td> <td> U+02266 </td> <tr><td> <code title="">leqslant;</code> </td> <td> U+02A7D </td> <tr><td> <code title="">les;</code> </td> <td> U+02A7D </td> <tr><td> <code title="">lescc;</code> </td> <td> U+02AA8 </td> <tr><td> <code title="">lesdot;</code> </td> <td> U+02A7F </td> <tr><td> <code title="">lesdoto;</code> </td> <td> U+02A81 </td> <tr><td> <code title="">lesdotor;</code> </td> <td> U+02A83 </td> <tr><td> <code title="">lesges;</code> </td> <td> U+02A93 </td> <tr><td> <code title="">lessapprox;</code> </td> <td> U+02A85 </td> <tr><td> <code title="">lessdot;</code> </td> <td> U+022D6 </td> <tr><td> <code title="">lesseqgtr;</code> </td> <td> U+022DA </td> <tr><td> <code title="">lesseqqgtr;</code> </td> <td> U+02A8B </td> <tr><td> <code title="">lessgtr;</code> </td> <td> U+02276 </td> <tr><td> <code title="">lesssim;</code> </td> <td> U+02272 </td> <tr><td> <code title="">lfisht;</code> </td> <td> U+0297C </td> <tr><td> <code title="">lfloor;</code> </td> <td> U+0230A </td> <tr><td> <code title="">lfr;</code> </td> <td> U+1D529 </td> <tr><td> <code title="">lg;</code> </td> <td> U+02276 </td> <tr><td> <code title="">lgE;</code> </td> <td> U+02A91 </td> <tr><td> <code title="">lhard;</code> </td> <td> U+021BD </td> <tr><td> <code title="">lharu;</code> </td> <td> U+021BC </td> <tr><td> <code title="">lharul;</code> </td> <td> U+0296A </td> <tr><td> <code title="">lhblk;</code> </td> <td> U+02584 </td> <tr><td> <code title="">ljcy;</code> </td> <td> U+00459 </td> <tr><td> <code title="">ll;</code> </td> <td> U+0226A </td> <tr><td> <code title="">llarr;</code> </td> <td> U+021C7 </td> <tr><td> <code title="">llcorner;</code> </td> <td> U+0231E </td> <tr><td> <code title="">llhard;</code> </td> <td> U+0296B </td> <tr><td> <code title="">lltri;</code> </td> <td> U+025FA </td> <tr><td> <code title="">lmidot;</code> </td> <td> U+00140 </td> <tr><td> <code title="">lmoust;</code> </td> <td> U+023B0 </td> <tr><td> <code title="">lmoustache;</code> </td> <td> U+023B0 </td> <tr><td> <code title="">lnE;</code> </td> <td> U+02268 </td> <tr><td> <code title="">lnap;</code> </td> <td> U+02A89 </td> <tr><td> <code title="">lnapprox;</code> </td> <td> U+02A89 </td> <tr><td> <code title="">lne;</code> </td> <td> U+02A87 </td> <tr><td> <code title="">lneq;</code> </td> <td> U+02A87 </td> <tr><td> <code title="">lneqq;</code> </td> <td> U+02268 </td> <tr><td> <code title="">lnsim;</code> </td> <td> U+022E6 </td> <tr><td> <code title="">loang;</code> </td> <td> U+027EC </td> <tr><td> <code title="">loarr;</code> </td> <td> U+021FD </td> <tr><td> <code title="">lobrk;</code> </td> <td> U+027E6 </td> <tr><td> <code title="">longleftarrow;</code> </td> <td> U+027F5 </td> <tr><td> <code title="">longleftrightarrow;</code> </td> <td> U+027F7 </td> <tr><td> <code title="">longmapsto;</code> </td> <td> U+027FC </td> <tr><td> <code title="">longrightarrow;</code> </td> <td> U+027F6 </td> <tr><td> <code title="">looparrowleft;</code> </td> <td> U+021AB </td> <tr><td> <code title="">looparrowright;</code> </td> <td> U+021AC </td> <tr><td> <code title="">lopar;</code> </td> <td> U+02985 </td> <tr><td> <code title="">lopf;</code> </td> <td> U+1D55D </td> <tr><td> <code title="">loplus;</code> </td> <td> U+02A2D </td> <tr><td> <code title="">lotimes;</code> </td> <td> U+02A34 </td> <tr><td> <code title="">lowast;</code> </td> <td> U+02217 </td> <tr><td> <code title="">lowbar;</code> </td> <td> U+0005F </td> <tr><td> <code title="">loz;</code> </td> <td> U+025CA </td> <tr><td> <code title="">lozenge;</code> </td> <td> U+025CA </td> <tr><td> <code title="">lozf;</code> </td> <td> U+029EB </td> <tr><td> <code title="">lpar;</code> </td> <td> U+00028 </td> <tr><td> <code title="">lparlt;</code> </td> <td> U+02993 </td> <tr><td> <code title="">lrarr;</code> </td> <td> U+021C6 </td> <tr><td> <code title="">lrcorner;</code> </td> <td> U+0231F </td> <tr><td> <code title="">lrhar;</code> </td> <td> U+021CB </td> <tr><td> <code title="">lrhard;</code> </td> <td> U+0296D </td> <tr><td> <code title="">lrm;</code> </td> <td> U+0200E </td> <tr><td> <code title="">lrtri;</code> </td> <td> U+022BF </td> <tr><td> <code title="">lsaquo;</code> </td> <td> U+02039 </td> <tr><td> <code title="">lscr;</code> </td> <td> U+1D4C1 </td> <tr><td> <code title="">lsh;</code> </td> <td> U+021B0 </td> <tr><td> <code title="">lsim;</code> </td> <td> U+02272 </td> <tr><td> <code title="">lsime;</code> </td> <td> U+02A8D </td> <tr><td> <code title="">lsimg;</code> </td> <td> U+02A8F </td> <tr><td> <code title="">lsqb;</code> </td> <td> U+0005B </td> <tr><td> <code title="">lsquo;</code> </td> <td> U+02018 </td> <tr><td> <code title="">lsquor;</code> </td> <td> U+0201A </td> <tr><td> <code title="">lstrok;</code> </td> <td> U+00142 </td> <tr><td> <code title="">lt;</code> </td> <td> U+0003C </td> <tr><td> <code title="">lt</code> </td> <td> U+0003C </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">ltcc;</code> </td> <td> U+02AA6 </td> <tr><td> <code title="">ltcir;</code> </td> <td> U+02A79 </td> <tr><td> <code title="">ltdot;</code> </td> <td> U+022D6 </td> <tr><td> <code title="">lthree;</code> </td> <td> U+022CB </td> <tr><td> <code title="">ltimes;</code> </td> <td> U+022C9 </td> <tr><td> <code title="">ltlarr;</code> </td> <td> U+02976 </td> <tr><td> <code title="">ltquest;</code> </td> <td> U+02A7B </td> <tr><td> <code title="">ltrPar;</code> </td> <td> U+02996 </td> <tr><td> <code title="">ltri;</code> </td> <td> U+025C3 </td> <tr><td> <code title="">ltrie;</code> </td> <td> U+022B4 </td> <tr><td> <code title="">ltrif;</code> </td> <td> U+025C2 </td> <tr><td> <code title="">lurdshar;</code> </td> <td> U+0294A </td> <tr><td> <code title="">luruhar;</code> </td> <td> U+02966 </td> <tr><td> <code title="">mDDot;</code> </td> <td> U+0223A </td> <tr><td> <code title="">macr;</code> </td> <td> U+000AF </td> <tr><td> <code title="">macr</code> </td> <td> U+000AF </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">male;</code> </td> <td> U+02642 </td> <tr><td> <code title="">malt;</code> </td> <td> U+02720 </td> <tr><td> <code title="">maltese;</code> </td> <td> U+02720 </td> <tr><td> <code title="">map;</code> </td> <td> U+021A6 </td> <tr><td> <code title="">mapsto;</code> </td> <td> U+021A6 </td> <tr><td> <code title="">mapstodown;</code> </td> <td> U+021A7 </td> <tr><td> <code title="">mapstoleft;</code> </td> <td> U+021A4 </td> <tr><td> <code title="">mapstoup;</code> </td> <td> U+021A5 </td> <tr><td> <code title="">marker;</code> </td> <td> U+025AE </td> <tr><td> <code title="">mcomma;</code> </td> <td> U+02A29 </td> <tr><td> <code title="">mcy;</code> </td> <td> U+0043C </td> <tr><td> <code title="">mdash;</code> </td> <td> U+02014 </td> <tr><td> <code title="">measuredangle;</code> </td> <td> U+02221 </td> <tr><td> <code title="">mfr;</code> </td> <td> U+1D52A </td> <tr><td> <code title="">mho;</code> </td> <td> U+02127 </td> <tr><td> <code title="">micro;</code> </td> <td> U+000B5 </td> <tr><td> <code title="">micro</code> </td> <td> U+000B5 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">mid;</code> </td> <td> U+02223 </td> <tr><td> <code title="">midast;</code> </td> <td> U+0002A </td> <tr><td> <code title="">midcir;</code> </td> <td> U+02AF0 </td> <tr><td> <code title="">middot;</code> </td> <td> U+000B7 </td> <tr><td> <code title="">middot</code> </td> <td> U+000B7 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">minus;</code> </td> <td> U+02212 </td> <tr><td> <code title="">minusb;</code> </td> <td> U+0229F </td> <tr><td> <code title="">minusd;</code> </td> <td> U+02238 </td> <tr><td> <code title="">minusdu;</code> </td> <td> U+02A2A </td> <tr><td> <code title="">mlcp;</code> </td> <td> U+02ADB </td> <tr><td> <code title="">mldr;</code> </td> <td> U+02026 </td> <tr><td> <code title="">mnplus;</code> </td> <td> U+02213 </td> <tr><td> <code title="">models;</code> </td> <td> U+022A7 </td> <tr><td> <code title="">mopf;</code> </td> <td> U+1D55E </td> <tr><td> <code title="">mp;</code> </td> <td> U+02213 </td> <tr><td> <code title="">mscr;</code> </td> <td> U+1D4C2 </td> <tr><td> <code title="">mstpos;</code> </td> <td> U+0223E </td> <tr><td> <code title="">mu;</code> </td> <td> U+003BC </td> <tr><td> <code title="">multimap;</code> </td> <td> U+022B8 </td> <tr><td> <code title="">mumap;</code> </td> <td> U+022B8 </td> <tr><td> <code title="">nLeftarrow;</code> </td> <td> U+021CD </td> <tr><td> <code title="">nLeftrightarrow;</code> </td> <td> U+021CE </td> <tr><td> <code title="">nRightarrow;</code> </td> <td> U+021CF </td> <tr><td> <code title="">nVDash;</code> </td> <td> U+022AF </td> <tr><td> <code title="">nVdash;</code> </td> <td> U+022AE </td> <tr><td> <code title="">nabla;</code> </td> <td> U+02207 </td> <tr><td> <code title="">nacute;</code> </td> <td> U+00144 </td> <tr><td> <code title="">nap;</code> </td> <td> U+02249 </td> <tr><td> <code title="">napos;</code> </td> <td> U+00149 </td> <tr><td> <code title="">napprox;</code> </td> <td> U+02249 </td> <tr><td> <code title="">natur;</code> </td> <td> U+0266E </td> <tr><td> <code title="">natural;</code> </td> <td> U+0266E </td> <tr><td> <code title="">naturals;</code> </td> <td> U+02115 </td> <tr><td> <code title="">nbsp;</code> </td> <td> U+000A0 </td> <tr><td> <code title="">nbsp</code> </td> <td> U+000A0 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">ncap;</code> </td> <td> U+02A43 </td> <tr><td> <code title="">ncaron;</code> </td> <td> U+00148 </td> <tr><td> <code title="">ncedil;</code> </td> <td> U+00146 </td> <tr><td> <code title="">ncong;</code> </td> <td> U+02247 </td> <tr><td> <code title="">ncup;</code> </td> <td> U+02A42 </td> <tr><td> <code title="">ncy;</code> </td> <td> U+0043D </td> <tr><td> <code title="">ndash;</code> </td> <td> U+02013 </td> <tr><td> <code title="">ne;</code> </td> <td> U+02260 </td> <tr><td> <code title="">neArr;</code> </td> <td> U+021D7 </td> <tr><td> <code title="">nearhk;</code> </td> <td> U+02924 </td> <tr><td> <code title="">nearr;</code> </td> <td> U+02197 </td> <tr><td> <code title="">nearrow;</code> </td> <td> U+02197 </td> <tr><td> <code title="">nequiv;</code> </td> <td> U+02262 </td> <tr><td> <code title="">nesear;</code> </td> <td> U+02928 </td> <tr><td> <code title="">nexist;</code> </td> <td> U+02204 </td> <tr><td> <code title="">nexists;</code> </td> <td> U+02204 </td> <tr><td> <code title="">nfr;</code> </td> <td> U+1D52B </td> <tr><td> <code title="">nge;</code> </td> <td> U+02271 </td> <tr><td> <code title="">ngeq;</code> </td> <td> U+02271 </td> <tr><td> <code title="">ngsim;</code> </td> <td> U+02275 </td> <tr><td> <code title="">ngt;</code> </td> <td> U+0226F </td> <tr><td> <code title="">ngtr;</code> </td> <td> U+0226F </td> <tr><td> <code title="">nhArr;</code> </td> <td> U+021CE </td> <tr><td> <code title="">nharr;</code> </td> <td> U+021AE </td> <tr><td> <code title="">nhpar;</code> </td> <td> U+02AF2 </td> <tr><td> <code title="">ni;</code> </td> <td> U+0220B </td> <tr><td> <code title="">nis;</code> </td> <td> U+022FC </td> <tr><td> <code title="">nisd;</code> </td> <td> U+022FA </td> <tr><td> <code title="">niv;</code> </td> <td> U+0220B </td> <tr><td> <code title="">njcy;</code> </td> <td> U+0045A </td> <tr><td> <code title="">nlArr;</code> </td> <td> U+021CD </td> <tr><td> <code title="">nlarr;</code> </td> <td> U+0219A </td> <tr><td> <code title="">nldr;</code> </td> <td> U+02025 </td> <tr><td> <code title="">nle;</code> </td> <td> U+02270 </td> <tr><td> <code title="">nleftarrow;</code> </td> <td> U+0219A </td> <tr><td> <code title="">nleftrightarrow;</code> </td> <td> U+021AE </td> <tr><td> <code title="">nleq;</code> </td> <td> U+02270 </td> <tr><td> <code title="">nless;</code> </td> <td> U+0226E </td> <tr><td> <code title="">nlsim;</code> </td> <td> U+02274 </td> <tr><td> <code title="">nlt;</code> </td> <td> U+0226E </td> <tr><td> <code title="">nltri;</code> </td> <td> U+022EA </td> <tr><td> <code title="">nltrie;</code> </td> <td> U+022EC </td> <tr><td> <code title="">nmid;</code> </td> <td> U+02224 </td> <tr><td> <code title="">nopf;</code> </td> <td> U+1D55F </td> <tr><td> <code title="">not;</code> </td> <td> U+000AC </td> <tr><td> <code title="">not</code> </td> <td> U+000AC </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">notin;</code> </td> <td> U+02209 </td> <tr><td> <code title="">notinva;</code> </td> <td> U+02209 </td> <tr><td> <code title="">notinvb;</code> </td> <td> U+022F7 </td> <tr><td> <code title="">notinvc;</code> </td> <td> U+022F6 </td> <tr><td> <code title="">notni;</code> </td> <td> U+0220C </td> <tr><td> <code title="">notniva;</code> </td> <td> U+0220C </td> <tr><td> <code title="">notnivb;</code> </td> <td> U+022FE </td> <tr><td> <code title="">notnivc;</code> </td> <td> U+022FD </td> <tr><td> <code title="">npar;</code> </td> <td> U+02226 </td> <tr><td> <code title="">nparallel;</code> </td> <td> U+02226 </td> <tr><td> <code title="">npolint;</code> </td> <td> U+02A14 </td> <tr><td> <code title="">npr;</code> </td> <td> U+02280 </td> <tr><td> <code title="">nprcue;</code> </td> <td> U+022E0 </td> <tr><td> <code title="">nprec;</code> </td> <td> U+02280 </td> <tr><td> <code title="">nrArr;</code> </td> <td> U+021CF </td> <tr><td> <code title="">nrarr;</code> </td> <td> U+0219B </td> <tr><td> <code title="">nrightarrow;</code> </td> <td> U+0219B </td> <tr><td> <code title="">nrtri;</code> </td> <td> U+022EB </td> <tr><td> <code title="">nrtrie;</code> </td> <td> U+022ED </td> <tr><td> <code title="">nsc;</code> </td> <td> U+02281 </td> <tr><td> <code title="">nsccue;</code> </td> <td> U+022E1 </td> <tr><td> <code title="">nscr;</code> </td> <td> U+1D4C3 </td> <tr><td> <code title="">nshortmid;</code> </td> <td> U+02224 </td> <tr><td> <code title="">nshortparallel;</code> </td> <td> U+02226 </td> <tr><td> <code title="">nsim;</code> </td> <td> U+02241 </td> <tr><td> <code title="">nsime;</code> </td> <td> U+02244 </td> <tr><td> <code title="">nsimeq;</code> </td> <td> U+02244 </td> <tr><td> <code title="">nsmid;</code> </td> <td> U+02224 </td> <tr><td> <code title="">nspar;</code> </td> <td> U+02226 </td> <tr><td> <code title="">nsqsube;</code> </td> <td> U+022E2 </td> <tr><td> <code title="">nsqsupe;</code> </td> <td> U+022E3 </td> <tr><td> <code title="">nsub;</code> </td> <td> U+02284 </td> <tr><td> <code title="">nsube;</code> </td> <td> U+02288 </td> <tr><td> <code title="">nsubseteq;</code> </td> <td> U+02288 </td> <tr><td> <code title="">nsucc;</code> </td> <td> U+02281 </td> <tr><td> <code title="">nsup;</code> </td> <td> U+02285 </td> <tr><td> <code title="">nsupe;</code> </td> <td> U+02289 </td> <tr><td> <code title="">nsupseteq;</code> </td> <td> U+02289 </td> <tr><td> <code title="">ntgl;</code> </td> <td> U+02279 </td> <tr><td> <code title="">ntilde;</code> </td> <td> U+000F1 </td> <tr><td> <code title="">ntilde</code> </td> <td> U+000F1 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">ntlg;</code> </td> <td> U+02278 </td> <tr><td> <code title="">ntriangleleft;</code> </td> <td> U+022EA </td> <tr><td> <code title="">ntrianglelefteq;</code> </td> <td> U+022EC </td> <tr><td> <code title="">ntriangleright;</code> </td> <td> U+022EB </td> <tr><td> <code title="">ntrianglerighteq;</code> </td> <td> U+022ED </td> <tr><td> <code title="">nu;</code> </td> <td> U+003BD </td> <tr><td> <code title="">num;</code> </td> <td> U+00023 </td> <tr><td> <code title="">numero;</code> </td> <td> U+02116 </td> <tr><td> <code title="">numsp;</code> </td> <td> U+02007 </td> <tr><td> <code title="">nvDash;</code> </td> <td> U+022AD </td> <tr><td> <code title="">nvHarr;</code> </td> <td> U+02904 </td> <tr><td> <code title="">nvdash;</code> </td> <td> U+022AC </td> <tr><td> <code title="">nvinfin;</code> </td> <td> U+029DE </td> <tr><td> <code title="">nvlArr;</code> </td> <td> U+02902 </td> <tr><td> <code title="">nvrArr;</code> </td> <td> U+02903 </td> <tr><td> <code title="">nwArr;</code> </td> <td> U+021D6 </td> <tr><td> <code title="">nwarhk;</code> </td> <td> U+02923 </td> <tr><td> <code title="">nwarr;</code> </td> <td> U+02196 </td> <tr><td> <code title="">nwarrow;</code> </td> <td> U+02196 </td> <tr><td> <code title="">nwnear;</code> </td> <td> U+02927 </td> <tr><td> <code title="">oS;</code> </td> <td> U+024C8 </td> <tr><td> <code title="">oacute;</code> </td> <td> U+000F3 </td> <tr><td> <code title="">oacute</code> </td> <td> U+000F3 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">oast;</code> </td> <td> U+0229B </td> <tr><td> <code title="">ocir;</code> </td> <td> U+0229A </td> <tr><td> <code title="">ocirc;</code> </td> <td> U+000F4 </td> <tr><td> <code title="">ocirc</code> </td> <td> U+000F4 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">ocy;</code> </td> <td> U+0043E </td> <tr><td> <code title="">odash;</code> </td> <td> U+0229D </td> <tr><td> <code title="">odblac;</code> </td> <td> U+00151 </td> <tr><td> <code title="">odiv;</code> </td> <td> U+02A38 </td> <tr><td> <code title="">odot;</code> </td> <td> U+02299 </td> <tr><td> <code title="">odsold;</code> </td> <td> U+029BC </td> <tr><td> <code title="">oelig;</code> </td> <td> U+00153 </td> <tr><td> <code title="">ofcir;</code> </td> <td> U+029BF </td> <tr><td> <code title="">ofr;</code> </td> <td> U+1D52C </td> <tr><td> <code title="">ogon;</code> </td> <td> U+002DB </td> <tr><td> <code title="">ograve;</code> </td> <td> U+000F2 </td> <tr><td> <code title="">ograve</code> </td> <td> U+000F2 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">ogt;</code> </td> <td> U+029C1 </td> <tr><td> <code title="">ohbar;</code> </td> <td> U+029B5 </td> <tr><td> <code title="">ohm;</code> </td> <td> U+003A9 </td> <tr><td> <code title="">oint;</code> </td> <td> U+0222E </td> <tr><td> <code title="">olarr;</code> </td> <td> U+021BA </td> <tr><td> <code title="">olcir;</code> </td> <td> U+029BE </td> <tr><td> <code title="">olcross;</code> </td> <td> U+029BB </td> <tr><td> <code title="">oline;</code> </td> <td> U+0203E </td> <tr><td> <code title="">olt;</code> </td> <td> U+029C0 </td> <tr><td> <code title="">omacr;</code> </td> <td> U+0014D </td> <tr><td> <code title="">omega;</code> </td> <td> U+003C9 </td> <tr><td> <code title="">omicron;</code> </td> <td> U+003BF </td> <tr><td> <code title="">omid;</code> </td> <td> U+029B6 </td> <tr><td> <code title="">ominus;</code> </td> <td> U+02296 </td> <tr><td> <code title="">oopf;</code> </td> <td> U+1D560 </td> <tr><td> <code title="">opar;</code> </td> <td> U+029B7 </td> <tr><td> <code title="">operp;</code> </td> <td> U+029B9 </td> <tr><td> <code title="">oplus;</code> </td> <td> U+02295 </td> <tr><td> <code title="">or;</code> </td> <td> U+02228 </td> <tr><td> <code title="">orarr;</code> </td> <td> U+021BB </td> <tr><td> <code title="">ord;</code> </td> <td> U+02A5D </td> <tr><td> <code title="">order;</code> </td> <td> U+02134 </td> <tr><td> <code title="">orderof;</code> </td> <td> U+02134 </td> <tr><td> <code title="">ordf;</code> </td> <td> U+000AA </td> <tr><td> <code title="">ordf</code> </td> <td> U+000AA </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">ordm;</code> </td> <td> U+000BA </td> <tr><td> <code title="">ordm</code> </td> <td> U+000BA </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">origof;</code> </td> <td> U+022B6 </td> <tr><td> <code title="">oror;</code> </td> <td> U+02A56 </td> <tr><td> <code title="">orslope;</code> </td> <td> U+02A57 </td> <tr><td> <code title="">orv;</code> </td> <td> U+02A5B </td> <tr><td> <code title="">oscr;</code> </td> <td> U+02134 </td> <tr><td> <code title="">oslash;</code> </td> <td> U+000F8 </td> <tr><td> <code title="">oslash</code> </td> <td> U+000F8 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">osol;</code> </td> <td> U+02298 </td> <tr><td> <code title="">otilde;</code> </td> <td> U+000F5 </td> <tr><td> <code title="">otilde</code> </td> <td> U+000F5 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">otimes;</code> </td> <td> U+02297 </td> <tr><td> <code title="">otimesas;</code> </td> <td> U+02A36 </td> <tr><td> <code title="">ouml;</code> </td> <td> U+000F6 </td> <tr><td> <code title="">ouml</code> </td> <td> U+000F6 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">ovbar;</code> </td> <td> U+0233D </td> <tr><td> <code title="">par;</code> </td> <td> U+02225 </td> <tr><td> <code title="">para;</code> </td> <td> U+000B6 </td> <tr><td> <code title="">para</code> </td> <td> U+000B6 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">parallel;</code> </td> <td> U+02225 </td> <tr><td> <code title="">parsim;</code> </td> <td> U+02AF3 </td> <tr><td> <code title="">parsl;</code> </td> <td> U+02AFD </td> <tr><td> <code title="">part;</code> </td> <td> U+02202 </td> <tr><td> <code title="">pcy;</code> </td> <td> U+0043F </td> <tr><td> <code title="">percnt;</code> </td> <td> U+00025 </td> <tr><td> <code title="">period;</code> </td> <td> U+0002E </td> <tr><td> <code title="">permil;</code> </td> <td> U+02030 </td> <tr><td> <code title="">perp;</code> </td> <td> U+022A5 </td> <tr><td> <code title="">pertenk;</code> </td> <td> U+02031 </td> <tr><td> <code title="">pfr;</code> </td> <td> U+1D52D </td> <tr><td> <code title="">phi;</code> </td> <td> U+003C6 </td> <tr><td> <code title="">phiv;</code> </td> <td> U+003D5 </td> <tr><td> <code title="">phmmat;</code> </td> <td> U+02133 </td> <tr><td> <code title="">phone;</code> </td> <td> U+0260E </td> <tr><td> <code title="">pi;</code> </td> <td> U+003C0 </td> <tr><td> <code title="">pitchfork;</code> </td> <td> U+022D4 </td> <tr><td> <code title="">piv;</code> </td> <td> U+003D6 </td> <tr><td> <code title="">planck;</code> </td> <td> U+0210F </td> <tr><td> <code title="">planckh;</code> </td> <td> U+0210E </td> <tr><td> <code title="">plankv;</code> </td> <td> U+0210F </td> <tr><td> <code title="">plus;</code> </td> <td> U+0002B </td> <tr><td> <code title="">plusacir;</code> </td> <td> U+02A23 </td> <tr><td> <code title="">plusb;</code> </td> <td> U+0229E </td> <tr><td> <code title="">pluscir;</code> </td> <td> U+02A22 </td> <tr><td> <code title="">plusdo;</code> </td> <td> U+02214 </td> <tr><td> <code title="">plusdu;</code> </td> <td> U+02A25 </td> <tr><td> <code title="">pluse;</code> </td> <td> U+02A72 </td> <tr><td> <code title="">plusmn;</code> </td> <td> U+000B1 </td> <tr><td> <code title="">plusmn</code> </td> <td> U+000B1 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">plussim;</code> </td> <td> U+02A26 </td> <tr><td> <code title="">plustwo;</code> </td> <td> U+02A27 </td> <tr><td> <code title="">pm;</code> </td> <td> U+000B1 </td> <tr><td> <code title="">pointint;</code> </td> <td> U+02A15 </td> <tr><td> <code title="">popf;</code> </td> <td> U+1D561 </td> <tr><td> <code title="">pound;</code> </td> <td> U+000A3 </td> <tr><td> <code title="">pound</code> </td> <td> U+000A3 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">pr;</code> </td> <td> U+0227A </td> <tr><td> <code title="">prE;</code> </td> <td> U+02AB3 </td> <tr><td> <code title="">prap;</code> </td> <td> U+02AB7 </td> <tr><td> <code title="">prcue;</code> </td> <td> U+0227C </td> <tr><td> <code title="">pre;</code> </td> <td> U+02AAF </td> <tr><td> <code title="">prec;</code> </td> <td> U+0227A </td> <tr><td> <code title="">precapprox;</code> </td> <td> U+02AB7 </td> <tr><td> <code title="">preccurlyeq;</code> </td> <td> U+0227C </td> <tr><td> <code title="">preceq;</code> </td> <td> U+02AAF </td> <tr><td> <code title="">precnapprox;</code> </td> <td> U+02AB9 </td> <tr><td> <code title="">precneqq;</code> </td> <td> U+02AB5 </td> <tr><td> <code title="">precnsim;</code> </td> <td> U+022E8 </td> <tr><td> <code title="">precsim;</code> </td> <td> U+0227E </td> <tr><td> <code title="">prime;</code> </td> <td> U+02032 </td> <tr><td> <code title="">primes;</code> </td> <td> U+02119 </td> <tr><td> <code title="">prnE;</code> </td> <td> U+02AB5 </td> <tr><td> <code title="">prnap;</code> </td> <td> U+02AB9 </td> <tr><td> <code title="">prnsim;</code> </td> <td> U+022E8 </td> <tr><td> <code title="">prod;</code> </td> <td> U+0220F </td> <tr><td> <code title="">profalar;</code> </td> <td> U+0232E </td> <tr><td> <code title="">profline;</code> </td> <td> U+02312 </td> <tr><td> <code title="">profsurf;</code> </td> <td> U+02313 </td> <tr><td> <code title="">prop;</code> </td> <td> U+0221D </td> <tr><td> <code title="">propto;</code> </td> <td> U+0221D </td> <tr><td> <code title="">prsim;</code> </td> <td> U+0227E </td> <tr><td> <code title="">prurel;</code> </td> <td> U+022B0 </td> <tr><td> <code title="">pscr;</code> </td> <td> U+1D4C5 </td> <tr><td> <code title="">psi;</code> </td> <td> U+003C8 </td> <tr><td> <code title="">puncsp;</code> </td> <td> U+02008 </td> <tr><td> <code title="">qfr;</code> </td> <td> U+1D52E </td> <tr><td> <code title="">qint;</code> </td> <td> U+02A0C </td> <tr><td> <code title="">qopf;</code> </td> <td> U+1D562 </td> <tr><td> <code title="">qprime;</code> </td> <td> U+02057 </td> <tr><td> <code title="">qscr;</code> </td> <td> U+1D4C6 </td> <tr><td> <code title="">quaternions;</code> </td> <td> U+0210D </td> <tr><td> <code title="">quatint;</code> </td> <td> U+02A16 </td> <tr><td> <code title="">quest;</code> </td> <td> U+0003F </td> <tr><td> <code title="">questeq;</code> </td> <td> U+0225F </td> <tr><td> <code title="">quot;</code> </td> <td> U+00022 </td> <tr><td> <code title="">quot</code> </td> <td> U+00022 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">rAarr;</code> </td> <td> U+021DB </td> <tr><td> <code title="">rArr;</code> </td> <td> U+021D2 </td> <tr><td> <code title="">rAtail;</code> </td> <td> U+0291C </td> <tr><td> <code title="">rBarr;</code> </td> <td> U+0290F </td> <tr><td> <code title="">rHar;</code> </td> <td> U+02964 </td> <tr><td> <code title="">racute;</code> </td> <td> U+00155 </td> <tr><td> <code title="">radic;</code> </td> <td> U+0221A </td> <tr><td> <code title="">raemptyv;</code> </td> <td> U+029B3 </td> <tr><td> <code title="">rang;</code> </td> <td> U+027E9 </td> <tr><td> <code title="">rangd;</code> </td> <td> U+02992 </td> <tr><td> <code title="">range;</code> </td> <td> U+029A5 </td> <tr><td> <code title="">rangle;</code> </td> <td> U+027E9 </td> <tr><td> <code title="">raquo;</code> </td> <td> U+000BB </td> <tr><td> <code title="">raquo</code> </td> <td> U+000BB </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">rarr;</code> </td> <td> U+02192 </td> <tr><td> <code title="">rarrap;</code> </td> <td> U+02975 </td> <tr><td> <code title="">rarrb;</code> </td> <td> U+021E5 </td> <tr><td> <code title="">rarrbfs;</code> </td> <td> U+02920 </td> <tr><td> <code title="">rarrc;</code> </td> <td> U+02933 </td> <tr><td> <code title="">rarrfs;</code> </td> <td> U+0291E </td> <tr><td> <code title="">rarrhk;</code> </td> <td> U+021AA </td> <tr><td> <code title="">rarrlp;</code> </td> <td> U+021AC </td> <tr><td> <code title="">rarrpl;</code> </td> <td> U+02945 </td> <tr><td> <code title="">rarrsim;</code> </td> <td> U+02974 </td> <tr><td> <code title="">rarrtl;</code> </td> <td> U+021A3 </td> <tr><td> <code title="">rarrw;</code> </td> <td> U+0219D </td> <tr><td> <code title="">ratail;</code> </td> <td> U+0291A </td> <tr><td> <code title="">ratio;</code> </td> <td> U+02236 </td> <tr><td> <code title="">rationals;</code> </td> <td> U+0211A </td> <tr><td> <code title="">rbarr;</code> </td> <td> U+0290D </td> <tr><td> <code title="">rbbrk;</code> </td> <td> U+02773 </td> <tr><td> <code title="">rbrace;</code> </td> <td> U+0007D </td> <tr><td> <code title="">rbrack;</code> </td> <td> U+0005D </td> <tr><td> <code title="">rbrke;</code> </td> <td> U+0298C </td> <tr><td> <code title="">rbrksld;</code> </td> <td> U+0298E </td> <tr><td> <code title="">rbrkslu;</code> </td> <td> U+02990 </td> <tr><td> <code title="">rcaron;</code> </td> <td> U+00159 </td> <tr><td> <code title="">rcedil;</code> </td> <td> U+00157 </td> <tr><td> <code title="">rceil;</code> </td> <td> U+02309 </td> <tr><td> <code title="">rcub;</code> </td> <td> U+0007D </td> <tr><td> <code title="">rcy;</code> </td> <td> U+00440 </td> <tr><td> <code title="">rdca;</code> </td> <td> U+02937 </td> <tr><td> <code title="">rdldhar;</code> </td> <td> U+02969 </td> <tr><td> <code title="">rdquo;</code> </td> <td> U+0201D </td> <tr><td> <code title="">rdquor;</code> </td> <td> U+0201D </td> <tr><td> <code title="">rdsh;</code> </td> <td> U+021B3 </td> <tr><td> <code title="">real;</code> </td> <td> U+0211C </td> <tr><td> <code title="">realine;</code> </td> <td> U+0211B </td> <tr><td> <code title="">realpart;</code> </td> <td> U+0211C </td> <tr><td> <code title="">reals;</code> </td> <td> U+0211D </td> <tr><td> <code title="">rect;</code> </td> <td> U+025AD </td> <tr><td> <code title="">reg;</code> </td> <td> U+000AE </td> <tr><td> <code title="">reg</code> </td> <td> U+000AE </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">rfisht;</code> </td> <td> U+0297D </td> <tr><td> <code title="">rfloor;</code> </td> <td> U+0230B </td> <tr><td> <code title="">rfr;</code> </td> <td> U+1D52F </td> <tr><td> <code title="">rhard;</code> </td> <td> U+021C1 </td> <tr><td> <code title="">rharu;</code> </td> <td> U+021C0 </td> <tr><td> <code title="">rharul;</code> </td> <td> U+0296C </td> <tr><td> <code title="">rho;</code> </td> <td> U+003C1 </td> <tr><td> <code title="">rhov;</code> </td> <td> U+003F1 </td> <tr><td> <code title="">rightarrow;</code> </td> <td> U+02192 </td> <tr><td> <code title="">rightarrowtail;</code> </td> <td> U+021A3 </td> <tr><td> <code title="">rightharpoondown;</code> </td> <td> U+021C1 </td> <tr><td> <code title="">rightharpoonup;</code> </td> <td> U+021C0 </td> <tr><td> <code title="">rightleftarrows;</code> </td> <td> U+021C4 </td> <tr><td> <code title="">rightleftharpoons;</code> </td> <td> U+021CC </td> <tr><td> <code title="">rightrightarrows;</code> </td> <td> U+021C9 </td> <tr><td> <code title="">rightsquigarrow;</code> </td> <td> U+0219D </td> <tr><td> <code title="">rightthreetimes;</code> </td> <td> U+022CC </td> <tr><td> <code title="">ring;</code> </td> <td> U+002DA </td> <tr><td> <code title="">risingdotseq;</code> </td> <td> U+02253 </td> <tr><td> <code title="">rlarr;</code> </td> <td> U+021C4 </td> <tr><td> <code title="">rlhar;</code> </td> <td> U+021CC </td> <tr><td> <code title="">rlm;</code> </td> <td> U+0200F </td> <tr><td> <code title="">rmoust;</code> </td> <td> U+023B1 </td> <tr><td> <code title="">rmoustache;</code> </td> <td> U+023B1 </td> <tr><td> <code title="">rnmid;</code> </td> <td> U+02AEE </td> <tr><td> <code title="">roang;</code> </td> <td> U+027ED </td> <tr><td> <code title="">roarr;</code> </td> <td> U+021FE </td> <tr><td> <code title="">robrk;</code> </td> <td> U+027E7 </td> <tr><td> <code title="">ropar;</code> </td> <td> U+02986 </td> <tr><td> <code title="">ropf;</code> </td> <td> U+1D563 </td> <tr><td> <code title="">roplus;</code> </td> <td> U+02A2E </td> <tr><td> <code title="">rotimes;</code> </td> <td> U+02A35 </td> <tr><td> <code title="">rpar;</code> </td> <td> U+00029 </td> <tr><td> <code title="">rpargt;</code> </td> <td> U+02994 </td> <tr><td> <code title="">rppolint;</code> </td> <td> U+02A12 </td> <tr><td> <code title="">rrarr;</code> </td> <td> U+021C9 </td> <tr><td> <code title="">rsaquo;</code> </td> <td> U+0203A </td> <tr><td> <code title="">rscr;</code> </td> <td> U+1D4C7 </td> <tr><td> <code title="">rsh;</code> </td> <td> U+021B1 </td> <tr><td> <code title="">rsqb;</code> </td> <td> U+0005D </td> <tr><td> <code title="">rsquo;</code> </td> <td> U+02019 </td> <tr><td> <code title="">rsquor;</code> </td> <td> U+02019 </td> <tr><td> <code title="">rthree;</code> </td> <td> U+022CC </td> <tr><td> <code title="">rtimes;</code> </td> <td> U+022CA </td> <tr><td> <code title="">rtri;</code> </td> <td> U+025B9 </td> <tr><td> <code title="">rtrie;</code> </td> <td> U+022B5 </td> <tr><td> <code title="">rtrif;</code> </td> <td> U+025B8 </td> <tr><td> <code title="">rtriltri;</code> </td> <td> U+029CE </td> <tr><td> <code title="">ruluhar;</code> </td> <td> U+02968 </td> <tr><td> <code title="">rx;</code> </td> <td> U+0211E </td> <tr><td> <code title="">sacute;</code> </td> <td> U+0015B </td> <tr><td> <code title="">sbquo;</code> </td> <td> U+0201A </td> <tr><td> <code title="">sc;</code> </td> <td> U+0227B </td> <tr><td> <code title="">scE;</code> </td> <td> U+02AB4 </td> <tr><td> <code title="">scap;</code> </td> <td> U+02AB8 </td> <tr><td> <code title="">scaron;</code> </td> <td> U+00161 </td> <tr><td> <code title="">sccue;</code> </td> <td> U+0227D </td> <tr><td> <code title="">sce;</code> </td> <td> U+02AB0 </td> <tr><td> <code title="">scedil;</code> </td> <td> U+0015F </td> <tr><td> <code title="">scirc;</code> </td> <td> U+0015D </td> <tr><td> <code title="">scnE;</code> </td> <td> U+02AB6 </td> <tr><td> <code title="">scnap;</code> </td> <td> U+02ABA </td> <tr><td> <code title="">scnsim;</code> </td> <td> U+022E9 </td> <tr><td> <code title="">scpolint;</code> </td> <td> U+02A13 </td> <tr><td> <code title="">scsim;</code> </td> <td> U+0227F </td> <tr><td> <code title="">scy;</code> </td> <td> U+00441 </td> <tr><td> <code title="">sdot;</code> </td> <td> U+022C5 </td> <tr><td> <code title="">sdotb;</code> </td> <td> U+022A1 </td> <tr><td> <code title="">sdote;</code> </td> <td> U+02A66 </td> <tr><td> <code title="">seArr;</code> </td> <td> U+021D8 </td> <tr><td> <code title="">searhk;</code> </td> <td> U+02925 </td> <tr><td> <code title="">searr;</code> </td> <td> U+02198 </td> <tr><td> <code title="">searrow;</code> </td> <td> U+02198 </td> <tr><td> <code title="">sect;</code> </td> <td> U+000A7 </td> <tr><td> <code title="">sect</code> </td> <td> U+000A7 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">semi;</code> </td> <td> U+0003B </td> <tr><td> <code title="">seswar;</code> </td> <td> U+02929 </td> <tr><td> <code title="">setminus;</code> </td> <td> U+02216 </td> <tr><td> <code title="">setmn;</code> </td> <td> U+02216 </td> <tr><td> <code title="">sext;</code> </td> <td> U+02736 </td> <tr><td> <code title="">sfr;</code> </td> <td> U+1D530 </td> <tr><td> <code title="">sfrown;</code> </td> <td> U+02322 </td> <tr><td> <code title="">sharp;</code> </td> <td> U+0266F </td> <tr><td> <code title="">shchcy;</code> </td> <td> U+00449 </td> <tr><td> <code title="">shcy;</code> </td> <td> U+00448 </td> <tr><td> <code title="">shortmid;</code> </td> <td> U+02223 </td> <tr><td> <code title="">shortparallel;</code> </td> <td> U+02225 </td> <tr><td> <code title="">shy;</code> </td> <td> U+000AD </td> <tr><td> <code title="">shy</code> </td> <td> U+000AD </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">sigma;</code> </td> <td> U+003C3 </td> <tr><td> <code title="">sigmaf;</code> </td> <td> U+003C2 </td> <tr><td> <code title="">sigmav;</code> </td> <td> U+003C2 </td> <tr><td> <code title="">sim;</code> </td> <td> U+0223C </td> <tr><td> <code title="">simdot;</code> </td> <td> U+02A6A </td> <tr><td> <code title="">sime;</code> </td> <td> U+02243 </td> <tr><td> <code title="">simeq;</code> </td> <td> U+02243 </td> <tr><td> <code title="">simg;</code> </td> <td> U+02A9E </td> <tr><td> <code title="">simgE;</code> </td> <td> U+02AA0 </td> <tr><td> <code title="">siml;</code> </td> <td> U+02A9D </td> <tr><td> <code title="">simlE;</code> </td> <td> U+02A9F </td> <tr><td> <code title="">simne;</code> </td> <td> U+02246 </td> <tr><td> <code title="">simplus;</code> </td> <td> U+02A24 </td> <tr><td> <code title="">simrarr;</code> </td> <td> U+02972 </td> <tr><td> <code title="">slarr;</code> </td> <td> U+02190 </td> <tr><td> <code title="">smallsetminus;</code> </td> <td> U+02216 </td> <tr><td> <code title="">smashp;</code> </td> <td> U+02A33 </td> <tr><td> <code title="">smeparsl;</code> </td> <td> U+029E4 </td> <tr><td> <code title="">smid;</code> </td> <td> U+02223 </td> <tr><td> <code title="">smile;</code> </td> <td> U+02323 </td> <tr><td> <code title="">smt;</code> </td> <td> U+02AAA </td> <tr><td> <code title="">smte;</code> </td> <td> U+02AAC </td> <tr><td> <code title="">softcy;</code> </td> <td> U+0044C </td> <tr><td> <code title="">sol;</code> </td> <td> U+0002F </td> <tr><td> <code title="">solb;</code> </td> <td> U+029C4 </td> <tr><td> <code title="">solbar;</code> </td> <td> U+0233F </td> <tr><td> <code title="">sopf;</code> </td> <td> U+1D564 </td> <tr><td> <code title="">spades;</code> </td> <td> U+02660 </td> <tr><td> <code title="">spadesuit;</code> </td> <td> U+02660 </td> <tr><td> <code title="">spar;</code> </td> <td> U+02225 </td> <tr><td> <code title="">sqcap;</code> </td> <td> U+02293 </td> <tr><td> <code title="">sqcup;</code> </td> <td> U+02294 </td> <tr><td> <code title="">sqsub;</code> </td> <td> U+0228F </td> <tr><td> <code title="">sqsube;</code> </td> <td> U+02291 </td> <tr><td> <code title="">sqsubset;</code> </td> <td> U+0228F </td> <tr><td> <code title="">sqsubseteq;</code> </td> <td> U+02291 </td> <tr><td> <code title="">sqsup;</code> </td> <td> U+02290 </td> <tr><td> <code title="">sqsupe;</code> </td> <td> U+02292 </td> <tr><td> <code title="">sqsupset;</code> </td> <td> U+02290 </td> <tr><td> <code title="">sqsupseteq;</code> </td> <td> U+02292 </td> <tr><td> <code title="">squ;</code> </td> <td> U+025A1 </td> <tr><td> <code title="">square;</code> </td> <td> U+025A1 </td> <tr><td> <code title="">squarf;</code> </td> <td> U+025AA </td> <tr><td> <code title="">squf;</code> </td> <td> U+025AA </td> <tr><td> <code title="">srarr;</code> </td> <td> U+02192 </td> <tr><td> <code title="">sscr;</code> </td> <td> U+1D4C8 </td> <tr><td> <code title="">ssetmn;</code> </td> <td> U+02216 </td> <tr><td> <code title="">ssmile;</code> </td> <td> U+02323 </td> <tr><td> <code title="">sstarf;</code> </td> <td> U+022C6 </td> <tr><td> <code title="">star;</code> </td> <td> U+02606 </td> <tr><td> <code title="">starf;</code> </td> <td> U+02605 </td> <tr><td> <code title="">straightepsilon;</code> </td> <td> U+003F5 </td> <tr><td> <code title="">straightphi;</code> </td> <td> U+003D5 </td> <tr><td> <code title="">strns;</code> </td> <td> U+000AF </td> <tr><td> <code title="">sub;</code> </td> <td> U+02282 </td> <tr><td> <code title="">subE;</code> </td> <td> U+02AC5 </td> <tr><td> <code title="">subdot;</code> </td> <td> U+02ABD </td> <tr><td> <code title="">sube;</code> </td> <td> U+02286 </td> <tr><td> <code title="">subedot;</code> </td> <td> U+02AC3 </td> <tr><td> <code title="">submult;</code> </td> <td> U+02AC1 </td> <tr><td> <code title="">subnE;</code> </td> <td> U+02ACB </td> <tr><td> <code title="">subne;</code> </td> <td> U+0228A </td> <tr><td> <code title="">subplus;</code> </td> <td> U+02ABF </td> <tr><td> <code title="">subrarr;</code> </td> <td> U+02979 </td> <tr><td> <code title="">subset;</code> </td> <td> U+02282 </td> <tr><td> <code title="">subseteq;</code> </td> <td> U+02286 </td> <tr><td> <code title="">subseteqq;</code> </td> <td> U+02AC5 </td> <tr><td> <code title="">subsetneq;</code> </td> <td> U+0228A </td> <tr><td> <code title="">subsetneqq;</code> </td> <td> U+02ACB </td> <tr><td> <code title="">subsim;</code> </td> <td> U+02AC7 </td> <tr><td> <code title="">subsub;</code> </td> <td> U+02AD5 </td> <tr><td> <code title="">subsup;</code> </td> <td> U+02AD3 </td> <tr><td> <code title="">succ;</code> </td> <td> U+0227B </td> <tr><td> <code title="">succapprox;</code> </td> <td> U+02AB8 </td> <tr><td> <code title="">succcurlyeq;</code> </td> <td> U+0227D </td> <tr><td> <code title="">succeq;</code> </td> <td> U+02AB0 </td> <tr><td> <code title="">succnapprox;</code> </td> <td> U+02ABA </td> <tr><td> <code title="">succneqq;</code> </td> <td> U+02AB6 </td> <tr><td> <code title="">succnsim;</code> </td> <td> U+022E9 </td> <tr><td> <code title="">succsim;</code> </td> <td> U+0227F </td> <tr><td> <code title="">sum;</code> </td> <td> U+02211 </td> <tr><td> <code title="">sung;</code> </td> <td> U+0266A </td> <tr><td> <code title="">sup1;</code> </td> <td> U+000B9 </td> <tr><td> <code title="">sup1</code> </td> <td> U+000B9 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">sup2;</code> </td> <td> U+000B2 </td> <tr><td> <code title="">sup2</code> </td> <td> U+000B2 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">sup3;</code> </td> <td> U+000B3 </td> <tr><td> <code title="">sup3</code> </td> <td> U+000B3 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">sup;</code> </td> <td> U+02283 </td> <tr><td> <code title="">supE;</code> </td> <td> U+02AC6 </td> <tr><td> <code title="">supdot;</code> </td> <td> U+02ABE </td> <tr><td> <code title="">supdsub;</code> </td> <td> U+02AD8 </td> <tr><td> <code title="">supe;</code> </td> <td> U+02287 </td> <tr><td> <code title="">supedot;</code> </td> <td> U+02AC4 </td> <tr><td> <code title="">suphsol;</code> </td> <td> U+027C9 </td> <tr><td> <code title="">suphsub;</code> </td> <td> U+02AD7 </td> <tr><td> <code title="">suplarr;</code> </td> <td> U+0297B </td> <tr><td> <code title="">supmult;</code> </td> <td> U+02AC2 </td> <tr><td> <code title="">supnE;</code> </td> <td> U+02ACC </td> <tr><td> <code title="">supne;</code> </td> <td> U+0228B </td> <tr><td> <code title="">supplus;</code> </td> <td> U+02AC0 </td> <tr><td> <code title="">supset;</code> </td> <td> U+02283 </td> <tr><td> <code title="">supseteq;</code> </td> <td> U+02287 </td> <tr><td> <code title="">supseteqq;</code> </td> <td> U+02AC6 </td> <tr><td> <code title="">supsetneq;</code> </td> <td> U+0228B </td> <tr><td> <code title="">supsetneqq;</code> </td> <td> U+02ACC </td> <tr><td> <code title="">supsim;</code> </td> <td> U+02AC8 </td> <tr><td> <code title="">supsub;</code> </td> <td> U+02AD4 </td> <tr><td> <code title="">supsup;</code> </td> <td> U+02AD6 </td> <tr><td> <code title="">swArr;</code> </td> <td> U+021D9 </td> <tr><td> <code title="">swarhk;</code> </td> <td> U+02926 </td> <tr><td> <code title="">swarr;</code> </td> <td> U+02199 </td> <tr><td> <code title="">swarrow;</code> </td> <td> U+02199 </td> <tr><td> <code title="">swnwar;</code> </td> <td> U+0292A </td> <tr><td> <code title="">szlig;</code> </td> <td> U+000DF </td> <tr><td> <code title="">szlig</code> </td> <td> U+000DF </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">target;</code> </td> <td> U+02316 </td> <tr><td> <code title="">tau;</code> </td> <td> U+003C4 </td> <tr><td> <code title="">tbrk;</code> </td> <td> U+023B4 </td> <tr><td> <code title="">tcaron;</code> </td> <td> U+00165 </td> <tr><td> <code title="">tcedil;</code> </td> <td> U+00163 </td> <tr><td> <code title="">tcy;</code> </td> <td> U+00442 </td> <tr><td> <code title="">tdot;</code> </td> <td> U+020DB </td> <tr><td> <code title="">telrec;</code> </td> <td> U+02315 </td> <tr><td> <code title="">tfr;</code> </td> <td> U+1D531 </td> <tr><td> <code title="">there4;</code> </td> <td> U+02234 </td> <tr><td> <code title="">therefore;</code> </td> <td> U+02234 </td> <tr><td> <code title="">theta;</code> </td> <td> U+003B8 </td> <tr><td> <code title="">thetasym;</code> </td> <td> U+003D1 </td> <tr><td> <code title="">thetav;</code> </td> <td> U+003D1 </td> <tr><td> <code title="">thickapprox;</code> </td> <td> U+02248 </td> <tr><td> <code title="">thicksim;</code> </td> <td> U+0223C </td> <tr><td> <code title="">thinsp;</code> </td> <td> U+02009 </td> <tr><td> <code title="">thkap;</code> </td> <td> U+02248 </td> <tr><td> <code title="">thksim;</code> </td> <td> U+0223C </td> <tr><td> <code title="">thorn;</code> </td> <td> U+000FE </td> <tr><td> <code title="">thorn</code> </td> <td> U+000FE </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">tilde;</code> </td> <td> U+002DC </td> <tr><td> <code title="">times;</code> </td> <td> U+000D7 </td> <tr><td> <code title="">times</code> </td> <td> U+000D7 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">timesb;</code> </td> <td> U+022A0 </td> <tr><td> <code title="">timesbar;</code> </td> <td> U+02A31 </td> <tr><td> <code title="">timesd;</code> </td> <td> U+02A30 </td> <tr><td> <code title="">tint;</code> </td> <td> U+0222D </td> <tr><td> <code title="">toea;</code> </td> <td> U+02928 </td> <tr><td> <code title="">top;</code> </td> <td> U+022A4 </td> <tr><td> <code title="">topbot;</code> </td> <td> U+02336 </td> <tr><td> <code title="">topcir;</code> </td> <td> U+02AF1 </td> <tr><td> <code title="">topf;</code> </td> <td> U+1D565 </td> <tr><td> <code title="">topfork;</code> </td> <td> U+02ADA </td> <tr><td> <code title="">tosa;</code> </td> <td> U+02929 </td> <tr><td> <code title="">tprime;</code> </td> <td> U+02034 </td> <tr><td> <code title="">trade;</code> </td> <td> U+02122 </td> <tr><td> <code title="">triangle;</code> </td> <td> U+025B5 </td> <tr><td> <code title="">triangledown;</code> </td> <td> U+025BF </td> <tr><td> <code title="">triangleleft;</code> </td> <td> U+025C3 </td> <tr><td> <code title="">trianglelefteq;</code> </td> <td> U+022B4 </td> <tr><td> <code title="">triangleq;</code> </td> <td> U+0225C </td> <tr><td> <code title="">triangleright;</code> </td> <td> U+025B9 </td> <tr><td> <code title="">trianglerighteq;</code> </td> <td> U+022B5 </td> <tr><td> <code title="">tridot;</code> </td> <td> U+025EC </td> <tr><td> <code title="">trie;</code> </td> <td> U+0225C </td> <tr><td> <code title="">triminus;</code> </td> <td> U+02A3A </td> <tr><td> <code title="">triplus;</code> </td> <td> U+02A39 </td> <tr><td> <code title="">trisb;</code> </td> <td> U+029CD </td> <tr><td> <code title="">tritime;</code> </td> <td> U+02A3B </td> <tr><td> <code title="">trpezium;</code> </td> <td> U+023E2 </td> <tr><td> <code title="">tscr;</code> </td> <td> U+1D4C9 </td> <tr><td> <code title="">tscy;</code> </td> <td> U+00446 </td> <tr><td> <code title="">tshcy;</code> </td> <td> U+0045B </td> <tr><td> <code title="">tstrok;</code> </td> <td> U+00167 </td> <tr><td> <code title="">twixt;</code> </td> <td> U+0226C </td> <tr><td> <code title="">twoheadleftarrow;</code> </td> <td> U+0219E </td> <tr><td> <code title="">twoheadrightarrow;</code> </td> <td> U+021A0 </td> <tr><td> <code title="">uArr;</code> </td> <td> U+021D1 </td> <tr><td> <code title="">uHar;</code> </td> <td> U+02963 </td> <tr><td> <code title="">uacute;</code> </td> <td> U+000FA </td> <tr><td> <code title="">uacute</code> </td> <td> U+000FA </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">uarr;</code> </td> <td> U+02191 </td> <tr><td> <code title="">ubrcy;</code> </td> <td> U+0045E </td> <tr><td> <code title="">ubreve;</code> </td> <td> U+0016D </td> <tr><td> <code title="">ucirc;</code> </td> <td> U+000FB </td> <tr><td> <code title="">ucirc</code> </td> <td> U+000FB </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">ucy;</code> </td> <td> U+00443 </td> <tr><td> <code title="">udarr;</code> </td> <td> U+021C5 </td> <tr><td> <code title="">udblac;</code> </td> <td> U+00171 </td> <tr><td> <code title="">udhar;</code> </td> <td> U+0296E </td> <tr><td> <code title="">ufisht;</code> </td> <td> U+0297E </td> <tr><td> <code title="">ufr;</code> </td> <td> U+1D532 </td> <tr><td> <code title="">ugrave;</code> </td> <td> U+000F9 </td> <tr><td> <code title="">ugrave</code> </td> <td> U+000F9 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">uharl;</code> </td> <td> U+021BF </td> <tr><td> <code title="">uharr;</code> </td> <td> U+021BE </td> <tr><td> <code title="">uhblk;</code> </td> <td> U+02580 </td> <tr><td> <code title="">ulcorn;</code> </td> <td> U+0231C </td> <tr><td> <code title="">ulcorner;</code> </td> <td> U+0231C </td> <tr><td> <code title="">ulcrop;</code> </td> <td> U+0230F </td> <tr><td> <code title="">ultri;</code> </td> <td> U+025F8 </td> <tr><td> <code title="">umacr;</code> </td> <td> U+0016B </td> <tr><td> <code title="">uml;</code> </td> <td> U+000A8 </td> <tr><td> <code title="">uml</code> </td> <td> U+000A8 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">uogon;</code> </td> <td> U+00173 </td> <tr><td> <code title="">uopf;</code> </td> <td> U+1D566 </td> <tr><td> <code title="">uparrow;</code> </td> <td> U+02191 </td> <tr><td> <code title="">updownarrow;</code> </td> <td> U+02195 </td> <tr><td> <code title="">upharpoonleft;</code> </td> <td> U+021BF </td> <tr><td> <code title="">upharpoonright;</code> </td> <td> U+021BE </td> <tr><td> <code title="">uplus;</code> </td> <td> U+0228E </td> <tr><td> <code title="">upsi;</code> </td> <td> U+003C5 </td> <tr><td> <code title="">upsih;</code> </td> <td> U+003D2 </td> <tr><td> <code title="">upsilon;</code> </td> <td> U+003C5 </td> <tr><td> <code title="">upuparrows;</code> </td> <td> U+021C8 </td> <tr><td> <code title="">urcorn;</code> </td> <td> U+0231D </td> <tr><td> <code title="">urcorner;</code> </td> <td> U+0231D </td> <tr><td> <code title="">urcrop;</code> </td> <td> U+0230E </td> <tr><td> <code title="">uring;</code> </td> <td> U+0016F </td> <tr><td> <code title="">urtri;</code> </td> <td> U+025F9 </td> <tr><td> <code title="">uscr;</code> </td> <td> U+1D4CA </td> <tr><td> <code title="">utdot;</code> </td> <td> U+022F0 </td> <tr><td> <code title="">utilde;</code> </td> <td> U+00169 </td> <tr><td> <code title="">utri;</code> </td> <td> U+025B5 </td> <tr><td> <code title="">utrif;</code> </td> <td> U+025B4 </td> <tr><td> <code title="">uuarr;</code> </td> <td> U+021C8 </td> <tr><td> <code title="">uuml;</code> </td> <td> U+000FC </td> <tr><td> <code title="">uuml</code> </td> <td> U+000FC </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">uwangle;</code> </td> <td> U+029A7 </td> <tr><td> <code title="">vArr;</code> </td> <td> U+021D5 </td> <tr><td> <code title="">vBar;</code> </td> <td> U+02AE8 </td> <tr><td> <code title="">vBarv;</code> </td> <td> U+02AE9 </td> <tr><td> <code title="">vDash;</code> </td> <td> U+022A8 </td> <tr><td> <code title="">vangrt;</code> </td> <td> U+0299C </td> <tr><td> <code title="">varepsilon;</code> </td> <td> U+003F5 </td> <tr><td> <code title="">varkappa;</code> </td> <td> U+003F0 </td> <tr><td> <code title="">varnothing;</code> </td> <td> U+02205 </td> <tr><td> <code title="">varphi;</code> </td> <td> U+003D5 </td> <tr><td> <code title="">varpi;</code> </td> <td> U+003D6 </td> <tr><td> <code title="">varpropto;</code> </td> <td> U+0221D </td> <tr><td> <code title="">varr;</code> </td> <td> U+02195 </td> <tr><td> <code title="">varrho;</code> </td> <td> U+003F1 </td> <tr><td> <code title="">varsigma;</code> </td> <td> U+003C2 </td> <tr><td> <code title="">vartheta;</code> </td> <td> U+003D1 </td> <tr><td> <code title="">vartriangleleft;</code> </td> <td> U+022B2 </td> <tr><td> <code title="">vartriangleright;</code> </td> <td> U+022B3 </td> <tr><td> <code title="">vcy;</code> </td> <td> U+00432 </td> <tr><td> <code title="">vdash;</code> </td> <td> U+022A2 </td> <tr><td> <code title="">vee;</code> </td> <td> U+02228 </td> <tr><td> <code title="">veebar;</code> </td> <td> U+022BB </td> <tr><td> <code title="">veeeq;</code> </td> <td> U+0225A </td> <tr><td> <code title="">vellip;</code> </td> <td> U+022EE </td> <tr><td> <code title="">verbar;</code> </td> <td> U+0007C </td> <tr><td> <code title="">vert;</code> </td> <td> U+0007C </td> <tr><td> <code title="">vfr;</code> </td> <td> U+1D533 </td> <tr><td> <code title="">vltri;</code> </td> <td> U+022B2 </td> <tr><td> <code title="">vopf;</code> </td> <td> U+1D567 </td> <tr><td> <code title="">vprop;</code> </td> <td> U+0221D </td> <tr><td> <code title="">vrtri;</code> </td> <td> U+022B3 </td> <tr><td> <code title="">vscr;</code> </td> <td> U+1D4CB </td> <tr><td> <code title="">vzigzag;</code> </td> <td> U+0299A </td> <tr><td> <code title="">wcirc;</code> </td> <td> U+00175 </td> <tr><td> <code title="">wedbar;</code> </td> <td> U+02A5F </td> <tr><td> <code title="">wedge;</code> </td> <td> U+02227 </td> <tr><td> <code title="">wedgeq;</code> </td> <td> U+02259 </td> <tr><td> <code title="">weierp;</code> </td> <td> U+02118 </td> <tr><td> <code title="">wfr;</code> </td> <td> U+1D534 </td> <tr><td> <code title="">wopf;</code> </td> <td> U+1D568 </td> <tr><td> <code title="">wp;</code> </td> <td> U+02118 </td> <tr><td> <code title="">wr;</code> </td> <td> U+02240 </td> <tr><td> <code title="">wreath;</code> </td> <td> U+02240 </td> <tr><td> <code title="">wscr;</code> </td> <td> U+1D4CC </td> <tr><td> <code title="">xcap;</code> </td> <td> U+022C2 </td> <tr><td> <code title="">xcirc;</code> </td> <td> U+025EF </td> <tr><td> <code title="">xcup;</code> </td> <td> U+022C3 </td> <tr><td> <code title="">xdtri;</code> </td> <td> U+025BD </td> <tr><td> <code title="">xfr;</code> </td> <td> U+1D535 </td> <tr><td> <code title="">xhArr;</code> </td> <td> U+027FA </td> <tr><td> <code title="">xharr;</code> </td> <td> U+027F7 </td> <tr><td> <code title="">xi;</code> </td> <td> U+003BE </td> <tr><td> <code title="">xlArr;</code> </td> <td> U+027F8 </td> <tr><td> <code title="">xlarr;</code> </td> <td> U+027F5 </td> <tr><td> <code title="">xmap;</code> </td> <td> U+027FC </td> <tr><td> <code title="">xnis;</code> </td> <td> U+022FB </td> <tr><td> <code title="">xodot;</code> </td> <td> U+02A00 </td> <tr><td> <code title="">xopf;</code> </td> <td> U+1D569 </td> <tr><td> <code title="">xoplus;</code> </td> <td> U+02A01 </td> <tr><td> <code title="">xotime;</code> </td> <td> U+02A02 </td> <tr><td> <code title="">xrArr;</code> </td> <td> U+027F9 </td> <tr><td> <code title="">xrarr;</code> </td> <td> U+027F6 </td> <tr><td> <code title="">xscr;</code> </td> <td> U+1D4CD </td> <tr><td> <code title="">xsqcup;</code> </td> <td> U+02A06 </td> <tr><td> <code title="">xuplus;</code> </td> <td> U+02A04 </td> <tr><td> <code title="">xutri;</code> </td> <td> U+025B3 </td> <tr><td> <code title="">xvee;</code> </td> <td> U+022C1 </td> <tr><td> <code title="">xwedge;</code> </td> <td> U+022C0 </td> <tr><td> <code title="">yacute;</code> </td> <td> U+000FD </td> <tr><td> <code title="">yacute</code> </td> <td> U+000FD </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">yacy;</code> </td> <td> U+0044F </td> <tr><td> <code title="">ycirc;</code> </td> <td> U+00177 </td> <tr><td> <code title="">ycy;</code> </td> <td> U+0044B </td> <tr><td> <code title="">yen;</code> </td> <td> U+000A5 </td> <tr><td> <code title="">yen</code> </td> <td> U+000A5 </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">yfr;</code> </td> <td> U+1D536 </td> <tr><td> <code title="">yicy;</code> </td> <td> U+00457 </td> <tr><td> <code title="">yopf;</code> </td> <td> U+1D56A </td> <tr><td> <code title="">yscr;</code> </td> <td> U+1D4CE </td> <tr><td> <code title="">yucy;</code> </td> <td> U+0044E </td> <tr><td> <code title="">yuml;</code> </td> <td> U+000FF </td> <tr><td> <code title="">yuml</code> </td> <td> U+000FF </td> </tr><!-- (invalid entity with missing semicolon for legacy support only) --><tr><td> <code title="">zacute;</code> </td> <td> U+0017A </td> <tr><td> <code title="">zcaron;</code> </td> <td> U+0017E </td> <tr><td> <code title="">zcy;</code> </td> <td> U+00437 </td> <tr><td> <code title="">zdot;</code> </td> <td> U+0017C </td> <tr><td> <code title="">zeetrf;</code> </td> <td> U+02128 </td> <tr><td> <code title="">zeta;</code> </td> <td> U+003B6 </td> <tr><td> <code title="">zfr;</code> </td> <td> U+1D537 </td> <tr><td> <code title="">zhcy;</code> </td> <td> U+00436 </td> <tr><td> <code title="">zigrarr;</code> </td> <td> U+021DD </td> <tr><td> <code title="">zopf;</code> </td> <td> U+1D56B </td> <tr><td> <code title="">zscr;</code> </td> <td> U+1D4CF </td> <tr><td> <code title="">zwj;</code> </td> <td> U+0200D </td> <tr><td> <code title="">zwnj;</code> </td> <td> U+0200C </td> </table>
+
+ \ No newline at end of file
diff --git a/parser/html/javasrc/AttributeName.java b/parser/html/javasrc/AttributeName.java
new file mode 100644
index 000000000..7b889e71e
--- /dev/null
+++ b/parser/html/javasrc/AttributeName.java
@@ -0,0 +1,2473 @@
+/*
+ * Copyright (c) 2008-2011 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package nu.validator.htmlparser.impl;
+
+import java.util.Arrays;
+
+import nu.validator.htmlparser.annotation.Local;
+import nu.validator.htmlparser.annotation.NoLength;
+import nu.validator.htmlparser.annotation.NsUri;
+import nu.validator.htmlparser.annotation.Prefix;
+import nu.validator.htmlparser.annotation.QName;
+import nu.validator.htmlparser.annotation.Virtual;
+import nu.validator.htmlparser.common.Interner;
+
+public final class AttributeName
+// Uncomment to regenerate
+// implements Comparable<AttributeName>
+{
+ // [NOCPP[
+
+ public static final int NCNAME_HTML = 1;
+
+ public static final int NCNAME_FOREIGN = (1 << 1) | (1 << 2);
+
+ public static final int NCNAME_LANG = (1 << 3);
+
+ public static final int IS_XMLNS = (1 << 4);
+
+ public static final int CASE_FOLDED = (1 << 5);
+
+ public static final int BOOLEAN = (1 << 6);
+
+ // ]NOCPP]
+
+ /**
+ * An array representing no namespace regardless of namespace mode (HTML,
+ * SVG, MathML, lang-mapping HTML) used.
+ */
+ static final @NoLength @NsUri String[] ALL_NO_NS = { "", "", "",
+ // [NOCPP[
+ ""
+ // ]NOCPP]
+ };
+
+ /**
+ * An array that has no namespace for the HTML mode but the XMLNS namespace
+ * for the SVG and MathML modes.
+ */
+ private static final @NoLength @NsUri String[] XMLNS_NS = { "",
+ "http://www.w3.org/2000/xmlns/", "http://www.w3.org/2000/xmlns/",
+ // [NOCPP[
+ ""
+ // ]NOCPP]
+ };
+
+ /**
+ * An array that has no namespace for the HTML mode but the XML namespace
+ * for the SVG and MathML modes.
+ */
+ private static final @NoLength @NsUri String[] XML_NS = { "",
+ "http://www.w3.org/XML/1998/namespace",
+ "http://www.w3.org/XML/1998/namespace",
+ // [NOCPP[
+ ""
+ // ]NOCPP]
+ };
+
+ /**
+ * An array that has no namespace for the HTML mode but the XLink namespace
+ * for the SVG and MathML modes.
+ */
+ private static final @NoLength @NsUri String[] XLINK_NS = { "",
+ "http://www.w3.org/1999/xlink", "http://www.w3.org/1999/xlink",
+ // [NOCPP[
+ ""
+ // ]NOCPP]
+ };
+
+ // [NOCPP[
+ /**
+ * An array that has no namespace for the HTML, SVG and MathML modes but has
+ * the XML namespace for the lang-mapping HTML mode.
+ */
+ private static final @NoLength @NsUri String[] LANG_NS = { "", "", "",
+ "http://www.w3.org/XML/1998/namespace" };
+
+ // ]NOCPP]
+
+ /**
+ * An array for no prefixes in any mode.
+ */
+ static final @NoLength @Prefix String[] ALL_NO_PREFIX = { null, null, null,
+ // [NOCPP[
+ null
+ // ]NOCPP]
+ };
+
+ /**
+ * An array for no prefixe in the HTML mode and the <code>xmlns</code>
+ * prefix in the SVG and MathML modes.
+ */
+ private static final @NoLength @Prefix String[] XMLNS_PREFIX = { null,
+ "xmlns", "xmlns",
+ // [NOCPP[
+ null
+ // ]NOCPP]
+ };
+
+ /**
+ * An array for no prefixe in the HTML mode and the <code>xlink</code>
+ * prefix in the SVG and MathML modes.
+ */
+ private static final @NoLength @Prefix String[] XLINK_PREFIX = { null,
+ "xlink", "xlink",
+ // [NOCPP[
+ null
+ // ]NOCPP]
+ };
+
+ /**
+ * An array for no prefixe in the HTML mode and the <code>xml</code> prefix
+ * in the SVG and MathML modes.
+ */
+ private static final @NoLength @Prefix String[] XML_PREFIX = { null, "xml",
+ "xml",
+ // [NOCPP[
+ null
+ // ]NOCPP]
+ };
+
+ // [NOCPP[
+
+ private static final @NoLength @Prefix String[] LANG_PREFIX = { null, null,
+ null, "xml" };
+
+ private static @QName String[] COMPUTE_QNAME(String[] local, String[] prefix) {
+ @QName String[] arr = new String[4];
+ for (int i = 0; i < arr.length; i++) {
+ if (prefix[i] == null) {
+ arr[i] = local[i];
+ } else {
+ arr[i] = (prefix[i] + ':' + local[i]).intern();
+ }
+ }
+ return arr;
+ }
+
+ // ]NOCPP]
+
+ /**
+ * An initialization helper for having a one name in the SVG mode and
+ * another name in the other modes.
+ *
+ * @param name
+ * the name for the non-SVG modes
+ * @param camel
+ * the name for the SVG mode
+ * @return the initialized name array
+ */
+ private static @NoLength @Local String[] SVG_DIFFERENT(@Local String name,
+ @Local String camel) {
+ @NoLength @Local String[] arr = new String[4];
+ arr[0] = name;
+ arr[1] = name;
+ arr[2] = camel;
+ // [NOCPP[
+ arr[3] = name;
+ // ]NOCPP]
+ return arr;
+ }
+
+ /**
+ * An initialization helper for having a one name in the MathML mode and
+ * another name in the other modes.
+ *
+ * @param name
+ * the name for the non-MathML modes
+ * @param camel
+ * the name for the MathML mode
+ * @return the initialized name array
+ */
+ private static @NoLength @Local String[] MATH_DIFFERENT(@Local String name,
+ @Local String camel) {
+ @NoLength @Local String[] arr = new String[4];
+ arr[0] = name;
+ arr[1] = camel;
+ arr[2] = name;
+ // [NOCPP[
+ arr[3] = name;
+ // ]NOCPP]
+ return arr;
+ }
+
+ /**
+ * An initialization helper for having a different local name in the HTML
+ * mode and the SVG and MathML modes.
+ *
+ * @param name
+ * the name for the HTML mode
+ * @param suffix
+ * the name for the SVG and MathML modes
+ * @return the initialized name array
+ */
+ private static @NoLength @Local String[] COLONIFIED_LOCAL(
+ @Local String name, @Local String suffix) {
+ @NoLength @Local String[] arr = new String[4];
+ arr[0] = name;
+ arr[1] = suffix;
+ arr[2] = suffix;
+ // [NOCPP[
+ arr[3] = name;
+ // ]NOCPP]
+ return arr;
+ }
+
+ /**
+ * An initialization helper for having the same local name in all modes.
+ *
+ * @param name
+ * the name
+ * @return the initialized name array
+ */
+ static @NoLength @Local String[] SAME_LOCAL(@Local String name) {
+ @NoLength @Local String[] arr = new String[4];
+ arr[0] = name;
+ arr[1] = name;
+ arr[2] = name;
+ // [NOCPP[
+ arr[3] = name;
+ // ]NOCPP]
+ return arr;
+ }
+
+ /**
+ * Returns an attribute name by buffer.
+ *
+ * <p>
+ * C++ ownership: The return value is either released by the caller if the
+ * attribute is a duplicate or the ownership is transferred to
+ * HtmlAttributes and released upon clearing or destroying that object.
+ *
+ * @param buf
+ * the buffer
+ * @param offset
+ * ignored
+ * @param length
+ * length of data
+ * @param checkNcName
+ * whether to check ncnameness
+ * @return an <code>AttributeName</code> corresponding to the argument data
+ */
+ static AttributeName nameByBuffer(@NoLength char[] buf, int offset,
+ int length
+ // [NOCPP[
+ , boolean checkNcName
+ // ]NOCPP]
+ , Interner interner) {
+ // XXX deal with offset
+ int hash = AttributeName.bufToHash(buf, length);
+ int index = Arrays.binarySearch(AttributeName.ATTRIBUTE_HASHES, hash);
+ if (index < 0) {
+ return AttributeName.createAttributeName(
+ Portability.newLocalNameFromBuffer(buf, offset, length,
+ interner)
+ // [NOCPP[
+ , checkNcName
+ // ]NOCPP]
+ );
+ } else {
+ AttributeName attributeName = AttributeName.ATTRIBUTE_NAMES[index];
+ @Local String name = attributeName.getLocal(AttributeName.HTML);
+ if (!Portability.localEqualsBuffer(name, buf, offset, length)) {
+ return AttributeName.createAttributeName(
+ Portability.newLocalNameFromBuffer(buf, offset, length,
+ interner)
+ // [NOCPP[
+ , checkNcName
+ // ]NOCPP]
+ );
+ }
+ return attributeName;
+ }
+ }
+
+ /**
+ * This method has to return a unique integer for each well-known
+ * lower-cased attribute name.
+ *
+ * @param buf
+ * @param len
+ * @return
+ */
+ private static int bufToHash(@NoLength char[] buf, int len) {
+ int hash2 = 0;
+ int hash = len;
+ hash <<= 5;
+ hash += buf[0] - 0x60;
+ int j = len;
+ for (int i = 0; i < 4 && j > 0; i++) {
+ j--;
+ hash <<= 5;
+ hash += buf[j] - 0x60;
+ hash2 <<= 6;
+ hash2 += buf[i] - 0x5F;
+ }
+ return hash ^ hash2;
+ }
+
+ /**
+ * The mode value for HTML.
+ */
+ public static final int HTML = 0;
+
+ /**
+ * The mode value for MathML.
+ */
+ public static final int MATHML = 1;
+
+ /**
+ * The mode value for SVG.
+ */
+ public static final int SVG = 2;
+
+ // [NOCPP[
+
+ /**
+ * The mode value for lang-mapping HTML.
+ */
+ public static final int HTML_LANG = 3;
+
+ // ]NOCPP]
+
+ /**
+ * The namespaces indexable by mode.
+ */
+ private final @NsUri @NoLength String[] uri;
+
+ /**
+ * The local names indexable by mode.
+ */
+ private final @Local @NoLength String[] local;
+
+ /**
+ * The prefixes indexably by mode.
+ */
+ private final @Prefix @NoLength String[] prefix;
+
+ // [NOCPP[
+
+ private final int flags;
+
+ /**
+ * The qnames indexable by mode.
+ */
+ private final @QName @NoLength String[] qName;
+
+ // ]NOCPP]
+
+ /**
+ * The startup-time constructor.
+ *
+ * @param uri
+ * the namespace
+ * @param local
+ * the local name
+ * @param prefix
+ * the prefix
+ * @param ncname
+ * the ncnameness
+ * @param xmlns
+ * whether this is an xmlns attribute
+ */
+ protected AttributeName(@NsUri @NoLength String[] uri,
+ @Local @NoLength String[] local, @Prefix @NoLength String[] prefix
+ // [NOCPP[
+ , int flags
+ // ]NOCPP]
+ ) {
+ this.uri = uri;
+ this.local = local;
+ this.prefix = prefix;
+ // [NOCPP[
+ this.qName = COMPUTE_QNAME(local, prefix);
+ this.flags = flags;
+ // ]NOCPP]
+ }
+
+ /**
+ * Creates an <code>AttributeName</code> for a local name.
+ *
+ * @param name
+ * the name
+ * @param checkNcName
+ * whether to check ncnameness
+ * @return an <code>AttributeName</code>
+ */
+ private static AttributeName createAttributeName(@Local String name
+ // [NOCPP[
+ , boolean checkNcName
+ // ]NOCPP]
+ ) {
+ // [NOCPP[
+ int flags = NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG;
+ if (name.startsWith("xmlns:")) {
+ flags = IS_XMLNS;
+ } else if (checkNcName && !NCName.isNCName(name)) {
+ flags = 0;
+ }
+ // ]NOCPP]
+ return new AttributeName(AttributeName.ALL_NO_NS,
+ AttributeName.SAME_LOCAL(name), ALL_NO_PREFIX, flags);
+ }
+
+ /**
+ * Deletes runtime-allocated instances in C++.
+ */
+ @Virtual void release() {
+ // No-op in Java.
+ // Implement as |delete this;| in subclass.
+ }
+
+ /**
+ * The C++ destructor.
+ */
+ @SuppressWarnings("unused") @Virtual private void destructor() {
+ Portability.deleteArray(local);
+ }
+
+ /**
+ * Clones the attribute using an interner. Returns <code>this</code> in Java
+ * and for non-dynamic instances in C++.
+ *
+ * @param interner
+ * an interner
+ * @return a clone
+ */
+ @Virtual public AttributeName cloneAttributeName(Interner interner) {
+ return this;
+ }
+
+ // [NOCPP[
+ /**
+ * Creator for use when the XML violation policy requires an attribute name
+ * to be changed.
+ *
+ * @param name
+ * the name of the attribute to create
+ */
+ static AttributeName create(@Local String name) {
+ return new AttributeName(AttributeName.ALL_NO_NS,
+ AttributeName.SAME_LOCAL(name), ALL_NO_PREFIX,
+ NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ }
+
+ /**
+ * Queries whether this name is an XML 1.0 4th ed. NCName.
+ *
+ * @param mode
+ * the SVG/MathML/HTML mode
+ * @return <code>true</code> if this is an NCName in the given mode
+ */
+ public boolean isNcName(int mode) {
+ return (flags & (1 << mode)) != 0;
+ }
+
+ /**
+ * Queries whether this is an <code>xmlns</code> attribute.
+ *
+ * @return <code>true</code> if this is an <code>xmlns</code> attribute
+ */
+ public boolean isXmlns() {
+ return (flags & IS_XMLNS) != 0;
+ }
+
+ /**
+ * Queries whether this attribute has a case-folded value in the HTML4 mode
+ * of the parser.
+ *
+ * @return <code>true</code> if the value is case-folded
+ */
+ boolean isCaseFolded() {
+ return (flags & CASE_FOLDED) != 0;
+ }
+
+ boolean isBoolean() {
+ return (flags & BOOLEAN) != 0;
+ }
+
+ public @QName String getQName(int mode) {
+ return qName[mode];
+ }
+
+ // ]NOCPP]
+
+ public @NsUri String getUri(int mode) {
+ return uri[mode];
+ }
+
+ public @Local String getLocal(int mode) {
+ return local[mode];
+ }
+
+ public @Prefix String getPrefix(int mode) {
+ return prefix[mode];
+ }
+
+ boolean equalsAnother(AttributeName another) {
+ return this.getLocal(AttributeName.HTML) == another.getLocal(AttributeName.HTML);
+ }
+
+ // START CODE ONLY USED FOR GENERATING CODE uncomment to regenerate
+
+// /**
+// * @see java.lang.Object#toString()
+// */
+// @Override public String toString() {
+// return "(" + formatNs() + ", " + formatLocal() + ", " + formatPrefix()
+// + ", " + formatFlags() + ")";
+// }
+//
+// private String formatFlags() {
+// StringBuilder builder = new StringBuilder();
+// if ((flags & NCNAME_HTML) != 0) {
+// if (builder.length() != 0) {
+// builder.append(" | ");
+// }
+// builder.append("NCNAME_HTML");
+// }
+// if ((flags & NCNAME_FOREIGN) != 0) {
+// if (builder.length() != 0) {
+// builder.append(" | ");
+// }
+// builder.append("NCNAME_FOREIGN");
+// }
+// if ((flags & NCNAME_LANG) != 0) {
+// if (builder.length() != 0) {
+// builder.append(" | ");
+// }
+// builder.append("NCNAME_LANG");
+// }
+// if (isXmlns()) {
+// if (builder.length() != 0) {
+// builder.append(" | ");
+// }
+// builder.append("IS_XMLNS");
+// }
+// if (isCaseFolded()) {
+// if (builder.length() != 0) {
+// builder.append(" | ");
+// }
+// builder.append("CASE_FOLDED");
+// }
+// if (isBoolean()) {
+// if (builder.length() != 0) {
+// builder.append(" | ");
+// }
+// builder.append("BOOLEAN");
+// }
+// if (builder.length() == 0) {
+// return "0";
+// }
+// return builder.toString();
+// }
+//
+// public int compareTo(AttributeName other) {
+// int thisHash = this.hash();
+// int otherHash = other.hash();
+// if (thisHash < otherHash) {
+// return -1;
+// } else if (thisHash == otherHash) {
+// return 0;
+// } else {
+// return 1;
+// }
+// }
+//
+// private String formatPrefix() {
+// if (prefix[0] == null && prefix[1] == null && prefix[2] == null
+// && prefix[3] == null) {
+// return "ALL_NO_PREFIX";
+// } else if (prefix[0] == null && prefix[1] == prefix[2]
+// && prefix[3] == null) {
+// if ("xmlns".equals(prefix[1])) {
+// return "XMLNS_PREFIX";
+// } else if ("xml".equals(prefix[1])) {
+// return "XML_PREFIX";
+// } else if ("xlink".equals(prefix[1])) {
+// return "XLINK_PREFIX";
+// } else {
+// throw new IllegalStateException();
+// }
+// } else if (prefix[0] == null && prefix[1] == null && prefix[2] == null
+// && prefix[3] == "xml") {
+// return "LANG_PREFIX";
+// } else {
+// throw new IllegalStateException();
+// }
+// }
+//
+// private String formatLocal() {
+// if (local[0] == local[1] && local[0] == local[3]
+// && local[0] != local[2]) {
+// return "SVG_DIFFERENT(\"" + local[0] + "\", \"" + local[2] + "\")";
+// }
+// if (local[0] == local[2] && local[0] == local[3]
+// && local[0] != local[1]) {
+// return "MATH_DIFFERENT(\"" + local[0] + "\", \"" + local[1] + "\")";
+// }
+// if (local[0] == local[3] && local[1] == local[2]
+// && local[0] != local[1]) {
+// return "COLONIFIED_LOCAL(\"" + local[0] + "\", \"" + local[1]
+// + "\")";
+// }
+// for (int i = 1; i < local.length; i++) {
+// if (local[0] != local[i]) {
+// throw new IllegalStateException();
+// }
+// }
+// return "SAME_LOCAL(\"" + local[0] + "\")";
+// }
+//
+// private String formatNs() {
+// if (uri[0] == "" && uri[1] == "" && uri[2] == "" && uri[3] == "") {
+// return "ALL_NO_NS";
+// } else if (uri[0] == "" && uri[1] == uri[2] && uri[3] == "") {
+// if ("http://www.w3.org/2000/xmlns/".equals(uri[1])) {
+// return "XMLNS_NS";
+// } else if ("http://www.w3.org/XML/1998/namespace".equals(uri[1])) {
+// return "XML_NS";
+// } else if ("http://www.w3.org/1999/xlink".equals(uri[1])) {
+// return "XLINK_NS";
+// } else {
+// throw new IllegalStateException();
+// }
+// } else if (uri[0] == "" && uri[1] == "" && uri[2] == ""
+// && uri[3] == "http://www.w3.org/XML/1998/namespace") {
+// return "LANG_NS";
+// } else {
+// throw new IllegalStateException();
+// }
+// }
+//
+// private String constName() {
+// String name = getLocal(HTML);
+// char[] buf = new char[name.length()];
+// for (int i = 0; i < name.length(); i++) {
+// char c = name.charAt(i);
+// if (c == '-' || c == ':') {
+// buf[i] = '_';
+// } else if (c >= 'a' && c <= 'z') {
+// buf[i] = (char) (c - 0x20);
+// } else {
+// buf[i] = c;
+// }
+// }
+// return new String(buf);
+// }
+//
+// private int hash() {
+// String name = getLocal(HTML);
+// return bufToHash(name.toCharArray(), name.length());
+// }
+//
+// /**
+// * Regenerate self
+// *
+// * @param args
+// */
+// public static void main(String[] args) {
+// Arrays.sort(ATTRIBUTE_NAMES);
+// for (int i = 1; i < ATTRIBUTE_NAMES.length; i++) {
+// if (ATTRIBUTE_NAMES[i].hash() == ATTRIBUTE_NAMES[i - 1].hash()) {
+// System.err.println("Hash collision: "
+// + ATTRIBUTE_NAMES[i].getLocal(HTML) + ", "
+// + ATTRIBUTE_NAMES[i - 1].getLocal(HTML));
+// return;
+// }
+// }
+// for (int i = 0; i < ATTRIBUTE_NAMES.length; i++) {
+// AttributeName att = ATTRIBUTE_NAMES[i];
+// System.out.println("public static final AttributeName "
+// + att.constName() + " = new AttributeName" + att.toString()
+// + ";");
+// }
+// System.out.println("private final static @NoLength AttributeName[] ATTRIBUTE_NAMES = {");
+// for (int i = 0; i < ATTRIBUTE_NAMES.length; i++) {
+// AttributeName att = ATTRIBUTE_NAMES[i];
+// System.out.println(att.constName() + ",");
+// }
+// System.out.println("};");
+// System.out.println("private final static int[] ATTRIBUTE_HASHES = {");
+// for (int i = 0; i < ATTRIBUTE_NAMES.length; i++) {
+// AttributeName att = ATTRIBUTE_NAMES[i];
+// System.out.println(Integer.toString(att.hash()) + ",");
+// }
+// System.out.println("};");
+// }
+
+ // START GENERATED CODE
+ public static final AttributeName D = new AttributeName(ALL_NO_NS, SAME_LOCAL("d"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName K = new AttributeName(ALL_NO_NS, SAME_LOCAL("k"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName R = new AttributeName(ALL_NO_NS, SAME_LOCAL("r"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName X = new AttributeName(ALL_NO_NS, SAME_LOCAL("x"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName Y = new AttributeName(ALL_NO_NS, SAME_LOCAL("y"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName Z = new AttributeName(ALL_NO_NS, SAME_LOCAL("z"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName BY = new AttributeName(ALL_NO_NS, SAME_LOCAL("by"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CX = new AttributeName(ALL_NO_NS, SAME_LOCAL("cx"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CY = new AttributeName(ALL_NO_NS, SAME_LOCAL("cy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DX = new AttributeName(ALL_NO_NS, SAME_LOCAL("dx"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DY = new AttributeName(ALL_NO_NS, SAME_LOCAL("dy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName G2 = new AttributeName(ALL_NO_NS, SAME_LOCAL("g2"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName G1 = new AttributeName(ALL_NO_NS, SAME_LOCAL("g1"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FX = new AttributeName(ALL_NO_NS, SAME_LOCAL("fx"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FY = new AttributeName(ALL_NO_NS, SAME_LOCAL("fy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName K4 = new AttributeName(ALL_NO_NS, SAME_LOCAL("k4"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName K2 = new AttributeName(ALL_NO_NS, SAME_LOCAL("k2"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName K3 = new AttributeName(ALL_NO_NS, SAME_LOCAL("k3"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName K1 = new AttributeName(ALL_NO_NS, SAME_LOCAL("k1"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ID = new AttributeName(ALL_NO_NS, SAME_LOCAL("id"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName IN = new AttributeName(ALL_NO_NS, SAME_LOCAL("in"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName U2 = new AttributeName(ALL_NO_NS, SAME_LOCAL("u2"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName U1 = new AttributeName(ALL_NO_NS, SAME_LOCAL("u1"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName RT = new AttributeName(ALL_NO_NS, SAME_LOCAL("rt"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName RX = new AttributeName(ALL_NO_NS, SAME_LOCAL("rx"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName RY = new AttributeName(ALL_NO_NS, SAME_LOCAL("ry"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName TO = new AttributeName(ALL_NO_NS, SAME_LOCAL("to"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName Y2 = new AttributeName(ALL_NO_NS, SAME_LOCAL("y2"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName Y1 = new AttributeName(ALL_NO_NS, SAME_LOCAL("y1"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName X1 = new AttributeName(ALL_NO_NS, SAME_LOCAL("x1"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName X2 = new AttributeName(ALL_NO_NS, SAME_LOCAL("x2"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ALT = new AttributeName(ALL_NO_NS, SAME_LOCAL("alt"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DIR = new AttributeName(ALL_NO_NS, SAME_LOCAL("dir"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName DUR = new AttributeName(ALL_NO_NS, SAME_LOCAL("dur"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName END = new AttributeName(ALL_NO_NS, SAME_LOCAL("end"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("for"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName IN2 = new AttributeName(ALL_NO_NS, SAME_LOCAL("in2"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MAX = new AttributeName(ALL_NO_NS, SAME_LOCAL("max"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("min"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LOW = new AttributeName(ALL_NO_NS, SAME_LOCAL("low"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName REL = new AttributeName(ALL_NO_NS, SAME_LOCAL("rel"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName REV = new AttributeName(ALL_NO_NS, SAME_LOCAL("rev"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SRC = new AttributeName(ALL_NO_NS, SAME_LOCAL("src"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName AXIS = new AttributeName(ALL_NO_NS, SAME_LOCAL("axis"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ABBR = new AttributeName(ALL_NO_NS, SAME_LOCAL("abbr"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName BBOX = new AttributeName(ALL_NO_NS, SAME_LOCAL("bbox"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CITE = new AttributeName(ALL_NO_NS, SAME_LOCAL("cite"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CODE = new AttributeName(ALL_NO_NS, SAME_LOCAL("code"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName BIAS = new AttributeName(ALL_NO_NS, SAME_LOCAL("bias"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName COLS = new AttributeName(ALL_NO_NS, SAME_LOCAL("cols"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CLIP = new AttributeName(ALL_NO_NS, SAME_LOCAL("clip"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CHAR = new AttributeName(ALL_NO_NS, SAME_LOCAL("char"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName BASE = new AttributeName(ALL_NO_NS, SAME_LOCAL("base"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName EDGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("edge"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DATA = new AttributeName(ALL_NO_NS, SAME_LOCAL("data"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FILL = new AttributeName(ALL_NO_NS, SAME_LOCAL("fill"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FROM = new AttributeName(ALL_NO_NS, SAME_LOCAL("from"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FORM = new AttributeName(ALL_NO_NS, SAME_LOCAL("form"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("face"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName HIGH = new AttributeName(ALL_NO_NS, SAME_LOCAL("high"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName HREF = new AttributeName(ALL_NO_NS, SAME_LOCAL("href"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName OPEN = new AttributeName(ALL_NO_NS, SAME_LOCAL("open"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ICON = new AttributeName(ALL_NO_NS, SAME_LOCAL("icon"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName NAME = new AttributeName(ALL_NO_NS, SAME_LOCAL("name"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MODE = new AttributeName(ALL_NO_NS, SAME_LOCAL("mode"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MASK = new AttributeName(ALL_NO_NS, SAME_LOCAL("mask"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LINK = new AttributeName(ALL_NO_NS, SAME_LOCAL("link"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LANG = new AttributeName(LANG_NS, SAME_LOCAL("lang"), LANG_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LOOP = new AttributeName(ALL_NO_NS, SAME_LOCAL("loop"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LIST = new AttributeName(ALL_NO_NS, SAME_LOCAL("list"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName TYPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("type"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName WHEN = new AttributeName(ALL_NO_NS, SAME_LOCAL("when"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName WRAP = new AttributeName(ALL_NO_NS, SAME_LOCAL("wrap"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName TEXT = new AttributeName(ALL_NO_NS, SAME_LOCAL("text"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName PATH = new AttributeName(ALL_NO_NS, SAME_LOCAL("path"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName PING = new AttributeName(ALL_NO_NS, SAME_LOCAL("ping"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName REFX = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("refx", "refX"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName REFY = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("refy", "refY"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("size"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SEED = new AttributeName(ALL_NO_NS, SAME_LOCAL("seed"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ROWS = new AttributeName(ALL_NO_NS, SAME_LOCAL("rows"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SPAN = new AttributeName(ALL_NO_NS, SAME_LOCAL("span"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STEP = new AttributeName(ALL_NO_NS, SAME_LOCAL("step"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName ROLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("role"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName XREF = new AttributeName(ALL_NO_NS, SAME_LOCAL("xref"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ASYNC = new AttributeName(ALL_NO_NS, SAME_LOCAL("async"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName ALINK = new AttributeName(ALL_NO_NS, SAME_LOCAL("alink"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ALIGN = new AttributeName(ALL_NO_NS, SAME_LOCAL("align"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName CLOSE = new AttributeName(ALL_NO_NS, SAME_LOCAL("close"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName COLOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("color"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CLASS = new AttributeName(ALL_NO_NS, SAME_LOCAL("class"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CLEAR = new AttributeName(ALL_NO_NS, SAME_LOCAL("clear"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName BEGIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("begin"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DEPTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("depth"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DEFER = new AttributeName(ALL_NO_NS, SAME_LOCAL("defer"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName FENCE = new AttributeName(ALL_NO_NS, SAME_LOCAL("fence"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FRAME = new AttributeName(ALL_NO_NS, SAME_LOCAL("frame"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName ISMAP = new AttributeName(ALL_NO_NS, SAME_LOCAL("ismap"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName ONEND = new AttributeName(ALL_NO_NS, SAME_LOCAL("onend"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName INDEX = new AttributeName(ALL_NO_NS, SAME_LOCAL("index"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ORDER = new AttributeName(ALL_NO_NS, SAME_LOCAL("order"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName OTHER = new AttributeName(ALL_NO_NS, SAME_LOCAL("other"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONCUT = new AttributeName(ALL_NO_NS, SAME_LOCAL("oncut"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName NARGS = new AttributeName(ALL_NO_NS, SAME_LOCAL("nargs"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MEDIA = new AttributeName(ALL_NO_NS, SAME_LOCAL("media"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LABEL = new AttributeName(ALL_NO_NS, SAME_LOCAL("label"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LOCAL = new AttributeName(ALL_NO_NS, SAME_LOCAL("local"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName WIDTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("width"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName TITLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("title"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VLINK = new AttributeName(ALL_NO_NS, SAME_LOCAL("vlink"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VALUE = new AttributeName(ALL_NO_NS, SAME_LOCAL("value"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SLOPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("slope"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SHAPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("shape"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName SCOPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("scope"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName SCALE = new AttributeName(ALL_NO_NS, SAME_LOCAL("scale"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SPEED = new AttributeName(ALL_NO_NS, SAME_LOCAL("speed"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STYLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("style"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName RULES = new AttributeName(ALL_NO_NS, SAME_LOCAL("rules"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName STEMH = new AttributeName(ALL_NO_NS, SAME_LOCAL("stemh"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SIZES = new AttributeName(ALL_NO_NS, SAME_LOCAL("sizes"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STEMV = new AttributeName(ALL_NO_NS, SAME_LOCAL("stemv"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName START = new AttributeName(ALL_NO_NS, SAME_LOCAL("start"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName XMLNS = new AttributeName(XMLNS_NS, SAME_LOCAL("xmlns"), ALL_NO_PREFIX, IS_XMLNS);
+ public static final AttributeName ACCEPT = new AttributeName(ALL_NO_NS, SAME_LOCAL("accept"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ACCENT = new AttributeName(ALL_NO_NS, SAME_LOCAL("accent"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ASCENT = new AttributeName(ALL_NO_NS, SAME_LOCAL("ascent"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ACTIVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("active"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName ALTIMG = new AttributeName(ALL_NO_NS, SAME_LOCAL("altimg"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ACTION = new AttributeName(ALL_NO_NS, SAME_LOCAL("action"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName BORDER = new AttributeName(ALL_NO_NS, SAME_LOCAL("border"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CURSOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("cursor"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName COORDS = new AttributeName(ALL_NO_NS, SAME_LOCAL("coords"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FILTER = new AttributeName(ALL_NO_NS, SAME_LOCAL("filter"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FORMAT = new AttributeName(ALL_NO_NS, SAME_LOCAL("format"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName HIDDEN = new AttributeName(ALL_NO_NS, SAME_LOCAL("hidden"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName HSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("hspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName HEIGHT = new AttributeName(ALL_NO_NS, SAME_LOCAL("height"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONMOVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmove"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONLOAD = new AttributeName(ALL_NO_NS, SAME_LOCAL("onload"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONDRAG = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondrag"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ORIGIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("origin"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONZOOM = new AttributeName(ALL_NO_NS, SAME_LOCAL("onzoom"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONHELP = new AttributeName(ALL_NO_NS, SAME_LOCAL("onhelp"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONSTOP = new AttributeName(ALL_NO_NS, SAME_LOCAL("onstop"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONDROP = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondrop"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONBLUR = new AttributeName(ALL_NO_NS, SAME_LOCAL("onblur"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName OBJECT = new AttributeName(ALL_NO_NS, SAME_LOCAL("object"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName OFFSET = new AttributeName(ALL_NO_NS, SAME_LOCAL("offset"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ORIENT = new AttributeName(ALL_NO_NS, SAME_LOCAL("orient"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONCOPY = new AttributeName(ALL_NO_NS, SAME_LOCAL("oncopy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName NOWRAP = new AttributeName(ALL_NO_NS, SAME_LOCAL("nowrap"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName NOHREF = new AttributeName(ALL_NO_NS, SAME_LOCAL("nohref"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName MACROS = new AttributeName(ALL_NO_NS, SAME_LOCAL("macros"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName METHOD = new AttributeName(ALL_NO_NS, SAME_LOCAL("method"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName LOWSRC = new AttributeName(ALL_NO_NS, SAME_LOCAL("lowsrc"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("lspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LQUOTE = new AttributeName(ALL_NO_NS, SAME_LOCAL("lquote"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName USEMAP = new AttributeName(ALL_NO_NS, SAME_LOCAL("usemap"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName WIDTHS = new AttributeName(ALL_NO_NS, SAME_LOCAL("widths"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName TARGET = new AttributeName(ALL_NO_NS, SAME_LOCAL("target"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VALUES = new AttributeName(ALL_NO_NS, SAME_LOCAL("values"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VALIGN = new AttributeName(ALL_NO_NS, SAME_LOCAL("valign"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName VSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("vspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName POSTER = new AttributeName(ALL_NO_NS, SAME_LOCAL("poster"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName POINTS = new AttributeName(ALL_NO_NS, SAME_LOCAL("points"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName PROMPT = new AttributeName(ALL_NO_NS, SAME_LOCAL("prompt"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SRCDOC = new AttributeName(ALL_NO_NS, SAME_LOCAL("srcdoc"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SCOPED = new AttributeName(ALL_NO_NS, SAME_LOCAL("scoped"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STRING = new AttributeName(ALL_NO_NS, SAME_LOCAL("string"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SCHEME = new AttributeName(ALL_NO_NS, SAME_LOCAL("scheme"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STROKE = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName RADIUS = new AttributeName(ALL_NO_NS, SAME_LOCAL("radius"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName RESULT = new AttributeName(ALL_NO_NS, SAME_LOCAL("result"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName REPEAT = new AttributeName(ALL_NO_NS, SAME_LOCAL("repeat"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SRCSET = new AttributeName(ALL_NO_NS, SAME_LOCAL("srcset"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName RSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("rspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ROTATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("rotate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName RQUOTE = new AttributeName(ALL_NO_NS, SAME_LOCAL("rquote"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ALTTEXT = new AttributeName(ALL_NO_NS, SAME_LOCAL("alttext"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARCHIVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("archive"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName AZIMUTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("azimuth"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CLOSURE = new AttributeName(ALL_NO_NS, SAME_LOCAL("closure"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CHECKED = new AttributeName(ALL_NO_NS, SAME_LOCAL("checked"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName CLASSID = new AttributeName(ALL_NO_NS, SAME_LOCAL("classid"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CHAROFF = new AttributeName(ALL_NO_NS, SAME_LOCAL("charoff"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName BGCOLOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("bgcolor"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName COLSPAN = new AttributeName(ALL_NO_NS, SAME_LOCAL("colspan"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CHARSET = new AttributeName(ALL_NO_NS, SAME_LOCAL("charset"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName COMPACT = new AttributeName(ALL_NO_NS, SAME_LOCAL("compact"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName CONTENT = new AttributeName(ALL_NO_NS, SAME_LOCAL("content"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ENCTYPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("enctype"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName DATASRC = new AttributeName(ALL_NO_NS, SAME_LOCAL("datasrc"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DATAFLD = new AttributeName(ALL_NO_NS, SAME_LOCAL("datafld"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DECLARE = new AttributeName(ALL_NO_NS, SAME_LOCAL("declare"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName DISPLAY = new AttributeName(ALL_NO_NS, SAME_LOCAL("display"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DIVISOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("divisor"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DEFAULT = new AttributeName(ALL_NO_NS, SAME_LOCAL("default"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName DESCENT = new AttributeName(ALL_NO_NS, SAME_LOCAL("descent"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName KERNING = new AttributeName(ALL_NO_NS, SAME_LOCAL("kerning"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName HANGING = new AttributeName(ALL_NO_NS, SAME_LOCAL("hanging"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName HEADERS = new AttributeName(ALL_NO_NS, SAME_LOCAL("headers"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONPASTE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onpaste"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONCLICK = new AttributeName(ALL_NO_NS, SAME_LOCAL("onclick"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName OPTIMUM = new AttributeName(ALL_NO_NS, SAME_LOCAL("optimum"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONBEGIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbegin"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONKEYUP = new AttributeName(ALL_NO_NS, SAME_LOCAL("onkeyup"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONFOCUS = new AttributeName(ALL_NO_NS, SAME_LOCAL("onfocus"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONERROR = new AttributeName(ALL_NO_NS, SAME_LOCAL("onerror"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONINPUT = new AttributeName(ALL_NO_NS, SAME_LOCAL("oninput"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONABORT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onabort"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONSTART = new AttributeName(ALL_NO_NS, SAME_LOCAL("onstart"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONRESET = new AttributeName(ALL_NO_NS, SAME_LOCAL("onreset"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName OPACITY = new AttributeName(ALL_NO_NS, SAME_LOCAL("opacity"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName NOSHADE = new AttributeName(ALL_NO_NS, SAME_LOCAL("noshade"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName MINSIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("minsize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MAXSIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("maxsize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LARGEOP = new AttributeName(ALL_NO_NS, SAME_LOCAL("largeop"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName UNICODE = new AttributeName(ALL_NO_NS, SAME_LOCAL("unicode"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName TARGETX = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("targetx", "targetX"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName TARGETY = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("targety", "targetY"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VIEWBOX = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("viewbox", "viewBox"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VERSION = new AttributeName(ALL_NO_NS, SAME_LOCAL("version"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName PATTERN = new AttributeName(ALL_NO_NS, SAME_LOCAL("pattern"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName PROFILE = new AttributeName(ALL_NO_NS, SAME_LOCAL("profile"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SPACING = new AttributeName(ALL_NO_NS, SAME_LOCAL("spacing"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName RESTART = new AttributeName(ALL_NO_NS, SAME_LOCAL("restart"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ROWSPAN = new AttributeName(ALL_NO_NS, SAME_LOCAL("rowspan"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SANDBOX = new AttributeName(ALL_NO_NS, SAME_LOCAL("sandbox"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SUMMARY = new AttributeName(ALL_NO_NS, SAME_LOCAL("summary"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STANDBY = new AttributeName(ALL_NO_NS, SAME_LOCAL("standby"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName REPLACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("replace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName AUTOPLAY = new AttributeName(ALL_NO_NS, SAME_LOCAL("autoplay"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ADDITIVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("additive"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CALCMODE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("calcmode", "calcMode"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CODETYPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("codetype"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CODEBASE = new AttributeName(ALL_NO_NS, SAME_LOCAL("codebase"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CONTROLS = new AttributeName(ALL_NO_NS, SAME_LOCAL("controls"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName BEVELLED = new AttributeName(ALL_NO_NS, SAME_LOCAL("bevelled"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName BASELINE = new AttributeName(ALL_NO_NS, SAME_LOCAL("baseline"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName EXPONENT = new AttributeName(ALL_NO_NS, SAME_LOCAL("exponent"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName EDGEMODE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("edgemode", "edgeMode"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ENCODING = new AttributeName(ALL_NO_NS, SAME_LOCAL("encoding"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName GLYPHREF = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("glyphref", "glyphRef"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DATETIME = new AttributeName(ALL_NO_NS, SAME_LOCAL("datetime"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DISABLED = new AttributeName(ALL_NO_NS, SAME_LOCAL("disabled"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName FONTSIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("fontsize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName KEYTIMES = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("keytimes", "keyTimes"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName PANOSE_1 = new AttributeName(ALL_NO_NS, SAME_LOCAL("panose-1"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName HREFLANG = new AttributeName(ALL_NO_NS, SAME_LOCAL("hreflang"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONRESIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onresize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONCHANGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onchange"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONBOUNCE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbounce"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONUNLOAD = new AttributeName(ALL_NO_NS, SAME_LOCAL("onunload"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONFINISH = new AttributeName(ALL_NO_NS, SAME_LOCAL("onfinish"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONSCROLL = new AttributeName(ALL_NO_NS, SAME_LOCAL("onscroll"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName OPERATOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("operator"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName OVERFLOW = new AttributeName(ALL_NO_NS, SAME_LOCAL("overflow"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONSUBMIT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onsubmit"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONREPEAT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onrepeat"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONSELECT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onselect"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName NOTATION = new AttributeName(ALL_NO_NS, SAME_LOCAL("notation"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName NORESIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("noresize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName MANIFEST = new AttributeName(ALL_NO_NS, SAME_LOCAL("manifest"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MATHSIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("mathsize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MULTIPLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("multiple"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName LONGDESC = new AttributeName(ALL_NO_NS, SAME_LOCAL("longdesc"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LANGUAGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("language"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName TEMPLATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("template"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName TABINDEX = new AttributeName(ALL_NO_NS, SAME_LOCAL("tabindex"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName PROPERTY = new AttributeName(ALL_NO_NS, SAME_LOCAL("property"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName READONLY = new AttributeName(ALL_NO_NS, SAME_LOCAL("readonly"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName SELECTED = new AttributeName(ALL_NO_NS, SAME_LOCAL("selected"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName ROWLINES = new AttributeName(ALL_NO_NS, SAME_LOCAL("rowlines"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SEAMLESS = new AttributeName(ALL_NO_NS, SAME_LOCAL("seamless"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ROWALIGN = new AttributeName(ALL_NO_NS, SAME_LOCAL("rowalign"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STRETCHY = new AttributeName(ALL_NO_NS, SAME_LOCAL("stretchy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName REQUIRED = new AttributeName(ALL_NO_NS, SAME_LOCAL("required"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName XML_BASE = new AttributeName(XML_NS, COLONIFIED_LOCAL("xml:base", "base"), XML_PREFIX, NCNAME_FOREIGN);
+ public static final AttributeName XML_LANG = new AttributeName(XML_NS, COLONIFIED_LOCAL("xml:lang", "lang"), XML_PREFIX, NCNAME_FOREIGN);
+ public static final AttributeName X_HEIGHT = new AttributeName(ALL_NO_NS, SAME_LOCAL("x-height"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_OWNS = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-owns"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName AUTOFOCUS = new AttributeName(ALL_NO_NS, SAME_LOCAL("autofocus"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName ARIA_SORT = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-sort"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ACCESSKEY = new AttributeName(ALL_NO_NS, SAME_LOCAL("accesskey"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_BUSY = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-busy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_GRAB = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-grab"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName AMPLITUDE = new AttributeName(ALL_NO_NS, SAME_LOCAL("amplitude"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_LIVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-live"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CLIP_RULE = new AttributeName(ALL_NO_NS, SAME_LOCAL("clip-rule"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CLIP_PATH = new AttributeName(ALL_NO_NS, SAME_LOCAL("clip-path"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName EQUALROWS = new AttributeName(ALL_NO_NS, SAME_LOCAL("equalrows"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ELEVATION = new AttributeName(ALL_NO_NS, SAME_LOCAL("elevation"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DIRECTION = new AttributeName(ALL_NO_NS, SAME_LOCAL("direction"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DRAGGABLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("draggable"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FILL_RULE = new AttributeName(ALL_NO_NS, SAME_LOCAL("fill-rule"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FONTSTYLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("fontstyle"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FONT_SIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("font-size"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName KEYSYSTEM = new AttributeName(ALL_NO_NS, SAME_LOCAL("keysystem"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName KEYPOINTS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("keypoints", "keyPoints"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName HIDEFOCUS = new AttributeName(ALL_NO_NS, SAME_LOCAL("hidefocus"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONMESSAGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmessage"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName INTERCEPT = new AttributeName(ALL_NO_NS, SAME_LOCAL("intercept"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONDRAGEND = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondragend"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONMOVEEND = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmoveend"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONINVALID = new AttributeName(ALL_NO_NS, SAME_LOCAL("oninvalid"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName INTEGRITY = new AttributeName(ALL_NO_NS, SAME_LOCAL("integrity"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONKEYDOWN = new AttributeName(ALL_NO_NS, SAME_LOCAL("onkeydown"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONFOCUSIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("onfocusin"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONMOUSEUP = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmouseup"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName INPUTMODE = new AttributeName(ALL_NO_NS, SAME_LOCAL("inputmode"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONROWEXIT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onrowexit"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MATHCOLOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("mathcolor"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MASKUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("maskunits", "maskUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MAXLENGTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("maxlength"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LINEBREAK = new AttributeName(ALL_NO_NS, SAME_LOCAL("linebreak"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName TRANSFORM = new AttributeName(ALL_NO_NS, SAME_LOCAL("transform"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName V_HANGING = new AttributeName(ALL_NO_NS, SAME_LOCAL("v-hanging"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VALUETYPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("valuetype"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName POINTSATZ = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("pointsatz", "pointsAtZ"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName POINTSATX = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("pointsatx", "pointsAtX"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName POINTSATY = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("pointsaty", "pointsAtY"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SYMMETRIC = new AttributeName(ALL_NO_NS, SAME_LOCAL("symmetric"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SCROLLING = new AttributeName(ALL_NO_NS, SAME_LOCAL("scrolling"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName REPEATDUR = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("repeatdur", "repeatDur"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SELECTION = new AttributeName(ALL_NO_NS, SAME_LOCAL("selection"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SEPARATOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("separator"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName XML_SPACE = new AttributeName(XML_NS, COLONIFIED_LOCAL("xml:space", "space"), XML_PREFIX, NCNAME_FOREIGN);
+ public static final AttributeName AUTOSUBMIT = new AttributeName(ALL_NO_NS, SAME_LOCAL("autosubmit"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+ public static final AttributeName ALPHABETIC = new AttributeName(ALL_NO_NS, SAME_LOCAL("alphabetic"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ACTIONTYPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("actiontype"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ACCUMULATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("accumulate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_LEVEL = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-level"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName COLUMNSPAN = new AttributeName(ALL_NO_NS, SAME_LOCAL("columnspan"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CAP_HEIGHT = new AttributeName(ALL_NO_NS, SAME_LOCAL("cap-height"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName BACKGROUND = new AttributeName(ALL_NO_NS, SAME_LOCAL("background"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName GLYPH_NAME = new AttributeName(ALL_NO_NS, SAME_LOCAL("glyph-name"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName GROUPALIGN = new AttributeName(ALL_NO_NS, SAME_LOCAL("groupalign"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FONTFAMILY = new AttributeName(ALL_NO_NS, SAME_LOCAL("fontfamily"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FONTWEIGHT = new AttributeName(ALL_NO_NS, SAME_LOCAL("fontweight"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FONT_STYLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("font-style"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName KEYSPLINES = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("keysplines", "keySplines"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName HTTP_EQUIV = new AttributeName(ALL_NO_NS, SAME_LOCAL("http-equiv"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONACTIVATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onactivate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName OCCURRENCE = new AttributeName(ALL_NO_NS, SAME_LOCAL("occurrence"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName IRRELEVANT = new AttributeName(ALL_NO_NS, SAME_LOCAL("irrelevant"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONDBLCLICK = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondblclick"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONDRAGDROP = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondragdrop"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONKEYPRESS = new AttributeName(ALL_NO_NS, SAME_LOCAL("onkeypress"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONROWENTER = new AttributeName(ALL_NO_NS, SAME_LOCAL("onrowenter"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONDRAGOVER = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondragover"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONFOCUSOUT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onfocusout"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONMOUSEOUT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmouseout"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName NUMOCTAVES = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("numoctaves", "numOctaves"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MARKER_MID = new AttributeName(ALL_NO_NS, SAME_LOCAL("marker-mid"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MARKER_END = new AttributeName(ALL_NO_NS, SAME_LOCAL("marker-end"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName TEXTLENGTH = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("textlength", "textLength"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VISIBILITY = new AttributeName(ALL_NO_NS, SAME_LOCAL("visibility"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VIEWTARGET = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("viewtarget", "viewTarget"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VERT_ADV_Y = new AttributeName(ALL_NO_NS, SAME_LOCAL("vert-adv-y"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName PATHLENGTH = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("pathlength", "pathLength"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName REPEAT_MAX = new AttributeName(ALL_NO_NS, SAME_LOCAL("repeat-max"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName RADIOGROUP = new AttributeName(ALL_NO_NS, SAME_LOCAL("radiogroup"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STOP_COLOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("stop-color"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SEPARATORS = new AttributeName(ALL_NO_NS, SAME_LOCAL("separators"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName REPEAT_MIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("repeat-min"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ROWSPACING = new AttributeName(ALL_NO_NS, SAME_LOCAL("rowspacing"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ZOOMANDPAN = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("zoomandpan", "zoomAndPan"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName XLINK_TYPE = new AttributeName(XLINK_NS, COLONIFIED_LOCAL("xlink:type", "type"), XLINK_PREFIX, NCNAME_FOREIGN);
+ public static final AttributeName XLINK_ROLE = new AttributeName(XLINK_NS, COLONIFIED_LOCAL("xlink:role", "role"), XLINK_PREFIX, NCNAME_FOREIGN);
+ public static final AttributeName XLINK_HREF = new AttributeName(XLINK_NS, COLONIFIED_LOCAL("xlink:href", "href"), XLINK_PREFIX, NCNAME_FOREIGN);
+ public static final AttributeName XLINK_SHOW = new AttributeName(XLINK_NS, COLONIFIED_LOCAL("xlink:show", "show"), XLINK_PREFIX, NCNAME_FOREIGN);
+ public static final AttributeName ACCENTUNDER = new AttributeName(ALL_NO_NS, SAME_LOCAL("accentunder"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_SECRET = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-secret"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_ATOMIC = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-atomic"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_HIDDEN = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-hidden"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_FLOWTO = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-flowto"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARABIC_FORM = new AttributeName(ALL_NO_NS, SAME_LOCAL("arabic-form"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CELLPADDING = new AttributeName(ALL_NO_NS, SAME_LOCAL("cellpadding"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CELLSPACING = new AttributeName(ALL_NO_NS, SAME_LOCAL("cellspacing"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName COLUMNWIDTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("columnwidth"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CROSSORIGIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("crossorigin"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName COLUMNALIGN = new AttributeName(ALL_NO_NS, SAME_LOCAL("columnalign"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName COLUMNLINES = new AttributeName(ALL_NO_NS, SAME_LOCAL("columnlines"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CONTEXTMENU = new AttributeName(ALL_NO_NS, SAME_LOCAL("contextmenu"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName BASEPROFILE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("baseprofile", "baseProfile"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FONT_FAMILY = new AttributeName(ALL_NO_NS, SAME_LOCAL("font-family"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FRAMEBORDER = new AttributeName(ALL_NO_NS, SAME_LOCAL("frameborder"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FILTERUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("filterunits", "filterUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FLOOD_COLOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("flood-color"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FONT_WEIGHT = new AttributeName(ALL_NO_NS, SAME_LOCAL("font-weight"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName HORIZ_ADV_X = new AttributeName(ALL_NO_NS, SAME_LOCAL("horiz-adv-x"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONDRAGLEAVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondragleave"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONMOUSEMOVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmousemove"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ORIENTATION = new AttributeName(ALL_NO_NS, SAME_LOCAL("orientation"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONMOUSEDOWN = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmousedown"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONMOUSEOVER = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmouseover"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONDRAGENTER = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondragenter"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName IDEOGRAPHIC = new AttributeName(ALL_NO_NS, SAME_LOCAL("ideographic"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONBEFORECUT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforecut"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONFORMINPUT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onforminput"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONDRAGSTART = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondragstart"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONMOVESTART = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmovestart"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MARKERUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("markerunits", "markerUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MATHVARIANT = new AttributeName(ALL_NO_NS, SAME_LOCAL("mathvariant"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MARGINWIDTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("marginwidth"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MARKERWIDTH = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("markerwidth", "markerWidth"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName TEXT_ANCHOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("text-anchor"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName TABLEVALUES = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("tablevalues", "tableValues"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SCRIPTLEVEL = new AttributeName(ALL_NO_NS, SAME_LOCAL("scriptlevel"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName REPEATCOUNT = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("repeatcount", "repeatCount"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STITCHTILES = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("stitchtiles", "stitchTiles"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STARTOFFSET = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("startoffset", "startOffset"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SCROLLDELAY = new AttributeName(ALL_NO_NS, SAME_LOCAL("scrolldelay"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName XMLNS_XLINK = new AttributeName(XMLNS_NS, COLONIFIED_LOCAL("xmlns:xlink", "xlink"), XMLNS_PREFIX, IS_XMLNS);
+ public static final AttributeName XLINK_TITLE = new AttributeName(XLINK_NS, COLONIFIED_LOCAL("xlink:title", "title"), XLINK_PREFIX, NCNAME_FOREIGN);
+ public static final AttributeName ARIA_INVALID = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-invalid"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_PRESSED = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-pressed"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_CHECKED = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-checked"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName AUTOCOMPLETE = new AttributeName(ALL_NO_NS, SAME_LOCAL("autocomplete"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName ARIA_SETSIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-setsize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_CHANNEL = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-channel"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName EQUALCOLUMNS = new AttributeName(ALL_NO_NS, SAME_LOCAL("equalcolumns"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DISPLAYSTYLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("displaystyle"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DATAFORMATAS = new AttributeName(ALL_NO_NS, SAME_LOCAL("dataformatas"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+ public static final AttributeName FILL_OPACITY = new AttributeName(ALL_NO_NS, SAME_LOCAL("fill-opacity"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FONT_VARIANT = new AttributeName(ALL_NO_NS, SAME_LOCAL("font-variant"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FONT_STRETCH = new AttributeName(ALL_NO_NS, SAME_LOCAL("font-stretch"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FRAMESPACING = new AttributeName(ALL_NO_NS, SAME_LOCAL("framespacing"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName KERNELMATRIX = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("kernelmatrix", "kernelMatrix"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONDEACTIVATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondeactivate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONROWSDELETE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onrowsdelete"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONMOUSELEAVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmouseleave"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONFORMCHANGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onformchange"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONCELLCHANGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("oncellchange"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONMOUSEWHEEL = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmousewheel"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONMOUSEENTER = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmouseenter"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONAFTERPRINT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onafterprint"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONBEFORECOPY = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforecopy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MARGINHEIGHT = new AttributeName(ALL_NO_NS, SAME_LOCAL("marginheight"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MARKERHEIGHT = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("markerheight", "markerHeight"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MARKER_START = new AttributeName(ALL_NO_NS, SAME_LOCAL("marker-start"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MATHEMATICAL = new AttributeName(ALL_NO_NS, SAME_LOCAL("mathematical"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LENGTHADJUST = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("lengthadjust", "lengthAdjust"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName UNSELECTABLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("unselectable"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName UNICODE_BIDI = new AttributeName(ALL_NO_NS, SAME_LOCAL("unicode-bidi"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName UNITS_PER_EM = new AttributeName(ALL_NO_NS, SAME_LOCAL("units-per-em"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName WORD_SPACING = new AttributeName(ALL_NO_NS, SAME_LOCAL("word-spacing"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName WRITING_MODE = new AttributeName(ALL_NO_NS, SAME_LOCAL("writing-mode"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName V_ALPHABETIC = new AttributeName(ALL_NO_NS, SAME_LOCAL("v-alphabetic"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName PATTERNUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("patternunits", "patternUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SPREADMETHOD = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("spreadmethod", "spreadMethod"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SURFACESCALE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("surfacescale", "surfaceScale"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STROKE_WIDTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke-width"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName REPEAT_START = new AttributeName(ALL_NO_NS, SAME_LOCAL("repeat-start"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STDDEVIATION = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("stddeviation", "stdDeviation"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STOP_OPACITY = new AttributeName(ALL_NO_NS, SAME_LOCAL("stop-opacity"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_CONTROLS = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-controls"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_HASPOPUP = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-haspopup"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ACCENT_HEIGHT = new AttributeName(ALL_NO_NS, SAME_LOCAL("accent-height"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_VALUENOW = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-valuenow"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_RELEVANT = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-relevant"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_POSINSET = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-posinset"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_VALUEMAX = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-valuemax"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_READONLY = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-readonly"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_SELECTED = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-selected"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_REQUIRED = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-required"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_EXPANDED = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-expanded"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_DISABLED = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-disabled"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ATTRIBUTETYPE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("attributetype", "attributeType"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ATTRIBUTENAME = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("attributename", "attributeName"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_DATATYPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-datatype"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_VALUEMIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-valuemin"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName BASEFREQUENCY = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("basefrequency", "baseFrequency"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName COLUMNSPACING = new AttributeName(ALL_NO_NS, SAME_LOCAL("columnspacing"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName COLOR_PROFILE = new AttributeName(ALL_NO_NS, SAME_LOCAL("color-profile"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CLIPPATHUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("clippathunits", "clipPathUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DEFINITIONURL = new AttributeName(ALL_NO_NS, MATH_DIFFERENT("definitionurl", "definitionURL"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName GRADIENTUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("gradientunits", "gradientUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FLOOD_OPACITY = new AttributeName(ALL_NO_NS, SAME_LOCAL("flood-opacity"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONAFTERUPDATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onafterupdate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONERRORUPDATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onerrorupdate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONBEFOREPASTE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforepaste"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONLOSECAPTURE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onlosecapture"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONCONTEXTMENU = new AttributeName(ALL_NO_NS, SAME_LOCAL("oncontextmenu"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONSELECTSTART = new AttributeName(ALL_NO_NS, SAME_LOCAL("onselectstart"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONBEFOREPRINT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforeprint"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MOVABLELIMITS = new AttributeName(ALL_NO_NS, SAME_LOCAL("movablelimits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LINETHICKNESS = new AttributeName(ALL_NO_NS, SAME_LOCAL("linethickness"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName UNICODE_RANGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("unicode-range"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName THINMATHSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("thinmathspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VERT_ORIGIN_X = new AttributeName(ALL_NO_NS, SAME_LOCAL("vert-origin-x"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VERT_ORIGIN_Y = new AttributeName(ALL_NO_NS, SAME_LOCAL("vert-origin-y"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName V_IDEOGRAPHIC = new AttributeName(ALL_NO_NS, SAME_LOCAL("v-ideographic"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName PRESERVEALPHA = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("preservealpha", "preserveAlpha"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SCRIPTMINSIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("scriptminsize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SPECIFICATION = new AttributeName(ALL_NO_NS, SAME_LOCAL("specification"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName XLINK_ACTUATE = new AttributeName(XLINK_NS, COLONIFIED_LOCAL("xlink:actuate", "actuate"), XLINK_PREFIX, NCNAME_FOREIGN);
+ public static final AttributeName XLINK_ARCROLE = new AttributeName(XLINK_NS, COLONIFIED_LOCAL("xlink:arcrole", "arcrole"), XLINK_PREFIX, NCNAME_FOREIGN);
+ public static final AttributeName ACCEPT_CHARSET = new AttributeName(ALL_NO_NS, SAME_LOCAL("accept-charset"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ALIGNMENTSCOPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("alignmentscope"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_MULTILINE = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-multiline"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName BASELINE_SHIFT = new AttributeName(ALL_NO_NS, SAME_LOCAL("baseline-shift"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName HORIZ_ORIGIN_X = new AttributeName(ALL_NO_NS, SAME_LOCAL("horiz-origin-x"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName HORIZ_ORIGIN_Y = new AttributeName(ALL_NO_NS, SAME_LOCAL("horiz-origin-y"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONBEFOREUPDATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforeupdate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONFILTERCHANGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onfilterchange"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONROWSINSERTED = new AttributeName(ALL_NO_NS, SAME_LOCAL("onrowsinserted"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONBEFOREUNLOAD = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforeunload"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MATHBACKGROUND = new AttributeName(ALL_NO_NS, SAME_LOCAL("mathbackground"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LETTER_SPACING = new AttributeName(ALL_NO_NS, SAME_LOCAL("letter-spacing"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LIGHTING_COLOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("lighting-color"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName THICKMATHSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("thickmathspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName TEXT_RENDERING = new AttributeName(ALL_NO_NS, SAME_LOCAL("text-rendering"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName V_MATHEMATICAL = new AttributeName(ALL_NO_NS, SAME_LOCAL("v-mathematical"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName POINTER_EVENTS = new AttributeName(ALL_NO_NS, SAME_LOCAL("pointer-events"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName PRIMITIVEUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("primitiveunits", "primitiveUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName REFERRERPOLICY = new AttributeName(ALL_NO_NS, SAME_LOCAL("referrerpolicy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SYSTEMLANGUAGE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("systemlanguage", "systemLanguage"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STROKE_LINECAP = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke-linecap"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SUBSCRIPTSHIFT = new AttributeName(ALL_NO_NS, SAME_LOCAL("subscriptshift"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STROKE_OPACITY = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke-opacity"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_DROPEFFECT = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-dropeffect"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_LABELLEDBY = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-labelledby"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_TEMPLATEID = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-templateid"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName COLOR_RENDERING = new AttributeName(ALL_NO_NS, SAME_LOCAL("color-rendering"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName CONTENTEDITABLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("contenteditable"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DIFFUSECONSTANT = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("diffuseconstant", "diffuseConstant"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONDATAAVAILABLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondataavailable"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONCONTROLSELECT = new AttributeName(ALL_NO_NS, SAME_LOCAL("oncontrolselect"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName IMAGE_RENDERING = new AttributeName(ALL_NO_NS, SAME_LOCAL("image-rendering"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MEDIUMMATHSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("mediummathspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName TEXT_DECORATION = new AttributeName(ALL_NO_NS, SAME_LOCAL("text-decoration"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SHAPE_RENDERING = new AttributeName(ALL_NO_NS, SAME_LOCAL("shape-rendering"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STROKE_LINEJOIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke-linejoin"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName REPEAT_TEMPLATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("repeat-template"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_DESCRIBEDBY = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-describedby"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName FONT_SIZE_ADJUST = new AttributeName(ALL_NO_NS, SAME_LOCAL("font-size-adjust"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName KERNELUNITLENGTH = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("kernelunitlength", "kernelUnitLength"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONBEFOREACTIVATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforeactivate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONPROPERTYCHANGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onpropertychange"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONDATASETCHANGED = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondatasetchanged"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName MASKCONTENTUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("maskcontentunits", "maskContentUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName PATTERNTRANSFORM = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("patterntransform", "patternTransform"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName REQUIREDFEATURES = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("requiredfeatures", "requiredFeatures"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName RENDERING_INTENT = new AttributeName(ALL_NO_NS, SAME_LOCAL("rendering-intent"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SPECULAREXPONENT = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("specularexponent", "specularExponent"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SPECULARCONSTANT = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("specularconstant", "specularConstant"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SUPERSCRIPTSHIFT = new AttributeName(ALL_NO_NS, SAME_LOCAL("superscriptshift"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STROKE_DASHARRAY = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke-dasharray"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName XCHANNELSELECTOR = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("xchannelselector", "xChannelSelector"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName YCHANNELSELECTOR = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("ychannelselector", "yChannelSelector"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_AUTOCOMPLETE = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-autocomplete"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ENABLE_BACKGROUND = new AttributeName(ALL_NO_NS, SAME_LOCAL("enable-background"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName DOMINANT_BASELINE = new AttributeName(ALL_NO_NS, SAME_LOCAL("dominant-baseline"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName GRADIENTTRANSFORM = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("gradienttransform", "gradientTransform"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONBEFORDEACTIVATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbefordeactivate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONDATASETCOMPLETE = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondatasetcomplete"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName OVERLINE_POSITION = new AttributeName(ALL_NO_NS, SAME_LOCAL("overline-position"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONBEFOREEDITFOCUS = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforeeditfocus"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName LIMITINGCONEANGLE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("limitingconeangle", "limitingConeAngle"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VERYTHINMATHSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("verythinmathspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STROKE_DASHOFFSET = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke-dashoffset"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STROKE_MITERLIMIT = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke-miterlimit"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ALIGNMENT_BASELINE = new AttributeName(ALL_NO_NS, SAME_LOCAL("alignment-baseline"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ONREADYSTATECHANGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onreadystatechange"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName OVERLINE_THICKNESS = new AttributeName(ALL_NO_NS, SAME_LOCAL("overline-thickness"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName UNDERLINE_POSITION = new AttributeName(ALL_NO_NS, SAME_LOCAL("underline-position"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VERYTHICKMATHSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("verythickmathspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName REQUIREDEXTENSIONS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("requiredextensions", "requiredExtensions"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName COLOR_INTERPOLATION = new AttributeName(ALL_NO_NS, SAME_LOCAL("color-interpolation"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName UNDERLINE_THICKNESS = new AttributeName(ALL_NO_NS, SAME_LOCAL("underline-thickness"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName PRESERVEASPECTRATIO = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("preserveaspectratio", "preserveAspectRatio"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName PATTERNCONTENTUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("patterncontentunits", "patternContentUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_MULTISELECTABLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-multiselectable"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName SCRIPTSIZEMULTIPLIER = new AttributeName(ALL_NO_NS, SAME_LOCAL("scriptsizemultiplier"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName ARIA_ACTIVEDESCENDANT = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-activedescendant"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VERYVERYTHINMATHSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("veryverythinmathspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName VERYVERYTHICKMATHSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("veryverythickmathspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STRIKETHROUGH_POSITION = new AttributeName(ALL_NO_NS, SAME_LOCAL("strikethrough-position"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName STRIKETHROUGH_THICKNESS = new AttributeName(ALL_NO_NS, SAME_LOCAL("strikethrough-thickness"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName GLYPH_ORIENTATION_VERTICAL = new AttributeName(ALL_NO_NS, SAME_LOCAL("glyph-orientation-vertical"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName COLOR_INTERPOLATION_FILTERS = new AttributeName(ALL_NO_NS, SAME_LOCAL("color-interpolation-filters"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ public static final AttributeName GLYPH_ORIENTATION_HORIZONTAL = new AttributeName(ALL_NO_NS, SAME_LOCAL("glyph-orientation-horizontal"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+ private final static @NoLength AttributeName[] ATTRIBUTE_NAMES = {
+ D,
+ K,
+ R,
+ X,
+ Y,
+ Z,
+ BY,
+ CX,
+ CY,
+ DX,
+ DY,
+ G2,
+ G1,
+ FX,
+ FY,
+ K4,
+ K2,
+ K3,
+ K1,
+ ID,
+ IN,
+ U2,
+ U1,
+ RT,
+ RX,
+ RY,
+ TO,
+ Y2,
+ Y1,
+ X1,
+ X2,
+ ALT,
+ DIR,
+ DUR,
+ END,
+ FOR,
+ IN2,
+ MAX,
+ MIN,
+ LOW,
+ REL,
+ REV,
+ SRC,
+ AXIS,
+ ABBR,
+ BBOX,
+ CITE,
+ CODE,
+ BIAS,
+ COLS,
+ CLIP,
+ CHAR,
+ BASE,
+ EDGE,
+ DATA,
+ FILL,
+ FROM,
+ FORM,
+ FACE,
+ HIGH,
+ HREF,
+ OPEN,
+ ICON,
+ NAME,
+ MODE,
+ MASK,
+ LINK,
+ LANG,
+ LOOP,
+ LIST,
+ TYPE,
+ WHEN,
+ WRAP,
+ TEXT,
+ PATH,
+ PING,
+ REFX,
+ REFY,
+ SIZE,
+ SEED,
+ ROWS,
+ SPAN,
+ STEP,
+ ROLE,
+ XREF,
+ ASYNC,
+ ALINK,
+ ALIGN,
+ CLOSE,
+ COLOR,
+ CLASS,
+ CLEAR,
+ BEGIN,
+ DEPTH,
+ DEFER,
+ FENCE,
+ FRAME,
+ ISMAP,
+ ONEND,
+ INDEX,
+ ORDER,
+ OTHER,
+ ONCUT,
+ NARGS,
+ MEDIA,
+ LABEL,
+ LOCAL,
+ WIDTH,
+ TITLE,
+ VLINK,
+ VALUE,
+ SLOPE,
+ SHAPE,
+ SCOPE,
+ SCALE,
+ SPEED,
+ STYLE,
+ RULES,
+ STEMH,
+ SIZES,
+ STEMV,
+ START,
+ XMLNS,
+ ACCEPT,
+ ACCENT,
+ ASCENT,
+ ACTIVE,
+ ALTIMG,
+ ACTION,
+ BORDER,
+ CURSOR,
+ COORDS,
+ FILTER,
+ FORMAT,
+ HIDDEN,
+ HSPACE,
+ HEIGHT,
+ ONMOVE,
+ ONLOAD,
+ ONDRAG,
+ ORIGIN,
+ ONZOOM,
+ ONHELP,
+ ONSTOP,
+ ONDROP,
+ ONBLUR,
+ OBJECT,
+ OFFSET,
+ ORIENT,
+ ONCOPY,
+ NOWRAP,
+ NOHREF,
+ MACROS,
+ METHOD,
+ LOWSRC,
+ LSPACE,
+ LQUOTE,
+ USEMAP,
+ WIDTHS,
+ TARGET,
+ VALUES,
+ VALIGN,
+ VSPACE,
+ POSTER,
+ POINTS,
+ PROMPT,
+ SRCDOC,
+ SCOPED,
+ STRING,
+ SCHEME,
+ STROKE,
+ RADIUS,
+ RESULT,
+ REPEAT,
+ SRCSET,
+ RSPACE,
+ ROTATE,
+ RQUOTE,
+ ALTTEXT,
+ ARCHIVE,
+ AZIMUTH,
+ CLOSURE,
+ CHECKED,
+ CLASSID,
+ CHAROFF,
+ BGCOLOR,
+ COLSPAN,
+ CHARSET,
+ COMPACT,
+ CONTENT,
+ ENCTYPE,
+ DATASRC,
+ DATAFLD,
+ DECLARE,
+ DISPLAY,
+ DIVISOR,
+ DEFAULT,
+ DESCENT,
+ KERNING,
+ HANGING,
+ HEADERS,
+ ONPASTE,
+ ONCLICK,
+ OPTIMUM,
+ ONBEGIN,
+ ONKEYUP,
+ ONFOCUS,
+ ONERROR,
+ ONINPUT,
+ ONABORT,
+ ONSTART,
+ ONRESET,
+ OPACITY,
+ NOSHADE,
+ MINSIZE,
+ MAXSIZE,
+ LARGEOP,
+ UNICODE,
+ TARGETX,
+ TARGETY,
+ VIEWBOX,
+ VERSION,
+ PATTERN,
+ PROFILE,
+ SPACING,
+ RESTART,
+ ROWSPAN,
+ SANDBOX,
+ SUMMARY,
+ STANDBY,
+ REPLACE,
+ AUTOPLAY,
+ ADDITIVE,
+ CALCMODE,
+ CODETYPE,
+ CODEBASE,
+ CONTROLS,
+ BEVELLED,
+ BASELINE,
+ EXPONENT,
+ EDGEMODE,
+ ENCODING,
+ GLYPHREF,
+ DATETIME,
+ DISABLED,
+ FONTSIZE,
+ KEYTIMES,
+ PANOSE_1,
+ HREFLANG,
+ ONRESIZE,
+ ONCHANGE,
+ ONBOUNCE,
+ ONUNLOAD,
+ ONFINISH,
+ ONSCROLL,
+ OPERATOR,
+ OVERFLOW,
+ ONSUBMIT,
+ ONREPEAT,
+ ONSELECT,
+ NOTATION,
+ NORESIZE,
+ MANIFEST,
+ MATHSIZE,
+ MULTIPLE,
+ LONGDESC,
+ LANGUAGE,
+ TEMPLATE,
+ TABINDEX,
+ PROPERTY,
+ READONLY,
+ SELECTED,
+ ROWLINES,
+ SEAMLESS,
+ ROWALIGN,
+ STRETCHY,
+ REQUIRED,
+ XML_BASE,
+ XML_LANG,
+ X_HEIGHT,
+ ARIA_OWNS,
+ AUTOFOCUS,
+ ARIA_SORT,
+ ACCESSKEY,
+ ARIA_BUSY,
+ ARIA_GRAB,
+ AMPLITUDE,
+ ARIA_LIVE,
+ CLIP_RULE,
+ CLIP_PATH,
+ EQUALROWS,
+ ELEVATION,
+ DIRECTION,
+ DRAGGABLE,
+ FILL_RULE,
+ FONTSTYLE,
+ FONT_SIZE,
+ KEYSYSTEM,
+ KEYPOINTS,
+ HIDEFOCUS,
+ ONMESSAGE,
+ INTERCEPT,
+ ONDRAGEND,
+ ONMOVEEND,
+ ONINVALID,
+ INTEGRITY,
+ ONKEYDOWN,
+ ONFOCUSIN,
+ ONMOUSEUP,
+ INPUTMODE,
+ ONROWEXIT,
+ MATHCOLOR,
+ MASKUNITS,
+ MAXLENGTH,
+ LINEBREAK,
+ TRANSFORM,
+ V_HANGING,
+ VALUETYPE,
+ POINTSATZ,
+ POINTSATX,
+ POINTSATY,
+ SYMMETRIC,
+ SCROLLING,
+ REPEATDUR,
+ SELECTION,
+ SEPARATOR,
+ XML_SPACE,
+ AUTOSUBMIT,
+ ALPHABETIC,
+ ACTIONTYPE,
+ ACCUMULATE,
+ ARIA_LEVEL,
+ COLUMNSPAN,
+ CAP_HEIGHT,
+ BACKGROUND,
+ GLYPH_NAME,
+ GROUPALIGN,
+ FONTFAMILY,
+ FONTWEIGHT,
+ FONT_STYLE,
+ KEYSPLINES,
+ HTTP_EQUIV,
+ ONACTIVATE,
+ OCCURRENCE,
+ IRRELEVANT,
+ ONDBLCLICK,
+ ONDRAGDROP,
+ ONKEYPRESS,
+ ONROWENTER,
+ ONDRAGOVER,
+ ONFOCUSOUT,
+ ONMOUSEOUT,
+ NUMOCTAVES,
+ MARKER_MID,
+ MARKER_END,
+ TEXTLENGTH,
+ VISIBILITY,
+ VIEWTARGET,
+ VERT_ADV_Y,
+ PATHLENGTH,
+ REPEAT_MAX,
+ RADIOGROUP,
+ STOP_COLOR,
+ SEPARATORS,
+ REPEAT_MIN,
+ ROWSPACING,
+ ZOOMANDPAN,
+ XLINK_TYPE,
+ XLINK_ROLE,
+ XLINK_HREF,
+ XLINK_SHOW,
+ ACCENTUNDER,
+ ARIA_SECRET,
+ ARIA_ATOMIC,
+ ARIA_HIDDEN,
+ ARIA_FLOWTO,
+ ARABIC_FORM,
+ CELLPADDING,
+ CELLSPACING,
+ COLUMNWIDTH,
+ CROSSORIGIN,
+ COLUMNALIGN,
+ COLUMNLINES,
+ CONTEXTMENU,
+ BASEPROFILE,
+ FONT_FAMILY,
+ FRAMEBORDER,
+ FILTERUNITS,
+ FLOOD_COLOR,
+ FONT_WEIGHT,
+ HORIZ_ADV_X,
+ ONDRAGLEAVE,
+ ONMOUSEMOVE,
+ ORIENTATION,
+ ONMOUSEDOWN,
+ ONMOUSEOVER,
+ ONDRAGENTER,
+ IDEOGRAPHIC,
+ ONBEFORECUT,
+ ONFORMINPUT,
+ ONDRAGSTART,
+ ONMOVESTART,
+ MARKERUNITS,
+ MATHVARIANT,
+ MARGINWIDTH,
+ MARKERWIDTH,
+ TEXT_ANCHOR,
+ TABLEVALUES,
+ SCRIPTLEVEL,
+ REPEATCOUNT,
+ STITCHTILES,
+ STARTOFFSET,
+ SCROLLDELAY,
+ XMLNS_XLINK,
+ XLINK_TITLE,
+ ARIA_INVALID,
+ ARIA_PRESSED,
+ ARIA_CHECKED,
+ AUTOCOMPLETE,
+ ARIA_SETSIZE,
+ ARIA_CHANNEL,
+ EQUALCOLUMNS,
+ DISPLAYSTYLE,
+ DATAFORMATAS,
+ FILL_OPACITY,
+ FONT_VARIANT,
+ FONT_STRETCH,
+ FRAMESPACING,
+ KERNELMATRIX,
+ ONDEACTIVATE,
+ ONROWSDELETE,
+ ONMOUSELEAVE,
+ ONFORMCHANGE,
+ ONCELLCHANGE,
+ ONMOUSEWHEEL,
+ ONMOUSEENTER,
+ ONAFTERPRINT,
+ ONBEFORECOPY,
+ MARGINHEIGHT,
+ MARKERHEIGHT,
+ MARKER_START,
+ MATHEMATICAL,
+ LENGTHADJUST,
+ UNSELECTABLE,
+ UNICODE_BIDI,
+ UNITS_PER_EM,
+ WORD_SPACING,
+ WRITING_MODE,
+ V_ALPHABETIC,
+ PATTERNUNITS,
+ SPREADMETHOD,
+ SURFACESCALE,
+ STROKE_WIDTH,
+ REPEAT_START,
+ STDDEVIATION,
+ STOP_OPACITY,
+ ARIA_CONTROLS,
+ ARIA_HASPOPUP,
+ ACCENT_HEIGHT,
+ ARIA_VALUENOW,
+ ARIA_RELEVANT,
+ ARIA_POSINSET,
+ ARIA_VALUEMAX,
+ ARIA_READONLY,
+ ARIA_SELECTED,
+ ARIA_REQUIRED,
+ ARIA_EXPANDED,
+ ARIA_DISABLED,
+ ATTRIBUTETYPE,
+ ATTRIBUTENAME,
+ ARIA_DATATYPE,
+ ARIA_VALUEMIN,
+ BASEFREQUENCY,
+ COLUMNSPACING,
+ COLOR_PROFILE,
+ CLIPPATHUNITS,
+ DEFINITIONURL,
+ GRADIENTUNITS,
+ FLOOD_OPACITY,
+ ONAFTERUPDATE,
+ ONERRORUPDATE,
+ ONBEFOREPASTE,
+ ONLOSECAPTURE,
+ ONCONTEXTMENU,
+ ONSELECTSTART,
+ ONBEFOREPRINT,
+ MOVABLELIMITS,
+ LINETHICKNESS,
+ UNICODE_RANGE,
+ THINMATHSPACE,
+ VERT_ORIGIN_X,
+ VERT_ORIGIN_Y,
+ V_IDEOGRAPHIC,
+ PRESERVEALPHA,
+ SCRIPTMINSIZE,
+ SPECIFICATION,
+ XLINK_ACTUATE,
+ XLINK_ARCROLE,
+ ACCEPT_CHARSET,
+ ALIGNMENTSCOPE,
+ ARIA_MULTILINE,
+ BASELINE_SHIFT,
+ HORIZ_ORIGIN_X,
+ HORIZ_ORIGIN_Y,
+ ONBEFOREUPDATE,
+ ONFILTERCHANGE,
+ ONROWSINSERTED,
+ ONBEFOREUNLOAD,
+ MATHBACKGROUND,
+ LETTER_SPACING,
+ LIGHTING_COLOR,
+ THICKMATHSPACE,
+ TEXT_RENDERING,
+ V_MATHEMATICAL,
+ POINTER_EVENTS,
+ PRIMITIVEUNITS,
+ REFERRERPOLICY,
+ SYSTEMLANGUAGE,
+ STROKE_LINECAP,
+ SUBSCRIPTSHIFT,
+ STROKE_OPACITY,
+ ARIA_DROPEFFECT,
+ ARIA_LABELLEDBY,
+ ARIA_TEMPLATEID,
+ COLOR_RENDERING,
+ CONTENTEDITABLE,
+ DIFFUSECONSTANT,
+ ONDATAAVAILABLE,
+ ONCONTROLSELECT,
+ IMAGE_RENDERING,
+ MEDIUMMATHSPACE,
+ TEXT_DECORATION,
+ SHAPE_RENDERING,
+ STROKE_LINEJOIN,
+ REPEAT_TEMPLATE,
+ ARIA_DESCRIBEDBY,
+ FONT_SIZE_ADJUST,
+ KERNELUNITLENGTH,
+ ONBEFOREACTIVATE,
+ ONPROPERTYCHANGE,
+ ONDATASETCHANGED,
+ MASKCONTENTUNITS,
+ PATTERNTRANSFORM,
+ REQUIREDFEATURES,
+ RENDERING_INTENT,
+ SPECULAREXPONENT,
+ SPECULARCONSTANT,
+ SUPERSCRIPTSHIFT,
+ STROKE_DASHARRAY,
+ XCHANNELSELECTOR,
+ YCHANNELSELECTOR,
+ ARIA_AUTOCOMPLETE,
+ ENABLE_BACKGROUND,
+ DOMINANT_BASELINE,
+ GRADIENTTRANSFORM,
+ ONBEFORDEACTIVATE,
+ ONDATASETCOMPLETE,
+ OVERLINE_POSITION,
+ ONBEFOREEDITFOCUS,
+ LIMITINGCONEANGLE,
+ VERYTHINMATHSPACE,
+ STROKE_DASHOFFSET,
+ STROKE_MITERLIMIT,
+ ALIGNMENT_BASELINE,
+ ONREADYSTATECHANGE,
+ OVERLINE_THICKNESS,
+ UNDERLINE_POSITION,
+ VERYTHICKMATHSPACE,
+ REQUIREDEXTENSIONS,
+ COLOR_INTERPOLATION,
+ UNDERLINE_THICKNESS,
+ PRESERVEASPECTRATIO,
+ PATTERNCONTENTUNITS,
+ ARIA_MULTISELECTABLE,
+ SCRIPTSIZEMULTIPLIER,
+ ARIA_ACTIVEDESCENDANT,
+ VERYVERYTHINMATHSPACE,
+ VERYVERYTHICKMATHSPACE,
+ STRIKETHROUGH_POSITION,
+ STRIKETHROUGH_THICKNESS,
+ GLYPH_ORIENTATION_VERTICAL,
+ COLOR_INTERPOLATION_FILTERS,
+ GLYPH_ORIENTATION_HORIZONTAL,
+ };
+ private final static int[] ATTRIBUTE_HASHES = {
+ 1153,
+ 1383,
+ 1601,
+ 1793,
+ 1827,
+ 1857,
+ 68600,
+ 69146,
+ 69177,
+ 70237,
+ 70270,
+ 71572,
+ 71669,
+ 72415,
+ 72444,
+ 74846,
+ 74904,
+ 74943,
+ 75001,
+ 75276,
+ 75590,
+ 84742,
+ 84839,
+ 85575,
+ 85963,
+ 85992,
+ 87204,
+ 88074,
+ 88171,
+ 89130,
+ 89163,
+ 3207892,
+ 3283895,
+ 3284791,
+ 3338752,
+ 3358197,
+ 3369562,
+ 3539124,
+ 3562402,
+ 3574260,
+ 3670335,
+ 3696933,
+ 3721879,
+ 135280021,
+ 135346322,
+ 136317019,
+ 136475749,
+ 136548517,
+ 136652214,
+ 136884919,
+ 136902418,
+ 136942992,
+ 137292068,
+ 139120259,
+ 139785574,
+ 142250603,
+ 142314056,
+ 142331176,
+ 142519584,
+ 144752417,
+ 145106895,
+ 146147200,
+ 146765926,
+ 148805544,
+ 149655723,
+ 149809441,
+ 150018784,
+ 150445028,
+ 150813181,
+ 150923321,
+ 152528754,
+ 152536216,
+ 152647366,
+ 152962785,
+ 155219321,
+ 155654904,
+ 157317483,
+ 157350248,
+ 157437941,
+ 157447478,
+ 157604838,
+ 157685404,
+ 157894402,
+ 158315188,
+ 166078431,
+ 169409980,
+ 169700259,
+ 169856932,
+ 170007032,
+ 170409695,
+ 170466488,
+ 170513710,
+ 170608367,
+ 173028944,
+ 173896963,
+ 176090625,
+ 176129212,
+ 179390001,
+ 179489057,
+ 179627464,
+ 179840468,
+ 179849042,
+ 180004216,
+ 181779081,
+ 183027151,
+ 183645319,
+ 183698797,
+ 185922012,
+ 185997252,
+ 188312483,
+ 188675799,
+ 190977533,
+ 190992569,
+ 191006194,
+ 191033518,
+ 191038774,
+ 191096249,
+ 191166163,
+ 191194426,
+ 191443343,
+ 191522106,
+ 191568039,
+ 200104642,
+ 202506661,
+ 202537381,
+ 202602917,
+ 203070590,
+ 203120766,
+ 203389054,
+ 203690071,
+ 203971238,
+ 203986524,
+ 209040857,
+ 209125756,
+ 212055489,
+ 212322418,
+ 212746849,
+ 213002877,
+ 213055164,
+ 213088023,
+ 213259873,
+ 213273386,
+ 213435118,
+ 213437318,
+ 213438231,
+ 213493071,
+ 213532268,
+ 213542834,
+ 213584431,
+ 213659891,
+ 215285828,
+ 215880731,
+ 216112976,
+ 216684637,
+ 217369699,
+ 217565298,
+ 217576549,
+ 218186795,
+ 219743185,
+ 220082234,
+ 221623802,
+ 221986406,
+ 222283890,
+ 223089542,
+ 223138630,
+ 223311265,
+ 224431494,
+ 224547358,
+ 224587256,
+ 224589550,
+ 224655650,
+ 224785518,
+ 224810917,
+ 224813302,
+ 225126263,
+ 225429618,
+ 225432950,
+ 225440869,
+ 236107233,
+ 236709921,
+ 236838947,
+ 237117095,
+ 237143271,
+ 237172455,
+ 237209953,
+ 237354143,
+ 237372743,
+ 237668065,
+ 237703073,
+ 237714273,
+ 239743521,
+ 240512803,
+ 240522627,
+ 240560417,
+ 240656513,
+ 241015715,
+ 241062755,
+ 241065383,
+ 243523041,
+ 245865199,
+ 246261793,
+ 246556195,
+ 246774817,
+ 246923491,
+ 246928419,
+ 246981667,
+ 247014847,
+ 247058369,
+ 247112833,
+ 247118177,
+ 247119137,
+ 247128739,
+ 247316903,
+ 249533729,
+ 250235623,
+ 250269543,
+ 251402351,
+ 252339047,
+ 253260911,
+ 253293679,
+ 254844367,
+ 255547879,
+ 256077281,
+ 256345377,
+ 258124199,
+ 258354465,
+ 258605063,
+ 258744193,
+ 258845603,
+ 258856961,
+ 258926689,
+ 269869248,
+ 270174334,
+ 270709417,
+ 270778994,
+ 270781796,
+ 271102503,
+ 271478858,
+ 271490090,
+ 272870654,
+ 273335275,
+ 273369140,
+ 273924313,
+ 274108530,
+ 274116736,
+ 276818662,
+ 277476156,
+ 279156579,
+ 279349675,
+ 280108533,
+ 280128712,
+ 280132869,
+ 280162403,
+ 280280292,
+ 280413430,
+ 280506130,
+ 280677397,
+ 280678580,
+ 280686710,
+ 280689066,
+ 282736758,
+ 283110901,
+ 283275116,
+ 283823226,
+ 283890012,
+ 284479340,
+ 284606461,
+ 286700477,
+ 286798916,
+ 290055764,
+ 291557706,
+ 291665349,
+ 291804100,
+ 292138018,
+ 292166446,
+ 292418738,
+ 292451039,
+ 300298041,
+ 300374839,
+ 300597935,
+ 303073389,
+ 303083839,
+ 303266673,
+ 303354997,
+ 303430688,
+ 303576261,
+ 303724281,
+ 303819694,
+ 304242723,
+ 304382625,
+ 306247792,
+ 307227811,
+ 307468786,
+ 307724489,
+ 310252031,
+ 310358241,
+ 310373094,
+ 310833159,
+ 311015256,
+ 313357609,
+ 313683893,
+ 313701861,
+ 313706996,
+ 313707317,
+ 313710350,
+ 313795700,
+ 314027746,
+ 314038181,
+ 314091299,
+ 314205627,
+ 314233813,
+ 316741830,
+ 316797986,
+ 317486755,
+ 317794164,
+ 320076137,
+ 322657125,
+ 322887778,
+ 323506876,
+ 323572412,
+ 323605180,
+ 325060058,
+ 325320188,
+ 325398738,
+ 325541490,
+ 325671619,
+ 333868843,
+ 336806130,
+ 337212108,
+ 337282686,
+ 337285434,
+ 337585223,
+ 338036037,
+ 338298087,
+ 338566051,
+ 340943551,
+ 341190970,
+ 342995704,
+ 343352124,
+ 343912673,
+ 344585053,
+ 346977248,
+ 347218098,
+ 347262163,
+ 347278576,
+ 347438191,
+ 347655959,
+ 347684788,
+ 347726430,
+ 347727772,
+ 347776035,
+ 347776629,
+ 349500753,
+ 350880161,
+ 350887073,
+ 353384123,
+ 355496998,
+ 355906922,
+ 355979793,
+ 356545959,
+ 358637867,
+ 358905016,
+ 359164318,
+ 359247286,
+ 359350571,
+ 359579447,
+ 365560330,
+ 367399355,
+ 367420285,
+ 367510727,
+ 368013212,
+ 370234760,
+ 370353345,
+ 370710317,
+ 371074566,
+ 371122285,
+ 371194213,
+ 371448425,
+ 371448430,
+ 371545055,
+ 371593469,
+ 371596922,
+ 371758751,
+ 371964792,
+ 372151328,
+ 376550136,
+ 376710172,
+ 376795771,
+ 376826271,
+ 376906556,
+ 380514830,
+ 380774774,
+ 380775037,
+ 381030322,
+ 381136500,
+ 381281631,
+ 381282269,
+ 381285504,
+ 381330595,
+ 381331422,
+ 381335911,
+ 381336484,
+ 383907298,
+ 383917408,
+ 384595009,
+ 384595013,
+ 387799894,
+ 387823201,
+ 392581647,
+ 392584937,
+ 392742684,
+ 392906485,
+ 393003349,
+ 400644707,
+ 400973830,
+ 404428547,
+ 404432113,
+ 404432865,
+ 404469244,
+ 404478897,
+ 404694860,
+ 406887479,
+ 408294949,
+ 408789955,
+ 410022510,
+ 410467324,
+ 410586448,
+ 410945965,
+ 411845275,
+ 414327152,
+ 414327932,
+ 414329781,
+ 414346257,
+ 414346439,
+ 414639928,
+ 414835998,
+ 414894517,
+ 414986533,
+ 417465377,
+ 417465381,
+ 417492216,
+ 418259232,
+ 419310946,
+ 420103495,
+ 420242342,
+ 420380455,
+ 420658662,
+ 420717432,
+ 423183880,
+ 424539259,
+ 425929170,
+ 425972964,
+ 426050649,
+ 426126450,
+ 426142833,
+ 426607922,
+ 437289840,
+ 437347469,
+ 437412335,
+ 437423943,
+ 437455540,
+ 437462252,
+ 437597991,
+ 437617485,
+ 437986305,
+ 437986507,
+ 437986828,
+ 437987072,
+ 438015591,
+ 438034813,
+ 438038966,
+ 438179623,
+ 438347971,
+ 438483573,
+ 438547062,
+ 438895551,
+ 441592676,
+ 442032555,
+ 443548979,
+ 447881379,
+ 447881655,
+ 447881895,
+ 447887844,
+ 448416189,
+ 448445746,
+ 448449012,
+ 450942191,
+ 452816744,
+ 453668677,
+ 454434495,
+ 456610076,
+ 456642844,
+ 456738709,
+ 457544600,
+ 459451897,
+ 459680944,
+ 468058810,
+ 468083581,
+ 470964084,
+ 471470955,
+ 471567278,
+ 472267822,
+ 481177859,
+ 481210627,
+ 481435874,
+ 481455115,
+ 481485378,
+ 481490218,
+ 485105638,
+ 486005878,
+ 486383494,
+ 487988916,
+ 488103783,
+ 490661867,
+ 491574090,
+ 491578272,
+ 492891370,
+ 493041952,
+ 493441205,
+ 493582844,
+ 493716979,
+ 504577572,
+ 504740359,
+ 505091638,
+ 505592418,
+ 505656212,
+ 509516275,
+ 514998531,
+ 515571132,
+ 515594682,
+ 518712698,
+ 521362273,
+ 526592419,
+ 526807354,
+ 527348842,
+ 538294791,
+ 544689535,
+ 545535009,
+ 548544752,
+ 548563346,
+ 548595116,
+ 551679010,
+ 558034099,
+ 560329411,
+ 560356209,
+ 560671018,
+ 560671152,
+ 560692590,
+ 560845442,
+ 569212097,
+ 569474241,
+ 572252718,
+ 575326764,
+ 576174758,
+ 576190819,
+ 582099184,
+ 582099438,
+ 582372519,
+ 582558889,
+ 586552164,
+ 591325418,
+ 594231990,
+ 594243961,
+ 605711268,
+ 615672071,
+ 616086845,
+ 621792370,
+ 624879850,
+ 627432831,
+ 640040548,
+ 654392808,
+ 658675477,
+ 659420283,
+ 672891587,
+ 694768102,
+ 705890982,
+ 725543146,
+ 759097578,
+ 761686526,
+ 795383908,
+ 878105336,
+ 908643300,
+ 945213471,
+ };
+}
diff --git a/parser/html/javasrc/ElementName.java b/parser/html/javasrc/ElementName.java
new file mode 100644
index 000000000..ee551a737
--- /dev/null
+++ b/parser/html/javasrc/ElementName.java
@@ -0,0 +1,1609 @@
+/*
+ * Copyright (c) 2008-2014 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package nu.validator.htmlparser.impl;
+
+import java.util.Arrays;
+
+import nu.validator.htmlparser.annotation.Inline;
+import nu.validator.htmlparser.annotation.Local;
+import nu.validator.htmlparser.annotation.NoLength;
+import nu.validator.htmlparser.annotation.Virtual;
+import nu.validator.htmlparser.common.Interner;
+
+public final class ElementName
+// uncomment when regenerating self
+// implements Comparable<ElementName>
+{
+
+ /**
+ * The mask for extracting the dispatch group.
+ */
+ public static final int GROUP_MASK = 127;
+
+ /**
+ * Indicates that the element is not a pre-interned element. Forbidden
+ * on preinterned elements.
+ */
+ public static final int CUSTOM = (1 << 30);
+
+ /**
+ * Indicates that the element is in the "special" category. This bit
+ * should not be pre-set on MathML or SVG specials--only on HTML specials.
+ */
+ public static final int SPECIAL = (1 << 29);
+
+ /**
+ * The element is foster-parenting. This bit should be pre-set on elements
+ * that are foster-parenting as HTML.
+ */
+ public static final int FOSTER_PARENTING = (1 << 28);
+
+ /**
+ * The element is scoping. This bit should be pre-set on elements
+ * that are scoping as HTML.
+ */
+ public static final int SCOPING = (1 << 27);
+
+ /**
+ * The element is scoping as SVG.
+ */
+ public static final int SCOPING_AS_SVG = (1 << 26);
+
+ /**
+ * The element is scoping as MathML.
+ */
+ public static final int SCOPING_AS_MATHML = (1 << 25);
+
+ /**
+ * The element is an HTML integration point.
+ */
+ public static final int HTML_INTEGRATION_POINT = (1 << 24);
+
+ /**
+ * The element has an optional end tag.
+ */
+ public static final int OPTIONAL_END_TAG = (1 << 23);
+
+ public static final ElementName NULL_ELEMENT_NAME = new ElementName(null);
+
+ public final @Local String name;
+
+ public final @Local String camelCaseName;
+
+ /**
+ * The lowest 7 bits are the dispatch group. The high bits are flags.
+ */
+ public final int flags;
+
+ @Inline public int getFlags() {
+ return flags;
+ }
+
+ public int getGroup() {
+ return flags & GROUP_MASK;
+ }
+
+ public boolean isCustom() {
+ return (flags & CUSTOM) != 0;
+ }
+
+ static ElementName elementNameByBuffer(@NoLength char[] buf, int offset, int length, Interner interner) {
+ int hash = ElementName.bufToHash(buf, length);
+ int index = Arrays.binarySearch(ElementName.ELEMENT_HASHES, hash);
+ if (index < 0) {
+ return new ElementName(Portability.newLocalNameFromBuffer(buf, offset, length, interner));
+ } else {
+ ElementName elementName = ElementName.ELEMENT_NAMES[index];
+ @Local String name = elementName.name;
+ if (!Portability.localEqualsBuffer(name, buf, offset, length)) {
+ return new ElementName(Portability.newLocalNameFromBuffer(buf,
+ offset, length, interner));
+ }
+ return elementName;
+ }
+ }
+
+ /**
+ * This method has to return a unique integer for each well-known
+ * lower-cased element name.
+ *
+ * @param buf
+ * @param len
+ * @return
+ */
+ private static int bufToHash(@NoLength char[] buf, int len) {
+ int hash = len;
+ hash <<= 5;
+ hash += buf[0] - 0x60;
+ int j = len;
+ for (int i = 0; i < 4 && j > 0; i++) {
+ j--;
+ hash <<= 5;
+ hash += buf[j] - 0x60;
+ }
+ return hash;
+ }
+
+ private ElementName(@Local String name, @Local String camelCaseName,
+ int flags) {
+ this.name = name;
+ this.camelCaseName = camelCaseName;
+ this.flags = flags;
+ }
+
+ protected ElementName(@Local String name) {
+ this.name = name;
+ this.camelCaseName = name;
+ this.flags = TreeBuilder.OTHER | CUSTOM;
+ }
+
+ @Virtual void release() {
+ // No-op in Java.
+ // Implement as delete this in subclass.
+ // Be sure to release the local name
+ }
+
+ @SuppressWarnings("unused") @Virtual private void destructor() {
+ }
+
+ @Virtual public ElementName cloneElementName(Interner interner) {
+ return this;
+ }
+
+ // START CODE ONLY USED FOR GENERATING CODE uncomment and run to regenerate
+
+// /**
+// * @see java.lang.Object#toString()
+// */
+// @Override public String toString() {
+// return "(\"" + name + "\", \"" + camelCaseName + "\", " + decomposedFlags() + ")";
+// }
+//
+// private String decomposedFlags() {
+// StringBuilder buf = new StringBuilder("TreeBuilder.");
+// buf.append(treeBuilderGroupToName());
+// if ((flags & SPECIAL) != 0) {
+// buf.append(" | SPECIAL");
+// }
+// if ((flags & FOSTER_PARENTING) != 0) {
+// buf.append(" | FOSTER_PARENTING");
+// }
+// if ((flags & SCOPING) != 0) {
+// buf.append(" | SCOPING");
+// }
+// if ((flags & SCOPING_AS_MATHML) != 0) {
+// buf.append(" | SCOPING_AS_MATHML");
+// }
+// if ((flags & SCOPING_AS_SVG) != 0) {
+// buf.append(" | SCOPING_AS_SVG");
+// }
+// if ((flags & OPTIONAL_END_TAG) != 0) {
+// buf.append(" | OPTIONAL_END_TAG");
+// }
+// return buf.toString();
+// }
+//
+// private String constName() {
+// char[] buf = new char[name.length()];
+// for (int i = 0; i < name.length(); i++) {
+// char c = name.charAt(i);
+// if (c == '-') {
+// buf[i] = '_';
+// } else if (c >= '0' && c <= '9') {
+// buf[i] = c;
+// } else {
+// buf[i] = (char) (c - 0x20);
+// }
+// }
+// return new String(buf);
+// }
+//
+// private int hash() {
+// return bufToHash(name.toCharArray(), name.length());
+// }
+//
+// public int compareTo(ElementName other) {
+// int thisHash = this.hash();
+// int otherHash = other.hash();
+// if (thisHash < otherHash) {
+// return -1;
+// } else if (thisHash == otherHash) {
+// return 0;
+// } else {
+// return 1;
+// }
+// }
+//
+// private String treeBuilderGroupToName() {
+// switch (getGroup()) {
+// case TreeBuilder.OTHER:
+// return "OTHER";
+// case TreeBuilder.A:
+// return "A";
+// case TreeBuilder.BASE:
+// return "BASE";
+// case TreeBuilder.BODY:
+// return "BODY";
+// case TreeBuilder.BR:
+// return "BR";
+// case TreeBuilder.BUTTON:
+// return "BUTTON";
+// case TreeBuilder.CAPTION:
+// return "CAPTION";
+// case TreeBuilder.COL:
+// return "COL";
+// case TreeBuilder.COLGROUP:
+// return "COLGROUP";
+// case TreeBuilder.FONT:
+// return "FONT";
+// case TreeBuilder.FORM:
+// return "FORM";
+// case TreeBuilder.FRAME:
+// return "FRAME";
+// case TreeBuilder.FRAMESET:
+// return "FRAMESET";
+// case TreeBuilder.IMAGE:
+// return "IMAGE";
+// case TreeBuilder.INPUT:
+// return "INPUT";
+// case TreeBuilder.ISINDEX:
+// return "ISINDEX";
+// case TreeBuilder.LI:
+// return "LI";
+// case TreeBuilder.LINK_OR_BASEFONT_OR_BGSOUND:
+// return "LINK_OR_BASEFONT_OR_BGSOUND";
+// case TreeBuilder.MATH:
+// return "MATH";
+// case TreeBuilder.META:
+// return "META";
+// case TreeBuilder.SVG:
+// return "SVG";
+// case TreeBuilder.HEAD:
+// return "HEAD";
+// case TreeBuilder.HR:
+// return "HR";
+// case TreeBuilder.HTML:
+// return "HTML";
+// case TreeBuilder.KEYGEN:
+// return "KEYGEN";
+// case TreeBuilder.NOBR:
+// return "NOBR";
+// case TreeBuilder.NOFRAMES:
+// return "NOFRAMES";
+// case TreeBuilder.NOSCRIPT:
+// return "NOSCRIPT";
+// case TreeBuilder.OPTGROUP:
+// return "OPTGROUP";
+// case TreeBuilder.OPTION:
+// return "OPTION";
+// case TreeBuilder.P:
+// return "P";
+// case TreeBuilder.PLAINTEXT:
+// return "PLAINTEXT";
+// case TreeBuilder.SCRIPT:
+// return "SCRIPT";
+// case TreeBuilder.SELECT:
+// return "SELECT";
+// case TreeBuilder.STYLE:
+// return "STYLE";
+// case TreeBuilder.TABLE:
+// return "TABLE";
+// case TreeBuilder.TEXTAREA:
+// return "TEXTAREA";
+// case TreeBuilder.TITLE:
+// return "TITLE";
+// case TreeBuilder.TEMPLATE:
+// return "TEMPLATE";
+// case TreeBuilder.TR:
+// return "TR";
+// case TreeBuilder.XMP:
+// return "XMP";
+// case TreeBuilder.TBODY_OR_THEAD_OR_TFOOT:
+// return "TBODY_OR_THEAD_OR_TFOOT";
+// case TreeBuilder.TD_OR_TH:
+// return "TD_OR_TH";
+// case TreeBuilder.DD_OR_DT:
+// return "DD_OR_DT";
+// case TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
+// return "H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6";
+// case TreeBuilder.OBJECT:
+// return "OBJECT";
+// case TreeBuilder.OUTPUT:
+// return "OUTPUT";
+// case TreeBuilder.MARQUEE_OR_APPLET:
+// return "MARQUEE_OR_APPLET";
+// case TreeBuilder.PRE_OR_LISTING:
+// return "PRE_OR_LISTING";
+// case TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
+// return "B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U";
+// case TreeBuilder.UL_OR_OL_OR_DL:
+// return "UL_OR_OL_OR_DL";
+// case TreeBuilder.IFRAME:
+// return "IFRAME";
+// case TreeBuilder.NOEMBED:
+// return "NOEMBED";
+// case TreeBuilder.EMBED:
+// return "EMBED";
+// case TreeBuilder.IMG:
+// return "IMG";
+// case TreeBuilder.AREA_OR_WBR:
+// return "AREA_OR_WBR";
+// case TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
+// return "DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU";
+// case TreeBuilder.FIELDSET:
+// return "FIELDSET";
+// case TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY:
+// return "ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY";
+// case TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR:
+// return "RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR";
+// case TreeBuilder.RB_OR_RTC:
+// return "RB_OR_RTC";
+// case TreeBuilder.RT_OR_RP:
+// return "RT_OR_RP";
+// case TreeBuilder.PARAM_OR_SOURCE_OR_TRACK:
+// return "PARAM_OR_SOURCE_OR_TRACK";
+// case TreeBuilder.MGLYPH_OR_MALIGNMARK:
+// return "MGLYPH_OR_MALIGNMARK";
+// case TreeBuilder.MI_MO_MN_MS_MTEXT:
+// return "MI_MO_MN_MS_MTEXT";
+// case TreeBuilder.ANNOTATION_XML:
+// return "ANNOTATION_XML";
+// case TreeBuilder.FOREIGNOBJECT_OR_DESC:
+// return "FOREIGNOBJECT_OR_DESC";
+// case TreeBuilder.MENUITEM:
+// return "MENUITEM";
+// }
+// return null;
+// }
+//
+// /**
+// * Regenerate self
+// *
+// * @param args
+// */
+// public static void main(String[] args) {
+// Arrays.sort(ELEMENT_NAMES);
+// for (int i = 1; i < ELEMENT_NAMES.length; i++) {
+// if (ELEMENT_NAMES[i].hash() == ELEMENT_NAMES[i - 1].hash()) {
+// System.err.println("Hash collision: " + ELEMENT_NAMES[i].name
+// + ", " + ELEMENT_NAMES[i - 1].name);
+// return;
+// }
+// }
+// for (int i = 0; i < ELEMENT_NAMES.length; i++) {
+// ElementName el = ELEMENT_NAMES[i];
+// System.out.println("public static final ElementName "
+// + el.constName() + " = new ElementName" + el.toString()
+// + ";");
+// }
+// System.out.println("private final static @NoLength ElementName[] ELEMENT_NAMES = {");
+// for (int i = 0; i < ELEMENT_NAMES.length; i++) {
+// ElementName el = ELEMENT_NAMES[i];
+// System.out.println(el.constName() + ",");
+// }
+// System.out.println("};");
+// System.out.println("private final static int[] ELEMENT_HASHES = {");
+// for (int i = 0; i < ELEMENT_NAMES.length; i++) {
+// ElementName el = ELEMENT_NAMES[i];
+// System.out.println(Integer.toString(el.hash()) + ",");
+// }
+// System.out.println("};");
+// }
+
+ // START GENERATED CODE
+ public static final ElementName A = new ElementName("a", "a", TreeBuilder.A);
+ public static final ElementName B = new ElementName("b", "b", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ public static final ElementName G = new ElementName("g", "g", TreeBuilder.OTHER);
+ public static final ElementName I = new ElementName("i", "i", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ public static final ElementName P = new ElementName("p", "p", TreeBuilder.P | SPECIAL | OPTIONAL_END_TAG);
+ public static final ElementName Q = new ElementName("q", "q", TreeBuilder.OTHER);
+ public static final ElementName S = new ElementName("s", "s", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ public static final ElementName U = new ElementName("u", "u", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ public static final ElementName BR = new ElementName("br", "br", TreeBuilder.BR | SPECIAL);
+ public static final ElementName CI = new ElementName("ci", "ci", TreeBuilder.OTHER);
+ public static final ElementName CN = new ElementName("cn", "cn", TreeBuilder.OTHER);
+ public static final ElementName DD = new ElementName("dd", "dd", TreeBuilder.DD_OR_DT | SPECIAL | OPTIONAL_END_TAG);
+ public static final ElementName DL = new ElementName("dl", "dl", TreeBuilder.UL_OR_OL_OR_DL | SPECIAL);
+ public static final ElementName DT = new ElementName("dt", "dt", TreeBuilder.DD_OR_DT | SPECIAL | OPTIONAL_END_TAG);
+ public static final ElementName EM = new ElementName("em", "em", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ public static final ElementName EQ = new ElementName("eq", "eq", TreeBuilder.OTHER);
+ public static final ElementName FN = new ElementName("fn", "fn", TreeBuilder.OTHER);
+ public static final ElementName H1 = new ElementName("h1", "h1", TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
+ public static final ElementName H2 = new ElementName("h2", "h2", TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
+ public static final ElementName H3 = new ElementName("h3", "h3", TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
+ public static final ElementName H4 = new ElementName("h4", "h4", TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
+ public static final ElementName H5 = new ElementName("h5", "h5", TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
+ public static final ElementName H6 = new ElementName("h6", "h6", TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
+ public static final ElementName GT = new ElementName("gt", "gt", TreeBuilder.OTHER);
+ public static final ElementName HR = new ElementName("hr", "hr", TreeBuilder.HR | SPECIAL);
+ public static final ElementName IN = new ElementName("in", "in", TreeBuilder.OTHER);
+ public static final ElementName LI = new ElementName("li", "li", TreeBuilder.LI | SPECIAL | OPTIONAL_END_TAG);
+ public static final ElementName LN = new ElementName("ln", "ln", TreeBuilder.OTHER);
+ public static final ElementName LT = new ElementName("lt", "lt", TreeBuilder.OTHER);
+ public static final ElementName MI = new ElementName("mi", "mi", TreeBuilder.MI_MO_MN_MS_MTEXT | SCOPING_AS_MATHML);
+ public static final ElementName MN = new ElementName("mn", "mn", TreeBuilder.MI_MO_MN_MS_MTEXT | SCOPING_AS_MATHML);
+ public static final ElementName MO = new ElementName("mo", "mo", TreeBuilder.MI_MO_MN_MS_MTEXT | SCOPING_AS_MATHML);
+ public static final ElementName MS = new ElementName("ms", "ms", TreeBuilder.MI_MO_MN_MS_MTEXT | SCOPING_AS_MATHML);
+ public static final ElementName OL = new ElementName("ol", "ol", TreeBuilder.UL_OR_OL_OR_DL | SPECIAL);
+ public static final ElementName OR = new ElementName("or", "or", TreeBuilder.OTHER);
+ public static final ElementName PI = new ElementName("pi", "pi", TreeBuilder.OTHER);
+ public static final ElementName RB = new ElementName("rb", "rb", TreeBuilder.RB_OR_RTC | OPTIONAL_END_TAG);
+ public static final ElementName RP = new ElementName("rp", "rp", TreeBuilder.RT_OR_RP | OPTIONAL_END_TAG);
+ public static final ElementName RT = new ElementName("rt", "rt", TreeBuilder.RT_OR_RP | OPTIONAL_END_TAG);
+ public static final ElementName TD = new ElementName("td", "td", TreeBuilder.TD_OR_TH | SPECIAL | SCOPING | OPTIONAL_END_TAG);
+ public static final ElementName TH = new ElementName("th", "th", TreeBuilder.TD_OR_TH | SPECIAL | SCOPING | OPTIONAL_END_TAG);
+ public static final ElementName TR = new ElementName("tr", "tr", TreeBuilder.TR | SPECIAL | FOSTER_PARENTING | OPTIONAL_END_TAG);
+ public static final ElementName TT = new ElementName("tt", "tt", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ public static final ElementName UL = new ElementName("ul", "ul", TreeBuilder.UL_OR_OL_OR_DL | SPECIAL);
+ public static final ElementName AND = new ElementName("and", "and", TreeBuilder.OTHER);
+ public static final ElementName ARG = new ElementName("arg", "arg", TreeBuilder.OTHER);
+ public static final ElementName ABS = new ElementName("abs", "abs", TreeBuilder.OTHER);
+ public static final ElementName BIG = new ElementName("big", "big", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ public static final ElementName BDO = new ElementName("bdo", "bdo", TreeBuilder.OTHER);
+ public static final ElementName CSC = new ElementName("csc", "csc", TreeBuilder.OTHER);
+ public static final ElementName COL = new ElementName("col", "col", TreeBuilder.COL | SPECIAL);
+ public static final ElementName COS = new ElementName("cos", "cos", TreeBuilder.OTHER);
+ public static final ElementName COT = new ElementName("cot", "cot", TreeBuilder.OTHER);
+ public static final ElementName DEL = new ElementName("del", "del", TreeBuilder.OTHER);
+ public static final ElementName DFN = new ElementName("dfn", "dfn", TreeBuilder.OTHER);
+ public static final ElementName DIR = new ElementName("dir", "dir", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+ public static final ElementName DIV = new ElementName("div", "div", TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
+ public static final ElementName EXP = new ElementName("exp", "exp", TreeBuilder.OTHER);
+ public static final ElementName GCD = new ElementName("gcd", "gcd", TreeBuilder.OTHER);
+ public static final ElementName GEQ = new ElementName("geq", "geq", TreeBuilder.OTHER);
+ public static final ElementName IMG = new ElementName("img", "img", TreeBuilder.IMG | SPECIAL);
+ public static final ElementName INS = new ElementName("ins", "ins", TreeBuilder.OTHER);
+ public static final ElementName INT = new ElementName("int", "int", TreeBuilder.OTHER);
+ public static final ElementName KBD = new ElementName("kbd", "kbd", TreeBuilder.OTHER);
+ public static final ElementName LOG = new ElementName("log", "log", TreeBuilder.OTHER);
+ public static final ElementName LCM = new ElementName("lcm", "lcm", TreeBuilder.OTHER);
+ public static final ElementName LEQ = new ElementName("leq", "leq", TreeBuilder.OTHER);
+ public static final ElementName MTD = new ElementName("mtd", "mtd", TreeBuilder.OTHER);
+ public static final ElementName MIN = new ElementName("min", "min", TreeBuilder.OTHER);
+ public static final ElementName MAP = new ElementName("map", "map", TreeBuilder.OTHER);
+ public static final ElementName MTR = new ElementName("mtr", "mtr", TreeBuilder.OTHER);
+ public static final ElementName MAX = new ElementName("max", "max", TreeBuilder.OTHER);
+ public static final ElementName NEQ = new ElementName("neq", "neq", TreeBuilder.OTHER);
+ public static final ElementName NOT = new ElementName("not", "not", TreeBuilder.OTHER);
+ public static final ElementName NAV = new ElementName("nav", "nav", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+ public static final ElementName PRE = new ElementName("pre", "pre", TreeBuilder.PRE_OR_LISTING | SPECIAL);
+ public static final ElementName RTC = new ElementName("rtc", "rtc", TreeBuilder.RB_OR_RTC | OPTIONAL_END_TAG);
+ public static final ElementName REM = new ElementName("rem", "rem", TreeBuilder.OTHER);
+ public static final ElementName SUB = new ElementName("sub", "sub", TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
+ public static final ElementName SEC = new ElementName("sec", "sec", TreeBuilder.OTHER);
+ public static final ElementName SVG = new ElementName("svg", "svg", TreeBuilder.SVG);
+ public static final ElementName SUM = new ElementName("sum", "sum", TreeBuilder.OTHER);
+ public static final ElementName SIN = new ElementName("sin", "sin", TreeBuilder.OTHER);
+ public static final ElementName SEP = new ElementName("sep", "sep", TreeBuilder.OTHER);
+ public static final ElementName SUP = new ElementName("sup", "sup", TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
+ public static final ElementName SET = new ElementName("set", "set", TreeBuilder.OTHER);
+ public static final ElementName TAN = new ElementName("tan", "tan", TreeBuilder.OTHER);
+ public static final ElementName USE = new ElementName("use", "use", TreeBuilder.OTHER);
+ public static final ElementName VAR = new ElementName("var", "var", TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
+ public static final ElementName WBR = new ElementName("wbr", "wbr", TreeBuilder.AREA_OR_WBR | SPECIAL);
+ public static final ElementName XMP = new ElementName("xmp", "xmp", TreeBuilder.XMP | SPECIAL);
+ public static final ElementName XOR = new ElementName("xor", "xor", TreeBuilder.OTHER);
+ public static final ElementName AREA = new ElementName("area", "area", TreeBuilder.AREA_OR_WBR | SPECIAL);
+ public static final ElementName ABBR = new ElementName("abbr", "abbr", TreeBuilder.OTHER);
+ public static final ElementName BASE = new ElementName("base", "base", TreeBuilder.BASE | SPECIAL);
+ public static final ElementName BVAR = new ElementName("bvar", "bvar", TreeBuilder.OTHER);
+ public static final ElementName BODY = new ElementName("body", "body", TreeBuilder.BODY | SPECIAL | OPTIONAL_END_TAG);
+ public static final ElementName CARD = new ElementName("card", "card", TreeBuilder.OTHER);
+ public static final ElementName CODE = new ElementName("code", "code", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ public static final ElementName CITE = new ElementName("cite", "cite", TreeBuilder.OTHER);
+ public static final ElementName CSCH = new ElementName("csch", "csch", TreeBuilder.OTHER);
+ public static final ElementName COSH = new ElementName("cosh", "cosh", TreeBuilder.OTHER);
+ public static final ElementName COTH = new ElementName("coth", "coth", TreeBuilder.OTHER);
+ public static final ElementName CURL = new ElementName("curl", "curl", TreeBuilder.OTHER);
+ public static final ElementName DESC = new ElementName("desc", "desc", TreeBuilder.FOREIGNOBJECT_OR_DESC | SCOPING_AS_SVG);
+ public static final ElementName DIFF = new ElementName("diff", "diff", TreeBuilder.OTHER);
+ public static final ElementName DEFS = new ElementName("defs", "defs", TreeBuilder.OTHER);
+ public static final ElementName FORM = new ElementName("form", "form", TreeBuilder.FORM | SPECIAL);
+ public static final ElementName FONT = new ElementName("font", "font", TreeBuilder.FONT);
+ public static final ElementName GRAD = new ElementName("grad", "grad", TreeBuilder.OTHER);
+ public static final ElementName HEAD = new ElementName("head", "head", TreeBuilder.HEAD | SPECIAL | OPTIONAL_END_TAG);
+ public static final ElementName HTML = new ElementName("html", "html", TreeBuilder.HTML | SPECIAL | SCOPING | OPTIONAL_END_TAG);
+ public static final ElementName LINE = new ElementName("line", "line", TreeBuilder.OTHER);
+ public static final ElementName LINK = new ElementName("link", "link", TreeBuilder.LINK_OR_BASEFONT_OR_BGSOUND | SPECIAL);
+ public static final ElementName LIST = new ElementName("list", "list", TreeBuilder.OTHER);
+ public static final ElementName META = new ElementName("meta", "meta", TreeBuilder.META | SPECIAL);
+ public static final ElementName MSUB = new ElementName("msub", "msub", TreeBuilder.OTHER);
+ public static final ElementName MODE = new ElementName("mode", "mode", TreeBuilder.OTHER);
+ public static final ElementName MATH = new ElementName("math", "math", TreeBuilder.MATH);
+ public static final ElementName MARK = new ElementName("mark", "mark", TreeBuilder.OTHER);
+ public static final ElementName MASK = new ElementName("mask", "mask", TreeBuilder.OTHER);
+ public static final ElementName MEAN = new ElementName("mean", "mean", TreeBuilder.OTHER);
+ public static final ElementName MAIN = new ElementName("main", "main", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+ public static final ElementName MSUP = new ElementName("msup", "msup", TreeBuilder.OTHER);
+ public static final ElementName MENU = new ElementName("menu", "menu", TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
+ public static final ElementName MROW = new ElementName("mrow", "mrow", TreeBuilder.OTHER);
+ public static final ElementName NONE = new ElementName("none", "none", TreeBuilder.OTHER);
+ public static final ElementName NOBR = new ElementName("nobr", "nobr", TreeBuilder.NOBR);
+ public static final ElementName NEST = new ElementName("nest", "nest", TreeBuilder.OTHER);
+ public static final ElementName PATH = new ElementName("path", "path", TreeBuilder.OTHER);
+ public static final ElementName PLUS = new ElementName("plus", "plus", TreeBuilder.OTHER);
+ public static final ElementName RULE = new ElementName("rule", "rule", TreeBuilder.OTHER);
+ public static final ElementName REAL = new ElementName("real", "real", TreeBuilder.OTHER);
+ public static final ElementName RELN = new ElementName("reln", "reln", TreeBuilder.OTHER);
+ public static final ElementName RECT = new ElementName("rect", "rect", TreeBuilder.OTHER);
+ public static final ElementName ROOT = new ElementName("root", "root", TreeBuilder.OTHER);
+ public static final ElementName RUBY = new ElementName("ruby", "ruby", TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
+ public static final ElementName SECH = new ElementName("sech", "sech", TreeBuilder.OTHER);
+ public static final ElementName SINH = new ElementName("sinh", "sinh", TreeBuilder.OTHER);
+ public static final ElementName SPAN = new ElementName("span", "span", TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
+ public static final ElementName SAMP = new ElementName("samp", "samp", TreeBuilder.OTHER);
+ public static final ElementName STOP = new ElementName("stop", "stop", TreeBuilder.OTHER);
+ public static final ElementName SDEV = new ElementName("sdev", "sdev", TreeBuilder.OTHER);
+ public static final ElementName TIME = new ElementName("time", "time", TreeBuilder.OTHER);
+ public static final ElementName TRUE = new ElementName("true", "true", TreeBuilder.OTHER);
+ public static final ElementName TREF = new ElementName("tref", "tref", TreeBuilder.OTHER);
+ public static final ElementName TANH = new ElementName("tanh", "tanh", TreeBuilder.OTHER);
+ public static final ElementName TEXT = new ElementName("text", "text", TreeBuilder.OTHER);
+ public static final ElementName VIEW = new ElementName("view", "view", TreeBuilder.OTHER);
+ public static final ElementName ASIDE = new ElementName("aside", "aside", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+ public static final ElementName AUDIO = new ElementName("audio", "audio", TreeBuilder.OTHER);
+ public static final ElementName APPLY = new ElementName("apply", "apply", TreeBuilder.OTHER);
+ public static final ElementName EMBED = new ElementName("embed", "embed", TreeBuilder.EMBED | SPECIAL);
+ public static final ElementName FRAME = new ElementName("frame", "frame", TreeBuilder.FRAME | SPECIAL);
+ public static final ElementName FALSE = new ElementName("false", "false", TreeBuilder.OTHER);
+ public static final ElementName FLOOR = new ElementName("floor", "floor", TreeBuilder.OTHER);
+ public static final ElementName GLYPH = new ElementName("glyph", "glyph", TreeBuilder.OTHER);
+ public static final ElementName HKERN = new ElementName("hkern", "hkern", TreeBuilder.OTHER);
+ public static final ElementName IMAGE = new ElementName("image", "image", TreeBuilder.IMAGE);
+ public static final ElementName IDENT = new ElementName("ident", "ident", TreeBuilder.OTHER);
+ public static final ElementName INPUT = new ElementName("input", "input", TreeBuilder.INPUT | SPECIAL);
+ public static final ElementName LABEL = new ElementName("label", "label", TreeBuilder.OTHER);
+ public static final ElementName LIMIT = new ElementName("limit", "limit", TreeBuilder.OTHER);
+ public static final ElementName MFRAC = new ElementName("mfrac", "mfrac", TreeBuilder.OTHER);
+ public static final ElementName MPATH = new ElementName("mpath", "mpath", TreeBuilder.OTHER);
+ public static final ElementName METER = new ElementName("meter", "meter", TreeBuilder.OTHER);
+ public static final ElementName MOVER = new ElementName("mover", "mover", TreeBuilder.OTHER);
+ public static final ElementName MINUS = new ElementName("minus", "minus", TreeBuilder.OTHER);
+ public static final ElementName MROOT = new ElementName("mroot", "mroot", TreeBuilder.OTHER);
+ public static final ElementName MSQRT = new ElementName("msqrt", "msqrt", TreeBuilder.OTHER);
+ public static final ElementName MTEXT = new ElementName("mtext", "mtext", TreeBuilder.MI_MO_MN_MS_MTEXT | SCOPING_AS_MATHML);
+ public static final ElementName NOTIN = new ElementName("notin", "notin", TreeBuilder.OTHER);
+ public static final ElementName PIECE = new ElementName("piece", "piece", TreeBuilder.OTHER);
+ public static final ElementName PARAM = new ElementName("param", "param", TreeBuilder.PARAM_OR_SOURCE_OR_TRACK | SPECIAL);
+ public static final ElementName POWER = new ElementName("power", "power", TreeBuilder.OTHER);
+ public static final ElementName REALS = new ElementName("reals", "reals", TreeBuilder.OTHER);
+ public static final ElementName STYLE = new ElementName("style", "style", TreeBuilder.STYLE | SPECIAL);
+ public static final ElementName SMALL = new ElementName("small", "small", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ public static final ElementName THEAD = new ElementName("thead", "thead", TreeBuilder.TBODY_OR_THEAD_OR_TFOOT | SPECIAL | FOSTER_PARENTING | OPTIONAL_END_TAG);
+ public static final ElementName TABLE = new ElementName("table", "table", TreeBuilder.TABLE | SPECIAL | FOSTER_PARENTING | SCOPING);
+ public static final ElementName TITLE = new ElementName("title", "title", TreeBuilder.TITLE | SPECIAL | SCOPING_AS_SVG);
+ public static final ElementName TRACK = new ElementName("track", "track", TreeBuilder.PARAM_OR_SOURCE_OR_TRACK | SPECIAL);
+ public static final ElementName TSPAN = new ElementName("tspan", "tspan", TreeBuilder.OTHER);
+ public static final ElementName TIMES = new ElementName("times", "times", TreeBuilder.OTHER);
+ public static final ElementName TFOOT = new ElementName("tfoot", "tfoot", TreeBuilder.TBODY_OR_THEAD_OR_TFOOT | SPECIAL | FOSTER_PARENTING | OPTIONAL_END_TAG);
+ public static final ElementName TBODY = new ElementName("tbody", "tbody", TreeBuilder.TBODY_OR_THEAD_OR_TFOOT | SPECIAL | FOSTER_PARENTING | OPTIONAL_END_TAG);
+ public static final ElementName UNION = new ElementName("union", "union", TreeBuilder.OTHER);
+ public static final ElementName VKERN = new ElementName("vkern", "vkern", TreeBuilder.OTHER);
+ public static final ElementName VIDEO = new ElementName("video", "video", TreeBuilder.OTHER);
+ public static final ElementName ARCSEC = new ElementName("arcsec", "arcsec", TreeBuilder.OTHER);
+ public static final ElementName ARCCSC = new ElementName("arccsc", "arccsc", TreeBuilder.OTHER);
+ public static final ElementName ARCTAN = new ElementName("arctan", "arctan", TreeBuilder.OTHER);
+ public static final ElementName ARCSIN = new ElementName("arcsin", "arcsin", TreeBuilder.OTHER);
+ public static final ElementName ARCCOS = new ElementName("arccos", "arccos", TreeBuilder.OTHER);
+ public static final ElementName APPLET = new ElementName("applet", "applet", TreeBuilder.MARQUEE_OR_APPLET | SPECIAL | SCOPING);
+ public static final ElementName ARCCOT = new ElementName("arccot", "arccot", TreeBuilder.OTHER);
+ public static final ElementName APPROX = new ElementName("approx", "approx", TreeBuilder.OTHER);
+ public static final ElementName BUTTON = new ElementName("button", "button", TreeBuilder.BUTTON | SPECIAL);
+ public static final ElementName CIRCLE = new ElementName("circle", "circle", TreeBuilder.OTHER);
+ public static final ElementName CENTER = new ElementName("center", "center", TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
+ public static final ElementName CURSOR = new ElementName("cursor", "cursor", TreeBuilder.OTHER);
+ public static final ElementName CANVAS = new ElementName("canvas", "canvas", TreeBuilder.OTHER);
+ public static final ElementName DIVIDE = new ElementName("divide", "divide", TreeBuilder.OTHER);
+ public static final ElementName DEGREE = new ElementName("degree", "degree", TreeBuilder.OTHER);
+ public static final ElementName DOMAIN = new ElementName("domain", "domain", TreeBuilder.OTHER);
+ public static final ElementName EXISTS = new ElementName("exists", "exists", TreeBuilder.OTHER);
+ public static final ElementName FETILE = new ElementName("fetile", "feTile", TreeBuilder.OTHER);
+ public static final ElementName FIGURE = new ElementName("figure", "figure", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+ public static final ElementName FORALL = new ElementName("forall", "forall", TreeBuilder.OTHER);
+ public static final ElementName FILTER = new ElementName("filter", "filter", TreeBuilder.OTHER);
+ public static final ElementName FOOTER = new ElementName("footer", "footer", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+ public static final ElementName HGROUP = new ElementName("hgroup", "hgroup", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+ public static final ElementName HEADER = new ElementName("header", "header", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+ public static final ElementName IFRAME = new ElementName("iframe", "iframe", TreeBuilder.IFRAME | SPECIAL);
+ public static final ElementName KEYGEN = new ElementName("keygen", "keygen", TreeBuilder.KEYGEN);
+ public static final ElementName LAMBDA = new ElementName("lambda", "lambda", TreeBuilder.OTHER);
+ public static final ElementName LEGEND = new ElementName("legend", "legend", TreeBuilder.OTHER);
+ public static final ElementName MSPACE = new ElementName("mspace", "mspace", TreeBuilder.OTHER);
+ public static final ElementName MTABLE = new ElementName("mtable", "mtable", TreeBuilder.OTHER);
+ public static final ElementName MSTYLE = new ElementName("mstyle", "mstyle", TreeBuilder.OTHER);
+ public static final ElementName MGLYPH = new ElementName("mglyph", "mglyph", TreeBuilder.MGLYPH_OR_MALIGNMARK);
+ public static final ElementName MEDIAN = new ElementName("median", "median", TreeBuilder.OTHER);
+ public static final ElementName MUNDER = new ElementName("munder", "munder", TreeBuilder.OTHER);
+ public static final ElementName MARKER = new ElementName("marker", "marker", TreeBuilder.OTHER);
+ public static final ElementName MERROR = new ElementName("merror", "merror", TreeBuilder.OTHER);
+ public static final ElementName MOMENT = new ElementName("moment", "moment", TreeBuilder.OTHER);
+ public static final ElementName MATRIX = new ElementName("matrix", "matrix", TreeBuilder.OTHER);
+ public static final ElementName OPTION = new ElementName("option", "option", TreeBuilder.OPTION | OPTIONAL_END_TAG);
+ public static final ElementName OBJECT = new ElementName("object", "object", TreeBuilder.OBJECT | SPECIAL | SCOPING);
+ public static final ElementName OUTPUT = new ElementName("output", "output", TreeBuilder.OUTPUT);
+ public static final ElementName PRIMES = new ElementName("primes", "primes", TreeBuilder.OTHER);
+ public static final ElementName SOURCE = new ElementName("source", "source", TreeBuilder.PARAM_OR_SOURCE_OR_TRACK);
+ public static final ElementName STRIKE = new ElementName("strike", "strike", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ public static final ElementName STRONG = new ElementName("strong", "strong", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ public static final ElementName SWITCH = new ElementName("switch", "switch", TreeBuilder.OTHER);
+ public static final ElementName SYMBOL = new ElementName("symbol", "symbol", TreeBuilder.OTHER);
+ public static final ElementName SELECT = new ElementName("select", "select", TreeBuilder.SELECT | SPECIAL);
+ public static final ElementName SUBSET = new ElementName("subset", "subset", TreeBuilder.OTHER);
+ public static final ElementName SCRIPT = new ElementName("script", "script", TreeBuilder.SCRIPT | SPECIAL);
+ public static final ElementName TBREAK = new ElementName("tbreak", "tbreak", TreeBuilder.OTHER);
+ public static final ElementName VECTOR = new ElementName("vector", "vector", TreeBuilder.OTHER);
+ public static final ElementName ARTICLE = new ElementName("article", "article", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+ public static final ElementName ANIMATE = new ElementName("animate", "animate", TreeBuilder.OTHER);
+ public static final ElementName ARCSECH = new ElementName("arcsech", "arcsech", TreeBuilder.OTHER);
+ public static final ElementName ARCCSCH = new ElementName("arccsch", "arccsch", TreeBuilder.OTHER);
+ public static final ElementName ARCTANH = new ElementName("arctanh", "arctanh", TreeBuilder.OTHER);
+ public static final ElementName ARCSINH = new ElementName("arcsinh", "arcsinh", TreeBuilder.OTHER);
+ public static final ElementName ARCCOSH = new ElementName("arccosh", "arccosh", TreeBuilder.OTHER);
+ public static final ElementName ARCCOTH = new ElementName("arccoth", "arccoth", TreeBuilder.OTHER);
+ public static final ElementName ACRONYM = new ElementName("acronym", "acronym", TreeBuilder.OTHER);
+ public static final ElementName ADDRESS = new ElementName("address", "address", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+ public static final ElementName BGSOUND = new ElementName("bgsound", "bgsound", TreeBuilder.LINK_OR_BASEFONT_OR_BGSOUND | SPECIAL);
+ public static final ElementName COMPOSE = new ElementName("compose", "compose", TreeBuilder.OTHER);
+ public static final ElementName CEILING = new ElementName("ceiling", "ceiling", TreeBuilder.OTHER);
+ public static final ElementName CSYMBOL = new ElementName("csymbol", "csymbol", TreeBuilder.OTHER);
+ public static final ElementName CAPTION = new ElementName("caption", "caption", TreeBuilder.CAPTION | SPECIAL | SCOPING);
+ public static final ElementName DISCARD = new ElementName("discard", "discard", TreeBuilder.OTHER);
+ public static final ElementName DECLARE = new ElementName("declare", "declare", TreeBuilder.OTHER);
+ public static final ElementName DETAILS = new ElementName("details", "details", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+ public static final ElementName ELLIPSE = new ElementName("ellipse", "ellipse", TreeBuilder.OTHER);
+ public static final ElementName FEFUNCA = new ElementName("fefunca", "feFuncA", TreeBuilder.OTHER);
+ public static final ElementName FEFUNCB = new ElementName("fefuncb", "feFuncB", TreeBuilder.OTHER);
+ public static final ElementName FEBLEND = new ElementName("feblend", "feBlend", TreeBuilder.OTHER);
+ public static final ElementName FEFLOOD = new ElementName("feflood", "feFlood", TreeBuilder.OTHER);
+ public static final ElementName FEIMAGE = new ElementName("feimage", "feImage", TreeBuilder.OTHER);
+ public static final ElementName FEMERGE = new ElementName("femerge", "feMerge", TreeBuilder.OTHER);
+ public static final ElementName FEFUNCG = new ElementName("fefuncg", "feFuncG", TreeBuilder.OTHER);
+ public static final ElementName FEFUNCR = new ElementName("fefuncr", "feFuncR", TreeBuilder.OTHER);
+ public static final ElementName HANDLER = new ElementName("handler", "handler", TreeBuilder.OTHER);
+ public static final ElementName INVERSE = new ElementName("inverse", "inverse", TreeBuilder.OTHER);
+ public static final ElementName IMPLIES = new ElementName("implies", "implies", TreeBuilder.OTHER);
+ public static final ElementName ISINDEX = new ElementName("isindex", "isindex", TreeBuilder.ISINDEX | SPECIAL);
+ public static final ElementName LOGBASE = new ElementName("logbase", "logbase", TreeBuilder.OTHER);
+ public static final ElementName LISTING = new ElementName("listing", "listing", TreeBuilder.PRE_OR_LISTING | SPECIAL);
+ public static final ElementName MFENCED = new ElementName("mfenced", "mfenced", TreeBuilder.OTHER);
+ public static final ElementName MPADDED = new ElementName("mpadded", "mpadded", TreeBuilder.OTHER);
+ public static final ElementName MARQUEE = new ElementName("marquee", "marquee", TreeBuilder.MARQUEE_OR_APPLET | SPECIAL | SCOPING);
+ public static final ElementName MACTION = new ElementName("maction", "maction", TreeBuilder.OTHER);
+ public static final ElementName MSUBSUP = new ElementName("msubsup", "msubsup", TreeBuilder.OTHER);
+ public static final ElementName NOEMBED = new ElementName("noembed", "noembed", TreeBuilder.NOEMBED | SPECIAL);
+ public static final ElementName POLYGON = new ElementName("polygon", "polygon", TreeBuilder.OTHER);
+ public static final ElementName PATTERN = new ElementName("pattern", "pattern", TreeBuilder.OTHER);
+ public static final ElementName PICTURE = new ElementName("picture", "picture", TreeBuilder.OTHER);
+ public static final ElementName PRODUCT = new ElementName("product", "product", TreeBuilder.OTHER);
+ public static final ElementName SETDIFF = new ElementName("setdiff", "setdiff", TreeBuilder.OTHER);
+ public static final ElementName SECTION = new ElementName("section", "section", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+ public static final ElementName SUMMARY = new ElementName("summary", "summary", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+ public static final ElementName TENDSTO = new ElementName("tendsto", "tendsto", TreeBuilder.OTHER);
+ public static final ElementName UPLIMIT = new ElementName("uplimit", "uplimit", TreeBuilder.OTHER);
+ public static final ElementName ALTGLYPH = new ElementName("altglyph", "altGlyph", TreeBuilder.OTHER);
+ public static final ElementName BASEFONT = new ElementName("basefont", "basefont", TreeBuilder.LINK_OR_BASEFONT_OR_BGSOUND | SPECIAL);
+ public static final ElementName CLIPPATH = new ElementName("clippath", "clipPath", TreeBuilder.OTHER);
+ public static final ElementName CODOMAIN = new ElementName("codomain", "codomain", TreeBuilder.OTHER);
+ public static final ElementName COLGROUP = new ElementName("colgroup", "colgroup", TreeBuilder.COLGROUP | SPECIAL | OPTIONAL_END_TAG);
+ public static final ElementName EMPTYSET = new ElementName("emptyset", "emptyset", TreeBuilder.OTHER);
+ public static final ElementName FACTOROF = new ElementName("factorof", "factorof", TreeBuilder.OTHER);
+ public static final ElementName FIELDSET = new ElementName("fieldset", "fieldset", TreeBuilder.FIELDSET | SPECIAL);
+ public static final ElementName FRAMESET = new ElementName("frameset", "frameset", TreeBuilder.FRAMESET | SPECIAL);
+ public static final ElementName FEOFFSET = new ElementName("feoffset", "feOffset", TreeBuilder.OTHER);
+ public static final ElementName GLYPHREF = new ElementName("glyphref", "glyphRef", TreeBuilder.OTHER);
+ public static final ElementName INTERVAL = new ElementName("interval", "interval", TreeBuilder.OTHER);
+ public static final ElementName INTEGERS = new ElementName("integers", "integers", TreeBuilder.OTHER);
+ public static final ElementName INFINITY = new ElementName("infinity", "infinity", TreeBuilder.OTHER);
+ public static final ElementName LISTENER = new ElementName("listener", "listener", TreeBuilder.OTHER);
+ public static final ElementName LOWLIMIT = new ElementName("lowlimit", "lowlimit", TreeBuilder.OTHER);
+ public static final ElementName METADATA = new ElementName("metadata", "metadata", TreeBuilder.OTHER);
+ public static final ElementName MENCLOSE = new ElementName("menclose", "menclose", TreeBuilder.OTHER);
+ public static final ElementName MENUITEM = new ElementName("menuitem", "menuitem", TreeBuilder.MENUITEM);
+ public static final ElementName MPHANTOM = new ElementName("mphantom", "mphantom", TreeBuilder.OTHER);
+ public static final ElementName NOFRAMES = new ElementName("noframes", "noframes", TreeBuilder.NOFRAMES | SPECIAL);
+ public static final ElementName NOSCRIPT = new ElementName("noscript", "noscript", TreeBuilder.NOSCRIPT | SPECIAL);
+ public static final ElementName OPTGROUP = new ElementName("optgroup", "optgroup", TreeBuilder.OPTGROUP | OPTIONAL_END_TAG);
+ public static final ElementName POLYLINE = new ElementName("polyline", "polyline", TreeBuilder.OTHER);
+ public static final ElementName PREFETCH = new ElementName("prefetch", "prefetch", TreeBuilder.OTHER);
+ public static final ElementName PROGRESS = new ElementName("progress", "progress", TreeBuilder.OTHER);
+ public static final ElementName PRSUBSET = new ElementName("prsubset", "prsubset", TreeBuilder.OTHER);
+ public static final ElementName QUOTIENT = new ElementName("quotient", "quotient", TreeBuilder.OTHER);
+ public static final ElementName SELECTOR = new ElementName("selector", "selector", TreeBuilder.OTHER);
+ public static final ElementName TEXTAREA = new ElementName("textarea", "textarea", TreeBuilder.TEXTAREA | SPECIAL);
+ public static final ElementName TEMPLATE = new ElementName("template", "template", TreeBuilder.TEMPLATE | SPECIAL | SCOPING);
+ public static final ElementName TEXTPATH = new ElementName("textpath", "textPath", TreeBuilder.OTHER);
+ public static final ElementName VARIANCE = new ElementName("variance", "variance", TreeBuilder.OTHER);
+ public static final ElementName ANIMATION = new ElementName("animation", "animation", TreeBuilder.OTHER);
+ public static final ElementName CONJUGATE = new ElementName("conjugate", "conjugate", TreeBuilder.OTHER);
+ public static final ElementName CONDITION = new ElementName("condition", "condition", TreeBuilder.OTHER);
+ public static final ElementName COMPLEXES = new ElementName("complexes", "complexes", TreeBuilder.OTHER);
+ public static final ElementName FONT_FACE = new ElementName("font-face", "font-face", TreeBuilder.OTHER);
+ public static final ElementName FACTORIAL = new ElementName("factorial", "factorial", TreeBuilder.OTHER);
+ public static final ElementName INTERSECT = new ElementName("intersect", "intersect", TreeBuilder.OTHER);
+ public static final ElementName IMAGINARY = new ElementName("imaginary", "imaginary", TreeBuilder.OTHER);
+ public static final ElementName LAPLACIAN = new ElementName("laplacian", "laplacian", TreeBuilder.OTHER);
+ public static final ElementName MATRIXROW = new ElementName("matrixrow", "matrixrow", TreeBuilder.OTHER);
+ public static final ElementName NOTSUBSET = new ElementName("notsubset", "notsubset", TreeBuilder.OTHER);
+ public static final ElementName OTHERWISE = new ElementName("otherwise", "otherwise", TreeBuilder.OTHER);
+ public static final ElementName PIECEWISE = new ElementName("piecewise", "piecewise", TreeBuilder.OTHER);
+ public static final ElementName PLAINTEXT = new ElementName("plaintext", "plaintext", TreeBuilder.PLAINTEXT | SPECIAL);
+ public static final ElementName RATIONALS = new ElementName("rationals", "rationals", TreeBuilder.OTHER);
+ public static final ElementName SEMANTICS = new ElementName("semantics", "semantics", TreeBuilder.OTHER);
+ public static final ElementName TRANSPOSE = new ElementName("transpose", "transpose", TreeBuilder.OTHER);
+ public static final ElementName ANNOTATION = new ElementName("annotation", "annotation", TreeBuilder.OTHER);
+ public static final ElementName BLOCKQUOTE = new ElementName("blockquote", "blockquote", TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
+ public static final ElementName DIVERGENCE = new ElementName("divergence", "divergence", TreeBuilder.OTHER);
+ public static final ElementName EULERGAMMA = new ElementName("eulergamma", "eulergamma", TreeBuilder.OTHER);
+ public static final ElementName EQUIVALENT = new ElementName("equivalent", "equivalent", TreeBuilder.OTHER);
+ public static final ElementName FIGCAPTION = new ElementName("figcaption", "figcaption", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
+ public static final ElementName IMAGINARYI = new ElementName("imaginaryi", "imaginaryi", TreeBuilder.OTHER);
+ public static final ElementName MALIGNMARK = new ElementName("malignmark", "malignmark", TreeBuilder.MGLYPH_OR_MALIGNMARK);
+ public static final ElementName MUNDEROVER = new ElementName("munderover", "munderover", TreeBuilder.OTHER);
+ public static final ElementName MLABELEDTR = new ElementName("mlabeledtr", "mlabeledtr", TreeBuilder.OTHER);
+ public static final ElementName NOTANUMBER = new ElementName("notanumber", "notanumber", TreeBuilder.OTHER);
+ public static final ElementName SOLIDCOLOR = new ElementName("solidcolor", "solidcolor", TreeBuilder.OTHER);
+ public static final ElementName ALTGLYPHDEF = new ElementName("altglyphdef", "altGlyphDef", TreeBuilder.OTHER);
+ public static final ElementName DETERMINANT = new ElementName("determinant", "determinant", TreeBuilder.OTHER);
+ public static final ElementName FEMERGENODE = new ElementName("femergenode", "feMergeNode", TreeBuilder.OTHER);
+ public static final ElementName FECOMPOSITE = new ElementName("fecomposite", "feComposite", TreeBuilder.OTHER);
+ public static final ElementName FESPOTLIGHT = new ElementName("fespotlight", "feSpotLight", TreeBuilder.OTHER);
+ public static final ElementName MALIGNGROUP = new ElementName("maligngroup", "maligngroup", TreeBuilder.OTHER);
+ public static final ElementName MPRESCRIPTS = new ElementName("mprescripts", "mprescripts", TreeBuilder.OTHER);
+ public static final ElementName MOMENTABOUT = new ElementName("momentabout", "momentabout", TreeBuilder.OTHER);
+ public static final ElementName NOTPRSUBSET = new ElementName("notprsubset", "notprsubset", TreeBuilder.OTHER);
+ public static final ElementName PARTIALDIFF = new ElementName("partialdiff", "partialdiff", TreeBuilder.OTHER);
+ public static final ElementName ALTGLYPHITEM = new ElementName("altglyphitem", "altGlyphItem", TreeBuilder.OTHER);
+ public static final ElementName ANIMATECOLOR = new ElementName("animatecolor", "animateColor", TreeBuilder.OTHER);
+ public static final ElementName DATATEMPLATE = new ElementName("datatemplate", "datatemplate", TreeBuilder.OTHER);
+ public static final ElementName EXPONENTIALE = new ElementName("exponentiale", "exponentiale", TreeBuilder.OTHER);
+ public static final ElementName FETURBULENCE = new ElementName("feturbulence", "feTurbulence", TreeBuilder.OTHER);
+ public static final ElementName FEPOINTLIGHT = new ElementName("fepointlight", "fePointLight", TreeBuilder.OTHER);
+ public static final ElementName FEDROPSHADOW = new ElementName("fedropshadow", "feDropShadow", TreeBuilder.OTHER);
+ public static final ElementName FEMORPHOLOGY = new ElementName("femorphology", "feMorphology", TreeBuilder.OTHER);
+ public static final ElementName OUTERPRODUCT = new ElementName("outerproduct", "outerproduct", TreeBuilder.OTHER);
+ public static final ElementName ANIMATEMOTION = new ElementName("animatemotion", "animateMotion", TreeBuilder.OTHER);
+ public static final ElementName COLOR_PROFILE = new ElementName("color-profile", "color-profile", TreeBuilder.OTHER);
+ public static final ElementName FONT_FACE_SRC = new ElementName("font-face-src", "font-face-src", TreeBuilder.OTHER);
+ public static final ElementName FONT_FACE_URI = new ElementName("font-face-uri", "font-face-uri", TreeBuilder.OTHER);
+ public static final ElementName FOREIGNOBJECT = new ElementName("foreignobject", "foreignObject", TreeBuilder.FOREIGNOBJECT_OR_DESC | SCOPING_AS_SVG);
+ public static final ElementName FECOLORMATRIX = new ElementName("fecolormatrix", "feColorMatrix", TreeBuilder.OTHER);
+ public static final ElementName MISSING_GLYPH = new ElementName("missing-glyph", "missing-glyph", TreeBuilder.OTHER);
+ public static final ElementName MMULTISCRIPTS = new ElementName("mmultiscripts", "mmultiscripts", TreeBuilder.OTHER);
+ public static final ElementName SCALARPRODUCT = new ElementName("scalarproduct", "scalarproduct", TreeBuilder.OTHER);
+ public static final ElementName VECTORPRODUCT = new ElementName("vectorproduct", "vectorproduct", TreeBuilder.OTHER);
+ public static final ElementName ANNOTATION_XML = new ElementName("annotation-xml", "annotation-xml", TreeBuilder.ANNOTATION_XML | SCOPING_AS_MATHML);
+ public static final ElementName DEFINITION_SRC = new ElementName("definition-src", "definition-src", TreeBuilder.OTHER);
+ public static final ElementName FONT_FACE_NAME = new ElementName("font-face-name", "font-face-name", TreeBuilder.OTHER);
+ public static final ElementName FEGAUSSIANBLUR = new ElementName("fegaussianblur", "feGaussianBlur", TreeBuilder.OTHER);
+ public static final ElementName FEDISTANTLIGHT = new ElementName("fedistantlight", "feDistantLight", TreeBuilder.OTHER);
+ public static final ElementName LINEARGRADIENT = new ElementName("lineargradient", "linearGradient", TreeBuilder.OTHER);
+ public static final ElementName NATURALNUMBERS = new ElementName("naturalnumbers", "naturalnumbers", TreeBuilder.OTHER);
+ public static final ElementName RADIALGRADIENT = new ElementName("radialgradient", "radialGradient", TreeBuilder.OTHER);
+ public static final ElementName ANIMATETRANSFORM = new ElementName("animatetransform", "animateTransform", TreeBuilder.OTHER);
+ public static final ElementName CARTESIANPRODUCT = new ElementName("cartesianproduct", "cartesianproduct", TreeBuilder.OTHER);
+ public static final ElementName FONT_FACE_FORMAT = new ElementName("font-face-format", "font-face-format", TreeBuilder.OTHER);
+ public static final ElementName FECONVOLVEMATRIX = new ElementName("feconvolvematrix", "feConvolveMatrix", TreeBuilder.OTHER);
+ public static final ElementName FEDIFFUSELIGHTING = new ElementName("fediffuselighting", "feDiffuseLighting", TreeBuilder.OTHER);
+ public static final ElementName FEDISPLACEMENTMAP = new ElementName("fedisplacementmap", "feDisplacementMap", TreeBuilder.OTHER);
+ public static final ElementName FESPECULARLIGHTING = new ElementName("fespecularlighting", "feSpecularLighting", TreeBuilder.OTHER);
+ public static final ElementName DOMAINOFAPPLICATION = new ElementName("domainofapplication", "domainofapplication", TreeBuilder.OTHER);
+ public static final ElementName FECOMPONENTTRANSFER = new ElementName("fecomponenttransfer", "feComponentTransfer", TreeBuilder.OTHER);
+ private final static @NoLength ElementName[] ELEMENT_NAMES = {
+ A,
+ B,
+ G,
+ I,
+ P,
+ Q,
+ S,
+ U,
+ BR,
+ CI,
+ CN,
+ DD,
+ DL,
+ DT,
+ EM,
+ EQ,
+ FN,
+ H1,
+ H2,
+ H3,
+ H4,
+ H5,
+ H6,
+ GT,
+ HR,
+ IN,
+ LI,
+ LN,
+ LT,
+ MI,
+ MN,
+ MO,
+ MS,
+ OL,
+ OR,
+ PI,
+ RB,
+ RP,
+ RT,
+ TD,
+ TH,
+ TR,
+ TT,
+ UL,
+ AND,
+ ARG,
+ ABS,
+ BIG,
+ BDO,
+ CSC,
+ COL,
+ COS,
+ COT,
+ DEL,
+ DFN,
+ DIR,
+ DIV,
+ EXP,
+ GCD,
+ GEQ,
+ IMG,
+ INS,
+ INT,
+ KBD,
+ LOG,
+ LCM,
+ LEQ,
+ MTD,
+ MIN,
+ MAP,
+ MTR,
+ MAX,
+ NEQ,
+ NOT,
+ NAV,
+ PRE,
+ RTC,
+ REM,
+ SUB,
+ SEC,
+ SVG,
+ SUM,
+ SIN,
+ SEP,
+ SUP,
+ SET,
+ TAN,
+ USE,
+ VAR,
+ WBR,
+ XMP,
+ XOR,
+ AREA,
+ ABBR,
+ BASE,
+ BVAR,
+ BODY,
+ CARD,
+ CODE,
+ CITE,
+ CSCH,
+ COSH,
+ COTH,
+ CURL,
+ DESC,
+ DIFF,
+ DEFS,
+ FORM,
+ FONT,
+ GRAD,
+ HEAD,
+ HTML,
+ LINE,
+ LINK,
+ LIST,
+ META,
+ MSUB,
+ MODE,
+ MATH,
+ MARK,
+ MASK,
+ MEAN,
+ MAIN,
+ MSUP,
+ MENU,
+ MROW,
+ NONE,
+ NOBR,
+ NEST,
+ PATH,
+ PLUS,
+ RULE,
+ REAL,
+ RELN,
+ RECT,
+ ROOT,
+ RUBY,
+ SECH,
+ SINH,
+ SPAN,
+ SAMP,
+ STOP,
+ SDEV,
+ TIME,
+ TRUE,
+ TREF,
+ TANH,
+ TEXT,
+ VIEW,
+ ASIDE,
+ AUDIO,
+ APPLY,
+ EMBED,
+ FRAME,
+ FALSE,
+ FLOOR,
+ GLYPH,
+ HKERN,
+ IMAGE,
+ IDENT,
+ INPUT,
+ LABEL,
+ LIMIT,
+ MFRAC,
+ MPATH,
+ METER,
+ MOVER,
+ MINUS,
+ MROOT,
+ MSQRT,
+ MTEXT,
+ NOTIN,
+ PIECE,
+ PARAM,
+ POWER,
+ REALS,
+ STYLE,
+ SMALL,
+ THEAD,
+ TABLE,
+ TITLE,
+ TRACK,
+ TSPAN,
+ TIMES,
+ TFOOT,
+ TBODY,
+ UNION,
+ VKERN,
+ VIDEO,
+ ARCSEC,
+ ARCCSC,
+ ARCTAN,
+ ARCSIN,
+ ARCCOS,
+ APPLET,
+ ARCCOT,
+ APPROX,
+ BUTTON,
+ CIRCLE,
+ CENTER,
+ CURSOR,
+ CANVAS,
+ DIVIDE,
+ DEGREE,
+ DOMAIN,
+ EXISTS,
+ FETILE,
+ FIGURE,
+ FORALL,
+ FILTER,
+ FOOTER,
+ HGROUP,
+ HEADER,
+ IFRAME,
+ KEYGEN,
+ LAMBDA,
+ LEGEND,
+ MSPACE,
+ MTABLE,
+ MSTYLE,
+ MGLYPH,
+ MEDIAN,
+ MUNDER,
+ MARKER,
+ MERROR,
+ MOMENT,
+ MATRIX,
+ OPTION,
+ OBJECT,
+ OUTPUT,
+ PRIMES,
+ SOURCE,
+ STRIKE,
+ STRONG,
+ SWITCH,
+ SYMBOL,
+ SELECT,
+ SUBSET,
+ SCRIPT,
+ TBREAK,
+ VECTOR,
+ ARTICLE,
+ ANIMATE,
+ ARCSECH,
+ ARCCSCH,
+ ARCTANH,
+ ARCSINH,
+ ARCCOSH,
+ ARCCOTH,
+ ACRONYM,
+ ADDRESS,
+ BGSOUND,
+ COMPOSE,
+ CEILING,
+ CSYMBOL,
+ CAPTION,
+ DISCARD,
+ DECLARE,
+ DETAILS,
+ ELLIPSE,
+ FEFUNCA,
+ FEFUNCB,
+ FEBLEND,
+ FEFLOOD,
+ FEIMAGE,
+ FEMERGE,
+ FEFUNCG,
+ FEFUNCR,
+ HANDLER,
+ INVERSE,
+ IMPLIES,
+ ISINDEX,
+ LOGBASE,
+ LISTING,
+ MFENCED,
+ MPADDED,
+ MARQUEE,
+ MACTION,
+ MSUBSUP,
+ NOEMBED,
+ POLYGON,
+ PATTERN,
+ PICTURE,
+ PRODUCT,
+ SETDIFF,
+ SECTION,
+ SUMMARY,
+ TENDSTO,
+ UPLIMIT,
+ ALTGLYPH,
+ BASEFONT,
+ CLIPPATH,
+ CODOMAIN,
+ COLGROUP,
+ EMPTYSET,
+ FACTOROF,
+ FIELDSET,
+ FRAMESET,
+ FEOFFSET,
+ GLYPHREF,
+ INTERVAL,
+ INTEGERS,
+ INFINITY,
+ LISTENER,
+ LOWLIMIT,
+ METADATA,
+ MENCLOSE,
+ MENUITEM,
+ MPHANTOM,
+ NOFRAMES,
+ NOSCRIPT,
+ OPTGROUP,
+ POLYLINE,
+ PREFETCH,
+ PROGRESS,
+ PRSUBSET,
+ QUOTIENT,
+ SELECTOR,
+ TEXTAREA,
+ TEMPLATE,
+ TEXTPATH,
+ VARIANCE,
+ ANIMATION,
+ CONJUGATE,
+ CONDITION,
+ COMPLEXES,
+ FONT_FACE,
+ FACTORIAL,
+ INTERSECT,
+ IMAGINARY,
+ LAPLACIAN,
+ MATRIXROW,
+ NOTSUBSET,
+ OTHERWISE,
+ PIECEWISE,
+ PLAINTEXT,
+ RATIONALS,
+ SEMANTICS,
+ TRANSPOSE,
+ ANNOTATION,
+ BLOCKQUOTE,
+ DIVERGENCE,
+ EULERGAMMA,
+ EQUIVALENT,
+ FIGCAPTION,
+ IMAGINARYI,
+ MALIGNMARK,
+ MUNDEROVER,
+ MLABELEDTR,
+ NOTANUMBER,
+ SOLIDCOLOR,
+ ALTGLYPHDEF,
+ DETERMINANT,
+ FEMERGENODE,
+ FECOMPOSITE,
+ FESPOTLIGHT,
+ MALIGNGROUP,
+ MPRESCRIPTS,
+ MOMENTABOUT,
+ NOTPRSUBSET,
+ PARTIALDIFF,
+ ALTGLYPHITEM,
+ ANIMATECOLOR,
+ DATATEMPLATE,
+ EXPONENTIALE,
+ FETURBULENCE,
+ FEPOINTLIGHT,
+ FEDROPSHADOW,
+ FEMORPHOLOGY,
+ OUTERPRODUCT,
+ ANIMATEMOTION,
+ COLOR_PROFILE,
+ FONT_FACE_SRC,
+ FONT_FACE_URI,
+ FOREIGNOBJECT,
+ FECOLORMATRIX,
+ MISSING_GLYPH,
+ MMULTISCRIPTS,
+ SCALARPRODUCT,
+ VECTORPRODUCT,
+ ANNOTATION_XML,
+ DEFINITION_SRC,
+ FONT_FACE_NAME,
+ FEGAUSSIANBLUR,
+ FEDISTANTLIGHT,
+ LINEARGRADIENT,
+ NATURALNUMBERS,
+ RADIALGRADIENT,
+ ANIMATETRANSFORM,
+ CARTESIANPRODUCT,
+ FONT_FACE_FORMAT,
+ FECONVOLVEMATRIX,
+ FEDIFFUSELIGHTING,
+ FEDISPLACEMENTMAP,
+ FESPECULARLIGHTING,
+ DOMAINOFAPPLICATION,
+ FECOMPONENTTRANSFER,
+ };
+ private final static int[] ELEMENT_HASHES = {
+ 1057,
+ 1090,
+ 1255,
+ 1321,
+ 1552,
+ 1585,
+ 1651,
+ 1717,
+ 68162,
+ 68899,
+ 69059,
+ 69764,
+ 70020,
+ 70276,
+ 71077,
+ 71205,
+ 72134,
+ 72232,
+ 72264,
+ 72296,
+ 72328,
+ 72360,
+ 72392,
+ 73351,
+ 74312,
+ 75209,
+ 78124,
+ 78284,
+ 78476,
+ 79149,
+ 79309,
+ 79341,
+ 79469,
+ 81295,
+ 81487,
+ 82224,
+ 84050,
+ 84498,
+ 84626,
+ 86164,
+ 86292,
+ 86612,
+ 86676,
+ 87445,
+ 3183041,
+ 3186241,
+ 3198017,
+ 3218722,
+ 3226754,
+ 3247715,
+ 3256803,
+ 3263971,
+ 3264995,
+ 3289252,
+ 3291332,
+ 3295524,
+ 3299620,
+ 3326725,
+ 3379303,
+ 3392679,
+ 3448233,
+ 3460553,
+ 3461577,
+ 3510347,
+ 3546604,
+ 3552364,
+ 3556524,
+ 3576461,
+ 3586349,
+ 3588141,
+ 3590797,
+ 3596333,
+ 3622062,
+ 3625454,
+ 3627054,
+ 3675728,
+ 3739282,
+ 3749042,
+ 3771059,
+ 3771571,
+ 3776211,
+ 3782323,
+ 3782963,
+ 3784883,
+ 3785395,
+ 3788979,
+ 3815476,
+ 3839605,
+ 3885110,
+ 3917911,
+ 3948984,
+ 3951096,
+ 135304769,
+ 135858241,
+ 136498210,
+ 136906434,
+ 137138658,
+ 137512995,
+ 137531875,
+ 137548067,
+ 137629283,
+ 137645539,
+ 137646563,
+ 137775779,
+ 138529956,
+ 138615076,
+ 139040932,
+ 140954086,
+ 141179366,
+ 141690439,
+ 142738600,
+ 143013512,
+ 146979116,
+ 147175724,
+ 147475756,
+ 147902637,
+ 147936877,
+ 148017645,
+ 148131885,
+ 148228141,
+ 148229165,
+ 148309165,
+ 148317229,
+ 148395629,
+ 148551853,
+ 148618829,
+ 149076462,
+ 149490158,
+ 149572782,
+ 151277616,
+ 151639440,
+ 153268914,
+ 153486514,
+ 153563314,
+ 153750706,
+ 153763314,
+ 153914034,
+ 154406067,
+ 154417459,
+ 154600979,
+ 154678323,
+ 154680979,
+ 154866835,
+ 155366708,
+ 155375188,
+ 155391572,
+ 155465780,
+ 155869364,
+ 158045494,
+ 168988979,
+ 169321621,
+ 169652752,
+ 173151309,
+ 174240818,
+ 174247297,
+ 174669292,
+ 175391532,
+ 176638123,
+ 177380397,
+ 177879204,
+ 177886734,
+ 180753473,
+ 181020073,
+ 181503558,
+ 181686320,
+ 181999237,
+ 181999311,
+ 182048201,
+ 182074866,
+ 182078003,
+ 182083764,
+ 182920847,
+ 184716457,
+ 184976961,
+ 185145071,
+ 187281445,
+ 187872052,
+ 188100653,
+ 188875944,
+ 188919873,
+ 188920457,
+ 189107250,
+ 189203987,
+ 189371817,
+ 189414886,
+ 189567458,
+ 190266670,
+ 191318187,
+ 191337609,
+ 202479203,
+ 202493027,
+ 202835587,
+ 202843747,
+ 203013219,
+ 203036048,
+ 203045987,
+ 203177552,
+ 203898516,
+ 204648562,
+ 205067918,
+ 205078130,
+ 205096654,
+ 205689142,
+ 205690439,
+ 205988909,
+ 207213161,
+ 207794484,
+ 207800999,
+ 208023602,
+ 208213644,
+ 208213647,
+ 210261490,
+ 210310273,
+ 210940978,
+ 213325049,
+ 213946445,
+ 214055079,
+ 215125040,
+ 215134273,
+ 215135028,
+ 215237420,
+ 215418148,
+ 215553166,
+ 215553394,
+ 215563858,
+ 215627949,
+ 215754324,
+ 217529652,
+ 217713834,
+ 217732628,
+ 218731945,
+ 221417045,
+ 221424946,
+ 221493746,
+ 221515401,
+ 221658189,
+ 221908140,
+ 221910626,
+ 221921586,
+ 222659762,
+ 225001091,
+ 236105833,
+ 236113965,
+ 236194995,
+ 236195427,
+ 236206132,
+ 236206387,
+ 236211683,
+ 236212707,
+ 236381647,
+ 236571826,
+ 237124271,
+ 238210544,
+ 238270764,
+ 238435405,
+ 238501172,
+ 239224867,
+ 239257644,
+ 239710497,
+ 240307721,
+ 241208789,
+ 241241557,
+ 241318060,
+ 241319404,
+ 241343533,
+ 241344069,
+ 241405397,
+ 241765845,
+ 243864964,
+ 244502085,
+ 244946220,
+ 245109902,
+ 247647266,
+ 247707956,
+ 248648814,
+ 248648836,
+ 248682161,
+ 248986932,
+ 249058914,
+ 249697357,
+ 252132601,
+ 252135604,
+ 251841204,
+ 252317348,
+ 255007012,
+ 255278388,
+ 255641645,
+ 256365156,
+ 257566121,
+ 269763372,
+ 271202790,
+ 271863856,
+ 272049197,
+ 272127474,
+ 274339449,
+ 274939471,
+ 275388004,
+ 275388005,
+ 275388006,
+ 275977800,
+ 278267602,
+ 278513831,
+ 278712622,
+ 281613765,
+ 281683369,
+ 282120228,
+ 282250732,
+ 282498697,
+ 282508942,
+ 283743649,
+ 283787570,
+ 284710386,
+ 285391148,
+ 285478533,
+ 285854898,
+ 285873762,
+ 286931113,
+ 288964227,
+ 289445441,
+ 289591340,
+ 289689648,
+ 291671489,
+ 303512884,
+ 305319975,
+ 305610036,
+ 305764101,
+ 308448294,
+ 308675890,
+ 312085683,
+ 312264750,
+ 315032867,
+ 316391000,
+ 317331042,
+ 317902135,
+ 318950711,
+ 319447220,
+ 321499182,
+ 322538804,
+ 323145200,
+ 337067316,
+ 337826293,
+ 339905989,
+ 340833697,
+ 341457068,
+ 342310196,
+ 345302593,
+ 349554733,
+ 349771471,
+ 349786245,
+ 350819405,
+ 356072847,
+ 370349192,
+ 373962798,
+ 375558638,
+ 375574835,
+ 376053993,
+ 383276530,
+ 383373833,
+ 383407586,
+ 384439906,
+ 386079012,
+ 404133513,
+ 404307343,
+ 407031852,
+ 408072233,
+ 409112005,
+ 409608425,
+ 409713793,
+ 409771500,
+ 419040932,
+ 437730612,
+ 439529766,
+ 442616365,
+ 442813037,
+ 443157674,
+ 443295316,
+ 450118444,
+ 450482697,
+ 456789668,
+ 459935396,
+ 471217869,
+ 474073645,
+ 476230702,
+ 476665218,
+ 476717289,
+ 483014825,
+ 485083298,
+ 489306281,
+ 538364390,
+ 540675748,
+ 543819186,
+ 543958612,
+ 576960820,
+ 577242548,
+ 610515252,
+ 642202932,
+ 644420819,
+ };
+}
diff --git a/parser/html/javasrc/HtmlAttributes.java b/parser/html/javasrc/HtmlAttributes.java
new file mode 100644
index 000000000..0ec25f96f
--- /dev/null
+++ b/parser/html/javasrc/HtmlAttributes.java
@@ -0,0 +1,618 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 2008-2011 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package nu.validator.htmlparser.impl;
+
+import nu.validator.htmlparser.annotation.Auto;
+import nu.validator.htmlparser.annotation.IdType;
+import nu.validator.htmlparser.annotation.Local;
+import nu.validator.htmlparser.annotation.NsUri;
+import nu.validator.htmlparser.annotation.Prefix;
+import nu.validator.htmlparser.annotation.QName;
+import nu.validator.htmlparser.common.Interner;
+import nu.validator.htmlparser.common.XmlViolationPolicy;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * Be careful with this class. QName is the name in from HTML tokenization.
+ * Otherwise, please refer to the interface doc.
+ *
+ * @version $Id: AttributesImpl.java 206 2008-03-20 14:09:29Z hsivonen $
+ * @author hsivonen
+ */
+public final class HtmlAttributes implements Attributes {
+
+ // [NOCPP[
+
+ private static final AttributeName[] EMPTY_ATTRIBUTENAMES = new AttributeName[0];
+
+ private static final String[] EMPTY_STRINGS = new String[0];
+
+ // ]NOCPP]
+
+ public static final HtmlAttributes EMPTY_ATTRIBUTES = new HtmlAttributes(
+ AttributeName.HTML);
+
+ private int mode;
+
+ private int length;
+
+ private @Auto AttributeName[] names;
+
+ private @Auto String[] values; // XXX perhaps make this @NoLength?
+
+ // CPPONLY: private @Auto int[] lines; // XXX perhaps make this @NoLength?
+
+ // [NOCPP[
+
+ private String idValue;
+
+ private int xmlnsLength;
+
+ private AttributeName[] xmlnsNames;
+
+ private String[] xmlnsValues;
+
+ // ]NOCPP]
+
+ public HtmlAttributes(int mode) {
+ this.mode = mode;
+ this.length = 0;
+ /*
+ * The length of 5 covers covers 98.3% of elements
+ * according to Hixie, but lets round to the next power of two for
+ * jemalloc.
+ */
+ this.names = new AttributeName[8];
+ this.values = new String[8];
+ // CPPONLY: this.lines = new int[8];
+
+ // [NOCPP[
+
+ this.idValue = null;
+
+ this.xmlnsLength = 0;
+
+ this.xmlnsNames = HtmlAttributes.EMPTY_ATTRIBUTENAMES;
+
+ this.xmlnsValues = HtmlAttributes.EMPTY_STRINGS;
+
+ // ]NOCPP]
+ }
+ /*
+ public HtmlAttributes(HtmlAttributes other) {
+ this.mode = other.mode;
+ this.length = other.length;
+ this.names = new AttributeName[other.length];
+ this.values = new String[other.length];
+ // [NOCPP[
+ this.idValue = other.idValue;
+ this.xmlnsLength = other.xmlnsLength;
+ this.xmlnsNames = new AttributeName[other.xmlnsLength];
+ this.xmlnsValues = new String[other.xmlnsLength];
+ // ]NOCPP]
+ }
+ */
+
+ void destructor() {
+ clear(0);
+ }
+
+ /**
+ * Only use with a static argument
+ *
+ * @param name
+ * @return
+ */
+ public int getIndex(AttributeName name) {
+ for (int i = 0; i < length; i++) {
+ if (names[i] == name) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Only use with static argument.
+ *
+ * @see org.xml.sax.Attributes#getValue(java.lang.String)
+ */
+ public String getValue(AttributeName name) {
+ int index = getIndex(name);
+ if (index == -1) {
+ return null;
+ } else {
+ return getValueNoBoundsCheck(index);
+ }
+ }
+
+ public int getLength() {
+ return length;
+ }
+
+ /**
+ * Variant of <code>getLocalName(int index)</code> without bounds check.
+ * @param index a valid attribute index
+ * @return the local name at index
+ */
+ public @Local String getLocalNameNoBoundsCheck(int index) {
+ // CPPONLY: assert index < length && index >= 0: "Index out of bounds";
+ return names[index].getLocal(mode);
+ }
+
+ /**
+ * Variant of <code>getURI(int index)</code> without bounds check.
+ * @param index a valid attribute index
+ * @return the namespace URI at index
+ */
+ public @NsUri String getURINoBoundsCheck(int index) {
+ // CPPONLY: assert index < length && index >= 0: "Index out of bounds";
+ return names[index].getUri(mode);
+ }
+
+ /**
+ * Variant of <code>getPrefix(int index)</code> without bounds check.
+ * @param index a valid attribute index
+ * @return the namespace prefix at index
+ */
+ public @Prefix String getPrefixNoBoundsCheck(int index) {
+ // CPPONLY: assert index < length && index >= 0: "Index out of bounds";
+ return names[index].getPrefix(mode);
+ }
+
+ /**
+ * Variant of <code>getValue(int index)</code> without bounds check.
+ * @param index a valid attribute index
+ * @return the attribute value at index
+ */
+ public String getValueNoBoundsCheck(int index) {
+ // CPPONLY: assert index < length && index >= 0: "Index out of bounds";
+ return values[index];
+ }
+
+ /**
+ * Variant of <code>getAttributeName(int index)</code> without bounds check.
+ * @param index a valid attribute index
+ * @return the attribute name at index
+ */
+ public AttributeName getAttributeNameNoBoundsCheck(int index) {
+ // CPPONLY: assert index < length && index >= 0: "Index out of bounds";
+ return names[index];
+ }
+
+ // CPPONLY: /**
+ // CPPONLY: * Obtains a line number without bounds check.
+ // CPPONLY: * @param index a valid attribute index
+ // CPPONLY: * @return the line number at index or -1 if unknown
+ // CPPONLY: */
+ // CPPONLY: public int getLineNoBoundsCheck(int index) {
+ // CPPONLY: assert index < length && index >= 0: "Index out of bounds";
+ // CPPONLY: return lines[index];
+ // CPPONLY: }
+
+ // [NOCPP[
+
+ /**
+ * Variant of <code>getQName(int index)</code> without bounds check.
+ * @param index a valid attribute index
+ * @return the QName at index
+ */
+ public @QName String getQNameNoBoundsCheck(int index) {
+ return names[index].getQName(mode);
+ }
+
+ /**
+ * Variant of <code>getType(int index)</code> without bounds check.
+ * @param index a valid attribute index
+ * @return the attribute type at index
+ */
+ public @IdType String getTypeNoBoundsCheck(int index) {
+ return (names[index] == AttributeName.ID) ? "ID" : "CDATA";
+ }
+
+ public int getIndex(String qName) {
+ for (int i = 0; i < length; i++) {
+ if (names[i].getQName(mode).equals(qName)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int getIndex(String uri, String localName) {
+ for (int i = 0; i < length; i++) {
+ if (names[i].getLocal(mode).equals(localName)
+ && names[i].getUri(mode).equals(uri)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public @IdType String getType(String qName) {
+ int index = getIndex(qName);
+ if (index == -1) {
+ return null;
+ } else {
+ return getType(index);
+ }
+ }
+
+ public @IdType String getType(String uri, String localName) {
+ int index = getIndex(uri, localName);
+ if (index == -1) {
+ return null;
+ } else {
+ return getType(index);
+ }
+ }
+
+ public String getValue(String qName) {
+ int index = getIndex(qName);
+ if (index == -1) {
+ return null;
+ } else {
+ return getValue(index);
+ }
+ }
+
+ public String getValue(String uri, String localName) {
+ int index = getIndex(uri, localName);
+ if (index == -1) {
+ return null;
+ } else {
+ return getValue(index);
+ }
+ }
+
+ public @Local String getLocalName(int index) {
+ if (index < length && index >= 0) {
+ return names[index].getLocal(mode);
+ } else {
+ return null;
+ }
+ }
+
+ public @QName String getQName(int index) {
+ if (index < length && index >= 0) {
+ return names[index].getQName(mode);
+ } else {
+ return null;
+ }
+ }
+
+ public @IdType String getType(int index) {
+ if (index < length && index >= 0) {
+ return (names[index] == AttributeName.ID) ? "ID" : "CDATA";
+ } else {
+ return null;
+ }
+ }
+
+ public AttributeName getAttributeName(int index) {
+ if (index < length && index >= 0) {
+ return names[index];
+ } else {
+ return null;
+ }
+ }
+
+ public @NsUri String getURI(int index) {
+ if (index < length && index >= 0) {
+ return names[index].getUri(mode);
+ } else {
+ return null;
+ }
+ }
+
+ public @Prefix String getPrefix(int index) {
+ if (index < length && index >= 0) {
+ return names[index].getPrefix(mode);
+ } else {
+ return null;
+ }
+ }
+
+ public String getValue(int index) {
+ if (index < length && index >= 0) {
+ return values[index];
+ } else {
+ return null;
+ }
+ }
+
+ public String getId() {
+ return idValue;
+ }
+
+ public int getXmlnsLength() {
+ return xmlnsLength;
+ }
+
+ public @Local String getXmlnsLocalName(int index) {
+ if (index < xmlnsLength && index >= 0) {
+ return xmlnsNames[index].getLocal(mode);
+ } else {
+ return null;
+ }
+ }
+
+ public @NsUri String getXmlnsURI(int index) {
+ if (index < xmlnsLength && index >= 0) {
+ return xmlnsNames[index].getUri(mode);
+ } else {
+ return null;
+ }
+ }
+
+ public String getXmlnsValue(int index) {
+ if (index < xmlnsLength && index >= 0) {
+ return xmlnsValues[index];
+ } else {
+ return null;
+ }
+ }
+
+ public int getXmlnsIndex(AttributeName name) {
+ for (int i = 0; i < xmlnsLength; i++) {
+ if (xmlnsNames[i] == name) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public String getXmlnsValue(AttributeName name) {
+ int index = getXmlnsIndex(name);
+ if (index == -1) {
+ return null;
+ } else {
+ return getXmlnsValue(index);
+ }
+ }
+
+ public AttributeName getXmlnsAttributeName(int index) {
+ if (index < xmlnsLength && index >= 0) {
+ return xmlnsNames[index];
+ } else {
+ return null;
+ }
+ }
+
+ // ]NOCPP]
+
+ void addAttribute(AttributeName name, String value
+ // [NOCPP[
+ , XmlViolationPolicy xmlnsPolicy
+ // ]NOCPP]
+ // CPPONLY: , int line
+ ) throws SAXException {
+ // [NOCPP[
+ if (name == AttributeName.ID) {
+ idValue = value;
+ }
+
+ if (name.isXmlns()) {
+ if (xmlnsNames.length == xmlnsLength) {
+ int newLen = xmlnsLength == 0 ? 2 : xmlnsLength << 1;
+ AttributeName[] newNames = new AttributeName[newLen];
+ System.arraycopy(xmlnsNames, 0, newNames, 0, xmlnsNames.length);
+ xmlnsNames = newNames;
+ String[] newValues = new String[newLen];
+ System.arraycopy(xmlnsValues, 0, newValues, 0, xmlnsValues.length);
+ xmlnsValues = newValues;
+ }
+ xmlnsNames[xmlnsLength] = name;
+ xmlnsValues[xmlnsLength] = value;
+ xmlnsLength++;
+ switch (xmlnsPolicy) {
+ case FATAL:
+ // this is ugly
+ throw new SAXException("Saw an xmlns attribute.");
+ case ALTER_INFOSET:
+ return;
+ case ALLOW:
+ // fall through
+ }
+ }
+
+ // ]NOCPP]
+
+ if (names.length == length) {
+ int newLen = length << 1; // The first growth covers virtually
+ // 100% of elements according to
+ // Hixie
+ AttributeName[] newNames = new AttributeName[newLen];
+ System.arraycopy(names, 0, newNames, 0, names.length);
+ names = newNames;
+ String[] newValues = new String[newLen];
+ System.arraycopy(values, 0, newValues, 0, values.length);
+ values = newValues;
+ // CPPONLY: int[] newLines = new int[newLen];
+ // CPPONLY: System.arraycopy(lines, 0, newLines, 0, lines.length);
+ // CPPONLY: lines = newLines;
+ }
+ names[length] = name;
+ values[length] = value;
+ // CPPONLY: lines[length] = line;
+ length++;
+ }
+
+ void clear(int m) {
+ for (int i = 0; i < length; i++) {
+ names[i].release();
+ names[i] = null;
+ Portability.releaseString(values[i]);
+ values[i] = null;
+ }
+ length = 0;
+ mode = m;
+ // [NOCPP[
+ idValue = null;
+ for (int i = 0; i < xmlnsLength; i++) {
+ xmlnsNames[i] = null;
+ xmlnsValues[i] = null;
+ }
+ xmlnsLength = 0;
+ // ]NOCPP]
+ }
+
+ /**
+ * This is used in C++ to release special <code>isindex</code>
+ * attribute values whose ownership is not transferred.
+ */
+ void releaseValue(int i) {
+ Portability.releaseString(values[i]);
+ }
+
+ /**
+ * This is only used for <code>AttributeName</code> ownership transfer
+ * in the isindex case to avoid freeing custom names twice in C++.
+ */
+ void clearWithoutReleasingContents() {
+ for (int i = 0; i < length; i++) {
+ names[i] = null;
+ values[i] = null;
+ }
+ length = 0;
+ }
+
+ boolean contains(AttributeName name) {
+ for (int i = 0; i < length; i++) {
+ if (name.equalsAnother(names[i])) {
+ return true;
+ }
+ }
+ // [NOCPP[
+ for (int i = 0; i < xmlnsLength; i++) {
+ if (name.equalsAnother(xmlnsNames[i])) {
+ return true;
+ }
+ }
+ // ]NOCPP]
+ return false;
+ }
+
+ public void adjustForMath() {
+ mode = AttributeName.MATHML;
+ }
+
+ public void adjustForSvg() {
+ mode = AttributeName.SVG;
+ }
+
+ public HtmlAttributes cloneAttributes(Interner interner)
+ throws SAXException {
+ assert (length == 0
+ // [NOCPP[
+ && xmlnsLength == 0
+ // ]NOCPP]
+ )
+ || mode == 0 || mode == 3;
+ HtmlAttributes clone = new HtmlAttributes(0);
+ for (int i = 0; i < length; i++) {
+ clone.addAttribute(names[i].cloneAttributeName(interner),
+ Portability.newStringFromString(values[i])
+ // [NOCPP[
+ , XmlViolationPolicy.ALLOW
+ // ]NOCPP]
+ // CPPONLY: , lines[i]
+ );
+ }
+ // [NOCPP[
+ for (int i = 0; i < xmlnsLength; i++) {
+ clone.addAttribute(xmlnsNames[i], xmlnsValues[i],
+ XmlViolationPolicy.ALLOW);
+ }
+ // ]NOCPP]
+ return clone; // XXX!!!
+ }
+
+ public boolean equalsAnother(HtmlAttributes other) {
+ assert mode == 0 || mode == 3 : "Trying to compare attributes in foreign content.";
+ int otherLength = other.getLength();
+ if (length != otherLength) {
+ return false;
+ }
+ for (int i = 0; i < length; i++) {
+ // Work around the limitations of C++
+ boolean found = false;
+ // The comparing just the local names is OK, since these attribute
+ // holders are both supposed to belong to HTML formatting elements
+ @Local String ownLocal = names[i].getLocal(AttributeName.HTML);
+ for (int j = 0; j < otherLength; j++) {
+ if (ownLocal == other.names[j].getLocal(AttributeName.HTML)) {
+ found = true;
+ if (!Portability.stringEqualsString(values[i], other.values[j])) {
+ return false;
+ }
+ }
+ }
+ if (!found) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // [NOCPP[
+
+ void processNonNcNames(TreeBuilder<?> treeBuilder, XmlViolationPolicy namePolicy) throws SAXException {
+ for (int i = 0; i < length; i++) {
+ AttributeName attName = names[i];
+ if (!attName.isNcName(mode)) {
+ String name = attName.getLocal(mode);
+ switch (namePolicy) {
+ case ALTER_INFOSET:
+ names[i] = AttributeName.create(NCName.escapeName(name));
+ // fall through
+ case ALLOW:
+ if (attName != AttributeName.XML_LANG) {
+ treeBuilder.warn("Attribute \u201C" + name + "\u201D is not serializable as XML 1.0.");
+ }
+ break;
+ case FATAL:
+ treeBuilder.fatal("Attribute \u201C" + name + "\u201D is not serializable as XML 1.0.");
+ break;
+ }
+ }
+ }
+ }
+
+ public void merge(HtmlAttributes attributes) throws SAXException {
+ int len = attributes.getLength();
+ for (int i = 0; i < len; i++) {
+ AttributeName name = attributes.getAttributeNameNoBoundsCheck(i);
+ if (!contains(name)) {
+ addAttribute(name, attributes.getValueNoBoundsCheck(i), XmlViolationPolicy.ALLOW);
+ }
+ }
+ }
+
+
+ // ]NOCPP]
+
+}
diff --git a/parser/html/javasrc/MetaScanner.java b/parser/html/javasrc/MetaScanner.java
new file mode 100644
index 000000000..be9aabfe3
--- /dev/null
+++ b/parser/html/javasrc/MetaScanner.java
@@ -0,0 +1,854 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 2008-2015 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package nu.validator.htmlparser.impl;
+
+import java.io.IOException;
+
+import nu.validator.htmlparser.annotation.Auto;
+import nu.validator.htmlparser.annotation.Inline;
+import nu.validator.htmlparser.common.ByteReadable;
+
+import org.xml.sax.SAXException;
+
+public abstract class MetaScanner {
+
+ /**
+ * Constant for "charset".
+ */
+ private static final char[] CHARSET = { 'h', 'a', 'r', 's', 'e', 't' };
+
+ /**
+ * Constant for "content".
+ */
+ private static final char[] CONTENT = { 'o', 'n', 't', 'e', 'n', 't' };
+
+ /**
+ * Constant for "http-equiv".
+ */
+ private static final char[] HTTP_EQUIV = { 't', 't', 'p', '-', 'e', 'q',
+ 'u', 'i', 'v' };
+
+ /**
+ * Constant for "content-type".
+ */
+ private static final char[] CONTENT_TYPE = { 'c', 'o', 'n', 't', 'e', 'n',
+ 't', '-', 't', 'y', 'p', 'e' };
+
+ private static final int NO = 0;
+
+ private static final int M = 1;
+
+ private static final int E = 2;
+
+ private static final int T = 3;
+
+ private static final int A = 4;
+
+ private static final int DATA = 0;
+
+ private static final int TAG_OPEN = 1;
+
+ private static final int SCAN_UNTIL_GT = 2;
+
+ private static final int TAG_NAME = 3;
+
+ private static final int BEFORE_ATTRIBUTE_NAME = 4;
+
+ private static final int ATTRIBUTE_NAME = 5;
+
+ private static final int AFTER_ATTRIBUTE_NAME = 6;
+
+ private static final int BEFORE_ATTRIBUTE_VALUE = 7;
+
+ private static final int ATTRIBUTE_VALUE_DOUBLE_QUOTED = 8;
+
+ private static final int ATTRIBUTE_VALUE_SINGLE_QUOTED = 9;
+
+ private static final int ATTRIBUTE_VALUE_UNQUOTED = 10;
+
+ private static final int AFTER_ATTRIBUTE_VALUE_QUOTED = 11;
+
+ private static final int MARKUP_DECLARATION_OPEN = 13;
+
+ private static final int MARKUP_DECLARATION_HYPHEN = 14;
+
+ private static final int COMMENT_START = 15;
+
+ private static final int COMMENT_START_DASH = 16;
+
+ private static final int COMMENT = 17;
+
+ private static final int COMMENT_END_DASH = 18;
+
+ private static final int COMMENT_END = 19;
+
+ private static final int SELF_CLOSING_START_TAG = 20;
+
+ private static final int HTTP_EQUIV_NOT_SEEN = 0;
+
+ private static final int HTTP_EQUIV_CONTENT_TYPE = 1;
+
+ private static final int HTTP_EQUIV_OTHER = 2;
+
+ /**
+ * The data source.
+ */
+ protected ByteReadable readable;
+
+ /**
+ * The state of the state machine that recognizes the tag name "meta".
+ */
+ private int metaState = NO;
+
+ /**
+ * The current position in recognizing the attribute name "content".
+ */
+ private int contentIndex = Integer.MAX_VALUE;
+
+ /**
+ * The current position in recognizing the attribute name "charset".
+ */
+ private int charsetIndex = Integer.MAX_VALUE;
+
+ /**
+ * The current position in recognizing the attribute name "http-equive".
+ */
+ private int httpEquivIndex = Integer.MAX_VALUE;
+
+ /**
+ * The current position in recognizing the attribute value "content-type".
+ */
+ private int contentTypeIndex = Integer.MAX_VALUE;
+
+ /**
+ * The tokenizer state.
+ */
+ protected int stateSave = DATA;
+
+ /**
+ * The currently filled length of strBuf.
+ */
+ private int strBufLen;
+
+ /**
+ * Accumulation buffer for attribute values.
+ */
+ private @Auto char[] strBuf;
+
+ private String content;
+
+ private String charset;
+
+ private int httpEquivState;
+
+ // CPPONLY: private TreeBuilder treeBuilder;
+
+ public MetaScanner(
+ // CPPONLY: TreeBuilder tb
+ ) {
+ this.readable = null;
+ this.metaState = NO;
+ this.contentIndex = Integer.MAX_VALUE;
+ this.charsetIndex = Integer.MAX_VALUE;
+ this.httpEquivIndex = Integer.MAX_VALUE;
+ this.contentTypeIndex = Integer.MAX_VALUE;
+ this.stateSave = DATA;
+ this.strBufLen = 0;
+ this.strBuf = new char[36];
+ this.content = null;
+ this.charset = null;
+ this.httpEquivState = HTTP_EQUIV_NOT_SEEN;
+ // CPPONLY: this.treeBuilder = tb;
+ }
+
+ @SuppressWarnings("unused") private void destructor() {
+ Portability.releaseString(content);
+ Portability.releaseString(charset);
+ }
+
+ // [NOCPP[
+
+ /**
+ * Reads a byte from the data source.
+ *
+ * -1 means end.
+ * @return
+ * @throws IOException
+ */
+ protected int read() throws IOException {
+ return readable.readByte();
+ }
+
+ // ]NOCPP]
+
+ // WARNING When editing this, makes sure the bytecode length shown by javap
+ // stays under 8000 bytes!
+ /**
+ * The runs the meta scanning algorithm.
+ */
+ protected final void stateLoop(int state)
+ throws SAXException, IOException {
+ int c = -1;
+ boolean reconsume = false;
+ stateloop: for (;;) {
+ switch (state) {
+ case DATA:
+ dataloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ c = read();
+ }
+ switch (c) {
+ case -1:
+ break stateloop;
+ case '<':
+ state = MetaScanner.TAG_OPEN;
+ break dataloop; // FALL THROUGH continue
+ // stateloop;
+ default:
+ continue;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case TAG_OPEN:
+ tagopenloop: for (;;) {
+ c = read();
+ switch (c) {
+ case -1:
+ break stateloop;
+ case 'm':
+ case 'M':
+ metaState = M;
+ state = MetaScanner.TAG_NAME;
+ break tagopenloop;
+ // continue stateloop;
+ case '!':
+ state = MetaScanner.MARKUP_DECLARATION_OPEN;
+ continue stateloop;
+ case '?':
+ case '/':
+ state = MetaScanner.SCAN_UNTIL_GT;
+ continue stateloop;
+ case '>':
+ state = MetaScanner.DATA;
+ continue stateloop;
+ default:
+ if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
+ metaState = NO;
+ state = MetaScanner.TAG_NAME;
+ break tagopenloop;
+ // continue stateloop;
+ }
+ state = MetaScanner.DATA;
+ reconsume = true;
+ continue stateloop;
+ }
+ }
+ // FALL THROUGH DON'T REORDER
+ case TAG_NAME:
+ tagnameloop: for (;;) {
+ c = read();
+ switch (c) {
+ case -1:
+ break stateloop;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\u000C':
+ state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
+ break tagnameloop;
+ // continue stateloop;
+ case '/':
+ state = MetaScanner.SELF_CLOSING_START_TAG;
+ continue stateloop;
+ case '>':
+ state = MetaScanner.DATA;
+ continue stateloop;
+ case 'e':
+ case 'E':
+ if (metaState == M) {
+ metaState = E;
+ } else {
+ metaState = NO;
+ }
+ continue;
+ case 't':
+ case 'T':
+ if (metaState == E) {
+ metaState = T;
+ } else {
+ metaState = NO;
+ }
+ continue;
+ case 'a':
+ case 'A':
+ if (metaState == T) {
+ metaState = A;
+ } else {
+ metaState = NO;
+ }
+ continue;
+ default:
+ metaState = NO;
+ continue;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case BEFORE_ATTRIBUTE_NAME:
+ beforeattributenameloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ c = read();
+ }
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case -1:
+ break stateloop;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\u000C':
+ continue;
+ case '/':
+ state = MetaScanner.SELF_CLOSING_START_TAG;
+ continue stateloop;
+ case '>':
+ if (handleTag()) {
+ break stateloop;
+ }
+ state = DATA;
+ continue stateloop;
+ case 'c':
+ case 'C':
+ contentIndex = 0;
+ charsetIndex = 0;
+ httpEquivIndex = Integer.MAX_VALUE;
+ contentTypeIndex = Integer.MAX_VALUE;
+ state = MetaScanner.ATTRIBUTE_NAME;
+ break beforeattributenameloop;
+ case 'h':
+ case 'H':
+ contentIndex = Integer.MAX_VALUE;
+ charsetIndex = Integer.MAX_VALUE;
+ httpEquivIndex = 0;
+ contentTypeIndex = Integer.MAX_VALUE;
+ state = MetaScanner.ATTRIBUTE_NAME;
+ break beforeattributenameloop;
+ default:
+ contentIndex = Integer.MAX_VALUE;
+ charsetIndex = Integer.MAX_VALUE;
+ httpEquivIndex = Integer.MAX_VALUE;
+ contentTypeIndex = Integer.MAX_VALUE;
+ state = MetaScanner.ATTRIBUTE_NAME;
+ break beforeattributenameloop;
+ // continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case ATTRIBUTE_NAME:
+ attributenameloop: for (;;) {
+ c = read();
+ switch (c) {
+ case -1:
+ break stateloop;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\u000C':
+ state = MetaScanner.AFTER_ATTRIBUTE_NAME;
+ continue stateloop;
+ case '/':
+ state = MetaScanner.SELF_CLOSING_START_TAG;
+ continue stateloop;
+ case '=':
+ strBufLen = 0;
+ contentTypeIndex = 0;
+ state = MetaScanner.BEFORE_ATTRIBUTE_VALUE;
+ break attributenameloop;
+ // continue stateloop;
+ case '>':
+ if (handleTag()) {
+ break stateloop;
+ }
+ state = MetaScanner.DATA;
+ continue stateloop;
+ default:
+ if (metaState == A) {
+ if (c >= 'A' && c <= 'Z') {
+ c += 0x20;
+ }
+ if (contentIndex < CONTENT.length && c == CONTENT[contentIndex]) {
+ ++contentIndex;
+ } else {
+ contentIndex = Integer.MAX_VALUE;
+ }
+ if (charsetIndex < CHARSET.length && c == CHARSET[charsetIndex]) {
+ ++charsetIndex;
+ } else {
+ charsetIndex = Integer.MAX_VALUE;
+ }
+ if (httpEquivIndex < HTTP_EQUIV.length && c == HTTP_EQUIV[httpEquivIndex]) {
+ ++httpEquivIndex;
+ } else {
+ httpEquivIndex = Integer.MAX_VALUE;
+ }
+ }
+ continue;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case BEFORE_ATTRIBUTE_VALUE:
+ beforeattributevalueloop: for (;;) {
+ c = read();
+ switch (c) {
+ case -1:
+ break stateloop;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\u000C':
+ continue;
+ case '"':
+ state = MetaScanner.ATTRIBUTE_VALUE_DOUBLE_QUOTED;
+ break beforeattributevalueloop;
+ // continue stateloop;
+ case '\'':
+ state = MetaScanner.ATTRIBUTE_VALUE_SINGLE_QUOTED;
+ continue stateloop;
+ case '>':
+ if (handleTag()) {
+ break stateloop;
+ }
+ state = MetaScanner.DATA;
+ continue stateloop;
+ default:
+ handleCharInAttributeValue(c);
+ state = MetaScanner.ATTRIBUTE_VALUE_UNQUOTED;
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
+ attributevaluedoublequotedloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ c = read();
+ }
+ switch (c) {
+ case -1:
+ break stateloop;
+ case '"':
+ handleAttributeValue();
+ state = MetaScanner.AFTER_ATTRIBUTE_VALUE_QUOTED;
+ break attributevaluedoublequotedloop;
+ // continue stateloop;
+ default:
+ handleCharInAttributeValue(c);
+ continue;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case AFTER_ATTRIBUTE_VALUE_QUOTED:
+ afterattributevaluequotedloop: for (;;) {
+ c = read();
+ switch (c) {
+ case -1:
+ break stateloop;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\u000C':
+ state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
+ continue stateloop;
+ case '/':
+ state = MetaScanner.SELF_CLOSING_START_TAG;
+ break afterattributevaluequotedloop;
+ // continue stateloop;
+ case '>':
+ if (handleTag()) {
+ break stateloop;
+ }
+ state = MetaScanner.DATA;
+ continue stateloop;
+ default:
+ state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
+ reconsume = true;
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case SELF_CLOSING_START_TAG:
+ c = read();
+ switch (c) {
+ case -1:
+ break stateloop;
+ case '>':
+ if (handleTag()) {
+ break stateloop;
+ }
+ state = MetaScanner.DATA;
+ continue stateloop;
+ default:
+ state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
+ reconsume = true;
+ continue stateloop;
+ }
+ // XXX reorder point
+ case ATTRIBUTE_VALUE_UNQUOTED:
+ for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ c = read();
+ }
+ switch (c) {
+ case -1:
+ break stateloop;
+ case ' ':
+ case '\t':
+ case '\n':
+
+ case '\u000C':
+ handleAttributeValue();
+ state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
+ continue stateloop;
+ case '>':
+ handleAttributeValue();
+ if (handleTag()) {
+ break stateloop;
+ }
+ state = MetaScanner.DATA;
+ continue stateloop;
+ default:
+ handleCharInAttributeValue(c);
+ continue;
+ }
+ }
+ // XXX reorder point
+ case AFTER_ATTRIBUTE_NAME:
+ for (;;) {
+ c = read();
+ switch (c) {
+ case -1:
+ break stateloop;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\u000C':
+ continue;
+ case '/':
+ handleAttributeValue();
+ state = MetaScanner.SELF_CLOSING_START_TAG;
+ continue stateloop;
+ case '=':
+ strBufLen = 0;
+ contentTypeIndex = 0;
+ state = MetaScanner.BEFORE_ATTRIBUTE_VALUE;
+ continue stateloop;
+ case '>':
+ handleAttributeValue();
+ if (handleTag()) {
+ break stateloop;
+ }
+ state = MetaScanner.DATA;
+ continue stateloop;
+ case 'c':
+ case 'C':
+ contentIndex = 0;
+ charsetIndex = 0;
+ state = MetaScanner.ATTRIBUTE_NAME;
+ continue stateloop;
+ default:
+ contentIndex = Integer.MAX_VALUE;
+ charsetIndex = Integer.MAX_VALUE;
+ state = MetaScanner.ATTRIBUTE_NAME;
+ continue stateloop;
+ }
+ }
+ // XXX reorder point
+ case MARKUP_DECLARATION_OPEN:
+ markupdeclarationopenloop: for (;;) {
+ c = read();
+ switch (c) {
+ case -1:
+ break stateloop;
+ case '-':
+ state = MetaScanner.MARKUP_DECLARATION_HYPHEN;
+ break markupdeclarationopenloop;
+ // continue stateloop;
+ default:
+ state = MetaScanner.SCAN_UNTIL_GT;
+ reconsume = true;
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case MARKUP_DECLARATION_HYPHEN:
+ markupdeclarationhyphenloop: for (;;) {
+ c = read();
+ switch (c) {
+ case -1:
+ break stateloop;
+ case '-':
+ state = MetaScanner.COMMENT_START;
+ break markupdeclarationhyphenloop;
+ // continue stateloop;
+ default:
+ state = MetaScanner.SCAN_UNTIL_GT;
+ reconsume = true;
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case COMMENT_START:
+ commentstartloop: for (;;) {
+ c = read();
+ switch (c) {
+ case -1:
+ break stateloop;
+ case '-':
+ state = MetaScanner.COMMENT_START_DASH;
+ continue stateloop;
+ case '>':
+ state = MetaScanner.DATA;
+ continue stateloop;
+ default:
+ state = MetaScanner.COMMENT;
+ break commentstartloop;
+ // continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case COMMENT:
+ commentloop: for (;;) {
+ c = read();
+ switch (c) {
+ case -1:
+ break stateloop;
+ case '-':
+ state = MetaScanner.COMMENT_END_DASH;
+ break commentloop;
+ // continue stateloop;
+ default:
+ continue;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case COMMENT_END_DASH:
+ commentenddashloop: for (;;) {
+ c = read();
+ switch (c) {
+ case -1:
+ break stateloop;
+ case '-':
+ state = MetaScanner.COMMENT_END;
+ break commentenddashloop;
+ // continue stateloop;
+ default:
+ state = MetaScanner.COMMENT;
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case COMMENT_END:
+ for (;;) {
+ c = read();
+ switch (c) {
+ case -1:
+ break stateloop;
+ case '>':
+ state = MetaScanner.DATA;
+ continue stateloop;
+ case '-':
+ continue;
+ default:
+ state = MetaScanner.COMMENT;
+ continue stateloop;
+ }
+ }
+ // XXX reorder point
+ case COMMENT_START_DASH:
+ c = read();
+ switch (c) {
+ case -1:
+ break stateloop;
+ case '-':
+ state = MetaScanner.COMMENT_END;
+ continue stateloop;
+ case '>':
+ state = MetaScanner.DATA;
+ continue stateloop;
+ default:
+ state = MetaScanner.COMMENT;
+ continue stateloop;
+ }
+ // XXX reorder point
+ case ATTRIBUTE_VALUE_SINGLE_QUOTED:
+ for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ c = read();
+ }
+ switch (c) {
+ case -1:
+ break stateloop;
+ case '\'':
+ handleAttributeValue();
+ state = MetaScanner.AFTER_ATTRIBUTE_VALUE_QUOTED;
+ continue stateloop;
+ default:
+ handleCharInAttributeValue(c);
+ continue;
+ }
+ }
+ // XXX reorder point
+ case SCAN_UNTIL_GT:
+ for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ c = read();
+ }
+ switch (c) {
+ case -1:
+ break stateloop;
+ case '>':
+ state = MetaScanner.DATA;
+ continue stateloop;
+ default:
+ continue;
+ }
+ }
+ }
+ }
+ stateSave = state;
+ }
+
+ private void handleCharInAttributeValue(int c) {
+ if (metaState == A) {
+ if (contentIndex == CONTENT.length || charsetIndex == CHARSET.length) {
+ addToBuffer(c);
+ } else if (httpEquivIndex == HTTP_EQUIV.length) {
+ if (contentTypeIndex < CONTENT_TYPE.length && toAsciiLowerCase(c) == CONTENT_TYPE[contentTypeIndex]) {
+ ++contentTypeIndex;
+ } else {
+ contentTypeIndex = Integer.MAX_VALUE;
+ }
+ }
+ }
+ }
+
+ @Inline private int toAsciiLowerCase(int c) {
+ if (c >= 'A' && c <= 'Z') {
+ return c + 0x20;
+ }
+ return c;
+ }
+
+ /**
+ * Adds a character to the accumulation buffer.
+ * @param c the character to add
+ */
+ private void addToBuffer(int c) {
+ if (strBufLen == strBuf.length) {
+ char[] newBuf = new char[strBuf.length + (strBuf.length << 1)];
+ System.arraycopy(strBuf, 0, newBuf, 0, strBuf.length);
+ strBuf = newBuf;
+ }
+ strBuf[strBufLen++] = (char)c;
+ }
+
+ /**
+ * Attempts to extract a charset name from the accumulation buffer.
+ * @return <code>true</code> if successful
+ * @throws SAXException
+ */
+ private void handleAttributeValue() throws SAXException {
+ if (metaState != A) {
+ return;
+ }
+ if (contentIndex == CONTENT.length && content == null) {
+ content = Portability.newStringFromBuffer(strBuf, 0, strBufLen
+ // CPPONLY: , treeBuilder
+ );
+ return;
+ }
+ if (charsetIndex == CHARSET.length && charset == null) {
+ charset = Portability.newStringFromBuffer(strBuf, 0, strBufLen
+ // CPPONLY: , treeBuilder
+ );
+ return;
+ }
+ if (httpEquivIndex == HTTP_EQUIV.length
+ && httpEquivState == HTTP_EQUIV_NOT_SEEN) {
+ httpEquivState = (contentTypeIndex == CONTENT_TYPE.length) ? HTTP_EQUIV_CONTENT_TYPE
+ : HTTP_EQUIV_OTHER;
+ return;
+ }
+ }
+
+ private boolean handleTag() throws SAXException {
+ boolean stop = handleTagInner();
+ Portability.releaseString(content);
+ content = null;
+ Portability.releaseString(charset);
+ charset = null;
+ httpEquivState = HTTP_EQUIV_NOT_SEEN;
+ return stop;
+ }
+
+ private boolean handleTagInner() throws SAXException {
+ if (charset != null && tryCharset(charset)) {
+ return true;
+ }
+ if (content != null && httpEquivState == HTTP_EQUIV_CONTENT_TYPE) {
+ String extract = TreeBuilder.extractCharsetFromContent(content
+ // CPPONLY: , treeBuilder
+ );
+ if (extract == null) {
+ return false;
+ }
+ boolean success = tryCharset(extract);
+ Portability.releaseString(extract);
+ return success;
+ }
+ return false;
+ }
+
+ /**
+ * Tries to switch to an encoding.
+ *
+ * @param encoding
+ * @return <code>true</code> if successful
+ * @throws SAXException
+ */
+ protected abstract boolean tryCharset(String encoding) throws SAXException;
+
+}
diff --git a/parser/html/javasrc/Portability.java b/parser/html/javasrc/Portability.java
new file mode 100644
index 000000000..485684ea1
--- /dev/null
+++ b/parser/html/javasrc/Portability.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2008-2015 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package nu.validator.htmlparser.impl;
+
+import nu.validator.htmlparser.annotation.Literal;
+import nu.validator.htmlparser.annotation.Local;
+import nu.validator.htmlparser.annotation.NoLength;
+import nu.validator.htmlparser.common.Interner;
+
+public final class Portability {
+
+ // Allocating methods
+
+ /**
+ * Allocates a new local name object. In C++, the refcount must be set up in such a way that
+ * calling <code>releaseLocal</code> on the return value balances the refcount set by this method.
+ */
+ public static @Local String newLocalNameFromBuffer(@NoLength char[] buf, int offset, int length, Interner interner) {
+ return new String(buf, offset, length).intern();
+ }
+
+ public static String newStringFromBuffer(@NoLength char[] buf, int offset, int length
+ // CPPONLY: , TreeBuilder treeBuilder
+ ) {
+ return new String(buf, offset, length);
+ }
+
+ public static String newEmptyString() {
+ return "";
+ }
+
+ public static String newStringFromLiteral(@Literal String literal) {
+ return literal;
+ }
+
+ public static String newStringFromString(String string) {
+ return string;
+ }
+
+ // XXX get rid of this
+ public static char[] newCharArrayFromLocal(@Local String local) {
+ return local.toCharArray();
+ }
+
+ public static char[] newCharArrayFromString(String string) {
+ return string.toCharArray();
+ }
+
+ public static @Local String newLocalFromLocal(@Local String local, Interner interner) {
+ return local;
+ }
+
+ // Deallocation methods
+
+ public static void releaseString(String str) {
+ // No-op in Java
+ }
+
+ // Comparison methods
+
+ public static boolean localEqualsBuffer(@Local String local, @NoLength char[] buf, int offset, int length) {
+ if (local.length() != length) {
+ return false;
+ }
+ for (int i = 0; i < length; i++) {
+ if (local.charAt(i) != buf[offset + i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(@Literal String lowerCaseLiteral,
+ String string) {
+ if (string == null) {
+ return false;
+ }
+ if (lowerCaseLiteral.length() > string.length()) {
+ return false;
+ }
+ for (int i = 0; i < lowerCaseLiteral.length(); i++) {
+ char c0 = lowerCaseLiteral.charAt(i);
+ char c1 = string.charAt(i);
+ if (c1 >= 'A' && c1 <= 'Z') {
+ c1 += 0x20;
+ }
+ if (c0 != c1) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean lowerCaseLiteralEqualsIgnoreAsciiCaseString(@Literal String lowerCaseLiteral,
+ String string) {
+ if (string == null) {
+ return false;
+ }
+ if (lowerCaseLiteral.length() != string.length()) {
+ return false;
+ }
+ for (int i = 0; i < lowerCaseLiteral.length(); i++) {
+ char c0 = lowerCaseLiteral.charAt(i);
+ char c1 = string.charAt(i);
+ if (c1 >= 'A' && c1 <= 'Z') {
+ c1 += 0x20;
+ }
+ if (c0 != c1) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean literalEqualsString(@Literal String literal, String string) {
+ return literal.equals(string);
+ }
+
+ public static boolean stringEqualsString(String one, String other) {
+ return one.equals(other);
+ }
+
+ public static void delete(Object o) {
+
+ }
+
+ public static void deleteArray(Object o) {
+
+ }
+}
diff --git a/parser/html/javasrc/README.txt b/parser/html/javasrc/README.txt
new file mode 100644
index 000000000..4555969ca
--- /dev/null
+++ b/parser/html/javasrc/README.txt
@@ -0,0 +1,6 @@
+The .java files in this directory were placed here by the Java-to-C++
+translator that lives in parser/html/java/translator. Together they represent
+a snapshot of the Java code that was translated to produce the corresponding
+.h and .cpp files in the parent directory. Changing these .java files is not
+worthwhile, as they will just be overwritten by the next translation. See
+parser/html/java/README.txt for information about performing the translation.
diff --git a/parser/html/javasrc/StackNode.java b/parser/html/javasrc/StackNode.java
new file mode 100644
index 000000000..9aeaba0be
--- /dev/null
+++ b/parser/html/javasrc/StackNode.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 2007-2011 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package nu.validator.htmlparser.impl;
+
+import nu.validator.htmlparser.annotation.Inline;
+import nu.validator.htmlparser.annotation.Local;
+import nu.validator.htmlparser.annotation.NsUri;
+
+final class StackNode<T> {
+ final int flags;
+
+ final @Local String name;
+
+ final @Local String popName;
+
+ final @NsUri String ns;
+
+ final T node;
+
+ // Only used on the list of formatting elements
+ HtmlAttributes attributes;
+
+ private int refcount = 1;
+
+ // [NOCPP[
+
+ private final TaintableLocatorImpl locator;
+
+ public TaintableLocatorImpl getLocator() {
+ return locator;
+ }
+
+ // ]NOCPP]
+
+ @Inline public int getFlags() {
+ return flags;
+ }
+
+ public int getGroup() {
+ return flags & ElementName.GROUP_MASK;
+ }
+
+ public boolean isScoping() {
+ return (flags & ElementName.SCOPING) != 0;
+ }
+
+ public boolean isSpecial() {
+ return (flags & ElementName.SPECIAL) != 0;
+ }
+
+ public boolean isFosterParenting() {
+ return (flags & ElementName.FOSTER_PARENTING) != 0;
+ }
+
+ public boolean isHtmlIntegrationPoint() {
+ return (flags & ElementName.HTML_INTEGRATION_POINT) != 0;
+ }
+
+ // [NOCPP[
+
+ public boolean isOptionalEndTag() {
+ return (flags & ElementName.OPTIONAL_END_TAG) != 0;
+ }
+
+ // ]NOCPP]
+
+ /**
+ * Constructor for copying. This doesn't take another <code>StackNode</code>
+ * because in C++ the caller is reponsible for reobtaining the local names
+ * from another interner.
+ *
+ * @param flags
+ * @param ns
+ * @param name
+ * @param node
+ * @param popName
+ * @param attributes
+ */
+ StackNode(int flags, @NsUri String ns, @Local String name, T node,
+ @Local String popName, HtmlAttributes attributes
+ // [NOCPP[
+ , TaintableLocatorImpl locator
+ // ]NOCPP]
+ ) {
+ this.flags = flags;
+ this.name = name;
+ this.popName = popName;
+ this.ns = ns;
+ this.node = node;
+ this.attributes = attributes;
+ this.refcount = 1;
+ // [NOCPP[
+ this.locator = locator;
+ // ]NOCPP]
+ }
+
+ /**
+ * Short hand for well-known HTML elements.
+ *
+ * @param elementName
+ * @param node
+ */
+ StackNode(ElementName elementName, T node
+ // [NOCPP[
+ , TaintableLocatorImpl locator
+ // ]NOCPP]
+ ) {
+ this.flags = elementName.getFlags();
+ this.name = elementName.name;
+ this.popName = elementName.name;
+ this.ns = "http://www.w3.org/1999/xhtml";
+ this.node = node;
+ this.attributes = null;
+ this.refcount = 1;
+ assert !elementName.isCustom() : "Don't use this constructor for custom elements.";
+ // [NOCPP[
+ this.locator = locator;
+ // ]NOCPP]
+ }
+
+ /**
+ * Constructor for HTML formatting elements.
+ *
+ * @param elementName
+ * @param node
+ * @param attributes
+ */
+ StackNode(ElementName elementName, T node, HtmlAttributes attributes
+ // [NOCPP[
+ , TaintableLocatorImpl locator
+ // ]NOCPP]
+ ) {
+ this.flags = elementName.getFlags();
+ this.name = elementName.name;
+ this.popName = elementName.name;
+ this.ns = "http://www.w3.org/1999/xhtml";
+ this.node = node;
+ this.attributes = attributes;
+ this.refcount = 1;
+ assert !elementName.isCustom() : "Don't use this constructor for custom elements.";
+ // [NOCPP[
+ this.locator = locator;
+ // ]NOCPP]
+ }
+
+ /**
+ * The common-case HTML constructor.
+ *
+ * @param elementName
+ * @param node
+ * @param popName
+ */
+ StackNode(ElementName elementName, T node, @Local String popName
+ // [NOCPP[
+ , TaintableLocatorImpl locator
+ // ]NOCPP]
+ ) {
+ this.flags = elementName.getFlags();
+ this.name = elementName.name;
+ this.popName = popName;
+ this.ns = "http://www.w3.org/1999/xhtml";
+ this.node = node;
+ this.attributes = null;
+ this.refcount = 1;
+ // [NOCPP[
+ this.locator = locator;
+ // ]NOCPP]
+ }
+
+ /**
+ * Constructor for SVG elements. Note that the order of the arguments is
+ * what distinguishes this from the HTML constructor. This is ugly, but
+ * AFAICT the least disruptive way to make this work with Java's generics
+ * and without unnecessary branches. :-(
+ *
+ * @param elementName
+ * @param popName
+ * @param node
+ */
+ StackNode(ElementName elementName, @Local String popName, T node
+ // [NOCPP[
+ , TaintableLocatorImpl locator
+ // ]NOCPP]
+ ) {
+ this.flags = prepareSvgFlags(elementName.getFlags());
+ this.name = elementName.name;
+ this.popName = popName;
+ this.ns = "http://www.w3.org/2000/svg";
+ this.node = node;
+ this.attributes = null;
+ this.refcount = 1;
+ // [NOCPP[
+ this.locator = locator;
+ // ]NOCPP]
+ }
+
+ /**
+ * Constructor for MathML.
+ *
+ * @param elementName
+ * @param node
+ * @param popName
+ * @param markAsIntegrationPoint
+ */
+ StackNode(ElementName elementName, T node, @Local String popName,
+ boolean markAsIntegrationPoint
+ // [NOCPP[
+ , TaintableLocatorImpl locator
+ // ]NOCPP]
+ ) {
+ this.flags = prepareMathFlags(elementName.getFlags(),
+ markAsIntegrationPoint);
+ this.name = elementName.name;
+ this.popName = popName;
+ this.ns = "http://www.w3.org/1998/Math/MathML";
+ this.node = node;
+ this.attributes = null;
+ this.refcount = 1;
+ // [NOCPP[
+ this.locator = locator;
+ // ]NOCPP]
+ }
+
+ private static int prepareSvgFlags(int flags) {
+ flags &= ~(ElementName.FOSTER_PARENTING | ElementName.SCOPING
+ | ElementName.SPECIAL | ElementName.OPTIONAL_END_TAG);
+ if ((flags & ElementName.SCOPING_AS_SVG) != 0) {
+ flags |= (ElementName.SCOPING | ElementName.SPECIAL | ElementName.HTML_INTEGRATION_POINT);
+ }
+ return flags;
+ }
+
+ private static int prepareMathFlags(int flags,
+ boolean markAsIntegrationPoint) {
+ flags &= ~(ElementName.FOSTER_PARENTING | ElementName.SCOPING
+ | ElementName.SPECIAL | ElementName.OPTIONAL_END_TAG);
+ if ((flags & ElementName.SCOPING_AS_MATHML) != 0) {
+ flags |= (ElementName.SCOPING | ElementName.SPECIAL);
+ }
+ if (markAsIntegrationPoint) {
+ flags |= ElementName.HTML_INTEGRATION_POINT;
+ }
+ return flags;
+ }
+
+ @SuppressWarnings("unused") private void destructor() {
+ Portability.delete(attributes);
+ }
+
+ public void dropAttributes() {
+ attributes = null;
+ }
+
+ // [NOCPP[
+ /**
+ * @see java.lang.Object#toString()
+ */
+ @Override public @Local String toString() {
+ return name;
+ }
+
+ // ]NOCPP]
+
+ public void retain() {
+ refcount++;
+ }
+
+ public void release() {
+ refcount--;
+ if (refcount == 0) {
+ Portability.delete(this);
+ }
+ }
+}
diff --git a/parser/html/javasrc/StateSnapshot.java b/parser/html/javasrc/StateSnapshot.java
new file mode 100644
index 000000000..ff89e0443
--- /dev/null
+++ b/parser/html/javasrc/StateSnapshot.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2009-2010 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package nu.validator.htmlparser.impl;
+
+import nu.validator.htmlparser.annotation.Auto;
+
+
+public class StateSnapshot<T> implements TreeBuilderState<T> {
+
+ private final @Auto StackNode<T>[] stack;
+
+ private final @Auto StackNode<T>[] listOfActiveFormattingElements;
+
+ private final @Auto int[] templateModeStack;
+
+ private final T formPointer;
+
+ private final T headPointer;
+
+ private final T deepTreeSurrogateParent;
+
+ private final int mode;
+
+ private final int originalMode;
+
+ private final boolean framesetOk;
+
+ private final boolean needToDropLF;
+
+ private final boolean quirks;
+
+ /**
+ * @param stack
+ * @param listOfActiveFormattingElements
+ * @param templateModeStack
+ * @param formPointer
+ * @param headPointer
+ * @param deepTreeSurrogateParent
+ * @param mode
+ * @param originalMode
+ * @param framesetOk
+ * @param needToDropLF
+ * @param quirks
+ */
+ StateSnapshot(StackNode<T>[] stack,
+ StackNode<T>[] listOfActiveFormattingElements, int[] templateModeStack, T formPointer,
+ T headPointer, T deepTreeSurrogateParent, int mode, int originalMode,
+ boolean framesetOk, boolean needToDropLF, boolean quirks) {
+ this.stack = stack;
+ this.listOfActiveFormattingElements = listOfActiveFormattingElements;
+ this.templateModeStack = templateModeStack;
+ this.formPointer = formPointer;
+ this.headPointer = headPointer;
+ this.deepTreeSurrogateParent = deepTreeSurrogateParent;
+ this.mode = mode;
+ this.originalMode = originalMode;
+ this.framesetOk = framesetOk;
+ this.needToDropLF = needToDropLF;
+ this.quirks = quirks;
+ }
+
+ /**
+ * @see nu.validator.htmlparser.impl.TreeBuilderState#getStack()
+ */
+ public StackNode<T>[] getStack() {
+ return stack;
+ }
+
+ /**
+ * @see nu.validator.htmlparser.impl.TreeBuilderState#getTemplateModeStack()
+ */
+ public int[] getTemplateModeStack() {
+ return templateModeStack;
+ }
+
+ /**
+ * @see nu.validator.htmlparser.impl.TreeBuilderState#getListOfActiveFormattingElements()
+ */
+ public StackNode<T>[] getListOfActiveFormattingElements() {
+ return listOfActiveFormattingElements;
+ }
+
+ /**
+ * @see nu.validator.htmlparser.impl.TreeBuilderState#getFormPointer()
+ */
+ public T getFormPointer() {
+ return formPointer;
+ }
+
+ /**
+ * Returns the headPointer.
+ *
+ * @return the headPointer
+ */
+ public T getHeadPointer() {
+ return headPointer;
+ }
+
+ /**
+ * Returns the deepTreeSurrogateParent.
+ *
+ * @return the deepTreeSurrogateParent
+ */
+ public T getDeepTreeSurrogateParent() {
+ return deepTreeSurrogateParent;
+ }
+
+ /**
+ * Returns the mode.
+ *
+ * @return the mode
+ */
+ public int getMode() {
+ return mode;
+ }
+
+ /**
+ * Returns the originalMode.
+ *
+ * @return the originalMode
+ */
+ public int getOriginalMode() {
+ return originalMode;
+ }
+
+ /**
+ * Returns the framesetOk.
+ *
+ * @return the framesetOk
+ */
+ public boolean isFramesetOk() {
+ return framesetOk;
+ }
+
+ /**
+ * Returns the needToDropLF.
+ *
+ * @return the needToDropLF
+ */
+ public boolean isNeedToDropLF() {
+ return needToDropLF;
+ }
+
+ /**
+ * Returns the quirks.
+ *
+ * @return the quirks
+ */
+ public boolean isQuirks() {
+ return quirks;
+ }
+
+ /**
+ * @see nu.validator.htmlparser.impl.TreeBuilderState#getListOfActiveFormattingElementsLength()
+ */
+ public int getListOfActiveFormattingElementsLength() {
+ return listOfActiveFormattingElements.length;
+ }
+
+ /**
+ * @see nu.validator.htmlparser.impl.TreeBuilderState#getStackLength()
+ */
+ public int getStackLength() {
+ return stack.length;
+ }
+
+ /**
+ * @see nu.validator.htmlparser.impl.TreeBuilderState#getTemplateModeStackLength()
+ */
+ public int getTemplateModeStackLength() {
+ return templateModeStack.length;
+ }
+
+ @SuppressWarnings("unused") private void destructor() {
+ for (int i = 0; i < stack.length; i++) {
+ stack[i].release();
+ }
+ for (int i = 0; i < listOfActiveFormattingElements.length; i++) {
+ if (listOfActiveFormattingElements[i] != null) {
+ listOfActiveFormattingElements[i].release();
+ }
+ }
+ }
+}
diff --git a/parser/html/javasrc/Tokenizer.java b/parser/html/javasrc/Tokenizer.java
new file mode 100644
index 000000000..d9eaafeb3
--- /dev/null
+++ b/parser/html/javasrc/Tokenizer.java
@@ -0,0 +1,7067 @@
+/*
+ * Copyright (c) 2005-2007 Henri Sivonen
+ * Copyright (c) 2007-2015 Mozilla Foundation
+ * Portions of comments Copyright 2004-2010 Apple Computer, Inc., Mozilla
+ * Foundation, and Opera Software ASA.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * The comments following this one that use the same comment syntax as this
+ * comment are quotes from the WHATWG HTML 5 spec as of 2 June 2007
+ * amended as of June 18 2008 and May 31 2010.
+ * That document came with this statement:
+ * "© Copyright 2004-2010 Apple Computer, Inc., Mozilla Foundation, and
+ * Opera Software ASA. You are granted a license to use, reproduce and
+ * create derivative works of this document."
+ */
+
+package nu.validator.htmlparser.impl;
+
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import nu.validator.htmlparser.annotation.Auto;
+import nu.validator.htmlparser.annotation.CharacterName;
+import nu.validator.htmlparser.annotation.Const;
+import nu.validator.htmlparser.annotation.Inline;
+import nu.validator.htmlparser.annotation.Local;
+import nu.validator.htmlparser.annotation.NoLength;
+import nu.validator.htmlparser.common.EncodingDeclarationHandler;
+import nu.validator.htmlparser.common.Interner;
+import nu.validator.htmlparser.common.TokenHandler;
+import nu.validator.htmlparser.common.XmlViolationPolicy;
+
+/**
+ * An implementation of
+ * https://html.spec.whatwg.org/multipage/syntax.html#tokenization
+ *
+ * This class implements the <code>Locator</code> interface. This is not an
+ * incidental implementation detail: Users of this class are encouraged to make
+ * use of the <code>Locator</code> nature.
+ *
+ * By default, the tokenizer may report data that XML 1.0 bans. The tokenizer
+ * can be configured to treat these conditions as fatal or to coerce the infoset
+ * to something that XML 1.0 allows.
+ *
+ * @version $Id$
+ * @author hsivonen
+ */
+public class Tokenizer implements Locator {
+
+ private static final int DATA_AND_RCDATA_MASK = ~1;
+
+ public static final int DATA = 0;
+
+ public static final int RCDATA = 1;
+
+ public static final int SCRIPT_DATA = 2;
+
+ public static final int RAWTEXT = 3;
+
+ public static final int SCRIPT_DATA_ESCAPED = 4;
+
+ public static final int ATTRIBUTE_VALUE_DOUBLE_QUOTED = 5;
+
+ public static final int ATTRIBUTE_VALUE_SINGLE_QUOTED = 6;
+
+ public static final int ATTRIBUTE_VALUE_UNQUOTED = 7;
+
+ public static final int PLAINTEXT = 8;
+
+ public static final int TAG_OPEN = 9;
+
+ public static final int CLOSE_TAG_OPEN = 10;
+
+ public static final int TAG_NAME = 11;
+
+ public static final int BEFORE_ATTRIBUTE_NAME = 12;
+
+ public static final int ATTRIBUTE_NAME = 13;
+
+ public static final int AFTER_ATTRIBUTE_NAME = 14;
+
+ public static final int BEFORE_ATTRIBUTE_VALUE = 15;
+
+ public static final int AFTER_ATTRIBUTE_VALUE_QUOTED = 16;
+
+ public static final int BOGUS_COMMENT = 17;
+
+ public static final int MARKUP_DECLARATION_OPEN = 18;
+
+ public static final int DOCTYPE = 19;
+
+ public static final int BEFORE_DOCTYPE_NAME = 20;
+
+ public static final int DOCTYPE_NAME = 21;
+
+ public static final int AFTER_DOCTYPE_NAME = 22;
+
+ public static final int BEFORE_DOCTYPE_PUBLIC_IDENTIFIER = 23;
+
+ public static final int DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED = 24;
+
+ public static final int DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED = 25;
+
+ public static final int AFTER_DOCTYPE_PUBLIC_IDENTIFIER = 26;
+
+ public static final int BEFORE_DOCTYPE_SYSTEM_IDENTIFIER = 27;
+
+ public static final int DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED = 28;
+
+ public static final int DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED = 29;
+
+ public static final int AFTER_DOCTYPE_SYSTEM_IDENTIFIER = 30;
+
+ public static final int BOGUS_DOCTYPE = 31;
+
+ public static final int COMMENT_START = 32;
+
+ public static final int COMMENT_START_DASH = 33;
+
+ public static final int COMMENT = 34;
+
+ public static final int COMMENT_END_DASH = 35;
+
+ public static final int COMMENT_END = 36;
+
+ public static final int COMMENT_END_BANG = 37;
+
+ public static final int NON_DATA_END_TAG_NAME = 38;
+
+ public static final int MARKUP_DECLARATION_HYPHEN = 39;
+
+ public static final int MARKUP_DECLARATION_OCTYPE = 40;
+
+ public static final int DOCTYPE_UBLIC = 41;
+
+ public static final int DOCTYPE_YSTEM = 42;
+
+ public static final int AFTER_DOCTYPE_PUBLIC_KEYWORD = 43;
+
+ public static final int BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS = 44;
+
+ public static final int AFTER_DOCTYPE_SYSTEM_KEYWORD = 45;
+
+ public static final int CONSUME_CHARACTER_REFERENCE = 46;
+
+ public static final int CONSUME_NCR = 47;
+
+ public static final int CHARACTER_REFERENCE_TAIL = 48;
+
+ public static final int HEX_NCR_LOOP = 49;
+
+ public static final int DECIMAL_NRC_LOOP = 50;
+
+ public static final int HANDLE_NCR_VALUE = 51;
+
+ public static final int HANDLE_NCR_VALUE_RECONSUME = 52;
+
+ public static final int CHARACTER_REFERENCE_HILO_LOOKUP = 53;
+
+ public static final int SELF_CLOSING_START_TAG = 54;
+
+ public static final int CDATA_START = 55;
+
+ public static final int CDATA_SECTION = 56;
+
+ public static final int CDATA_RSQB = 57;
+
+ public static final int CDATA_RSQB_RSQB = 58;
+
+ public static final int SCRIPT_DATA_LESS_THAN_SIGN = 59;
+
+ public static final int SCRIPT_DATA_ESCAPE_START = 60;
+
+ public static final int SCRIPT_DATA_ESCAPE_START_DASH = 61;
+
+ public static final int SCRIPT_DATA_ESCAPED_DASH = 62;
+
+ public static final int SCRIPT_DATA_ESCAPED_DASH_DASH = 63;
+
+ public static final int BOGUS_COMMENT_HYPHEN = 64;
+
+ public static final int RAWTEXT_RCDATA_LESS_THAN_SIGN = 65;
+
+ public static final int SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN = 66;
+
+ public static final int SCRIPT_DATA_DOUBLE_ESCAPE_START = 67;
+
+ public static final int SCRIPT_DATA_DOUBLE_ESCAPED = 68;
+
+ public static final int SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN = 69;
+
+ public static final int SCRIPT_DATA_DOUBLE_ESCAPED_DASH = 70;
+
+ public static final int SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH = 71;
+
+ public static final int SCRIPT_DATA_DOUBLE_ESCAPE_END = 72;
+
+ public static final int PROCESSING_INSTRUCTION = 73;
+
+ public static final int PROCESSING_INSTRUCTION_QUESTION_MARK = 74;
+
+ /**
+ * Magic value for UTF-16 operations.
+ */
+ private static final int LEAD_OFFSET = (0xD800 - (0x10000 >> 10));
+
+ /**
+ * UTF-16 code unit array containing less than and greater than for emitting
+ * those characters on certain parse errors.
+ */
+ private static final @NoLength char[] LT_GT = { '<', '>' };
+
+ /**
+ * UTF-16 code unit array containing less than and solidus for emitting
+ * those characters on certain parse errors.
+ */
+ private static final @NoLength char[] LT_SOLIDUS = { '<', '/' };
+
+ /**
+ * UTF-16 code unit array containing ]] for emitting those characters on
+ * state transitions.
+ */
+ private static final @NoLength char[] RSQB_RSQB = { ']', ']' };
+
+ /**
+ * Array version of U+FFFD.
+ */
+ private static final @NoLength char[] REPLACEMENT_CHARACTER = { '\uFFFD' };
+
+ // [NOCPP[
+
+ /**
+ * Array version of space.
+ */
+ private static final @NoLength char[] SPACE = { ' ' };
+
+ // ]NOCPP]
+
+ /**
+ * Array version of line feed.
+ */
+ private static final @NoLength char[] LF = { '\n' };
+
+ /**
+ * "CDATA[" as <code>char[]</code>
+ */
+ private static final @NoLength char[] CDATA_LSQB = { 'C', 'D', 'A', 'T',
+ 'A', '[' };
+
+ /**
+ * "octype" as <code>char[]</code>
+ */
+ private static final @NoLength char[] OCTYPE = { 'o', 'c', 't', 'y', 'p',
+ 'e' };
+
+ /**
+ * "ublic" as <code>char[]</code>
+ */
+ private static final @NoLength char[] UBLIC = { 'u', 'b', 'l', 'i', 'c' };
+
+ /**
+ * "ystem" as <code>char[]</code>
+ */
+ private static final @NoLength char[] YSTEM = { 'y', 's', 't', 'e', 'm' };
+
+ private static final char[] TITLE_ARR = { 't', 'i', 't', 'l', 'e' };
+
+ private static final char[] SCRIPT_ARR = { 's', 'c', 'r', 'i', 'p', 't' };
+
+ private static final char[] STYLE_ARR = { 's', 't', 'y', 'l', 'e' };
+
+ private static final char[] PLAINTEXT_ARR = { 'p', 'l', 'a', 'i', 'n', 't',
+ 'e', 'x', 't' };
+
+ private static final char[] XMP_ARR = { 'x', 'm', 'p' };
+
+ private static final char[] TEXTAREA_ARR = { 't', 'e', 'x', 't', 'a', 'r',
+ 'e', 'a' };
+
+ private static final char[] IFRAME_ARR = { 'i', 'f', 'r', 'a', 'm', 'e' };
+
+ private static final char[] NOEMBED_ARR = { 'n', 'o', 'e', 'm', 'b', 'e',
+ 'd' };
+
+ private static final char[] NOSCRIPT_ARR = { 'n', 'o', 's', 'c', 'r', 'i',
+ 'p', 't' };
+
+ private static final char[] NOFRAMES_ARR = { 'n', 'o', 'f', 'r', 'a', 'm',
+ 'e', 's' };
+
+ /**
+ * The token handler.
+ */
+ protected final TokenHandler tokenHandler;
+
+ protected EncodingDeclarationHandler encodingDeclarationHandler;
+
+ // [NOCPP[
+
+ /**
+ * The error handler.
+ */
+ protected ErrorHandler errorHandler;
+
+ // ]NOCPP]
+
+ /**
+ * Whether the previous char read was CR.
+ */
+ protected boolean lastCR;
+
+ protected int stateSave;
+
+ private int returnStateSave;
+
+ protected int index;
+
+ private boolean forceQuirks;
+
+ private char additional;
+
+ private int entCol;
+
+ private int firstCharKey;
+
+ private int lo;
+
+ private int hi;
+
+ private int candidate;
+
+ private int charRefBufMark;
+
+ protected int value;
+
+ private boolean seenDigits;
+
+ protected int cstart;
+
+ /**
+ * The SAX public id for the resource being tokenized. (Only passed to back
+ * as part of locator data.)
+ */
+ private String publicId;
+
+ /**
+ * The SAX system id for the resource being tokenized. (Only passed to back
+ * as part of locator data.)
+ */
+ private String systemId;
+
+ /**
+ * Buffer for bufferable things other than those that fit the description
+ * of <code>charRefBuf</code>.
+ */
+ private @Auto char[] strBuf;
+
+ /**
+ * Number of significant <code>char</code>s in <code>strBuf</code>.
+ */
+ private int strBufLen;
+
+ /**
+ * Buffer for characters that might form a character reference but may
+ * end up not forming one.
+ */
+ private final @Auto char[] charRefBuf;
+
+ /**
+ * Number of significant <code>char</code>s in <code>charRefBuf</code>.
+ */
+ private int charRefBufLen;
+
+ /**
+ * Buffer for expanding NCRs falling into the Basic Multilingual Plane.
+ */
+ private final @Auto char[] bmpChar;
+
+ /**
+ * Buffer for expanding astral NCRs.
+ */
+ private final @Auto char[] astralChar;
+
+ /**
+ * The element whose end tag closes the current CDATA or RCDATA element.
+ */
+ protected ElementName endTagExpectation = null;
+
+ private char[] endTagExpectationAsArray; // not @Auto!
+
+ /**
+ * <code>true</code> if tokenizing an end tag
+ */
+ protected boolean endTag;
+
+ /**
+ * The current tag token name.
+ */
+ private ElementName tagName = null;
+
+ /**
+ * The current attribute name.
+ */
+ protected AttributeName attributeName = null;
+
+ // [NOCPP[
+
+ /**
+ * Whether comment tokens are emitted.
+ */
+ private boolean wantsComments = false;
+
+ /**
+ * <code>true</code> when HTML4-specific additional errors are requested.
+ */
+ protected boolean html4;
+
+ /**
+ * Whether the stream is past the first 1024 bytes.
+ */
+ private boolean metaBoundaryPassed;
+
+ // ]NOCPP]
+
+ /**
+ * The name of the current doctype token.
+ */
+ private @Local String doctypeName;
+
+ /**
+ * The public id of the current doctype token.
+ */
+ private String publicIdentifier;
+
+ /**
+ * The system id of the current doctype token.
+ */
+ private String systemIdentifier;
+
+ /**
+ * The attribute holder.
+ */
+ private HtmlAttributes attributes;
+
+ // [NOCPP[
+
+ /**
+ * The policy for vertical tab and form feed.
+ */
+ private XmlViolationPolicy contentSpacePolicy = XmlViolationPolicy.ALTER_INFOSET;
+
+ /**
+ * The policy for comments.
+ */
+ private XmlViolationPolicy commentPolicy = XmlViolationPolicy.ALTER_INFOSET;
+
+ private XmlViolationPolicy xmlnsPolicy = XmlViolationPolicy.ALTER_INFOSET;
+
+ private XmlViolationPolicy namePolicy = XmlViolationPolicy.ALTER_INFOSET;
+
+ private boolean html4ModeCompatibleWithXhtml1Schemata;
+
+ private int mappingLangToXmlLang;
+
+ // ]NOCPP]
+
+ private final boolean newAttributesEachTime;
+
+ private boolean shouldSuspend;
+
+ protected boolean confident;
+
+ private int line;
+
+ /*
+ * The line number of the current attribute. First set to the line of the
+ * attribute name and if there is a value, set to the line the value
+ * started on.
+ */
+ // CPPONLY: private int attributeLine;
+
+ private Interner interner;
+
+ // CPPONLY: private boolean viewingXmlSource;
+
+ // [NOCPP[
+
+ protected LocatorImpl ampersandLocation;
+
+ public Tokenizer(TokenHandler tokenHandler, boolean newAttributesEachTime) {
+ this.tokenHandler = tokenHandler;
+ this.encodingDeclarationHandler = null;
+ this.newAttributesEachTime = newAttributesEachTime;
+ // &CounterClockwiseContourIntegral; is the longest valid char ref and
+ // the semicolon never gets appended to the buffer.
+ this.charRefBuf = new char[32];
+ this.bmpChar = new char[1];
+ this.astralChar = new char[2];
+ this.tagName = null;
+ this.attributeName = null;
+ this.doctypeName = null;
+ this.publicIdentifier = null;
+ this.systemIdentifier = null;
+ this.attributes = null;
+ }
+
+ // ]NOCPP]
+
+ /**
+ * The constructor.
+ *
+ * @param tokenHandler
+ * the handler for receiving tokens
+ */
+ public Tokenizer(TokenHandler tokenHandler
+ // CPPONLY: , boolean viewingXmlSource
+ ) {
+ this.tokenHandler = tokenHandler;
+ this.encodingDeclarationHandler = null;
+ // [NOCPP[
+ this.newAttributesEachTime = false;
+ // ]NOCPP]
+ // &CounterClockwiseContourIntegral; is the longest valid char ref and
+ // the semicolon never gets appended to the buffer.
+ this.charRefBuf = new char[32];
+ this.bmpChar = new char[1];
+ this.astralChar = new char[2];
+ this.tagName = null;
+ this.attributeName = null;
+ this.doctypeName = null;
+ this.publicIdentifier = null;
+ this.systemIdentifier = null;
+ // [NOCPP[
+ this.attributes = null;
+ // ]NOCPP]
+ // CPPONLY: this.attributes = tokenHandler.HasBuilder() ? new HtmlAttributes(mappingLangToXmlLang) : null;
+ // CPPONLY: this.newAttributesEachTime = !tokenHandler.HasBuilder();
+ // CPPONLY: this.viewingXmlSource = viewingXmlSource;
+ }
+
+ public void setInterner(Interner interner) {
+ this.interner = interner;
+ }
+
+ public void initLocation(String newPublicId, String newSystemId) {
+ this.systemId = newSystemId;
+ this.publicId = newPublicId;
+
+ }
+
+ // CPPONLY: boolean isViewingXmlSource() {
+ // CPPONLY: return viewingXmlSource;
+ // CPPONLY: }
+
+ // [NOCPP[
+
+ /**
+ * Returns the mappingLangToXmlLang.
+ *
+ * @return the mappingLangToXmlLang
+ */
+ public boolean isMappingLangToXmlLang() {
+ return mappingLangToXmlLang == AttributeName.HTML_LANG;
+ }
+
+ /**
+ * Sets the mappingLangToXmlLang.
+ *
+ * @param mappingLangToXmlLang
+ * the mappingLangToXmlLang to set
+ */
+ public void setMappingLangToXmlLang(boolean mappingLangToXmlLang) {
+ this.mappingLangToXmlLang = mappingLangToXmlLang ? AttributeName.HTML_LANG
+ : AttributeName.HTML;
+ }
+
+ /**
+ * Sets the error handler.
+ *
+ * @see org.xml.sax.XMLReader#setErrorHandler(org.xml.sax.ErrorHandler)
+ */
+ public void setErrorHandler(ErrorHandler eh) {
+ this.errorHandler = eh;
+ }
+
+ public ErrorHandler getErrorHandler() {
+ return this.errorHandler;
+ }
+
+ /**
+ * Sets the commentPolicy.
+ *
+ * @param commentPolicy
+ * the commentPolicy to set
+ */
+ public void setCommentPolicy(XmlViolationPolicy commentPolicy) {
+ this.commentPolicy = commentPolicy;
+ }
+
+ /**
+ * Sets the contentNonXmlCharPolicy.
+ *
+ * @param contentNonXmlCharPolicy
+ * the contentNonXmlCharPolicy to set
+ */
+ public void setContentNonXmlCharPolicy(
+ XmlViolationPolicy contentNonXmlCharPolicy) {
+ if (contentNonXmlCharPolicy != XmlViolationPolicy.ALLOW) {
+ throw new IllegalArgumentException(
+ "Must use ErrorReportingTokenizer to set contentNonXmlCharPolicy to non-ALLOW.");
+ }
+ }
+
+ /**
+ * Sets the contentSpacePolicy.
+ *
+ * @param contentSpacePolicy
+ * the contentSpacePolicy to set
+ */
+ public void setContentSpacePolicy(XmlViolationPolicy contentSpacePolicy) {
+ this.contentSpacePolicy = contentSpacePolicy;
+ }
+
+ /**
+ * Sets the xmlnsPolicy.
+ *
+ * @param xmlnsPolicy
+ * the xmlnsPolicy to set
+ */
+ public void setXmlnsPolicy(XmlViolationPolicy xmlnsPolicy) {
+ if (xmlnsPolicy == XmlViolationPolicy.FATAL) {
+ throw new IllegalArgumentException("Can't use FATAL here.");
+ }
+ this.xmlnsPolicy = xmlnsPolicy;
+ }
+
+ public void setNamePolicy(XmlViolationPolicy namePolicy) {
+ this.namePolicy = namePolicy;
+ }
+
+ /**
+ * Sets the html4ModeCompatibleWithXhtml1Schemata.
+ *
+ * @param html4ModeCompatibleWithXhtml1Schemata
+ * the html4ModeCompatibleWithXhtml1Schemata to set
+ */
+ public void setHtml4ModeCompatibleWithXhtml1Schemata(
+ boolean html4ModeCompatibleWithXhtml1Schemata) {
+ this.html4ModeCompatibleWithXhtml1Schemata = html4ModeCompatibleWithXhtml1Schemata;
+ }
+
+ // ]NOCPP]
+
+ // For the token handler to call
+ /**
+ * Sets the tokenizer state and the associated element name. This should
+ * only ever used to put the tokenizer into one of the states that have
+ * a special end tag expectation.
+ *
+ * @param specialTokenizerState
+ * the tokenizer state to set
+ * @param endTagExpectation
+ * the expected end tag for transitioning back to normal
+ */
+ public void setStateAndEndTagExpectation(int specialTokenizerState,
+ @Local String endTagExpectation) {
+ this.stateSave = specialTokenizerState;
+ if (specialTokenizerState == Tokenizer.DATA) {
+ return;
+ }
+ @Auto char[] asArray = Portability.newCharArrayFromLocal(endTagExpectation);
+ this.endTagExpectation = ElementName.elementNameByBuffer(asArray, 0,
+ asArray.length, interner);
+ endTagExpectationToArray();
+ }
+
+ /**
+ * Sets the tokenizer state and the associated element name. This should
+ * only ever used to put the tokenizer into one of the states that have
+ * a special end tag expectation.
+ *
+ * @param specialTokenizerState
+ * the tokenizer state to set
+ * @param endTagExpectation
+ * the expected end tag for transitioning back to normal
+ */
+ public void setStateAndEndTagExpectation(int specialTokenizerState,
+ ElementName endTagExpectation) {
+ this.stateSave = specialTokenizerState;
+ this.endTagExpectation = endTagExpectation;
+ endTagExpectationToArray();
+ }
+
+ private void endTagExpectationToArray() {
+ switch (endTagExpectation.getGroup()) {
+ case TreeBuilder.TITLE:
+ endTagExpectationAsArray = TITLE_ARR;
+ return;
+ case TreeBuilder.SCRIPT:
+ endTagExpectationAsArray = SCRIPT_ARR;
+ return;
+ case TreeBuilder.STYLE:
+ endTagExpectationAsArray = STYLE_ARR;
+ return;
+ case TreeBuilder.PLAINTEXT:
+ endTagExpectationAsArray = PLAINTEXT_ARR;
+ return;
+ case TreeBuilder.XMP:
+ endTagExpectationAsArray = XMP_ARR;
+ return;
+ case TreeBuilder.TEXTAREA:
+ endTagExpectationAsArray = TEXTAREA_ARR;
+ return;
+ case TreeBuilder.IFRAME:
+ endTagExpectationAsArray = IFRAME_ARR;
+ return;
+ case TreeBuilder.NOEMBED:
+ endTagExpectationAsArray = NOEMBED_ARR;
+ return;
+ case TreeBuilder.NOSCRIPT:
+ endTagExpectationAsArray = NOSCRIPT_ARR;
+ return;
+ case TreeBuilder.NOFRAMES:
+ endTagExpectationAsArray = NOFRAMES_ARR;
+ return;
+ default:
+ assert false: "Bad end tag expectation.";
+ return;
+ }
+ }
+
+ /**
+ * For C++ use only.
+ */
+ public void setLineNumber(int line) {
+ // CPPONLY: this.attributeLine = line; // XXX is this needed?
+ this.line = line;
+ }
+
+ // start Locator impl
+
+ /**
+ * @see org.xml.sax.Locator#getLineNumber()
+ */
+ @Inline public int getLineNumber() {
+ return line;
+ }
+
+ // [NOCPP[
+
+ /**
+ * @see org.xml.sax.Locator#getColumnNumber()
+ */
+ @Inline public int getColumnNumber() {
+ return -1;
+ }
+
+ /**
+ * @see org.xml.sax.Locator#getPublicId()
+ */
+ public String getPublicId() {
+ return publicId;
+ }
+
+ /**
+ * @see org.xml.sax.Locator#getSystemId()
+ */
+ public String getSystemId() {
+ return systemId;
+ }
+
+ // end Locator impl
+
+ // end public API
+
+ public void notifyAboutMetaBoundary() {
+ metaBoundaryPassed = true;
+ }
+
+ void turnOnAdditionalHtml4Errors() {
+ html4 = true;
+ }
+
+ // ]NOCPP]
+
+ HtmlAttributes emptyAttributes() {
+ // [NOCPP[
+ if (newAttributesEachTime) {
+ return new HtmlAttributes(mappingLangToXmlLang);
+ } else {
+ // ]NOCPP]
+ return HtmlAttributes.EMPTY_ATTRIBUTES;
+ // [NOCPP[
+ }
+ // ]NOCPP]
+ }
+
+ @Inline private void appendCharRefBuf(char c) {
+ // CPPONLY: assert charRefBufLen < charRefBuf.length:
+ // CPPONLY: "RELEASE: Attempted to overrun charRefBuf!";
+ charRefBuf[charRefBufLen++] = c;
+ }
+
+ private void emitOrAppendCharRefBuf(int returnState) throws SAXException {
+ if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
+ appendCharRefBufToStrBuf();
+ } else {
+ if (charRefBufLen > 0) {
+ tokenHandler.characters(charRefBuf, 0, charRefBufLen);
+ charRefBufLen = 0;
+ }
+ }
+ }
+
+ @Inline private void clearStrBufAfterUse() {
+ strBufLen = 0;
+ }
+
+ @Inline private void clearStrBufBeforeUse() {
+ assert strBufLen == 0: "strBufLen not reset after previous use!";
+ strBufLen = 0; // no-op in the absence of bugs
+ }
+
+ @Inline private void clearStrBufAfterOneHyphen() {
+ assert strBufLen == 1: "strBufLen length not one!";
+ assert strBuf[0] == '-': "strBuf does not start with a hyphen!";
+ strBufLen = 0;
+ }
+
+ /**
+ * Appends to the buffer.
+ *
+ * @param c
+ * the UTF-16 code unit to append
+ */
+ @Inline private void appendStrBuf(char c) {
+ // CPPONLY: assert strBufLen < strBuf.length: "Previous buffer length insufficient.";
+ // CPPONLY: if (strBufLen == strBuf.length) {
+ // CPPONLY: if (!EnsureBufferSpace(1)) {
+ // CPPONLY: assert false: "RELEASE: Unable to recover from buffer reallocation failure";
+ // CPPONLY: } // TODO: Add telemetry when outer if fires but inner does not
+ // CPPONLY: }
+ strBuf[strBufLen++] = c;
+ }
+
+ /**
+ * The buffer as a String. Currently only used for error reporting.
+ *
+ * <p>
+ * C++ memory note: The return value must be released.
+ *
+ * @return the buffer as a string
+ */
+ protected String strBufToString() {
+ String str = Portability.newStringFromBuffer(strBuf, 0, strBufLen
+ // CPPONLY: , tokenHandler
+ );
+ clearStrBufAfterUse();
+ return str;
+ }
+
+ /**
+ * Returns the buffer as a local name. The return value is released in
+ * emitDoctypeToken().
+ *
+ * @return the buffer as local name
+ */
+ private void strBufToDoctypeName() {
+ doctypeName = Portability.newLocalNameFromBuffer(strBuf, 0, strBufLen,
+ interner);
+ clearStrBufAfterUse();
+ }
+
+ /**
+ * Emits the buffer as character tokens.
+ *
+ * @throws SAXException
+ * if the token handler threw
+ */
+ private void emitStrBuf() throws SAXException {
+ if (strBufLen > 0) {
+ tokenHandler.characters(strBuf, 0, strBufLen);
+ clearStrBufAfterUse();
+ }
+ }
+
+ @Inline private void appendSecondHyphenToBogusComment() throws SAXException {
+ // [NOCPP[
+ switch (commentPolicy) {
+ case ALTER_INFOSET:
+ appendStrBuf(' ');
+ // FALLTHROUGH
+ case ALLOW:
+ warn("The document is not mappable to XML 1.0 due to two consecutive hyphens in a comment.");
+ // ]NOCPP]
+ appendStrBuf('-');
+ // [NOCPP[
+ break;
+ case FATAL:
+ fatal("The document is not mappable to XML 1.0 due to two consecutive hyphens in a comment.");
+ break;
+ }
+ // ]NOCPP]
+ }
+
+ // [NOCPP[
+ private void maybeAppendSpaceToBogusComment() throws SAXException {
+ switch (commentPolicy) {
+ case ALTER_INFOSET:
+ appendStrBuf(' ');
+ // FALLTHROUGH
+ case ALLOW:
+ warn("The document is not mappable to XML 1.0 due to a trailing hyphen in a comment.");
+ break;
+ case FATAL:
+ fatal("The document is not mappable to XML 1.0 due to a trailing hyphen in a comment.");
+ break;
+ }
+ }
+
+ // ]NOCPP]
+
+ @Inline private void adjustDoubleHyphenAndAppendToStrBufAndErr(char c)
+ throws SAXException {
+ errConsecutiveHyphens();
+ // [NOCPP[
+ switch (commentPolicy) {
+ case ALTER_INFOSET:
+ strBufLen--;
+ // WARNING!!! This expands the worst case of the buffer length
+ // given the length of input!
+ appendStrBuf(' ');
+ appendStrBuf('-');
+ // FALLTHROUGH
+ case ALLOW:
+ warn("The document is not mappable to XML 1.0 due to two consecutive hyphens in a comment.");
+ // ]NOCPP]
+ appendStrBuf(c);
+ // [NOCPP[
+ break;
+ case FATAL:
+ fatal("The document is not mappable to XML 1.0 due to two consecutive hyphens in a comment.");
+ break;
+ }
+ // ]NOCPP]
+ }
+
+ private void appendStrBuf(@NoLength char[] buffer, int offset, int length) {
+ int newLen = strBufLen + length;
+ // CPPONLY: assert newLen <= strBuf.length: "Previous buffer length insufficient.";
+ // CPPONLY: if (strBuf.length < newLen) {
+ // CPPONLY: if (!EnsureBufferSpace(length)) {
+ // CPPONLY: assert false: "RELEASE: Unable to recover from buffer reallocation failure";
+ // CPPONLY: } // TODO: Add telemetry when outer if fires but inner does not
+ // CPPONLY: }
+ System.arraycopy(buffer, offset, strBuf, strBufLen, length);
+ strBufLen = newLen;
+ }
+
+ /**
+ * Append the contents of the char reference buffer to the main one.
+ */
+ @Inline private void appendCharRefBufToStrBuf() {
+ appendStrBuf(charRefBuf, 0, charRefBufLen);
+ charRefBufLen = 0;
+ }
+
+ /**
+ * Emits the current comment token.
+ *
+ * @param pos
+ * TODO
+ *
+ * @throws SAXException
+ */
+ private void emitComment(int provisionalHyphens, int pos)
+ throws SAXException {
+ // [NOCPP[
+ if (wantsComments) {
+ // ]NOCPP]
+ tokenHandler.comment(strBuf, 0, strBufLen
+ - provisionalHyphens);
+ // [NOCPP[
+ }
+ // ]NOCPP]
+ clearStrBufAfterUse();
+ cstart = pos + 1;
+ }
+
+ /**
+ * Flushes coalesced character tokens.
+ *
+ * @param buf
+ * TODO
+ * @param pos
+ * TODO
+ *
+ * @throws SAXException
+ */
+ protected void flushChars(@NoLength char[] buf, int pos)
+ throws SAXException {
+ if (pos > cstart) {
+ tokenHandler.characters(buf, cstart, pos - cstart);
+ }
+ cstart = Integer.MAX_VALUE;
+ }
+
+ /**
+ * Reports an condition that would make the infoset incompatible with XML
+ * 1.0 as fatal.
+ *
+ * @param message
+ * the message
+ * @throws SAXException
+ * @throws SAXParseException
+ */
+ public void fatal(String message) throws SAXException {
+ SAXParseException spe = new SAXParseException(message, this);
+ if (errorHandler != null) {
+ errorHandler.fatalError(spe);
+ }
+ throw spe;
+ }
+
+ /**
+ * Reports a Parse Error.
+ *
+ * @param message
+ * the message
+ * @throws SAXException
+ */
+ public void err(String message) throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ SAXParseException spe = new SAXParseException(message, this);
+ errorHandler.error(spe);
+ }
+
+ public void errTreeBuilder(String message) throws SAXException {
+ ErrorHandler eh = null;
+ if (tokenHandler instanceof TreeBuilder<?>) {
+ TreeBuilder<?> treeBuilder = (TreeBuilder<?>) tokenHandler;
+ eh = treeBuilder.getErrorHandler();
+ }
+ if (eh == null) {
+ eh = errorHandler;
+ }
+ if (eh == null) {
+ return;
+ }
+ SAXParseException spe = new SAXParseException(message, this);
+ eh.error(spe);
+ }
+
+ /**
+ * Reports a warning
+ *
+ * @param message
+ * the message
+ * @throws SAXException
+ */
+ public void warn(String message) throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ SAXParseException spe = new SAXParseException(message, this);
+ errorHandler.warning(spe);
+ }
+
+ private void strBufToElementNameString() {
+ tagName = ElementName.elementNameByBuffer(strBuf, 0, strBufLen,
+ interner);
+ clearStrBufAfterUse();
+ }
+
+ private int emitCurrentTagToken(boolean selfClosing, int pos)
+ throws SAXException {
+ cstart = pos + 1;
+ maybeErrSlashInEndTag(selfClosing);
+ stateSave = Tokenizer.DATA;
+ HtmlAttributes attrs = (attributes == null ? HtmlAttributes.EMPTY_ATTRIBUTES
+ : attributes);
+ if (endTag) {
+ /*
+ * When an end tag token is emitted, the content model flag must be
+ * switched to the PCDATA state.
+ */
+ maybeErrAttributesOnEndTag(attrs);
+ // CPPONLY: if (!viewingXmlSource) {
+ tokenHandler.endTag(tagName);
+ // CPPONLY: }
+ // CPPONLY: if (newAttributesEachTime) {
+ // CPPONLY: Portability.delete(attributes);
+ // CPPONLY: attributes = null;
+ // CPPONLY: }
+ } else {
+ // CPPONLY: if (viewingXmlSource) {
+ // CPPONLY: assert newAttributesEachTime;
+ // CPPONLY: Portability.delete(attributes);
+ // CPPONLY: attributes = null;
+ // CPPONLY: } else {
+ tokenHandler.startTag(tagName, attrs, selfClosing);
+ // CPPONLY: }
+ }
+ tagName.release();
+ tagName = null;
+ if (newAttributesEachTime) {
+ attributes = null;
+ } else {
+ attributes.clear(mappingLangToXmlLang);
+ }
+ /*
+ * The token handler may have called setStateAndEndTagExpectation
+ * and changed stateSave since the start of this method.
+ */
+ return stateSave;
+ }
+
+ private void attributeNameComplete() throws SAXException {
+ attributeName = AttributeName.nameByBuffer(strBuf, 0, strBufLen
+ // [NOCPP[
+ , namePolicy != XmlViolationPolicy.ALLOW
+ // ]NOCPP]
+ , interner);
+ clearStrBufAfterUse();
+
+ if (attributes == null) {
+ attributes = new HtmlAttributes(mappingLangToXmlLang);
+ }
+
+ /*
+ * When the user agent leaves the attribute name state (and before
+ * emitting the tag token, if appropriate), the complete attribute's
+ * name must be compared to the other attributes on the same token; if
+ * there is already an attribute on the token with the exact same name,
+ * then this is a parse error and the new attribute must be dropped,
+ * along with the value that gets associated with it (if any).
+ */
+ if (attributes.contains(attributeName)) {
+ errDuplicateAttribute();
+ attributeName.release();
+ attributeName = null;
+ }
+ }
+
+ private void addAttributeWithoutValue() throws SAXException {
+ noteAttributeWithoutValue();
+
+ // [NOCPP[
+ if (metaBoundaryPassed && AttributeName.CHARSET == attributeName
+ && ElementName.META == tagName) {
+ err("A \u201Ccharset\u201D attribute on a \u201Cmeta\u201D element found after the first 512 bytes.");
+ }
+ // ]NOCPP]
+ if (attributeName != null) {
+ // [NOCPP[
+ if (html4) {
+ if (attributeName.isBoolean()) {
+ if (html4ModeCompatibleWithXhtml1Schemata) {
+ attributes.addAttribute(attributeName,
+ attributeName.getLocal(AttributeName.HTML),
+ xmlnsPolicy);
+ } else {
+ attributes.addAttribute(attributeName, "", xmlnsPolicy);
+ }
+ } else {
+ if (AttributeName.BORDER != attributeName) {
+ err("Attribute value omitted for a non-boolean attribute. (HTML4-only error.)");
+ attributes.addAttribute(attributeName, "", xmlnsPolicy);
+ }
+ }
+ } else {
+ if (AttributeName.SRC == attributeName
+ || AttributeName.HREF == attributeName) {
+ warn("Attribute \u201C"
+ + attributeName.getLocal(AttributeName.HTML)
+ + "\u201D without an explicit value seen. The attribute may be dropped by IE7.");
+ }
+ // ]NOCPP]
+ attributes.addAttribute(attributeName,
+ Portability.newEmptyString()
+ // [NOCPP[
+ , xmlnsPolicy
+ // ]NOCPP]
+ // CPPONLY: , attributeLine
+ );
+ // [NOCPP[
+ }
+ // ]NOCPP]
+ attributeName = null; // attributeName has been adopted by the
+ // |attributes| object
+ } else {
+ clearStrBufAfterUse();
+ }
+ }
+
+ private void addAttributeWithValue() throws SAXException {
+ // [NOCPP[
+ if (metaBoundaryPassed && ElementName.META == tagName
+ && AttributeName.CHARSET == attributeName) {
+ err("A \u201Ccharset\u201D attribute on a \u201Cmeta\u201D element found after the first 512 bytes.");
+ }
+ // ]NOCPP]
+ if (attributeName != null) {
+ String val = strBufToString(); // Ownership transferred to
+ // HtmlAttributes
+ // CPPONLY: if (mViewSource) {
+ // CPPONLY: mViewSource.MaybeLinkifyAttributeValue(attributeName, val);
+ // CPPONLY: }
+ // [NOCPP[
+ if (!endTag && html4 && html4ModeCompatibleWithXhtml1Schemata
+ && attributeName.isCaseFolded()) {
+ val = newAsciiLowerCaseStringFromString(val);
+ }
+ // ]NOCPP]
+ attributes.addAttribute(attributeName, val
+ // [NOCPP[
+ , xmlnsPolicy
+ // ]NOCPP]
+ // CPPONLY: , attributeLine
+ );
+ attributeName = null; // attributeName has been adopted by the
+ // |attributes| object
+ } else {
+ // We have a duplicate attribute. Explicitly discard its value.
+ clearStrBufAfterUse();
+ }
+ }
+
+ // [NOCPP[
+
+ private static String newAsciiLowerCaseStringFromString(String str) {
+ if (str == null) {
+ return null;
+ }
+ char[] buf = new char[str.length()];
+ for (int i = 0; i < str.length(); i++) {
+ char c = str.charAt(i);
+ if (c >= 'A' && c <= 'Z') {
+ c += 0x20;
+ }
+ buf[i] = c;
+ }
+ return new String(buf);
+ }
+
+ protected void startErrorReporting() throws SAXException {
+
+ }
+
+ // ]NOCPP]
+
+ public void start() throws SAXException {
+ initializeWithoutStarting();
+ tokenHandler.startTokenization(this);
+ // [NOCPP[
+ startErrorReporting();
+ // ]NOCPP]
+ }
+
+ public boolean tokenizeBuffer(UTF16Buffer buffer) throws SAXException {
+ int state = stateSave;
+ int returnState = returnStateSave;
+ char c = '\u0000';
+ shouldSuspend = false;
+ lastCR = false;
+
+ int start = buffer.getStart();
+ int end = buffer.getEnd();
+
+ // In C++, the caller of tokenizeBuffer needs to do this explicitly.
+ // [NOCPP[
+ ensureBufferSpace(end - start);
+ // ]NOCPP]
+
+ /**
+ * The index of the last <code>char</code> read from <code>buf</code>.
+ */
+ int pos = start - 1;
+
+ /**
+ * The index of the first <code>char</code> in <code>buf</code> that is
+ * part of a coalesced run of character tokens or
+ * <code>Integer.MAX_VALUE</code> if there is not a current run being
+ * coalesced.
+ */
+ switch (state) {
+ case DATA:
+ case RCDATA:
+ case SCRIPT_DATA:
+ case PLAINTEXT:
+ case RAWTEXT:
+ case CDATA_SECTION:
+ case SCRIPT_DATA_ESCAPED:
+ case SCRIPT_DATA_ESCAPE_START:
+ case SCRIPT_DATA_ESCAPE_START_DASH:
+ case SCRIPT_DATA_ESCAPED_DASH:
+ case SCRIPT_DATA_ESCAPED_DASH_DASH:
+ case SCRIPT_DATA_DOUBLE_ESCAPE_START:
+ case SCRIPT_DATA_DOUBLE_ESCAPED:
+ case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:
+ case SCRIPT_DATA_DOUBLE_ESCAPED_DASH:
+ case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:
+ case SCRIPT_DATA_DOUBLE_ESCAPE_END:
+ cstart = start;
+ break;
+ default:
+ cstart = Integer.MAX_VALUE;
+ break;
+ }
+
+ /**
+ * The number of <code>char</code>s in <code>buf</code> that have
+ * meaning. (The rest of the array is garbage and should not be
+ * examined.)
+ */
+ // CPPONLY: if (mViewSource) {
+ // CPPONLY: mViewSource.SetBuffer(buffer);
+ // CPPONLY: pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
+ // CPPONLY: mViewSource.DropBuffer((pos == buffer.getEnd()) ? pos : pos + 1);
+ // CPPONLY: } else {
+ // CPPONLY: pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
+ // CPPONLY: }
+ // [NOCPP[
+ pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState,
+ end);
+ // ]NOCPP]
+ if (pos == end) {
+ // exiting due to end of buffer
+ buffer.setStart(pos);
+ } else {
+ buffer.setStart(pos + 1);
+ }
+ return lastCR;
+ }
+
+ // [NOCPP[
+ private void ensureBufferSpace(int inputLength) throws SAXException {
+ // Add 2 to account for emissions of LT_GT, LT_SOLIDUS and RSQB_RSQB.
+ // Adding to the general worst case instead of only the
+ // TreeBuilder-exposed worst case to avoid re-introducing a bug when
+ // unifying the tokenizer and tree builder buffers in the future.
+ int worstCase = strBufLen + inputLength + charRefBufLen + 2;
+ tokenHandler.ensureBufferSpace(worstCase);
+ if (commentPolicy == XmlViolationPolicy.ALTER_INFOSET) {
+ // When altering infoset, if the comment contents are consecutive
+ // hyphens, each hyphen generates a space, too. These buffer
+ // contents never get emitted as characters() to the tokenHandler,
+ // which is why this calculation happens after the call to
+ // ensureBufferSpace on tokenHandler.
+ worstCase *= 2;
+ }
+ if (strBuf == null) {
+ // Add an arbitrary small value to avoid immediate reallocation
+ // once there are a few characters in the buffer.
+ strBuf = new char[worstCase + 128];
+ } else if (worstCase > strBuf.length) {
+ // HotSpot reportedly allocates memory with 8-byte accuracy, so
+ // there's no point in trying to do math here to avoid slop.
+ // Maybe we should add some small constant to worstCase here
+ // but not doing that without profiling. In C++ with jemalloc,
+ // the corresponding method should do math to round up here
+ // to avoid slop.
+ char[] newBuf = new char[worstCase];
+ System.arraycopy(strBuf, 0, newBuf, 0, strBufLen);
+ strBuf = newBuf;
+ }
+ }
+ // ]NOCPP]
+
+ @SuppressWarnings("unused") private int stateLoop(int state, char c,
+ int pos, @NoLength char[] buf, boolean reconsume, int returnState,
+ int endPos) throws SAXException {
+ /*
+ * Idioms used in this code:
+ *
+ *
+ * Consuming the next input character
+ *
+ * To consume the next input character, the code does this: if (++pos ==
+ * endPos) { break stateloop; } c = checkChar(buf, pos);
+ *
+ *
+ * Staying in a state
+ *
+ * When there's a state that the tokenizer may stay in over multiple
+ * input characters, the state has a wrapper |for(;;)| loop and staying
+ * in the state continues the loop.
+ *
+ *
+ * Switching to another state
+ *
+ * To switch to another state, the code sets the state variable to the
+ * magic number of the new state. Then it either continues stateloop or
+ * breaks out of the state's own wrapper loop if the target state is
+ * right after the current state in source order. (This is a partial
+ * workaround for Java's lack of goto.)
+ *
+ *
+ * Reconsume support
+ *
+ * The spec sometimes says that an input character is reconsumed in
+ * another state. If a state can ever be entered so that an input
+ * character can be reconsumed in it, the state's code starts with an
+ * |if (reconsume)| that sets reconsume to false and skips over the
+ * normal code for consuming a new character.
+ *
+ * To reconsume the current character in another state, the code sets
+ * |reconsume| to true and then switches to the other state.
+ *
+ *
+ * Emitting character tokens
+ *
+ * This method emits character tokens lazily. Whenever a new range of
+ * character tokens starts, the field cstart must be set to the start
+ * index of the range. The flushChars() method must be called at the end
+ * of a range to flush it.
+ *
+ *
+ * U+0000 handling
+ *
+ * The various states have to handle the replacement of U+0000 with
+ * U+FFFD. However, if U+0000 would be reconsumed in another state, the
+ * replacement doesn't need to happen, because it's handled by the
+ * reconsuming state.
+ *
+ *
+ * LF handling
+ *
+ * Every state needs to increment the line number upon LF unless the LF
+ * gets reconsumed by another state which increments the line number.
+ *
+ *
+ * CR handling
+ *
+ * Every state needs to handle CR unless the CR gets reconsumed and is
+ * handled by the reconsuming state. The CR needs to be handled as if it
+ * were and LF, the lastCR field must be set to true and then this
+ * method must return. The IO driver will then swallow the next
+ * character if it is an LF to coalesce CRLF.
+ */
+ stateloop: for (;;) {
+ switch (state) {
+ case DATA:
+ dataloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ switch (c) {
+ case '&':
+ /*
+ * U+0026 AMPERSAND (&) Switch to the character
+ * reference in data state.
+ */
+ flushChars(buf, pos);
+ assert charRefBufLen == 0: "charRefBufLen not reset after previous use!";
+ appendCharRefBuf(c);
+ setAdditionalAndRememberAmpersandLocation('\u0000');
+ returnState = state;
+ state = transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos);
+ continue stateloop;
+ case '<':
+ /*
+ * U+003C LESS-THAN SIGN (<) Switch to the tag
+ * open state.
+ */
+ flushChars(buf, pos);
+
+ state = transition(state, Tokenizer.TAG_OPEN, reconsume, pos);
+ break dataloop; // FALL THROUGH continue
+ // stateloop;
+ case '\u0000':
+ emitReplacementCharacter(buf, pos);
+ continue;
+ case '\r':
+ emitCarriageReturn(buf, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ default:
+ /*
+ * Anything else Emit the input character as a
+ * character token.
+ *
+ * Stay in the data state.
+ */
+ continue;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case TAG_OPEN:
+ tagopenloop: for (;;) {
+ /*
+ * The behavior of this state depends on the content
+ * model flag.
+ */
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * If the content model flag is set to the PCDATA state
+ * Consume the next input character:
+ */
+ if (c >= 'A' && c <= 'Z') {
+ /*
+ * U+0041 LATIN CAPITAL LETTER A through to U+005A
+ * LATIN CAPITAL LETTER Z Create a new start tag
+ * token,
+ */
+ endTag = false;
+ /*
+ * set its tag name to the lowercase version of the
+ * input character (add 0x0020 to the character's
+ * code point),
+ */
+ clearStrBufBeforeUse();
+ appendStrBuf((char) (c + 0x20));
+ /* then switch to the tag name state. */
+ state = transition(state, Tokenizer.TAG_NAME, reconsume, pos);
+ /*
+ * (Don't emit the token yet; further details will
+ * be filled in before it is emitted.)
+ */
+ break tagopenloop;
+ // continue stateloop;
+ } else if (c >= 'a' && c <= 'z') {
+ /*
+ * U+0061 LATIN SMALL LETTER A through to U+007A
+ * LATIN SMALL LETTER Z Create a new start tag
+ * token,
+ */
+ endTag = false;
+ /*
+ * set its tag name to the input character,
+ */
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ /* then switch to the tag name state. */
+ state = transition(state, Tokenizer.TAG_NAME, reconsume, pos);
+ /*
+ * (Don't emit the token yet; further details will
+ * be filled in before it is emitted.)
+ */
+ break tagopenloop;
+ // continue stateloop;
+ }
+ switch (c) {
+ case '!':
+ /*
+ * U+0021 EXCLAMATION MARK (!) Switch to the
+ * markup declaration open state.
+ */
+ state = transition(state, Tokenizer.MARKUP_DECLARATION_OPEN, reconsume, pos);
+ continue stateloop;
+ case '/':
+ /*
+ * U+002F SOLIDUS (/) Switch to the close tag
+ * open state.
+ */
+ state = transition(state, Tokenizer.CLOSE_TAG_OPEN, reconsume, pos);
+ continue stateloop;
+ case '?':
+ // CPPONLY: if (viewingXmlSource) {
+ // CPPONLY: state = transition(state,
+ // CPPONLY: Tokenizer.PROCESSING_INSTRUCTION,
+ // CPPONLY: reconsume,
+ // CPPONLY: pos);
+ // CPPONLY: continue stateloop;
+ // CPPONLY: }
+ /*
+ * U+003F QUESTION MARK (?) Parse error.
+ */
+ errProcessingInstruction();
+ /*
+ * Switch to the bogus comment state.
+ */
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
+ continue stateloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Parse error.
+ */
+ errLtGt();
+ /*
+ * Emit a U+003C LESS-THAN SIGN character token
+ * and a U+003E GREATER-THAN SIGN character
+ * token.
+ */
+ tokenHandler.characters(Tokenizer.LT_GT, 0, 2);
+ /* Switch to the data state. */
+ cstart = pos + 1;
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ default:
+ /*
+ * Anything else Parse error.
+ */
+ errBadCharAfterLt(c);
+ /*
+ * Emit a U+003C LESS-THAN SIGN character token
+ */
+ tokenHandler.characters(Tokenizer.LT_GT, 0, 1);
+ /*
+ * and reconsume the current input character in
+ * the data state.
+ */
+ cstart = pos;
+ reconsume = true;
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // FALL THROUGH DON'T REORDER
+ case TAG_NAME:
+ tagnameloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ strBufToElementNameString();
+ state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE
+ * Switch to the before attribute name state.
+ */
+ strBufToElementNameString();
+ state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ break tagnameloop;
+ // continue stateloop;
+ case '/':
+ /*
+ * U+002F SOLIDUS (/) Switch to the self-closing
+ * start tag state.
+ */
+ strBufToElementNameString();
+ state = transition(state, Tokenizer.SELF_CLOSING_START_TAG, reconsume, pos);
+ continue stateloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit the current
+ * tag token.
+ */
+ strBufToElementNameString();
+ state = transition(state, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ break stateloop;
+ }
+ /*
+ * Switch to the data state.
+ */
+ continue stateloop;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ if (c >= 'A' && c <= 'Z') {
+ /*
+ * U+0041 LATIN CAPITAL LETTER A through to
+ * U+005A LATIN CAPITAL LETTER Z Append the
+ * lowercase version of the current input
+ * character (add 0x0020 to the character's
+ * code point) to the current tag token's
+ * tag name.
+ */
+ c += 0x20;
+ }
+ /*
+ * Anything else Append the current input
+ * character to the current tag token's tag
+ * name.
+ */
+ appendStrBuf(c);
+ /*
+ * Stay in the tag name state.
+ */
+ continue;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case BEFORE_ATTRIBUTE_NAME:
+ beforeattributenameloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE Stay
+ * in the before attribute name state.
+ */
+ continue;
+ case '/':
+ /*
+ * U+002F SOLIDUS (/) Switch to the self-closing
+ * start tag state.
+ */
+ state = transition(state, Tokenizer.SELF_CLOSING_START_TAG, reconsume, pos);
+ continue stateloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit the current
+ * tag token.
+ */
+ state = transition(state, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ break stateloop;
+ }
+ /*
+ * Switch to the data state.
+ */
+ continue stateloop;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ case '\"':
+ case '\'':
+ case '<':
+ case '=':
+ /*
+ * U+0022 QUOTATION MARK (") U+0027 APOSTROPHE
+ * (') U+003C LESS-THAN SIGN (<) U+003D EQUALS
+ * SIGN (=) Parse error.
+ */
+ errBadCharBeforeAttributeNameOrNull(c);
+ /*
+ * Treat it as per the "anything else" entry
+ * below.
+ */
+ default:
+ /*
+ * Anything else Start a new attribute in the
+ * current tag token.
+ */
+ if (c >= 'A' && c <= 'Z') {
+ /*
+ * U+0041 LATIN CAPITAL LETTER A through to
+ * U+005A LATIN CAPITAL LETTER Z Set that
+ * attribute's name to the lowercase version
+ * of the current input character (add
+ * 0x0020 to the character's code point)
+ */
+ c += 0x20;
+ }
+ // CPPONLY: attributeLine = line;
+ /*
+ * Set that attribute's name to the current
+ * input character,
+ */
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ /*
+ * and its value to the empty string.
+ */
+ // Will do later.
+ /*
+ * Switch to the attribute name state.
+ */
+ state = transition(state, Tokenizer.ATTRIBUTE_NAME, reconsume, pos);
+ break beforeattributenameloop;
+ // continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case ATTRIBUTE_NAME:
+ attributenameloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ attributeNameComplete();
+ state = transition(state, Tokenizer.AFTER_ATTRIBUTE_NAME, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE
+ * Switch to the after attribute name state.
+ */
+ attributeNameComplete();
+ state = transition(state, Tokenizer.AFTER_ATTRIBUTE_NAME, reconsume, pos);
+ continue stateloop;
+ case '/':
+ /*
+ * U+002F SOLIDUS (/) Switch to the self-closing
+ * start tag state.
+ */
+ attributeNameComplete();
+ addAttributeWithoutValue();
+ state = transition(state, Tokenizer.SELF_CLOSING_START_TAG, reconsume, pos);
+ continue stateloop;
+ case '=':
+ /*
+ * U+003D EQUALS SIGN (=) Switch to the before
+ * attribute value state.
+ */
+ attributeNameComplete();
+ state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_VALUE, reconsume, pos);
+ break attributenameloop;
+ // continue stateloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit the current
+ * tag token.
+ */
+ attributeNameComplete();
+ addAttributeWithoutValue();
+ state = transition(state, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ break stateloop;
+ }
+ /*
+ * Switch to the data state.
+ */
+ continue stateloop;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ case '\"':
+ case '\'':
+ case '<':
+ /*
+ * U+0022 QUOTATION MARK (") U+0027 APOSTROPHE
+ * (') U+003C LESS-THAN SIGN (<) Parse error.
+ */
+ errQuoteOrLtInAttributeNameOrNull(c);
+ /*
+ * Treat it as per the "anything else" entry
+ * below.
+ */
+ default:
+ if (c >= 'A' && c <= 'Z') {
+ /*
+ * U+0041 LATIN CAPITAL LETTER A through to
+ * U+005A LATIN CAPITAL LETTER Z Append the
+ * lowercase version of the current input
+ * character (add 0x0020 to the character's
+ * code point) to the current attribute's
+ * name.
+ */
+ c += 0x20;
+ }
+ /*
+ * Anything else Append the current input
+ * character to the current attribute's name.
+ */
+ appendStrBuf(c);
+ /*
+ * Stay in the attribute name state.
+ */
+ continue;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case BEFORE_ATTRIBUTE_VALUE:
+ beforeattributevalueloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE Stay
+ * in the before attribute value state.
+ */
+ continue;
+ case '"':
+ /*
+ * U+0022 QUOTATION MARK (") Switch to the
+ * attribute value (double-quoted) state.
+ */
+ // CPPONLY: attributeLine = line;
+ clearStrBufBeforeUse();
+ state = transition(state, Tokenizer.ATTRIBUTE_VALUE_DOUBLE_QUOTED, reconsume, pos);
+ break beforeattributevalueloop;
+ // continue stateloop;
+ case '&':
+ /*
+ * U+0026 AMPERSAND (&) Switch to the attribute
+ * value (unquoted) state and reconsume this
+ * input character.
+ */
+ // CPPONLY: attributeLine = line;
+ clearStrBufBeforeUse();
+ reconsume = true;
+ state = transition(state, Tokenizer.ATTRIBUTE_VALUE_UNQUOTED, reconsume, pos);
+ noteUnquotedAttributeValue();
+ continue stateloop;
+ case '\'':
+ /*
+ * U+0027 APOSTROPHE (') Switch to the attribute
+ * value (single-quoted) state.
+ */
+ // CPPONLY: attributeLine = line;
+ clearStrBufBeforeUse();
+ state = transition(state, Tokenizer.ATTRIBUTE_VALUE_SINGLE_QUOTED, reconsume, pos);
+ continue stateloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Parse error.
+ */
+ errAttributeValueMissing();
+ /*
+ * Emit the current tag token.
+ */
+ addAttributeWithoutValue();
+ state = transition(state, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ break stateloop;
+ }
+ /*
+ * Switch to the data state.
+ */
+ continue stateloop;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ case '<':
+ case '=':
+ case '`':
+ /*
+ * U+003C LESS-THAN SIGN (<) U+003D EQUALS SIGN
+ * (=) U+0060 GRAVE ACCENT (`)
+ */
+ errLtOrEqualsOrGraveInUnquotedAttributeOrNull(c);
+ /*
+ * Treat it as per the "anything else" entry
+ * below.
+ */
+ default:
+ // [NOCPP[
+ errHtml4NonNameInUnquotedAttribute(c);
+ // ]NOCPP]
+ /*
+ * Anything else Append the current input
+ * character to the current attribute's value.
+ */
+ // CPPONLY: attributeLine = line;
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ /*
+ * Switch to the attribute value (unquoted)
+ * state.
+ */
+
+ state = transition(state, Tokenizer.ATTRIBUTE_VALUE_UNQUOTED, reconsume, pos);
+ noteUnquotedAttributeValue();
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
+ attributevaluedoublequotedloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '"':
+ /*
+ * U+0022 QUOTATION MARK (") Switch to the after
+ * attribute value (quoted) state.
+ */
+ addAttributeWithValue();
+
+ state = transition(state, Tokenizer.AFTER_ATTRIBUTE_VALUE_QUOTED, reconsume, pos);
+ break attributevaluedoublequotedloop;
+ // continue stateloop;
+ case '&':
+ /*
+ * U+0026 AMPERSAND (&) Switch to the character
+ * reference in attribute value state, with the
+ * additional allowed character being U+0022
+ * QUOTATION MARK (").
+ */
+ assert charRefBufLen == 0: "charRefBufLen not reset after previous use!";
+ appendCharRefBuf(c);
+ setAdditionalAndRememberAmpersandLocation('\"');
+ returnState = state;
+ state = transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos);
+ continue stateloop;
+ case '\r':
+ appendStrBufCarriageReturn();
+ break stateloop;
+ case '\n':
+ appendStrBufLineFeed();
+ continue;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ /*
+ * Anything else Append the current input
+ * character to the current attribute's value.
+ */
+ appendStrBuf(c);
+ /*
+ * Stay in the attribute value (double-quoted)
+ * state.
+ */
+ continue;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case AFTER_ATTRIBUTE_VALUE_QUOTED:
+ afterattributevaluequotedloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE
+ * Switch to the before attribute name state.
+ */
+ state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ continue stateloop;
+ case '/':
+ /*
+ * U+002F SOLIDUS (/) Switch to the self-closing
+ * start tag state.
+ */
+ state = transition(state, Tokenizer.SELF_CLOSING_START_TAG, reconsume, pos);
+ break afterattributevaluequotedloop;
+ // continue stateloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit the current
+ * tag token.
+ */
+ state = transition(state, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ break stateloop;
+ }
+ /*
+ * Switch to the data state.
+ */
+ continue stateloop;
+ default:
+ /*
+ * Anything else Parse error.
+ */
+ errNoSpaceBetweenAttributes();
+ /*
+ * Reconsume the character in the before
+ * attribute name state.
+ */
+ reconsume = true;
+ state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case SELF_CLOSING_START_TAG:
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Set the self-closing
+ * flag of the current tag token. Emit the current
+ * tag token.
+ */
+ // [NOCPP[
+ errHtml4XmlVoidSyntax();
+ // ]NOCPP]
+ state = transition(state, emitCurrentTagToken(true, pos), reconsume, pos);
+ if (shouldSuspend) {
+ break stateloop;
+ }
+ /*
+ * Switch to the data state.
+ */
+ continue stateloop;
+ default:
+ /* Anything else Parse error. */
+ errSlashNotFollowedByGt();
+ /*
+ * Reconsume the character in the before attribute
+ * name state.
+ */
+ reconsume = true;
+ state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ continue stateloop;
+ }
+ // XXX reorder point
+ case ATTRIBUTE_VALUE_UNQUOTED:
+ for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ addAttributeWithValue();
+ state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE
+ * Switch to the before attribute name state.
+ */
+ addAttributeWithValue();
+ state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ continue stateloop;
+ case '&':
+ /*
+ * U+0026 AMPERSAND (&) Switch to the character
+ * reference in attribute value state, with the
+ * additional allowed character being U+003E
+ * GREATER-THAN SIGN (>)
+ */
+ assert charRefBufLen == 0: "charRefBufLen not reset after previous use!";
+ appendCharRefBuf(c);
+ setAdditionalAndRememberAmpersandLocation('>');
+ returnState = state;
+ state = transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos);
+ continue stateloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit the current
+ * tag token.
+ */
+ addAttributeWithValue();
+ state = transition(state, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ break stateloop;
+ }
+ /*
+ * Switch to the data state.
+ */
+ continue stateloop;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ case '<':
+ case '\"':
+ case '\'':
+ case '=':
+ case '`':
+ /*
+ * U+0022 QUOTATION MARK (") U+0027 APOSTROPHE
+ * (') U+003C LESS-THAN SIGN (<) U+003D EQUALS
+ * SIGN (=) U+0060 GRAVE ACCENT (`) Parse error.
+ */
+ errUnquotedAttributeValOrNull(c);
+ /*
+ * Treat it as per the "anything else" entry
+ * below.
+ */
+ // fall through
+ default:
+ // [NOCPP]
+ errHtml4NonNameInUnquotedAttribute(c);
+ // ]NOCPP]
+ /*
+ * Anything else Append the current input
+ * character to the current attribute's value.
+ */
+ appendStrBuf(c);
+ /*
+ * Stay in the attribute value (unquoted) state.
+ */
+ continue;
+ }
+ }
+ // XXX reorder point
+ case AFTER_ATTRIBUTE_NAME:
+ for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE Stay
+ * in the after attribute name state.
+ */
+ continue;
+ case '/':
+ /*
+ * U+002F SOLIDUS (/) Switch to the self-closing
+ * start tag state.
+ */
+ addAttributeWithoutValue();
+ state = transition(state, Tokenizer.SELF_CLOSING_START_TAG, reconsume, pos);
+ continue stateloop;
+ case '=':
+ /*
+ * U+003D EQUALS SIGN (=) Switch to the before
+ * attribute value state.
+ */
+ state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_VALUE, reconsume, pos);
+ continue stateloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit the current
+ * tag token.
+ */
+ addAttributeWithoutValue();
+ state = transition(state, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ break stateloop;
+ }
+ /*
+ * Switch to the data state.
+ */
+ continue stateloop;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ case '\"':
+ case '\'':
+ case '<':
+ errQuoteOrLtInAttributeNameOrNull(c);
+ /*
+ * Treat it as per the "anything else" entry
+ * below.
+ */
+ default:
+ addAttributeWithoutValue();
+ /*
+ * Anything else Start a new attribute in the
+ * current tag token.
+ */
+ if (c >= 'A' && c <= 'Z') {
+ /*
+ * U+0041 LATIN CAPITAL LETTER A through to
+ * U+005A LATIN CAPITAL LETTER Z Set that
+ * attribute's name to the lowercase version
+ * of the current input character (add
+ * 0x0020 to the character's code point)
+ */
+ c += 0x20;
+ }
+ /*
+ * Set that attribute's name to the current
+ * input character,
+ */
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ /*
+ * and its value to the empty string.
+ */
+ // Will do later.
+ /*
+ * Switch to the attribute name state.
+ */
+ state = transition(state, Tokenizer.ATTRIBUTE_NAME, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // XXX reorder point
+ case MARKUP_DECLARATION_OPEN:
+ markupdeclarationopenloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * If the next two characters are both U+002D
+ * HYPHEN-MINUS characters (-), consume those two
+ * characters, create a comment token whose data is the
+ * empty string, and switch to the comment start state.
+ *
+ * Otherwise, if the next seven characters are an ASCII
+ * case-insensitive match for the word "DOCTYPE", then
+ * consume those characters and switch to the DOCTYPE
+ * state.
+ *
+ * Otherwise, if the insertion mode is
+ * "in foreign content" and the current node is not an
+ * element in the HTML namespace and the next seven
+ * characters are an case-sensitive match for the string
+ * "[CDATA[" (the five uppercase letters "CDATA" with a
+ * U+005B LEFT SQUARE BRACKET character before and
+ * after), then consume those characters and switch to
+ * the CDATA section state.
+ *
+ * Otherwise, is is a parse error. Switch to the bogus
+ * comment state. The next character that is consumed,
+ * if any, is the first character that will be in the
+ * comment.
+ */
+ switch (c) {
+ case '-':
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ state = transition(state, Tokenizer.MARKUP_DECLARATION_HYPHEN, reconsume, pos);
+ break markupdeclarationopenloop;
+ // continue stateloop;
+ case 'd':
+ case 'D':
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ index = 0;
+ state = transition(state, Tokenizer.MARKUP_DECLARATION_OCTYPE, reconsume, pos);
+ continue stateloop;
+ case '[':
+ if (tokenHandler.cdataSectionAllowed()) {
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ index = 0;
+ state = transition(state, Tokenizer.CDATA_START, reconsume, pos);
+ continue stateloop;
+ }
+ // else fall through
+ default:
+ errBogusComment();
+ clearStrBufBeforeUse();
+ reconsume = true;
+ state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case MARKUP_DECLARATION_HYPHEN:
+ markupdeclarationhyphenloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ switch (c) {
+ case '\u0000':
+ break stateloop;
+ case '-':
+ clearStrBufAfterOneHyphen();
+ state = transition(state, Tokenizer.COMMENT_START, reconsume, pos);
+ break markupdeclarationhyphenloop;
+ // continue stateloop;
+ default:
+ errBogusComment();
+ reconsume = true;
+ state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case COMMENT_START:
+ commentstartloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Comment start state
+ *
+ *
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '-':
+ /*
+ * U+002D HYPHEN-MINUS (-) Switch to the comment
+ * start dash state.
+ */
+ appendStrBuf(c);
+ state = transition(state, Tokenizer.COMMENT_START_DASH, reconsume, pos);
+ continue stateloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Parse error.
+ */
+ errPrematureEndOfComment();
+ /* Emit the comment token. */
+ emitComment(0, pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '\r':
+ appendStrBufCarriageReturn();
+ state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+ break stateloop;
+ case '\n':
+ appendStrBufLineFeed();
+ state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+ break commentstartloop;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ /*
+ * Anything else Append the input character to
+ * the comment token's data.
+ */
+ appendStrBuf(c);
+ /*
+ * Switch to the comment state.
+ */
+ state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+ break commentstartloop;
+ // continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case COMMENT:
+ commentloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Comment state Consume the next input character:
+ */
+ switch (c) {
+ case '-':
+ /*
+ * U+002D HYPHEN-MINUS (-) Switch to the comment
+ * end dash state
+ */
+ appendStrBuf(c);
+ state = transition(state, Tokenizer.COMMENT_END_DASH, reconsume, pos);
+ break commentloop;
+ // continue stateloop;
+ case '\r':
+ appendStrBufCarriageReturn();
+ break stateloop;
+ case '\n':
+ appendStrBufLineFeed();
+ continue;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ /*
+ * Anything else Append the input character to
+ * the comment token's data.
+ */
+ appendStrBuf(c);
+ /*
+ * Stay in the comment state.
+ */
+ continue;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case COMMENT_END_DASH:
+ commentenddashloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Comment end dash state Consume the next input
+ * character:
+ */
+ switch (c) {
+ case '-':
+ /*
+ * U+002D HYPHEN-MINUS (-) Switch to the comment
+ * end state
+ */
+ appendStrBuf(c);
+ state = transition(state, Tokenizer.COMMENT_END, reconsume, pos);
+ break commentenddashloop;
+ // continue stateloop;
+ case '\r':
+ appendStrBufCarriageReturn();
+ state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+ break stateloop;
+ case '\n':
+ appendStrBufLineFeed();
+ state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+ continue stateloop;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ /*
+ * Anything else Append a U+002D HYPHEN-MINUS
+ * (-) character and the input character to the
+ * comment token's data.
+ */
+ appendStrBuf(c);
+ /*
+ * Switch to the comment state.
+ */
+ state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case COMMENT_END:
+ commentendloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Comment end dash state Consume the next input
+ * character:
+ */
+ switch (c) {
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit the comment
+ * token.
+ */
+ emitComment(2, pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '-':
+ /* U+002D HYPHEN-MINUS (-) Parse error. */
+ /*
+ * Append a U+002D HYPHEN-MINUS (-) character to
+ * the comment token's data.
+ */
+ adjustDoubleHyphenAndAppendToStrBufAndErr(c);
+ /*
+ * Stay in the comment end state.
+ */
+ continue;
+ case '\r':
+ adjustDoubleHyphenAndAppendToStrBufCarriageReturn();
+ state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+ break stateloop;
+ case '\n':
+ adjustDoubleHyphenAndAppendToStrBufLineFeed();
+ state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+ continue stateloop;
+ case '!':
+ errHyphenHyphenBang();
+ appendStrBuf(c);
+ state = transition(state, Tokenizer.COMMENT_END_BANG, reconsume, pos);
+ continue stateloop;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ /*
+ * Append two U+002D HYPHEN-MINUS (-) characters
+ * and the input character to the comment
+ * token's data.
+ */
+ adjustDoubleHyphenAndAppendToStrBufAndErr(c);
+ /*
+ * Switch to the comment state.
+ */
+ state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // XXX reorder point
+ case COMMENT_END_BANG:
+ for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Comment end bang state
+ *
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit the comment
+ * token.
+ */
+ emitComment(3, pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '-':
+ /*
+ * Append two U+002D HYPHEN-MINUS (-) characters
+ * and a U+0021 EXCLAMATION MARK (!) character
+ * to the comment token's data.
+ */
+ appendStrBuf(c);
+ /*
+ * Switch to the comment end dash state.
+ */
+ state = transition(state, Tokenizer.COMMENT_END_DASH, reconsume, pos);
+ continue stateloop;
+ case '\r':
+ appendStrBufCarriageReturn();
+ break stateloop;
+ case '\n':
+ appendStrBufLineFeed();
+ continue;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ /*
+ * Anything else Append two U+002D HYPHEN-MINUS
+ * (-) characters, a U+0021 EXCLAMATION MARK (!)
+ * character, and the input character to the
+ * comment token's data. Switch to the comment
+ * state.
+ */
+ appendStrBuf(c);
+ /*
+ * Switch to the comment state.
+ */
+ state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // XXX reorder point
+ case COMMENT_START_DASH:
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Comment start dash state
+ *
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '-':
+ /*
+ * U+002D HYPHEN-MINUS (-) Switch to the comment end
+ * state
+ */
+ appendStrBuf(c);
+ state = transition(state, Tokenizer.COMMENT_END, reconsume, pos);
+ continue stateloop;
+ case '>':
+ errPrematureEndOfComment();
+ /* Emit the comment token. */
+ emitComment(1, pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '\r':
+ appendStrBufCarriageReturn();
+ state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+ break stateloop;
+ case '\n':
+ appendStrBufLineFeed();
+ state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+ continue stateloop;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ /*
+ * Append a U+002D HYPHEN-MINUS character (-) and
+ * the current input character to the comment
+ * token's data.
+ */
+ appendStrBuf(c);
+ /*
+ * Switch to the comment state.
+ */
+ state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+ continue stateloop;
+ }
+ // XXX reorder point
+ case CDATA_START:
+ for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ if (index < 6) { // CDATA_LSQB.length
+ if (c == Tokenizer.CDATA_LSQB[index]) {
+ appendStrBuf(c);
+ } else {
+ errBogusComment();
+ reconsume = true;
+ state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
+ continue stateloop;
+ }
+ index++;
+ continue;
+ } else {
+ clearStrBufAfterUse();
+ cstart = pos; // start coalescing
+ reconsume = true;
+ state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos);
+ break; // FALL THROUGH continue stateloop;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case CDATA_SECTION:
+ cdatasectionloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ switch (c) {
+ case ']':
+ flushChars(buf, pos);
+ state = transition(state, Tokenizer.CDATA_RSQB, reconsume, pos);
+ break cdatasectionloop; // FALL THROUGH
+ case '\u0000':
+ emitReplacementCharacter(buf, pos);
+ continue;
+ case '\r':
+ emitCarriageReturn(buf, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ default:
+ continue;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case CDATA_RSQB:
+ cdatarsqb: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ switch (c) {
+ case ']':
+ state = transition(state, Tokenizer.CDATA_RSQB_RSQB, reconsume, pos);
+ break cdatarsqb;
+ default:
+ tokenHandler.characters(Tokenizer.RSQB_RSQB, 0,
+ 1);
+ cstart = pos;
+ reconsume = true;
+ state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case CDATA_RSQB_RSQB:
+ cdatarsqbrsqb: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ switch (c) {
+ case ']':
+ // Saw a third ]. Emit one ] (logically the
+ // first one) and stay in this state to
+ // remember that the last two characters seen
+ // have been ]].
+ tokenHandler.characters(Tokenizer.RSQB_RSQB, 0, 1);
+ continue;
+ case '>':
+ cstart = pos + 1;
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ default:
+ tokenHandler.characters(Tokenizer.RSQB_RSQB, 0, 2);
+ cstart = pos;
+ reconsume = true;
+ state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // XXX reorder point
+ case ATTRIBUTE_VALUE_SINGLE_QUOTED:
+ attributevaluesinglequotedloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\'':
+ /*
+ * U+0027 APOSTROPHE (') Switch to the after
+ * attribute value (quoted) state.
+ */
+ addAttributeWithValue();
+
+ state = transition(state, Tokenizer.AFTER_ATTRIBUTE_VALUE_QUOTED, reconsume, pos);
+ continue stateloop;
+ case '&':
+ /*
+ * U+0026 AMPERSAND (&) Switch to the character
+ * reference in attribute value state, with the
+ * + additional allowed character being U+0027
+ * APOSTROPHE (').
+ */
+ assert charRefBufLen == 0: "charRefBufLen not reset after previous use!";
+ appendCharRefBuf(c);
+ setAdditionalAndRememberAmpersandLocation('\'');
+ returnState = state;
+ state = transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos);
+ break attributevaluesinglequotedloop;
+ // continue stateloop;
+ case '\r':
+ appendStrBufCarriageReturn();
+ break stateloop;
+ case '\n':
+ appendStrBufLineFeed();
+ continue;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ /*
+ * Anything else Append the current input
+ * character to the current attribute's value.
+ */
+ appendStrBuf(c);
+ /*
+ * Stay in the attribute value (double-quoted)
+ * state.
+ */
+ continue;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case CONSUME_CHARACTER_REFERENCE:
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ if (c == '\u0000') {
+ break stateloop;
+ }
+ /*
+ * Unlike the definition is the spec, this state does not
+ * return a value and never requires the caller to
+ * backtrack. This state takes care of emitting characters
+ * or appending to the current attribute value. It also
+ * takes care of that in the case when consuming the
+ * character reference fails.
+ */
+ /*
+ * This section defines how to consume a character
+ * reference. This definition is used when parsing character
+ * references in text and in attributes.
+ *
+ * The behavior depends on the identity of the next
+ * character (the one immediately after the U+0026 AMPERSAND
+ * character):
+ */
+ switch (c) {
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r': // we'll reconsume!
+ case '\u000C':
+ case '<':
+ case '&':
+ emitOrAppendCharRefBuf(returnState);
+ if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = transition(state, returnState, reconsume, pos);
+ continue stateloop;
+ case '#':
+ /*
+ * U+0023 NUMBER SIGN (#) Consume the U+0023 NUMBER
+ * SIGN.
+ */
+ appendCharRefBuf('#');
+ state = transition(state, Tokenizer.CONSUME_NCR, reconsume, pos);
+ continue stateloop;
+ default:
+ if (c == additional) {
+ emitOrAppendCharRefBuf(returnState);
+ reconsume = true;
+ state = transition(state, returnState, reconsume, pos);
+ continue stateloop;
+ }
+ if (c >= 'a' && c <= 'z') {
+ firstCharKey = c - 'a' + 26;
+ } else if (c >= 'A' && c <= 'Z') {
+ firstCharKey = c - 'A';
+ } else {
+ // No match
+ /*
+ * If no match can be made, then this is a parse
+ * error.
+ */
+ errNoNamedCharacterMatch();
+ emitOrAppendCharRefBuf(returnState);
+ if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = transition(state, returnState, reconsume, pos);
+ continue stateloop;
+ }
+ // Didn't fail yet
+ appendCharRefBuf(c);
+ state = transition(state, Tokenizer.CHARACTER_REFERENCE_HILO_LOOKUP, reconsume, pos);
+ // FALL THROUGH continue stateloop;
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case CHARACTER_REFERENCE_HILO_LOOKUP:
+ {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ if (c == '\u0000') {
+ break stateloop;
+ }
+ /*
+ * The data structure is as follows:
+ *
+ * HILO_ACCEL is a two-dimensional int array whose major
+ * index corresponds to the second character of the
+ * character reference (code point as index) and the
+ * minor index corresponds to the first character of the
+ * character reference (packed so that A-Z runs from 0
+ * to 25 and a-z runs from 26 to 51). This layout makes
+ * it easier to use the sparseness of the data structure
+ * to omit parts of it: The second dimension of the
+ * table is null when no character reference starts with
+ * the character corresponding to that row.
+ *
+ * The int value HILO_ACCEL (by these indeces) is zero
+ * if there exists no character reference starting with
+ * that two-letter prefix. Otherwise, the value is an
+ * int that packs two shorts so that the higher short is
+ * the index of the highest character reference name
+ * with that prefix in NAMES and the lower short
+ * corresponds to the index of the lowest character
+ * reference name with that prefix. (It happens that the
+ * first two character reference names share their
+ * prefix so the packed int cannot be 0 by packing the
+ * two shorts.)
+ *
+ * NAMES is an array of byte arrays where each byte
+ * array encodes the name of a character references as
+ * ASCII. The names omit the first two letters of the
+ * name. (Since storing the first two letters would be
+ * redundant with the data contained in HILO_ACCEL.) The
+ * entries are lexically sorted.
+ *
+ * For a given index in NAMES, the same index in VALUES
+ * contains the corresponding expansion as an array of
+ * two UTF-16 code units (either the character and
+ * U+0000 or a suggogate pair).
+ */
+ int hilo = 0;
+ if (c <= 'z') {
+ @Const @NoLength int[] row = NamedCharactersAccel.HILO_ACCEL[c];
+ if (row != null) {
+ hilo = row[firstCharKey];
+ }
+ }
+ if (hilo == 0) {
+ /*
+ * If no match can be made, then this is a parse
+ * error.
+ */
+ errNoNamedCharacterMatch();
+ emitOrAppendCharRefBuf(returnState);
+ if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = transition(state, returnState, reconsume, pos);
+ continue stateloop;
+ }
+ // Didn't fail yet
+ appendCharRefBuf(c);
+ lo = hilo & 0xFFFF;
+ hi = hilo >> 16;
+ entCol = -1;
+ candidate = -1;
+ charRefBufMark = 0;
+ state = transition(state, Tokenizer.CHARACTER_REFERENCE_TAIL, reconsume, pos);
+ // FALL THROUGH continue stateloop;
+ }
+ case CHARACTER_REFERENCE_TAIL:
+ outer: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ if (c == '\u0000') {
+ break stateloop;
+ }
+ entCol++;
+ /*
+ * Consume the maximum number of characters possible,
+ * with the consumed characters matching one of the
+ * identifiers in the first column of the named
+ * character references table (in a case-sensitive
+ * manner).
+ */
+ loloop: for (;;) {
+ if (hi < lo) {
+ break outer;
+ }
+ if (entCol == NamedCharacters.NAMES[lo].length()) {
+ candidate = lo;
+ charRefBufMark = charRefBufLen;
+ lo++;
+ } else if (entCol > NamedCharacters.NAMES[lo].length()) {
+ break outer;
+ } else if (c > NamedCharacters.NAMES[lo].charAt(entCol)) {
+ lo++;
+ } else {
+ break loloop;
+ }
+ }
+
+ hiloop: for (;;) {
+ if (hi < lo) {
+ break outer;
+ }
+ if (entCol == NamedCharacters.NAMES[hi].length()) {
+ break hiloop;
+ }
+ if (entCol > NamedCharacters.NAMES[hi].length()) {
+ break outer;
+ } else if (c < NamedCharacters.NAMES[hi].charAt(entCol)) {
+ hi--;
+ } else {
+ break hiloop;
+ }
+ }
+
+ if (c == ';') {
+ // If we see a semicolon, there cannot be a
+ // longer match. Break the loop. However, before
+ // breaking, take the longest match so far as the
+ // candidate, if we are just about to complete a
+ // match.
+ if (entCol + 1 == NamedCharacters.NAMES[lo].length()) {
+ candidate = lo;
+ charRefBufMark = charRefBufLen;
+ }
+ break outer;
+ }
+
+ if (hi < lo) {
+ break outer;
+ }
+ appendCharRefBuf(c);
+ continue;
+ }
+
+ if (candidate == -1) {
+ // reconsume deals with CR, LF or nul
+ /*
+ * If no match can be made, then this is a parse error.
+ */
+ errNoNamedCharacterMatch();
+ emitOrAppendCharRefBuf(returnState);
+ if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = transition(state, returnState, reconsume, pos);
+ continue stateloop;
+ } else {
+ // c can't be CR, LF or nul if we got here
+ @Const @CharacterName String candidateName = NamedCharacters.NAMES[candidate];
+ if (candidateName.length() == 0
+ || candidateName.charAt(candidateName.length() - 1) != ';') {
+ /*
+ * If the last character matched is not a U+003B
+ * SEMICOLON (;), there is a parse error.
+ */
+ if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
+ /*
+ * If the entity is being consumed as part of an
+ * attribute, and the last character matched is
+ * not a U+003B SEMICOLON (;),
+ */
+ char ch;
+ if (charRefBufMark == charRefBufLen) {
+ ch = c;
+ } else {
+ ch = charRefBuf[charRefBufMark];
+ }
+ if (ch == '=' || (ch >= '0' && ch <= '9')
+ || (ch >= 'A' && ch <= 'Z')
+ || (ch >= 'a' && ch <= 'z')) {
+ /*
+ * and the next character is either a U+003D
+ * EQUALS SIGN character (=) or in the range
+ * U+0030 DIGIT ZERO to U+0039 DIGIT NINE,
+ * U+0041 LATIN CAPITAL LETTER A to U+005A
+ * LATIN CAPITAL LETTER Z, or U+0061 LATIN
+ * SMALL LETTER A to U+007A LATIN SMALL
+ * LETTER Z, then, for historical reasons,
+ * all the characters that were matched
+ * after the U+0026 AMPERSAND (&) must be
+ * unconsumed, and nothing is returned.
+ */
+ errNoNamedCharacterMatch();
+ appendCharRefBufToStrBuf();
+ reconsume = true;
+ state = transition(state, returnState, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
+ errUnescapedAmpersandInterpretedAsCharacterReference();
+ } else {
+ errNotSemicolonTerminated();
+ }
+ }
+
+ /*
+ * Otherwise, return a character token for the character
+ * corresponding to the entity name (as given by the
+ * second column of the named character references
+ * table).
+ */
+ // CPPONLY: completedNamedCharacterReference();
+ @Const @NoLength char[] val = NamedCharacters.VALUES[candidate];
+ if (
+ // [NOCPP[
+ val.length == 1
+ // ]NOCPP]
+ // CPPONLY: val[1] == 0
+ ) {
+ emitOrAppendOne(val, returnState);
+ } else {
+ emitOrAppendTwo(val, returnState);
+ }
+ // this is so complicated!
+ if (charRefBufMark < charRefBufLen) {
+ if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
+ appendStrBuf(charRefBuf, charRefBufMark,
+ charRefBufLen - charRefBufMark);
+ } else {
+ tokenHandler.characters(charRefBuf, charRefBufMark,
+ charRefBufLen - charRefBufMark);
+ }
+ }
+ // charRefBufLen will be zeroed below!
+
+ // Check if we broke out early with c being the last
+ // character that matched as opposed to being the
+ // first one that didn't match. In the case of an
+ // early break, the next run on text should start
+ // *after* the current character and the current
+ // character shouldn't be reconsumed.
+ boolean earlyBreak = (c == ';' && charRefBufMark == charRefBufLen);
+ charRefBufLen = 0;
+ if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
+ cstart = earlyBreak ? pos + 1 : pos;
+ }
+ reconsume = !earlyBreak;
+ state = transition(state, returnState, reconsume, pos);
+ continue stateloop;
+ /*
+ * If the markup contains I'm &notit; I tell you, the
+ * entity is parsed as "not", as in, I'm ¬it; I tell
+ * you. But if the markup was I'm &notin; I tell you,
+ * the entity would be parsed as "notin;", resulting in
+ * I'm ∉ I tell you.
+ */
+ }
+ // XXX reorder point
+ case CONSUME_NCR:
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ value = 0;
+ seenDigits = false;
+ /*
+ * The behavior further depends on the character after the
+ * U+0023 NUMBER SIGN:
+ */
+ switch (c) {
+ case 'x':
+ case 'X':
+
+ /*
+ * U+0078 LATIN SMALL LETTER X U+0058 LATIN CAPITAL
+ * LETTER X Consume the X.
+ *
+ * Follow the steps below, but using the range of
+ * characters U+0030 DIGIT ZERO through to U+0039
+ * DIGIT NINE, U+0061 LATIN SMALL LETTER A through
+ * to U+0066 LATIN SMALL LETTER F, and U+0041 LATIN
+ * CAPITAL LETTER A, through to U+0046 LATIN CAPITAL
+ * LETTER F (in other words, 0-9, A-F, a-f).
+ *
+ * When it comes to interpreting the number,
+ * interpret it as a hexadecimal number.
+ */
+ appendCharRefBuf(c);
+ state = transition(state, Tokenizer.HEX_NCR_LOOP, reconsume, pos);
+ continue stateloop;
+ default:
+ /*
+ * Anything else Follow the steps below, but using
+ * the range of characters U+0030 DIGIT ZERO through
+ * to U+0039 DIGIT NINE (i.e. just 0-9).
+ *
+ * When it comes to interpreting the number,
+ * interpret it as a decimal number.
+ */
+ reconsume = true;
+ state = transition(state, Tokenizer.DECIMAL_NRC_LOOP, reconsume, pos);
+ // FALL THROUGH continue stateloop;
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case DECIMAL_NRC_LOOP:
+ decimalloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ /*
+ * Consume as many characters as match the range of
+ * characters given above.
+ */
+ assert value >= 0: "value must not become negative.";
+ if (c >= '0' && c <= '9') {
+ seenDigits = true;
+ // Avoid overflow
+ if (value <= 0x10FFFF) {
+ value *= 10;
+ value += c - '0';
+ }
+ continue;
+ } else if (c == ';') {
+ if (seenDigits) {
+ if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
+ cstart = pos + 1;
+ }
+ state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos);
+ // FALL THROUGH continue stateloop;
+ break decimalloop;
+ } else {
+ errNoDigitsInNCR();
+ appendCharRefBuf(';');
+ emitOrAppendCharRefBuf(returnState);
+ if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
+ cstart = pos + 1;
+ }
+ state = transition(state, returnState, reconsume, pos);
+ continue stateloop;
+ }
+ } else {
+ /*
+ * If no characters match the range, then don't
+ * consume any characters (and unconsume the U+0023
+ * NUMBER SIGN character and, if appropriate, the X
+ * character). This is a parse error; nothing is
+ * returned.
+ *
+ * Otherwise, if the next character is a U+003B
+ * SEMICOLON, consume that too. If it isn't, there
+ * is a parse error.
+ */
+ if (!seenDigits) {
+ errNoDigitsInNCR();
+ emitOrAppendCharRefBuf(returnState);
+ if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = transition(state, returnState, reconsume, pos);
+ continue stateloop;
+ } else {
+ errCharRefLacksSemicolon();
+ if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos);
+ // FALL THROUGH continue stateloop;
+ break decimalloop;
+ }
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case HANDLE_NCR_VALUE:
+ // WARNING previous state sets reconsume
+ // We are not going to emit the contents of charRefBuf.
+ charRefBufLen = 0;
+ // XXX inline this case if the method size can take it
+ handleNcrValue(returnState);
+ state = transition(state, returnState, reconsume, pos);
+ continue stateloop;
+ // XXX reorder point
+ case HEX_NCR_LOOP:
+ for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume as many characters as match the range of
+ * characters given above.
+ */
+ assert value >= 0: "value must not become negative.";
+ if (c >= '0' && c <= '9') {
+ seenDigits = true;
+ // Avoid overflow
+ if (value <= 0x10FFFF) {
+ value *= 16;
+ value += c - '0';
+ }
+ continue;
+ } else if (c >= 'A' && c <= 'F') {
+ seenDigits = true;
+ // Avoid overflow
+ if (value <= 0x10FFFF) {
+ value *= 16;
+ value += c - 'A' + 10;
+ }
+ continue;
+ } else if (c >= 'a' && c <= 'f') {
+ seenDigits = true;
+ // Avoid overflow
+ if (value <= 0x10FFFF) {
+ value *= 16;
+ value += c - 'a' + 10;
+ }
+ continue;
+ } else if (c == ';') {
+ if (seenDigits) {
+ if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
+ cstart = pos + 1;
+ }
+ state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos);
+ continue stateloop;
+ } else {
+ errNoDigitsInNCR();
+ appendCharRefBuf(';');
+ emitOrAppendCharRefBuf(returnState);
+ if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
+ cstart = pos + 1;
+ }
+ state = transition(state, returnState, reconsume, pos);
+ continue stateloop;
+ }
+ } else {
+ /*
+ * If no characters match the range, then don't
+ * consume any characters (and unconsume the U+0023
+ * NUMBER SIGN character and, if appropriate, the X
+ * character). This is a parse error; nothing is
+ * returned.
+ *
+ * Otherwise, if the next character is a U+003B
+ * SEMICOLON, consume that too. If it isn't, there
+ * is a parse error.
+ */
+ if (!seenDigits) {
+ errNoDigitsInNCR();
+ emitOrAppendCharRefBuf(returnState);
+ if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = transition(state, returnState, reconsume, pos);
+ continue stateloop;
+ } else {
+ errCharRefLacksSemicolon();
+ if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ }
+ // XXX reorder point
+ case PLAINTEXT:
+ plaintextloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ switch (c) {
+ case '\u0000':
+ emitPlaintextReplacementCharacter(buf, pos);
+ continue;
+ case '\r':
+ emitCarriageReturn(buf, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ default:
+ /*
+ * Anything else Emit the current input
+ * character as a character token. Stay in the
+ * RAWTEXT state.
+ */
+ continue;
+ }
+ }
+ // XXX reorder point
+ case CLOSE_TAG_OPEN:
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Otherwise, if the content model flag is set to the PCDATA
+ * state, or if the next few characters do match that tag
+ * name, consume the next input character:
+ */
+ switch (c) {
+ case '>':
+ /* U+003E GREATER-THAN SIGN (>) Parse error. */
+ errLtSlashGt();
+ /*
+ * Switch to the data state.
+ */
+ cstart = pos + 1;
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '\r':
+ silentCarriageReturn();
+ /* Anything else Parse error. */
+ errGarbageAfterLtSlash();
+ /*
+ * Switch to the bogus comment state.
+ */
+ clearStrBufBeforeUse();
+ appendStrBuf('\n');
+ state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ /* Anything else Parse error. */
+ errGarbageAfterLtSlash();
+ /*
+ * Switch to the bogus comment state.
+ */
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
+ continue stateloop;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ if (c >= 'A' && c <= 'Z') {
+ c += 0x20;
+ }
+ if (c >= 'a' && c <= 'z') {
+ /*
+ * U+0061 LATIN SMALL LETTER A through to U+007A
+ * LATIN SMALL LETTER Z Create a new end tag
+ * token,
+ */
+ endTag = true;
+ /*
+ * set its tag name to the input character,
+ */
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ /*
+ * then switch to the tag name state. (Don't
+ * emit the token yet; further details will be
+ * filled in before it is emitted.)
+ */
+ state = transition(state, Tokenizer.TAG_NAME, reconsume, pos);
+ continue stateloop;
+ } else {
+ /* Anything else Parse error. */
+ errGarbageAfterLtSlash();
+ /*
+ * Switch to the bogus comment state.
+ */
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // XXX reorder point
+ case RCDATA:
+ rcdataloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ switch (c) {
+ case '&':
+ /*
+ * U+0026 AMPERSAND (&) Switch to the character
+ * reference in RCDATA state.
+ */
+ flushChars(buf, pos);
+ assert charRefBufLen == 0: "charRefBufLen not reset after previous use!";
+ appendCharRefBuf(c);
+ setAdditionalAndRememberAmpersandLocation('\u0000');
+ returnState = state;
+ state = transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos);
+ continue stateloop;
+ case '<':
+ /*
+ * U+003C LESS-THAN SIGN (<) Switch to the
+ * RCDATA less-than sign state.
+ */
+ flushChars(buf, pos);
+
+ returnState = state;
+ state = transition(state, Tokenizer.RAWTEXT_RCDATA_LESS_THAN_SIGN, reconsume, pos);
+ continue stateloop;
+ case '\u0000':
+ emitReplacementCharacter(buf, pos);
+ continue;
+ case '\r':
+ emitCarriageReturn(buf, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ default:
+ /*
+ * Emit the current input character as a
+ * character token. Stay in the RCDATA state.
+ */
+ continue;
+ }
+ }
+ // XXX reorder point
+ case RAWTEXT:
+ rawtextloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ switch (c) {
+ case '<':
+ /*
+ * U+003C LESS-THAN SIGN (<) Switch to the
+ * RAWTEXT less-than sign state.
+ */
+ flushChars(buf, pos);
+
+ returnState = state;
+ state = transition(state, Tokenizer.RAWTEXT_RCDATA_LESS_THAN_SIGN, reconsume, pos);
+ break rawtextloop;
+ // FALL THRU continue stateloop;
+ case '\u0000':
+ emitReplacementCharacter(buf, pos);
+ continue;
+ case '\r':
+ emitCarriageReturn(buf, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ default:
+ /*
+ * Emit the current input character as a
+ * character token. Stay in the RAWTEXT state.
+ */
+ continue;
+ }
+ }
+ // XXX fallthru don't reorder
+ case RAWTEXT_RCDATA_LESS_THAN_SIGN:
+ rawtextrcdatalessthansignloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ switch (c) {
+ case '/':
+ /*
+ * U+002F SOLIDUS (/) Set the temporary buffer
+ * to the empty string. Switch to the script
+ * data end tag open state.
+ */
+ index = 0;
+ clearStrBufBeforeUse();
+ state = transition(state, Tokenizer.NON_DATA_END_TAG_NAME, reconsume, pos);
+ break rawtextrcdatalessthansignloop;
+ // FALL THRU continue stateloop;
+ default:
+ /*
+ * Otherwise, emit a U+003C LESS-THAN SIGN
+ * character token
+ */
+ tokenHandler.characters(Tokenizer.LT_GT, 0, 1);
+ /*
+ * and reconsume the current input character in
+ * the data state.
+ */
+ cstart = pos;
+ reconsume = true;
+ state = transition(state, returnState, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // XXX fall thru. don't reorder.
+ case NON_DATA_END_TAG_NAME:
+ for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * ASSERT! when entering this state, set index to 0 and
+ * call clearStrBufBeforeUse() assert (contentModelElement !=
+ * null); Let's implement the above without lookahead.
+ * strBuf is the 'temporary buffer'.
+ */
+ if (index < endTagExpectationAsArray.length) {
+ char e = endTagExpectationAsArray[index];
+ char folded = c;
+ if (c >= 'A' && c <= 'Z') {
+ folded += 0x20;
+ }
+ if (folded != e) {
+ // [NOCPP[
+ errHtml4LtSlashInRcdata(folded);
+ // ]NOCPP]
+ tokenHandler.characters(Tokenizer.LT_SOLIDUS,
+ 0, 2);
+ emitStrBuf();
+ cstart = pos;
+ reconsume = true;
+ state = transition(state, returnState, reconsume, pos);
+ continue stateloop;
+ }
+ appendStrBuf(c);
+ index++;
+ continue;
+ } else {
+ endTag = true;
+ // XXX replace contentModelElement with different
+ // type
+ tagName = endTagExpectation;
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ clearStrBufAfterUse(); // strBuf not used
+ state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE
+ * FEED (LF) U+000C FORM FEED (FF) U+0020
+ * SPACE If the current end tag token is an
+ * appropriate end tag token, then switch to
+ * the before attribute name state.
+ */
+ clearStrBufAfterUse(); // strBuf not used
+ state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ continue stateloop;
+ case '/':
+ /*
+ * U+002F SOLIDUS (/) If the current end tag
+ * token is an appropriate end tag token,
+ * then switch to the self-closing start tag
+ * state.
+ */
+ clearStrBufAfterUse(); // strBuf not used
+ state = transition(state, Tokenizer.SELF_CLOSING_START_TAG, reconsume, pos);
+ continue stateloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) If the
+ * current end tag token is an appropriate
+ * end tag token, then emit the current tag
+ * token and switch to the data state.
+ */
+ clearStrBufAfterUse(); // strBuf not used
+ state = transition(state, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ break stateloop;
+ }
+ continue stateloop;
+ default:
+ /*
+ * Emit a U+003C LESS-THAN SIGN character
+ * token, a U+002F SOLIDUS character token,
+ * a character token for each of the
+ * characters in the temporary buffer (in
+ * the order they were added to the buffer),
+ * and reconsume the current input character
+ * in the RAWTEXT state.
+ */
+ // [NOCPP[
+ errWarnLtSlashInRcdata();
+ // ]NOCPP]
+ tokenHandler.characters(
+ Tokenizer.LT_SOLIDUS, 0, 2);
+ emitStrBuf();
+ if (c == '\u0000') {
+ emitReplacementCharacter(buf, pos);
+ } else {
+ cstart = pos; // don't drop the
+ // character
+ }
+ state = transition(state, returnState, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ }
+ // XXX reorder point
+ // BEGIN HOTSPOT WORKAROUND
+ case BOGUS_COMMENT:
+ boguscommentloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ /*
+ * Consume every character up to and including the first
+ * U+003E GREATER-THAN SIGN character (>) or the end of
+ * the file (EOF), whichever comes first. Emit a comment
+ * token whose data is the concatenation of all the
+ * characters starting from and including the character
+ * that caused the state machine to switch into the
+ * bogus comment state, up to and including the
+ * character immediately before the last consumed
+ * character (i.e. up to the character just before the
+ * U+003E or EOF character). (If the comment was started
+ * by the end of the file (EOF), the token is empty.)
+ *
+ * Switch to the data state.
+ *
+ * If the end of the file was reached, reconsume the EOF
+ * character.
+ */
+ switch (c) {
+ case '>':
+ emitComment(0, pos);
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '-':
+ appendStrBuf(c);
+ state = transition(state, Tokenizer.BOGUS_COMMENT_HYPHEN, reconsume, pos);
+ break boguscommentloop;
+ case '\r':
+ appendStrBufCarriageReturn();
+ break stateloop;
+ case '\n':
+ appendStrBufLineFeed();
+ continue;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ appendStrBuf(c);
+ continue;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case BOGUS_COMMENT_HYPHEN:
+ boguscommenthyphenloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ switch (c) {
+ case '>':
+ // [NOCPP[
+ maybeAppendSpaceToBogusComment();
+ // ]NOCPP]
+ emitComment(0, pos);
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '-':
+ appendSecondHyphenToBogusComment();
+ continue boguscommenthyphenloop;
+ case '\r':
+ appendStrBufCarriageReturn();
+ state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
+ break stateloop;
+ case '\n':
+ appendStrBufLineFeed();
+ state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
+ continue stateloop;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ appendStrBuf(c);
+ state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // XXX reorder point
+ case SCRIPT_DATA:
+ scriptdataloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ switch (c) {
+ case '<':
+ /*
+ * U+003C LESS-THAN SIGN (<) Switch to the
+ * script data less-than sign state.
+ */
+ flushChars(buf, pos);
+ returnState = state;
+ state = transition(state, Tokenizer.SCRIPT_DATA_LESS_THAN_SIGN, reconsume, pos);
+ break scriptdataloop; // FALL THRU continue
+ // stateloop;
+ case '\u0000':
+ emitReplacementCharacter(buf, pos);
+ continue;
+ case '\r':
+ emitCarriageReturn(buf, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ default:
+ /*
+ * Anything else Emit the current input
+ * character as a character token. Stay in the
+ * script data state.
+ */
+ continue;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case SCRIPT_DATA_LESS_THAN_SIGN:
+ scriptdatalessthansignloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ switch (c) {
+ case '/':
+ /*
+ * U+002F SOLIDUS (/) Set the temporary buffer
+ * to the empty string. Switch to the script
+ * data end tag open state.
+ */
+ index = 0;
+ clearStrBufBeforeUse();
+ state = transition(state, Tokenizer.NON_DATA_END_TAG_NAME, reconsume, pos);
+ continue stateloop;
+ case '!':
+ tokenHandler.characters(Tokenizer.LT_GT, 0, 1);
+ cstart = pos;
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPE_START, reconsume, pos);
+ break scriptdatalessthansignloop; // FALL THRU
+ // continue
+ // stateloop;
+ default:
+ /*
+ * Otherwise, emit a U+003C LESS-THAN SIGN
+ * character token
+ */
+ tokenHandler.characters(Tokenizer.LT_GT, 0, 1);
+ /*
+ * and reconsume the current input character in
+ * the data state.
+ */
+ cstart = pos;
+ reconsume = true;
+ state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case SCRIPT_DATA_ESCAPE_START:
+ scriptdataescapestartloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '-':
+ /*
+ * U+002D HYPHEN-MINUS (-) Emit a U+002D
+ * HYPHEN-MINUS character token. Switch to the
+ * script data escape start dash state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPE_START_DASH, reconsume, pos);
+ break scriptdataescapestartloop; // FALL THRU
+ // continue
+ // stateloop;
+ default:
+ /*
+ * Anything else Reconsume the current input
+ * character in the script data state.
+ */
+ reconsume = true;
+ state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case SCRIPT_DATA_ESCAPE_START_DASH:
+ scriptdataescapestartdashloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '-':
+ /*
+ * U+002D HYPHEN-MINUS (-) Emit a U+002D
+ * HYPHEN-MINUS character token. Switch to the
+ * script data escaped dash dash state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED_DASH_DASH, reconsume, pos);
+ break scriptdataescapestartdashloop;
+ // continue stateloop;
+ default:
+ /*
+ * Anything else Reconsume the current input
+ * character in the script data state.
+ */
+ reconsume = true;
+ state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case SCRIPT_DATA_ESCAPED_DASH_DASH:
+ scriptdataescapeddashdashloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '-':
+ /*
+ * U+002D HYPHEN-MINUS (-) Emit a U+002D
+ * HYPHEN-MINUS character token. Stay in the
+ * script data escaped dash dash state.
+ */
+ continue;
+ case '<':
+ /*
+ * U+003C LESS-THAN SIGN (<) Switch to the
+ * script data escaped less-than sign state.
+ */
+ flushChars(buf, pos);
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN, reconsume, pos);
+ continue stateloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit a U+003E
+ * GREATER-THAN SIGN character token. Switch to
+ * the script data state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos);
+ continue stateloop;
+ case '\u0000':
+ emitReplacementCharacter(buf, pos);
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos);
+ break scriptdataescapeddashdashloop;
+ case '\r':
+ emitCarriageReturn(buf, pos);
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ default:
+ /*
+ * Anything else Emit the current input
+ * character as a character token. Switch to the
+ * script data escaped state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos);
+ break scriptdataescapeddashdashloop;
+ // continue stateloop;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case SCRIPT_DATA_ESCAPED:
+ scriptdataescapedloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '-':
+ /*
+ * U+002D HYPHEN-MINUS (-) Emit a U+002D
+ * HYPHEN-MINUS character token. Switch to the
+ * script data escaped dash state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED_DASH, reconsume, pos);
+ break scriptdataescapedloop; // FALL THRU
+ // continue
+ // stateloop;
+ case '<':
+ /*
+ * U+003C LESS-THAN SIGN (<) Switch to the
+ * script data escaped less-than sign state.
+ */
+ flushChars(buf, pos);
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN, reconsume, pos);
+ continue stateloop;
+ case '\u0000':
+ emitReplacementCharacter(buf, pos);
+ continue;
+ case '\r':
+ emitCarriageReturn(buf, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ default:
+ /*
+ * Anything else Emit the current input
+ * character as a character token. Stay in the
+ * script data escaped state.
+ */
+ continue;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case SCRIPT_DATA_ESCAPED_DASH:
+ scriptdataescapeddashloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '-':
+ /*
+ * U+002D HYPHEN-MINUS (-) Emit a U+002D
+ * HYPHEN-MINUS character token. Switch to the
+ * script data escaped dash dash state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED_DASH_DASH, reconsume, pos);
+ continue stateloop;
+ case '<':
+ /*
+ * U+003C LESS-THAN SIGN (<) Switch to the
+ * script data escaped less-than sign state.
+ */
+ flushChars(buf, pos);
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN, reconsume, pos);
+ break scriptdataescapeddashloop;
+ // continue stateloop;
+ case '\u0000':
+ emitReplacementCharacter(buf, pos);
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos);
+ continue stateloop;
+ case '\r':
+ emitCarriageReturn(buf, pos);
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ default:
+ /*
+ * Anything else Emit the current input
+ * character as a character token. Switch to the
+ * script data escaped state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:
+ scriptdataescapedlessthanloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '/':
+ /*
+ * U+002F SOLIDUS (/) Set the temporary buffer
+ * to the empty string. Switch to the script
+ * data escaped end tag open state.
+ */
+ index = 0;
+ clearStrBufBeforeUse();
+ returnState = Tokenizer.SCRIPT_DATA_ESCAPED;
+ state = transition(state, Tokenizer.NON_DATA_END_TAG_NAME, reconsume, pos);
+ continue stateloop;
+ case 'S':
+ case 's':
+ /*
+ * U+0041 LATIN CAPITAL LETTER A through to
+ * U+005A LATIN CAPITAL LETTER Z Emit a U+003C
+ * LESS-THAN SIGN character token and the
+ * current input character as a character token.
+ */
+ tokenHandler.characters(Tokenizer.LT_GT, 0, 1);
+ cstart = pos;
+ index = 1;
+ /*
+ * Set the temporary buffer to the empty string.
+ * Append the lowercase version of the current
+ * input character (add 0x0020 to the
+ * character's code point) to the temporary
+ * buffer. Switch to the script data double
+ * escape start state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPE_START, reconsume, pos);
+ break scriptdataescapedlessthanloop;
+ // continue stateloop;
+ default:
+ /*
+ * Anything else Emit a U+003C LESS-THAN SIGN
+ * character token and reconsume the current
+ * input character in the script data escaped
+ * state.
+ */
+ tokenHandler.characters(Tokenizer.LT_GT, 0, 1);
+ cstart = pos;
+ reconsume = true;
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case SCRIPT_DATA_DOUBLE_ESCAPE_START:
+ scriptdatadoubleescapestartloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ assert index > 0;
+ if (index < 6) { // SCRIPT_ARR.length
+ char folded = c;
+ if (c >= 'A' && c <= 'Z') {
+ folded += 0x20;
+ }
+ if (folded != Tokenizer.SCRIPT_ARR[index]) {
+ reconsume = true;
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos);
+ continue stateloop;
+ }
+ index++;
+ continue;
+ }
+ switch (c) {
+ case '\r':
+ emitCarriageReturn(buf, pos);
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ case ' ':
+ case '\t':
+ case '\u000C':
+ case '/':
+ case '>':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE
+ * U+002F SOLIDUS (/) U+003E GREATER-THAN SIGN
+ * (>) Emit the current input character as a
+ * character token. If the temporary buffer is
+ * the string "script", then switch to the
+ * script data double escaped state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ break scriptdatadoubleescapestartloop;
+ // continue stateloop;
+ default:
+ /*
+ * Anything else Reconsume the current input
+ * character in the script data escaped state.
+ */
+ reconsume = true;
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case SCRIPT_DATA_DOUBLE_ESCAPED:
+ scriptdatadoubleescapedloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '-':
+ /*
+ * U+002D HYPHEN-MINUS (-) Emit a U+002D
+ * HYPHEN-MINUS character token. Switch to the
+ * script data double escaped dash state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED_DASH, reconsume, pos);
+ break scriptdatadoubleescapedloop; // FALL THRU
+ // continue
+ // stateloop;
+ case '<':
+ /*
+ * U+003C LESS-THAN SIGN (<) Emit a U+003C
+ * LESS-THAN SIGN character token. Switch to the
+ * script data double escaped less-than sign
+ * state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN, reconsume, pos);
+ continue stateloop;
+ case '\u0000':
+ emitReplacementCharacter(buf, pos);
+ continue;
+ case '\r':
+ emitCarriageReturn(buf, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ default:
+ /*
+ * Anything else Emit the current input
+ * character as a character token. Stay in the
+ * script data double escaped state.
+ */
+ continue;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case SCRIPT_DATA_DOUBLE_ESCAPED_DASH:
+ scriptdatadoubleescapeddashloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '-':
+ /*
+ * U+002D HYPHEN-MINUS (-) Emit a U+002D
+ * HYPHEN-MINUS character token. Switch to the
+ * script data double escaped dash dash state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH, reconsume, pos);
+ break scriptdatadoubleescapeddashloop;
+ // continue stateloop;
+ case '<':
+ /*
+ * U+003C LESS-THAN SIGN (<) Emit a U+003C
+ * LESS-THAN SIGN character token. Switch to the
+ * script data double escaped less-than sign
+ * state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN, reconsume, pos);
+ continue stateloop;
+ case '\u0000':
+ emitReplacementCharacter(buf, pos);
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ continue stateloop;
+ case '\r':
+ emitCarriageReturn(buf, pos);
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ default:
+ /*
+ * Anything else Emit the current input
+ * character as a character token. Switch to the
+ * script data double escaped state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:
+ scriptdatadoubleescapeddashdashloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '-':
+ /*
+ * U+002D HYPHEN-MINUS (-) Emit a U+002D
+ * HYPHEN-MINUS character token. Stay in the
+ * script data double escaped dash dash state.
+ */
+ continue;
+ case '<':
+ /*
+ * U+003C LESS-THAN SIGN (<) Emit a U+003C
+ * LESS-THAN SIGN character token. Switch to the
+ * script data double escaped less-than sign
+ * state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN, reconsume, pos);
+ break scriptdatadoubleescapeddashdashloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit a U+003E
+ * GREATER-THAN SIGN character token. Switch to
+ * the script data state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos);
+ continue stateloop;
+ case '\u0000':
+ emitReplacementCharacter(buf, pos);
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ continue stateloop;
+ case '\r':
+ emitCarriageReturn(buf, pos);
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ default:
+ /*
+ * Anything else Emit the current input
+ * character as a character token. Switch to the
+ * script data double escaped state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:
+ scriptdatadoubleescapedlessthanloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '/':
+ /*
+ * U+002F SOLIDUS (/) Emit a U+002F SOLIDUS
+ * character token. Set the temporary buffer to
+ * the empty string. Switch to the script data
+ * double escape end state.
+ */
+ index = 0;
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPE_END, reconsume, pos);
+ break scriptdatadoubleescapedlessthanloop;
+ default:
+ /*
+ * Anything else Reconsume the current input
+ * character in the script data double escaped
+ * state.
+ */
+ reconsume = true;
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+ case SCRIPT_DATA_DOUBLE_ESCAPE_END:
+ scriptdatadoubleescapeendloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ if (index < 6) { // SCRIPT_ARR.length
+ char folded = c;
+ if (c >= 'A' && c <= 'Z') {
+ folded += 0x20;
+ }
+ if (folded != Tokenizer.SCRIPT_ARR[index]) {
+ reconsume = true;
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ continue stateloop;
+ }
+ index++;
+ continue;
+ }
+ switch (c) {
+ case '\r':
+ emitCarriageReturn(buf, pos);
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ case ' ':
+ case '\t':
+ case '\u000C':
+ case '/':
+ case '>':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE
+ * U+002F SOLIDUS (/) U+003E GREATER-THAN SIGN
+ * (>) Emit the current input character as a
+ * character token. If the temporary buffer is
+ * the string "script", then switch to the
+ * script data escaped state.
+ */
+ state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos);
+ continue stateloop;
+ default:
+ /*
+ * Reconsume the current input character in the
+ * script data double escaped state.
+ */
+ reconsume = true;
+ state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // XXX reorder point
+ case MARKUP_DECLARATION_OCTYPE:
+ markupdeclarationdoctypeloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ if (index < 6) { // OCTYPE.length
+ char folded = c;
+ if (c >= 'A' && c <= 'Z') {
+ folded += 0x20;
+ }
+ if (folded == Tokenizer.OCTYPE[index]) {
+ appendStrBuf(c);
+ } else {
+ errBogusComment();
+ reconsume = true;
+ state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
+ continue stateloop;
+ }
+ index++;
+ continue;
+ } else {
+ reconsume = true;
+ state = transition(state, Tokenizer.DOCTYPE, reconsume, pos);
+ break markupdeclarationdoctypeloop;
+ // continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case DOCTYPE:
+ doctypeloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ initDoctypeFields();
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ state = transition(state, Tokenizer.BEFORE_DOCTYPE_NAME, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE
+ * Switch to the before DOCTYPE name state.
+ */
+ state = transition(state, Tokenizer.BEFORE_DOCTYPE_NAME, reconsume, pos);
+ break doctypeloop;
+ // continue stateloop;
+ default:
+ /*
+ * Anything else Parse error.
+ */
+ errMissingSpaceBeforeDoctypeName();
+ /*
+ * Reconsume the current character in the before
+ * DOCTYPE name state.
+ */
+ reconsume = true;
+ state = transition(state, Tokenizer.BEFORE_DOCTYPE_NAME, reconsume, pos);
+ break doctypeloop;
+ // continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case BEFORE_DOCTYPE_NAME:
+ beforedoctypenameloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE Stay
+ * in the before DOCTYPE name state.
+ */
+ continue;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Parse error.
+ */
+ errNamelessDoctype();
+ /*
+ * Create a new DOCTYPE token. Set its
+ * force-quirks flag to on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit the token.
+ */
+ emitDoctypeToken(pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ if (c >= 'A' && c <= 'Z') {
+ /*
+ * U+0041 LATIN CAPITAL LETTER A through to
+ * U+005A LATIN CAPITAL LETTER Z Create a
+ * new DOCTYPE token. Set the token's name
+ * to the lowercase version of the input
+ * character (add 0x0020 to the character's
+ * code point).
+ */
+ c += 0x20;
+ }
+ /* Anything else Create a new DOCTYPE token. */
+ /*
+ * Set the token's name name to the current
+ * input character.
+ */
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ /*
+ * Switch to the DOCTYPE name state.
+ */
+ state = transition(state, Tokenizer.DOCTYPE_NAME, reconsume, pos);
+ break beforedoctypenameloop;
+ // continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case DOCTYPE_NAME:
+ doctypenameloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ strBufToDoctypeName();
+ state = transition(state, Tokenizer.AFTER_DOCTYPE_NAME, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE
+ * Switch to the after DOCTYPE name state.
+ */
+ strBufToDoctypeName();
+ state = transition(state, Tokenizer.AFTER_DOCTYPE_NAME, reconsume, pos);
+ break doctypenameloop;
+ // continue stateloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit the current
+ * DOCTYPE token.
+ */
+ strBufToDoctypeName();
+ emitDoctypeToken(pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ /*
+ * U+0041 LATIN CAPITAL LETTER A through to
+ * U+005A LATIN CAPITAL LETTER Z Append the
+ * lowercase version of the input character (add
+ * 0x0020 to the character's code point) to the
+ * current DOCTYPE token's name.
+ */
+ if (c >= 'A' && c <= 'Z') {
+ c += 0x0020;
+ }
+ /*
+ * Anything else Append the current input
+ * character to the current DOCTYPE token's
+ * name.
+ */
+ appendStrBuf(c);
+ /*
+ * Stay in the DOCTYPE name state.
+ */
+ continue;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case AFTER_DOCTYPE_NAME:
+ afterdoctypenameloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE Stay
+ * in the after DOCTYPE name state.
+ */
+ continue;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit the current
+ * DOCTYPE token.
+ */
+ emitDoctypeToken(pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case 'p':
+ case 'P':
+ index = 0;
+ state = transition(state, Tokenizer.DOCTYPE_UBLIC, reconsume, pos);
+ break afterdoctypenameloop;
+ // continue stateloop;
+ case 's':
+ case 'S':
+ index = 0;
+ state = transition(state, Tokenizer.DOCTYPE_YSTEM, reconsume, pos);
+ continue stateloop;
+ default:
+ /*
+ * Otherwise, this is the parse error.
+ */
+ bogusDoctype();
+
+ /*
+ * Set the DOCTYPE token's force-quirks flag to
+ * on.
+ */
+ // done by bogusDoctype();
+ /*
+ * Switch to the bogus DOCTYPE state.
+ */
+ state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case DOCTYPE_UBLIC:
+ doctypeublicloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * If the six characters starting from the current input
+ * character are an ASCII case-insensitive match for the
+ * word "PUBLIC", then consume those characters and
+ * switch to the before DOCTYPE public identifier state.
+ */
+ if (index < 5) { // UBLIC.length
+ char folded = c;
+ if (c >= 'A' && c <= 'Z') {
+ folded += 0x20;
+ }
+ if (folded != Tokenizer.UBLIC[index]) {
+ bogusDoctype();
+ // forceQuirks = true;
+ reconsume = true;
+ state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos);
+ continue stateloop;
+ }
+ index++;
+ continue;
+ } else {
+ reconsume = true;
+ state = transition(state, Tokenizer.AFTER_DOCTYPE_PUBLIC_KEYWORD, reconsume, pos);
+ break doctypeublicloop;
+ // continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case AFTER_DOCTYPE_PUBLIC_KEYWORD:
+ afterdoctypepublickeywordloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ state = transition(state, Tokenizer.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE
+ * Switch to the before DOCTYPE public
+ * identifier state.
+ */
+ state = transition(state, Tokenizer.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos);
+ break afterdoctypepublickeywordloop;
+ // FALL THROUGH continue stateloop
+ case '"':
+ /*
+ * U+0022 QUOTATION MARK (") Parse Error.
+ */
+ errNoSpaceBetweenDoctypePublicKeywordAndQuote();
+ /*
+ * Set the DOCTYPE token's public identifier to
+ * the empty string (not missing),
+ */
+ clearStrBufBeforeUse();
+ /*
+ * then switch to the DOCTYPE public identifier
+ * (double-quoted) state.
+ */
+ state = transition(state, Tokenizer.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
+ continue stateloop;
+ case '\'':
+ /*
+ * U+0027 APOSTROPHE (') Parse Error.
+ */
+ errNoSpaceBetweenDoctypePublicKeywordAndQuote();
+ /*
+ * Set the DOCTYPE token's public identifier to
+ * the empty string (not missing),
+ */
+ clearStrBufBeforeUse();
+ /*
+ * then switch to the DOCTYPE public identifier
+ * (single-quoted) state.
+ */
+ state = transition(state, Tokenizer.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
+ continue stateloop;
+ case '>':
+ /* U+003E GREATER-THAN SIGN (>) Parse error. */
+ errExpectedPublicId();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to
+ * on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit that DOCTYPE token.
+ */
+ emitDoctypeToken(pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ default:
+ bogusDoctype();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to
+ * on.
+ */
+ // done by bogusDoctype();
+ /*
+ * Switch to the bogus DOCTYPE state.
+ */
+ state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
+ beforedoctypepublicidentifierloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE Stay
+ * in the before DOCTYPE public identifier
+ * state.
+ */
+ continue;
+ case '"':
+ /*
+ * U+0022 QUOTATION MARK (") Set the DOCTYPE
+ * token's public identifier to the empty string
+ * (not missing),
+ */
+ clearStrBufBeforeUse();
+ /*
+ * then switch to the DOCTYPE public identifier
+ * (double-quoted) state.
+ */
+ state = transition(state, Tokenizer.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
+ break beforedoctypepublicidentifierloop;
+ // continue stateloop;
+ case '\'':
+ /*
+ * U+0027 APOSTROPHE (') Set the DOCTYPE token's
+ * public identifier to the empty string (not
+ * missing),
+ */
+ clearStrBufBeforeUse();
+ /*
+ * then switch to the DOCTYPE public identifier
+ * (single-quoted) state.
+ */
+ state = transition(state, Tokenizer.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
+ continue stateloop;
+ case '>':
+ /* U+003E GREATER-THAN SIGN (>) Parse error. */
+ errExpectedPublicId();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to
+ * on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit that DOCTYPE token.
+ */
+ emitDoctypeToken(pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ default:
+ bogusDoctype();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to
+ * on.
+ */
+ // done by bogusDoctype();
+ /*
+ * Switch to the bogus DOCTYPE state.
+ */
+ state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
+ doctypepublicidentifierdoublequotedloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '"':
+ /*
+ * U+0022 QUOTATION MARK (") Switch to the after
+ * DOCTYPE public identifier state.
+ */
+ publicIdentifier = strBufToString();
+ state = transition(state, Tokenizer.AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos);
+ break doctypepublicidentifierdoublequotedloop;
+ // continue stateloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Parse error.
+ */
+ errGtInPublicId();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to
+ * on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit that DOCTYPE token.
+ */
+ publicIdentifier = strBufToString();
+ emitDoctypeToken(pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '\r':
+ appendStrBufCarriageReturn();
+ break stateloop;
+ case '\n':
+ appendStrBufLineFeed();
+ continue;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ /*
+ * Anything else Append the current input
+ * character to the current DOCTYPE token's
+ * public identifier.
+ */
+ appendStrBuf(c);
+ /*
+ * Stay in the DOCTYPE public identifier
+ * (double-quoted) state.
+ */
+ continue;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
+ afterdoctypepublicidentifierloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ state = transition(state, Tokenizer.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE
+ * Switch to the between DOCTYPE public and
+ * system identifiers state.
+ */
+ state = transition(state, Tokenizer.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS, reconsume, pos);
+ break afterdoctypepublicidentifierloop;
+ // continue stateloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit the current
+ * DOCTYPE token.
+ */
+ emitDoctypeToken(pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '"':
+ /*
+ * U+0022 QUOTATION MARK (") Parse error.
+ */
+ errNoSpaceBetweenPublicAndSystemIds();
+ /*
+ * Set the DOCTYPE token's system identifier to
+ * the empty string (not missing),
+ */
+ clearStrBufBeforeUse();
+ /*
+ * then switch to the DOCTYPE system identifier
+ * (double-quoted) state.
+ */
+ state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
+ continue stateloop;
+ case '\'':
+ /*
+ * U+0027 APOSTROPHE (') Parse error.
+ */
+ errNoSpaceBetweenPublicAndSystemIds();
+ /*
+ * Set the DOCTYPE token's system identifier to
+ * the empty string (not missing),
+ */
+ clearStrBufBeforeUse();
+ /*
+ * then switch to the DOCTYPE system identifier
+ * (single-quoted) state.
+ */
+ state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
+ continue stateloop;
+ default:
+ bogusDoctype();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to
+ * on.
+ */
+ // done by bogusDoctype();
+ /*
+ * Switch to the bogus DOCTYPE state.
+ */
+ state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
+ betweendoctypepublicandsystemidentifiersloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE Stay
+ * in the between DOCTYPE public and system
+ * identifiers state.
+ */
+ continue;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit the current
+ * DOCTYPE token.
+ */
+ emitDoctypeToken(pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '"':
+ /*
+ * U+0022 QUOTATION MARK (") Set the DOCTYPE
+ * token's system identifier to the empty string
+ * (not missing),
+ */
+ clearStrBufBeforeUse();
+ /*
+ * then switch to the DOCTYPE system identifier
+ * (double-quoted) state.
+ */
+ state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
+ break betweendoctypepublicandsystemidentifiersloop;
+ // continue stateloop;
+ case '\'':
+ /*
+ * U+0027 APOSTROPHE (') Set the DOCTYPE token's
+ * system identifier to the empty string (not
+ * missing),
+ */
+ clearStrBufBeforeUse();
+ /*
+ * then switch to the DOCTYPE system identifier
+ * (single-quoted) state.
+ */
+ state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
+ continue stateloop;
+ default:
+ bogusDoctype();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to
+ * on.
+ */
+ // done by bogusDoctype();
+ /*
+ * Switch to the bogus DOCTYPE state.
+ */
+ state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
+ doctypesystemidentifierdoublequotedloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '"':
+ /*
+ * U+0022 QUOTATION MARK (") Switch to the after
+ * DOCTYPE system identifier state.
+ */
+ systemIdentifier = strBufToString();
+ state = transition(state, Tokenizer.AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos);
+ continue stateloop;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Parse error.
+ */
+ errGtInSystemId();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to
+ * on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit that DOCTYPE token.
+ */
+ systemIdentifier = strBufToString();
+ emitDoctypeToken(pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '\r':
+ appendStrBufCarriageReturn();
+ break stateloop;
+ case '\n':
+ appendStrBufLineFeed();
+ continue;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ /*
+ * Anything else Append the current input
+ * character to the current DOCTYPE token's
+ * system identifier.
+ */
+ appendStrBuf(c);
+ /*
+ * Stay in the DOCTYPE system identifier
+ * (double-quoted) state.
+ */
+ continue;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
+ afterdoctypesystemidentifierloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE Stay
+ * in the after DOCTYPE system identifier state.
+ */
+ continue;
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit the current
+ * DOCTYPE token.
+ */
+ emitDoctypeToken(pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ default:
+ /*
+ * Switch to the bogus DOCTYPE state. (This does
+ * not set the DOCTYPE token's force-quirks flag
+ * to on.)
+ */
+ bogusDoctypeWithoutQuirks();
+ state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos);
+ break afterdoctypesystemidentifierloop;
+ // continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case BOGUS_DOCTYPE:
+ for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '>':
+ /*
+ * U+003E GREATER-THAN SIGN (>) Emit that
+ * DOCTYPE token.
+ */
+ emitDoctypeToken(pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '\r':
+ silentCarriageReturn();
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ default:
+ /*
+ * Anything else Stay in the bogus DOCTYPE
+ * state.
+ */
+ continue;
+ }
+ }
+ // XXX reorder point
+ case DOCTYPE_YSTEM:
+ doctypeystemloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Otherwise, if the six characters starting from the
+ * current input character are an ASCII case-insensitive
+ * match for the word "SYSTEM", then consume those
+ * characters and switch to the before DOCTYPE system
+ * identifier state.
+ */
+ if (index < 5) { // YSTEM.length
+ char folded = c;
+ if (c >= 'A' && c <= 'Z') {
+ folded += 0x20;
+ }
+ if (folded != Tokenizer.YSTEM[index]) {
+ bogusDoctype();
+ reconsume = true;
+ state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos);
+ continue stateloop;
+ }
+ index++;
+ continue stateloop;
+ } else {
+ reconsume = true;
+ state = transition(state, Tokenizer.AFTER_DOCTYPE_SYSTEM_KEYWORD, reconsume, pos);
+ break doctypeystemloop;
+ // continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case AFTER_DOCTYPE_SYSTEM_KEYWORD:
+ afterdoctypesystemkeywordloop: for (;;) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ }
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ state = transition(state, Tokenizer.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos);
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE
+ * Switch to the before DOCTYPE public
+ * identifier state.
+ */
+ state = transition(state, Tokenizer.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos);
+ break afterdoctypesystemkeywordloop;
+ // FALL THROUGH continue stateloop
+ case '"':
+ /*
+ * U+0022 QUOTATION MARK (") Parse Error.
+ */
+ errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
+ /*
+ * Set the DOCTYPE token's system identifier to
+ * the empty string (not missing),
+ */
+ clearStrBufBeforeUse();
+ /*
+ * then switch to the DOCTYPE public identifier
+ * (double-quoted) state.
+ */
+ state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
+ continue stateloop;
+ case '\'':
+ /*
+ * U+0027 APOSTROPHE (') Parse Error.
+ */
+ errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
+ /*
+ * Set the DOCTYPE token's public identifier to
+ * the empty string (not missing),
+ */
+ clearStrBufBeforeUse();
+ /*
+ * then switch to the DOCTYPE public identifier
+ * (single-quoted) state.
+ */
+ state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
+ continue stateloop;
+ case '>':
+ /* U+003E GREATER-THAN SIGN (>) Parse error. */
+ errExpectedPublicId();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to
+ * on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit that DOCTYPE token.
+ */
+ emitDoctypeToken(pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ default:
+ bogusDoctype();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to
+ * on.
+ */
+ // done by bogusDoctype();
+ /*
+ * Switch to the bogus DOCTYPE state.
+ */
+ state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
+ beforedoctypesystemidentifierloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\r':
+ silentCarriageReturn();
+ break stateloop;
+ case '\n':
+ silentLineFeed();
+ // fall thru
+ case ' ':
+ case '\t':
+ case '\u000C':
+ /*
+ * U+0009 CHARACTER TABULATION U+000A LINE FEED
+ * (LF) U+000C FORM FEED (FF) U+0020 SPACE Stay
+ * in the before DOCTYPE system identifier
+ * state.
+ */
+ continue;
+ case '"':
+ /*
+ * U+0022 QUOTATION MARK (") Set the DOCTYPE
+ * token's system identifier to the empty string
+ * (not missing),
+ */
+ clearStrBufBeforeUse();
+ /*
+ * then switch to the DOCTYPE system identifier
+ * (double-quoted) state.
+ */
+ state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
+ continue stateloop;
+ case '\'':
+ /*
+ * U+0027 APOSTROPHE (') Set the DOCTYPE token's
+ * system identifier to the empty string (not
+ * missing),
+ */
+ clearStrBufBeforeUse();
+ /*
+ * then switch to the DOCTYPE system identifier
+ * (single-quoted) state.
+ */
+ state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
+ break beforedoctypesystemidentifierloop;
+ // continue stateloop;
+ case '>':
+ /* U+003E GREATER-THAN SIGN (>) Parse error. */
+ errExpectedSystemId();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to
+ * on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit that DOCTYPE token.
+ */
+ emitDoctypeToken(pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ default:
+ bogusDoctype();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to
+ * on.
+ */
+ // done by bogusDoctype();
+ /*
+ * Switch to the bogus DOCTYPE state.
+ */
+ state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos);
+ continue stateloop;
+ }
+ }
+ // FALLTHRU DON'T REORDER
+ case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
+ for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\'':
+ /*
+ * U+0027 APOSTROPHE (') Switch to the after
+ * DOCTYPE system identifier state.
+ */
+ systemIdentifier = strBufToString();
+ state = transition(state, Tokenizer.AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos);
+ continue stateloop;
+ case '>':
+ errGtInSystemId();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to
+ * on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit that DOCTYPE token.
+ */
+ systemIdentifier = strBufToString();
+ emitDoctypeToken(pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '\r':
+ appendStrBufCarriageReturn();
+ break stateloop;
+ case '\n':
+ appendStrBufLineFeed();
+ continue;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ /*
+ * Anything else Append the current input
+ * character to the current DOCTYPE token's
+ * system identifier.
+ */
+ appendStrBuf(c);
+ /*
+ * Stay in the DOCTYPE system identifier
+ * (double-quoted) state.
+ */
+ continue;
+ }
+ }
+ // XXX reorder point
+ case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
+ for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ /*
+ * Consume the next input character:
+ */
+ switch (c) {
+ case '\'':
+ /*
+ * U+0027 APOSTROPHE (') Switch to the after
+ * DOCTYPE public identifier state.
+ */
+ publicIdentifier = strBufToString();
+ state = transition(state, Tokenizer.AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos);
+ continue stateloop;
+ case '>':
+ errGtInPublicId();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to
+ * on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit that DOCTYPE token.
+ */
+ publicIdentifier = strBufToString();
+ emitDoctypeToken(pos);
+ /*
+ * Switch to the data state.
+ */
+ state = transition(state, Tokenizer.DATA, reconsume, pos);
+ continue stateloop;
+ case '\r':
+ appendStrBufCarriageReturn();
+ break stateloop;
+ case '\n':
+ appendStrBufLineFeed();
+ continue;
+ case '\u0000':
+ c = '\uFFFD';
+ // fall thru
+ default:
+ /*
+ * Anything else Append the current input
+ * character to the current DOCTYPE token's
+ * public identifier.
+ */
+ appendStrBuf(c);
+ /*
+ * Stay in the DOCTYPE public identifier
+ * (single-quoted) state.
+ */
+ continue;
+ }
+ }
+ // XXX reorder point
+ case PROCESSING_INSTRUCTION:
+ processinginstructionloop: for (;;) {
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ switch (c) {
+ case '?':
+ state = transition(
+ state,
+ Tokenizer.PROCESSING_INSTRUCTION_QUESTION_MARK,
+ reconsume, pos);
+ break processinginstructionloop;
+ // continue stateloop;
+ default:
+ continue;
+ }
+ }
+ case PROCESSING_INSTRUCTION_QUESTION_MARK:
+ if (++pos == endPos) {
+ break stateloop;
+ }
+ c = checkChar(buf, pos);
+ switch (c) {
+ case '>':
+ state = transition(state, Tokenizer.DATA,
+ reconsume, pos);
+ continue stateloop;
+ default:
+ state = transition(state,
+ Tokenizer.PROCESSING_INSTRUCTION,
+ reconsume, pos);
+ continue stateloop;
+ }
+ // END HOTSPOT WORKAROUND
+ }
+ }
+ flushChars(buf, pos);
+ /*
+ * if (prevCR && pos != endPos) { // why is this needed? pos--; col--; }
+ */
+ // Save locals
+ stateSave = state;
+ returnStateSave = returnState;
+ return pos;
+ }
+
+ // HOTSPOT WORKAROUND INSERTION POINT
+
+ // [NOCPP[
+
+ protected int transition(int from, int to, boolean reconsume, int pos) throws SAXException {
+ return to;
+ }
+
+ // ]NOCPP]
+
+ private void initDoctypeFields() {
+ // Discard the characters "DOCTYPE" accumulated as a potential bogus
+ // comment into strBuf.
+ clearStrBufAfterUse();
+ doctypeName = "";
+ if (systemIdentifier != null) {
+ Portability.releaseString(systemIdentifier);
+ systemIdentifier = null;
+ }
+ if (publicIdentifier != null) {
+ Portability.releaseString(publicIdentifier);
+ publicIdentifier = null;
+ }
+ forceQuirks = false;
+ }
+
+ @Inline private void adjustDoubleHyphenAndAppendToStrBufCarriageReturn()
+ throws SAXException {
+ silentCarriageReturn();
+ adjustDoubleHyphenAndAppendToStrBufAndErr('\n');
+ }
+
+ @Inline private void adjustDoubleHyphenAndAppendToStrBufLineFeed()
+ throws SAXException {
+ silentLineFeed();
+ adjustDoubleHyphenAndAppendToStrBufAndErr('\n');
+ }
+
+ @Inline private void appendStrBufLineFeed() {
+ silentLineFeed();
+ appendStrBuf('\n');
+ }
+
+ @Inline private void appendStrBufCarriageReturn() {
+ silentCarriageReturn();
+ appendStrBuf('\n');
+ }
+
+ @Inline protected void silentCarriageReturn() {
+ ++line;
+ lastCR = true;
+ }
+
+ @Inline protected void silentLineFeed() {
+ ++line;
+ }
+
+ private void emitCarriageReturn(@NoLength char[] buf, int pos)
+ throws SAXException {
+ silentCarriageReturn();
+ flushChars(buf, pos);
+ tokenHandler.characters(Tokenizer.LF, 0, 1);
+ cstart = Integer.MAX_VALUE;
+ }
+
+ private void emitReplacementCharacter(@NoLength char[] buf, int pos)
+ throws SAXException {
+ flushChars(buf, pos);
+ tokenHandler.zeroOriginatingReplacementCharacter();
+ cstart = pos + 1;
+ }
+
+ private void emitPlaintextReplacementCharacter(@NoLength char[] buf, int pos)
+ throws SAXException {
+ flushChars(buf, pos);
+ tokenHandler.characters(REPLACEMENT_CHARACTER, 0, 1);
+ cstart = pos + 1;
+ }
+
+ private void setAdditionalAndRememberAmpersandLocation(char add) {
+ additional = add;
+ // [NOCPP[
+ ampersandLocation = new LocatorImpl(this);
+ // ]NOCPP]
+ }
+
+ private void bogusDoctype() throws SAXException {
+ errBogusDoctype();
+ forceQuirks = true;
+ }
+
+ private void bogusDoctypeWithoutQuirks() throws SAXException {
+ errBogusDoctype();
+ forceQuirks = false;
+ }
+
+ private void handleNcrValue(int returnState) throws SAXException {
+ /*
+ * If one or more characters match the range, then take them all and
+ * interpret the string of characters as a number (either hexadecimal or
+ * decimal as appropriate).
+ */
+ if (value <= 0xFFFF) {
+ if (value >= 0x80 && value <= 0x9f) {
+ /*
+ * If that number is one of the numbers in the first column of
+ * the following table, then this is a parse error.
+ */
+ errNcrInC1Range();
+ /*
+ * Find the row with that number in the first column, and return
+ * a character token for the Unicode character given in the
+ * second column of that row.
+ */
+ @NoLength char[] val = NamedCharacters.WINDOWS_1252[value - 0x80];
+ emitOrAppendOne(val, returnState);
+ // [NOCPP[
+ } else if (value == 0xC
+ && contentSpacePolicy != XmlViolationPolicy.ALLOW) {
+ if (contentSpacePolicy == XmlViolationPolicy.ALTER_INFOSET) {
+ emitOrAppendOne(Tokenizer.SPACE, returnState);
+ } else if (contentSpacePolicy == XmlViolationPolicy.FATAL) {
+ fatal("A character reference expanded to a form feed which is not legal XML 1.0 white space.");
+ }
+ // ]NOCPP]
+ } else if (value == 0x0) {
+ errNcrZero();
+ emitOrAppendOne(Tokenizer.REPLACEMENT_CHARACTER, returnState);
+ } else if ((value & 0xF800) == 0xD800) {
+ errNcrSurrogate();
+ emitOrAppendOne(Tokenizer.REPLACEMENT_CHARACTER, returnState);
+ } else {
+ /*
+ * Otherwise, return a character token for the Unicode character
+ * whose code point is that number.
+ */
+ char ch = (char) value;
+ // [NOCPP[
+ if (value == 0x0D) {
+ errNcrCr();
+ } else if ((value <= 0x0008) || (value == 0x000B)
+ || (value >= 0x000E && value <= 0x001F)) {
+ ch = errNcrControlChar(ch);
+ } else if (value >= 0xFDD0 && value <= 0xFDEF) {
+ errNcrUnassigned();
+ } else if ((value & 0xFFFE) == 0xFFFE) {
+ ch = errNcrNonCharacter(ch);
+ } else if (value >= 0x007F && value <= 0x009F) {
+ errNcrControlChar();
+ } else {
+ maybeWarnPrivateUse(ch);
+ }
+ // ]NOCPP]
+ bmpChar[0] = ch;
+ emitOrAppendOne(bmpChar, returnState);
+ }
+ } else if (value <= 0x10FFFF) {
+ // [NOCPP[
+ maybeWarnPrivateUseAstral();
+ if ((value & 0xFFFE) == 0xFFFE) {
+ errAstralNonCharacter(value);
+ }
+ // ]NOCPP]
+ astralChar[0] = (char) (Tokenizer.LEAD_OFFSET + (value >> 10));
+ astralChar[1] = (char) (0xDC00 + (value & 0x3FF));
+ emitOrAppendTwo(astralChar, returnState);
+ } else {
+ errNcrOutOfRange();
+ emitOrAppendOne(Tokenizer.REPLACEMENT_CHARACTER, returnState);
+ }
+ }
+
+ public void eof() throws SAXException {
+ int state = stateSave;
+ int returnState = returnStateSave;
+
+ eofloop: for (;;) {
+ switch (state) {
+ case SCRIPT_DATA_LESS_THAN_SIGN:
+ case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:
+ /*
+ * Otherwise, emit a U+003C LESS-THAN SIGN character token
+ */
+ tokenHandler.characters(Tokenizer.LT_GT, 0, 1);
+ /*
+ * and reconsume the current input character in the data
+ * state.
+ */
+ break eofloop;
+ case TAG_OPEN:
+ /*
+ * The behavior of this state depends on the content model
+ * flag.
+ */
+ /*
+ * Anything else Parse error.
+ */
+ errEofAfterLt();
+ /*
+ * Emit a U+003C LESS-THAN SIGN character token
+ */
+ tokenHandler.characters(Tokenizer.LT_GT, 0, 1);
+ /*
+ * and reconsume the current input character in the data
+ * state.
+ */
+ break eofloop;
+ case RAWTEXT_RCDATA_LESS_THAN_SIGN:
+ /*
+ * Emit a U+003C LESS-THAN SIGN character token
+ */
+ tokenHandler.characters(Tokenizer.LT_GT, 0, 1);
+ /*
+ * and reconsume the current input character in the RCDATA
+ * state.
+ */
+ break eofloop;
+ case NON_DATA_END_TAG_NAME:
+ /*
+ * Emit a U+003C LESS-THAN SIGN character token, a U+002F
+ * SOLIDUS character token,
+ */
+ tokenHandler.characters(Tokenizer.LT_SOLIDUS, 0, 2);
+ /*
+ * a character token for each of the characters in the
+ * temporary buffer (in the order they were added to the
+ * buffer),
+ */
+ emitStrBuf();
+ /*
+ * and reconsume the current input character in the RCDATA
+ * state.
+ */
+ break eofloop;
+ case CLOSE_TAG_OPEN:
+ /* EOF Parse error. */
+ errEofAfterLt();
+ /*
+ * Emit a U+003C LESS-THAN SIGN character token and a U+002F
+ * SOLIDUS character token.
+ */
+ tokenHandler.characters(Tokenizer.LT_SOLIDUS, 0, 2);
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case TAG_NAME:
+ /*
+ * EOF Parse error.
+ */
+ errEofInTagName();
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case BEFORE_ATTRIBUTE_NAME:
+ case AFTER_ATTRIBUTE_VALUE_QUOTED:
+ case SELF_CLOSING_START_TAG:
+ /* EOF Parse error. */
+ errEofWithoutGt();
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case ATTRIBUTE_NAME:
+ /*
+ * EOF Parse error.
+ */
+ errEofInAttributeName();
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case AFTER_ATTRIBUTE_NAME:
+ case BEFORE_ATTRIBUTE_VALUE:
+ /* EOF Parse error. */
+ errEofWithoutGt();
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
+ case ATTRIBUTE_VALUE_SINGLE_QUOTED:
+ case ATTRIBUTE_VALUE_UNQUOTED:
+ /* EOF Parse error. */
+ errEofInAttributeValue();
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case BOGUS_COMMENT:
+ emitComment(0, 0);
+ break eofloop;
+ case BOGUS_COMMENT_HYPHEN:
+ // [NOCPP[
+ maybeAppendSpaceToBogusComment();
+ // ]NOCPP]
+ emitComment(0, 0);
+ break eofloop;
+ case MARKUP_DECLARATION_OPEN:
+ errBogusComment();
+ emitComment(0, 0);
+ break eofloop;
+ case MARKUP_DECLARATION_HYPHEN:
+ errBogusComment();
+ emitComment(0, 0);
+ break eofloop;
+ case MARKUP_DECLARATION_OCTYPE:
+ if (index < 6) {
+ errBogusComment();
+ emitComment(0, 0);
+ } else {
+ /* EOF Parse error. */
+ errEofInDoctype();
+ /*
+ * Create a new DOCTYPE token. Set its force-quirks flag
+ * to on.
+ */
+ doctypeName = "";
+ if (systemIdentifier != null) {
+ Portability.releaseString(systemIdentifier);
+ systemIdentifier = null;
+ }
+ if (publicIdentifier != null) {
+ Portability.releaseString(publicIdentifier);
+ publicIdentifier = null;
+ }
+ forceQuirks = true;
+ /*
+ * Emit the token.
+ */
+ emitDoctypeToken(0);
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ }
+ break eofloop;
+ case COMMENT_START:
+ case COMMENT:
+ /*
+ * EOF Parse error.
+ */
+ errEofInComment();
+ /* Emit the comment token. */
+ emitComment(0, 0);
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case COMMENT_END:
+ errEofInComment();
+ /* Emit the comment token. */
+ emitComment(2, 0);
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case COMMENT_END_DASH:
+ case COMMENT_START_DASH:
+ errEofInComment();
+ /* Emit the comment token. */
+ emitComment(1, 0);
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case COMMENT_END_BANG:
+ errEofInComment();
+ /* Emit the comment token. */
+ emitComment(3, 0);
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case DOCTYPE:
+ case BEFORE_DOCTYPE_NAME:
+ errEofInDoctype();
+ /*
+ * Create a new DOCTYPE token. Set its force-quirks flag to
+ * on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit the token.
+ */
+ emitDoctypeToken(0);
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case DOCTYPE_NAME:
+ errEofInDoctype();
+ strBufToDoctypeName();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit that DOCTYPE token.
+ */
+ emitDoctypeToken(0);
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case DOCTYPE_UBLIC:
+ case DOCTYPE_YSTEM:
+ case AFTER_DOCTYPE_NAME:
+ case AFTER_DOCTYPE_PUBLIC_KEYWORD:
+ case AFTER_DOCTYPE_SYSTEM_KEYWORD:
+ case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
+ errEofInDoctype();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit that DOCTYPE token.
+ */
+ emitDoctypeToken(0);
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
+ case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
+ /* EOF Parse error. */
+ errEofInPublicId();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit that DOCTYPE token.
+ */
+ publicIdentifier = strBufToString();
+ emitDoctypeToken(0);
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
+ case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
+ case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
+ errEofInDoctype();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit that DOCTYPE token.
+ */
+ emitDoctypeToken(0);
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
+ case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
+ /* EOF Parse error. */
+ errEofInSystemId();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit that DOCTYPE token.
+ */
+ systemIdentifier = strBufToString();
+ emitDoctypeToken(0);
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
+ errEofInDoctype();
+ /*
+ * Set the DOCTYPE token's force-quirks flag to on.
+ */
+ forceQuirks = true;
+ /*
+ * Emit that DOCTYPE token.
+ */
+ emitDoctypeToken(0);
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case BOGUS_DOCTYPE:
+ /*
+ * Emit that DOCTYPE token.
+ */
+ emitDoctypeToken(0);
+ /*
+ * Reconsume the EOF character in the data state.
+ */
+ break eofloop;
+ case CONSUME_CHARACTER_REFERENCE:
+ /*
+ * Unlike the definition is the spec, this state does not
+ * return a value and never requires the caller to
+ * backtrack. This state takes care of emitting characters
+ * or appending to the current attribute value. It also
+ * takes care of that in the case when consuming the entity
+ * fails.
+ */
+ /*
+ * This section defines how to consume an entity. This
+ * definition is used when parsing entities in text and in
+ * attributes.
+ *
+ * The behavior depends on the identity of the next
+ * character (the one immediately after the U+0026 AMPERSAND
+ * character):
+ */
+
+ emitOrAppendCharRefBuf(returnState);
+ state = returnState;
+ continue;
+ case CHARACTER_REFERENCE_HILO_LOOKUP:
+ errNoNamedCharacterMatch();
+ emitOrAppendCharRefBuf(returnState);
+ state = returnState;
+ continue;
+ case CHARACTER_REFERENCE_TAIL:
+ outer: for (;;) {
+ char c = '\u0000';
+ entCol++;
+ /*
+ * Consume the maximum number of characters possible,
+ * with the consumed characters matching one of the
+ * identifiers in the first column of the named
+ * character references table (in a case-sensitive
+ * manner).
+ */
+ hiloop: for (;;) {
+ if (hi == -1) {
+ break hiloop;
+ }
+ if (entCol == NamedCharacters.NAMES[hi].length()) {
+ break hiloop;
+ }
+ if (entCol > NamedCharacters.NAMES[hi].length()) {
+ break outer;
+ } else if (c < NamedCharacters.NAMES[hi].charAt(entCol)) {
+ hi--;
+ } else {
+ break hiloop;
+ }
+ }
+
+ loloop: for (;;) {
+ if (hi < lo) {
+ break outer;
+ }
+ if (entCol == NamedCharacters.NAMES[lo].length()) {
+ candidate = lo;
+ charRefBufMark = charRefBufLen;
+ lo++;
+ } else if (entCol > NamedCharacters.NAMES[lo].length()) {
+ break outer;
+ } else if (c > NamedCharacters.NAMES[lo].charAt(entCol)) {
+ lo++;
+ } else {
+ break loloop;
+ }
+ }
+ if (hi < lo) {
+ break outer;
+ }
+ continue;
+ }
+
+ if (candidate == -1) {
+ /*
+ * If no match can be made, then this is a parse error.
+ */
+ errNoNamedCharacterMatch();
+ emitOrAppendCharRefBuf(returnState);
+ state = returnState;
+ continue eofloop;
+ } else {
+ @Const @CharacterName String candidateName = NamedCharacters.NAMES[candidate];
+ if (candidateName.length() == 0
+ || candidateName.charAt(candidateName.length() - 1) != ';') {
+ /*
+ * If the last character matched is not a U+003B
+ * SEMICOLON (;), there is a parse error.
+ */
+ if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
+ /*
+ * If the entity is being consumed as part of an
+ * attribute, and the last character matched is
+ * not a U+003B SEMICOLON (;),
+ */
+ char ch;
+ if (charRefBufMark == charRefBufLen) {
+ ch = '\u0000';
+ } else {
+ ch = charRefBuf[charRefBufMark];
+ }
+ if ((ch >= '0' && ch <= '9')
+ || (ch >= 'A' && ch <= 'Z')
+ || (ch >= 'a' && ch <= 'z')) {
+ /*
+ * and the next character is in the range
+ * U+0030 DIGIT ZERO to U+0039 DIGIT NINE,
+ * U+0041 LATIN CAPITAL LETTER A to U+005A
+ * LATIN CAPITAL LETTER Z, or U+0061 LATIN
+ * SMALL LETTER A to U+007A LATIN SMALL
+ * LETTER Z, then, for historical reasons,
+ * all the characters that were matched
+ * after the U+0026 AMPERSAND (&) must be
+ * unconsumed, and nothing is returned.
+ */
+ errNoNamedCharacterMatch();
+ appendCharRefBufToStrBuf();
+ state = returnState;
+ continue eofloop;
+ }
+ }
+ if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
+ errUnescapedAmpersandInterpretedAsCharacterReference();
+ } else {
+ errNotSemicolonTerminated();
+ }
+ }
+
+ /*
+ * Otherwise, return a character token for the character
+ * corresponding to the entity name (as given by the
+ * second column of the named character references
+ * table).
+ */
+ @Const @NoLength char[] val = NamedCharacters.VALUES[candidate];
+ if (
+ // [NOCPP[
+ val.length == 1
+ // ]NOCPP]
+ // CPPONLY: val[1] == 0
+ ) {
+ emitOrAppendOne(val, returnState);
+ } else {
+ emitOrAppendTwo(val, returnState);
+ }
+ // this is so complicated!
+ if (charRefBufMark < charRefBufLen) {
+ if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
+ appendStrBuf(charRefBuf, charRefBufMark,
+ charRefBufLen - charRefBufMark);
+ } else {
+ tokenHandler.characters(charRefBuf, charRefBufMark,
+ charRefBufLen - charRefBufMark);
+ }
+ }
+ charRefBufLen = 0;
+ state = returnState;
+ continue eofloop;
+ /*
+ * If the markup contains I'm &notit; I tell you, the
+ * entity is parsed as "not", as in, I'm ¬it; I tell
+ * you. But if the markup was I'm &notin; I tell you,
+ * the entity would be parsed as "notin;", resulting in
+ * I'm ∉ I tell you.
+ */
+ }
+ case CONSUME_NCR:
+ case DECIMAL_NRC_LOOP:
+ case HEX_NCR_LOOP:
+ /*
+ * If no characters match the range, then don't consume any
+ * characters (and unconsume the U+0023 NUMBER SIGN
+ * character and, if appropriate, the X character). This is
+ * a parse error; nothing is returned.
+ *
+ * Otherwise, if the next character is a U+003B SEMICOLON,
+ * consume that too. If it isn't, there is a parse error.
+ */
+ if (!seenDigits) {
+ errNoDigitsInNCR();
+ emitOrAppendCharRefBuf(returnState);
+ state = returnState;
+ continue;
+ } else {
+ errCharRefLacksSemicolon();
+ }
+ // WARNING previous state sets reconsume
+ handleNcrValue(returnState);
+ state = returnState;
+ continue;
+ case CDATA_RSQB:
+ tokenHandler.characters(Tokenizer.RSQB_RSQB, 0, 1);
+ break eofloop;
+ case CDATA_RSQB_RSQB:
+ tokenHandler.characters(Tokenizer.RSQB_RSQB, 0, 2);
+ break eofloop;
+ case DATA:
+ default:
+ break eofloop;
+ }
+ }
+ // case DATA:
+ /*
+ * EOF Emit an end-of-file token.
+ */
+ tokenHandler.eof();
+ return;
+ }
+
+ private void emitDoctypeToken(int pos) throws SAXException {
+ cstart = pos + 1;
+ tokenHandler.doctype(doctypeName, publicIdentifier, systemIdentifier,
+ forceQuirks);
+ // It is OK and sufficient to release these here, since
+ // there's no way out of the doctype states than through paths
+ // that call this method.
+ doctypeName = null;
+ Portability.releaseString(publicIdentifier);
+ publicIdentifier = null;
+ Portability.releaseString(systemIdentifier);
+ systemIdentifier = null;
+ }
+
+ @Inline protected char checkChar(@NoLength char[] buf, int pos)
+ throws SAXException {
+ return buf[pos];
+ }
+
+ public boolean internalEncodingDeclaration(String internalCharset)
+ throws SAXException {
+ if (encodingDeclarationHandler != null) {
+ return encodingDeclarationHandler.internalEncodingDeclaration(internalCharset);
+ }
+ return false;
+ }
+
+ /**
+ * @param val
+ * @throws SAXException
+ */
+ private void emitOrAppendTwo(@Const @NoLength char[] val, int returnState)
+ throws SAXException {
+ if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
+ appendStrBuf(val[0]);
+ appendStrBuf(val[1]);
+ } else {
+ tokenHandler.characters(val, 0, 2);
+ }
+ }
+
+ private void emitOrAppendOne(@Const @NoLength char[] val, int returnState)
+ throws SAXException {
+ if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
+ appendStrBuf(val[0]);
+ } else {
+ tokenHandler.characters(val, 0, 1);
+ }
+ }
+
+ public void end() throws SAXException {
+ strBuf = null;
+ doctypeName = null;
+ if (systemIdentifier != null) {
+ Portability.releaseString(systemIdentifier);
+ systemIdentifier = null;
+ }
+ if (publicIdentifier != null) {
+ Portability.releaseString(publicIdentifier);
+ publicIdentifier = null;
+ }
+ if (tagName != null) {
+ tagName.release();
+ tagName = null;
+ }
+ if (attributeName != null) {
+ attributeName.release();
+ attributeName = null;
+ }
+ tokenHandler.endTokenization();
+ if (attributes != null) {
+ // [NOCPP[
+ attributes = null;
+ // ]NOCPP]
+ // CPPONLY: attributes.clear(mappingLangToXmlLang);
+ }
+ }
+
+ public void requestSuspension() {
+ shouldSuspend = true;
+ }
+
+ // [NOCPP[
+
+ public void becomeConfident() {
+ confident = true;
+ }
+
+ /**
+ * Returns the nextCharOnNewLine.
+ *
+ * @return the nextCharOnNewLine
+ */
+ public boolean isNextCharOnNewLine() {
+ return false;
+ }
+
+ public boolean isPrevCR() {
+ return lastCR;
+ }
+
+ /**
+ * Returns the line.
+ *
+ * @return the line
+ */
+ public int getLine() {
+ return -1;
+ }
+
+ /**
+ * Returns the col.
+ *
+ * @return the col
+ */
+ public int getCol() {
+ return -1;
+ }
+
+ // ]NOCPP]
+
+ public boolean isInDataState() {
+ return (stateSave == DATA);
+ }
+
+ public void resetToDataState() {
+ clearStrBufAfterUse();
+ charRefBufLen = 0;
+ stateSave = Tokenizer.DATA;
+ // line = 1; XXX line numbers
+ lastCR = false;
+ index = 0;
+ forceQuirks = false;
+ additional = '\u0000';
+ entCol = -1;
+ firstCharKey = -1;
+ lo = 0;
+ hi = 0; // will always be overwritten before use anyway
+ candidate = -1;
+ charRefBufMark = 0;
+ value = 0;
+ seenDigits = false;
+ endTag = false;
+ shouldSuspend = false;
+ initDoctypeFields();
+ if (tagName != null) {
+ tagName.release();
+ tagName = null;
+ }
+ if (attributeName != null) {
+ attributeName.release();
+ attributeName = null;
+ }
+ if (newAttributesEachTime) {
+ if (attributes != null) {
+ Portability.delete(attributes);
+ attributes = null;
+ }
+ }
+ }
+
+ public void loadState(Tokenizer other) throws SAXException {
+ strBufLen = other.strBufLen;
+ if (strBufLen > strBuf.length) {
+ strBuf = new char[strBufLen];
+ }
+ System.arraycopy(other.strBuf, 0, strBuf, 0, strBufLen);
+
+ charRefBufLen = other.charRefBufLen;
+ System.arraycopy(other.charRefBuf, 0, charRefBuf, 0, charRefBufLen);
+
+ stateSave = other.stateSave;
+ returnStateSave = other.returnStateSave;
+ endTagExpectation = other.endTagExpectation;
+ endTagExpectationAsArray = other.endTagExpectationAsArray;
+ // line = 1; XXX line numbers
+ lastCR = other.lastCR;
+ index = other.index;
+ forceQuirks = other.forceQuirks;
+ additional = other.additional;
+ entCol = other.entCol;
+ firstCharKey = other.firstCharKey;
+ lo = other.lo;
+ hi = other.hi;
+ candidate = other.candidate;
+ charRefBufMark = other.charRefBufMark;
+ value = other.value;
+ seenDigits = other.seenDigits;
+ endTag = other.endTag;
+ shouldSuspend = false;
+
+ if (other.doctypeName == null) {
+ doctypeName = null;
+ } else {
+ doctypeName = Portability.newLocalFromLocal(other.doctypeName,
+ interner);
+ }
+
+ Portability.releaseString(systemIdentifier);
+ if (other.systemIdentifier == null) {
+ systemIdentifier = null;
+ } else {
+ systemIdentifier = Portability.newStringFromString(other.systemIdentifier);
+ }
+
+ Portability.releaseString(publicIdentifier);
+ if (other.publicIdentifier == null) {
+ publicIdentifier = null;
+ } else {
+ publicIdentifier = Portability.newStringFromString(other.publicIdentifier);
+ }
+
+ if (tagName != null) {
+ tagName.release();
+ }
+ if (other.tagName == null) {
+ tagName = null;
+ } else {
+ tagName = other.tagName.cloneElementName(interner);
+ }
+
+ if (attributeName != null) {
+ attributeName.release();
+ }
+ if (other.attributeName == null) {
+ attributeName = null;
+ } else {
+ attributeName = other.attributeName.cloneAttributeName(interner);
+ }
+
+ Portability.delete(attributes);
+ if (other.attributes == null) {
+ attributes = null;
+ } else {
+ attributes = other.attributes.cloneAttributes(interner);
+ }
+ }
+
+ public void initializeWithoutStarting() throws SAXException {
+ confident = false;
+ strBuf = null;
+ line = 1;
+ // CPPONLY: attributeLine = 1;
+ // [NOCPP[
+ html4 = false;
+ metaBoundaryPassed = false;
+ wantsComments = tokenHandler.wantsComments();
+ if (!newAttributesEachTime) {
+ attributes = new HtmlAttributes(mappingLangToXmlLang);
+ }
+ // ]NOCPP]
+ resetToDataState();
+ }
+
+ protected void errGarbageAfterLtSlash() throws SAXException {
+ }
+
+ protected void errLtSlashGt() throws SAXException {
+ }
+
+ protected void errWarnLtSlashInRcdata() throws SAXException {
+ }
+
+ protected void errHtml4LtSlashInRcdata(char folded) throws SAXException {
+ }
+
+ protected void errCharRefLacksSemicolon() throws SAXException {
+ }
+
+ protected void errNoDigitsInNCR() throws SAXException {
+ }
+
+ protected void errGtInSystemId() throws SAXException {
+ }
+
+ protected void errGtInPublicId() throws SAXException {
+ }
+
+ protected void errNamelessDoctype() throws SAXException {
+ }
+
+ protected void errConsecutiveHyphens() throws SAXException {
+ }
+
+ protected void errPrematureEndOfComment() throws SAXException {
+ }
+
+ protected void errBogusComment() throws SAXException {
+ }
+
+ protected void errUnquotedAttributeValOrNull(char c) throws SAXException {
+ }
+
+ protected void errSlashNotFollowedByGt() throws SAXException {
+ }
+
+ protected void errHtml4XmlVoidSyntax() throws SAXException {
+ }
+
+ protected void errNoSpaceBetweenAttributes() throws SAXException {
+ }
+
+ protected void errHtml4NonNameInUnquotedAttribute(char c)
+ throws SAXException {
+ }
+
+ protected void errLtOrEqualsOrGraveInUnquotedAttributeOrNull(char c)
+ throws SAXException {
+ }
+
+ protected void errAttributeValueMissing() throws SAXException {
+ }
+
+ protected void errBadCharBeforeAttributeNameOrNull(char c)
+ throws SAXException {
+ }
+
+ protected void errEqualsSignBeforeAttributeName() throws SAXException {
+ }
+
+ protected void errBadCharAfterLt(char c) throws SAXException {
+ }
+
+ protected void errLtGt() throws SAXException {
+ }
+
+ protected void errProcessingInstruction() throws SAXException {
+ }
+
+ protected void errUnescapedAmpersandInterpretedAsCharacterReference()
+ throws SAXException {
+ }
+
+ protected void errNotSemicolonTerminated() throws SAXException {
+ }
+
+ protected void errNoNamedCharacterMatch() throws SAXException {
+ }
+
+ protected void errQuoteBeforeAttributeName(char c) throws SAXException {
+ }
+
+ protected void errQuoteOrLtInAttributeNameOrNull(char c)
+ throws SAXException {
+ }
+
+ protected void errExpectedPublicId() throws SAXException {
+ }
+
+ protected void errBogusDoctype() throws SAXException {
+ }
+
+ protected void maybeWarnPrivateUseAstral() throws SAXException {
+ }
+
+ protected void maybeWarnPrivateUse(char ch) throws SAXException {
+ }
+
+ protected void maybeErrAttributesOnEndTag(HtmlAttributes attrs)
+ throws SAXException {
+ }
+
+ protected void maybeErrSlashInEndTag(boolean selfClosing)
+ throws SAXException {
+ }
+
+ protected char errNcrNonCharacter(char ch) throws SAXException {
+ return ch;
+ }
+
+ protected void errAstralNonCharacter(int ch) throws SAXException {
+ }
+
+ protected void errNcrSurrogate() throws SAXException {
+ }
+
+ protected char errNcrControlChar(char ch) throws SAXException {
+ return ch;
+ }
+
+ protected void errNcrCr() throws SAXException {
+ }
+
+ protected void errNcrInC1Range() throws SAXException {
+ }
+
+ protected void errEofInPublicId() throws SAXException {
+ }
+
+ protected void errEofInComment() throws SAXException {
+ }
+
+ protected void errEofInDoctype() throws SAXException {
+ }
+
+ protected void errEofInAttributeValue() throws SAXException {
+ }
+
+ protected void errEofInAttributeName() throws SAXException {
+ }
+
+ protected void errEofWithoutGt() throws SAXException {
+ }
+
+ protected void errEofInTagName() throws SAXException {
+ }
+
+ protected void errEofInEndTag() throws SAXException {
+ }
+
+ protected void errEofAfterLt() throws SAXException {
+ }
+
+ protected void errNcrOutOfRange() throws SAXException {
+ }
+
+ protected void errNcrUnassigned() throws SAXException {
+ }
+
+ protected void errDuplicateAttribute() throws SAXException {
+ }
+
+ protected void errEofInSystemId() throws SAXException {
+ }
+
+ protected void errExpectedSystemId() throws SAXException {
+ }
+
+ protected void errMissingSpaceBeforeDoctypeName() throws SAXException {
+ }
+
+ protected void errHyphenHyphenBang() throws SAXException {
+ }
+
+ protected void errNcrControlChar() throws SAXException {
+ }
+
+ protected void errNcrZero() throws SAXException {
+ }
+
+ protected void errNoSpaceBetweenDoctypeSystemKeywordAndQuote()
+ throws SAXException {
+ }
+
+ protected void errNoSpaceBetweenPublicAndSystemIds() throws SAXException {
+ }
+
+ protected void errNoSpaceBetweenDoctypePublicKeywordAndQuote()
+ throws SAXException {
+ }
+
+ protected void noteAttributeWithoutValue() throws SAXException {
+ }
+
+ protected void noteUnquotedAttributeValue() throws SAXException {
+ }
+
+ /**
+ * Sets the encodingDeclarationHandler.
+ *
+ * @param encodingDeclarationHandler
+ * the encodingDeclarationHandler to set
+ */
+ public void setEncodingDeclarationHandler(
+ EncodingDeclarationHandler encodingDeclarationHandler) {
+ this.encodingDeclarationHandler = encodingDeclarationHandler;
+ }
+
+ void destructor() {
+ // The translator will write refcount tracing stuff here
+ Portability.delete(attributes);
+ attributes = null;
+ }
+
+ // [NOCPP[
+
+ /**
+ * Sets an offset to be added to the position reported to
+ * <code>TransitionHandler</code>.
+ *
+ * @param offset the offset
+ */
+ public void setTransitionBaseOffset(int offset) {
+
+ }
+
+ // ]NOCPP]
+
+}
diff --git a/parser/html/javasrc/TreeBuilder.java b/parser/html/javasrc/TreeBuilder.java
new file mode 100644
index 000000000..5e83d1847
--- /dev/null
+++ b/parser/html/javasrc/TreeBuilder.java
@@ -0,0 +1,6558 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 2007-2015 Mozilla Foundation
+ * Portions of comments Copyright 2004-2008 Apple Computer, Inc., Mozilla
+ * Foundation, and Opera Software ASA.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * The comments following this one that use the same comment syntax as this
+ * comment are quotes from the WHATWG HTML 5 spec as of 27 June 2007
+ * amended as of June 28 2007.
+ * That document came with this statement:
+ * "© Copyright 2004-2007 Apple Computer, Inc., Mozilla Foundation, and
+ * Opera Software ASA. You are granted a license to use, reproduce and
+ * create derivative works of this document."
+ */
+
+package nu.validator.htmlparser.impl;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import nu.validator.htmlparser.annotation.Auto;
+import nu.validator.htmlparser.annotation.Const;
+import nu.validator.htmlparser.annotation.IdType;
+import nu.validator.htmlparser.annotation.Inline;
+import nu.validator.htmlparser.annotation.Literal;
+import nu.validator.htmlparser.annotation.Local;
+import nu.validator.htmlparser.annotation.NoLength;
+import nu.validator.htmlparser.annotation.NsUri;
+import nu.validator.htmlparser.common.DoctypeExpectation;
+import nu.validator.htmlparser.common.DocumentMode;
+import nu.validator.htmlparser.common.DocumentModeHandler;
+import nu.validator.htmlparser.common.Interner;
+import nu.validator.htmlparser.common.TokenHandler;
+import nu.validator.htmlparser.common.XmlViolationPolicy;
+
+public abstract class TreeBuilder<T> implements TokenHandler,
+ TreeBuilderState<T> {
+
+ /**
+ * Array version of U+FFFD.
+ */
+ private static final @NoLength char[] REPLACEMENT_CHARACTER = { '\uFFFD' };
+
+ // Start dispatch groups
+
+ final static int OTHER = 0;
+
+ final static int A = 1;
+
+ final static int BASE = 2;
+
+ final static int BODY = 3;
+
+ final static int BR = 4;
+
+ final static int BUTTON = 5;
+
+ final static int CAPTION = 6;
+
+ final static int COL = 7;
+
+ final static int COLGROUP = 8;
+
+ final static int FORM = 9;
+
+ final static int FRAME = 10;
+
+ final static int FRAMESET = 11;
+
+ final static int IMAGE = 12;
+
+ final static int INPUT = 13;
+
+ final static int ISINDEX = 14;
+
+ final static int LI = 15;
+
+ final static int LINK_OR_BASEFONT_OR_BGSOUND = 16;
+
+ final static int MATH = 17;
+
+ final static int META = 18;
+
+ final static int SVG = 19;
+
+ final static int HEAD = 20;
+
+ final static int HR = 22;
+
+ final static int HTML = 23;
+
+ final static int NOBR = 24;
+
+ final static int NOFRAMES = 25;
+
+ final static int NOSCRIPT = 26;
+
+ final static int OPTGROUP = 27;
+
+ final static int OPTION = 28;
+
+ final static int P = 29;
+
+ final static int PLAINTEXT = 30;
+
+ final static int SCRIPT = 31;
+
+ final static int SELECT = 32;
+
+ final static int STYLE = 33;
+
+ final static int TABLE = 34;
+
+ final static int TEXTAREA = 35;
+
+ final static int TITLE = 36;
+
+ final static int TR = 37;
+
+ final static int XMP = 38;
+
+ final static int TBODY_OR_THEAD_OR_TFOOT = 39;
+
+ final static int TD_OR_TH = 40;
+
+ final static int DD_OR_DT = 41;
+
+ final static int H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 = 42;
+
+ final static int MARQUEE_OR_APPLET = 43;
+
+ final static int PRE_OR_LISTING = 44;
+
+ final static int B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U = 45;
+
+ final static int UL_OR_OL_OR_DL = 46;
+
+ final static int IFRAME = 47;
+
+ final static int EMBED = 48;
+
+ final static int AREA_OR_WBR = 49;
+
+ final static int DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU = 50;
+
+ final static int ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY = 51;
+
+ final static int RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR = 52;
+
+ final static int RB_OR_RTC = 53;
+
+ final static int PARAM_OR_SOURCE_OR_TRACK = 55;
+
+ final static int MGLYPH_OR_MALIGNMARK = 56;
+
+ final static int MI_MO_MN_MS_MTEXT = 57;
+
+ final static int ANNOTATION_XML = 58;
+
+ final static int FOREIGNOBJECT_OR_DESC = 59;
+
+ final static int NOEMBED = 60;
+
+ final static int FIELDSET = 61;
+
+ final static int OUTPUT = 62;
+
+ final static int OBJECT = 63;
+
+ final static int FONT = 64;
+
+ final static int KEYGEN = 65;
+
+ final static int MENUITEM = 66;
+
+ final static int TEMPLATE = 67;
+
+ final static int IMG = 68;
+
+ final static int RT_OR_RP = 69;
+
+ // start insertion modes
+
+ private static final int IN_ROW = 0;
+
+ private static final int IN_TABLE_BODY = 1;
+
+ private static final int IN_TABLE = 2;
+
+ private static final int IN_CAPTION = 3;
+
+ private static final int IN_CELL = 4;
+
+ private static final int FRAMESET_OK = 5;
+
+ private static final int IN_BODY = 6;
+
+ private static final int IN_HEAD = 7;
+
+ private static final int IN_HEAD_NOSCRIPT = 8;
+
+ // no fall-through
+
+ private static final int IN_COLUMN_GROUP = 9;
+
+ // no fall-through
+
+ private static final int IN_SELECT_IN_TABLE = 10;
+
+ private static final int IN_SELECT = 11;
+
+ // no fall-through
+
+ private static final int AFTER_BODY = 12;
+
+ // no fall-through
+
+ private static final int IN_FRAMESET = 13;
+
+ private static final int AFTER_FRAMESET = 14;
+
+ // no fall-through
+
+ private static final int INITIAL = 15;
+
+ // could add fall-through
+
+ private static final int BEFORE_HTML = 16;
+
+ // could add fall-through
+
+ private static final int BEFORE_HEAD = 17;
+
+ // no fall-through
+
+ private static final int AFTER_HEAD = 18;
+
+ // no fall-through
+
+ private static final int AFTER_AFTER_BODY = 19;
+
+ // no fall-through
+
+ private static final int AFTER_AFTER_FRAMESET = 20;
+
+ // no fall-through
+
+ private static final int TEXT = 21;
+
+ private static final int IN_TEMPLATE = 22;
+
+ // start charset states
+
+ private static final int CHARSET_INITIAL = 0;
+
+ private static final int CHARSET_C = 1;
+
+ private static final int CHARSET_H = 2;
+
+ private static final int CHARSET_A = 3;
+
+ private static final int CHARSET_R = 4;
+
+ private static final int CHARSET_S = 5;
+
+ private static final int CHARSET_E = 6;
+
+ private static final int CHARSET_T = 7;
+
+ private static final int CHARSET_EQUALS = 8;
+
+ private static final int CHARSET_SINGLE_QUOTED = 9;
+
+ private static final int CHARSET_DOUBLE_QUOTED = 10;
+
+ private static final int CHARSET_UNQUOTED = 11;
+
+ // end pseudo enums
+
+ // [NOCPP[
+
+ private final static String[] HTML4_PUBLIC_IDS = {
+ "-//W3C//DTD HTML 4.0 Frameset//EN",
+ "-//W3C//DTD HTML 4.0 Transitional//EN",
+ "-//W3C//DTD HTML 4.0//EN", "-//W3C//DTD HTML 4.01 Frameset//EN",
+ "-//W3C//DTD HTML 4.01 Transitional//EN",
+ "-//W3C//DTD HTML 4.01//EN" };
+
+ // ]NOCPP]
+
+ @Literal private final static String[] QUIRKY_PUBLIC_IDS = {
+ "+//silmaril//dtd html pro v0r11 19970101//",
+ "-//advasoft ltd//dtd html 3.0 aswedit + extensions//",
+ "-//as//dtd html 3.0 aswedit + extensions//",
+ "-//ietf//dtd html 2.0 level 1//",
+ "-//ietf//dtd html 2.0 level 2//",
+ "-//ietf//dtd html 2.0 strict level 1//",
+ "-//ietf//dtd html 2.0 strict level 2//",
+ "-//ietf//dtd html 2.0 strict//",
+ "-//ietf//dtd html 2.0//",
+ "-//ietf//dtd html 2.1e//",
+ "-//ietf//dtd html 3.0//",
+ "-//ietf//dtd html 3.2 final//",
+ "-//ietf//dtd html 3.2//",
+ "-//ietf//dtd html 3//",
+ "-//ietf//dtd html level 0//",
+ "-//ietf//dtd html level 1//",
+ "-//ietf//dtd html level 2//",
+ "-//ietf//dtd html level 3//",
+ "-//ietf//dtd html strict level 0//",
+ "-//ietf//dtd html strict level 1//",
+ "-//ietf//dtd html strict level 2//",
+ "-//ietf//dtd html strict level 3//",
+ "-//ietf//dtd html strict//",
+ "-//ietf//dtd html//",
+ "-//metrius//dtd metrius presentational//",
+ "-//microsoft//dtd internet explorer 2.0 html strict//",
+ "-//microsoft//dtd internet explorer 2.0 html//",
+ "-//microsoft//dtd internet explorer 2.0 tables//",
+ "-//microsoft//dtd internet explorer 3.0 html strict//",
+ "-//microsoft//dtd internet explorer 3.0 html//",
+ "-//microsoft//dtd internet explorer 3.0 tables//",
+ "-//netscape comm. corp.//dtd html//",
+ "-//netscape comm. corp.//dtd strict html//",
+ "-//o'reilly and associates//dtd html 2.0//",
+ "-//o'reilly and associates//dtd html extended 1.0//",
+ "-//o'reilly and associates//dtd html extended relaxed 1.0//",
+ "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//",
+ "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//",
+ "-//spyglass//dtd html 2.0 extended//",
+ "-//sq//dtd html 2.0 hotmetal + extensions//",
+ "-//sun microsystems corp.//dtd hotjava html//",
+ "-//sun microsystems corp.//dtd hotjava strict html//",
+ "-//w3c//dtd html 3 1995-03-24//", "-//w3c//dtd html 3.2 draft//",
+ "-//w3c//dtd html 3.2 final//", "-//w3c//dtd html 3.2//",
+ "-//w3c//dtd html 3.2s draft//", "-//w3c//dtd html 4.0 frameset//",
+ "-//w3c//dtd html 4.0 transitional//",
+ "-//w3c//dtd html experimental 19960712//",
+ "-//w3c//dtd html experimental 970421//", "-//w3c//dtd w3 html//",
+ "-//w3o//dtd w3 html 3.0//", "-//webtechs//dtd mozilla html 2.0//",
+ "-//webtechs//dtd mozilla html//" };
+
+ private static final int NOT_FOUND_ON_STACK = Integer.MAX_VALUE;
+
+ // [NOCPP[
+
+ private static final @Local String HTML_LOCAL = "html";
+
+ // ]NOCPP]
+
+ private int mode = INITIAL;
+
+ private int originalMode = INITIAL;
+
+ /**
+ * Used only when moving back to IN_BODY.
+ */
+ private boolean framesetOk = true;
+
+ protected Tokenizer tokenizer;
+
+ // [NOCPP[
+
+ protected ErrorHandler errorHandler;
+
+ private DocumentModeHandler documentModeHandler;
+
+ private DoctypeExpectation doctypeExpectation = DoctypeExpectation.HTML;
+
+ private LocatorImpl firstCommentLocation;
+
+ // ]NOCPP]
+
+ private boolean scriptingEnabled = false;
+
+ private boolean needToDropLF;
+
+ // [NOCPP[
+
+ private boolean wantingComments;
+
+ // ]NOCPP]
+
+ private boolean fragment;
+
+ private @Local String contextName;
+
+ private @NsUri String contextNamespace;
+
+ private T contextNode;
+
+ /**
+ * Stack of template insertion modes
+ */
+ private @Auto int[] templateModeStack;
+
+ /**
+ * Current template mode stack pointer.
+ */
+ private int templateModePtr = -1;
+
+ private @Auto StackNode<T>[] stack;
+
+ private int currentPtr = -1;
+
+ private @Auto StackNode<T>[] listOfActiveFormattingElements;
+
+ private int listPtr = -1;
+
+ private T formPointer;
+
+ private T headPointer;
+
+ /**
+ * Used to work around Gecko limitations. Not used in Java.
+ */
+ private T deepTreeSurrogateParent;
+
+ protected @Auto char[] charBuffer;
+
+ protected int charBufferLen = 0;
+
+ private boolean quirks = false;
+
+ private boolean isSrcdocDocument = false;
+
+ // [NOCPP[
+
+ private boolean reportingDoctype = true;
+
+ private XmlViolationPolicy namePolicy = XmlViolationPolicy.ALTER_INFOSET;
+
+ private final Map<String, LocatorImpl> idLocations = new HashMap<String, LocatorImpl>();
+
+ private boolean html4;
+
+ // ]NOCPP]
+
+ protected TreeBuilder() {
+ fragment = false;
+ }
+
+ /**
+ * Reports an condition that would make the infoset incompatible with XML
+ * 1.0 as fatal.
+ *
+ * @throws SAXException
+ * @throws SAXParseException
+ */
+ protected void fatal() throws SAXException {
+ }
+
+ // [NOCPP[
+
+ protected final void fatal(Exception e) throws SAXException {
+ SAXParseException spe = new SAXParseException(e.getMessage(),
+ tokenizer, e);
+ if (errorHandler != null) {
+ errorHandler.fatalError(spe);
+ }
+ throw spe;
+ }
+
+ final void fatal(String s) throws SAXException {
+ SAXParseException spe = new SAXParseException(s, tokenizer);
+ if (errorHandler != null) {
+ errorHandler.fatalError(spe);
+ }
+ throw spe;
+ }
+
+ /**
+ * Reports a Parse Error.
+ *
+ * @param message
+ * the message
+ * @throws SAXException
+ */
+ final void err(String message) throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck(message);
+ }
+
+ /**
+ * Reports a Parse Error without checking if an error handler is present.
+ *
+ * @param message
+ * the message
+ * @throws SAXException
+ */
+ final void errNoCheck(String message) throws SAXException {
+ SAXParseException spe = new SAXParseException(message, tokenizer);
+ errorHandler.error(spe);
+ }
+
+ private void errListUnclosedStartTags(int eltPos) throws SAXException {
+ if (currentPtr != -1) {
+ for (int i = currentPtr; i > eltPos; i--) {
+ reportUnclosedElementNameAndLocation(i);
+ }
+ }
+ }
+
+ /**
+ * Reports the name and location of an unclosed element.
+ *
+ * @throws SAXException
+ */
+ private final void reportUnclosedElementNameAndLocation(int pos) throws SAXException {
+ StackNode<T> node = stack[pos];
+ if (node.isOptionalEndTag()) {
+ return;
+ }
+ TaintableLocatorImpl locator = node.getLocator();
+ if (locator.isTainted()) {
+ return;
+ }
+ locator.markTainted();
+ SAXParseException spe = new SAXParseException(
+ "Unclosed element \u201C" + node.popName + "\u201D.", locator);
+ errorHandler.error(spe);
+ }
+
+ /**
+ * Reports a warning
+ *
+ * @param message
+ * the message
+ * @throws SAXException
+ */
+ final void warn(String message) throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ SAXParseException spe = new SAXParseException(message, tokenizer);
+ errorHandler.warning(spe);
+ }
+
+ /**
+ * Reports a warning with an explicit locator
+ *
+ * @param message
+ * the message
+ * @throws SAXException
+ */
+ final void warn(String message, Locator locator) throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ SAXParseException spe = new SAXParseException(message, locator);
+ errorHandler.warning(spe);
+ }
+
+ // ]NOCPP]
+
+ @SuppressWarnings("unchecked") public final void startTokenization(Tokenizer self) throws SAXException {
+ tokenizer = self;
+ stack = new StackNode[64];
+ templateModeStack = new int[64];
+ listOfActiveFormattingElements = new StackNode[64];
+ needToDropLF = false;
+ originalMode = INITIAL;
+ templateModePtr = -1;
+ currentPtr = -1;
+ listPtr = -1;
+ formPointer = null;
+ headPointer = null;
+ deepTreeSurrogateParent = null;
+ // [NOCPP[
+ html4 = false;
+ idLocations.clear();
+ wantingComments = wantsComments();
+ firstCommentLocation = null;
+ // ]NOCPP]
+ start(fragment);
+ charBufferLen = 0;
+ charBuffer = null;
+ framesetOk = true;
+ if (fragment) {
+ T elt;
+ if (contextNode != null) {
+ elt = contextNode;
+ } else {
+ elt = createHtmlElementSetAsRoot(tokenizer.emptyAttributes());
+ }
+ // When the context node is not in the HTML namespace, contrary
+ // to the spec, the first node on the stack is not set to "html"
+ // in the HTML namespace. Instead, it is set to a node that has
+ // the characteristics of the appropriate "adjusted current node".
+ // This way, there is no need to perform "adjusted current node"
+ // checks during tree construction. Instead, it's sufficient to
+ // just look at the current node. However, this also means that it
+ // is not safe to treat "html" in the HTML namespace as a sentinel
+ // that ends stack popping. Instead, stack popping loops that are
+ // meant not to pop the first element on the stack need to check
+ // for currentPos becoming zero.
+ if (contextNamespace == "http://www.w3.org/2000/svg") {
+ ElementName elementName = ElementName.SVG;
+ if ("title" == contextName || "desc" == contextName
+ || "foreignObject" == contextName) {
+ // These elements are all alike and we don't care about
+ // the exact name.
+ elementName = ElementName.FOREIGNOBJECT;
+ }
+ // This is the SVG variant of the StackNode constructor.
+ StackNode<T> node = new StackNode<T>(elementName,
+ elementName.camelCaseName, elt
+ // [NOCPP[
+ , errorHandler == null ? null
+ : new TaintableLocatorImpl(tokenizer)
+ // ]NOCPP]
+ );
+ currentPtr++;
+ stack[currentPtr] = node;
+ tokenizer.setStateAndEndTagExpectation(Tokenizer.DATA,
+ contextName);
+ // The frameset-ok flag is set even though <frameset> never
+ // ends up being allowed as HTML frameset in the fragment case.
+ mode = FRAMESET_OK;
+ } else if (contextNamespace == "http://www.w3.org/1998/Math/MathML") {
+ ElementName elementName = ElementName.MATH;
+ if ("mi" == contextName || "mo" == contextName
+ || "mn" == contextName || "ms" == contextName
+ || "mtext" == contextName) {
+ // These elements are all alike and we don't care about
+ // the exact name.
+ elementName = ElementName.MTEXT;
+ } else if ("annotation-xml" == contextName) {
+ elementName = ElementName.ANNOTATION_XML;
+ // Blink does not check the encoding attribute of the
+ // annotation-xml element innerHTML is being set on.
+ // Let's do the same at least until
+ // https://www.w3.org/Bugs/Public/show_bug.cgi?id=26783
+ // is resolved.
+ }
+ // This is the MathML variant of the StackNode constructor.
+ StackNode<T> node = new StackNode<T>(elementName, elt,
+ elementName.name, false
+ // [NOCPP[
+ , errorHandler == null ? null
+ : new TaintableLocatorImpl(tokenizer)
+ // ]NOCPP]
+ );
+ currentPtr++;
+ stack[currentPtr] = node;
+ tokenizer.setStateAndEndTagExpectation(Tokenizer.DATA,
+ contextName);
+ // The frameset-ok flag is set even though <frameset> never
+ // ends up being allowed as HTML frameset in the fragment case.
+ mode = FRAMESET_OK;
+ } else { // html
+ StackNode<T> node = new StackNode<T>(ElementName.HTML, elt
+ // [NOCPP[
+ , errorHandler == null ? null
+ : new TaintableLocatorImpl(tokenizer)
+ // ]NOCPP]
+ );
+ currentPtr++;
+ stack[currentPtr] = node;
+ if ("template" == contextName) {
+ pushTemplateMode(IN_TEMPLATE);
+ }
+ resetTheInsertionMode();
+ formPointer = getFormPointerForContext(contextNode);
+ if ("title" == contextName || "textarea" == contextName) {
+ tokenizer.setStateAndEndTagExpectation(Tokenizer.RCDATA,
+ contextName);
+ } else if ("style" == contextName || "xmp" == contextName
+ || "iframe" == contextName || "noembed" == contextName
+ || "noframes" == contextName
+ || (scriptingEnabled && "noscript" == contextName)) {
+ tokenizer.setStateAndEndTagExpectation(Tokenizer.RAWTEXT,
+ contextName);
+ } else if ("plaintext" == contextName) {
+ tokenizer.setStateAndEndTagExpectation(Tokenizer.PLAINTEXT,
+ contextName);
+ } else if ("script" == contextName) {
+ tokenizer.setStateAndEndTagExpectation(
+ Tokenizer.SCRIPT_DATA, contextName);
+ } else {
+ tokenizer.setStateAndEndTagExpectation(Tokenizer.DATA,
+ contextName);
+ }
+ }
+ contextName = null;
+ contextNode = null;
+ } else {
+ mode = INITIAL;
+ // If we are viewing XML source, put a foreign element permanently
+ // on the stack so that cdataSectionAllowed() returns true.
+ // CPPONLY: if (tokenizer.isViewingXmlSource()) {
+ // CPPONLY: T elt = createElement("http://www.w3.org/2000/svg",
+ // CPPONLY: "svg",
+ // CPPONLY: tokenizer.emptyAttributes(), null);
+ // CPPONLY: StackNode<T> node = new StackNode<T>(ElementName.SVG,
+ // CPPONLY: "svg",
+ // CPPONLY: elt);
+ // CPPONLY: currentPtr++;
+ // CPPONLY: stack[currentPtr] = node;
+ // CPPONLY: }
+ }
+ }
+
+ public final void doctype(@Local String name, String publicIdentifier,
+ String systemIdentifier, boolean forceQuirks) throws SAXException {
+ needToDropLF = false;
+ if (!isInForeign() && mode == INITIAL) {
+ // [NOCPP[
+ if (reportingDoctype) {
+ // ]NOCPP]
+ String emptyString = Portability.newEmptyString();
+ appendDoctypeToDocument(name == null ? "" : name,
+ publicIdentifier == null ? emptyString
+ : publicIdentifier,
+ systemIdentifier == null ? emptyString
+ : systemIdentifier);
+ Portability.releaseString(emptyString);
+ // [NOCPP[
+ }
+ switch (doctypeExpectation) {
+ case HTML:
+ // ]NOCPP]
+ if (isQuirky(name, publicIdentifier, systemIdentifier,
+ forceQuirks)) {
+ errQuirkyDoctype();
+ documentModeInternal(DocumentMode.QUIRKS_MODE,
+ publicIdentifier, systemIdentifier, false);
+ } else if (isAlmostStandards(publicIdentifier,
+ systemIdentifier)) {
+ // [NOCPP[
+ if (firstCommentLocation != null) {
+ warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.",
+ firstCommentLocation);
+ }
+ // ]NOCPP]
+ errAlmostStandardsDoctype();
+ documentModeInternal(
+ DocumentMode.ALMOST_STANDARDS_MODE,
+ publicIdentifier, systemIdentifier, false);
+ } else {
+ // [NOCPP[
+ if (firstCommentLocation != null) {
+ warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.",
+ firstCommentLocation);
+ }
+ if ((Portability.literalEqualsString(
+ "-//W3C//DTD HTML 4.0//EN", publicIdentifier) && (systemIdentifier == null || Portability.literalEqualsString(
+ "http://www.w3.org/TR/REC-html40/strict.dtd",
+ systemIdentifier)))
+ || (Portability.literalEqualsString(
+ "-//W3C//DTD HTML 4.01//EN",
+ publicIdentifier) && (systemIdentifier == null || Portability.literalEqualsString(
+ "http://www.w3.org/TR/html4/strict.dtd",
+ systemIdentifier)))
+ || (Portability.literalEqualsString(
+ "-//W3C//DTD XHTML 1.0 Strict//EN",
+ publicIdentifier) && Portability.literalEqualsString(
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd",
+ systemIdentifier))
+ || (Portability.literalEqualsString(
+ "-//W3C//DTD XHTML 1.1//EN",
+ publicIdentifier) && Portability.literalEqualsString(
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd",
+ systemIdentifier))
+
+ ) {
+ warn("Obsolete doctype. Expected \u201C<!DOCTYPE html>\u201D.");
+ } else if (!((systemIdentifier == null || Portability.literalEqualsString(
+ "about:legacy-compat", systemIdentifier)) && publicIdentifier == null)) {
+ err("Legacy doctype. Expected \u201C<!DOCTYPE html>\u201D.");
+ }
+ // ]NOCPP]
+ documentModeInternal(DocumentMode.STANDARDS_MODE,
+ publicIdentifier, systemIdentifier, false);
+ }
+ // [NOCPP[
+ break;
+ case HTML401_STRICT:
+ html4 = true;
+ tokenizer.turnOnAdditionalHtml4Errors();
+ if (isQuirky(name, publicIdentifier, systemIdentifier,
+ forceQuirks)) {
+ err("Quirky doctype. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
+ documentModeInternal(DocumentMode.QUIRKS_MODE,
+ publicIdentifier, systemIdentifier, true);
+ } else if (isAlmostStandards(publicIdentifier,
+ systemIdentifier)) {
+ if (firstCommentLocation != null) {
+ warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.",
+ firstCommentLocation);
+ }
+ err("Almost standards mode doctype. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
+ documentModeInternal(
+ DocumentMode.ALMOST_STANDARDS_MODE,
+ publicIdentifier, systemIdentifier, true);
+ } else {
+ if (firstCommentLocation != null) {
+ warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.",
+ firstCommentLocation);
+ }
+ if ("-//W3C//DTD HTML 4.01//EN".equals(publicIdentifier)) {
+ if (!"http://www.w3.org/TR/html4/strict.dtd".equals(systemIdentifier)) {
+ warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
+ }
+ } else {
+ err("The doctype was not the HTML 4.01 Strict doctype. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
+ }
+ documentModeInternal(DocumentMode.STANDARDS_MODE,
+ publicIdentifier, systemIdentifier, true);
+ }
+ break;
+ case HTML401_TRANSITIONAL:
+ html4 = true;
+ tokenizer.turnOnAdditionalHtml4Errors();
+ if (isQuirky(name, publicIdentifier, systemIdentifier,
+ forceQuirks)) {
+ err("Quirky doctype. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
+ documentModeInternal(DocumentMode.QUIRKS_MODE,
+ publicIdentifier, systemIdentifier, true);
+ } else if (isAlmostStandards(publicIdentifier,
+ systemIdentifier)) {
+ if (firstCommentLocation != null) {
+ warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.",
+ firstCommentLocation);
+ }
+ if ("-//W3C//DTD HTML 4.01 Transitional//EN".equals(publicIdentifier)
+ && systemIdentifier != null) {
+ if (!"http://www.w3.org/TR/html4/loose.dtd".equals(systemIdentifier)) {
+ warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
+ }
+ } else {
+ err("The doctype was not a non-quirky HTML 4.01 Transitional doctype. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
+ }
+ documentModeInternal(
+ DocumentMode.ALMOST_STANDARDS_MODE,
+ publicIdentifier, systemIdentifier, true);
+ } else {
+ if (firstCommentLocation != null) {
+ warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.",
+ firstCommentLocation);
+ }
+ err("The doctype was not the HTML 4.01 Transitional doctype. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
+ documentModeInternal(DocumentMode.STANDARDS_MODE,
+ publicIdentifier, systemIdentifier, true);
+ }
+ break;
+ case AUTO:
+ html4 = isHtml4Doctype(publicIdentifier);
+ if (html4) {
+ tokenizer.turnOnAdditionalHtml4Errors();
+ }
+ if (isQuirky(name, publicIdentifier, systemIdentifier,
+ forceQuirks)) {
+ err("Quirky doctype. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
+ documentModeInternal(DocumentMode.QUIRKS_MODE,
+ publicIdentifier, systemIdentifier, html4);
+ } else if (isAlmostStandards(publicIdentifier,
+ systemIdentifier)) {
+ if (firstCommentLocation != null) {
+ warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.",
+ firstCommentLocation);
+ }
+ if ("-//W3C//DTD HTML 4.01 Transitional//EN".equals(publicIdentifier)) {
+ if (!"http://www.w3.org/TR/html4/loose.dtd".equals(systemIdentifier)) {
+ warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
+ }
+ } else {
+ err("Almost standards mode doctype. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
+ }
+ documentModeInternal(
+ DocumentMode.ALMOST_STANDARDS_MODE,
+ publicIdentifier, systemIdentifier, html4);
+ } else {
+ if (firstCommentLocation != null) {
+ warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.",
+ firstCommentLocation);
+ }
+ if ("-//W3C//DTD HTML 4.01//EN".equals(publicIdentifier)) {
+ if (!"http://www.w3.org/TR/html4/strict.dtd".equals(systemIdentifier)) {
+ warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
+ }
+ } else if ("-//W3C//DTD XHTML 1.0 Strict//EN".equals(publicIdentifier)) {
+ if (!"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd".equals(systemIdentifier)) {
+ warn("The doctype did not contain the system identifier prescribed by the XHTML 1.0 specification. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\u201D.");
+ }
+ } else if ("//W3C//DTD XHTML 1.1//EN".equals(publicIdentifier)) {
+ if (!"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd".equals(systemIdentifier)) {
+ warn("The doctype did not contain the system identifier prescribed by the XHTML 1.1 specification. Expected \u201C<!DOCTYPE HTML PUBLIC \"//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\u201D.");
+ }
+ } else if (!((systemIdentifier == null || Portability.literalEqualsString(
+ "about:legacy-compat", systemIdentifier)) && publicIdentifier == null)) {
+ err("Unexpected doctype. Expected, e.g., \u201C<!DOCTYPE html>\u201D.");
+ }
+ documentModeInternal(DocumentMode.STANDARDS_MODE,
+ publicIdentifier, systemIdentifier, html4);
+ }
+ break;
+ case NO_DOCTYPE_ERRORS:
+ if (isQuirky(name, publicIdentifier, systemIdentifier,
+ forceQuirks)) {
+ documentModeInternal(DocumentMode.QUIRKS_MODE,
+ publicIdentifier, systemIdentifier, false);
+ } else if (isAlmostStandards(publicIdentifier,
+ systemIdentifier)) {
+ documentModeInternal(
+ DocumentMode.ALMOST_STANDARDS_MODE,
+ publicIdentifier, systemIdentifier, false);
+ } else {
+ documentModeInternal(DocumentMode.STANDARDS_MODE,
+ publicIdentifier, systemIdentifier, false);
+ }
+ break;
+ }
+ // ]NOCPP]
+
+ /*
+ *
+ * Then, switch to the root element mode of the tree construction
+ * stage.
+ */
+ mode = BEFORE_HTML;
+ return;
+ }
+ /*
+ * A DOCTYPE token Parse error.
+ */
+ errStrayDoctype();
+ /*
+ * Ignore the token.
+ */
+ return;
+ }
+
+ // [NOCPP[
+
+ private boolean isHtml4Doctype(String publicIdentifier) {
+ if (publicIdentifier != null
+ && (Arrays.binarySearch(TreeBuilder.HTML4_PUBLIC_IDS,
+ publicIdentifier) > -1)) {
+ return true;
+ }
+ return false;
+ }
+
+ // ]NOCPP]
+
+ public final void comment(@NoLength char[] buf, int start, int length)
+ throws SAXException {
+ needToDropLF = false;
+ // [NOCPP[
+ if (firstCommentLocation == null) {
+ firstCommentLocation = new LocatorImpl(tokenizer);
+ }
+ if (!wantingComments) {
+ return;
+ }
+ // ]NOCPP]
+ if (!isInForeign()) {
+ switch (mode) {
+ case INITIAL:
+ case BEFORE_HTML:
+ case AFTER_AFTER_BODY:
+ case AFTER_AFTER_FRAMESET:
+ /*
+ * A comment token Append a Comment node to the Document
+ * object with the data attribute set to the data given in
+ * the comment token.
+ */
+ appendCommentToDocument(buf, start, length);
+ return;
+ case AFTER_BODY:
+ /*
+ * A comment token Append a Comment node to the first
+ * element in the stack of open elements (the html element),
+ * with the data attribute set to the data given in the
+ * comment token.
+ */
+ flushCharacters();
+ appendComment(stack[0].node, buf, start, length);
+ return;
+ default:
+ break;
+ }
+ }
+ /*
+ * A comment token Append a Comment node to the current node with the
+ * data attribute set to the data given in the comment token.
+ */
+ flushCharacters();
+ appendComment(stack[currentPtr].node, buf, start, length);
+ return;
+ }
+
+ /**
+ * @see nu.validator.htmlparser.common.TokenHandler#characters(char[], int,
+ * int)
+ */
+ public final void characters(@Const @NoLength char[] buf, int start, int length)
+ throws SAXException {
+ // Note: Can't attach error messages to EOF in C++ yet
+
+ // CPPONLY: if (tokenizer.isViewingXmlSource()) {
+ // CPPONLY: return;
+ // CPPONLY: }
+ if (needToDropLF) {
+ needToDropLF = false;
+ if (buf[start] == '\n') {
+ start++;
+ length--;
+ if (length == 0) {
+ return;
+ }
+ }
+ }
+
+ // optimize the most common case
+ switch (mode) {
+ case IN_BODY:
+ case IN_CELL:
+ case IN_CAPTION:
+ if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
+ reconstructTheActiveFormattingElements();
+ }
+ // fall through
+ case TEXT:
+ accumulateCharacters(buf, start, length);
+ return;
+ case IN_TABLE:
+ case IN_TABLE_BODY:
+ case IN_ROW:
+ accumulateCharactersForced(buf, start, length);
+ return;
+ default:
+ int end = start + length;
+ charactersloop: for (int i = start; i < end; i++) {
+ switch (buf[i]) {
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ case '\u000C':
+ /*
+ * A character token that is one of one of U+0009
+ * CHARACTER TABULATION, U+000A LINE FEED (LF),
+ * U+000C FORM FEED (FF), or U+0020 SPACE
+ */
+ switch (mode) {
+ case INITIAL:
+ case BEFORE_HTML:
+ case BEFORE_HEAD:
+ /*
+ * Ignore the token.
+ */
+ start = i + 1;
+ continue;
+ case IN_HEAD:
+ case IN_HEAD_NOSCRIPT:
+ case AFTER_HEAD:
+ case IN_COLUMN_GROUP:
+ case IN_FRAMESET:
+ case AFTER_FRAMESET:
+ /*
+ * Append the character to the current node.
+ */
+ continue;
+ case FRAMESET_OK:
+ case IN_TEMPLATE:
+ case IN_BODY:
+ case IN_CELL:
+ case IN_CAPTION:
+ if (start < i) {
+ accumulateCharacters(buf, start, i
+ - start);
+ start = i;
+ }
+
+ /*
+ * Reconstruct the active formatting
+ * elements, if any.
+ */
+ if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
+ flushCharacters();
+ reconstructTheActiveFormattingElements();
+ }
+ /*
+ * Append the token's character to the
+ * current node.
+ */
+ break charactersloop;
+ case IN_SELECT:
+ case IN_SELECT_IN_TABLE:
+ break charactersloop;
+ case IN_TABLE:
+ case IN_TABLE_BODY:
+ case IN_ROW:
+ accumulateCharactersForced(buf, i, 1);
+ start = i + 1;
+ continue;
+ case AFTER_BODY:
+ case AFTER_AFTER_BODY:
+ case AFTER_AFTER_FRAMESET:
+ if (start < i) {
+ accumulateCharacters(buf, start, i
+ - start);
+ start = i;
+ }
+ /*
+ * Reconstruct the active formatting
+ * elements, if any.
+ */
+ flushCharacters();
+ reconstructTheActiveFormattingElements();
+ /*
+ * Append the token's character to the
+ * current node.
+ */
+ continue;
+ }
+ default:
+ /*
+ * A character token that is not one of one of
+ * U+0009 CHARACTER TABULATION, U+000A LINE FEED
+ * (LF), U+000C FORM FEED (FF), or U+0020 SPACE
+ */
+ switch (mode) {
+ case INITIAL:
+ /*
+ * Parse error.
+ */
+ // [NOCPP[
+ switch (doctypeExpectation) {
+ case AUTO:
+ err("Non-space characters found without seeing a doctype first. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
+ break;
+ case HTML:
+ // XXX figure out a way to report this in the Gecko View Source case
+ err("Non-space characters found without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
+ break;
+ case HTML401_STRICT:
+ err("Non-space characters found without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
+ break;
+ case HTML401_TRANSITIONAL:
+ err("Non-space characters found without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
+ break;
+ case NO_DOCTYPE_ERRORS:
+ }
+ // ]NOCPP]
+ /*
+ *
+ * Set the document to quirks mode.
+ */
+ documentModeInternal(
+ DocumentMode.QUIRKS_MODE, null,
+ null, false);
+ /*
+ * Then, switch to the root element mode of
+ * the tree construction stage
+ */
+ mode = BEFORE_HTML;
+ /*
+ * and reprocess the current token.
+ */
+ i--;
+ continue;
+ case BEFORE_HTML:
+ /*
+ * Create an HTMLElement node with the tag
+ * name html, in the HTML namespace. Append
+ * it to the Document object.
+ */
+ // No need to flush characters here,
+ // because there's nothing to flush.
+ appendHtmlElementToDocumentAndPush();
+ /* Switch to the main mode */
+ mode = BEFORE_HEAD;
+ /*
+ * reprocess the current token.
+ */
+ i--;
+ continue;
+ case BEFORE_HEAD:
+ if (start < i) {
+ accumulateCharacters(buf, start, i
+ - start);
+ start = i;
+ }
+ /*
+ * /Act as if a start tag token with the tag
+ * name "head" and no attributes had been
+ * seen,
+ */
+ flushCharacters();
+ appendToCurrentNodeAndPushHeadElement(HtmlAttributes.EMPTY_ATTRIBUTES);
+ mode = IN_HEAD;
+ /*
+ * then reprocess the current token.
+ *
+ * This will result in an empty head element
+ * being generated, with the current token
+ * being reprocessed in the "after head"
+ * insertion mode.
+ */
+ i--;
+ continue;
+ case IN_HEAD:
+ if (start < i) {
+ accumulateCharacters(buf, start, i
+ - start);
+ start = i;
+ }
+ /*
+ * Act as if an end tag token with the tag
+ * name "head" had been seen,
+ */
+ flushCharacters();
+ pop();
+ mode = AFTER_HEAD;
+ /*
+ * and reprocess the current token.
+ */
+ i--;
+ continue;
+ case IN_HEAD_NOSCRIPT:
+ if (start < i) {
+ accumulateCharacters(buf, start, i
+ - start);
+ start = i;
+ }
+ /*
+ * Parse error. Act as if an end tag with
+ * the tag name "noscript" had been seen
+ */
+ errNonSpaceInNoscriptInHead();
+ flushCharacters();
+ pop();
+ mode = IN_HEAD;
+ /*
+ * and reprocess the current token.
+ */
+ i--;
+ continue;
+ case AFTER_HEAD:
+ if (start < i) {
+ accumulateCharacters(buf, start, i
+ - start);
+ start = i;
+ }
+ /*
+ * Act as if a start tag token with the tag
+ * name "body" and no attributes had been
+ * seen,
+ */
+ flushCharacters();
+ appendToCurrentNodeAndPushBodyElement();
+ mode = FRAMESET_OK;
+ /*
+ * and then reprocess the current token.
+ */
+ i--;
+ continue;
+ case FRAMESET_OK:
+ framesetOk = false;
+ mode = IN_BODY;
+ i--;
+ continue;
+ case IN_TEMPLATE:
+ case IN_BODY:
+ case IN_CELL:
+ case IN_CAPTION:
+ if (start < i) {
+ accumulateCharacters(buf, start, i
+ - start);
+ start = i;
+ }
+ /*
+ * Reconstruct the active formatting
+ * elements, if any.
+ */
+ if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
+ flushCharacters();
+ reconstructTheActiveFormattingElements();
+ }
+ /*
+ * Append the token's character to the
+ * current node.
+ */
+ break charactersloop;
+ case IN_TABLE:
+ case IN_TABLE_BODY:
+ case IN_ROW:
+ accumulateCharactersForced(buf, i, 1);
+ start = i + 1;
+ continue;
+ case IN_COLUMN_GROUP:
+ if (start < i) {
+ accumulateCharacters(buf, start, i
+ - start);
+ start = i;
+ }
+ /*
+ * Act as if an end tag with the tag name
+ * "colgroup" had been seen, and then, if
+ * that token wasn't ignored, reprocess the
+ * current token.
+ */
+ if (currentPtr == 0 || stack[currentPtr].getGroup() ==
+ TreeBuilder.TEMPLATE) {
+ errNonSpaceInColgroupInFragment();
+ start = i + 1;
+ continue;
+ }
+ flushCharacters();
+ pop();
+ mode = IN_TABLE;
+ i--;
+ continue;
+ case IN_SELECT:
+ case IN_SELECT_IN_TABLE:
+ break charactersloop;
+ case AFTER_BODY:
+ errNonSpaceAfterBody();
+ fatal();
+ mode = framesetOk ? FRAMESET_OK : IN_BODY;
+ i--;
+ continue;
+ case IN_FRAMESET:
+ if (start < i) {
+ accumulateCharacters(buf, start, i
+ - start);
+ // start index is adjusted below.
+ }
+ /*
+ * Parse error.
+ */
+ errNonSpaceInFrameset();
+ /*
+ * Ignore the token.
+ */
+ start = i + 1;
+ continue;
+ case AFTER_FRAMESET:
+ if (start < i) {
+ accumulateCharacters(buf, start, i
+ - start);
+ // start index is adjusted below.
+ }
+ /*
+ * Parse error.
+ */
+ errNonSpaceAfterFrameset();
+ /*
+ * Ignore the token.
+ */
+ start = i + 1;
+ continue;
+ case AFTER_AFTER_BODY:
+ /*
+ * Parse error.
+ */
+ errNonSpaceInTrailer();
+ /*
+ * Switch back to the main mode and
+ * reprocess the token.
+ */
+ mode = framesetOk ? FRAMESET_OK : IN_BODY;
+ i--;
+ continue;
+ case AFTER_AFTER_FRAMESET:
+ if (start < i) {
+ accumulateCharacters(buf, start, i
+ - start);
+ // start index is adjusted below.
+ }
+ /*
+ * Parse error.
+ */
+ errNonSpaceInTrailer();
+ /*
+ * Ignore the token.
+ */
+ start = i + 1;
+ continue;
+ }
+ }
+ }
+ if (start < end) {
+ accumulateCharacters(buf, start, end - start);
+ }
+ }
+ }
+
+ /**
+ * @see nu.validator.htmlparser.common.TokenHandler#zeroOriginatingReplacementCharacter()
+ */
+ public void zeroOriginatingReplacementCharacter() throws SAXException {
+ if (mode == TEXT) {
+ accumulateCharacters(REPLACEMENT_CHARACTER, 0, 1);
+ return;
+ }
+ if (currentPtr >= 0) {
+ if (isSpecialParentInForeign(stack[currentPtr])) {
+ return;
+ }
+ accumulateCharacters(REPLACEMENT_CHARACTER, 0, 1);
+ }
+ }
+
+ public final void eof() throws SAXException {
+ flushCharacters();
+ // Note: Can't attach error messages to EOF in C++ yet
+ eofloop: for (;;) {
+ switch (mode) {
+ case INITIAL:
+ /*
+ * Parse error.
+ */
+ // [NOCPP[
+ switch (doctypeExpectation) {
+ case AUTO:
+ err("End of file seen without seeing a doctype first. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
+ break;
+ case HTML:
+ err("End of file seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
+ break;
+ case HTML401_STRICT:
+ err("End of file seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
+ break;
+ case HTML401_TRANSITIONAL:
+ err("End of file seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
+ break;
+ case NO_DOCTYPE_ERRORS:
+ }
+ // ]NOCPP]
+ /*
+ *
+ * Set the document to quirks mode.
+ */
+ documentModeInternal(DocumentMode.QUIRKS_MODE, null, null,
+ false);
+ /*
+ * Then, switch to the root element mode of the tree
+ * construction stage
+ */
+ mode = BEFORE_HTML;
+ /*
+ * and reprocess the current token.
+ */
+ continue;
+ case BEFORE_HTML:
+ /*
+ * Create an HTMLElement node with the tag name html, in the
+ * HTML namespace. Append it to the Document object.
+ */
+ appendHtmlElementToDocumentAndPush();
+ // XXX application cache manifest
+ /* Switch to the main mode */
+ mode = BEFORE_HEAD;
+ /*
+ * reprocess the current token.
+ */
+ continue;
+ case BEFORE_HEAD:
+ appendToCurrentNodeAndPushHeadElement(HtmlAttributes.EMPTY_ATTRIBUTES);
+ mode = IN_HEAD;
+ continue;
+ case IN_HEAD:
+ // [NOCPP[
+ if (errorHandler != null && currentPtr > 1) {
+ errEofWithUnclosedElements();
+ }
+ // ]NOCPP]
+ while (currentPtr > 0) {
+ popOnEof();
+ }
+ mode = AFTER_HEAD;
+ continue;
+ case IN_HEAD_NOSCRIPT:
+ // [NOCPP[
+ errEofWithUnclosedElements();
+ // ]NOCPP]
+ while (currentPtr > 1) {
+ popOnEof();
+ }
+ mode = IN_HEAD;
+ continue;
+ case AFTER_HEAD:
+ appendToCurrentNodeAndPushBodyElement();
+ mode = IN_BODY;
+ continue;
+ case IN_TABLE_BODY:
+ case IN_ROW:
+ case IN_TABLE:
+ case IN_SELECT_IN_TABLE:
+ case IN_SELECT:
+ case IN_COLUMN_GROUP:
+ case FRAMESET_OK:
+ case IN_CAPTION:
+ case IN_CELL:
+ case IN_BODY:
+ // [NOCPP[
+ // i > 0 to stop in time in the foreign fragment case.
+ openelementloop: for (int i = currentPtr; i > 0; i--) {
+ int group = stack[i].getGroup();
+ switch (group) {
+ case DD_OR_DT:
+ case LI:
+ case P:
+ case TBODY_OR_THEAD_OR_TFOOT:
+ case TD_OR_TH:
+ case BODY:
+ case HTML:
+ break;
+ default:
+ errEofWithUnclosedElements();
+ break openelementloop;
+ }
+ }
+ // ]NOCPP]
+
+ if (isTemplateModeStackEmpty()) {
+ break eofloop;
+ }
+
+ // fall through to IN_TEMPLATE
+ case IN_TEMPLATE:
+ int eltPos = findLast("template");
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ assert fragment;
+ break eofloop;
+ }
+ if (errorHandler != null) {
+ errUnclosedElements(eltPos, "template");
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ popTemplateMode();
+ resetTheInsertionMode();
+
+ // Reprocess token.
+ continue;
+ case TEXT:
+ // [NOCPP[
+ if (errorHandler != null) {
+ errNoCheck("End of file seen when expecting text or an end tag.");
+ errListUnclosedStartTags(0);
+ }
+ // ]NOCPP]
+ // XXX mark script as already executed
+ if (originalMode == AFTER_HEAD) {
+ popOnEof();
+ }
+ popOnEof();
+ mode = originalMode;
+ continue;
+ case IN_FRAMESET:
+ // [NOCPP[
+ if (errorHandler != null && currentPtr > 0) {
+ errEofWithUnclosedElements();
+ }
+ // ]NOCPP]
+ break eofloop;
+ case AFTER_BODY:
+ case AFTER_FRAMESET:
+ case AFTER_AFTER_BODY:
+ case AFTER_AFTER_FRAMESET:
+ default:
+ // [NOCPP[
+ if (currentPtr == 0) { // This silliness is here to poison
+ // buggy compiler optimizations in
+ // GWT
+ System.currentTimeMillis();
+ }
+ // ]NOCPP]
+ break eofloop;
+ }
+ }
+ while (currentPtr > 0) {
+ popOnEof();
+ }
+ if (!fragment) {
+ popOnEof();
+ }
+ /* Stop parsing. */
+ }
+
+ /**
+ * @see nu.validator.htmlparser.common.TokenHandler#endTokenization()
+ */
+ public final void endTokenization() throws SAXException {
+ formPointer = null;
+ headPointer = null;
+ deepTreeSurrogateParent = null;
+ templateModeStack = null;
+ if (stack != null) {
+ while (currentPtr > -1) {
+ stack[currentPtr].release();
+ currentPtr--;
+ }
+ stack = null;
+ }
+ if (listOfActiveFormattingElements != null) {
+ while (listPtr > -1) {
+ if (listOfActiveFormattingElements[listPtr] != null) {
+ listOfActiveFormattingElements[listPtr].release();
+ }
+ listPtr--;
+ }
+ listOfActiveFormattingElements = null;
+ }
+ // [NOCPP[
+ idLocations.clear();
+ // ]NOCPP]
+ charBuffer = null;
+ end();
+ }
+
+ public final void startTag(ElementName elementName,
+ HtmlAttributes attributes, boolean selfClosing) throws SAXException {
+ flushCharacters();
+
+ // [NOCPP[
+ if (errorHandler != null) {
+ // ID uniqueness
+ @IdType String id = attributes.getId();
+ if (id != null) {
+ LocatorImpl oldLoc = idLocations.get(id);
+ if (oldLoc != null) {
+ err("Duplicate ID \u201C" + id + "\u201D.");
+ errorHandler.warning(new SAXParseException(
+ "The first occurrence of ID \u201C" + id
+ + "\u201D was here.", oldLoc));
+ } else {
+ idLocations.put(id, new LocatorImpl(tokenizer));
+ }
+ }
+ }
+ // ]NOCPP]
+
+ int eltPos;
+ needToDropLF = false;
+ starttagloop: for (;;) {
+ int group = elementName.getGroup();
+ @Local String name = elementName.name;
+ if (isInForeign()) {
+ StackNode<T> currentNode = stack[currentPtr];
+ @NsUri String currNs = currentNode.ns;
+ if (!(currentNode.isHtmlIntegrationPoint() || (currNs == "http://www.w3.org/1998/Math/MathML" && ((currentNode.getGroup() == MI_MO_MN_MS_MTEXT && group != MGLYPH_OR_MALIGNMARK) || (currentNode.getGroup() == ANNOTATION_XML && group == SVG))))) {
+ switch (group) {
+ case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
+ case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
+ case BODY:
+ case BR:
+ case RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR:
+ case DD_OR_DT:
+ case UL_OR_OL_OR_DL:
+ case EMBED:
+ case IMG:
+ case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
+ case HEAD:
+ case HR:
+ case LI:
+ case META:
+ case NOBR:
+ case P:
+ case PRE_OR_LISTING:
+ case TABLE:
+ case FONT:
+ // re-check FONT to deal with the special case
+ if (!(group == FONT && !(attributes.contains(AttributeName.COLOR)
+ || attributes.contains(AttributeName.FACE) || attributes.contains(AttributeName.SIZE)))) {
+ errHtmlStartTagInForeignContext(name);
+ if (!fragment) {
+ while (!isSpecialParentInForeign(stack[currentPtr])) {
+ pop();
+ }
+ continue starttagloop;
+ } // else fall thru
+ }
+ // else fall thru
+ default:
+ if ("http://www.w3.org/2000/svg" == currNs) {
+ attributes.adjustForSvg();
+ if (selfClosing) {
+ appendVoidElementToCurrentMayFosterSVG(
+ elementName, attributes);
+ selfClosing = false;
+ } else {
+ appendToCurrentNodeAndPushElementMayFosterSVG(
+ elementName, attributes);
+ }
+ attributes = null; // CPP
+ break starttagloop;
+ } else {
+ attributes.adjustForMath();
+ if (selfClosing) {
+ appendVoidElementToCurrentMayFosterMathML(
+ elementName, attributes);
+ selfClosing = false;
+ } else {
+ appendToCurrentNodeAndPushElementMayFosterMathML(
+ elementName, attributes);
+ }
+ attributes = null; // CPP
+ break starttagloop;
+ }
+ } // switch
+ } // foreignObject / annotation-xml
+ }
+ switch (mode) {
+ case IN_TEMPLATE:
+ switch (group) {
+ case COL:
+ popTemplateMode();
+ pushTemplateMode(IN_COLUMN_GROUP);
+ mode = IN_COLUMN_GROUP;
+ // Reprocess token.
+ continue;
+ case CAPTION:
+ case COLGROUP:
+ case TBODY_OR_THEAD_OR_TFOOT:
+ popTemplateMode();
+ pushTemplateMode(IN_TABLE);
+ mode = IN_TABLE;
+ // Reprocess token.
+ continue;
+ case TR:
+ popTemplateMode();
+ pushTemplateMode(IN_TABLE_BODY);
+ mode = IN_TABLE_BODY;
+ // Reprocess token.
+ continue;
+ case TD_OR_TH:
+ popTemplateMode();
+ pushTemplateMode(IN_ROW);
+ mode = IN_ROW;
+ // Reprocess token.
+ continue;
+ case META:
+ checkMetaCharset(attributes);
+ appendVoidElementToCurrentMayFoster(
+ elementName,
+ attributes);
+ selfClosing = false;
+ attributes = null; // CPP
+ break starttagloop;
+ case TITLE:
+ startTagTitleInHead(elementName, attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case BASE:
+ case LINK_OR_BASEFONT_OR_BGSOUND:
+ appendVoidElementToCurrentMayFoster(
+ elementName,
+ attributes);
+ selfClosing = false;
+ attributes = null; // CPP
+ break starttagloop;
+ case SCRIPT:
+ startTagScriptInHead(elementName, attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case NOFRAMES:
+ case STYLE:
+ startTagGenericRawText(elementName, attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case TEMPLATE:
+ startTagTemplateInHead(elementName, attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ default:
+ popTemplateMode();
+ pushTemplateMode(IN_BODY);
+ mode = IN_BODY;
+ // Reprocess token.
+ continue;
+ }
+ case IN_ROW:
+ switch (group) {
+ case TD_OR_TH:
+ clearStackBackTo(findLastOrRoot(TreeBuilder.TR));
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ mode = IN_CELL;
+ insertMarker();
+ attributes = null; // CPP
+ break starttagloop;
+ case CAPTION:
+ case COL:
+ case COLGROUP:
+ case TBODY_OR_THEAD_OR_TFOOT:
+ case TR:
+ eltPos = findLastOrRoot(TreeBuilder.TR);
+ if (eltPos == 0) {
+ assert fragment || isTemplateContents();
+ errNoTableRowToClose();
+ break starttagloop;
+ }
+ clearStackBackTo(eltPos);
+ pop();
+ mode = IN_TABLE_BODY;
+ continue;
+ default:
+ // fall through to IN_TABLE
+ }
+ case IN_TABLE_BODY:
+ switch (group) {
+ case TR:
+ clearStackBackTo(findLastInTableScopeOrRootTemplateTbodyTheadTfoot());
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ mode = IN_ROW;
+ attributes = null; // CPP
+ break starttagloop;
+ case TD_OR_TH:
+ errStartTagInTableBody(name);
+ clearStackBackTo(findLastInTableScopeOrRootTemplateTbodyTheadTfoot());
+ appendToCurrentNodeAndPushElement(
+ ElementName.TR,
+ HtmlAttributes.EMPTY_ATTRIBUTES);
+ mode = IN_ROW;
+ continue;
+ case CAPTION:
+ case COL:
+ case COLGROUP:
+ case TBODY_OR_THEAD_OR_TFOOT:
+ eltPos = findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
+ if (eltPos == 0 || stack[eltPos].getGroup() == TEMPLATE) {
+ assert fragment || isTemplateContents();
+ errStrayStartTag(name);
+ break starttagloop;
+ } else {
+ clearStackBackTo(eltPos);
+ pop();
+ mode = IN_TABLE;
+ continue;
+ }
+ default:
+ // fall through to IN_TABLE
+ }
+ case IN_TABLE:
+ intableloop: for (;;) {
+ switch (group) {
+ case CAPTION:
+ clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
+ insertMarker();
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ mode = IN_CAPTION;
+ attributes = null; // CPP
+ break starttagloop;
+ case COLGROUP:
+ clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ mode = IN_COLUMN_GROUP;
+ attributes = null; // CPP
+ break starttagloop;
+ case COL:
+ clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
+ appendToCurrentNodeAndPushElement(
+ ElementName.COLGROUP,
+ HtmlAttributes.EMPTY_ATTRIBUTES);
+ mode = IN_COLUMN_GROUP;
+ continue starttagloop;
+ case TBODY_OR_THEAD_OR_TFOOT:
+ clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ mode = IN_TABLE_BODY;
+ attributes = null; // CPP
+ break starttagloop;
+ case TR:
+ case TD_OR_TH:
+ clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
+ appendToCurrentNodeAndPushElement(
+ ElementName.TBODY,
+ HtmlAttributes.EMPTY_ATTRIBUTES);
+ mode = IN_TABLE_BODY;
+ continue starttagloop;
+ case TEMPLATE:
+ // fall through to IN_HEAD
+ break intableloop;
+ case TABLE:
+ errTableSeenWhileTableOpen();
+ eltPos = findLastInTableScope(name);
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ assert fragment || isTemplateContents();
+ break starttagloop;
+ }
+ generateImpliedEndTags();
+ if (errorHandler != null && !isCurrent("table")) {
+ errNoCheckUnclosedElementsOnStack();
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ resetTheInsertionMode();
+ continue starttagloop;
+ case SCRIPT:
+ // XXX need to manage much more stuff
+ // here if
+ // supporting
+ // document.write()
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ originalMode = mode;
+ mode = TEXT;
+ tokenizer.setStateAndEndTagExpectation(
+ Tokenizer.SCRIPT_DATA, elementName);
+ attributes = null; // CPP
+ break starttagloop;
+ case STYLE:
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ originalMode = mode;
+ mode = TEXT;
+ tokenizer.setStateAndEndTagExpectation(
+ Tokenizer.RAWTEXT, elementName);
+ attributes = null; // CPP
+ break starttagloop;
+ case INPUT:
+ errStartTagInTable(name);
+ if (!Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "hidden",
+ attributes.getValue(AttributeName.TYPE))) {
+ break intableloop;
+ }
+ appendVoidElementToCurrent(
+ name, attributes,
+ formPointer);
+ selfClosing = false;
+ attributes = null; // CPP
+ break starttagloop;
+ case FORM:
+ if (formPointer != null || isTemplateContents()) {
+ errFormWhenFormOpen();
+ break starttagloop;
+ } else {
+ errStartTagInTable(name);
+ appendVoidFormToCurrent(attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ }
+ default:
+ errStartTagInTable(name);
+ // fall through to IN_BODY
+ break intableloop;
+ }
+ }
+ case IN_CAPTION:
+ switch (group) {
+ case CAPTION:
+ case COL:
+ case COLGROUP:
+ case TBODY_OR_THEAD_OR_TFOOT:
+ case TR:
+ case TD_OR_TH:
+ errStrayStartTag(name);
+ eltPos = findLastInTableScope("caption");
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ break starttagloop;
+ }
+ generateImpliedEndTags();
+ if (errorHandler != null && currentPtr != eltPos) {
+ errNoCheckUnclosedElementsOnStack();
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ mode = IN_TABLE;
+ continue;
+ default:
+ // fall through to IN_BODY
+ }
+ case IN_CELL:
+ switch (group) {
+ case CAPTION:
+ case COL:
+ case COLGROUP:
+ case TBODY_OR_THEAD_OR_TFOOT:
+ case TR:
+ case TD_OR_TH:
+ eltPos = findLastInTableScopeTdTh();
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ errNoCellToClose();
+ break starttagloop;
+ } else {
+ closeTheCell(eltPos);
+ continue;
+ }
+ default:
+ // fall through to IN_BODY
+ }
+ case FRAMESET_OK:
+ switch (group) {
+ case FRAMESET:
+ if (mode == FRAMESET_OK) {
+ if (currentPtr == 0 || stack[1].getGroup() != BODY) {
+ assert fragment || isTemplateContents();
+ errStrayStartTag(name);
+ break starttagloop;
+ } else {
+ errFramesetStart();
+ detachFromParent(stack[1].node);
+ while (currentPtr > 0) {
+ pop();
+ }
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ mode = IN_FRAMESET;
+ attributes = null; // CPP
+ break starttagloop;
+ }
+ } else {
+ errStrayStartTag(name);
+ break starttagloop;
+ }
+ // NOT falling through!
+ case PRE_OR_LISTING:
+ case LI:
+ case DD_OR_DT:
+ case BUTTON:
+ case MARQUEE_OR_APPLET:
+ case OBJECT:
+ case TABLE:
+ case AREA_OR_WBR:
+ case BR:
+ case EMBED:
+ case IMG:
+ case INPUT:
+ case KEYGEN:
+ case HR:
+ case TEXTAREA:
+ case XMP:
+ case IFRAME:
+ case SELECT:
+ if (mode == FRAMESET_OK
+ && !(group == INPUT && Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "hidden",
+ attributes.getValue(AttributeName.TYPE)))) {
+ framesetOk = false;
+ mode = IN_BODY;
+ }
+ // fall through to IN_BODY
+ default:
+ // fall through to IN_BODY
+ }
+ case IN_BODY:
+ inbodyloop: for (;;) {
+ switch (group) {
+ case HTML:
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = null; // CPP
+ }
+ break starttagloop;
+ case BASE:
+ case LINK_OR_BASEFONT_OR_BGSOUND:
+ case META:
+ case STYLE:
+ case SCRIPT:
+ case TITLE:
+ case TEMPLATE:
+ // Fall through to IN_HEAD
+ break inbodyloop;
+ case BODY:
+ if (currentPtr == 0 || stack[1].getGroup() != BODY || isTemplateContents()) {
+ assert fragment || isTemplateContents();
+ errStrayStartTag(name);
+ break starttagloop;
+ }
+ errFooSeenWhenFooOpen(name);
+ framesetOk = false;
+ if (mode == FRAMESET_OK) {
+ mode = IN_BODY;
+ }
+ if (addAttributesToBody(attributes)) {
+ attributes = null; // CPP
+ }
+ break starttagloop;
+ case P:
+ case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
+ case UL_OR_OL_OR_DL:
+ case ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY:
+ implicitlyCloseP();
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
+ implicitlyCloseP();
+ if (stack[currentPtr].getGroup() == H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6) {
+ errHeadingWhenHeadingOpen();
+ pop();
+ }
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case FIELDSET:
+ implicitlyCloseP();
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes, formPointer);
+ attributes = null; // CPP
+ break starttagloop;
+ case PRE_OR_LISTING:
+ implicitlyCloseP();
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes);
+ needToDropLF = true;
+ attributes = null; // CPP
+ break starttagloop;
+ case FORM:
+ if (formPointer != null && !isTemplateContents()) {
+ errFormWhenFormOpen();
+ break starttagloop;
+ } else {
+ implicitlyCloseP();
+ appendToCurrentNodeAndPushFormElementMayFoster(attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ }
+ case LI:
+ case DD_OR_DT:
+ eltPos = currentPtr;
+ for (;;) {
+ StackNode<T> node = stack[eltPos]; // weak
+ // ref
+ if (node.getGroup() == group) { // LI or
+ // DD_OR_DT
+ generateImpliedEndTagsExceptFor(node.name);
+ if (errorHandler != null
+ && eltPos != currentPtr) {
+ errUnclosedElementsImplied(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ break;
+ } else if (eltPos == 0 || (node.isSpecial()
+ && (node.ns != "http://www.w3.org/1999/xhtml"
+ || (node.name != "p"
+ && node.name != "address"
+ && node.name != "div")))) {
+ break;
+ }
+ eltPos--;
+ }
+ implicitlyCloseP();
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case PLAINTEXT:
+ implicitlyCloseP();
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes);
+ tokenizer.setStateAndEndTagExpectation(
+ Tokenizer.PLAINTEXT, elementName);
+ attributes = null; // CPP
+ break starttagloop;
+ case A:
+ int activeAPos = findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker("a");
+ if (activeAPos != -1) {
+ errFooSeenWhenFooOpen(name);
+ StackNode<T> activeA = listOfActiveFormattingElements[activeAPos];
+ activeA.retain();
+ adoptionAgencyEndTag("a");
+ removeFromStack(activeA);
+ activeAPos = findInListOfActiveFormattingElements(activeA);
+ if (activeAPos != -1) {
+ removeFromListOfActiveFormattingElements(activeAPos);
+ }
+ activeA.release();
+ }
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushFormattingElementMayFoster(
+ elementName,
+ attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
+ case FONT:
+ reconstructTheActiveFormattingElements();
+ maybeForgetEarlierDuplicateFormattingElement(elementName.name, attributes);
+ appendToCurrentNodeAndPushFormattingElementMayFoster(
+ elementName,
+ attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case NOBR:
+ reconstructTheActiveFormattingElements();
+ if (TreeBuilder.NOT_FOUND_ON_STACK != findLastInScope("nobr")) {
+ errFooSeenWhenFooOpen(name);
+ adoptionAgencyEndTag("nobr");
+ reconstructTheActiveFormattingElements();
+ }
+ appendToCurrentNodeAndPushFormattingElementMayFoster(
+ elementName,
+ attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case BUTTON:
+ eltPos = findLastInScope(name);
+ if (eltPos != TreeBuilder.NOT_FOUND_ON_STACK) {
+ errFooSeenWhenFooOpen(name);
+ generateImpliedEndTags();
+ if (errorHandler != null
+ && !isCurrent(name)) {
+ errUnclosedElementsImplied(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ continue starttagloop;
+ } else {
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes, formPointer);
+ attributes = null; // CPP
+ break starttagloop;
+ }
+ case OBJECT:
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes, formPointer);
+ insertMarker();
+ attributes = null; // CPP
+ break starttagloop;
+ case MARQUEE_OR_APPLET:
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes);
+ insertMarker();
+ attributes = null; // CPP
+ break starttagloop;
+ case TABLE:
+ // The only quirk. Blame Hixie and
+ // Acid2.
+ if (!quirks) {
+ implicitlyCloseP();
+ }
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes);
+ mode = IN_TABLE;
+ attributes = null; // CPP
+ break starttagloop;
+ case BR:
+ case EMBED:
+ case AREA_OR_WBR:
+ reconstructTheActiveFormattingElements();
+ // FALL THROUGH to PARAM_OR_SOURCE_OR_TRACK
+ // CPPONLY: case MENUITEM:
+ case PARAM_OR_SOURCE_OR_TRACK:
+ appendVoidElementToCurrentMayFoster(
+ elementName,
+ attributes);
+ selfClosing = false;
+ attributes = null; // CPP
+ break starttagloop;
+ case HR:
+ implicitlyCloseP();
+ appendVoidElementToCurrentMayFoster(
+ elementName,
+ attributes);
+ selfClosing = false;
+ attributes = null; // CPP
+ break starttagloop;
+ case IMAGE:
+ errImage();
+ elementName = ElementName.IMG;
+ continue starttagloop;
+ case IMG:
+ case KEYGEN:
+ case INPUT:
+ reconstructTheActiveFormattingElements();
+ appendVoidElementToCurrentMayFoster(
+ name, attributes,
+ formPointer);
+ selfClosing = false;
+ attributes = null; // CPP
+ break starttagloop;
+ case ISINDEX:
+ errIsindex();
+ if (formPointer != null && !isTemplateContents()) {
+ break starttagloop;
+ }
+ implicitlyCloseP();
+ HtmlAttributes formAttrs = new HtmlAttributes(0);
+ int actionIndex = attributes.getIndex(AttributeName.ACTION);
+ if (actionIndex > -1) {
+ formAttrs.addAttribute(
+ AttributeName.ACTION,
+ attributes.getValueNoBoundsCheck(actionIndex)
+ // [NOCPP[
+ , XmlViolationPolicy.ALLOW
+ // ]NOCPP]
+ // CPPONLY: , attributes.getLineNoBoundsCheck(actionIndex)
+ );
+ }
+ appendToCurrentNodeAndPushFormElementMayFoster(formAttrs);
+ appendVoidElementToCurrentMayFoster(
+ ElementName.HR,
+ HtmlAttributes.EMPTY_ATTRIBUTES);
+ appendToCurrentNodeAndPushElementMayFoster(
+ ElementName.LABEL,
+ HtmlAttributes.EMPTY_ATTRIBUTES);
+ int promptIndex = attributes.getIndex(AttributeName.PROMPT);
+ if (promptIndex > -1) {
+ @Auto char[] prompt = Portability.newCharArrayFromString(attributes.getValueNoBoundsCheck(promptIndex));
+ appendCharacters(stack[currentPtr].node,
+ prompt, 0, prompt.length);
+ } else {
+ appendIsindexPrompt(stack[currentPtr].node);
+ }
+ HtmlAttributes inputAttributes = new HtmlAttributes(
+ 0);
+ inputAttributes.addAttribute(
+ AttributeName.NAME,
+ Portability.newStringFromLiteral("isindex")
+ // [NOCPP[
+ , XmlViolationPolicy.ALLOW
+ // ]NOCPP]
+ // CPPONLY: , tokenizer.getLineNumber()
+ );
+ for (int i = 0; i < attributes.getLength(); i++) {
+ AttributeName attributeQName = attributes.getAttributeNameNoBoundsCheck(i);
+ if (AttributeName.NAME == attributeQName
+ || AttributeName.PROMPT == attributeQName) {
+ attributes.releaseValue(i);
+ } else if (AttributeName.ACTION != attributeQName) {
+ inputAttributes.addAttribute(
+ attributeQName,
+ attributes.getValueNoBoundsCheck(i)
+ // [NOCPP[
+ , XmlViolationPolicy.ALLOW
+ // ]NOCPP]
+ // CPPONLY: , attributes.getLineNoBoundsCheck(i)
+ );
+ }
+ }
+ attributes.clearWithoutReleasingContents();
+ appendVoidElementToCurrentMayFoster(
+ "input",
+ inputAttributes, formPointer);
+ pop(); // label
+ appendVoidElementToCurrentMayFoster(
+ ElementName.HR,
+ HtmlAttributes.EMPTY_ATTRIBUTES);
+ pop(); // form
+
+ if (!isTemplateContents()) {
+ formPointer = null;
+ }
+
+ selfClosing = false;
+ // Portability.delete(formAttrs);
+ // Portability.delete(inputAttributes);
+ // Don't delete attributes, they are deleted
+ // later
+ break starttagloop;
+ case TEXTAREA:
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes, formPointer);
+ tokenizer.setStateAndEndTagExpectation(
+ Tokenizer.RCDATA, elementName);
+ originalMode = mode;
+ mode = TEXT;
+ needToDropLF = true;
+ attributes = null; // CPP
+ break starttagloop;
+ case XMP:
+ implicitlyCloseP();
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes);
+ originalMode = mode;
+ mode = TEXT;
+ tokenizer.setStateAndEndTagExpectation(
+ Tokenizer.RAWTEXT, elementName);
+ attributes = null; // CPP
+ break starttagloop;
+ case NOSCRIPT:
+ if (!scriptingEnabled) {
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ } else {
+ // fall through
+ }
+ case NOFRAMES:
+ case IFRAME:
+ case NOEMBED:
+ startTagGenericRawText(elementName, attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case SELECT:
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes, formPointer);
+ switch (mode) {
+ case IN_TABLE:
+ case IN_CAPTION:
+ case IN_COLUMN_GROUP:
+ case IN_TABLE_BODY:
+ case IN_ROW:
+ case IN_CELL:
+ mode = IN_SELECT_IN_TABLE;
+ break;
+ default:
+ mode = IN_SELECT;
+ break;
+ }
+ attributes = null; // CPP
+ break starttagloop;
+ case OPTGROUP:
+ case OPTION:
+ if (isCurrent("option")) {
+ pop();
+ }
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case RB_OR_RTC:
+ eltPos = findLastInScope("ruby");
+ if (eltPos != NOT_FOUND_ON_STACK) {
+ generateImpliedEndTags();
+ }
+ if (eltPos != currentPtr) {
+ if (eltPos == NOT_FOUND_ON_STACK) {
+ errStartTagSeenWithoutRuby(name);
+ } else {
+ errUnclosedChildrenInRuby();
+ }
+ }
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case RT_OR_RP:
+ eltPos = findLastInScope("ruby");
+ if (eltPos != NOT_FOUND_ON_STACK) {
+ generateImpliedEndTagsExceptFor("rtc");
+ }
+ if (eltPos != currentPtr) {
+ if (!isCurrent("rtc")) {
+ if (eltPos == NOT_FOUND_ON_STACK) {
+ errStartTagSeenWithoutRuby(name);
+ } else {
+ errUnclosedChildrenInRuby();
+ }
+ }
+ }
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case MATH:
+ reconstructTheActiveFormattingElements();
+ attributes.adjustForMath();
+ if (selfClosing) {
+ appendVoidElementToCurrentMayFosterMathML(
+ elementName, attributes);
+ selfClosing = false;
+ } else {
+ appendToCurrentNodeAndPushElementMayFosterMathML(
+ elementName, attributes);
+ }
+ attributes = null; // CPP
+ break starttagloop;
+ case SVG:
+ reconstructTheActiveFormattingElements();
+ attributes.adjustForSvg();
+ if (selfClosing) {
+ appendVoidElementToCurrentMayFosterSVG(
+ elementName,
+ attributes);
+ selfClosing = false;
+ } else {
+ appendToCurrentNodeAndPushElementMayFosterSVG(
+ elementName, attributes);
+ }
+ attributes = null; // CPP
+ break starttagloop;
+ case CAPTION:
+ case COL:
+ case COLGROUP:
+ case TBODY_OR_THEAD_OR_TFOOT:
+ case TR:
+ case TD_OR_TH:
+ case FRAME:
+ case FRAMESET:
+ case HEAD:
+ errStrayStartTag(name);
+ break starttagloop;
+ case OUTPUT:
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes, formPointer);
+ attributes = null; // CPP
+ break starttagloop;
+ default:
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ }
+ }
+ case IN_HEAD:
+ inheadloop: for (;;) {
+ switch (group) {
+ case HTML:
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = null; // CPP
+ }
+ break starttagloop;
+ case BASE:
+ case LINK_OR_BASEFONT_OR_BGSOUND:
+ appendVoidElementToCurrentMayFoster(
+ elementName,
+ attributes);
+ selfClosing = false;
+ attributes = null; // CPP
+ break starttagloop;
+ case META:
+ // Fall through to IN_HEAD_NOSCRIPT
+ break inheadloop;
+ case TITLE:
+ startTagTitleInHead(elementName, attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case NOSCRIPT:
+ if (scriptingEnabled) {
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ originalMode = mode;
+ mode = TEXT;
+ tokenizer.setStateAndEndTagExpectation(
+ Tokenizer.RAWTEXT, elementName);
+ } else {
+ appendToCurrentNodeAndPushElementMayFoster(
+ elementName,
+ attributes);
+ mode = IN_HEAD_NOSCRIPT;
+ }
+ attributes = null; // CPP
+ break starttagloop;
+ case SCRIPT:
+ startTagScriptInHead(elementName, attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case STYLE:
+ case NOFRAMES:
+ startTagGenericRawText(elementName, attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case HEAD:
+ /* Parse error. */
+ errFooSeenWhenFooOpen(name);
+ /* Ignore the token. */
+ break starttagloop;
+ case TEMPLATE:
+ startTagTemplateInHead(elementName, attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ default:
+ pop();
+ mode = AFTER_HEAD;
+ continue starttagloop;
+ }
+ }
+ case IN_HEAD_NOSCRIPT:
+ switch (group) {
+ case HTML:
+ // XXX did Hixie really mean to omit "base"
+ // here?
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = null; // CPP
+ }
+ break starttagloop;
+ case LINK_OR_BASEFONT_OR_BGSOUND:
+ appendVoidElementToCurrentMayFoster(
+ elementName,
+ attributes);
+ selfClosing = false;
+ attributes = null; // CPP
+ break starttagloop;
+ case META:
+ checkMetaCharset(attributes);
+ appendVoidElementToCurrentMayFoster(
+ elementName,
+ attributes);
+ selfClosing = false;
+ attributes = null; // CPP
+ break starttagloop;
+ case STYLE:
+ case NOFRAMES:
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ originalMode = mode;
+ mode = TEXT;
+ tokenizer.setStateAndEndTagExpectation(
+ Tokenizer.RAWTEXT, elementName);
+ attributes = null; // CPP
+ break starttagloop;
+ case HEAD:
+ errFooSeenWhenFooOpen(name);
+ break starttagloop;
+ case NOSCRIPT:
+ errFooSeenWhenFooOpen(name);
+ break starttagloop;
+ default:
+ errBadStartTagInHead(name);
+ pop();
+ mode = IN_HEAD;
+ continue;
+ }
+ case IN_COLUMN_GROUP:
+ switch (group) {
+ case HTML:
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = null; // CPP
+ }
+ break starttagloop;
+ case COL:
+ appendVoidElementToCurrentMayFoster(
+ elementName,
+ attributes);
+ selfClosing = false;
+ attributes = null; // CPP
+ break starttagloop;
+ case TEMPLATE:
+ startTagTemplateInHead(elementName, attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ default:
+ if (currentPtr == 0 || stack[currentPtr].getGroup() == TEMPLATE) {
+ assert fragment || isTemplateContents();
+ errGarbageInColgroup();
+ break starttagloop;
+ }
+ pop();
+ mode = IN_TABLE;
+ continue;
+ }
+ case IN_SELECT_IN_TABLE:
+ switch (group) {
+ case CAPTION:
+ case TBODY_OR_THEAD_OR_TFOOT:
+ case TR:
+ case TD_OR_TH:
+ case TABLE:
+ errStartTagWithSelectOpen(name);
+ eltPos = findLastInTableScope("select");
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ assert fragment;
+ break starttagloop; // http://www.w3.org/Bugs/Public/show_bug.cgi?id=8375
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ resetTheInsertionMode();
+ continue;
+ default:
+ // fall through to IN_SELECT
+ }
+ case IN_SELECT:
+ switch (group) {
+ case HTML:
+ errStrayStartTag(name);
+ if (!fragment) {
+ addAttributesToHtml(attributes);
+ attributes = null; // CPP
+ }
+ break starttagloop;
+ case OPTION:
+ if (isCurrent("option")) {
+ pop();
+ }
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case OPTGROUP:
+ if (isCurrent("option")) {
+ pop();
+ }
+ if (isCurrent("optgroup")) {
+ pop();
+ }
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case SELECT:
+ errStartSelectWhereEndSelectExpected();
+ eltPos = findLastInTableScope(name);
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ assert fragment;
+ errNoSelectInTableScope();
+ break starttagloop;
+ } else {
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ resetTheInsertionMode();
+ break starttagloop;
+ }
+ case INPUT:
+ case TEXTAREA:
+ case KEYGEN:
+ errStartTagWithSelectOpen(name);
+ eltPos = findLastInTableScope("select");
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ assert fragment;
+ break starttagloop;
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ resetTheInsertionMode();
+ continue;
+ case SCRIPT:
+ startTagScriptInHead(elementName, attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case TEMPLATE:
+ startTagTemplateInHead(elementName, attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ default:
+ errStrayStartTag(name);
+ break starttagloop;
+ }
+ case AFTER_BODY:
+ switch (group) {
+ case HTML:
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = null; // CPP
+ }
+ break starttagloop;
+ default:
+ errStrayStartTag(name);
+ mode = framesetOk ? FRAMESET_OK : IN_BODY;
+ continue;
+ }
+ case IN_FRAMESET:
+ switch (group) {
+ case FRAMESET:
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ case FRAME:
+ appendVoidElementToCurrentMayFoster(
+ elementName,
+ attributes);
+ selfClosing = false;
+ attributes = null; // CPP
+ break starttagloop;
+ default:
+ // fall through to AFTER_FRAMESET
+ }
+ case AFTER_FRAMESET:
+ switch (group) {
+ case HTML:
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = null; // CPP
+ }
+ break starttagloop;
+ case NOFRAMES:
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ originalMode = mode;
+ mode = TEXT;
+ tokenizer.setStateAndEndTagExpectation(
+ Tokenizer.RAWTEXT, elementName);
+ attributes = null; // CPP
+ break starttagloop;
+ default:
+ errStrayStartTag(name);
+ break starttagloop;
+ }
+ case INITIAL:
+ /*
+ * Parse error.
+ */
+ // [NOCPP[
+ switch (doctypeExpectation) {
+ case AUTO:
+ err("Start tag seen without seeing a doctype first. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
+ break;
+ case HTML:
+ // ]NOCPP]
+ errStartTagWithoutDoctype();
+ // [NOCPP[
+ break;
+ case HTML401_STRICT:
+ err("Start tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
+ break;
+ case HTML401_TRANSITIONAL:
+ err("Start tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
+ break;
+ case NO_DOCTYPE_ERRORS:
+ }
+ // ]NOCPP]
+ /*
+ *
+ * Set the document to quirks mode.
+ */
+ documentModeInternal(DocumentMode.QUIRKS_MODE, null, null,
+ false);
+ /*
+ * Then, switch to the root element mode of the tree
+ * construction stage
+ */
+ mode = BEFORE_HTML;
+ /*
+ * and reprocess the current token.
+ */
+ continue;
+ case BEFORE_HTML:
+ switch (group) {
+ case HTML:
+ // optimize error check and streaming SAX by
+ // hoisting
+ // "html" handling here.
+ if (attributes == HtmlAttributes.EMPTY_ATTRIBUTES) {
+ // This has the right magic side effect
+ // that
+ // it
+ // makes attributes in SAX Tree mutable.
+ appendHtmlElementToDocumentAndPush();
+ } else {
+ appendHtmlElementToDocumentAndPush(attributes);
+ }
+ // XXX application cache should fire here
+ mode = BEFORE_HEAD;
+ attributes = null; // CPP
+ break starttagloop;
+ default:
+ /*
+ * Create an HTMLElement node with the tag name
+ * html, in the HTML namespace. Append it to the
+ * Document object.
+ */
+ appendHtmlElementToDocumentAndPush();
+ /* Switch to the main mode */
+ mode = BEFORE_HEAD;
+ /*
+ * reprocess the current token.
+ */
+ continue;
+ }
+ case BEFORE_HEAD:
+ switch (group) {
+ case HTML:
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = null; // CPP
+ }
+ break starttagloop;
+ case HEAD:
+ /*
+ * A start tag whose tag name is "head"
+ *
+ * Create an element for the token.
+ *
+ * Set the head element pointer to this new element
+ * node.
+ *
+ * Append the new element to the current node and
+ * push it onto the stack of open elements.
+ */
+ appendToCurrentNodeAndPushHeadElement(attributes);
+ /*
+ * Change the insertion mode to "in head".
+ */
+ mode = IN_HEAD;
+ attributes = null; // CPP
+ break starttagloop;
+ default:
+ /*
+ * Any other start tag token
+ *
+ * Act as if a start tag token with the tag name
+ * "head" and no attributes had been seen,
+ */
+ appendToCurrentNodeAndPushHeadElement(HtmlAttributes.EMPTY_ATTRIBUTES);
+ mode = IN_HEAD;
+ /*
+ * then reprocess the current token.
+ *
+ * This will result in an empty head element being
+ * generated, with the current token being
+ * reprocessed in the "after head" insertion mode.
+ */
+ continue;
+ }
+ case AFTER_HEAD:
+ switch (group) {
+ case HTML:
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = null; // CPP
+ }
+ break starttagloop;
+ case BODY:
+ if (attributes.getLength() == 0) {
+ // This has the right magic side effect
+ // that
+ // it
+ // makes attributes in SAX Tree mutable.
+ appendToCurrentNodeAndPushBodyElement();
+ } else {
+ appendToCurrentNodeAndPushBodyElement(attributes);
+ }
+ framesetOk = false;
+ mode = IN_BODY;
+ attributes = null; // CPP
+ break starttagloop;
+ case FRAMESET:
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ mode = IN_FRAMESET;
+ attributes = null; // CPP
+ break starttagloop;
+ case TEMPLATE:
+ errFooBetweenHeadAndBody(name);
+ pushHeadPointerOntoStack();
+ StackNode<T> headOnStack = stack[currentPtr];
+ startTagTemplateInHead(elementName, attributes);
+ removeFromStack(headOnStack);
+ attributes = null; // CPP
+ break starttagloop;
+ case BASE:
+ case LINK_OR_BASEFONT_OR_BGSOUND:
+ errFooBetweenHeadAndBody(name);
+ pushHeadPointerOntoStack();
+ appendVoidElementToCurrentMayFoster(
+ elementName,
+ attributes);
+ selfClosing = false;
+ pop(); // head
+ attributes = null; // CPP
+ break starttagloop;
+ case META:
+ errFooBetweenHeadAndBody(name);
+ checkMetaCharset(attributes);
+ pushHeadPointerOntoStack();
+ appendVoidElementToCurrentMayFoster(
+ elementName,
+ attributes);
+ selfClosing = false;
+ pop(); // head
+ attributes = null; // CPP
+ break starttagloop;
+ case SCRIPT:
+ errFooBetweenHeadAndBody(name);
+ pushHeadPointerOntoStack();
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ originalMode = mode;
+ mode = TEXT;
+ tokenizer.setStateAndEndTagExpectation(
+ Tokenizer.SCRIPT_DATA, elementName);
+ attributes = null; // CPP
+ break starttagloop;
+ case STYLE:
+ case NOFRAMES:
+ errFooBetweenHeadAndBody(name);
+ pushHeadPointerOntoStack();
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ originalMode = mode;
+ mode = TEXT;
+ tokenizer.setStateAndEndTagExpectation(
+ Tokenizer.RAWTEXT, elementName);
+ attributes = null; // CPP
+ break starttagloop;
+ case TITLE:
+ errFooBetweenHeadAndBody(name);
+ pushHeadPointerOntoStack();
+ appendToCurrentNodeAndPushElement(
+ elementName,
+ attributes);
+ originalMode = mode;
+ mode = TEXT;
+ tokenizer.setStateAndEndTagExpectation(
+ Tokenizer.RCDATA, elementName);
+ attributes = null; // CPP
+ break starttagloop;
+ case HEAD:
+ errStrayStartTag(name);
+ break starttagloop;
+ default:
+ appendToCurrentNodeAndPushBodyElement();
+ mode = FRAMESET_OK;
+ continue;
+ }
+ case AFTER_AFTER_BODY:
+ switch (group) {
+ case HTML:
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = null; // CPP
+ }
+ break starttagloop;
+ default:
+ errStrayStartTag(name);
+ fatal();
+ mode = framesetOk ? FRAMESET_OK : IN_BODY;
+ continue;
+ }
+ case AFTER_AFTER_FRAMESET:
+ switch (group) {
+ case HTML:
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = null; // CPP
+ }
+ break starttagloop;
+ case NOFRAMES:
+ startTagGenericRawText(elementName, attributes);
+ attributes = null; // CPP
+ break starttagloop;
+ default:
+ errStrayStartTag(name);
+ break starttagloop;
+ }
+ case TEXT:
+ assert false;
+ break starttagloop; // Avoid infinite loop if the assertion
+ // fails
+ }
+ }
+ if (selfClosing) {
+ errSelfClosing();
+ }
+ // CPPONLY: if (mBuilder == null && attributes != HtmlAttributes.EMPTY_ATTRIBUTES) {
+ // CPPONLY: Portability.delete(attributes);
+ // CPPONLY: }
+ }
+
+ private void startTagTitleInHead(ElementName elementName, HtmlAttributes attributes) throws SAXException {
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ originalMode = mode;
+ mode = TEXT;
+ tokenizer.setStateAndEndTagExpectation(Tokenizer.RCDATA, elementName);
+ }
+
+ private void startTagGenericRawText(ElementName elementName, HtmlAttributes attributes) throws SAXException {
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ originalMode = mode;
+ mode = TEXT;
+ tokenizer.setStateAndEndTagExpectation(Tokenizer.RAWTEXT, elementName);
+ }
+
+ private void startTagScriptInHead(ElementName elementName, HtmlAttributes attributes) throws SAXException {
+ // XXX need to manage much more stuff here if supporting document.write()
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ originalMode = mode;
+ mode = TEXT;
+ tokenizer.setStateAndEndTagExpectation(Tokenizer.SCRIPT_DATA, elementName);
+ }
+
+ private void startTagTemplateInHead(ElementName elementName, HtmlAttributes attributes) throws SAXException {
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ insertMarker();
+ framesetOk = false;
+ originalMode = mode;
+ mode = IN_TEMPLATE;
+ pushTemplateMode(IN_TEMPLATE);
+ }
+
+ private boolean isTemplateContents() {
+ return TreeBuilder.NOT_FOUND_ON_STACK != findLast("template");
+ }
+
+ private boolean isTemplateModeStackEmpty() {
+ return templateModePtr == -1;
+ }
+
+ private boolean isSpecialParentInForeign(StackNode<T> stackNode) {
+ @NsUri String ns = stackNode.ns;
+ return ("http://www.w3.org/1999/xhtml" == ns)
+ || (stackNode.isHtmlIntegrationPoint())
+ || (("http://www.w3.org/1998/Math/MathML" == ns) && (stackNode.getGroup() == MI_MO_MN_MS_MTEXT));
+ }
+
+ /**
+ *
+ * <p>
+ * C++ memory note: The return value must be released.
+ *
+ * @return
+ * @throws SAXException
+ * @throws StopSniffingException
+ */
+ public static String extractCharsetFromContent(String attributeValue
+ // CPPONLY: , TreeBuilder tb
+ ) {
+ // This is a bit ugly. Converting the string to char array in order to
+ // make the portability layer smaller.
+ int charsetState = CHARSET_INITIAL;
+ int start = -1;
+ int end = -1;
+ @Auto char[] buffer = Portability.newCharArrayFromString(attributeValue);
+
+ charsetloop: for (int i = 0; i < buffer.length; i++) {
+ char c = buffer[i];
+ switch (charsetState) {
+ case CHARSET_INITIAL:
+ switch (c) {
+ case 'c':
+ case 'C':
+ charsetState = CHARSET_C;
+ continue;
+ default:
+ continue;
+ }
+ case CHARSET_C:
+ switch (c) {
+ case 'h':
+ case 'H':
+ charsetState = CHARSET_H;
+ continue;
+ default:
+ charsetState = CHARSET_INITIAL;
+ continue;
+ }
+ case CHARSET_H:
+ switch (c) {
+ case 'a':
+ case 'A':
+ charsetState = CHARSET_A;
+ continue;
+ default:
+ charsetState = CHARSET_INITIAL;
+ continue;
+ }
+ case CHARSET_A:
+ switch (c) {
+ case 'r':
+ case 'R':
+ charsetState = CHARSET_R;
+ continue;
+ default:
+ charsetState = CHARSET_INITIAL;
+ continue;
+ }
+ case CHARSET_R:
+ switch (c) {
+ case 's':
+ case 'S':
+ charsetState = CHARSET_S;
+ continue;
+ default:
+ charsetState = CHARSET_INITIAL;
+ continue;
+ }
+ case CHARSET_S:
+ switch (c) {
+ case 'e':
+ case 'E':
+ charsetState = CHARSET_E;
+ continue;
+ default:
+ charsetState = CHARSET_INITIAL;
+ continue;
+ }
+ case CHARSET_E:
+ switch (c) {
+ case 't':
+ case 'T':
+ charsetState = CHARSET_T;
+ continue;
+ default:
+ charsetState = CHARSET_INITIAL;
+ continue;
+ }
+ case CHARSET_T:
+ switch (c) {
+ case '\t':
+ case '\n':
+ case '\u000C':
+ case '\r':
+ case ' ':
+ continue;
+ case '=':
+ charsetState = CHARSET_EQUALS;
+ continue;
+ default:
+ return null;
+ }
+ case CHARSET_EQUALS:
+ switch (c) {
+ case '\t':
+ case '\n':
+ case '\u000C':
+ case '\r':
+ case ' ':
+ continue;
+ case '\'':
+ start = i + 1;
+ charsetState = CHARSET_SINGLE_QUOTED;
+ continue;
+ case '\"':
+ start = i + 1;
+ charsetState = CHARSET_DOUBLE_QUOTED;
+ continue;
+ default:
+ start = i;
+ charsetState = CHARSET_UNQUOTED;
+ continue;
+ }
+ case CHARSET_SINGLE_QUOTED:
+ switch (c) {
+ case '\'':
+ end = i;
+ break charsetloop;
+ default:
+ continue;
+ }
+ case CHARSET_DOUBLE_QUOTED:
+ switch (c) {
+ case '\"':
+ end = i;
+ break charsetloop;
+ default:
+ continue;
+ }
+ case CHARSET_UNQUOTED:
+ switch (c) {
+ case '\t':
+ case '\n':
+ case '\u000C':
+ case '\r':
+ case ' ':
+ case ';':
+ end = i;
+ break charsetloop;
+ default:
+ continue;
+ }
+ }
+ }
+ String charset = null;
+ if (start != -1) {
+ if (end == -1) {
+ end = buffer.length;
+ }
+ charset = Portability.newStringFromBuffer(buffer, start, end
+ - start
+ // CPPONLY: , tb
+ );
+ }
+ return charset;
+ }
+
+ private void checkMetaCharset(HtmlAttributes attributes)
+ throws SAXException {
+ String charset = attributes.getValue(AttributeName.CHARSET);
+ if (charset != null) {
+ if (tokenizer.internalEncodingDeclaration(charset)) {
+ requestSuspension();
+ return;
+ }
+ return;
+ }
+ if (!Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "content-type",
+ attributes.getValue(AttributeName.HTTP_EQUIV))) {
+ return;
+ }
+ String content = attributes.getValue(AttributeName.CONTENT);
+ if (content != null) {
+ String extract = TreeBuilder.extractCharsetFromContent(content
+ // CPPONLY: , this
+ );
+ // remember not to return early without releasing the string
+ if (extract != null) {
+ if (tokenizer.internalEncodingDeclaration(extract)) {
+ requestSuspension();
+ }
+ }
+ Portability.releaseString(extract);
+ }
+ }
+
+ public final void endTag(ElementName elementName) throws SAXException {
+ flushCharacters();
+ needToDropLF = false;
+ int eltPos;
+ int group = elementName.getGroup();
+ @Local String name = elementName.name;
+ endtagloop: for (;;) {
+ if (isInForeign()) {
+ if (stack[currentPtr].name != name) {
+ if (currentPtr == 0) {
+ errStrayEndTag(name);
+ } else {
+ errEndTagDidNotMatchCurrentOpenElement(name, stack[currentPtr].popName);
+ }
+ }
+ eltPos = currentPtr;
+ for (;;) {
+ if (eltPos == 0) {
+ assert fragment: "We can get this close to the root of the stack in foreign content only in the fragment case.";
+ break endtagloop;
+ }
+ if (stack[eltPos].name == name) {
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ break endtagloop;
+ }
+ if (stack[--eltPos].ns == "http://www.w3.org/1999/xhtml") {
+ break;
+ }
+ }
+ }
+ switch (mode) {
+ case IN_TEMPLATE:
+ switch (group) {
+ case TEMPLATE:
+ // fall through to IN_HEAD
+ break;
+ default:
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ case IN_ROW:
+ switch (group) {
+ case TR:
+ eltPos = findLastOrRoot(TreeBuilder.TR);
+ if (eltPos == 0) {
+ assert fragment || isTemplateContents();
+ errNoTableRowToClose();
+ break endtagloop;
+ }
+ clearStackBackTo(eltPos);
+ pop();
+ mode = IN_TABLE_BODY;
+ break endtagloop;
+ case TABLE:
+ eltPos = findLastOrRoot(TreeBuilder.TR);
+ if (eltPos == 0) {
+ assert fragment || isTemplateContents();
+ errNoTableRowToClose();
+ break endtagloop;
+ }
+ clearStackBackTo(eltPos);
+ pop();
+ mode = IN_TABLE_BODY;
+ continue;
+ case TBODY_OR_THEAD_OR_TFOOT:
+ if (findLastInTableScope(name) == TreeBuilder.NOT_FOUND_ON_STACK) {
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ eltPos = findLastOrRoot(TreeBuilder.TR);
+ if (eltPos == 0) {
+ assert fragment || isTemplateContents();
+ errNoTableRowToClose();
+ break endtagloop;
+ }
+ clearStackBackTo(eltPos);
+ pop();
+ mode = IN_TABLE_BODY;
+ continue;
+ case BODY:
+ case CAPTION:
+ case COL:
+ case COLGROUP:
+ case HTML:
+ case TD_OR_TH:
+ errStrayEndTag(name);
+ break endtagloop;
+ default:
+ // fall through to IN_TABLE
+ }
+ case IN_TABLE_BODY:
+ switch (group) {
+ case TBODY_OR_THEAD_OR_TFOOT:
+ eltPos = findLastOrRoot(name);
+ if (eltPos == 0) {
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ clearStackBackTo(eltPos);
+ pop();
+ mode = IN_TABLE;
+ break endtagloop;
+ case TABLE:
+ eltPos = findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
+ if (eltPos == 0 || stack[eltPos].getGroup() == TEMPLATE) {
+ assert fragment || isTemplateContents();
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ clearStackBackTo(eltPos);
+ pop();
+ mode = IN_TABLE;
+ continue;
+ case BODY:
+ case CAPTION:
+ case COL:
+ case COLGROUP:
+ case HTML:
+ case TD_OR_TH:
+ case TR:
+ errStrayEndTag(name);
+ break endtagloop;
+ default:
+ // fall through to IN_TABLE
+ }
+ case IN_TABLE:
+ switch (group) {
+ case TABLE:
+ eltPos = findLast("table");
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ assert fragment || isTemplateContents();
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ resetTheInsertionMode();
+ break endtagloop;
+ case BODY:
+ case CAPTION:
+ case COL:
+ case COLGROUP:
+ case HTML:
+ case TBODY_OR_THEAD_OR_TFOOT:
+ case TD_OR_TH:
+ case TR:
+ errStrayEndTag(name);
+ break endtagloop;
+ case TEMPLATE:
+ // fall through to IN_HEAD
+ break;
+ default:
+ errStrayEndTag(name);
+ // fall through to IN_BODY
+ }
+ case IN_CAPTION:
+ switch (group) {
+ case CAPTION:
+ eltPos = findLastInTableScope("caption");
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ break endtagloop;
+ }
+ generateImpliedEndTags();
+ if (errorHandler != null && currentPtr != eltPos) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ mode = IN_TABLE;
+ break endtagloop;
+ case TABLE:
+ errTableClosedWhileCaptionOpen();
+ eltPos = findLastInTableScope("caption");
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ break endtagloop;
+ }
+ generateImpliedEndTags();
+ if (errorHandler != null && currentPtr != eltPos) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ mode = IN_TABLE;
+ continue;
+ case BODY:
+ case COL:
+ case COLGROUP:
+ case HTML:
+ case TBODY_OR_THEAD_OR_TFOOT:
+ case TD_OR_TH:
+ case TR:
+ errStrayEndTag(name);
+ break endtagloop;
+ default:
+ // fall through to IN_BODY
+ }
+ case IN_CELL:
+ switch (group) {
+ case TD_OR_TH:
+ eltPos = findLastInTableScope(name);
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ generateImpliedEndTags();
+ if (errorHandler != null && !isCurrent(name)) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ mode = IN_ROW;
+ break endtagloop;
+ case TABLE:
+ case TBODY_OR_THEAD_OR_TFOOT:
+ case TR:
+ if (findLastInTableScope(name) == TreeBuilder.NOT_FOUND_ON_STACK) {
+ assert name == "tbody" || name == "tfoot" || name == "thead" || fragment || isTemplateContents();
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ closeTheCell(findLastInTableScopeTdTh());
+ continue;
+ case BODY:
+ case CAPTION:
+ case COL:
+ case COLGROUP:
+ case HTML:
+ errStrayEndTag(name);
+ break endtagloop;
+ default:
+ // fall through to IN_BODY
+ }
+ case FRAMESET_OK:
+ case IN_BODY:
+ switch (group) {
+ case BODY:
+ if (!isSecondOnStackBody()) {
+ assert fragment || isTemplateContents();
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ assert currentPtr >= 1;
+ if (errorHandler != null) {
+ uncloseloop1: for (int i = 2; i <= currentPtr; i++) {
+ switch (stack[i].getGroup()) {
+ case DD_OR_DT:
+ case LI:
+ case OPTGROUP:
+ case OPTION: // is this possible?
+ case P:
+ case RB_OR_RTC:
+ case RT_OR_RP:
+ case TD_OR_TH:
+ case TBODY_OR_THEAD_OR_TFOOT:
+ break;
+ default:
+ errEndWithUnclosedElements(name);
+ break uncloseloop1;
+ }
+ }
+ }
+ mode = AFTER_BODY;
+ break endtagloop;
+ case HTML:
+ if (!isSecondOnStackBody()) {
+ assert fragment || isTemplateContents();
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ if (errorHandler != null) {
+ uncloseloop2: for (int i = 0; i <= currentPtr; i++) {
+ switch (stack[i].getGroup()) {
+ case DD_OR_DT:
+ case LI:
+ case P:
+ case RB_OR_RTC:
+ case RT_OR_RP:
+ case TBODY_OR_THEAD_OR_TFOOT:
+ case TD_OR_TH:
+ case BODY:
+ case HTML:
+ break;
+ default:
+ errEndWithUnclosedElements(name);
+ break uncloseloop2;
+ }
+ }
+ }
+ mode = AFTER_BODY;
+ continue;
+ case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
+ case UL_OR_OL_OR_DL:
+ case PRE_OR_LISTING:
+ case FIELDSET:
+ case BUTTON:
+ case ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY:
+ eltPos = findLastInScope(name);
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ errStrayEndTag(name);
+ } else {
+ generateImpliedEndTags();
+ if (errorHandler != null && !isCurrent(name)) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ }
+ break endtagloop;
+ case FORM:
+ if (!isTemplateContents()) {
+ if (formPointer == null) {
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ formPointer = null;
+ eltPos = findLastInScope(name);
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ generateImpliedEndTags();
+ if (errorHandler != null && !isCurrent(name)) {
+ errUnclosedElements(eltPos, name);
+ }
+ removeFromStack(eltPos);
+ break endtagloop;
+ } else {
+ eltPos = findLastInScope(name);
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ generateImpliedEndTags();
+ if (errorHandler != null && !isCurrent(name)) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ break endtagloop;
+ }
+ case P:
+ eltPos = findLastInButtonScope("p");
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ errNoElementToCloseButEndTagSeen("p");
+ // XXX Can the 'in foreign' case happen anymore?
+ if (isInForeign()) {
+ errHtmlStartTagInForeignContext(name);
+ // Check for currentPtr for the fragment
+ // case.
+ while (currentPtr >= 0 && stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
+ pop();
+ }
+ }
+ appendVoidElementToCurrentMayFoster(
+ elementName,
+ HtmlAttributes.EMPTY_ATTRIBUTES);
+ break endtagloop;
+ }
+ generateImpliedEndTagsExceptFor("p");
+ assert eltPos != TreeBuilder.NOT_FOUND_ON_STACK;
+ if (errorHandler != null && eltPos != currentPtr) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ break endtagloop;
+ case LI:
+ eltPos = findLastInListScope(name);
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ errNoElementToCloseButEndTagSeen(name);
+ } else {
+ generateImpliedEndTagsExceptFor(name);
+ if (errorHandler != null
+ && eltPos != currentPtr) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ }
+ break endtagloop;
+ case DD_OR_DT:
+ eltPos = findLastInScope(name);
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ errNoElementToCloseButEndTagSeen(name);
+ } else {
+ generateImpliedEndTagsExceptFor(name);
+ if (errorHandler != null
+ && eltPos != currentPtr) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ }
+ break endtagloop;
+ case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
+ eltPos = findLastInScopeHn();
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ errStrayEndTag(name);
+ } else {
+ generateImpliedEndTags();
+ if (errorHandler != null && !isCurrent(name)) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ }
+ break endtagloop;
+ case OBJECT:
+ case MARQUEE_OR_APPLET:
+ eltPos = findLastInScope(name);
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ errStrayEndTag(name);
+ } else {
+ generateImpliedEndTags();
+ if (errorHandler != null && !isCurrent(name)) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ }
+ break endtagloop;
+ case BR:
+ errEndTagBr();
+ if (isInForeign()) {
+ // XXX can this happen anymore?
+ errHtmlStartTagInForeignContext(name);
+ // Check for currentPtr for the fragment
+ // case.
+ while (currentPtr >= 0 && stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
+ pop();
+ }
+ }
+ reconstructTheActiveFormattingElements();
+ appendVoidElementToCurrentMayFoster(
+ elementName,
+ HtmlAttributes.EMPTY_ATTRIBUTES);
+ break endtagloop;
+ case TEMPLATE:
+ // fall through to IN_HEAD;
+ break;
+ case AREA_OR_WBR:
+ // CPPONLY: case MENUITEM:
+ case PARAM_OR_SOURCE_OR_TRACK:
+ case EMBED:
+ case IMG:
+ case IMAGE:
+ case INPUT:
+ case KEYGEN: // XXX??
+ case HR:
+ case ISINDEX:
+ case IFRAME:
+ case NOEMBED: // XXX???
+ case NOFRAMES: // XXX??
+ case SELECT:
+ case TABLE:
+ case TEXTAREA: // XXX??
+ errStrayEndTag(name);
+ break endtagloop;
+ case NOSCRIPT:
+ if (scriptingEnabled) {
+ errStrayEndTag(name);
+ break endtagloop;
+ } else {
+ // fall through
+ }
+ case A:
+ case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
+ case FONT:
+ case NOBR:
+ if (adoptionAgencyEndTag(name)) {
+ break endtagloop;
+ }
+ // else handle like any other tag
+ default:
+ if (isCurrent(name)) {
+ pop();
+ break endtagloop;
+ }
+
+ eltPos = currentPtr;
+ for (;;) {
+ StackNode<T> node = stack[eltPos];
+ if (node.ns == "http://www.w3.org/1999/xhtml" && node.name == name) {
+ generateImpliedEndTags();
+ if (errorHandler != null
+ && !isCurrent(name)) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ break endtagloop;
+ } else if (eltPos == 0 || node.isSpecial()) {
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ eltPos--;
+ }
+ }
+ case IN_HEAD:
+ switch (group) {
+ case HEAD:
+ pop();
+ mode = AFTER_HEAD;
+ break endtagloop;
+ case BR:
+ case HTML:
+ case BODY:
+ pop();
+ mode = AFTER_HEAD;
+ continue;
+ case TEMPLATE:
+ endTagTemplateInHead();
+ break endtagloop;
+ default:
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ case IN_HEAD_NOSCRIPT:
+ switch (group) {
+ case NOSCRIPT:
+ pop();
+ mode = IN_HEAD;
+ break endtagloop;
+ case BR:
+ errStrayEndTag(name);
+ pop();
+ mode = IN_HEAD;
+ continue;
+ default:
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ case IN_COLUMN_GROUP:
+ switch (group) {
+ case COLGROUP:
+ if (currentPtr == 0 || stack[currentPtr].getGroup() ==
+ TreeBuilder.TEMPLATE) {
+ assert fragment || isTemplateContents();
+ errGarbageInColgroup();
+ break endtagloop;
+ }
+ pop();
+ mode = IN_TABLE;
+ break endtagloop;
+ case COL:
+ errStrayEndTag(name);
+ break endtagloop;
+ case TEMPLATE:
+ endTagTemplateInHead();
+ break endtagloop;
+ default:
+ if (currentPtr == 0 || stack[currentPtr].getGroup() ==
+ TreeBuilder.TEMPLATE) {
+ assert fragment || isTemplateContents();
+ errGarbageInColgroup();
+ break endtagloop;
+ }
+ pop();
+ mode = IN_TABLE;
+ continue;
+ }
+ case IN_SELECT_IN_TABLE:
+ switch (group) {
+ case CAPTION:
+ case TABLE:
+ case TBODY_OR_THEAD_OR_TFOOT:
+ case TR:
+ case TD_OR_TH:
+ errEndTagSeenWithSelectOpen(name);
+ if (findLastInTableScope(name) != TreeBuilder.NOT_FOUND_ON_STACK) {
+ eltPos = findLastInTableScope("select");
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ assert fragment;
+ break endtagloop; // http://www.w3.org/Bugs/Public/show_bug.cgi?id=8375
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ resetTheInsertionMode();
+ continue;
+ } else {
+ break endtagloop;
+ }
+ default:
+ // fall through to IN_SELECT
+ }
+ case IN_SELECT:
+ switch (group) {
+ case OPTION:
+ if (isCurrent("option")) {
+ pop();
+ break endtagloop;
+ } else {
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ case OPTGROUP:
+ if (isCurrent("option")
+ && "optgroup" == stack[currentPtr - 1].name) {
+ pop();
+ }
+ if (isCurrent("optgroup")) {
+ pop();
+ } else {
+ errStrayEndTag(name);
+ }
+ break endtagloop;
+ case SELECT:
+ eltPos = findLastInTableScope("select");
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ assert fragment;
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ resetTheInsertionMode();
+ break endtagloop;
+ case TEMPLATE:
+ endTagTemplateInHead();
+ break endtagloop;
+ default:
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ case AFTER_BODY:
+ switch (group) {
+ case HTML:
+ if (fragment) {
+ errStrayEndTag(name);
+ break endtagloop;
+ } else {
+ mode = AFTER_AFTER_BODY;
+ break endtagloop;
+ }
+ default:
+ errEndTagAfterBody();
+ mode = framesetOk ? FRAMESET_OK : IN_BODY;
+ continue;
+ }
+ case IN_FRAMESET:
+ switch (group) {
+ case FRAMESET:
+ if (currentPtr == 0) {
+ assert fragment;
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ pop();
+ if ((!fragment) && !isCurrent("frameset")) {
+ mode = AFTER_FRAMESET;
+ }
+ break endtagloop;
+ default:
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ case AFTER_FRAMESET:
+ switch (group) {
+ case HTML:
+ mode = AFTER_AFTER_FRAMESET;
+ break endtagloop;
+ default:
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ case INITIAL:
+ /*
+ * Parse error.
+ */
+ // [NOCPP[
+ switch (doctypeExpectation) {
+ case AUTO:
+ err("End tag seen without seeing a doctype first. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
+ break;
+ case HTML:
+ // ]NOCPP]
+ errEndTagSeenWithoutDoctype();
+ // [NOCPP[
+ break;
+ case HTML401_STRICT:
+ err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
+ break;
+ case HTML401_TRANSITIONAL:
+ err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
+ break;
+ case NO_DOCTYPE_ERRORS:
+ }
+ // ]NOCPP]
+ /*
+ *
+ * Set the document to quirks mode.
+ */
+ documentModeInternal(DocumentMode.QUIRKS_MODE, null, null,
+ false);
+ /*
+ * Then, switch to the root element mode of the tree
+ * construction stage
+ */
+ mode = BEFORE_HTML;
+ /*
+ * and reprocess the current token.
+ */
+ continue;
+ case BEFORE_HTML:
+ switch (group) {
+ case HEAD:
+ case BR:
+ case HTML:
+ case BODY:
+ /*
+ * Create an HTMLElement node with the tag name
+ * html, in the HTML namespace. Append it to the
+ * Document object.
+ */
+ appendHtmlElementToDocumentAndPush();
+ /* Switch to the main mode */
+ mode = BEFORE_HEAD;
+ /*
+ * reprocess the current token.
+ */
+ continue;
+ default:
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ case BEFORE_HEAD:
+ switch (group) {
+ case HEAD:
+ case BR:
+ case HTML:
+ case BODY:
+ appendToCurrentNodeAndPushHeadElement(HtmlAttributes.EMPTY_ATTRIBUTES);
+ mode = IN_HEAD;
+ continue;
+ default:
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ case AFTER_HEAD:
+ switch (group) {
+ case TEMPLATE:
+ endTagTemplateInHead();
+ break endtagloop;
+ case HTML:
+ case BODY:
+ case BR:
+ appendToCurrentNodeAndPushBodyElement();
+ mode = FRAMESET_OK;
+ continue;
+ default:
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+ case AFTER_AFTER_BODY:
+ errStrayEndTag(name);
+ mode = framesetOk ? FRAMESET_OK : IN_BODY;
+ continue;
+ case AFTER_AFTER_FRAMESET:
+ errStrayEndTag(name);
+ break endtagloop;
+ case TEXT:
+ // XXX need to manage insertion point here
+ pop();
+ if (originalMode == AFTER_HEAD) {
+ silentPop();
+ }
+ mode = originalMode;
+ break endtagloop;
+ }
+ } // endtagloop
+ }
+
+ private void endTagTemplateInHead() throws SAXException {
+ int eltPos = findLast("template");
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ errStrayEndTag("template");
+ return;
+ }
+ generateImpliedEndTags();
+ if (errorHandler != null && !isCurrent("template")) {
+ errUnclosedElements(eltPos, "template");
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ popTemplateMode();
+ resetTheInsertionMode();
+ }
+
+ private int findLastInTableScopeOrRootTemplateTbodyTheadTfoot() {
+ for (int i = currentPtr; i > 0; i--) {
+ if (stack[i].getGroup() == TreeBuilder.TBODY_OR_THEAD_OR_TFOOT ||
+ stack[i].getGroup() == TreeBuilder.TEMPLATE) {
+ return i;
+ }
+ }
+ return 0;
+ }
+
+ private int findLast(@Local String name) {
+ for (int i = currentPtr; i > 0; i--) {
+ if (stack[i].ns == "http://www.w3.org/1999/xhtml" && stack[i].name == name) {
+ return i;
+ }
+ }
+ return TreeBuilder.NOT_FOUND_ON_STACK;
+ }
+
+ private int findLastInTableScope(@Local String name) {
+ for (int i = currentPtr; i > 0; i--) {
+ if (stack[i].ns == "http://www.w3.org/1999/xhtml") {
+ if (stack[i].name == name) {
+ return i;
+ } else if (stack[i].name == "table" || stack[i].name == "template") {
+ return TreeBuilder.NOT_FOUND_ON_STACK;
+ }
+ }
+ }
+ return TreeBuilder.NOT_FOUND_ON_STACK;
+ }
+
+ private int findLastInButtonScope(@Local String name) {
+ for (int i = currentPtr; i > 0; i--) {
+ if (stack[i].ns == "http://www.w3.org/1999/xhtml") {
+ if (stack[i].name == name) {
+ return i;
+ } else if (stack[i].name == "button") {
+ return TreeBuilder.NOT_FOUND_ON_STACK;
+ }
+ }
+
+ if (stack[i].isScoping()) {
+ return TreeBuilder.NOT_FOUND_ON_STACK;
+ }
+ }
+ return TreeBuilder.NOT_FOUND_ON_STACK;
+ }
+
+ private int findLastInScope(@Local String name) {
+ for (int i = currentPtr; i > 0; i--) {
+ if (stack[i].ns == "http://www.w3.org/1999/xhtml" && stack[i].name == name) {
+ return i;
+ } else if (stack[i].isScoping()) {
+ return TreeBuilder.NOT_FOUND_ON_STACK;
+ }
+ }
+ return TreeBuilder.NOT_FOUND_ON_STACK;
+ }
+
+ private int findLastInListScope(@Local String name) {
+ for (int i = currentPtr; i > 0; i--) {
+ if (stack[i].ns == "http://www.w3.org/1999/xhtml") {
+ if (stack[i].name == name) {
+ return i;
+ } else if (stack[i].name == "ul" || stack[i].name == "ol") {
+ return TreeBuilder.NOT_FOUND_ON_STACK;
+ }
+ }
+
+ if (stack[i].isScoping()) {
+ return TreeBuilder.NOT_FOUND_ON_STACK;
+ }
+ }
+ return TreeBuilder.NOT_FOUND_ON_STACK;
+ }
+
+ private int findLastInScopeHn() {
+ for (int i = currentPtr; i > 0; i--) {
+ if (stack[i].getGroup() == TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6) {
+ return i;
+ } else if (stack[i].isScoping()) {
+ return TreeBuilder.NOT_FOUND_ON_STACK;
+ }
+ }
+ return TreeBuilder.NOT_FOUND_ON_STACK;
+ }
+
+ private void generateImpliedEndTagsExceptFor(@Local String name)
+ throws SAXException {
+ for (;;) {
+ StackNode<T> node = stack[currentPtr];
+ switch (node.getGroup()) {
+ case P:
+ case LI:
+ case DD_OR_DT:
+ case OPTION:
+ case OPTGROUP:
+ case RB_OR_RTC:
+ case RT_OR_RP:
+ if (node.ns == "http://www.w3.org/1999/xhtml" && node.name == name) {
+ return;
+ }
+ pop();
+ continue;
+ default:
+ return;
+ }
+ }
+ }
+
+ private void generateImpliedEndTags() throws SAXException {
+ for (;;) {
+ switch (stack[currentPtr].getGroup()) {
+ case P:
+ case LI:
+ case DD_OR_DT:
+ case OPTION:
+ case OPTGROUP:
+ case RB_OR_RTC:
+ case RT_OR_RP:
+ pop();
+ continue;
+ default:
+ return;
+ }
+ }
+ }
+
+ private boolean isSecondOnStackBody() {
+ return currentPtr >= 1 && stack[1].getGroup() == TreeBuilder.BODY;
+ }
+
+ private void documentModeInternal(DocumentMode m, String publicIdentifier,
+ String systemIdentifier, boolean html4SpecificAdditionalErrorChecks)
+ throws SAXException {
+
+ if (isSrcdocDocument) {
+ // Srcdoc documents are always rendered in standards mode.
+ quirks = false;
+ if (documentModeHandler != null) {
+ documentModeHandler.documentMode(
+ DocumentMode.STANDARDS_MODE
+ // [NOCPP[
+ , null, null, false
+ // ]NOCPP]
+ );
+ }
+ return;
+ }
+
+ quirks = (m == DocumentMode.QUIRKS_MODE);
+ if (documentModeHandler != null) {
+ documentModeHandler.documentMode(
+ m
+ // [NOCPP[
+ , publicIdentifier, systemIdentifier,
+ html4SpecificAdditionalErrorChecks
+ // ]NOCPP]
+ );
+ }
+ // [NOCPP[
+ documentMode(m, publicIdentifier, systemIdentifier,
+ html4SpecificAdditionalErrorChecks);
+ // ]NOCPP]
+ }
+
+ private boolean isAlmostStandards(String publicIdentifier,
+ String systemIdentifier) {
+ if (Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "-//w3c//dtd xhtml 1.0 transitional//en", publicIdentifier)) {
+ return true;
+ }
+ if (Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "-//w3c//dtd xhtml 1.0 frameset//en", publicIdentifier)) {
+ return true;
+ }
+ if (systemIdentifier != null) {
+ if (Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "-//w3c//dtd html 4.01 transitional//en", publicIdentifier)) {
+ return true;
+ }
+ if (Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "-//w3c//dtd html 4.01 frameset//en", publicIdentifier)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isQuirky(@Local String name, String publicIdentifier,
+ String systemIdentifier, boolean forceQuirks) {
+ if (forceQuirks) {
+ return true;
+ }
+ if (name != HTML_LOCAL) {
+ return true;
+ }
+ if (publicIdentifier != null) {
+ for (int i = 0; i < TreeBuilder.QUIRKY_PUBLIC_IDS.length; i++) {
+ if (Portability.lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
+ TreeBuilder.QUIRKY_PUBLIC_IDS[i], publicIdentifier)) {
+ return true;
+ }
+ }
+ if (Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "-//w3o//dtd w3 html strict 3.0//en//", publicIdentifier)
+ || Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "-/w3c/dtd html 4.0 transitional/en",
+ publicIdentifier)
+ || Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "html", publicIdentifier)) {
+ return true;
+ }
+ }
+ if (systemIdentifier == null) {
+ if (Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "-//w3c//dtd html 4.01 transitional//en", publicIdentifier)) {
+ return true;
+ } else if (Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "-//w3c//dtd html 4.01 frameset//en", publicIdentifier)) {
+ return true;
+ }
+ } else if (Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd",
+ systemIdentifier)) {
+ return true;
+ }
+ return false;
+ }
+
+ private void closeTheCell(int eltPos) throws SAXException {
+ generateImpliedEndTags();
+ if (errorHandler != null && eltPos != currentPtr) {
+ errUnclosedElementsCell(eltPos);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ mode = IN_ROW;
+ return;
+ }
+
+ private int findLastInTableScopeTdTh() {
+ for (int i = currentPtr; i > 0; i--) {
+ @Local String name = stack[i].name;
+ if (stack[i].ns == "http://www.w3.org/1999/xhtml") {
+ if ("td" == name || "th" == name) {
+ return i;
+ } else if (name == "table" || name == "template") {
+ return TreeBuilder.NOT_FOUND_ON_STACK;
+ }
+ }
+ }
+ return TreeBuilder.NOT_FOUND_ON_STACK;
+ }
+
+ private void clearStackBackTo(int eltPos) throws SAXException {
+ int eltGroup = stack[eltPos].getGroup();
+ while (currentPtr > eltPos) { // > not >= intentional
+ if (stack[currentPtr].ns == "http://www.w3.org/1999/xhtml"
+ && stack[currentPtr].getGroup() == TEMPLATE
+ && (eltGroup == TABLE || eltGroup == TBODY_OR_THEAD_OR_TFOOT|| eltGroup == TR || eltPos == 0)) {
+ return;
+ }
+ pop();
+ }
+ }
+
+ private void resetTheInsertionMode() {
+ StackNode<T> node;
+ @Local String name;
+ @NsUri String ns;
+ for (int i = currentPtr; i >= 0; i--) {
+ node = stack[i];
+ name = node.name;
+ ns = node.ns;
+ if (i == 0) {
+ if (!(contextNamespace == "http://www.w3.org/1999/xhtml" && (contextName == "td" || contextName == "th"))) {
+ if (fragment) {
+ // Make sure we are parsing a fragment otherwise the context element doesn't make sense.
+ name = contextName;
+ ns = contextNamespace;
+ }
+ } else {
+ mode = framesetOk ? FRAMESET_OK : IN_BODY; // XXX from Hixie's email
+ return;
+ }
+ }
+ if ("select" == name) {
+ int ancestorIndex = i;
+ while (ancestorIndex > 0) {
+ StackNode<T> ancestor = stack[ancestorIndex--];
+ if ("http://www.w3.org/1999/xhtml" == ancestor.ns) {
+ if ("template" == ancestor.name) {
+ break;
+ }
+ if ("table" == ancestor.name) {
+ mode = IN_SELECT_IN_TABLE;
+ return;
+ }
+ }
+ }
+ mode = IN_SELECT;
+ return;
+ } else if ("td" == name || "th" == name) {
+ mode = IN_CELL;
+ return;
+ } else if ("tr" == name) {
+ mode = IN_ROW;
+ return;
+ } else if ("tbody" == name || "thead" == name || "tfoot" == name) {
+ mode = IN_TABLE_BODY;
+ return;
+ } else if ("caption" == name) {
+ mode = IN_CAPTION;
+ return;
+ } else if ("colgroup" == name) {
+ mode = IN_COLUMN_GROUP;
+ return;
+ } else if ("table" == name) {
+ mode = IN_TABLE;
+ return;
+ } else if ("http://www.w3.org/1999/xhtml" != ns) {
+ mode = framesetOk ? FRAMESET_OK : IN_BODY;
+ return;
+ } else if ("template" == name) {
+ assert templateModePtr >= 0;
+ mode = templateModeStack[templateModePtr];
+ return;
+ } else if ("head" == name) {
+ if (name == contextName) {
+ mode = framesetOk ? FRAMESET_OK : IN_BODY; // really
+ } else {
+ mode = IN_HEAD;
+ }
+ return;
+ } else if ("body" == name) {
+ mode = framesetOk ? FRAMESET_OK : IN_BODY;
+ return;
+ } else if ("frameset" == name) {
+ // TODO: Fragment case. Add error reporting.
+ mode = IN_FRAMESET;
+ return;
+ } else if ("html" == name) {
+ if (headPointer == null) {
+ // TODO: Fragment case. Add error reporting.
+ mode = BEFORE_HEAD;
+ } else {
+ mode = AFTER_HEAD;
+ }
+ return;
+ } else if (i == 0) {
+ mode = framesetOk ? FRAMESET_OK : IN_BODY;
+ return;
+ }
+ }
+ }
+
+ /**
+ * @throws SAXException
+ *
+ */
+ private void implicitlyCloseP() throws SAXException {
+ int eltPos = findLastInButtonScope("p");
+ if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+ return;
+ }
+ generateImpliedEndTagsExceptFor("p");
+ if (errorHandler != null && eltPos != currentPtr) {
+ errUnclosedElementsImplied(eltPos, "p");
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ }
+
+ private boolean debugOnlyClearLastStackSlot() {
+ stack[currentPtr] = null;
+ return true;
+ }
+
+ private boolean debugOnlyClearLastListSlot() {
+ listOfActiveFormattingElements[listPtr] = null;
+ return true;
+ }
+
+ private void pushTemplateMode(int mode) {
+ templateModePtr++;
+ if (templateModePtr == templateModeStack.length) {
+ int[] newStack = new int[templateModeStack.length + 64];
+ System.arraycopy(templateModeStack, 0, newStack, 0, templateModeStack.length);
+ templateModeStack = newStack;
+ }
+ templateModeStack[templateModePtr] = mode;
+ }
+
+ @SuppressWarnings("unchecked") private void push(StackNode<T> node) throws SAXException {
+ currentPtr++;
+ if (currentPtr == stack.length) {
+ StackNode<T>[] newStack = new StackNode[stack.length + 64];
+ System.arraycopy(stack, 0, newStack, 0, stack.length);
+ stack = newStack;
+ }
+ stack[currentPtr] = node;
+ elementPushed(node.ns, node.popName, node.node);
+ }
+
+ @SuppressWarnings("unchecked") private void silentPush(StackNode<T> node) throws SAXException {
+ currentPtr++;
+ if (currentPtr == stack.length) {
+ StackNode<T>[] newStack = new StackNode[stack.length + 64];
+ System.arraycopy(stack, 0, newStack, 0, stack.length);
+ stack = newStack;
+ }
+ stack[currentPtr] = node;
+ }
+
+ @SuppressWarnings("unchecked") private void append(StackNode<T> node) {
+ listPtr++;
+ if (listPtr == listOfActiveFormattingElements.length) {
+ StackNode<T>[] newList = new StackNode[listOfActiveFormattingElements.length + 64];
+ System.arraycopy(listOfActiveFormattingElements, 0, newList, 0,
+ listOfActiveFormattingElements.length);
+ listOfActiveFormattingElements = newList;
+ }
+ listOfActiveFormattingElements[listPtr] = node;
+ }
+
+ @Inline private void insertMarker() {
+ append(null);
+ }
+
+ private void clearTheListOfActiveFormattingElementsUpToTheLastMarker() {
+ while (listPtr > -1) {
+ if (listOfActiveFormattingElements[listPtr] == null) {
+ --listPtr;
+ return;
+ }
+ listOfActiveFormattingElements[listPtr].release();
+ --listPtr;
+ }
+ }
+
+ @Inline private boolean isCurrent(@Local String name) {
+ return stack[currentPtr].ns == "http://www.w3.org/1999/xhtml" &&
+ name == stack[currentPtr].name;
+ }
+
+ private void removeFromStack(int pos) throws SAXException {
+ if (currentPtr == pos) {
+ pop();
+ } else {
+ fatal();
+ stack[pos].release();
+ System.arraycopy(stack, pos + 1, stack, pos, currentPtr - pos);
+ assert debugOnlyClearLastStackSlot();
+ currentPtr--;
+ }
+ }
+
+ private void removeFromStack(StackNode<T> node) throws SAXException {
+ if (stack[currentPtr] == node) {
+ pop();
+ } else {
+ int pos = currentPtr - 1;
+ while (pos >= 0 && stack[pos] != node) {
+ pos--;
+ }
+ if (pos == -1) {
+ // dead code?
+ return;
+ }
+ fatal();
+ node.release();
+ System.arraycopy(stack, pos + 1, stack, pos, currentPtr - pos);
+ currentPtr--;
+ }
+ }
+
+ private void removeFromListOfActiveFormattingElements(int pos) {
+ assert listOfActiveFormattingElements[pos] != null;
+ listOfActiveFormattingElements[pos].release();
+ if (pos == listPtr) {
+ assert debugOnlyClearLastListSlot();
+ listPtr--;
+ return;
+ }
+ assert pos < listPtr;
+ System.arraycopy(listOfActiveFormattingElements, pos + 1,
+ listOfActiveFormattingElements, pos, listPtr - pos);
+ assert debugOnlyClearLastListSlot();
+ listPtr--;
+ }
+
+ /**
+ * Adoption agency algorithm.
+ *
+ * @param name subject as described in the specified algorithm.
+ * @return Returns true if the algorithm has completed and there is nothing remaining to
+ * be done. Returns false if the algorithm needs to "act as described in the 'any other
+ * end tag' entry" as described in the specified algorithm.
+ * @throws SAXException
+ */
+ private boolean adoptionAgencyEndTag(@Local String name) throws SAXException {
+ // This check intends to ensure that for properly nested tags, closing tags will match
+ // against the stack instead of the listOfActiveFormattingElements.
+ if (stack[currentPtr].ns == "http://www.w3.org/1999/xhtml" &&
+ stack[currentPtr].name == name &&
+ findInListOfActiveFormattingElements(stack[currentPtr]) == -1) {
+ // If the current element matches the name but isn't on the list of active
+ // formatting elements, then it is possible that the list was mangled by the Noah's Ark
+ // clause. In this case, we want to match the end tag against the stack instead of
+ // proceeding with the AAA algorithm that may match against the list of
+ // active formatting elements (and possibly mangle the tree in unexpected ways).
+ pop();
+ return true;
+ }
+
+ // If you crash around here, perhaps some stack node variable claimed to
+ // be a weak ref isn't.
+ for (int i = 0; i < 8; ++i) {
+ int formattingEltListPos = listPtr;
+ while (formattingEltListPos > -1) {
+ StackNode<T> listNode = listOfActiveFormattingElements[formattingEltListPos]; // weak ref
+ if (listNode == null) {
+ formattingEltListPos = -1;
+ break;
+ } else if (listNode.name == name) {
+ break;
+ }
+ formattingEltListPos--;
+ }
+ if (formattingEltListPos == -1) {
+ return false;
+ }
+ // this *looks* like a weak ref to the list of formatting elements
+ StackNode<T> formattingElt = listOfActiveFormattingElements[formattingEltListPos];
+ int formattingEltStackPos = currentPtr;
+ boolean inScope = true;
+ while (formattingEltStackPos > -1) {
+ StackNode<T> node = stack[formattingEltStackPos]; // weak ref
+ if (node == formattingElt) {
+ break;
+ } else if (node.isScoping()) {
+ inScope = false;
+ }
+ formattingEltStackPos--;
+ }
+ if (formattingEltStackPos == -1) {
+ errNoElementToCloseButEndTagSeen(name);
+ removeFromListOfActiveFormattingElements(formattingEltListPos);
+ return true;
+ }
+ if (!inScope) {
+ errNoElementToCloseButEndTagSeen(name);
+ return true;
+ }
+ // stackPos now points to the formatting element and it is in scope
+ if (formattingEltStackPos != currentPtr) {
+ errEndTagViolatesNestingRules(name);
+ }
+ int furthestBlockPos = formattingEltStackPos + 1;
+ while (furthestBlockPos <= currentPtr) {
+ StackNode<T> node = stack[furthestBlockPos]; // weak ref
+ assert furthestBlockPos > 0: "How is formattingEltStackPos + 1 not > 0?";
+ if (node.isSpecial()) {
+ break;
+ }
+ furthestBlockPos++;
+ }
+ if (furthestBlockPos > currentPtr) {
+ // no furthest block
+ while (currentPtr >= formattingEltStackPos) {
+ pop();
+ }
+ removeFromListOfActiveFormattingElements(formattingEltListPos);
+ return true;
+ }
+ StackNode<T> commonAncestor = stack[formattingEltStackPos - 1]; // weak ref
+ StackNode<T> furthestBlock = stack[furthestBlockPos]; // weak ref
+ // detachFromParent(furthestBlock.node); XXX AAA CHANGE
+ int bookmark = formattingEltListPos;
+ int nodePos = furthestBlockPos;
+ StackNode<T> lastNode = furthestBlock; // weak ref
+ int j = 0;
+ for (;;) {
+ ++j;
+ nodePos--;
+ if (nodePos == formattingEltStackPos) {
+ break;
+ }
+ StackNode<T> node = stack[nodePos]; // weak ref
+ int nodeListPos = findInListOfActiveFormattingElements(node);
+
+ if (j > 3 && nodeListPos != -1) {
+ removeFromListOfActiveFormattingElements(nodeListPos);
+
+ // Adjust the indices into the list to account
+ // for the removal of nodeListPos.
+ if (nodeListPos <= formattingEltListPos) {
+ formattingEltListPos--;
+ }
+ if (nodeListPos <= bookmark) {
+ bookmark--;
+ }
+
+ // Update position to reflect removal from list.
+ nodeListPos = -1;
+ }
+
+ if (nodeListPos == -1) {
+ assert formattingEltStackPos < nodePos;
+ assert bookmark < nodePos;
+ assert furthestBlockPos > nodePos;
+ removeFromStack(nodePos); // node is now a bad pointer in C++
+ furthestBlockPos--;
+ continue;
+ }
+ // now node is both on stack and in the list
+ if (nodePos == furthestBlockPos) {
+ bookmark = nodeListPos + 1;
+ }
+ // if (hasChildren(node.node)) { XXX AAA CHANGE
+ assert node == listOfActiveFormattingElements[nodeListPos];
+ assert node == stack[nodePos];
+ T clone = createElement("http://www.w3.org/1999/xhtml",
+ node.name, node.attributes.cloneAttributes(null), commonAncestor.node);
+ StackNode<T> newNode = new StackNode<T>(node.getFlags(), node.ns,
+ node.name, clone, node.popName, node.attributes
+ // [NOCPP[
+ , node.getLocator()
+ // ]NOCPP]
+ ); // creation ownership goes to stack
+ node.dropAttributes(); // adopt ownership to newNode
+ stack[nodePos] = newNode;
+ newNode.retain(); // retain for list
+ listOfActiveFormattingElements[nodeListPos] = newNode;
+ node.release(); // release from stack
+ node.release(); // release from list
+ node = newNode;
+ // } XXX AAA CHANGE
+ detachFromParent(lastNode.node);
+ appendElement(lastNode.node, node.node);
+ lastNode = node;
+ }
+ if (commonAncestor.isFosterParenting()) {
+ fatal();
+ detachFromParent(lastNode.node);
+ insertIntoFosterParent(lastNode.node);
+ } else {
+ detachFromParent(lastNode.node);
+ appendElement(lastNode.node, commonAncestor.node);
+ }
+ T clone = createElement("http://www.w3.org/1999/xhtml",
+ formattingElt.name,
+ formattingElt.attributes.cloneAttributes(null), furthestBlock.node);
+ StackNode<T> formattingClone = new StackNode<T>(
+ formattingElt.getFlags(), formattingElt.ns,
+ formattingElt.name, clone, formattingElt.popName,
+ formattingElt.attributes
+ // [NOCPP[
+ , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
+ // ]NOCPP]
+ ); // Ownership transfers to stack below
+ formattingElt.dropAttributes(); // transfer ownership to
+ // formattingClone
+ appendChildrenToNewParent(furthestBlock.node, clone);
+ appendElement(clone, furthestBlock.node);
+ removeFromListOfActiveFormattingElements(formattingEltListPos);
+ insertIntoListOfActiveFormattingElements(formattingClone, bookmark);
+ assert formattingEltStackPos < furthestBlockPos;
+ removeFromStack(formattingEltStackPos);
+ // furthestBlockPos is now off by one and points to the slot after
+ // it
+ insertIntoStack(formattingClone, furthestBlockPos);
+ }
+ return true;
+ }
+
+ private void insertIntoStack(StackNode<T> node, int position)
+ throws SAXException {
+ assert currentPtr + 1 < stack.length;
+ assert position <= currentPtr + 1;
+ if (position == currentPtr + 1) {
+ push(node);
+ } else {
+ System.arraycopy(stack, position, stack, position + 1,
+ (currentPtr - position) + 1);
+ currentPtr++;
+ stack[position] = node;
+ }
+ }
+
+ private void insertIntoListOfActiveFormattingElements(
+ StackNode<T> formattingClone, int bookmark) {
+ formattingClone.retain();
+ assert listPtr + 1 < listOfActiveFormattingElements.length;
+ if (bookmark <= listPtr) {
+ System.arraycopy(listOfActiveFormattingElements, bookmark,
+ listOfActiveFormattingElements, bookmark + 1,
+ (listPtr - bookmark) + 1);
+ }
+ listPtr++;
+ listOfActiveFormattingElements[bookmark] = formattingClone;
+ }
+
+ private int findInListOfActiveFormattingElements(StackNode<T> node) {
+ for (int i = listPtr; i >= 0; i--) {
+ if (node == listOfActiveFormattingElements[i]) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private int findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(
+ @Local String name) {
+ for (int i = listPtr; i >= 0; i--) {
+ StackNode<T> node = listOfActiveFormattingElements[i];
+ if (node == null) {
+ return -1;
+ } else if (node.name == name) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+
+ private void maybeForgetEarlierDuplicateFormattingElement(
+ @Local String name, HtmlAttributes attributes) throws SAXException {
+ int candidate = -1;
+ int count = 0;
+ for (int i = listPtr; i >= 0; i--) {
+ StackNode<T> node = listOfActiveFormattingElements[i];
+ if (node == null) {
+ break;
+ }
+ if (node.name == name && node.attributes.equalsAnother(attributes)) {
+ candidate = i;
+ ++count;
+ }
+ }
+ if (count >= 3) {
+ removeFromListOfActiveFormattingElements(candidate);
+ }
+ }
+
+ private int findLastOrRoot(@Local String name) {
+ for (int i = currentPtr; i > 0; i--) {
+ if (stack[i].ns == "http://www.w3.org/1999/xhtml" && stack[i].name == name) {
+ return i;
+ }
+ }
+ return 0;
+ }
+
+ private int findLastOrRoot(int group) {
+ for (int i = currentPtr; i > 0; i--) {
+ if (stack[i].getGroup() == group) {
+ return i;
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Attempt to add attribute to the body element.
+ * @param attributes the attributes
+ * @return <code>true</code> iff the attributes were added
+ * @throws SAXException
+ */
+ private boolean addAttributesToBody(HtmlAttributes attributes)
+ throws SAXException {
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
+ // ]NOCPP]
+ if (currentPtr >= 1) {
+ StackNode<T> body = stack[1];
+ if (body.getGroup() == TreeBuilder.BODY) {
+ addAttributesToElement(body.node, attributes);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void addAttributesToHtml(HtmlAttributes attributes)
+ throws SAXException {
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
+ // ]NOCPP]
+ addAttributesToElement(stack[0].node, attributes);
+ }
+
+ private void pushHeadPointerOntoStack() throws SAXException {
+ assert headPointer != null;
+ assert mode == AFTER_HEAD;
+ fatal();
+ silentPush(new StackNode<T>(ElementName.HEAD, headPointer
+ // [NOCPP[
+ , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
+ // ]NOCPP]
+ ));
+ }
+
+ /**
+ * @throws SAXException
+ *
+ */
+ private void reconstructTheActiveFormattingElements() throws SAXException {
+ if (listPtr == -1) {
+ return;
+ }
+ StackNode<T> mostRecent = listOfActiveFormattingElements[listPtr];
+ if (mostRecent == null || isInStack(mostRecent)) {
+ return;
+ }
+ int entryPos = listPtr;
+ for (;;) {
+ entryPos--;
+ if (entryPos == -1) {
+ break;
+ }
+ if (listOfActiveFormattingElements[entryPos] == null) {
+ break;
+ }
+ if (isInStack(listOfActiveFormattingElements[entryPos])) {
+ break;
+ }
+ }
+ while (entryPos < listPtr) {
+ entryPos++;
+ StackNode<T> entry = listOfActiveFormattingElements[entryPos];
+ StackNode<T> currentNode = stack[currentPtr];
+
+ T clone;
+ if (currentNode.isFosterParenting()) {
+ clone = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", entry.name,
+ entry.attributes.cloneAttributes(null));
+ } else {
+ clone = createElement("http://www.w3.org/1999/xhtml", entry.name,
+ entry.attributes.cloneAttributes(null), currentNode.node);
+ appendElement(clone, currentNode.node);
+ }
+
+ StackNode<T> entryClone = new StackNode<T>(entry.getFlags(),
+ entry.ns, entry.name, clone, entry.popName,
+ entry.attributes
+ // [NOCPP[
+ , entry.getLocator()
+ // ]NOCPP]
+ );
+
+ entry.dropAttributes(); // transfer ownership to entryClone
+
+ push(entryClone);
+ // stack takes ownership of the local variable
+ listOfActiveFormattingElements[entryPos] = entryClone;
+ // overwriting the old entry on the list, so release & retain
+ entry.release();
+ entryClone.retain();
+ }
+ }
+
+ private void insertIntoFosterParent(T child) throws SAXException {
+ int tablePos = findLastOrRoot(TreeBuilder.TABLE);
+ int templatePos = findLastOrRoot(TreeBuilder.TEMPLATE);
+
+ if (templatePos >= tablePos) {
+ appendElement(child, stack[templatePos].node);
+ return;
+ }
+
+ StackNode<T> node = stack[tablePos];
+ insertFosterParentedChild(child, node.node, stack[tablePos - 1].node);
+ }
+
+ private T createAndInsertFosterParentedElement(@NsUri String ns, @Local String name,
+ HtmlAttributes attributes) throws SAXException {
+ return createAndInsertFosterParentedElement(ns, name, attributes, null);
+ }
+
+ private T createAndInsertFosterParentedElement(@NsUri String ns, @Local String name,
+ HtmlAttributes attributes, T form) throws SAXException {
+ int tablePos = findLastOrRoot(TreeBuilder.TABLE);
+ int templatePos = findLastOrRoot(TreeBuilder.TEMPLATE);
+
+ if (templatePos >= tablePos) {
+ T child = createElement(ns, name, attributes, form, stack[templatePos].node);
+ appendElement(child, stack[templatePos].node);
+ return child;
+ }
+
+ StackNode<T> node = stack[tablePos];
+ return createAndInsertFosterParentedElement(ns, name, attributes, form, node.node, stack[tablePos - 1].node);
+ }
+
+ private boolean isInStack(StackNode<T> node) {
+ for (int i = currentPtr; i >= 0; i--) {
+ if (stack[i] == node) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void popTemplateMode() {
+ templateModePtr--;
+ }
+
+ private void pop() throws SAXException {
+ StackNode<T> node = stack[currentPtr];
+ assert debugOnlyClearLastStackSlot();
+ currentPtr--;
+ elementPopped(node.ns, node.popName, node.node);
+ node.release();
+ }
+
+ private void silentPop() throws SAXException {
+ StackNode<T> node = stack[currentPtr];
+ assert debugOnlyClearLastStackSlot();
+ currentPtr--;
+ node.release();
+ }
+
+ private void popOnEof() throws SAXException {
+ StackNode<T> node = stack[currentPtr];
+ assert debugOnlyClearLastStackSlot();
+ currentPtr--;
+ markMalformedIfScript(node.node);
+ elementPopped(node.ns, node.popName, node.node);
+ node.release();
+ }
+
+ // [NOCPP[
+ private void checkAttributes(HtmlAttributes attributes, @NsUri String ns)
+ throws SAXException {
+ if (errorHandler != null) {
+ int len = attributes.getXmlnsLength();
+ for (int i = 0; i < len; i++) {
+ AttributeName name = attributes.getXmlnsAttributeName(i);
+ if (name == AttributeName.XMLNS) {
+ if (html4) {
+ err("Attribute \u201Cxmlns\u201D not allowed here. (HTML4-only error.)");
+ } else {
+ String xmlns = attributes.getXmlnsValue(i);
+ if (!ns.equals(xmlns)) {
+ err("Bad value \u201C"
+ + xmlns
+ + "\u201D for the attribute \u201Cxmlns\u201D (only \u201C"
+ + ns + "\u201D permitted here).");
+ switch (namePolicy) {
+ case ALTER_INFOSET:
+ // fall through
+ case ALLOW:
+ warn("Attribute \u201Cxmlns\u201D is not serializable as XML 1.0.");
+ break;
+ case FATAL:
+ fatal("Attribute \u201Cxmlns\u201D is not serializable as XML 1.0.");
+ break;
+ }
+ }
+ }
+ } else if (ns != "http://www.w3.org/1999/xhtml"
+ && name == AttributeName.XMLNS_XLINK) {
+ String xmlns = attributes.getXmlnsValue(i);
+ if (!"http://www.w3.org/1999/xlink".equals(xmlns)) {
+ err("Bad value \u201C"
+ + xmlns
+ + "\u201D for the attribute \u201Cxmlns:link\u201D (only \u201Chttp://www.w3.org/1999/xlink\u201D permitted here).");
+ switch (namePolicy) {
+ case ALTER_INFOSET:
+ // fall through
+ case ALLOW:
+ warn("Attribute \u201Cxmlns:xlink\u201D with a value other than \u201Chttp://www.w3.org/1999/xlink\u201D is not serializable as XML 1.0 without changing document semantics.");
+ break;
+ case FATAL:
+ fatal("Attribute \u201Cxmlns:xlink\u201D with a value other than \u201Chttp://www.w3.org/1999/xlink\u201D is not serializable as XML 1.0 without changing document semantics.");
+ break;
+ }
+ }
+ } else {
+ err("Attribute \u201C" + attributes.getXmlnsLocalName(i)
+ + "\u201D not allowed here.");
+ switch (namePolicy) {
+ case ALTER_INFOSET:
+ // fall through
+ case ALLOW:
+ warn("Attribute with the local name \u201C"
+ + attributes.getXmlnsLocalName(i)
+ + "\u201D is not serializable as XML 1.0.");
+ break;
+ case FATAL:
+ fatal("Attribute with the local name \u201C"
+ + attributes.getXmlnsLocalName(i)
+ + "\u201D is not serializable as XML 1.0.");
+ break;
+ }
+ }
+ }
+ }
+ attributes.processNonNcNames(this, namePolicy);
+ }
+
+ private String checkPopName(@Local String name) throws SAXException {
+ if (NCName.isNCName(name)) {
+ return name;
+ } else {
+ switch (namePolicy) {
+ case ALLOW:
+ warn("Element name \u201C" + name
+ + "\u201D cannot be represented as XML 1.0.");
+ return name;
+ case ALTER_INFOSET:
+ warn("Element name \u201C" + name
+ + "\u201D cannot be represented as XML 1.0.");
+ return NCName.escapeName(name);
+ case FATAL:
+ fatal("Element name \u201C" + name
+ + "\u201D cannot be represented as XML 1.0.");
+ }
+ }
+ return null; // keep compiler happy
+ }
+
+ // ]NOCPP]
+
+ private void appendHtmlElementToDocumentAndPush(HtmlAttributes attributes)
+ throws SAXException {
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
+ // ]NOCPP]
+ T elt = createHtmlElementSetAsRoot(attributes);
+ StackNode<T> node = new StackNode<T>(ElementName.HTML,
+ elt
+ // [NOCPP[
+ , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
+ // ]NOCPP]
+ );
+ push(node);
+ }
+
+ private void appendHtmlElementToDocumentAndPush() throws SAXException {
+ appendHtmlElementToDocumentAndPush(tokenizer.emptyAttributes());
+ }
+
+ private void appendToCurrentNodeAndPushHeadElement(HtmlAttributes attributes)
+ throws SAXException {
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
+ // ]NOCPP]
+ T currentNode = stack[currentPtr].node;
+ T elt = createElement("http://www.w3.org/1999/xhtml", "head", attributes, currentNode);
+ appendElement(elt, currentNode);
+ headPointer = elt;
+ StackNode<T> node = new StackNode<T>(ElementName.HEAD,
+ elt
+ // [NOCPP[
+ , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
+ // ]NOCPP]
+ );
+ push(node);
+ }
+
+ private void appendToCurrentNodeAndPushBodyElement(HtmlAttributes attributes)
+ throws SAXException {
+ appendToCurrentNodeAndPushElement(ElementName.BODY,
+ attributes);
+ }
+
+ private void appendToCurrentNodeAndPushBodyElement() throws SAXException {
+ appendToCurrentNodeAndPushBodyElement(tokenizer.emptyAttributes());
+ }
+
+ private void appendToCurrentNodeAndPushFormElementMayFoster(
+ HtmlAttributes attributes) throws SAXException {
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
+ // ]NOCPP]
+
+ T elt;
+ StackNode<T> current = stack[currentPtr];
+ if (current.isFosterParenting()) {
+ fatal();
+ elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", "form", attributes);
+ } else {
+ elt = createElement("http://www.w3.org/1999/xhtml", "form", attributes, current.node);
+ appendElement(elt, current.node);
+ }
+
+ if (!isTemplateContents()) {
+ formPointer = elt;
+ }
+
+ StackNode<T> node = new StackNode<T>(ElementName.FORM,
+ elt
+ // [NOCPP[
+ , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
+ // ]NOCPP]
+ );
+ push(node);
+ }
+
+ private void appendToCurrentNodeAndPushFormattingElementMayFoster(
+ ElementName elementName, HtmlAttributes attributes)
+ throws SAXException {
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
+ // ]NOCPP]
+ // This method can't be called for custom elements
+ HtmlAttributes clone = attributes.cloneAttributes(null);
+ // Attributes must not be read after calling createElement, because
+ // createElement may delete attributes in C++.
+ T elt;
+ StackNode<T> current = stack[currentPtr];
+ if (current.isFosterParenting()) {
+ fatal();
+ elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", elementName.name, attributes);
+ } else {
+ elt = createElement("http://www.w3.org/1999/xhtml", elementName.name, attributes, current.node);
+ appendElement(elt, current.node);
+ }
+ StackNode<T> node = new StackNode<T>(elementName, elt, clone
+ // [NOCPP[
+ , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
+ // ]NOCPP]
+ );
+ push(node);
+ append(node);
+ node.retain(); // append doesn't retain itself
+ }
+
+ private void appendToCurrentNodeAndPushElement(ElementName elementName,
+ HtmlAttributes attributes)
+ throws SAXException {
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
+ // ]NOCPP]
+ // This method can't be called for custom elements
+ T currentNode = stack[currentPtr].node;
+ T elt = createElement("http://www.w3.org/1999/xhtml", elementName.name, attributes, currentNode);
+ appendElement(elt, currentNode);
+ if (ElementName.TEMPLATE == elementName) {
+ elt = getDocumentFragmentForTemplate(elt);
+ }
+ StackNode<T> node = new StackNode<T>(elementName, elt
+ // [NOCPP[
+ , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
+ // ]NOCPP]
+ );
+ push(node);
+ }
+
+ private void appendToCurrentNodeAndPushElementMayFoster(ElementName elementName,
+ HtmlAttributes attributes)
+ throws SAXException {
+ @Local String popName = elementName.name;
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
+ if (elementName.isCustom()) {
+ popName = checkPopName(popName);
+ }
+ // ]NOCPP]
+ T elt;
+ StackNode<T> current = stack[currentPtr];
+ if (current.isFosterParenting()) {
+ fatal();
+ elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", popName, attributes);
+ } else {
+ elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, current.node);
+ appendElement(elt, current.node);
+ }
+ StackNode<T> node = new StackNode<T>(elementName, elt, popName
+ // [NOCPP[
+ , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
+ // ]NOCPP]
+ );
+ push(node);
+ }
+
+ private void appendToCurrentNodeAndPushElementMayFosterMathML(
+ ElementName elementName, HtmlAttributes attributes)
+ throws SAXException {
+ @Local String popName = elementName.name;
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/1998/Math/MathML");
+ if (elementName.isCustom()) {
+ popName = checkPopName(popName);
+ }
+ // ]NOCPP]
+ boolean markAsHtmlIntegrationPoint = false;
+ if (ElementName.ANNOTATION_XML == elementName
+ && annotationXmlEncodingPermitsHtml(attributes)) {
+ markAsHtmlIntegrationPoint = true;
+ }
+ // Attributes must not be read after calling createElement(), since
+ // createElement may delete the object in C++.
+ T elt;
+ StackNode<T> current = stack[currentPtr];
+ if (current.isFosterParenting()) {
+ fatal();
+ elt = createAndInsertFosterParentedElement("http://www.w3.org/1998/Math/MathML", popName, attributes);
+ } else {
+ elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, current.node);
+ appendElement(elt, current.node);
+ }
+ StackNode<T> node = new StackNode<T>(elementName, elt, popName,
+ markAsHtmlIntegrationPoint
+ // [NOCPP[
+ , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
+ // ]NOCPP]
+ );
+ push(node);
+ }
+
+ // [NOCPP[
+ T getDocumentFragmentForTemplate(T template) {
+ return template;
+ }
+
+ T getFormPointerForContext(T context) {
+ return null;
+ }
+ // ]NOCPP]
+
+ private boolean annotationXmlEncodingPermitsHtml(HtmlAttributes attributes) {
+ String encoding = attributes.getValue(AttributeName.ENCODING);
+ if (encoding == null) {
+ return false;
+ }
+ return Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "application/xhtml+xml", encoding)
+ || Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "text/html", encoding);
+ }
+
+ private void appendToCurrentNodeAndPushElementMayFosterSVG(
+ ElementName elementName, HtmlAttributes attributes)
+ throws SAXException {
+ @Local String popName = elementName.camelCaseName;
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/2000/svg");
+ if (elementName.isCustom()) {
+ popName = checkPopName(popName);
+ }
+ // ]NOCPP]
+ T elt;
+ StackNode<T> current = stack[currentPtr];
+ if (current.isFosterParenting()) {
+ fatal();
+ elt = createAndInsertFosterParentedElement("http://www.w3.org/2000/svg", popName, attributes);
+ } else {
+ elt = createElement("http://www.w3.org/2000/svg", popName, attributes, current.node);
+ appendElement(elt, current.node);
+ }
+ StackNode<T> node = new StackNode<T>(elementName, popName, elt
+ // [NOCPP[
+ , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
+ // ]NOCPP]
+ );
+ push(node);
+ }
+
+ private void appendToCurrentNodeAndPushElementMayFoster(ElementName elementName,
+ HtmlAttributes attributes, T form)
+ throws SAXException {
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
+ // ]NOCPP]
+ // Can't be called for custom elements
+ T elt;
+ T formOwner = form == null || fragment || isTemplateContents() ? null : form;
+ StackNode<T> current = stack[currentPtr];
+ if (current.isFosterParenting()) {
+ fatal();
+ elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", elementName.name,
+ attributes, formOwner);
+ } else {
+ elt = createElement("http://www.w3.org/1999/xhtml", elementName.name,
+ attributes, formOwner, current.node);
+ appendElement(elt, current.node);
+ }
+ StackNode<T> node = new StackNode<T>(elementName, elt
+ // [NOCPP[
+ , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
+ // ]NOCPP]
+ );
+ push(node);
+ }
+
+ private void appendVoidElementToCurrentMayFoster(
+ @Local String name, HtmlAttributes attributes, T form) throws SAXException {
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
+ // ]NOCPP]
+ // Can't be called for custom elements
+ T elt;
+ T formOwner = form == null || fragment || isTemplateContents() ? null : form;
+ StackNode<T> current = stack[currentPtr];
+ if (current.isFosterParenting()) {
+ fatal();
+ elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", name,
+ attributes, formOwner);
+ } else {
+ elt = createElement("http://www.w3.org/1999/xhtml", name,
+ attributes, formOwner, current.node);
+ appendElement(elt, current.node);
+ }
+ elementPushed("http://www.w3.org/1999/xhtml", name, elt);
+ elementPopped("http://www.w3.org/1999/xhtml", name, elt);
+ }
+
+ private void appendVoidElementToCurrentMayFoster(
+ ElementName elementName, HtmlAttributes attributes)
+ throws SAXException {
+ @Local String popName = elementName.name;
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
+ if (elementName.isCustom()) {
+ popName = checkPopName(popName);
+ }
+ // ]NOCPP]
+ T elt;
+ StackNode<T> current = stack[currentPtr];
+ if (current.isFosterParenting()) {
+ fatal();
+ elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", popName, attributes);
+ } else {
+ elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, current.node);
+ appendElement(elt, current.node);
+ }
+ elementPushed("http://www.w3.org/1999/xhtml", popName, elt);
+ elementPopped("http://www.w3.org/1999/xhtml", popName, elt);
+ }
+
+ private void appendVoidElementToCurrentMayFosterSVG(
+ ElementName elementName, HtmlAttributes attributes)
+ throws SAXException {
+ @Local String popName = elementName.camelCaseName;
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/2000/svg");
+ if (elementName.isCustom()) {
+ popName = checkPopName(popName);
+ }
+ // ]NOCPP]
+ T elt;
+ StackNode<T> current = stack[currentPtr];
+ if (current.isFosterParenting()) {
+ fatal();
+ elt = createAndInsertFosterParentedElement("http://www.w3.org/2000/svg", popName, attributes);
+ } else {
+ elt = createElement("http://www.w3.org/2000/svg", popName, attributes, current.node);
+ appendElement(elt, current.node);
+ }
+ elementPushed("http://www.w3.org/2000/svg", popName, elt);
+ elementPopped("http://www.w3.org/2000/svg", popName, elt);
+ }
+
+ private void appendVoidElementToCurrentMayFosterMathML(
+ ElementName elementName, HtmlAttributes attributes)
+ throws SAXException {
+ @Local String popName = elementName.name;
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/1998/Math/MathML");
+ if (elementName.isCustom()) {
+ popName = checkPopName(popName);
+ }
+ // ]NOCPP]
+ T elt;
+ StackNode<T> current = stack[currentPtr];
+ if (current.isFosterParenting()) {
+ fatal();
+ elt = createAndInsertFosterParentedElement("http://www.w3.org/1998/Math/MathML", popName, attributes);
+ } else {
+ elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, current.node);
+ appendElement(elt, current.node);
+ }
+ elementPushed("http://www.w3.org/1998/Math/MathML", popName, elt);
+ elementPopped("http://www.w3.org/1998/Math/MathML", popName, elt);
+ }
+
+ private void appendVoidElementToCurrent(
+ @Local String name, HtmlAttributes attributes, T form) throws SAXException {
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
+ // ]NOCPP]
+ // Can't be called for custom elements
+ T currentNode = stack[currentPtr].node;
+ T elt = createElement("http://www.w3.org/1999/xhtml", name, attributes,
+ form == null || fragment || isTemplateContents() ? null : form, currentNode);
+ appendElement(elt, currentNode);
+ elementPushed("http://www.w3.org/1999/xhtml", name, elt);
+ elementPopped("http://www.w3.org/1999/xhtml", name, elt);
+ }
+
+ private void appendVoidFormToCurrent(HtmlAttributes attributes) throws SAXException {
+ // [NOCPP[
+ checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
+ // ]NOCPP]
+ T currentNode = stack[currentPtr].node;
+ T elt = createElement("http://www.w3.org/1999/xhtml", "form",
+ attributes, currentNode);
+ formPointer = elt;
+ // ownership transferred to form pointer
+ appendElement(elt, currentNode);
+ elementPushed("http://www.w3.org/1999/xhtml", "form", elt);
+ elementPopped("http://www.w3.org/1999/xhtml", "form", elt);
+ }
+
+ // [NOCPP[
+
+ private final void accumulateCharactersForced(@Const @NoLength char[] buf,
+ int start, int length) throws SAXException {
+ System.arraycopy(buf, start, charBuffer, charBufferLen, length);
+ charBufferLen += length;
+ }
+
+ @Override public void ensureBufferSpace(int inputLength)
+ throws SAXException {
+ // TODO: Unify Tokenizer.strBuf and TreeBuilder.charBuffer so that
+ // this method becomes unnecessary.
+ int worstCase = charBufferLen + inputLength;
+ if (charBuffer == null) {
+ // Add an arbitrary small value to avoid immediate reallocation
+ // once there are a few characters in the buffer.
+ charBuffer = new char[worstCase + 128];
+ } else if (worstCase > charBuffer.length) {
+ // HotSpot reportedly allocates memory with 8-byte accuracy, so
+ // there's no point in trying to do math here to avoid slop.
+ // Maybe we should add some small constant to worstCase here
+ // but not doing that without profiling. In C++ with jemalloc,
+ // the corresponding method should do math to round up here
+ // to avoid slop.
+ char[] newBuf = new char[worstCase];
+ System.arraycopy(charBuffer, 0, newBuf, 0, charBufferLen);
+ charBuffer = newBuf;
+ }
+ }
+
+ // ]NOCPP]
+
+ protected void accumulateCharacters(@Const @NoLength char[] buf, int start,
+ int length) throws SAXException {
+ appendCharacters(stack[currentPtr].node, buf, start, length);
+ }
+
+ // ------------------------------- //
+
+ protected final void requestSuspension() {
+ tokenizer.requestSuspension();
+ }
+
+ protected abstract T createElement(@NsUri String ns, @Local String name,
+ HtmlAttributes attributes, T intendedParent) throws SAXException;
+
+ protected T createElement(@NsUri String ns, @Local String name,
+ HtmlAttributes attributes, T form, T intendedParent) throws SAXException {
+ return createElement("http://www.w3.org/1999/xhtml", name, attributes, intendedParent);
+ }
+
+ protected abstract T createHtmlElementSetAsRoot(HtmlAttributes attributes)
+ throws SAXException;
+
+ protected abstract void detachFromParent(T element) throws SAXException;
+
+ protected abstract boolean hasChildren(T element) throws SAXException;
+
+ protected abstract void appendElement(T child, T newParent)
+ throws SAXException;
+
+ protected abstract void appendChildrenToNewParent(T oldParent, T newParent)
+ throws SAXException;
+
+ protected abstract void insertFosterParentedChild(T child, T table,
+ T stackParent) throws SAXException;
+
+ // We don't generate CPP code for this method because it is not used in generated CPP
+ // code. Instead, the form owner version of this method is called with a null form owner.
+ // [NOCPP[
+
+ protected abstract T createAndInsertFosterParentedElement(@NsUri String ns, @Local String name,
+ HtmlAttributes attributes, T table, T stackParent) throws SAXException;
+
+ // ]NOCPP]
+
+ protected T createAndInsertFosterParentedElement(@NsUri String ns, @Local String name,
+ HtmlAttributes attributes, T form, T table, T stackParent) throws SAXException {
+ return createAndInsertFosterParentedElement(ns, name, attributes, table, stackParent);
+ };
+
+ protected abstract void insertFosterParentedCharacters(
+ @NoLength char[] buf, int start, int length, T table, T stackParent)
+ throws SAXException;
+
+ protected abstract void appendCharacters(T parent, @NoLength char[] buf,
+ int start, int length) throws SAXException;
+
+ protected abstract void appendIsindexPrompt(T parent) throws SAXException;
+
+ protected abstract void appendComment(T parent, @NoLength char[] buf,
+ int start, int length) throws SAXException;
+
+ protected abstract void appendCommentToDocument(@NoLength char[] buf,
+ int start, int length) throws SAXException;
+
+ protected abstract void addAttributesToElement(T element,
+ HtmlAttributes attributes) throws SAXException;
+
+ protected void markMalformedIfScript(T elt) throws SAXException {
+
+ }
+
+ protected void start(boolean fragmentMode) throws SAXException {
+
+ }
+
+ protected void end() throws SAXException {
+
+ }
+
+ protected void appendDoctypeToDocument(@Local String name,
+ String publicIdentifier, String systemIdentifier)
+ throws SAXException {
+
+ }
+
+ protected void elementPushed(@NsUri String ns, @Local String name, T node)
+ throws SAXException {
+
+ }
+
+ protected void elementPopped(@NsUri String ns, @Local String name, T node)
+ throws SAXException {
+
+ }
+
+ // [NOCPP[
+
+ protected void documentMode(DocumentMode m, String publicIdentifier,
+ String systemIdentifier, boolean html4SpecificAdditionalErrorChecks)
+ throws SAXException {
+
+ }
+
+ /**
+ * @see nu.validator.htmlparser.common.TokenHandler#wantsComments()
+ */
+ public boolean wantsComments() {
+ return wantingComments;
+ }
+
+ public void setIgnoringComments(boolean ignoreComments) {
+ wantingComments = !ignoreComments;
+ }
+
+ /**
+ * Sets the errorHandler.
+ *
+ * @param errorHandler
+ * the errorHandler to set
+ */
+ public final void setErrorHandler(ErrorHandler errorHandler) {
+ this.errorHandler = errorHandler;
+ }
+
+ /**
+ * Returns the errorHandler.
+ *
+ * @return the errorHandler
+ */
+ public ErrorHandler getErrorHandler() {
+ return errorHandler;
+ }
+
+ /**
+ * The argument MUST be an interned string or <code>null</code>.
+ *
+ * @param context
+ */
+ public final void setFragmentContext(@Local String context) {
+ this.contextName = context;
+ this.contextNamespace = "http://www.w3.org/1999/xhtml";
+ this.contextNode = null;
+ this.fragment = (contextName != null);
+ this.quirks = false;
+ }
+
+ // ]NOCPP]
+
+ /**
+ * @see nu.validator.htmlparser.common.TokenHandler#cdataSectionAllowed()
+ */
+ @Inline public boolean cdataSectionAllowed() throws SAXException {
+ return isInForeign();
+ }
+
+ private boolean isInForeign() {
+ return currentPtr >= 0
+ && stack[currentPtr].ns != "http://www.w3.org/1999/xhtml";
+ }
+
+ private boolean isInForeignButNotHtmlOrMathTextIntegrationPoint() {
+ if (currentPtr < 0) {
+ return false;
+ }
+ return !isSpecialParentInForeign(stack[currentPtr]);
+ }
+
+ /**
+ * The argument MUST be an interned string or <code>null</code>.
+ *
+ * @param context
+ */
+ public final void setFragmentContext(@Local String context,
+ @NsUri String ns, T node, boolean quirks) {
+ // [NOCPP[
+ if (!((context == null && ns == null)
+ || "http://www.w3.org/1999/xhtml" == ns
+ || "http://www.w3.org/2000/svg" == ns || "http://www.w3.org/1998/Math/MathML" == ns)) {
+ throw new IllegalArgumentException(
+ "The namespace must be the HTML, SVG or MathML namespace (or null when the local name is null). Got: "
+ + ns);
+ }
+ // ]NOCPP]
+ this.contextName = context;
+ this.contextNamespace = ns;
+ this.contextNode = node;
+ this.fragment = (contextName != null);
+ this.quirks = quirks;
+ }
+
+ protected final T currentNode() {
+ return stack[currentPtr].node;
+ }
+
+ /**
+ * Returns the scriptingEnabled.
+ *
+ * @return the scriptingEnabled
+ */
+ public boolean isScriptingEnabled() {
+ return scriptingEnabled;
+ }
+
+ /**
+ * Sets the scriptingEnabled.
+ *
+ * @param scriptingEnabled
+ * the scriptingEnabled to set
+ */
+ public void setScriptingEnabled(boolean scriptingEnabled) {
+ this.scriptingEnabled = scriptingEnabled;
+ }
+
+ public void setIsSrcdocDocument(boolean isSrcdocDocument) {
+ this.isSrcdocDocument = isSrcdocDocument;
+ }
+
+ // [NOCPP[
+
+ /**
+ * Sets the doctypeExpectation.
+ *
+ * @param doctypeExpectation
+ * the doctypeExpectation to set
+ */
+ public void setDoctypeExpectation(DoctypeExpectation doctypeExpectation) {
+ this.doctypeExpectation = doctypeExpectation;
+ }
+
+ public void setNamePolicy(XmlViolationPolicy namePolicy) {
+ this.namePolicy = namePolicy;
+ }
+
+ /**
+ * Sets the documentModeHandler.
+ *
+ * @param documentModeHandler
+ * the documentModeHandler to set
+ */
+ public void setDocumentModeHandler(DocumentModeHandler documentModeHandler) {
+ this.documentModeHandler = documentModeHandler;
+ }
+
+ /**
+ * Sets the reportingDoctype.
+ *
+ * @param reportingDoctype
+ * the reportingDoctype to set
+ */
+ public void setReportingDoctype(boolean reportingDoctype) {
+ this.reportingDoctype = reportingDoctype;
+ }
+
+ // ]NOCPP]
+
+ /**
+ * Flushes the pending characters. Public for document.write use cases only.
+ * @throws SAXException
+ */
+ public final void flushCharacters() throws SAXException {
+ if (charBufferLen > 0) {
+ if ((mode == IN_TABLE || mode == IN_TABLE_BODY || mode == IN_ROW)
+ && charBufferContainsNonWhitespace()) {
+ errNonSpaceInTable();
+ reconstructTheActiveFormattingElements();
+ if (!stack[currentPtr].isFosterParenting()) {
+ // reconstructing gave us a new current node
+ appendCharacters(currentNode(), charBuffer, 0,
+ charBufferLen);
+ charBufferLen = 0;
+ return;
+ }
+
+ int tablePos = findLastOrRoot(TreeBuilder.TABLE);
+ int templatePos = findLastOrRoot(TreeBuilder.TEMPLATE);
+
+ if (templatePos >= tablePos) {
+ appendCharacters(stack[templatePos].node, charBuffer, 0, charBufferLen);
+ charBufferLen = 0;
+ return;
+ }
+
+ StackNode<T> tableElt = stack[tablePos];
+ insertFosterParentedCharacters(charBuffer, 0, charBufferLen,
+ tableElt.node, stack[tablePos - 1].node);
+ charBufferLen = 0;
+ return;
+ }
+ appendCharacters(currentNode(), charBuffer, 0, charBufferLen);
+ charBufferLen = 0;
+ }
+ }
+
+ private boolean charBufferContainsNonWhitespace() {
+ for (int i = 0; i < charBufferLen; i++) {
+ switch (charBuffer[i]) {
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ case '\u000C':
+ continue;
+ default:
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Creates a comparable snapshot of the tree builder state. Snapshot
+ * creation is only supported immediately after a script end tag has been
+ * processed. In C++ the caller is responsible for calling
+ * <code>delete</code> on the returned object.
+ *
+ * @return a snapshot.
+ * @throws SAXException
+ */
+ @SuppressWarnings("unchecked") public TreeBuilderState<T> newSnapshot()
+ throws SAXException {
+ StackNode<T>[] listCopy = new StackNode[listPtr + 1];
+ for (int i = 0; i < listCopy.length; i++) {
+ StackNode<T> node = listOfActiveFormattingElements[i];
+ if (node != null) {
+ StackNode<T> newNode = new StackNode<T>(node.getFlags(), node.ns,
+ node.name, node.node, node.popName,
+ node.attributes.cloneAttributes(null)
+ // [NOCPP[
+ , node.getLocator()
+ // ]NOCPP]
+ );
+ listCopy[i] = newNode;
+ } else {
+ listCopy[i] = null;
+ }
+ }
+ StackNode<T>[] stackCopy = new StackNode[currentPtr + 1];
+ for (int i = 0; i < stackCopy.length; i++) {
+ StackNode<T> node = stack[i];
+ int listIndex = findInListOfActiveFormattingElements(node);
+ if (listIndex == -1) {
+ StackNode<T> newNode = new StackNode<T>(node.getFlags(), node.ns,
+ node.name, node.node, node.popName,
+ null
+ // [NOCPP[
+ , node.getLocator()
+ // ]NOCPP]
+ );
+ stackCopy[i] = newNode;
+ } else {
+ stackCopy[i] = listCopy[listIndex];
+ stackCopy[i].retain();
+ }
+ }
+ int[] templateModeStackCopy = new int[templateModePtr + 1];
+ System.arraycopy(templateModeStack, 0, templateModeStackCopy, 0,
+ templateModeStackCopy.length);
+ return new StateSnapshot<T>(stackCopy, listCopy, templateModeStackCopy, formPointer,
+ headPointer, deepTreeSurrogateParent, mode, originalMode, framesetOk,
+ needToDropLF, quirks);
+ }
+
+ public boolean snapshotMatches(TreeBuilderState<T> snapshot) {
+ StackNode<T>[] stackCopy = snapshot.getStack();
+ int stackLen = snapshot.getStackLength();
+ StackNode<T>[] listCopy = snapshot.getListOfActiveFormattingElements();
+ int listLen = snapshot.getListOfActiveFormattingElementsLength();
+ int[] templateModeStackCopy = snapshot.getTemplateModeStack();
+ int templateModeStackLen = snapshot.getTemplateModeStackLength();
+
+ if (stackLen != currentPtr + 1
+ || listLen != listPtr + 1
+ || templateModeStackLen != templateModePtr + 1
+ || formPointer != snapshot.getFormPointer()
+ || headPointer != snapshot.getHeadPointer()
+ || deepTreeSurrogateParent != snapshot.getDeepTreeSurrogateParent()
+ || mode != snapshot.getMode()
+ || originalMode != snapshot.getOriginalMode()
+ || framesetOk != snapshot.isFramesetOk()
+ || needToDropLF != snapshot.isNeedToDropLF()
+ || quirks != snapshot.isQuirks()) { // maybe just assert quirks
+ return false;
+ }
+ for (int i = listLen - 1; i >= 0; i--) {
+ if (listCopy[i] == null
+ && listOfActiveFormattingElements[i] == null) {
+ continue;
+ } else if (listCopy[i] == null
+ || listOfActiveFormattingElements[i] == null) {
+ return false;
+ }
+ if (listCopy[i].node != listOfActiveFormattingElements[i].node) {
+ return false; // it's possible that this condition is overly
+ // strict
+ }
+ }
+ for (int i = stackLen - 1; i >= 0; i--) {
+ if (stackCopy[i].node != stack[i].node) {
+ return false;
+ }
+ }
+ for (int i = templateModeStackLen - 1; i >=0; i--) {
+ if (templateModeStackCopy[i] != templateModeStack[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @SuppressWarnings("unchecked") public void loadState(
+ TreeBuilderState<T> snapshot, Interner interner)
+ throws SAXException {
+ StackNode<T>[] stackCopy = snapshot.getStack();
+ int stackLen = snapshot.getStackLength();
+ StackNode<T>[] listCopy = snapshot.getListOfActiveFormattingElements();
+ int listLen = snapshot.getListOfActiveFormattingElementsLength();
+ int[] templateModeStackCopy = snapshot.getTemplateModeStack();
+ int templateModeStackLen = snapshot.getTemplateModeStackLength();
+
+ for (int i = 0; i <= listPtr; i++) {
+ if (listOfActiveFormattingElements[i] != null) {
+ listOfActiveFormattingElements[i].release();
+ }
+ }
+ if (listOfActiveFormattingElements.length < listLen) {
+ listOfActiveFormattingElements = new StackNode[listLen];
+ }
+ listPtr = listLen - 1;
+
+ for (int i = 0; i <= currentPtr; i++) {
+ stack[i].release();
+ }
+ if (stack.length < stackLen) {
+ stack = new StackNode[stackLen];
+ }
+ currentPtr = stackLen - 1;
+
+ if (templateModeStack.length < templateModeStackLen) {
+ templateModeStack = new int[templateModeStackLen];
+ }
+ templateModePtr = templateModeStackLen - 1;
+
+ for (int i = 0; i < listLen; i++) {
+ StackNode<T> node = listCopy[i];
+ if (node != null) {
+ StackNode<T> newNode = new StackNode<T>(node.getFlags(), node.ns,
+ Portability.newLocalFromLocal(node.name, interner), node.node,
+ Portability.newLocalFromLocal(node.popName, interner),
+ node.attributes.cloneAttributes(null)
+ // [NOCPP[
+ , node.getLocator()
+ // ]NOCPP]
+ );
+ listOfActiveFormattingElements[i] = newNode;
+ } else {
+ listOfActiveFormattingElements[i] = null;
+ }
+ }
+ for (int i = 0; i < stackLen; i++) {
+ StackNode<T> node = stackCopy[i];
+ int listIndex = findInArray(node, listCopy);
+ if (listIndex == -1) {
+ StackNode<T> newNode = new StackNode<T>(node.getFlags(), node.ns,
+ Portability.newLocalFromLocal(node.name, interner), node.node,
+ Portability.newLocalFromLocal(node.popName, interner),
+ null
+ // [NOCPP[
+ , node.getLocator()
+ // ]NOCPP]
+ );
+ stack[i] = newNode;
+ } else {
+ stack[i] = listOfActiveFormattingElements[listIndex];
+ stack[i].retain();
+ }
+ }
+ System.arraycopy(templateModeStackCopy, 0, templateModeStack, 0, templateModeStackLen);
+ formPointer = snapshot.getFormPointer();
+ headPointer = snapshot.getHeadPointer();
+ deepTreeSurrogateParent = snapshot.getDeepTreeSurrogateParent();
+ mode = snapshot.getMode();
+ originalMode = snapshot.getOriginalMode();
+ framesetOk = snapshot.isFramesetOk();
+ needToDropLF = snapshot.isNeedToDropLF();
+ quirks = snapshot.isQuirks();
+ }
+
+ private int findInArray(StackNode<T> node, StackNode<T>[] arr) {
+ for (int i = listPtr; i >= 0; i--) {
+ if (node == arr[i]) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * @see nu.validator.htmlparser.impl.TreeBuilderState#getFormPointer()
+ */
+ public T getFormPointer() {
+ return formPointer;
+ }
+
+ /**
+ * Returns the headPointer.
+ *
+ * @return the headPointer
+ */
+ public T getHeadPointer() {
+ return headPointer;
+ }
+
+ /**
+ * Returns the deepTreeSurrogateParent.
+ *
+ * @return the deepTreeSurrogateParent
+ */
+ public T getDeepTreeSurrogateParent() {
+ return deepTreeSurrogateParent;
+ }
+
+ /**
+ * @see nu.validator.htmlparser.impl.TreeBuilderState#getListOfActiveFormattingElements()
+ */
+ public StackNode<T>[] getListOfActiveFormattingElements() {
+ return listOfActiveFormattingElements;
+ }
+
+ /**
+ * @see nu.validator.htmlparser.impl.TreeBuilderState#getStack()
+ */
+ public StackNode<T>[] getStack() {
+ return stack;
+ }
+
+ /**
+ * @see nu.validator.htmlparser.impl.TreeBuilderState#getTemplateModeStack()
+ */
+ public int[] getTemplateModeStack() {
+ return templateModeStack;
+ }
+
+ /**
+ * Returns the mode.
+ *
+ * @return the mode
+ */
+ public int getMode() {
+ return mode;
+ }
+
+ /**
+ * Returns the originalMode.
+ *
+ * @return the originalMode
+ */
+ public int getOriginalMode() {
+ return originalMode;
+ }
+
+ /**
+ * Returns the framesetOk.
+ *
+ * @return the framesetOk
+ */
+ public boolean isFramesetOk() {
+ return framesetOk;
+ }
+
+ /**
+ * Returns the needToDropLF.
+ *
+ * @return the needToDropLF
+ */
+ public boolean isNeedToDropLF() {
+ return needToDropLF;
+ }
+
+ /**
+ * Returns the quirks.
+ *
+ * @return the quirks
+ */
+ public boolean isQuirks() {
+ return quirks;
+ }
+
+ /**
+ * @see nu.validator.htmlparser.impl.TreeBuilderState#getListOfActiveFormattingElementsLength()
+ */
+ public int getListOfActiveFormattingElementsLength() {
+ return listPtr + 1;
+ }
+
+ /**
+ * @see nu.validator.htmlparser.impl.TreeBuilderState#getStackLength()
+ */
+ public int getStackLength() {
+ return currentPtr + 1;
+ }
+
+ /**
+ * @see nu.validator.htmlparser.impl.TreeBuilderState#getTemplateModeStackLength()
+ */
+ public int getTemplateModeStackLength() {
+ return templateModePtr + 1;
+ }
+
+ /**
+ * Reports a stray start tag.
+ * @param name the name of the stray tag
+ *
+ * @throws SAXException
+ */
+ private void errStrayStartTag(@Local String name) throws SAXException {
+ err("Stray start tag \u201C" + name + "\u201D.");
+ }
+
+ /**
+ * Reports a stray end tag.
+ * @param name the name of the stray tag
+ *
+ * @throws SAXException
+ */
+ private void errStrayEndTag(@Local String name) throws SAXException {
+ err("Stray end tag \u201C" + name + "\u201D.");
+ }
+
+ /**
+ * Reports a state when elements expected to be closed were not.
+ *
+ * @param eltPos the position of the start tag on the stack of the element
+ * being closed.
+ * @param name the name of the end tag
+ *
+ * @throws SAXException
+ */
+ private void errUnclosedElements(int eltPos, @Local String name) throws SAXException {
+ errNoCheck("End tag \u201C" + name + "\u201D seen, but there were open elements.");
+ errListUnclosedStartTags(eltPos);
+ }
+
+ /**
+ * Reports a state when elements expected to be closed ahead of an implied
+ * end tag but were not.
+ *
+ * @param eltPos the position of the start tag on the stack of the element
+ * being closed.
+ * @param name the name of the end tag
+ *
+ * @throws SAXException
+ */
+ private void errUnclosedElementsImplied(int eltPos, String name) throws SAXException {
+ errNoCheck("End tag \u201C" + name + "\u201D implied, but there were open elements.");
+ errListUnclosedStartTags(eltPos);
+ }
+
+ /**
+ * Reports a state when elements expected to be closed ahead of an implied
+ * table cell close.
+ *
+ * @param eltPos the position of the start tag on the stack of the element
+ * being closed.
+ * @throws SAXException
+ */
+ private void errUnclosedElementsCell(int eltPos) throws SAXException {
+ errNoCheck("A table cell was implicitly closed, but there were open elements.");
+ errListUnclosedStartTags(eltPos);
+ }
+
+ private void errStrayDoctype() throws SAXException {
+ err("Stray doctype.");
+ }
+
+ private void errAlmostStandardsDoctype() throws SAXException {
+ if (!isSrcdocDocument) {
+ err("Almost standards mode doctype. Expected \u201C<!DOCTYPE html>\u201D.");
+ }
+ }
+
+ private void errQuirkyDoctype() throws SAXException {
+ if (!isSrcdocDocument) {
+ err("Quirky doctype. Expected \u201C<!DOCTYPE html>\u201D.");
+ }
+ }
+
+ private void errNonSpaceInTrailer() throws SAXException {
+ err("Non-space character in page trailer.");
+ }
+
+ private void errNonSpaceAfterFrameset() throws SAXException {
+ err("Non-space after \u201Cframeset\u201D.");
+ }
+
+ private void errNonSpaceInFrameset() throws SAXException {
+ err("Non-space in \u201Cframeset\u201D.");
+ }
+
+ private void errNonSpaceAfterBody() throws SAXException {
+ err("Non-space character after body.");
+ }
+
+ private void errNonSpaceInColgroupInFragment() throws SAXException {
+ err("Non-space in \u201Ccolgroup\u201D when parsing fragment.");
+ }
+
+ private void errNonSpaceInNoscriptInHead() throws SAXException {
+ err("Non-space character inside \u201Cnoscript\u201D inside \u201Chead\u201D.");
+ }
+
+ private void errFooBetweenHeadAndBody(@Local String name) throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("\u201C" + name + "\u201D element between \u201Chead\u201D and \u201Cbody\u201D.");
+ }
+
+ private void errStartTagWithoutDoctype() throws SAXException {
+ if (!isSrcdocDocument) {
+ err("Start tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
+ }
+ }
+
+ private void errNoSelectInTableScope() throws SAXException {
+ err("No \u201Cselect\u201D in table scope.");
+ }
+
+ private void errStartSelectWhereEndSelectExpected() throws SAXException {
+ err("\u201Cselect\u201D start tag where end tag expected.");
+ }
+
+ private void errStartTagWithSelectOpen(@Local String name)
+ throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("\u201C" + name
+ + "\u201D start tag with \u201Cselect\u201D open.");
+ }
+
+ private void errBadStartTagInHead(@Local String name) throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("Bad start tag in \u201C" + name
+ + "\u201D in \u201Chead\u201D.");
+ }
+
+ private void errImage() throws SAXException {
+ err("Saw a start tag \u201Cimage\u201D.");
+ }
+
+ private void errIsindex() throws SAXException {
+ err("\u201Cisindex\u201D seen.");
+ }
+
+ private void errFooSeenWhenFooOpen(@Local String name) throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("An \u201C" + name + "\u201D start tag seen but an element of the same type was already open.");
+ }
+
+ private void errHeadingWhenHeadingOpen() throws SAXException {
+ err("Heading cannot be a child of another heading.");
+ }
+
+ private void errFramesetStart() throws SAXException {
+ err("\u201Cframeset\u201D start tag seen.");
+ }
+
+ private void errNoCellToClose() throws SAXException {
+ err("No cell to close.");
+ }
+
+ private void errStartTagInTable(@Local String name) throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("Start tag \u201C" + name
+ + "\u201D seen in \u201Ctable\u201D.");
+ }
+
+ private void errFormWhenFormOpen() throws SAXException {
+ err("Saw a \u201Cform\u201D start tag, but there was already an active \u201Cform\u201D element. Nested forms are not allowed. Ignoring the tag.");
+ }
+
+ private void errTableSeenWhileTableOpen() throws SAXException {
+ err("Start tag for \u201Ctable\u201D seen but the previous \u201Ctable\u201D is still open.");
+ }
+
+ private void errStartTagInTableBody(@Local String name) throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("\u201C" + name + "\u201D start tag in table body.");
+ }
+
+ private void errEndTagSeenWithoutDoctype() throws SAXException {
+ if (!isSrcdocDocument) {
+ err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
+ }
+ }
+
+ private void errEndTagAfterBody() throws SAXException {
+ err("Saw an end tag after \u201Cbody\u201D had been closed.");
+ }
+
+ private void errEndTagSeenWithSelectOpen(@Local String name) throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("\u201C" + name
+ + "\u201D end tag with \u201Cselect\u201D open.");
+ }
+
+ private void errGarbageInColgroup() throws SAXException {
+ err("Garbage in \u201Ccolgroup\u201D fragment.");
+ }
+
+ private void errEndTagBr() throws SAXException {
+ err("End tag \u201Cbr\u201D.");
+ }
+
+ private void errNoElementToCloseButEndTagSeen(@Local String name)
+ throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("No \u201C" + name + "\u201D element in scope but a \u201C"
+ + name + "\u201D end tag seen.");
+ }
+
+ private void errHtmlStartTagInForeignContext(@Local String name)
+ throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("HTML start tag \u201C" + name
+ + "\u201D in a foreign namespace context.");
+ }
+
+ private void errTableClosedWhileCaptionOpen() throws SAXException {
+ err("\u201Ctable\u201D closed but \u201Ccaption\u201D was still open.");
+ }
+
+ private void errNoTableRowToClose() throws SAXException {
+ err("No table row to close.");
+ }
+
+ private void errNonSpaceInTable() throws SAXException {
+ err("Misplaced non-space characters insided a table.");
+ }
+
+ private void errUnclosedChildrenInRuby() throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("Unclosed children in \u201Cruby\u201D.");
+ }
+
+ private void errStartTagSeenWithoutRuby(@Local String name) throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("Start tag \u201C"
+ + name
+ + "\u201D seen without a \u201Cruby\u201D element being open.");
+ }
+
+ private void errSelfClosing() throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("Self-closing syntax (\u201C/>\u201D) used on a non-void HTML element. Ignoring the slash and treating as a start tag.");
+ }
+
+ private void errNoCheckUnclosedElementsOnStack() throws SAXException {
+ errNoCheck("Unclosed elements on stack.");
+ }
+
+ private void errEndTagDidNotMatchCurrentOpenElement(@Local String name,
+ @Local String currOpenName) throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("End tag \u201C"
+ + name
+ + "\u201D did not match the name of the current open element (\u201C"
+ + currOpenName + "\u201D).");
+ }
+
+ private void errEndTagViolatesNestingRules(@Local String name) throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("End tag \u201C" + name + "\u201D violates nesting rules.");
+ }
+
+ private void errEofWithUnclosedElements() throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("End of file seen and there were open elements.");
+ // just report all remaining unclosed elements
+ errListUnclosedStartTags(0);
+ }
+
+ /**
+ * Reports arriving at/near end of document with unclosed elements remaining.
+ *
+ * @param message
+ * the message
+ * @throws SAXException
+ */
+ private void errEndWithUnclosedElements(@Local String name) throws SAXException {
+ if (errorHandler == null) {
+ return;
+ }
+ errNoCheck("End tag for \u201C"
+ + name
+ + "\u201D seen, but there were unclosed elements.");
+ // just report all remaining unclosed elements
+ errListUnclosedStartTags(0);
+ }
+}
diff --git a/parser/html/javasrc/UTF16Buffer.java b/parser/html/javasrc/UTF16Buffer.java
new file mode 100644
index 000000000..ec79185ec
--- /dev/null
+++ b/parser/html/javasrc/UTF16Buffer.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2008-2010 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package nu.validator.htmlparser.impl;
+
+import nu.validator.htmlparser.annotation.NoLength;
+
+/**
+ * An UTF-16 buffer that knows the start and end indeces of its unconsumed
+ * content.
+ *
+ * @version $Id$
+ * @author hsivonen
+ */
+public final class UTF16Buffer {
+
+ /**
+ * The backing store of the buffer. May be larger than the logical content
+ * of this <code>UTF16Buffer</code>.
+ */
+ private final @NoLength char[] buffer;
+
+ /**
+ * The index of the first unconsumed character in the backing buffer.
+ */
+ private int start;
+
+ /**
+ * The index of the slot immediately after the last character in the backing
+ * buffer that is part of the logical content of this
+ * <code>UTF16Buffer</code>.
+ */
+ private int end;
+
+ //[NOCPP[
+
+ /**
+ * Constructor for wrapping an existing UTF-16 code unit array.
+ *
+ * @param buffer
+ * the backing buffer
+ * @param start
+ * the index of the first character to consume
+ * @param end
+ * the index immediately after the last character to consume
+ */
+ public UTF16Buffer(@NoLength char[] buffer, int start, int end) {
+ this.buffer = buffer;
+ this.start = start;
+ this.end = end;
+ }
+
+ // ]NOCPP]
+
+ /**
+ * Returns the start index.
+ *
+ * @return the start index
+ */
+ public int getStart() {
+ return start;
+ }
+
+ /**
+ * Sets the start index.
+ *
+ * @param start
+ * the start index
+ */
+ public void setStart(int start) {
+ this.start = start;
+ }
+
+ /**
+ * Returns the backing buffer.
+ *
+ * @return the backing buffer
+ */
+ public @NoLength char[] getBuffer() {
+ return buffer;
+ }
+
+ /**
+ * Returns the end index.
+ *
+ * @return the end index
+ */
+ public int getEnd() {
+ return end;
+ }
+
+ /**
+ * Checks if the buffer has data left.
+ *
+ * @return <code>true</code> if there's data left
+ */
+ public boolean hasMore() {
+ return start < end;
+ }
+
+ /**
+ * Returns <code>end - start</code>.
+ *
+ * @return <code>end - start</code>
+ */
+ public int getLength() {
+ return end - start;
+ }
+
+ /**
+ * Adjusts the start index to skip over the first character if it is a line
+ * feed and the previous character was a carriage return.
+ *
+ * @param lastWasCR
+ * whether the previous character was a carriage return
+ */
+ public void adjust(boolean lastWasCR) {
+ if (lastWasCR && buffer[start] == '\n') {
+ start++;
+ }
+ }
+
+ /**
+ * Sets the end index.
+ *
+ * @param end
+ * the end index
+ */
+ public void setEnd(int end) {
+ this.end = end;
+ }
+}
diff --git a/parser/html/moz.build b/parser/html/moz.build
new file mode 100644
index 000000000..2b351f084
--- /dev/null
+++ b/parser/html/moz.build
@@ -0,0 +1,104 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+XPIDL_SOURCES += [
+ 'nsIParserUtils.idl',
+ 'nsIScriptableUnescapeHTML.idl',
+]
+
+XPIDL_MODULE = 'html5'
+
+EXPORTS += [
+ 'jArray.h',
+ 'nsAHtml5TreeBuilderState.h',
+ 'nsAHtml5TreeOpSink.h',
+ 'nsHtml5ArrayCopy.h',
+ 'nsHtml5AtomList.h',
+ 'nsHtml5Atoms.h',
+ 'nsHtml5AtomTable.h',
+ 'nsHtml5ByteReadable.h',
+ 'nsHtml5DependentUTF16Buffer.h',
+ 'nsHtml5DocumentBuilder.h',
+ 'nsHtml5DocumentMode.h',
+ 'nsHtml5HtmlAttributes.h',
+ 'nsHtml5Macros.h',
+ 'nsHtml5MetaScanner.h',
+ 'nsHtml5MetaScannerHSupplement.h',
+ 'nsHtml5Module.h',
+ 'nsHtml5NamedCharacters.h',
+ 'nsHtml5NamedCharactersAccel.h',
+ 'nsHtml5OplessBuilder.h',
+ 'nsHtml5OwningUTF16Buffer.h',
+ 'nsHtml5Parser.h',
+ 'nsHtml5PlainTextUtils.h',
+ 'nsHtml5RefPtr.h',
+ 'nsHtml5Speculation.h',
+ 'nsHtml5SpeculativeLoad.h',
+ 'nsHtml5StreamListener.h',
+ 'nsHtml5StreamParser.h',
+ 'nsHtml5StringParser.h',
+ 'nsHtml5SVGLoadDispatcher.h',
+ 'nsHtml5TreeOperation.h',
+ 'nsHtml5TreeOpExecutor.h',
+ 'nsHtml5TreeOpStage.h',
+ 'nsHtml5UTF16Buffer.h',
+ 'nsHtml5UTF16BufferHSupplement.h',
+ 'nsHtml5ViewSourceUtils.h',
+ 'nsIContentHandle.h',
+ 'nsParserUtils.h',
+]
+
+UNIFIED_SOURCES += [
+ 'nsHtml5Atom.cpp',
+ 'nsHtml5Atoms.cpp',
+ 'nsHtml5AtomTable.cpp',
+ 'nsHtml5AttributeName.cpp',
+ 'nsHtml5DependentUTF16Buffer.cpp',
+ 'nsHtml5DocumentBuilder.cpp',
+ 'nsHtml5ElementName.cpp',
+ 'nsHtml5Highlighter.cpp',
+ 'nsHtml5HtmlAttributes.cpp',
+ 'nsHtml5MetaScanner.cpp',
+ 'nsHtml5Module.cpp',
+ 'nsHtml5NamedCharacters.cpp',
+ 'nsHtml5NamedCharactersAccel.cpp',
+ 'nsHtml5OplessBuilder.cpp',
+ 'nsHtml5OwningUTF16Buffer.cpp',
+ 'nsHtml5Parser.cpp',
+ 'nsHtml5PlainTextUtils.cpp',
+ 'nsHtml5Portability.cpp',
+ 'nsHtml5ReleasableAttributeName.cpp',
+ 'nsHtml5ReleasableElementName.cpp',
+ 'nsHtml5Speculation.cpp',
+ 'nsHtml5SpeculativeLoad.cpp',
+ 'nsHtml5StackNode.cpp',
+ 'nsHtml5StateSnapshot.cpp',
+ 'nsHtml5StreamListener.cpp',
+ 'nsHtml5StreamParser.cpp',
+ 'nsHtml5StringParser.cpp',
+ 'nsHtml5SVGLoadDispatcher.cpp',
+ 'nsHtml5Tokenizer.cpp',
+ 'nsHtml5TreeBuilder.cpp',
+ 'nsHtml5TreeOperation.cpp',
+ 'nsHtml5TreeOpExecutor.cpp',
+ 'nsHtml5TreeOpStage.cpp',
+ 'nsHtml5UTF16Buffer.cpp',
+ 'nsHtml5ViewSourceUtils.cpp',
+ 'nsParserUtils.cpp',
+]
+
+FINAL_LIBRARY = 'xul'
+
+# DEFINES['ENABLE_VOID_MENUITEM'] = True
+
+LOCAL_INCLUDES += [
+ '/dom/base',
+]
+
+if CONFIG['GNU_CXX']:
+ CXXFLAGS += ['-Wno-error=shadow']
+ if CONFIG['CLANG_CXX']:
+ CXXFLAGS += ['-Wno-implicit-fallthrough']
diff --git a/parser/html/nsAHtml5TreeBuilderState.h b/parser/html/nsAHtml5TreeBuilderState.h
new file mode 100644
index 000000000..f5fb4e2bd
--- /dev/null
+++ b/parser/html/nsAHtml5TreeBuilderState.h
@@ -0,0 +1,50 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsAHtml5TreeBuilderState_h
+#define nsAHtml5TreeBuilderState_h
+
+#include "nsIContentHandle.h"
+
+/**
+ * Interface for exposing the internal state of the HTML5 tree builder.
+ * For more documentation, please see
+ * http://hg.mozilla.org/projects/htmlparser/file/tip/src/nu/validator/htmlparser/impl/StateSnapshot.java
+ */
+class nsAHtml5TreeBuilderState {
+ public:
+
+ virtual jArray<nsHtml5StackNode*,int32_t> getStack() = 0;
+
+ virtual jArray<nsHtml5StackNode*,int32_t> getListOfActiveFormattingElements() = 0;
+
+ virtual jArray<int32_t,int32_t> getTemplateModeStack() = 0;
+
+ virtual int32_t getStackLength() = 0;
+
+ virtual int32_t getListOfActiveFormattingElementsLength() = 0;
+
+ virtual int32_t getTemplateModeStackLength() = 0;
+
+ virtual nsIContentHandle* getFormPointer() = 0;
+
+ virtual nsIContentHandle* getHeadPointer() = 0;
+
+ virtual nsIContentHandle* getDeepTreeSurrogateParent() = 0;
+
+ virtual int32_t getMode() = 0;
+
+ virtual int32_t getOriginalMode() = 0;
+
+ virtual bool isFramesetOk() = 0;
+
+ virtual bool isNeedToDropLF() = 0;
+
+ virtual bool isQuirks() = 0;
+
+ virtual ~nsAHtml5TreeBuilderState() {
+ }
+};
+
+#endif /* nsAHtml5TreeBuilderState_h */
diff --git a/parser/html/nsAHtml5TreeOpSink.h b/parser/html/nsAHtml5TreeOpSink.h
new file mode 100644
index 000000000..f3d10c4d4
--- /dev/null
+++ b/parser/html/nsAHtml5TreeOpSink.h
@@ -0,0 +1,24 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsAHtml5TreeOpSink_h
+#define nsAHtml5TreeOpSink_h
+
+/**
+ * The purpose of this interface is to connect a tree op executor
+ * (main-thread case), a tree op stage (non-speculative off-the-main-thread
+ * case) or a speculation (speculative case).
+ */
+class nsAHtml5TreeOpSink {
+ public:
+
+ /**
+ * Flush the operations from the tree operations from the argument
+ * queue into this sink unconditionally.
+ */
+ virtual void MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue) = 0;
+
+};
+
+#endif /* nsAHtml5TreeOpSink_h */
diff --git a/parser/html/nsHtml5ArrayCopy.h b/parser/html/nsHtml5ArrayCopy.h
new file mode 100644
index 000000000..78ed65568
--- /dev/null
+++ b/parser/html/nsHtml5ArrayCopy.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2008 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef nsHtml5ArrayCopy_h
+#define nsHtml5ArrayCopy_h
+
+
+class nsString;
+class nsHtml5StackNode;
+class nsHtml5AttributeName;
+
+// Unfortunately, these don't work as template functions because the arguments
+// would need coercion from a template class, which complicates things.
+class nsHtml5ArrayCopy {
+ public:
+
+ static inline void
+ arraycopy(char16_t* source, int32_t sourceOffset, char16_t* target, int32_t targetOffset, int32_t length)
+ {
+ memcpy(&(target[targetOffset]), &(source[sourceOffset]), size_t(length) * sizeof(char16_t));
+ }
+
+ static inline void
+ arraycopy(char16_t* source, char16_t* target, int32_t length)
+ {
+ memcpy(target, source, size_t(length) * sizeof(char16_t));
+ }
+
+ static inline void
+ arraycopy(int32_t* source, int32_t* target, int32_t length)
+ {
+ memcpy(target, source, size_t(length) * sizeof(int32_t));
+ }
+
+ static inline void
+ arraycopy(nsString** source, nsString** target, int32_t length)
+ {
+ memcpy(target, source, size_t(length) * sizeof(nsString*));
+ }
+
+ static inline void
+ arraycopy(nsHtml5AttributeName** source, nsHtml5AttributeName** target, int32_t length)
+ {
+ memcpy(target, source, size_t(length) * sizeof(nsHtml5AttributeName*));
+ }
+
+ static inline void
+ arraycopy(nsHtml5StackNode** source, nsHtml5StackNode** target, int32_t length)
+ {
+ memcpy(target, source, size_t(length) * sizeof(nsHtml5StackNode*));
+ }
+
+ static inline void
+ arraycopy(nsHtml5StackNode** arr, int32_t sourceOffset, int32_t targetOffset, int32_t length)
+ {
+ memmove(&(arr[targetOffset]), &(arr[sourceOffset]), size_t(length) * sizeof(nsHtml5StackNode*));
+ }
+};
+#endif // nsHtml5ArrayCopy_h
diff --git a/parser/html/nsHtml5Atom.cpp b/parser/html/nsHtml5Atom.cpp
new file mode 100644
index 000000000..4d15c5e41
--- /dev/null
+++ b/parser/html/nsHtml5Atom.cpp
@@ -0,0 +1,91 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5Atom.h"
+#include "nsAutoPtr.h"
+#include "mozilla/Unused.h"
+
+nsHtml5Atom::nsHtml5Atom(const nsAString& aString)
+{
+ mLength = aString.Length();
+ mIsStatic = false;
+ RefPtr<nsStringBuffer> buf = nsStringBuffer::FromString(aString);
+ if (buf) {
+ mString = static_cast<char16_t*>(buf->Data());
+ } else {
+ const size_t size = (mLength + 1) * sizeof(char16_t);
+ buf = nsStringBuffer::Alloc(size);
+ if (MOZ_UNLIKELY(!buf)) {
+ // We OOM because atom allocations should be small and it's hard to
+ // handle them more gracefully in a constructor.
+ NS_ABORT_OOM(size);
+ }
+ mString = static_cast<char16_t*>(buf->Data());
+ CopyUnicodeTo(aString, 0, mString, mLength);
+ mString[mLength] = char16_t(0);
+ }
+
+ NS_ASSERTION(mString[mLength] == char16_t(0), "null terminated");
+ NS_ASSERTION(buf && buf->StorageSize() >= (mLength+1) * sizeof(char16_t),
+ "enough storage");
+ NS_ASSERTION(Equals(aString), "correct data");
+
+ // Take ownership of buffer
+ mozilla::Unused << buf.forget();
+}
+
+nsHtml5Atom::~nsHtml5Atom()
+{
+ nsStringBuffer::FromData(mString)->Release();
+}
+
+NS_IMETHODIMP_(MozExternalRefCountType)
+nsHtml5Atom::AddRef()
+{
+ NS_NOTREACHED("Attempt to AddRef an nsHtml5Atom.");
+ return 2;
+}
+
+NS_IMETHODIMP_(MozExternalRefCountType)
+nsHtml5Atom::Release()
+{
+ NS_NOTREACHED("Attempt to Release an nsHtml5Atom.");
+ return 1;
+}
+
+NS_IMETHODIMP
+nsHtml5Atom::QueryInterface(REFNSIID aIID, void** aInstancePtr)
+{
+ NS_NOTREACHED("Attempt to call QueryInterface an nsHtml5Atom.");
+ return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+nsHtml5Atom::ScriptableToString(nsAString& aBuf)
+{
+ NS_NOTREACHED("Should not call ScriptableToString.");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsHtml5Atom::ToUTF8String(nsACString& aReturn)
+{
+ NS_NOTREACHED("Should not attempt to convert to an UTF-8 string.");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsHtml5Atom::ScriptableEquals(const nsAString& aString, bool* aResult)
+{
+ NS_NOTREACHED("Should not call ScriptableEquals.");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP_(size_t)
+nsHtml5Atom::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
+{
+ NS_NOTREACHED("Should not call SizeOfIncludingThis.");
+ return 0;
+}
+
diff --git a/parser/html/nsHtml5Atom.h b/parser/html/nsHtml5Atom.h
new file mode 100644
index 000000000..c11fb0bad
--- /dev/null
+++ b/parser/html/nsHtml5Atom.h
@@ -0,0 +1,28 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5Atom_h
+#define nsHtml5Atom_h
+
+#include "nsIAtom.h"
+#include "mozilla/Attributes.h"
+
+/**
+ * A dynamic atom implementation meant for use within the nsHtml5Tokenizer and
+ * nsHtml5TreeBuilder owned by one nsHtml5Parser or nsHtml5StreamParser
+ * instance.
+ *
+ * Usage is documented in nsHtml5AtomTable and nsIAtom.
+ */
+class nsHtml5Atom final : public nsIAtom
+{
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIATOM
+
+ explicit nsHtml5Atom(const nsAString& aString);
+ ~nsHtml5Atom();
+};
+
+#endif // nsHtml5Atom_h
diff --git a/parser/html/nsHtml5AtomList.h b/parser/html/nsHtml5AtomList.h
new file mode 100644
index 000000000..934fd9551
--- /dev/null
+++ b/parser/html/nsHtml5AtomList.h
@@ -0,0 +1,1074 @@
+/*
+ * Copyright (c) 2008-2010 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+HTML5_ATOM(emptystring, "")
+HTML5_ATOM(title, "title")
+HTML5_ATOM(desc, "desc")
+HTML5_ATOM(foreignObject, "foreignObject")
+HTML5_ATOM(mi, "mi")
+HTML5_ATOM(mo, "mo")
+HTML5_ATOM(mn, "mn")
+HTML5_ATOM(ms, "ms")
+HTML5_ATOM(mtext, "mtext")
+HTML5_ATOM(annotation_xml, "annotation-xml")
+HTML5_ATOM(template_, "template")
+HTML5_ATOM(textarea, "textarea")
+HTML5_ATOM(style, "style")
+HTML5_ATOM(xmp, "xmp")
+HTML5_ATOM(iframe, "iframe")
+HTML5_ATOM(noembed, "noembed")
+HTML5_ATOM(noframes, "noframes")
+HTML5_ATOM(noscript, "noscript")
+HTML5_ATOM(plaintext, "plaintext")
+HTML5_ATOM(script, "script")
+HTML5_ATOM(svg, "svg")
+HTML5_ATOM(table, "table")
+HTML5_ATOM(caption, "caption")
+HTML5_ATOM(p, "p")
+HTML5_ATOM(address, "address")
+HTML5_ATOM(div, "div")
+HTML5_ATOM(a, "a")
+HTML5_ATOM(nobr, "nobr")
+HTML5_ATOM(input, "input")
+HTML5_ATOM(option, "option")
+HTML5_ATOM(ruby, "ruby")
+HTML5_ATOM(rtc, "rtc")
+HTML5_ATOM(select, "select")
+HTML5_ATOM(optgroup, "optgroup")
+HTML5_ATOM(tbody, "tbody")
+HTML5_ATOM(tfoot, "tfoot")
+HTML5_ATOM(thead, "thead")
+HTML5_ATOM(frameset, "frameset")
+HTML5_ATOM(button, "button")
+HTML5_ATOM(ul, "ul")
+HTML5_ATOM(ol, "ol")
+HTML5_ATOM(html, "html")
+HTML5_ATOM(td, "td")
+HTML5_ATOM(th, "th")
+HTML5_ATOM(tr, "tr")
+HTML5_ATOM(colgroup, "colgroup")
+HTML5_ATOM(head, "head")
+HTML5_ATOM(body, "body")
+HTML5_ATOM(form, "form")
+HTML5_ATOM(xmlns, "xmlns")
+HTML5_ATOM(xlink, "xlink")
+HTML5_ATOM(xml, "xml")
+HTML5_ATOM(d, "d")
+HTML5_ATOM(k, "k")
+HTML5_ATOM(r, "r")
+HTML5_ATOM(x, "x")
+HTML5_ATOM(y, "y")
+HTML5_ATOM(z, "z")
+HTML5_ATOM(by, "by")
+HTML5_ATOM(cx, "cx")
+HTML5_ATOM(cy, "cy")
+HTML5_ATOM(dx, "dx")
+HTML5_ATOM(dy, "dy")
+HTML5_ATOM(g2, "g2")
+HTML5_ATOM(g1, "g1")
+HTML5_ATOM(fx, "fx")
+HTML5_ATOM(fy, "fy")
+HTML5_ATOM(k4, "k4")
+HTML5_ATOM(k2, "k2")
+HTML5_ATOM(k3, "k3")
+HTML5_ATOM(k1, "k1")
+HTML5_ATOM(id, "id")
+HTML5_ATOM(in, "in")
+HTML5_ATOM(u2, "u2")
+HTML5_ATOM(u1, "u1")
+HTML5_ATOM(rt, "rt")
+HTML5_ATOM(rx, "rx")
+HTML5_ATOM(ry, "ry")
+HTML5_ATOM(to, "to")
+HTML5_ATOM(y2, "y2")
+HTML5_ATOM(y1, "y1")
+HTML5_ATOM(x1, "x1")
+HTML5_ATOM(x2, "x2")
+HTML5_ATOM(alt, "alt")
+HTML5_ATOM(dir, "dir")
+HTML5_ATOM(dur, "dur")
+HTML5_ATOM(end, "end")
+HTML5_ATOM(for_, "for")
+HTML5_ATOM(in2, "in2")
+HTML5_ATOM(max, "max")
+HTML5_ATOM(min, "min")
+HTML5_ATOM(low, "low")
+HTML5_ATOM(rel, "rel")
+HTML5_ATOM(rev, "rev")
+HTML5_ATOM(src, "src")
+HTML5_ATOM(axis, "axis")
+HTML5_ATOM(abbr, "abbr")
+HTML5_ATOM(bbox, "bbox")
+HTML5_ATOM(cite, "cite")
+HTML5_ATOM(code, "code")
+HTML5_ATOM(bias, "bias")
+HTML5_ATOM(cols, "cols")
+HTML5_ATOM(clip, "clip")
+HTML5_ATOM(char_, "char")
+HTML5_ATOM(base, "base")
+HTML5_ATOM(edge, "edge")
+HTML5_ATOM(data, "data")
+HTML5_ATOM(fill, "fill")
+HTML5_ATOM(from, "from")
+HTML5_ATOM(face, "face")
+HTML5_ATOM(high, "high")
+HTML5_ATOM(href, "href")
+HTML5_ATOM(open, "open")
+HTML5_ATOM(icon, "icon")
+HTML5_ATOM(name, "name")
+HTML5_ATOM(mode, "mode")
+HTML5_ATOM(mask, "mask")
+HTML5_ATOM(link, "link")
+HTML5_ATOM(lang, "lang")
+HTML5_ATOM(loop, "loop")
+HTML5_ATOM(list, "list")
+HTML5_ATOM(type, "type")
+HTML5_ATOM(when, "when")
+HTML5_ATOM(wrap, "wrap")
+HTML5_ATOM(text, "text")
+HTML5_ATOM(path, "path")
+HTML5_ATOM(ping, "ping")
+HTML5_ATOM(refx, "refx")
+HTML5_ATOM(refX, "refX")
+HTML5_ATOM(refy, "refy")
+HTML5_ATOM(refY, "refY")
+HTML5_ATOM(size, "size")
+HTML5_ATOM(seed, "seed")
+HTML5_ATOM(rows, "rows")
+HTML5_ATOM(span, "span")
+HTML5_ATOM(step, "step")
+HTML5_ATOM(role, "role")
+HTML5_ATOM(xref, "xref")
+HTML5_ATOM(async, "async")
+HTML5_ATOM(alink, "alink")
+HTML5_ATOM(align, "align")
+HTML5_ATOM(close, "close")
+HTML5_ATOM(color, "color")
+HTML5_ATOM(class_, "class")
+HTML5_ATOM(clear, "clear")
+HTML5_ATOM(begin, "begin")
+HTML5_ATOM(depth, "depth")
+HTML5_ATOM(defer, "defer")
+HTML5_ATOM(fence, "fence")
+HTML5_ATOM(frame, "frame")
+HTML5_ATOM(ismap, "ismap")
+HTML5_ATOM(onend, "onend")
+HTML5_ATOM(index, "index")
+HTML5_ATOM(order, "order")
+HTML5_ATOM(other, "other")
+HTML5_ATOM(oncut, "oncut")
+HTML5_ATOM(nargs, "nargs")
+HTML5_ATOM(media, "media")
+HTML5_ATOM(label, "label")
+HTML5_ATOM(local, "local")
+HTML5_ATOM(width, "width")
+HTML5_ATOM(vlink, "vlink")
+HTML5_ATOM(value, "value")
+HTML5_ATOM(slope, "slope")
+HTML5_ATOM(shape, "shape")
+HTML5_ATOM(scope, "scope")
+HTML5_ATOM(scale, "scale")
+HTML5_ATOM(speed, "speed")
+HTML5_ATOM(rules, "rules")
+HTML5_ATOM(stemh, "stemh")
+HTML5_ATOM(sizes, "sizes")
+HTML5_ATOM(stemv, "stemv")
+HTML5_ATOM(start, "start")
+HTML5_ATOM(accept, "accept")
+HTML5_ATOM(accent, "accent")
+HTML5_ATOM(ascent, "ascent")
+HTML5_ATOM(active, "active")
+HTML5_ATOM(altimg, "altimg")
+HTML5_ATOM(action, "action")
+HTML5_ATOM(border, "border")
+HTML5_ATOM(cursor, "cursor")
+HTML5_ATOM(coords, "coords")
+HTML5_ATOM(filter, "filter")
+HTML5_ATOM(format, "format")
+HTML5_ATOM(hidden, "hidden")
+HTML5_ATOM(hspace, "hspace")
+HTML5_ATOM(height, "height")
+HTML5_ATOM(onmove, "onmove")
+HTML5_ATOM(onload, "onload")
+HTML5_ATOM(ondrag, "ondrag")
+HTML5_ATOM(origin, "origin")
+HTML5_ATOM(onzoom, "onzoom")
+HTML5_ATOM(onhelp, "onhelp")
+HTML5_ATOM(onstop, "onstop")
+HTML5_ATOM(ondrop, "ondrop")
+HTML5_ATOM(onblur, "onblur")
+HTML5_ATOM(object, "object")
+HTML5_ATOM(offset, "offset")
+HTML5_ATOM(orient, "orient")
+HTML5_ATOM(oncopy, "oncopy")
+HTML5_ATOM(nowrap, "nowrap")
+HTML5_ATOM(nohref, "nohref")
+HTML5_ATOM(macros, "macros")
+HTML5_ATOM(method, "method")
+HTML5_ATOM(lowsrc, "lowsrc")
+HTML5_ATOM(lspace, "lspace")
+HTML5_ATOM(lquote, "lquote")
+HTML5_ATOM(usemap, "usemap")
+HTML5_ATOM(widths, "widths")
+HTML5_ATOM(target, "target")
+HTML5_ATOM(values, "values")
+HTML5_ATOM(valign, "valign")
+HTML5_ATOM(vspace, "vspace")
+HTML5_ATOM(poster, "poster")
+HTML5_ATOM(points, "points")
+HTML5_ATOM(prompt, "prompt")
+HTML5_ATOM(srcdoc, "srcdoc")
+HTML5_ATOM(scoped, "scoped")
+HTML5_ATOM(string, "string")
+HTML5_ATOM(scheme, "scheme")
+HTML5_ATOM(stroke, "stroke")
+HTML5_ATOM(radius, "radius")
+HTML5_ATOM(result, "result")
+HTML5_ATOM(repeat, "repeat")
+HTML5_ATOM(srcset, "srcset")
+HTML5_ATOM(rspace, "rspace")
+HTML5_ATOM(rotate, "rotate")
+HTML5_ATOM(rquote, "rquote")
+HTML5_ATOM(alttext, "alttext")
+HTML5_ATOM(archive, "archive")
+HTML5_ATOM(azimuth, "azimuth")
+HTML5_ATOM(closure, "closure")
+HTML5_ATOM(checked, "checked")
+HTML5_ATOM(classid, "classid")
+HTML5_ATOM(charoff, "charoff")
+HTML5_ATOM(bgcolor, "bgcolor")
+HTML5_ATOM(colspan, "colspan")
+HTML5_ATOM(charset, "charset")
+HTML5_ATOM(compact, "compact")
+HTML5_ATOM(content, "content")
+HTML5_ATOM(enctype, "enctype")
+HTML5_ATOM(datasrc, "datasrc")
+HTML5_ATOM(datafld, "datafld")
+HTML5_ATOM(declare, "declare")
+HTML5_ATOM(display, "display")
+HTML5_ATOM(divisor, "divisor")
+HTML5_ATOM(default_, "default")
+HTML5_ATOM(descent, "descent")
+HTML5_ATOM(kerning, "kerning")
+HTML5_ATOM(hanging, "hanging")
+HTML5_ATOM(headers, "headers")
+HTML5_ATOM(onpaste, "onpaste")
+HTML5_ATOM(onclick, "onclick")
+HTML5_ATOM(optimum, "optimum")
+HTML5_ATOM(onbegin, "onbegin")
+HTML5_ATOM(onkeyup, "onkeyup")
+HTML5_ATOM(onfocus, "onfocus")
+HTML5_ATOM(onerror, "onerror")
+HTML5_ATOM(oninput, "oninput")
+HTML5_ATOM(onabort, "onabort")
+HTML5_ATOM(onstart, "onstart")
+HTML5_ATOM(onreset, "onreset")
+HTML5_ATOM(opacity, "opacity")
+HTML5_ATOM(noshade, "noshade")
+HTML5_ATOM(minsize, "minsize")
+HTML5_ATOM(maxsize, "maxsize")
+HTML5_ATOM(largeop, "largeop")
+HTML5_ATOM(unicode_, "unicode")
+HTML5_ATOM(targetx, "targetx")
+HTML5_ATOM(targetX, "targetX")
+HTML5_ATOM(targety, "targety")
+HTML5_ATOM(targetY, "targetY")
+HTML5_ATOM(viewbox, "viewbox")
+HTML5_ATOM(viewBox, "viewBox")
+HTML5_ATOM(version, "version")
+HTML5_ATOM(pattern, "pattern")
+HTML5_ATOM(profile, "profile")
+HTML5_ATOM(spacing, "spacing")
+HTML5_ATOM(restart, "restart")
+HTML5_ATOM(rowspan, "rowspan")
+HTML5_ATOM(sandbox, "sandbox")
+HTML5_ATOM(summary, "summary")
+HTML5_ATOM(standby, "standby")
+HTML5_ATOM(replace, "replace")
+HTML5_ATOM(autoplay, "autoplay")
+HTML5_ATOM(additive, "additive")
+HTML5_ATOM(calcmode, "calcmode")
+HTML5_ATOM(calcMode, "calcMode")
+HTML5_ATOM(codetype, "codetype")
+HTML5_ATOM(codebase, "codebase")
+HTML5_ATOM(controls, "controls")
+HTML5_ATOM(bevelled, "bevelled")
+HTML5_ATOM(baseline, "baseline")
+HTML5_ATOM(exponent, "exponent")
+HTML5_ATOM(edgemode, "edgemode")
+HTML5_ATOM(edgeMode, "edgeMode")
+HTML5_ATOM(encoding, "encoding")
+HTML5_ATOM(glyphref, "glyphref")
+HTML5_ATOM(glyphRef, "glyphRef")
+HTML5_ATOM(datetime, "datetime")
+HTML5_ATOM(disabled, "disabled")
+HTML5_ATOM(fontsize, "fontsize")
+HTML5_ATOM(keytimes, "keytimes")
+HTML5_ATOM(keyTimes, "keyTimes")
+HTML5_ATOM(panose_1, "panose-1")
+HTML5_ATOM(hreflang, "hreflang")
+HTML5_ATOM(onresize, "onresize")
+HTML5_ATOM(onchange, "onchange")
+HTML5_ATOM(onbounce, "onbounce")
+HTML5_ATOM(onunload, "onunload")
+HTML5_ATOM(onfinish, "onfinish")
+HTML5_ATOM(onscroll, "onscroll")
+HTML5_ATOM(operator_, "operator")
+HTML5_ATOM(overflow, "overflow")
+HTML5_ATOM(onsubmit, "onsubmit")
+HTML5_ATOM(onrepeat, "onrepeat")
+HTML5_ATOM(onselect, "onselect")
+HTML5_ATOM(notation, "notation")
+HTML5_ATOM(noresize, "noresize")
+HTML5_ATOM(manifest, "manifest")
+HTML5_ATOM(mathsize, "mathsize")
+HTML5_ATOM(multiple, "multiple")
+HTML5_ATOM(longdesc, "longdesc")
+HTML5_ATOM(language, "language")
+HTML5_ATOM(tabindex, "tabindex")
+HTML5_ATOM(property, "property")
+HTML5_ATOM(readonly, "readonly")
+HTML5_ATOM(selected, "selected")
+HTML5_ATOM(rowlines, "rowlines")
+HTML5_ATOM(seamless, "seamless")
+HTML5_ATOM(rowalign, "rowalign")
+HTML5_ATOM(stretchy, "stretchy")
+HTML5_ATOM(required, "required")
+HTML5_ATOM(xml_base, "xml:base")
+HTML5_ATOM(xml_lang, "xml:lang")
+HTML5_ATOM(x_height, "x-height")
+HTML5_ATOM(aria_owns, "aria-owns")
+HTML5_ATOM(autofocus, "autofocus")
+HTML5_ATOM(aria_sort, "aria-sort")
+HTML5_ATOM(accesskey, "accesskey")
+HTML5_ATOM(aria_busy, "aria-busy")
+HTML5_ATOM(aria_grab, "aria-grab")
+HTML5_ATOM(amplitude, "amplitude")
+HTML5_ATOM(aria_live, "aria-live")
+HTML5_ATOM(clip_rule, "clip-rule")
+HTML5_ATOM(clip_path, "clip-path")
+HTML5_ATOM(equalrows, "equalrows")
+HTML5_ATOM(elevation, "elevation")
+HTML5_ATOM(direction, "direction")
+HTML5_ATOM(draggable, "draggable")
+HTML5_ATOM(fill_rule, "fill-rule")
+HTML5_ATOM(fontstyle, "fontstyle")
+HTML5_ATOM(font_size, "font-size")
+HTML5_ATOM(keysystem, "keysystem")
+HTML5_ATOM(keypoints, "keypoints")
+HTML5_ATOM(keyPoints, "keyPoints")
+HTML5_ATOM(hidefocus, "hidefocus")
+HTML5_ATOM(onmessage, "onmessage")
+HTML5_ATOM(intercept, "intercept")
+HTML5_ATOM(ondragend, "ondragend")
+HTML5_ATOM(onmoveend, "onmoveend")
+HTML5_ATOM(oninvalid, "oninvalid")
+HTML5_ATOM(integrity, "integrity")
+HTML5_ATOM(onkeydown, "onkeydown")
+HTML5_ATOM(onfocusin, "onfocusin")
+HTML5_ATOM(onmouseup, "onmouseup")
+HTML5_ATOM(inputmode, "inputmode")
+HTML5_ATOM(onrowexit, "onrowexit")
+HTML5_ATOM(mathcolor, "mathcolor")
+HTML5_ATOM(maskunits, "maskunits")
+HTML5_ATOM(maskUnits, "maskUnits")
+HTML5_ATOM(maxlength, "maxlength")
+HTML5_ATOM(linebreak, "linebreak")
+HTML5_ATOM(transform, "transform")
+HTML5_ATOM(v_hanging, "v-hanging")
+HTML5_ATOM(valuetype, "valuetype")
+HTML5_ATOM(pointsatz, "pointsatz")
+HTML5_ATOM(pointsAtZ, "pointsAtZ")
+HTML5_ATOM(pointsatx, "pointsatx")
+HTML5_ATOM(pointsAtX, "pointsAtX")
+HTML5_ATOM(pointsaty, "pointsaty")
+HTML5_ATOM(pointsAtY, "pointsAtY")
+HTML5_ATOM(symmetric, "symmetric")
+HTML5_ATOM(scrolling, "scrolling")
+HTML5_ATOM(repeatdur, "repeatdur")
+HTML5_ATOM(repeatDur, "repeatDur")
+HTML5_ATOM(selection, "selection")
+HTML5_ATOM(separator, "separator")
+HTML5_ATOM(xml_space, "xml:space")
+HTML5_ATOM(space, "space")
+HTML5_ATOM(autosubmit, "autosubmit")
+HTML5_ATOM(alphabetic, "alphabetic")
+HTML5_ATOM(actiontype, "actiontype")
+HTML5_ATOM(accumulate, "accumulate")
+HTML5_ATOM(aria_level, "aria-level")
+HTML5_ATOM(columnspan, "columnspan")
+HTML5_ATOM(cap_height, "cap-height")
+HTML5_ATOM(background, "background")
+HTML5_ATOM(glyph_name, "glyph-name")
+HTML5_ATOM(groupalign, "groupalign")
+HTML5_ATOM(fontfamily, "fontfamily")
+HTML5_ATOM(fontweight, "fontweight")
+HTML5_ATOM(font_style, "font-style")
+HTML5_ATOM(keysplines, "keysplines")
+HTML5_ATOM(keySplines, "keySplines")
+HTML5_ATOM(http_equiv, "http-equiv")
+HTML5_ATOM(onactivate, "onactivate")
+HTML5_ATOM(occurrence, "occurrence")
+HTML5_ATOM(irrelevant, "irrelevant")
+HTML5_ATOM(ondblclick, "ondblclick")
+HTML5_ATOM(ondragdrop, "ondragdrop")
+HTML5_ATOM(onkeypress, "onkeypress")
+HTML5_ATOM(onrowenter, "onrowenter")
+HTML5_ATOM(ondragover, "ondragover")
+HTML5_ATOM(onfocusout, "onfocusout")
+HTML5_ATOM(onmouseout, "onmouseout")
+HTML5_ATOM(numoctaves, "numoctaves")
+HTML5_ATOM(numOctaves, "numOctaves")
+HTML5_ATOM(marker_mid, "marker-mid")
+HTML5_ATOM(marker_end, "marker-end")
+HTML5_ATOM(textlength, "textlength")
+HTML5_ATOM(textLength, "textLength")
+HTML5_ATOM(visibility, "visibility")
+HTML5_ATOM(viewtarget, "viewtarget")
+HTML5_ATOM(viewTarget, "viewTarget")
+HTML5_ATOM(vert_adv_y, "vert-adv-y")
+HTML5_ATOM(pathlength, "pathlength")
+HTML5_ATOM(pathLength, "pathLength")
+HTML5_ATOM(repeat_max, "repeat-max")
+HTML5_ATOM(radiogroup, "radiogroup")
+HTML5_ATOM(stop_color, "stop-color")
+HTML5_ATOM(separators, "separators")
+HTML5_ATOM(repeat_min, "repeat-min")
+HTML5_ATOM(rowspacing, "rowspacing")
+HTML5_ATOM(zoomandpan, "zoomandpan")
+HTML5_ATOM(zoomAndPan, "zoomAndPan")
+HTML5_ATOM(xlink_type, "xlink:type")
+HTML5_ATOM(xlink_role, "xlink:role")
+HTML5_ATOM(xlink_href, "xlink:href")
+HTML5_ATOM(xlink_show, "xlink:show")
+HTML5_ATOM(show, "show")
+HTML5_ATOM(accentunder, "accentunder")
+HTML5_ATOM(aria_secret, "aria-secret")
+HTML5_ATOM(aria_atomic, "aria-atomic")
+HTML5_ATOM(aria_hidden, "aria-hidden")
+HTML5_ATOM(aria_flowto, "aria-flowto")
+HTML5_ATOM(arabic_form, "arabic-form")
+HTML5_ATOM(cellpadding, "cellpadding")
+HTML5_ATOM(cellspacing, "cellspacing")
+HTML5_ATOM(columnwidth, "columnwidth")
+HTML5_ATOM(crossorigin, "crossorigin")
+HTML5_ATOM(columnalign, "columnalign")
+HTML5_ATOM(columnlines, "columnlines")
+HTML5_ATOM(contextmenu, "contextmenu")
+HTML5_ATOM(baseprofile, "baseprofile")
+HTML5_ATOM(baseProfile, "baseProfile")
+HTML5_ATOM(font_family, "font-family")
+HTML5_ATOM(frameborder, "frameborder")
+HTML5_ATOM(filterunits, "filterunits")
+HTML5_ATOM(filterUnits, "filterUnits")
+HTML5_ATOM(flood_color, "flood-color")
+HTML5_ATOM(font_weight, "font-weight")
+HTML5_ATOM(horiz_adv_x, "horiz-adv-x")
+HTML5_ATOM(ondragleave, "ondragleave")
+HTML5_ATOM(onmousemove, "onmousemove")
+HTML5_ATOM(orientation, "orientation")
+HTML5_ATOM(onmousedown, "onmousedown")
+HTML5_ATOM(onmouseover, "onmouseover")
+HTML5_ATOM(ondragenter, "ondragenter")
+HTML5_ATOM(ideographic, "ideographic")
+HTML5_ATOM(onbeforecut, "onbeforecut")
+HTML5_ATOM(onforminput, "onforminput")
+HTML5_ATOM(ondragstart, "ondragstart")
+HTML5_ATOM(onmovestart, "onmovestart")
+HTML5_ATOM(markerunits, "markerunits")
+HTML5_ATOM(markerUnits, "markerUnits")
+HTML5_ATOM(mathvariant, "mathvariant")
+HTML5_ATOM(marginwidth, "marginwidth")
+HTML5_ATOM(markerwidth, "markerwidth")
+HTML5_ATOM(markerWidth, "markerWidth")
+HTML5_ATOM(text_anchor, "text-anchor")
+HTML5_ATOM(tablevalues, "tablevalues")
+HTML5_ATOM(tableValues, "tableValues")
+HTML5_ATOM(scriptlevel, "scriptlevel")
+HTML5_ATOM(repeatcount, "repeatcount")
+HTML5_ATOM(repeatCount, "repeatCount")
+HTML5_ATOM(stitchtiles, "stitchtiles")
+HTML5_ATOM(stitchTiles, "stitchTiles")
+HTML5_ATOM(startoffset, "startoffset")
+HTML5_ATOM(startOffset, "startOffset")
+HTML5_ATOM(scrolldelay, "scrolldelay")
+HTML5_ATOM(xmlns_xlink, "xmlns:xlink")
+HTML5_ATOM(xlink_title, "xlink:title")
+HTML5_ATOM(aria_invalid, "aria-invalid")
+HTML5_ATOM(aria_pressed, "aria-pressed")
+HTML5_ATOM(aria_checked, "aria-checked")
+HTML5_ATOM(autocomplete, "autocomplete")
+HTML5_ATOM(aria_setsize, "aria-setsize")
+HTML5_ATOM(aria_channel, "aria-channel")
+HTML5_ATOM(equalcolumns, "equalcolumns")
+HTML5_ATOM(displaystyle, "displaystyle")
+HTML5_ATOM(dataformatas, "dataformatas")
+HTML5_ATOM(fill_opacity, "fill-opacity")
+HTML5_ATOM(font_variant, "font-variant")
+HTML5_ATOM(font_stretch, "font-stretch")
+HTML5_ATOM(framespacing, "framespacing")
+HTML5_ATOM(kernelmatrix, "kernelmatrix")
+HTML5_ATOM(kernelMatrix, "kernelMatrix")
+HTML5_ATOM(ondeactivate, "ondeactivate")
+HTML5_ATOM(onrowsdelete, "onrowsdelete")
+HTML5_ATOM(onmouseleave, "onmouseleave")
+HTML5_ATOM(onformchange, "onformchange")
+HTML5_ATOM(oncellchange, "oncellchange")
+HTML5_ATOM(onmousewheel, "onmousewheel")
+HTML5_ATOM(onmouseenter, "onmouseenter")
+HTML5_ATOM(onafterprint, "onafterprint")
+HTML5_ATOM(onbeforecopy, "onbeforecopy")
+HTML5_ATOM(marginheight, "marginheight")
+HTML5_ATOM(markerheight, "markerheight")
+HTML5_ATOM(markerHeight, "markerHeight")
+HTML5_ATOM(marker_start, "marker-start")
+HTML5_ATOM(mathematical, "mathematical")
+HTML5_ATOM(lengthadjust, "lengthadjust")
+HTML5_ATOM(lengthAdjust, "lengthAdjust")
+HTML5_ATOM(unselectable, "unselectable")
+HTML5_ATOM(unicode_bidi, "unicode-bidi")
+HTML5_ATOM(units_per_em, "units-per-em")
+HTML5_ATOM(word_spacing, "word-spacing")
+HTML5_ATOM(writing_mode, "writing-mode")
+HTML5_ATOM(v_alphabetic, "v-alphabetic")
+HTML5_ATOM(patternunits, "patternunits")
+HTML5_ATOM(patternUnits, "patternUnits")
+HTML5_ATOM(spreadmethod, "spreadmethod")
+HTML5_ATOM(spreadMethod, "spreadMethod")
+HTML5_ATOM(surfacescale, "surfacescale")
+HTML5_ATOM(surfaceScale, "surfaceScale")
+HTML5_ATOM(stroke_width, "stroke-width")
+HTML5_ATOM(repeat_start, "repeat-start")
+HTML5_ATOM(stddeviation, "stddeviation")
+HTML5_ATOM(stdDeviation, "stdDeviation")
+HTML5_ATOM(stop_opacity, "stop-opacity")
+HTML5_ATOM(aria_controls, "aria-controls")
+HTML5_ATOM(aria_haspopup, "aria-haspopup")
+HTML5_ATOM(accent_height, "accent-height")
+HTML5_ATOM(aria_valuenow, "aria-valuenow")
+HTML5_ATOM(aria_relevant, "aria-relevant")
+HTML5_ATOM(aria_posinset, "aria-posinset")
+HTML5_ATOM(aria_valuemax, "aria-valuemax")
+HTML5_ATOM(aria_readonly, "aria-readonly")
+HTML5_ATOM(aria_selected, "aria-selected")
+HTML5_ATOM(aria_required, "aria-required")
+HTML5_ATOM(aria_expanded, "aria-expanded")
+HTML5_ATOM(aria_disabled, "aria-disabled")
+HTML5_ATOM(attributetype, "attributetype")
+HTML5_ATOM(attributeType, "attributeType")
+HTML5_ATOM(attributename, "attributename")
+HTML5_ATOM(attributeName, "attributeName")
+HTML5_ATOM(aria_datatype, "aria-datatype")
+HTML5_ATOM(aria_valuemin, "aria-valuemin")
+HTML5_ATOM(basefrequency, "basefrequency")
+HTML5_ATOM(baseFrequency, "baseFrequency")
+HTML5_ATOM(columnspacing, "columnspacing")
+HTML5_ATOM(color_profile, "color-profile")
+HTML5_ATOM(clippathunits, "clippathunits")
+HTML5_ATOM(clipPathUnits, "clipPathUnits")
+HTML5_ATOM(definitionurl, "definitionurl")
+HTML5_ATOM(definitionURL, "definitionURL")
+HTML5_ATOM(gradientunits, "gradientunits")
+HTML5_ATOM(gradientUnits, "gradientUnits")
+HTML5_ATOM(flood_opacity, "flood-opacity")
+HTML5_ATOM(onafterupdate, "onafterupdate")
+HTML5_ATOM(onerrorupdate, "onerrorupdate")
+HTML5_ATOM(onbeforepaste, "onbeforepaste")
+HTML5_ATOM(onlosecapture, "onlosecapture")
+HTML5_ATOM(oncontextmenu, "oncontextmenu")
+HTML5_ATOM(onselectstart, "onselectstart")
+HTML5_ATOM(onbeforeprint, "onbeforeprint")
+HTML5_ATOM(movablelimits, "movablelimits")
+HTML5_ATOM(linethickness, "linethickness")
+HTML5_ATOM(unicode_range, "unicode-range")
+HTML5_ATOM(thinmathspace, "thinmathspace")
+HTML5_ATOM(vert_origin_x, "vert-origin-x")
+HTML5_ATOM(vert_origin_y, "vert-origin-y")
+HTML5_ATOM(v_ideographic, "v-ideographic")
+HTML5_ATOM(preservealpha, "preservealpha")
+HTML5_ATOM(preserveAlpha, "preserveAlpha")
+HTML5_ATOM(scriptminsize, "scriptminsize")
+HTML5_ATOM(specification, "specification")
+HTML5_ATOM(xlink_actuate, "xlink:actuate")
+HTML5_ATOM(actuate, "actuate")
+HTML5_ATOM(xlink_arcrole, "xlink:arcrole")
+HTML5_ATOM(arcrole, "arcrole")
+HTML5_ATOM(accept_charset, "accept-charset")
+HTML5_ATOM(alignmentscope, "alignmentscope")
+HTML5_ATOM(aria_multiline, "aria-multiline")
+HTML5_ATOM(baseline_shift, "baseline-shift")
+HTML5_ATOM(horiz_origin_x, "horiz-origin-x")
+HTML5_ATOM(horiz_origin_y, "horiz-origin-y")
+HTML5_ATOM(onbeforeupdate, "onbeforeupdate")
+HTML5_ATOM(onfilterchange, "onfilterchange")
+HTML5_ATOM(onrowsinserted, "onrowsinserted")
+HTML5_ATOM(onbeforeunload, "onbeforeunload")
+HTML5_ATOM(mathbackground, "mathbackground")
+HTML5_ATOM(letter_spacing, "letter-spacing")
+HTML5_ATOM(lighting_color, "lighting-color")
+HTML5_ATOM(thickmathspace, "thickmathspace")
+HTML5_ATOM(text_rendering, "text-rendering")
+HTML5_ATOM(v_mathematical, "v-mathematical")
+HTML5_ATOM(pointer_events, "pointer-events")
+HTML5_ATOM(primitiveunits, "primitiveunits")
+HTML5_ATOM(primitiveUnits, "primitiveUnits")
+HTML5_ATOM(referrerpolicy, "referrerpolicy")
+HTML5_ATOM(systemlanguage, "systemlanguage")
+HTML5_ATOM(systemLanguage, "systemLanguage")
+HTML5_ATOM(stroke_linecap, "stroke-linecap")
+HTML5_ATOM(subscriptshift, "subscriptshift")
+HTML5_ATOM(stroke_opacity, "stroke-opacity")
+HTML5_ATOM(aria_dropeffect, "aria-dropeffect")
+HTML5_ATOM(aria_labelledby, "aria-labelledby")
+HTML5_ATOM(aria_templateid, "aria-templateid")
+HTML5_ATOM(color_rendering, "color-rendering")
+HTML5_ATOM(contenteditable, "contenteditable")
+HTML5_ATOM(diffuseconstant, "diffuseconstant")
+HTML5_ATOM(diffuseConstant, "diffuseConstant")
+HTML5_ATOM(ondataavailable, "ondataavailable")
+HTML5_ATOM(oncontrolselect, "oncontrolselect")
+HTML5_ATOM(image_rendering, "image-rendering")
+HTML5_ATOM(mediummathspace, "mediummathspace")
+HTML5_ATOM(text_decoration, "text-decoration")
+HTML5_ATOM(shape_rendering, "shape-rendering")
+HTML5_ATOM(stroke_linejoin, "stroke-linejoin")
+HTML5_ATOM(repeat_template, "repeat-template")
+HTML5_ATOM(aria_describedby, "aria-describedby")
+HTML5_ATOM(font_size_adjust, "font-size-adjust")
+HTML5_ATOM(kernelunitlength, "kernelunitlength")
+HTML5_ATOM(kernelUnitLength, "kernelUnitLength")
+HTML5_ATOM(onbeforeactivate, "onbeforeactivate")
+HTML5_ATOM(onpropertychange, "onpropertychange")
+HTML5_ATOM(ondatasetchanged, "ondatasetchanged")
+HTML5_ATOM(maskcontentunits, "maskcontentunits")
+HTML5_ATOM(maskContentUnits, "maskContentUnits")
+HTML5_ATOM(patterntransform, "patterntransform")
+HTML5_ATOM(patternTransform, "patternTransform")
+HTML5_ATOM(requiredfeatures, "requiredfeatures")
+HTML5_ATOM(requiredFeatures, "requiredFeatures")
+HTML5_ATOM(rendering_intent, "rendering-intent")
+HTML5_ATOM(specularexponent, "specularexponent")
+HTML5_ATOM(specularExponent, "specularExponent")
+HTML5_ATOM(specularconstant, "specularconstant")
+HTML5_ATOM(specularConstant, "specularConstant")
+HTML5_ATOM(superscriptshift, "superscriptshift")
+HTML5_ATOM(stroke_dasharray, "stroke-dasharray")
+HTML5_ATOM(xchannelselector, "xchannelselector")
+HTML5_ATOM(xChannelSelector, "xChannelSelector")
+HTML5_ATOM(ychannelselector, "ychannelselector")
+HTML5_ATOM(yChannelSelector, "yChannelSelector")
+HTML5_ATOM(aria_autocomplete, "aria-autocomplete")
+HTML5_ATOM(enable_background, "enable-background")
+HTML5_ATOM(dominant_baseline, "dominant-baseline")
+HTML5_ATOM(gradienttransform, "gradienttransform")
+HTML5_ATOM(gradientTransform, "gradientTransform")
+HTML5_ATOM(onbefordeactivate, "onbefordeactivate")
+HTML5_ATOM(ondatasetcomplete, "ondatasetcomplete")
+HTML5_ATOM(overline_position, "overline-position")
+HTML5_ATOM(onbeforeeditfocus, "onbeforeeditfocus")
+HTML5_ATOM(limitingconeangle, "limitingconeangle")
+HTML5_ATOM(limitingConeAngle, "limitingConeAngle")
+HTML5_ATOM(verythinmathspace, "verythinmathspace")
+HTML5_ATOM(stroke_dashoffset, "stroke-dashoffset")
+HTML5_ATOM(stroke_miterlimit, "stroke-miterlimit")
+HTML5_ATOM(alignment_baseline, "alignment-baseline")
+HTML5_ATOM(onreadystatechange, "onreadystatechange")
+HTML5_ATOM(overline_thickness, "overline-thickness")
+HTML5_ATOM(underline_position, "underline-position")
+HTML5_ATOM(verythickmathspace, "verythickmathspace")
+HTML5_ATOM(requiredextensions, "requiredextensions")
+HTML5_ATOM(requiredExtensions, "requiredExtensions")
+HTML5_ATOM(color_interpolation, "color-interpolation")
+HTML5_ATOM(underline_thickness, "underline-thickness")
+HTML5_ATOM(preserveaspectratio, "preserveaspectratio")
+HTML5_ATOM(preserveAspectRatio, "preserveAspectRatio")
+HTML5_ATOM(patterncontentunits, "patterncontentunits")
+HTML5_ATOM(patternContentUnits, "patternContentUnits")
+HTML5_ATOM(aria_multiselectable, "aria-multiselectable")
+HTML5_ATOM(scriptsizemultiplier, "scriptsizemultiplier")
+HTML5_ATOM(aria_activedescendant, "aria-activedescendant")
+HTML5_ATOM(veryverythinmathspace, "veryverythinmathspace")
+HTML5_ATOM(veryverythickmathspace, "veryverythickmathspace")
+HTML5_ATOM(strikethrough_position, "strikethrough-position")
+HTML5_ATOM(strikethrough_thickness, "strikethrough-thickness")
+HTML5_ATOM(glyph_orientation_vertical, "glyph-orientation-vertical")
+HTML5_ATOM(color_interpolation_filters, "color-interpolation-filters")
+HTML5_ATOM(glyph_orientation_horizontal, "glyph-orientation-horizontal")
+HTML5_ATOM(b, "b")
+HTML5_ATOM(g, "g")
+HTML5_ATOM(i, "i")
+HTML5_ATOM(q, "q")
+HTML5_ATOM(s, "s")
+HTML5_ATOM(u, "u")
+HTML5_ATOM(br, "br")
+HTML5_ATOM(ci, "ci")
+HTML5_ATOM(cn, "cn")
+HTML5_ATOM(dd, "dd")
+HTML5_ATOM(dl, "dl")
+HTML5_ATOM(dt, "dt")
+HTML5_ATOM(em, "em")
+HTML5_ATOM(eq, "eq")
+HTML5_ATOM(fn, "fn")
+HTML5_ATOM(h1, "h1")
+HTML5_ATOM(h2, "h2")
+HTML5_ATOM(h3, "h3")
+HTML5_ATOM(h4, "h4")
+HTML5_ATOM(h5, "h5")
+HTML5_ATOM(h6, "h6")
+HTML5_ATOM(gt, "gt")
+HTML5_ATOM(hr, "hr")
+HTML5_ATOM(li, "li")
+HTML5_ATOM(ln, "ln")
+HTML5_ATOM(lt, "lt")
+HTML5_ATOM(or_, "or")
+HTML5_ATOM(pi, "pi")
+HTML5_ATOM(rb, "rb")
+HTML5_ATOM(rp, "rp")
+HTML5_ATOM(tt, "tt")
+HTML5_ATOM(and_, "and")
+HTML5_ATOM(arg, "arg")
+HTML5_ATOM(abs, "abs")
+HTML5_ATOM(big, "big")
+HTML5_ATOM(bdo, "bdo")
+HTML5_ATOM(csc, "csc")
+HTML5_ATOM(col, "col")
+HTML5_ATOM(cos, "cos")
+HTML5_ATOM(cot, "cot")
+HTML5_ATOM(del, "del")
+HTML5_ATOM(dfn, "dfn")
+HTML5_ATOM(exp, "exp")
+HTML5_ATOM(gcd, "gcd")
+HTML5_ATOM(geq, "geq")
+HTML5_ATOM(img, "img")
+HTML5_ATOM(ins, "ins")
+HTML5_ATOM(int_, "int")
+HTML5_ATOM(kbd, "kbd")
+HTML5_ATOM(log, "log")
+HTML5_ATOM(lcm, "lcm")
+HTML5_ATOM(leq, "leq")
+HTML5_ATOM(mtd, "mtd")
+HTML5_ATOM(map, "map")
+HTML5_ATOM(mtr, "mtr")
+HTML5_ATOM(neq, "neq")
+HTML5_ATOM(not_, "not")
+HTML5_ATOM(nav, "nav")
+HTML5_ATOM(pre, "pre")
+HTML5_ATOM(rem, "rem")
+HTML5_ATOM(sub, "sub")
+HTML5_ATOM(sec, "sec")
+HTML5_ATOM(sum, "sum")
+HTML5_ATOM(sin, "sin")
+HTML5_ATOM(sep, "sep")
+HTML5_ATOM(sup, "sup")
+HTML5_ATOM(set, "set")
+HTML5_ATOM(tan, "tan")
+HTML5_ATOM(use, "use")
+HTML5_ATOM(var, "var")
+HTML5_ATOM(wbr, "wbr")
+HTML5_ATOM(xor_, "xor")
+HTML5_ATOM(area, "area")
+HTML5_ATOM(bvar, "bvar")
+HTML5_ATOM(card, "card")
+HTML5_ATOM(csch, "csch")
+HTML5_ATOM(cosh, "cosh")
+HTML5_ATOM(coth, "coth")
+HTML5_ATOM(curl, "curl")
+HTML5_ATOM(diff, "diff")
+HTML5_ATOM(defs, "defs")
+HTML5_ATOM(font, "font")
+HTML5_ATOM(grad, "grad")
+HTML5_ATOM(line, "line")
+HTML5_ATOM(meta, "meta")
+HTML5_ATOM(msub, "msub")
+HTML5_ATOM(math, "math")
+HTML5_ATOM(mark, "mark")
+HTML5_ATOM(mean, "mean")
+HTML5_ATOM(main, "main")
+HTML5_ATOM(msup, "msup")
+HTML5_ATOM(menu, "menu")
+HTML5_ATOM(mrow, "mrow")
+HTML5_ATOM(none, "none")
+HTML5_ATOM(nest, "nest")
+HTML5_ATOM(plus, "plus")
+HTML5_ATOM(rule, "rule")
+HTML5_ATOM(real, "real")
+HTML5_ATOM(reln, "reln")
+HTML5_ATOM(rect, "rect")
+HTML5_ATOM(root, "root")
+HTML5_ATOM(sech, "sech")
+HTML5_ATOM(sinh, "sinh")
+HTML5_ATOM(samp, "samp")
+HTML5_ATOM(stop, "stop")
+HTML5_ATOM(sdev, "sdev")
+HTML5_ATOM(time, "time")
+HTML5_ATOM(true_, "true")
+HTML5_ATOM(tref, "tref")
+HTML5_ATOM(tanh, "tanh")
+HTML5_ATOM(view, "view")
+HTML5_ATOM(aside, "aside")
+HTML5_ATOM(audio, "audio")
+HTML5_ATOM(apply, "apply")
+HTML5_ATOM(embed, "embed")
+HTML5_ATOM(false_, "false")
+HTML5_ATOM(floor, "floor")
+HTML5_ATOM(glyph, "glyph")
+HTML5_ATOM(hkern, "hkern")
+HTML5_ATOM(image, "image")
+HTML5_ATOM(ident, "ident")
+HTML5_ATOM(limit, "limit")
+HTML5_ATOM(mfrac, "mfrac")
+HTML5_ATOM(mpath, "mpath")
+HTML5_ATOM(meter, "meter")
+HTML5_ATOM(mover, "mover")
+HTML5_ATOM(minus, "minus")
+HTML5_ATOM(mroot, "mroot")
+HTML5_ATOM(msqrt, "msqrt")
+HTML5_ATOM(notin, "notin")
+HTML5_ATOM(piece, "piece")
+HTML5_ATOM(param, "param")
+HTML5_ATOM(power, "power")
+HTML5_ATOM(reals, "reals")
+HTML5_ATOM(small_, "small")
+HTML5_ATOM(track, "track")
+HTML5_ATOM(tspan, "tspan")
+HTML5_ATOM(times, "times")
+HTML5_ATOM(union_, "union")
+HTML5_ATOM(vkern, "vkern")
+HTML5_ATOM(video, "video")
+HTML5_ATOM(arcsec, "arcsec")
+HTML5_ATOM(arccsc, "arccsc")
+HTML5_ATOM(arctan, "arctan")
+HTML5_ATOM(arcsin, "arcsin")
+HTML5_ATOM(arccos, "arccos")
+HTML5_ATOM(applet, "applet")
+HTML5_ATOM(arccot, "arccot")
+HTML5_ATOM(approx, "approx")
+HTML5_ATOM(circle, "circle")
+HTML5_ATOM(center, "center")
+HTML5_ATOM(canvas, "canvas")
+HTML5_ATOM(divide, "divide")
+HTML5_ATOM(degree, "degree")
+HTML5_ATOM(domain, "domain")
+HTML5_ATOM(exists, "exists")
+HTML5_ATOM(fetile, "fetile")
+HTML5_ATOM(feTile, "feTile")
+HTML5_ATOM(figure, "figure")
+HTML5_ATOM(forall, "forall")
+HTML5_ATOM(footer, "footer")
+HTML5_ATOM(hgroup, "hgroup")
+HTML5_ATOM(header, "header")
+HTML5_ATOM(keygen, "keygen")
+HTML5_ATOM(lambda, "lambda")
+HTML5_ATOM(legend, "legend")
+HTML5_ATOM(mspace, "mspace")
+HTML5_ATOM(mtable, "mtable")
+HTML5_ATOM(mstyle, "mstyle")
+HTML5_ATOM(mglyph, "mglyph")
+HTML5_ATOM(median, "median")
+HTML5_ATOM(munder, "munder")
+HTML5_ATOM(marker, "marker")
+HTML5_ATOM(merror, "merror")
+HTML5_ATOM(moment, "moment")
+HTML5_ATOM(matrix, "matrix")
+HTML5_ATOM(output, "output")
+HTML5_ATOM(primes, "primes")
+HTML5_ATOM(source, "source")
+HTML5_ATOM(strike, "strike")
+HTML5_ATOM(strong, "strong")
+HTML5_ATOM(switch_, "switch")
+HTML5_ATOM(symbol, "symbol")
+HTML5_ATOM(subset, "subset")
+HTML5_ATOM(tbreak, "tbreak")
+HTML5_ATOM(vector, "vector")
+HTML5_ATOM(article, "article")
+HTML5_ATOM(animate, "animate")
+HTML5_ATOM(arcsech, "arcsech")
+HTML5_ATOM(arccsch, "arccsch")
+HTML5_ATOM(arctanh, "arctanh")
+HTML5_ATOM(arcsinh, "arcsinh")
+HTML5_ATOM(arccosh, "arccosh")
+HTML5_ATOM(arccoth, "arccoth")
+HTML5_ATOM(acronym, "acronym")
+HTML5_ATOM(bgsound, "bgsound")
+HTML5_ATOM(compose, "compose")
+HTML5_ATOM(ceiling, "ceiling")
+HTML5_ATOM(csymbol, "csymbol")
+HTML5_ATOM(discard, "discard")
+HTML5_ATOM(details, "details")
+HTML5_ATOM(ellipse, "ellipse")
+HTML5_ATOM(fefunca, "fefunca")
+HTML5_ATOM(feFuncA, "feFuncA")
+HTML5_ATOM(fefuncb, "fefuncb")
+HTML5_ATOM(feFuncB, "feFuncB")
+HTML5_ATOM(feblend, "feblend")
+HTML5_ATOM(feBlend, "feBlend")
+HTML5_ATOM(feflood, "feflood")
+HTML5_ATOM(feFlood, "feFlood")
+HTML5_ATOM(feimage, "feimage")
+HTML5_ATOM(feImage, "feImage")
+HTML5_ATOM(femerge, "femerge")
+HTML5_ATOM(feMerge, "feMerge")
+HTML5_ATOM(fefuncg, "fefuncg")
+HTML5_ATOM(feFuncG, "feFuncG")
+HTML5_ATOM(fefuncr, "fefuncr")
+HTML5_ATOM(feFuncR, "feFuncR")
+HTML5_ATOM(handler, "handler")
+HTML5_ATOM(inverse, "inverse")
+HTML5_ATOM(implies, "implies")
+HTML5_ATOM(isindex, "isindex")
+HTML5_ATOM(logbase, "logbase")
+HTML5_ATOM(listing, "listing")
+HTML5_ATOM(mfenced, "mfenced")
+HTML5_ATOM(mpadded, "mpadded")
+HTML5_ATOM(marquee, "marquee")
+HTML5_ATOM(maction, "maction")
+HTML5_ATOM(msubsup, "msubsup")
+HTML5_ATOM(polygon, "polygon")
+HTML5_ATOM(picture, "picture")
+HTML5_ATOM(product, "product")
+HTML5_ATOM(setdiff, "setdiff")
+HTML5_ATOM(section, "section")
+HTML5_ATOM(tendsto, "tendsto")
+HTML5_ATOM(uplimit, "uplimit")
+HTML5_ATOM(altglyph, "altglyph")
+HTML5_ATOM(altGlyph, "altGlyph")
+HTML5_ATOM(basefont, "basefont")
+HTML5_ATOM(clippath, "clippath")
+HTML5_ATOM(clipPath, "clipPath")
+HTML5_ATOM(codomain, "codomain")
+HTML5_ATOM(emptyset, "emptyset")
+HTML5_ATOM(factorof, "factorof")
+HTML5_ATOM(fieldset, "fieldset")
+HTML5_ATOM(feoffset, "feoffset")
+HTML5_ATOM(feOffset, "feOffset")
+HTML5_ATOM(interval, "interval")
+HTML5_ATOM(integers, "integers")
+HTML5_ATOM(infinity, "infinity")
+HTML5_ATOM(listener, "listener")
+HTML5_ATOM(lowlimit, "lowlimit")
+HTML5_ATOM(metadata, "metadata")
+HTML5_ATOM(menclose, "menclose")
+HTML5_ATOM(menuitem, "menuitem")
+HTML5_ATOM(mphantom, "mphantom")
+HTML5_ATOM(polyline, "polyline")
+HTML5_ATOM(prefetch, "prefetch")
+HTML5_ATOM(progress, "progress")
+HTML5_ATOM(prsubset, "prsubset")
+HTML5_ATOM(quotient, "quotient")
+HTML5_ATOM(selector, "selector")
+HTML5_ATOM(textpath, "textpath")
+HTML5_ATOM(textPath, "textPath")
+HTML5_ATOM(variance, "variance")
+HTML5_ATOM(animation, "animation")
+HTML5_ATOM(conjugate, "conjugate")
+HTML5_ATOM(condition, "condition")
+HTML5_ATOM(complexes, "complexes")
+HTML5_ATOM(font_face, "font-face")
+HTML5_ATOM(factorial, "factorial")
+HTML5_ATOM(intersect, "intersect")
+HTML5_ATOM(imaginary, "imaginary")
+HTML5_ATOM(laplacian, "laplacian")
+HTML5_ATOM(matrixrow, "matrixrow")
+HTML5_ATOM(notsubset, "notsubset")
+HTML5_ATOM(otherwise, "otherwise")
+HTML5_ATOM(piecewise, "piecewise")
+HTML5_ATOM(rationals, "rationals")
+HTML5_ATOM(semantics, "semantics")
+HTML5_ATOM(transpose, "transpose")
+HTML5_ATOM(annotation, "annotation")
+HTML5_ATOM(blockquote, "blockquote")
+HTML5_ATOM(divergence, "divergence")
+HTML5_ATOM(eulergamma, "eulergamma")
+HTML5_ATOM(equivalent, "equivalent")
+HTML5_ATOM(figcaption, "figcaption")
+HTML5_ATOM(imaginaryi, "imaginaryi")
+HTML5_ATOM(malignmark, "malignmark")
+HTML5_ATOM(munderover, "munderover")
+HTML5_ATOM(mlabeledtr, "mlabeledtr")
+HTML5_ATOM(notanumber, "notanumber")
+HTML5_ATOM(solidcolor, "solidcolor")
+HTML5_ATOM(altglyphdef, "altglyphdef")
+HTML5_ATOM(altGlyphDef, "altGlyphDef")
+HTML5_ATOM(determinant, "determinant")
+HTML5_ATOM(femergenode, "femergenode")
+HTML5_ATOM(feMergeNode, "feMergeNode")
+HTML5_ATOM(fecomposite, "fecomposite")
+HTML5_ATOM(feComposite, "feComposite")
+HTML5_ATOM(fespotlight, "fespotlight")
+HTML5_ATOM(feSpotLight, "feSpotLight")
+HTML5_ATOM(maligngroup, "maligngroup")
+HTML5_ATOM(mprescripts, "mprescripts")
+HTML5_ATOM(momentabout, "momentabout")
+HTML5_ATOM(notprsubset, "notprsubset")
+HTML5_ATOM(partialdiff, "partialdiff")
+HTML5_ATOM(altglyphitem, "altglyphitem")
+HTML5_ATOM(altGlyphItem, "altGlyphItem")
+HTML5_ATOM(animatecolor, "animatecolor")
+HTML5_ATOM(animateColor, "animateColor")
+HTML5_ATOM(datatemplate, "datatemplate")
+HTML5_ATOM(exponentiale, "exponentiale")
+HTML5_ATOM(feturbulence, "feturbulence")
+HTML5_ATOM(feTurbulence, "feTurbulence")
+HTML5_ATOM(fepointlight, "fepointlight")
+HTML5_ATOM(fePointLight, "fePointLight")
+HTML5_ATOM(fedropshadow, "fedropshadow")
+HTML5_ATOM(feDropShadow, "feDropShadow")
+HTML5_ATOM(femorphology, "femorphology")
+HTML5_ATOM(feMorphology, "feMorphology")
+HTML5_ATOM(outerproduct, "outerproduct")
+HTML5_ATOM(animatemotion, "animatemotion")
+HTML5_ATOM(animateMotion, "animateMotion")
+HTML5_ATOM(font_face_src, "font-face-src")
+HTML5_ATOM(font_face_uri, "font-face-uri")
+HTML5_ATOM(foreignobject, "foreignobject")
+HTML5_ATOM(fecolormatrix, "fecolormatrix")
+HTML5_ATOM(feColorMatrix, "feColorMatrix")
+HTML5_ATOM(missing_glyph, "missing-glyph")
+HTML5_ATOM(mmultiscripts, "mmultiscripts")
+HTML5_ATOM(scalarproduct, "scalarproduct")
+HTML5_ATOM(vectorproduct, "vectorproduct")
+HTML5_ATOM(definition_src, "definition-src")
+HTML5_ATOM(font_face_name, "font-face-name")
+HTML5_ATOM(fegaussianblur, "fegaussianblur")
+HTML5_ATOM(feGaussianBlur, "feGaussianBlur")
+HTML5_ATOM(fedistantlight, "fedistantlight")
+HTML5_ATOM(feDistantLight, "feDistantLight")
+HTML5_ATOM(lineargradient, "lineargradient")
+HTML5_ATOM(linearGradient, "linearGradient")
+HTML5_ATOM(naturalnumbers, "naturalnumbers")
+HTML5_ATOM(radialgradient, "radialgradient")
+HTML5_ATOM(radialGradient, "radialGradient")
+HTML5_ATOM(animatetransform, "animatetransform")
+HTML5_ATOM(animateTransform, "animateTransform")
+HTML5_ATOM(cartesianproduct, "cartesianproduct")
+HTML5_ATOM(font_face_format, "font-face-format")
+HTML5_ATOM(feconvolvematrix, "feconvolvematrix")
+HTML5_ATOM(feConvolveMatrix, "feConvolveMatrix")
+HTML5_ATOM(fediffuselighting, "fediffuselighting")
+HTML5_ATOM(feDiffuseLighting, "feDiffuseLighting")
+HTML5_ATOM(fedisplacementmap, "fedisplacementmap")
+HTML5_ATOM(feDisplacementMap, "feDisplacementMap")
+HTML5_ATOM(fespecularlighting, "fespecularlighting")
+HTML5_ATOM(feSpecularLighting, "feSpecularLighting")
+HTML5_ATOM(domainofapplication, "domainofapplication")
+HTML5_ATOM(fecomponenttransfer, "fecomponenttransfer")
+HTML5_ATOM(feComponentTransfer, "feComponentTransfer")
diff --git a/parser/html/nsHtml5AtomTable.cpp b/parser/html/nsHtml5AtomTable.cpp
new file mode 100644
index 000000000..d523f58b0
--- /dev/null
+++ b/parser/html/nsHtml5AtomTable.cpp
@@ -0,0 +1,56 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5AtomTable.h"
+#include "nsHtml5Atom.h"
+#include "nsThreadUtils.h"
+
+nsHtml5AtomEntry::nsHtml5AtomEntry(KeyTypePointer aStr)
+ : nsStringHashKey(aStr)
+ , mAtom(new nsHtml5Atom(*aStr))
+{
+}
+
+nsHtml5AtomEntry::nsHtml5AtomEntry(const nsHtml5AtomEntry& aOther)
+ : nsStringHashKey(aOther)
+ , mAtom(nullptr)
+{
+ NS_NOTREACHED("nsHtml5AtomTable is broken and tried to copy an entry");
+}
+
+nsHtml5AtomEntry::~nsHtml5AtomEntry()
+{
+}
+
+nsHtml5AtomTable::nsHtml5AtomTable()
+{
+#ifdef DEBUG
+ NS_GetMainThread(getter_AddRefs(mPermittedLookupThread));
+#endif
+}
+
+nsHtml5AtomTable::~nsHtml5AtomTable()
+{
+}
+
+nsIAtom*
+nsHtml5AtomTable::GetAtom(const nsAString& aKey)
+{
+#ifdef DEBUG
+ {
+ nsCOMPtr<nsIThread> currentThread;
+ NS_GetCurrentThread(getter_AddRefs(currentThread));
+ NS_ASSERTION(mPermittedLookupThread == currentThread, "Wrong thread!");
+ }
+#endif
+ nsIAtom* atom = NS_GetStaticAtom(aKey);
+ if (atom) {
+ return atom;
+ }
+ nsHtml5AtomEntry* entry = mTable.PutEntry(aKey);
+ if (!entry) {
+ return nullptr;
+ }
+ return entry->GetAtom();
+}
diff --git a/parser/html/nsHtml5AtomTable.h b/parser/html/nsHtml5AtomTable.h
new file mode 100644
index 000000000..43f9b5f2f
--- /dev/null
+++ b/parser/html/nsHtml5AtomTable.h
@@ -0,0 +1,107 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5AtomTable_h
+#define nsHtml5AtomTable_h
+
+#include "nsHashKeys.h"
+#include "nsTHashtable.h"
+#include "nsAutoPtr.h"
+#include "nsIAtom.h"
+#include "nsIThread.h"
+
+class nsHtml5Atom;
+
+class nsHtml5AtomEntry : public nsStringHashKey
+{
+ public:
+ explicit nsHtml5AtomEntry(KeyTypePointer aStr);
+ nsHtml5AtomEntry(const nsHtml5AtomEntry& aOther);
+ ~nsHtml5AtomEntry();
+ inline nsHtml5Atom* GetAtom()
+ {
+ return mAtom;
+ }
+ private:
+ nsAutoPtr<nsHtml5Atom> mAtom;
+};
+
+/**
+ * nsHtml5AtomTable provides non-locking lookup and creation of atoms for
+ * nsHtml5Parser or nsHtml5StreamParser.
+ *
+ * The hashtable holds dynamically allocated atoms that are private to an
+ * instance of nsHtml5Parser or nsHtml5StreamParser. (Static atoms are used on
+ * interned nsHtml5ElementNames and interned nsHtml5AttributeNames. Also, when
+ * the doctype name is 'html', that identifier needs to be represented as a
+ * static atom.)
+ *
+ * Each instance of nsHtml5Parser has a single instance of nsHtml5AtomTable,
+ * and each instance of nsHtml5StreamParser has a single instance of
+ * nsHtml5AtomTable. Dynamic atoms obtained from an nsHtml5AtomTable are valid
+ * for == comparison with each other or with atoms declared in nsHtml5Atoms
+ * within the nsHtml5Tokenizer and the nsHtml5TreeBuilder instances owned by
+ * the same nsHtml5Parser/nsHtml5StreamParser instance that owns the
+ * nsHtml5AtomTable instance.
+ *
+ * Dynamic atoms (atoms whose IsStaticAtom() returns false) obtained from
+ * nsHtml5AtomTable must be re-obtained from another atom table when there's a
+ * need to migrate atoms from an nsHtml5Parser to its nsHtml5StreamParser
+ * (re-obtain from the other nsHtml5AtomTable), from an nsHtml5Parser to its
+ * owner nsHtml5Parser (re-obtain from the other nsHtml5AtomTable) or from the
+ * parser to the DOM (re-obtain from the application-wide atom table). To
+ * re-obtain an atom from another atom table, obtain a string from the atom
+ * using ToString(nsAString&) and look up an atom in the other table using that
+ * string.
+ *
+ * An instance of nsHtml5AtomTable that belongs to an nsHtml5Parser is only
+ * accessed from the main thread. An instance of nsHtml5AtomTable that belongs
+ * to an nsHtml5StreamParser is accessed both from the main thread and from the
+ * thread that executes the runnables of the nsHtml5StreamParser instance.
+ * However, the threads never access the nsHtml5AtomTable instance concurrently
+ * in the nsHtml5StreamParser case.
+ *
+ * Methods on the atoms obtained from nsHtml5AtomTable may be called on any
+ * thread, although they only need to be called on the main thread or on the
+ * thread working for the nsHtml5StreamParser when nsHtml5AtomTable belongs to
+ * an nsHtml5StreamParser.
+ *
+ * Dynamic atoms obtained from nsHtml5AtomTable are deleted when the
+ * nsHtml5AtomTable itself is destructed, which happens when the owner
+ * nsHtml5Parser or nsHtml5StreamParser is destructed.
+ */
+class nsHtml5AtomTable
+{
+ public:
+ nsHtml5AtomTable();
+ ~nsHtml5AtomTable();
+
+ /**
+ * Obtains the atom for the given string in the scope of this atom table.
+ */
+ nsIAtom* GetAtom(const nsAString& aKey);
+
+ /**
+ * Empties the table.
+ */
+ void Clear()
+ {
+ mTable.Clear();
+ }
+
+#ifdef DEBUG
+ void SetPermittedLookupThread(nsIThread* aThread)
+ {
+ mPermittedLookupThread = aThread;
+ }
+#endif
+
+ private:
+ nsTHashtable<nsHtml5AtomEntry> mTable;
+#ifdef DEBUG
+ nsCOMPtr<nsIThread> mPermittedLookupThread;
+#endif
+};
+
+#endif // nsHtml5AtomTable_h
diff --git a/parser/html/nsHtml5Atoms.cpp b/parser/html/nsHtml5Atoms.cpp
new file mode 100644
index 000000000..ae8136179
--- /dev/null
+++ b/parser/html/nsHtml5Atoms.cpp
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * This class wraps up the creation (and destruction) of the standard
+ * set of atoms used by the HTML5 parser; the atoms are created when
+ * nsHtml5Module is loaded and they are destroyed when nsHtml5Module is
+ * unloaded.
+ */
+
+#include "nsHtml5Atoms.h"
+#include "nsStaticAtom.h"
+
+using namespace mozilla;
+
+// define storage for all atoms
+#define HTML5_ATOM(_name, _value) nsIAtom* nsHtml5Atoms::_name;
+#include "nsHtml5AtomList.h"
+#undef HTML5_ATOM
+
+#define HTML5_ATOM(name_, value_) NS_STATIC_ATOM_BUFFER(name_##_buffer, value_)
+#include "nsHtml5AtomList.h"
+#undef HTML5_ATOM
+
+static const nsStaticAtom Html5Atoms_info[] = {
+#define HTML5_ATOM(name_, value_) NS_STATIC_ATOM(name_##_buffer, &nsHtml5Atoms::name_),
+#include "nsHtml5AtomList.h"
+#undef HTML5_ATOM
+};
+
+void nsHtml5Atoms::AddRefAtoms()
+{
+ NS_RegisterStaticAtoms(Html5Atoms_info);
+}
diff --git a/parser/html/nsHtml5Atoms.h b/parser/html/nsHtml5Atoms.h
new file mode 100644
index 000000000..069aa8445
--- /dev/null
+++ b/parser/html/nsHtml5Atoms.h
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * This class wraps up the creation (and destruction) of the standard
+ * set of atoms used by gklayout; the atoms are created when gklayout
+ * is loaded and they are destroyed when gklayout is unloaded.
+ */
+
+#ifndef nsHtml5Atoms_h
+#define nsHtml5Atoms_h
+
+#include "nsIAtom.h"
+
+class nsHtml5Atoms {
+ public:
+ static void AddRefAtoms();
+ /* Declare all atoms
+ The atom names and values are stored in nsGkAtomList.h and
+ are brought to you by the magic of C preprocessing
+ Add new atoms to nsGkAtomList and all support logic will be auto-generated
+ */
+#define HTML5_ATOM(_name, _value) static nsIAtom* _name;
+#include "nsHtml5AtomList.h"
+#undef HTML5_ATOM
+};
+
+#endif /* nsHtml5Atoms_h */
diff --git a/parser/html/nsHtml5AttributeName.cpp b/parser/html/nsHtml5AttributeName.cpp
new file mode 100644
index 000000000..fc7745adc
--- /dev/null
+++ b/parser/html/nsHtml5AttributeName.cpp
@@ -0,0 +1,2585 @@
+/*
+ * Copyright (c) 2008-2011 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit AttributeName.java instead and regenerate.
+ */
+
+#define nsHtml5AttributeName_cpp__
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5ByteReadable.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
+
+#include "nsHtml5Tokenizer.h"
+#include "nsHtml5TreeBuilder.h"
+#include "nsHtml5MetaScanner.h"
+#include "nsHtml5ElementName.h"
+#include "nsHtml5HtmlAttributes.h"
+#include "nsHtml5StackNode.h"
+#include "nsHtml5UTF16Buffer.h"
+#include "nsHtml5StateSnapshot.h"
+#include "nsHtml5Portability.h"
+
+#include "nsHtml5AttributeName.h"
+#include "nsHtml5ReleasableAttributeName.h"
+
+int32_t* nsHtml5AttributeName::ALL_NO_NS = 0;
+int32_t* nsHtml5AttributeName::XMLNS_NS = 0;
+int32_t* nsHtml5AttributeName::XML_NS = 0;
+int32_t* nsHtml5AttributeName::XLINK_NS = 0;
+nsIAtom** nsHtml5AttributeName::ALL_NO_PREFIX = 0;
+nsIAtom** nsHtml5AttributeName::XMLNS_PREFIX = 0;
+nsIAtom** nsHtml5AttributeName::XLINK_PREFIX = 0;
+nsIAtom** nsHtml5AttributeName::XML_PREFIX = 0;
+nsIAtom**
+nsHtml5AttributeName::SVG_DIFFERENT(nsIAtom* name, nsIAtom* camel)
+{
+ nsIAtom** arr = new nsIAtom*[4];
+ arr[0] = name;
+ arr[1] = name;
+ arr[2] = camel;
+ return arr;
+}
+
+nsIAtom**
+nsHtml5AttributeName::MATH_DIFFERENT(nsIAtom* name, nsIAtom* camel)
+{
+ nsIAtom** arr = new nsIAtom*[4];
+ arr[0] = name;
+ arr[1] = camel;
+ arr[2] = name;
+ return arr;
+}
+
+nsIAtom**
+nsHtml5AttributeName::COLONIFIED_LOCAL(nsIAtom* name, nsIAtom* suffix)
+{
+ nsIAtom** arr = new nsIAtom*[4];
+ arr[0] = name;
+ arr[1] = suffix;
+ arr[2] = suffix;
+ return arr;
+}
+
+nsIAtom**
+nsHtml5AttributeName::SAME_LOCAL(nsIAtom* name)
+{
+ nsIAtom** arr = new nsIAtom*[4];
+ arr[0] = name;
+ arr[1] = name;
+ arr[2] = name;
+ return arr;
+}
+
+nsHtml5AttributeName*
+nsHtml5AttributeName::nameByBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5AtomTable* interner)
+{
+ int32_t hash = nsHtml5AttributeName::bufToHash(buf, length);
+ int32_t index = nsHtml5AttributeName::ATTRIBUTE_HASHES.binarySearch(hash);
+ if (index < 0) {
+ return nsHtml5AttributeName::createAttributeName(nsHtml5Portability::newLocalNameFromBuffer(buf, offset, length, interner));
+ } else {
+ nsHtml5AttributeName* attributeName = nsHtml5AttributeName::ATTRIBUTE_NAMES[index];
+ nsIAtom* name = attributeName->getLocal(NS_HTML5ATTRIBUTE_NAME_HTML);
+ if (!nsHtml5Portability::localEqualsBuffer(name, buf, offset, length)) {
+ return nsHtml5AttributeName::createAttributeName(nsHtml5Portability::newLocalNameFromBuffer(buf, offset, length, interner));
+ }
+ return attributeName;
+ }
+}
+
+int32_t
+nsHtml5AttributeName::bufToHash(char16_t* buf, int32_t len)
+{
+ int32_t hash2 = 0;
+ int32_t hash = len;
+ hash <<= 5;
+ hash += buf[0] - 0x60;
+ int32_t j = len;
+ for (int32_t i = 0; i < 4 && j > 0; i++) {
+ j--;
+ hash <<= 5;
+ hash += buf[j] - 0x60;
+ hash2 <<= 6;
+ hash2 += buf[i] - 0x5F;
+ }
+ return hash ^ hash2;
+}
+
+
+nsHtml5AttributeName::nsHtml5AttributeName(int32_t* uri, nsIAtom** local, nsIAtom** prefix)
+ : uri(uri),
+ local(local),
+ prefix(prefix)
+{
+ MOZ_COUNT_CTOR(nsHtml5AttributeName);
+}
+
+nsHtml5AttributeName*
+nsHtml5AttributeName::createAttributeName(nsIAtom* name)
+{
+ return new nsHtml5ReleasableAttributeName(nsHtml5AttributeName::ALL_NO_NS, nsHtml5AttributeName::SAME_LOCAL(name), ALL_NO_PREFIX);
+}
+
+void
+nsHtml5AttributeName::release()
+{
+}
+
+
+nsHtml5AttributeName::~nsHtml5AttributeName()
+{
+ MOZ_COUNT_DTOR(nsHtml5AttributeName);
+ delete[] local;
+}
+
+nsHtml5AttributeName*
+nsHtml5AttributeName::cloneAttributeName(nsHtml5AtomTable* interner)
+{
+ return this;
+}
+
+int32_t
+nsHtml5AttributeName::getUri(int32_t mode)
+{
+ return uri[mode];
+}
+
+nsIAtom*
+nsHtml5AttributeName::getLocal(int32_t mode)
+{
+ return local[mode];
+}
+
+nsIAtom*
+nsHtml5AttributeName::getPrefix(int32_t mode)
+{
+ return prefix[mode];
+}
+
+bool
+nsHtml5AttributeName::equalsAnother(nsHtml5AttributeName* another)
+{
+ return this->getLocal(NS_HTML5ATTRIBUTE_NAME_HTML) == another->getLocal(NS_HTML5ATTRIBUTE_NAME_HTML);
+}
+
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_D = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_K = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_R = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_X = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_Y = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_Z = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_BY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_G2 = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_G1 = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_K4 = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_K2 = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_K3 = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_K1 = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ID = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_IN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_U2 = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_U1 = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_RT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_RX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_RY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_TO = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_Y2 = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_Y1 = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_X1 = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_X2 = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ALT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DIR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DUR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_END = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FOR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_IN2 = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MAX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MIN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LOW = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REL = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REV = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SRC = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_AXIS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ABBR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_BBOX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CITE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CODE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_BIAS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_COLS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CLIP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CHAR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_BASE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_EDGE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DATA = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FILL = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FROM = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FORM = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FACE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_HIGH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_HREF = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_OPEN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ICON = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_NAME = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MODE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MASK = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LINK = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LANG = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LOOP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LIST = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_TYPE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_WHEN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_WRAP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_TEXT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_PATH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_PING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REFX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REFY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SIZE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SEED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ROWS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SPAN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STEP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ROLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_XREF = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ASYNC = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ALINK = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ALIGN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CLOSE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_COLOR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CLASS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CLEAR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_BEGIN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DEPTH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DEFER = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FENCE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FRAME = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ISMAP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONEND = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_INDEX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ORDER = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_OTHER = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONCUT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_NARGS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MEDIA = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LABEL = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LOCAL = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_WIDTH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_TITLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VLINK = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VALUE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SLOPE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SHAPE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SCOPE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SCALE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SPEED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STYLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_RULES = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STEMH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SIZES = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STEMV = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_START = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_XMLNS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ACCEPT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ACCENT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ASCENT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ACTIVE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ALTIMG = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ACTION = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_BORDER = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CURSOR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_COORDS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FILTER = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FORMAT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_HIDDEN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_HSPACE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_HEIGHT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONMOVE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONLOAD = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONDRAG = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ORIGIN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONZOOM = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONHELP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONSTOP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONDROP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONBLUR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_OBJECT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_OFFSET = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ORIENT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONCOPY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_NOWRAP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_NOHREF = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MACROS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_METHOD = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LOWSRC = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LSPACE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LQUOTE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_USEMAP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_WIDTHS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_TARGET = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VALUES = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VALIGN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VSPACE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_POSTER = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_POINTS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_PROMPT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SRCDOC = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SCOPED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STRING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SCHEME = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STROKE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_RADIUS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_RESULT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REPEAT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SRCSET = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_RSPACE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ROTATE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_RQUOTE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ALTTEXT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARCHIVE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_AZIMUTH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CLOSURE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CHECKED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CLASSID = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CHAROFF = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_BGCOLOR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_COLSPAN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CHARSET = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_COMPACT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CONTENT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ENCTYPE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DATASRC = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DATAFLD = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DECLARE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DISPLAY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DIVISOR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DEFAULT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DESCENT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_KERNING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_HANGING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_HEADERS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONPASTE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONCLICK = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_OPTIMUM = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONBEGIN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONKEYUP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONFOCUS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONERROR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONINPUT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONABORT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONSTART = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONRESET = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_OPACITY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_NOSHADE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MINSIZE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MAXSIZE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LARGEOP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_UNICODE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_TARGETX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_TARGETY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VIEWBOX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VERSION = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_PATTERN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_PROFILE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SPACING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_RESTART = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ROWSPAN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SANDBOX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SUMMARY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STANDBY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REPLACE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_AUTOPLAY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ADDITIVE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CALCMODE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CODETYPE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CODEBASE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CONTROLS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_BEVELLED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_BASELINE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_EXPONENT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_EDGEMODE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ENCODING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_GLYPHREF = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DATETIME = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DISABLED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FONTSIZE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_KEYTIMES = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_PANOSE_1 = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_HREFLANG = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONRESIZE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONCHANGE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONBOUNCE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONUNLOAD = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONFINISH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONSCROLL = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_OPERATOR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_OVERFLOW = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONSUBMIT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONREPEAT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONSELECT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_NOTATION = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_NORESIZE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MANIFEST = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MATHSIZE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MULTIPLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LONGDESC = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LANGUAGE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_TEMPLATE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_TABINDEX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_PROPERTY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_READONLY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SELECTED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ROWLINES = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SEAMLESS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ROWALIGN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STRETCHY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REQUIRED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_XML_BASE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_XML_LANG = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_X_HEIGHT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_OWNS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_AUTOFOCUS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_SORT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ACCESSKEY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_BUSY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_GRAB = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_AMPLITUDE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_LIVE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CLIP_RULE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CLIP_PATH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_EQUALROWS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ELEVATION = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DIRECTION = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DRAGGABLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FILL_RULE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FONTSTYLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FONT_SIZE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_KEYSYSTEM = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_KEYPOINTS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_HIDEFOCUS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONMESSAGE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_INTERCEPT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONDRAGEND = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONMOVEEND = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONINVALID = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_INTEGRITY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONKEYDOWN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONFOCUSIN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONMOUSEUP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_INPUTMODE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONROWEXIT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MATHCOLOR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MASKUNITS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MAXLENGTH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LINEBREAK = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_TRANSFORM = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_V_HANGING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VALUETYPE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_POINTSATZ = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_POINTSATX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_POINTSATY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SYMMETRIC = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SCROLLING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REPEATDUR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SELECTION = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SEPARATOR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_XML_SPACE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_AUTOSUBMIT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ALPHABETIC = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ACTIONTYPE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ACCUMULATE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_LEVEL = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_COLUMNSPAN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CAP_HEIGHT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_BACKGROUND = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_GLYPH_NAME = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_GROUPALIGN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FONTFAMILY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FONTWEIGHT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FONT_STYLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_KEYSPLINES = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_HTTP_EQUIV = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONACTIVATE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_OCCURRENCE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_IRRELEVANT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONDBLCLICK = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONDRAGDROP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONKEYPRESS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONROWENTER = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONDRAGOVER = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONFOCUSOUT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONMOUSEOUT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_NUMOCTAVES = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MARKER_MID = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MARKER_END = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_TEXTLENGTH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VISIBILITY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VIEWTARGET = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VERT_ADV_Y = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_PATHLENGTH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REPEAT_MAX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_RADIOGROUP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STOP_COLOR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SEPARATORS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REPEAT_MIN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ROWSPACING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ZOOMANDPAN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_XLINK_TYPE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_XLINK_ROLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_XLINK_HREF = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_XLINK_SHOW = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ACCENTUNDER = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_SECRET = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_ATOMIC = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_HIDDEN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_FLOWTO = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARABIC_FORM = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CELLPADDING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CELLSPACING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_COLUMNWIDTH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CROSSORIGIN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_COLUMNALIGN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_COLUMNLINES = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CONTEXTMENU = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_BASEPROFILE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FONT_FAMILY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FRAMEBORDER = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FILTERUNITS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FLOOD_COLOR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FONT_WEIGHT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_HORIZ_ADV_X = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONDRAGLEAVE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONMOUSEMOVE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ORIENTATION = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONMOUSEDOWN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONMOUSEOVER = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONDRAGENTER = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_IDEOGRAPHIC = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONBEFORECUT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONFORMINPUT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONDRAGSTART = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONMOVESTART = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MARKERUNITS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MATHVARIANT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MARGINWIDTH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MARKERWIDTH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_TEXT_ANCHOR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_TABLEVALUES = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SCRIPTLEVEL = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REPEATCOUNT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STITCHTILES = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STARTOFFSET = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SCROLLDELAY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_XMLNS_XLINK = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_XLINK_TITLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_INVALID = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_PRESSED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_CHECKED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_AUTOCOMPLETE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_SETSIZE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_CHANNEL = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_EQUALCOLUMNS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DISPLAYSTYLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DATAFORMATAS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FILL_OPACITY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FONT_VARIANT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FONT_STRETCH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FRAMESPACING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_KERNELMATRIX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONDEACTIVATE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONROWSDELETE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONMOUSELEAVE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONFORMCHANGE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONCELLCHANGE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONMOUSEWHEEL = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONMOUSEENTER = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONAFTERPRINT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONBEFORECOPY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MARGINHEIGHT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MARKERHEIGHT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MARKER_START = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MATHEMATICAL = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LENGTHADJUST = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_UNSELECTABLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_UNICODE_BIDI = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_UNITS_PER_EM = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_WORD_SPACING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_WRITING_MODE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_V_ALPHABETIC = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_PATTERNUNITS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SPREADMETHOD = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SURFACESCALE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STROKE_WIDTH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REPEAT_START = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STDDEVIATION = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STOP_OPACITY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_CONTROLS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_HASPOPUP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ACCENT_HEIGHT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_VALUENOW = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_RELEVANT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_POSINSET = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_VALUEMAX = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_READONLY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_SELECTED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_REQUIRED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_EXPANDED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_DISABLED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ATTRIBUTETYPE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ATTRIBUTENAME = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_DATATYPE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_VALUEMIN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_BASEFREQUENCY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_COLUMNSPACING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_COLOR_PROFILE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CLIPPATHUNITS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DEFINITIONURL = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_GRADIENTUNITS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FLOOD_OPACITY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONAFTERUPDATE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONERRORUPDATE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONBEFOREPASTE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONLOSECAPTURE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONCONTEXTMENU = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONSELECTSTART = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONBEFOREPRINT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MOVABLELIMITS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LINETHICKNESS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_UNICODE_RANGE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_THINMATHSPACE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VERT_ORIGIN_X = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VERT_ORIGIN_Y = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_V_IDEOGRAPHIC = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_PRESERVEALPHA = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SCRIPTMINSIZE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SPECIFICATION = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_XLINK_ACTUATE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_XLINK_ARCROLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ACCEPT_CHARSET = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ALIGNMENTSCOPE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_MULTILINE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_BASELINE_SHIFT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_HORIZ_ORIGIN_X = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_HORIZ_ORIGIN_Y = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONBEFOREUPDATE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONFILTERCHANGE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONROWSINSERTED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONBEFOREUNLOAD = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MATHBACKGROUND = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LETTER_SPACING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LIGHTING_COLOR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_THICKMATHSPACE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_TEXT_RENDERING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_V_MATHEMATICAL = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_POINTER_EVENTS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_PRIMITIVEUNITS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REFERRERPOLICY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SYSTEMLANGUAGE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STROKE_LINECAP = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SUBSCRIPTSHIFT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STROKE_OPACITY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_DROPEFFECT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_LABELLEDBY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_TEMPLATEID = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_COLOR_RENDERING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_CONTENTEDITABLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DIFFUSECONSTANT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONDATAAVAILABLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONCONTROLSELECT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_IMAGE_RENDERING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MEDIUMMATHSPACE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_TEXT_DECORATION = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SHAPE_RENDERING = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STROKE_LINEJOIN = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REPEAT_TEMPLATE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_DESCRIBEDBY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_FONT_SIZE_ADJUST = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_KERNELUNITLENGTH = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONBEFOREACTIVATE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONPROPERTYCHANGE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONDATASETCHANGED = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_MASKCONTENTUNITS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_PATTERNTRANSFORM = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REQUIREDFEATURES = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_RENDERING_INTENT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SPECULAREXPONENT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SPECULARCONSTANT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SUPERSCRIPTSHIFT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STROKE_DASHARRAY = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_XCHANNELSELECTOR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_YCHANNELSELECTOR = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_AUTOCOMPLETE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ENABLE_BACKGROUND = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_DOMINANT_BASELINE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_GRADIENTTRANSFORM = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONBEFORDEACTIVATE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONDATASETCOMPLETE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_OVERLINE_POSITION = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONBEFOREEDITFOCUS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_LIMITINGCONEANGLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VERYTHINMATHSPACE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STROKE_DASHOFFSET = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STROKE_MITERLIMIT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ALIGNMENT_BASELINE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ONREADYSTATECHANGE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_OVERLINE_THICKNESS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_UNDERLINE_POSITION = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VERYTHICKMATHSPACE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_REQUIREDEXTENSIONS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_COLOR_INTERPOLATION = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_UNDERLINE_THICKNESS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_PRESERVEASPECTRATIO = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_PATTERNCONTENTUNITS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_MULTISELECTABLE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_SCRIPTSIZEMULTIPLIER = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_ARIA_ACTIVEDESCENDANT = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VERYVERYTHINMATHSPACE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_VERYVERYTHICKMATHSPACE = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STRIKETHROUGH_POSITION = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_STRIKETHROUGH_THICKNESS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_GLYPH_ORIENTATION_VERTICAL = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_COLOR_INTERPOLATION_FILTERS = nullptr;
+nsHtml5AttributeName* nsHtml5AttributeName::ATTR_GLYPH_ORIENTATION_HORIZONTAL = nullptr;
+nsHtml5AttributeName** nsHtml5AttributeName::ATTRIBUTE_NAMES = 0;
+static int32_t const ATTRIBUTE_HASHES_DATA[] = { 1153, 1383, 1601, 1793, 1827, 1857, 68600, 69146, 69177, 70237, 70270, 71572, 71669, 72415, 72444, 74846, 74904, 74943, 75001, 75276, 75590, 84742, 84839, 85575, 85963, 85992, 87204, 88074, 88171, 89130, 89163, 3207892, 3283895, 3284791, 3338752, 3358197, 3369562, 3539124, 3562402, 3574260, 3670335, 3696933, 3721879, 135280021, 135346322, 136317019, 136475749, 136548517, 136652214, 136884919, 136902418, 136942992, 137292068, 139120259, 139785574, 142250603, 142314056, 142331176, 142519584, 144752417, 145106895, 146147200, 146765926, 148805544, 149655723, 149809441, 150018784, 150445028, 150813181, 150923321, 152528754, 152536216, 152647366, 152962785, 155219321, 155654904, 157317483, 157350248, 157437941, 157447478, 157604838, 157685404, 157894402, 158315188, 166078431, 169409980, 169700259, 169856932, 170007032, 170409695, 170466488, 170513710, 170608367, 173028944, 173896963, 176090625, 176129212, 179390001, 179489057, 179627464, 179840468, 179849042, 180004216, 181779081, 183027151, 183645319, 183698797, 185922012, 185997252, 188312483, 188675799, 190977533, 190992569, 191006194, 191033518, 191038774, 191096249, 191166163, 191194426, 191443343, 191522106, 191568039, 200104642, 202506661, 202537381, 202602917, 203070590, 203120766, 203389054, 203690071, 203971238, 203986524, 209040857, 209125756, 212055489, 212322418, 212746849, 213002877, 213055164, 213088023, 213259873, 213273386, 213435118, 213437318, 213438231, 213493071, 213532268, 213542834, 213584431, 213659891, 215285828, 215880731, 216112976, 216684637, 217369699, 217565298, 217576549, 218186795, 219743185, 220082234, 221623802, 221986406, 222283890, 223089542, 223138630, 223311265, 224431494, 224547358, 224587256, 224589550, 224655650, 224785518, 224810917, 224813302, 225126263, 225429618, 225432950, 225440869, 236107233, 236709921, 236838947, 237117095, 237143271, 237172455, 237209953, 237354143, 237372743, 237668065, 237703073, 237714273, 239743521, 240512803, 240522627, 240560417, 240656513, 241015715, 241062755, 241065383, 243523041, 245865199, 246261793, 246556195, 246774817, 246923491, 246928419, 246981667, 247014847, 247058369, 247112833, 247118177, 247119137, 247128739, 247316903, 249533729, 250235623, 250269543, 251402351, 252339047, 253260911, 253293679, 254844367, 255547879, 256077281, 256345377, 258124199, 258354465, 258605063, 258744193, 258845603, 258856961, 258926689, 269869248, 270174334, 270709417, 270778994, 270781796, 271102503, 271478858, 271490090, 272870654, 273335275, 273369140, 273924313, 274108530, 274116736, 276818662, 277476156, 279156579, 279349675, 280108533, 280128712, 280132869, 280162403, 280280292, 280413430, 280506130, 280677397, 280678580, 280686710, 280689066, 282736758, 283110901, 283275116, 283823226, 283890012, 284479340, 284606461, 286700477, 286798916, 290055764, 291557706, 291665349, 291804100, 292138018, 292166446, 292418738, 292451039, 300298041, 300374839, 300597935, 303073389, 303083839, 303266673, 303354997, 303430688, 303576261, 303724281, 303819694, 304242723, 304382625, 306247792, 307227811, 307468786, 307724489, 310252031, 310358241, 310373094, 310833159, 311015256, 313357609, 313683893, 313701861, 313706996, 313707317, 313710350, 313795700, 314027746, 314038181, 314091299, 314205627, 314233813, 316741830, 316797986, 317486755, 317794164, 320076137, 322657125, 322887778, 323506876, 323572412, 323605180, 325060058, 325320188, 325398738, 325541490, 325671619, 333868843, 336806130, 337212108, 337282686, 337285434, 337585223, 338036037, 338298087, 338566051, 340943551, 341190970, 342995704, 343352124, 343912673, 344585053, 346977248, 347218098, 347262163, 347278576, 347438191, 347655959, 347684788, 347726430, 347727772, 347776035, 347776629, 349500753, 350880161, 350887073, 353384123, 355496998, 355906922, 355979793, 356545959, 358637867, 358905016, 359164318, 359247286, 359350571, 359579447, 365560330, 367399355, 367420285, 367510727, 368013212, 370234760, 370353345, 370710317, 371074566, 371122285, 371194213, 371448425, 371448430, 371545055, 371593469, 371596922, 371758751, 371964792, 372151328, 376550136, 376710172, 376795771, 376826271, 376906556, 380514830, 380774774, 380775037, 381030322, 381136500, 381281631, 381282269, 381285504, 381330595, 381331422, 381335911, 381336484, 383907298, 383917408, 384595009, 384595013, 387799894, 387823201, 392581647, 392584937, 392742684, 392906485, 393003349, 400644707, 400973830, 404428547, 404432113, 404432865, 404469244, 404478897, 404694860, 406887479, 408294949, 408789955, 410022510, 410467324, 410586448, 410945965, 411845275, 414327152, 414327932, 414329781, 414346257, 414346439, 414639928, 414835998, 414894517, 414986533, 417465377, 417465381, 417492216, 418259232, 419310946, 420103495, 420242342, 420380455, 420658662, 420717432, 423183880, 424539259, 425929170, 425972964, 426050649, 426126450, 426142833, 426607922, 437289840, 437347469, 437412335, 437423943, 437455540, 437462252, 437597991, 437617485, 437986305, 437986507, 437986828, 437987072, 438015591, 438034813, 438038966, 438179623, 438347971, 438483573, 438547062, 438895551, 441592676, 442032555, 443548979, 447881379, 447881655, 447881895, 447887844, 448416189, 448445746, 448449012, 450942191, 452816744, 453668677, 454434495, 456610076, 456642844, 456738709, 457544600, 459451897, 459680944, 468058810, 468083581, 470964084, 471470955, 471567278, 472267822, 481177859, 481210627, 481435874, 481455115, 481485378, 481490218, 485105638, 486005878, 486383494, 487988916, 488103783, 490661867, 491574090, 491578272, 492891370, 493041952, 493441205, 493582844, 493716979, 504577572, 504740359, 505091638, 505592418, 505656212, 509516275, 514998531, 515571132, 515594682, 518712698, 521362273, 526592419, 526807354, 527348842, 538294791, 544689535, 545535009, 548544752, 548563346, 548595116, 551679010, 558034099, 560329411, 560356209, 560671018, 560671152, 560692590, 560845442, 569212097, 569474241, 572252718, 575326764, 576174758, 576190819, 582099184, 582099438, 582372519, 582558889, 586552164, 591325418, 594231990, 594243961, 605711268, 615672071, 616086845, 621792370, 624879850, 627432831, 640040548, 654392808, 658675477, 659420283, 672891587, 694768102, 705890982, 725543146, 759097578, 761686526, 795383908, 878105336, 908643300, 945213471 };
+staticJArray<int32_t,int32_t> nsHtml5AttributeName::ATTRIBUTE_HASHES = { ATTRIBUTE_HASHES_DATA, MOZ_ARRAY_LENGTH(ATTRIBUTE_HASHES_DATA) };
+void
+nsHtml5AttributeName::initializeStatics()
+{
+ ALL_NO_NS = new int32_t[3];
+ ALL_NO_NS[0] = kNameSpaceID_None;
+ ALL_NO_NS[1] = kNameSpaceID_None;
+ ALL_NO_NS[2] = kNameSpaceID_None;
+ XMLNS_NS = new int32_t[3];
+ XMLNS_NS[0] = kNameSpaceID_None;
+ XMLNS_NS[1] = kNameSpaceID_XMLNS;
+ XMLNS_NS[2] = kNameSpaceID_XMLNS;
+ XML_NS = new int32_t[3];
+ XML_NS[0] = kNameSpaceID_None;
+ XML_NS[1] = kNameSpaceID_XML;
+ XML_NS[2] = kNameSpaceID_XML;
+ XLINK_NS = new int32_t[3];
+ XLINK_NS[0] = kNameSpaceID_None;
+ XLINK_NS[1] = kNameSpaceID_XLink;
+ XLINK_NS[2] = kNameSpaceID_XLink;
+ ALL_NO_PREFIX = new nsIAtom*[3];
+ ALL_NO_PREFIX[0] = nullptr;
+ ALL_NO_PREFIX[1] = nullptr;
+ ALL_NO_PREFIX[2] = nullptr;
+ XMLNS_PREFIX = new nsIAtom*[3];
+ XMLNS_PREFIX[0] = nullptr;
+ XMLNS_PREFIX[1] = nsHtml5Atoms::xmlns;
+ XMLNS_PREFIX[2] = nsHtml5Atoms::xmlns;
+ XLINK_PREFIX = new nsIAtom*[3];
+ XLINK_PREFIX[0] = nullptr;
+ XLINK_PREFIX[1] = nsHtml5Atoms::xlink;
+ XLINK_PREFIX[2] = nsHtml5Atoms::xlink;
+ XML_PREFIX = new nsIAtom*[3];
+ XML_PREFIX[0] = nullptr;
+ XML_PREFIX[1] = nsHtml5Atoms::xml;
+ XML_PREFIX[2] = nsHtml5Atoms::xml;
+ ATTR_D = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::d), ALL_NO_PREFIX);
+ ATTR_K = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::k), ALL_NO_PREFIX);
+ ATTR_R = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::r), ALL_NO_PREFIX);
+ ATTR_X = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::x), ALL_NO_PREFIX);
+ ATTR_Y = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::y), ALL_NO_PREFIX);
+ ATTR_Z = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::z), ALL_NO_PREFIX);
+ ATTR_BY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::by), ALL_NO_PREFIX);
+ ATTR_CX = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::cx), ALL_NO_PREFIX);
+ ATTR_CY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::cy), ALL_NO_PREFIX);
+ ATTR_DX = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::dx), ALL_NO_PREFIX);
+ ATTR_DY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::dy), ALL_NO_PREFIX);
+ ATTR_G2 = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::g2), ALL_NO_PREFIX);
+ ATTR_G1 = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::g1), ALL_NO_PREFIX);
+ ATTR_FX = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::fx), ALL_NO_PREFIX);
+ ATTR_FY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::fy), ALL_NO_PREFIX);
+ ATTR_K4 = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::k4), ALL_NO_PREFIX);
+ ATTR_K2 = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::k2), ALL_NO_PREFIX);
+ ATTR_K3 = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::k3), ALL_NO_PREFIX);
+ ATTR_K1 = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::k1), ALL_NO_PREFIX);
+ ATTR_ID = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::id), ALL_NO_PREFIX);
+ ATTR_IN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::in), ALL_NO_PREFIX);
+ ATTR_U2 = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::u2), ALL_NO_PREFIX);
+ ATTR_U1 = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::u1), ALL_NO_PREFIX);
+ ATTR_RT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::rt), ALL_NO_PREFIX);
+ ATTR_RX = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::rx), ALL_NO_PREFIX);
+ ATTR_RY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ry), ALL_NO_PREFIX);
+ ATTR_TO = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::to), ALL_NO_PREFIX);
+ ATTR_Y2 = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::y2), ALL_NO_PREFIX);
+ ATTR_Y1 = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::y1), ALL_NO_PREFIX);
+ ATTR_X1 = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::x1), ALL_NO_PREFIX);
+ ATTR_X2 = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::x2), ALL_NO_PREFIX);
+ ATTR_ALT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::alt), ALL_NO_PREFIX);
+ ATTR_DIR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::dir), ALL_NO_PREFIX);
+ ATTR_DUR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::dur), ALL_NO_PREFIX);
+ ATTR_END = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::end), ALL_NO_PREFIX);
+ ATTR_FOR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::for_), ALL_NO_PREFIX);
+ ATTR_IN2 = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::in2), ALL_NO_PREFIX);
+ ATTR_MAX = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::max), ALL_NO_PREFIX);
+ ATTR_MIN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::min), ALL_NO_PREFIX);
+ ATTR_LOW = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::low), ALL_NO_PREFIX);
+ ATTR_REL = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::rel), ALL_NO_PREFIX);
+ ATTR_REV = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::rev), ALL_NO_PREFIX);
+ ATTR_SRC = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::src), ALL_NO_PREFIX);
+ ATTR_AXIS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::axis), ALL_NO_PREFIX);
+ ATTR_ABBR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::abbr), ALL_NO_PREFIX);
+ ATTR_BBOX = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::bbox), ALL_NO_PREFIX);
+ ATTR_CITE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::cite), ALL_NO_PREFIX);
+ ATTR_CODE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::code), ALL_NO_PREFIX);
+ ATTR_BIAS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::bias), ALL_NO_PREFIX);
+ ATTR_COLS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::cols), ALL_NO_PREFIX);
+ ATTR_CLIP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::clip), ALL_NO_PREFIX);
+ ATTR_CHAR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::char_), ALL_NO_PREFIX);
+ ATTR_BASE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::base), ALL_NO_PREFIX);
+ ATTR_EDGE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::edge), ALL_NO_PREFIX);
+ ATTR_DATA = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::data), ALL_NO_PREFIX);
+ ATTR_FILL = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::fill), ALL_NO_PREFIX);
+ ATTR_FROM = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::from), ALL_NO_PREFIX);
+ ATTR_FORM = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::form), ALL_NO_PREFIX);
+ ATTR_FACE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::face), ALL_NO_PREFIX);
+ ATTR_HIGH = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::high), ALL_NO_PREFIX);
+ ATTR_HREF = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::href), ALL_NO_PREFIX);
+ ATTR_OPEN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::open), ALL_NO_PREFIX);
+ ATTR_ICON = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::icon), ALL_NO_PREFIX);
+ ATTR_NAME = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::name), ALL_NO_PREFIX);
+ ATTR_MODE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::mode), ALL_NO_PREFIX);
+ ATTR_MASK = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::mask), ALL_NO_PREFIX);
+ ATTR_LINK = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::link), ALL_NO_PREFIX);
+ ATTR_LANG = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::lang), ALL_NO_PREFIX);
+ ATTR_LOOP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::loop), ALL_NO_PREFIX);
+ ATTR_LIST = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::list), ALL_NO_PREFIX);
+ ATTR_TYPE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::type), ALL_NO_PREFIX);
+ ATTR_WHEN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::when), ALL_NO_PREFIX);
+ ATTR_WRAP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::wrap), ALL_NO_PREFIX);
+ ATTR_TEXT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::text), ALL_NO_PREFIX);
+ ATTR_PATH = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::path), ALL_NO_PREFIX);
+ ATTR_PING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ping), ALL_NO_PREFIX);
+ ATTR_REFX = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::refx, nsHtml5Atoms::refX), ALL_NO_PREFIX);
+ ATTR_REFY = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::refy, nsHtml5Atoms::refY), ALL_NO_PREFIX);
+ ATTR_SIZE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::size), ALL_NO_PREFIX);
+ ATTR_SEED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::seed), ALL_NO_PREFIX);
+ ATTR_ROWS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::rows), ALL_NO_PREFIX);
+ ATTR_SPAN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::span), ALL_NO_PREFIX);
+ ATTR_STEP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::step), ALL_NO_PREFIX);
+ ATTR_ROLE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::role), ALL_NO_PREFIX);
+ ATTR_XREF = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::xref), ALL_NO_PREFIX);
+ ATTR_ASYNC = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::async), ALL_NO_PREFIX);
+ ATTR_ALINK = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::alink), ALL_NO_PREFIX);
+ ATTR_ALIGN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::align), ALL_NO_PREFIX);
+ ATTR_CLOSE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::close), ALL_NO_PREFIX);
+ ATTR_COLOR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::color), ALL_NO_PREFIX);
+ ATTR_CLASS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::class_), ALL_NO_PREFIX);
+ ATTR_CLEAR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::clear), ALL_NO_PREFIX);
+ ATTR_BEGIN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::begin), ALL_NO_PREFIX);
+ ATTR_DEPTH = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::depth), ALL_NO_PREFIX);
+ ATTR_DEFER = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::defer), ALL_NO_PREFIX);
+ ATTR_FENCE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::fence), ALL_NO_PREFIX);
+ ATTR_FRAME = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::frame), ALL_NO_PREFIX);
+ ATTR_ISMAP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ismap), ALL_NO_PREFIX);
+ ATTR_ONEND = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onend), ALL_NO_PREFIX);
+ ATTR_INDEX = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::index), ALL_NO_PREFIX);
+ ATTR_ORDER = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::order), ALL_NO_PREFIX);
+ ATTR_OTHER = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::other), ALL_NO_PREFIX);
+ ATTR_ONCUT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::oncut), ALL_NO_PREFIX);
+ ATTR_NARGS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::nargs), ALL_NO_PREFIX);
+ ATTR_MEDIA = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::media), ALL_NO_PREFIX);
+ ATTR_LABEL = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::label), ALL_NO_PREFIX);
+ ATTR_LOCAL = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::local), ALL_NO_PREFIX);
+ ATTR_WIDTH = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::width), ALL_NO_PREFIX);
+ ATTR_TITLE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::title), ALL_NO_PREFIX);
+ ATTR_VLINK = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::vlink), ALL_NO_PREFIX);
+ ATTR_VALUE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::value), ALL_NO_PREFIX);
+ ATTR_SLOPE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::slope), ALL_NO_PREFIX);
+ ATTR_SHAPE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::shape), ALL_NO_PREFIX);
+ ATTR_SCOPE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::scope), ALL_NO_PREFIX);
+ ATTR_SCALE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::scale), ALL_NO_PREFIX);
+ ATTR_SPEED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::speed), ALL_NO_PREFIX);
+ ATTR_STYLE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::style), ALL_NO_PREFIX);
+ ATTR_RULES = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::rules), ALL_NO_PREFIX);
+ ATTR_STEMH = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::stemh), ALL_NO_PREFIX);
+ ATTR_SIZES = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::sizes), ALL_NO_PREFIX);
+ ATTR_STEMV = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::stemv), ALL_NO_PREFIX);
+ ATTR_START = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::start), ALL_NO_PREFIX);
+ ATTR_XMLNS = new nsHtml5AttributeName(XMLNS_NS, SAME_LOCAL(nsHtml5Atoms::xmlns), ALL_NO_PREFIX);
+ ATTR_ACCEPT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::accept), ALL_NO_PREFIX);
+ ATTR_ACCENT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::accent), ALL_NO_PREFIX);
+ ATTR_ASCENT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ascent), ALL_NO_PREFIX);
+ ATTR_ACTIVE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::active), ALL_NO_PREFIX);
+ ATTR_ALTIMG = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::altimg), ALL_NO_PREFIX);
+ ATTR_ACTION = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::action), ALL_NO_PREFIX);
+ ATTR_BORDER = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::border), ALL_NO_PREFIX);
+ ATTR_CURSOR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::cursor), ALL_NO_PREFIX);
+ ATTR_COORDS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::coords), ALL_NO_PREFIX);
+ ATTR_FILTER = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::filter), ALL_NO_PREFIX);
+ ATTR_FORMAT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::format), ALL_NO_PREFIX);
+ ATTR_HIDDEN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::hidden), ALL_NO_PREFIX);
+ ATTR_HSPACE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::hspace), ALL_NO_PREFIX);
+ ATTR_HEIGHT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::height), ALL_NO_PREFIX);
+ ATTR_ONMOVE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onmove), ALL_NO_PREFIX);
+ ATTR_ONLOAD = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onload), ALL_NO_PREFIX);
+ ATTR_ONDRAG = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ondrag), ALL_NO_PREFIX);
+ ATTR_ORIGIN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::origin), ALL_NO_PREFIX);
+ ATTR_ONZOOM = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onzoom), ALL_NO_PREFIX);
+ ATTR_ONHELP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onhelp), ALL_NO_PREFIX);
+ ATTR_ONSTOP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onstop), ALL_NO_PREFIX);
+ ATTR_ONDROP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ondrop), ALL_NO_PREFIX);
+ ATTR_ONBLUR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onblur), ALL_NO_PREFIX);
+ ATTR_OBJECT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::object), ALL_NO_PREFIX);
+ ATTR_OFFSET = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::offset), ALL_NO_PREFIX);
+ ATTR_ORIENT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::orient), ALL_NO_PREFIX);
+ ATTR_ONCOPY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::oncopy), ALL_NO_PREFIX);
+ ATTR_NOWRAP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::nowrap), ALL_NO_PREFIX);
+ ATTR_NOHREF = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::nohref), ALL_NO_PREFIX);
+ ATTR_MACROS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::macros), ALL_NO_PREFIX);
+ ATTR_METHOD = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::method), ALL_NO_PREFIX);
+ ATTR_LOWSRC = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::lowsrc), ALL_NO_PREFIX);
+ ATTR_LSPACE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::lspace), ALL_NO_PREFIX);
+ ATTR_LQUOTE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::lquote), ALL_NO_PREFIX);
+ ATTR_USEMAP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::usemap), ALL_NO_PREFIX);
+ ATTR_WIDTHS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::widths), ALL_NO_PREFIX);
+ ATTR_TARGET = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::target), ALL_NO_PREFIX);
+ ATTR_VALUES = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::values), ALL_NO_PREFIX);
+ ATTR_VALIGN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::valign), ALL_NO_PREFIX);
+ ATTR_VSPACE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::vspace), ALL_NO_PREFIX);
+ ATTR_POSTER = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::poster), ALL_NO_PREFIX);
+ ATTR_POINTS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::points), ALL_NO_PREFIX);
+ ATTR_PROMPT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::prompt), ALL_NO_PREFIX);
+ ATTR_SRCDOC = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::srcdoc), ALL_NO_PREFIX);
+ ATTR_SCOPED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::scoped), ALL_NO_PREFIX);
+ ATTR_STRING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::string), ALL_NO_PREFIX);
+ ATTR_SCHEME = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::scheme), ALL_NO_PREFIX);
+ ATTR_STROKE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::stroke), ALL_NO_PREFIX);
+ ATTR_RADIUS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::radius), ALL_NO_PREFIX);
+ ATTR_RESULT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::result), ALL_NO_PREFIX);
+ ATTR_REPEAT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::repeat), ALL_NO_PREFIX);
+ ATTR_SRCSET = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::srcset), ALL_NO_PREFIX);
+ ATTR_RSPACE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::rspace), ALL_NO_PREFIX);
+ ATTR_ROTATE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::rotate), ALL_NO_PREFIX);
+ ATTR_RQUOTE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::rquote), ALL_NO_PREFIX);
+ ATTR_ALTTEXT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::alttext), ALL_NO_PREFIX);
+ ATTR_ARCHIVE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::archive), ALL_NO_PREFIX);
+ ATTR_AZIMUTH = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::azimuth), ALL_NO_PREFIX);
+ ATTR_CLOSURE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::closure), ALL_NO_PREFIX);
+ ATTR_CHECKED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::checked), ALL_NO_PREFIX);
+ ATTR_CLASSID = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::classid), ALL_NO_PREFIX);
+ ATTR_CHAROFF = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::charoff), ALL_NO_PREFIX);
+ ATTR_BGCOLOR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::bgcolor), ALL_NO_PREFIX);
+ ATTR_COLSPAN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::colspan), ALL_NO_PREFIX);
+ ATTR_CHARSET = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::charset), ALL_NO_PREFIX);
+ ATTR_COMPACT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::compact), ALL_NO_PREFIX);
+ ATTR_CONTENT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::content), ALL_NO_PREFIX);
+ ATTR_ENCTYPE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::enctype), ALL_NO_PREFIX);
+ ATTR_DATASRC = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::datasrc), ALL_NO_PREFIX);
+ ATTR_DATAFLD = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::datafld), ALL_NO_PREFIX);
+ ATTR_DECLARE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::declare), ALL_NO_PREFIX);
+ ATTR_DISPLAY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::display), ALL_NO_PREFIX);
+ ATTR_DIVISOR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::divisor), ALL_NO_PREFIX);
+ ATTR_DEFAULT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::default_), ALL_NO_PREFIX);
+ ATTR_DESCENT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::descent), ALL_NO_PREFIX);
+ ATTR_KERNING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::kerning), ALL_NO_PREFIX);
+ ATTR_HANGING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::hanging), ALL_NO_PREFIX);
+ ATTR_HEADERS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::headers), ALL_NO_PREFIX);
+ ATTR_ONPASTE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onpaste), ALL_NO_PREFIX);
+ ATTR_ONCLICK = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onclick), ALL_NO_PREFIX);
+ ATTR_OPTIMUM = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::optimum), ALL_NO_PREFIX);
+ ATTR_ONBEGIN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onbegin), ALL_NO_PREFIX);
+ ATTR_ONKEYUP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onkeyup), ALL_NO_PREFIX);
+ ATTR_ONFOCUS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onfocus), ALL_NO_PREFIX);
+ ATTR_ONERROR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onerror), ALL_NO_PREFIX);
+ ATTR_ONINPUT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::oninput), ALL_NO_PREFIX);
+ ATTR_ONABORT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onabort), ALL_NO_PREFIX);
+ ATTR_ONSTART = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onstart), ALL_NO_PREFIX);
+ ATTR_ONRESET = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onreset), ALL_NO_PREFIX);
+ ATTR_OPACITY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::opacity), ALL_NO_PREFIX);
+ ATTR_NOSHADE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::noshade), ALL_NO_PREFIX);
+ ATTR_MINSIZE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::minsize), ALL_NO_PREFIX);
+ ATTR_MAXSIZE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::maxsize), ALL_NO_PREFIX);
+ ATTR_LARGEOP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::largeop), ALL_NO_PREFIX);
+ ATTR_UNICODE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::unicode_), ALL_NO_PREFIX);
+ ATTR_TARGETX = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::targetx, nsHtml5Atoms::targetX), ALL_NO_PREFIX);
+ ATTR_TARGETY = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::targety, nsHtml5Atoms::targetY), ALL_NO_PREFIX);
+ ATTR_VIEWBOX = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::viewbox, nsHtml5Atoms::viewBox), ALL_NO_PREFIX);
+ ATTR_VERSION = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::version), ALL_NO_PREFIX);
+ ATTR_PATTERN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::pattern), ALL_NO_PREFIX);
+ ATTR_PROFILE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::profile), ALL_NO_PREFIX);
+ ATTR_SPACING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::spacing), ALL_NO_PREFIX);
+ ATTR_RESTART = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::restart), ALL_NO_PREFIX);
+ ATTR_ROWSPAN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::rowspan), ALL_NO_PREFIX);
+ ATTR_SANDBOX = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::sandbox), ALL_NO_PREFIX);
+ ATTR_SUMMARY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::summary), ALL_NO_PREFIX);
+ ATTR_STANDBY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::standby), ALL_NO_PREFIX);
+ ATTR_REPLACE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::replace), ALL_NO_PREFIX);
+ ATTR_AUTOPLAY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::autoplay), ALL_NO_PREFIX);
+ ATTR_ADDITIVE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::additive), ALL_NO_PREFIX);
+ ATTR_CALCMODE = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::calcmode, nsHtml5Atoms::calcMode), ALL_NO_PREFIX);
+ ATTR_CODETYPE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::codetype), ALL_NO_PREFIX);
+ ATTR_CODEBASE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::codebase), ALL_NO_PREFIX);
+ ATTR_CONTROLS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::controls), ALL_NO_PREFIX);
+ ATTR_BEVELLED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::bevelled), ALL_NO_PREFIX);
+ ATTR_BASELINE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::baseline), ALL_NO_PREFIX);
+ ATTR_EXPONENT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::exponent), ALL_NO_PREFIX);
+ ATTR_EDGEMODE = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::edgemode, nsHtml5Atoms::edgeMode), ALL_NO_PREFIX);
+ ATTR_ENCODING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::encoding), ALL_NO_PREFIX);
+ ATTR_GLYPHREF = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::glyphref, nsHtml5Atoms::glyphRef), ALL_NO_PREFIX);
+ ATTR_DATETIME = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::datetime), ALL_NO_PREFIX);
+ ATTR_DISABLED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::disabled), ALL_NO_PREFIX);
+ ATTR_FONTSIZE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::fontsize), ALL_NO_PREFIX);
+ ATTR_KEYTIMES = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::keytimes, nsHtml5Atoms::keyTimes), ALL_NO_PREFIX);
+ ATTR_PANOSE_1 = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::panose_1), ALL_NO_PREFIX);
+ ATTR_HREFLANG = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::hreflang), ALL_NO_PREFIX);
+ ATTR_ONRESIZE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onresize), ALL_NO_PREFIX);
+ ATTR_ONCHANGE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onchange), ALL_NO_PREFIX);
+ ATTR_ONBOUNCE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onbounce), ALL_NO_PREFIX);
+ ATTR_ONUNLOAD = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onunload), ALL_NO_PREFIX);
+ ATTR_ONFINISH = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onfinish), ALL_NO_PREFIX);
+ ATTR_ONSCROLL = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onscroll), ALL_NO_PREFIX);
+ ATTR_OPERATOR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::operator_), ALL_NO_PREFIX);
+ ATTR_OVERFLOW = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::overflow), ALL_NO_PREFIX);
+ ATTR_ONSUBMIT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onsubmit), ALL_NO_PREFIX);
+ ATTR_ONREPEAT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onrepeat), ALL_NO_PREFIX);
+ ATTR_ONSELECT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onselect), ALL_NO_PREFIX);
+ ATTR_NOTATION = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::notation), ALL_NO_PREFIX);
+ ATTR_NORESIZE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::noresize), ALL_NO_PREFIX);
+ ATTR_MANIFEST = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::manifest), ALL_NO_PREFIX);
+ ATTR_MATHSIZE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::mathsize), ALL_NO_PREFIX);
+ ATTR_MULTIPLE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::multiple), ALL_NO_PREFIX);
+ ATTR_LONGDESC = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::longdesc), ALL_NO_PREFIX);
+ ATTR_LANGUAGE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::language), ALL_NO_PREFIX);
+ ATTR_TEMPLATE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::template_), ALL_NO_PREFIX);
+ ATTR_TABINDEX = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::tabindex), ALL_NO_PREFIX);
+ ATTR_PROPERTY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::property), ALL_NO_PREFIX);
+ ATTR_READONLY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::readonly), ALL_NO_PREFIX);
+ ATTR_SELECTED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::selected), ALL_NO_PREFIX);
+ ATTR_ROWLINES = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::rowlines), ALL_NO_PREFIX);
+ ATTR_SEAMLESS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::seamless), ALL_NO_PREFIX);
+ ATTR_ROWALIGN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::rowalign), ALL_NO_PREFIX);
+ ATTR_STRETCHY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::stretchy), ALL_NO_PREFIX);
+ ATTR_REQUIRED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::required), ALL_NO_PREFIX);
+ ATTR_XML_BASE = new nsHtml5AttributeName(XML_NS, COLONIFIED_LOCAL(nsHtml5Atoms::xml_base, nsHtml5Atoms::base), XML_PREFIX);
+ ATTR_XML_LANG = new nsHtml5AttributeName(XML_NS, COLONIFIED_LOCAL(nsHtml5Atoms::xml_lang, nsHtml5Atoms::lang), XML_PREFIX);
+ ATTR_X_HEIGHT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::x_height), ALL_NO_PREFIX);
+ ATTR_ARIA_OWNS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_owns), ALL_NO_PREFIX);
+ ATTR_AUTOFOCUS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::autofocus), ALL_NO_PREFIX);
+ ATTR_ARIA_SORT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_sort), ALL_NO_PREFIX);
+ ATTR_ACCESSKEY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::accesskey), ALL_NO_PREFIX);
+ ATTR_ARIA_BUSY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_busy), ALL_NO_PREFIX);
+ ATTR_ARIA_GRAB = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_grab), ALL_NO_PREFIX);
+ ATTR_AMPLITUDE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::amplitude), ALL_NO_PREFIX);
+ ATTR_ARIA_LIVE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_live), ALL_NO_PREFIX);
+ ATTR_CLIP_RULE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::clip_rule), ALL_NO_PREFIX);
+ ATTR_CLIP_PATH = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::clip_path), ALL_NO_PREFIX);
+ ATTR_EQUALROWS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::equalrows), ALL_NO_PREFIX);
+ ATTR_ELEVATION = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::elevation), ALL_NO_PREFIX);
+ ATTR_DIRECTION = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::direction), ALL_NO_PREFIX);
+ ATTR_DRAGGABLE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::draggable), ALL_NO_PREFIX);
+ ATTR_FILL_RULE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::fill_rule), ALL_NO_PREFIX);
+ ATTR_FONTSTYLE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::fontstyle), ALL_NO_PREFIX);
+ ATTR_FONT_SIZE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::font_size), ALL_NO_PREFIX);
+ ATTR_KEYSYSTEM = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::keysystem), ALL_NO_PREFIX);
+ ATTR_KEYPOINTS = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::keypoints, nsHtml5Atoms::keyPoints), ALL_NO_PREFIX);
+ ATTR_HIDEFOCUS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::hidefocus), ALL_NO_PREFIX);
+ ATTR_ONMESSAGE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onmessage), ALL_NO_PREFIX);
+ ATTR_INTERCEPT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::intercept), ALL_NO_PREFIX);
+ ATTR_ONDRAGEND = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ondragend), ALL_NO_PREFIX);
+ ATTR_ONMOVEEND = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onmoveend), ALL_NO_PREFIX);
+ ATTR_ONINVALID = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::oninvalid), ALL_NO_PREFIX);
+ ATTR_INTEGRITY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::integrity), ALL_NO_PREFIX);
+ ATTR_ONKEYDOWN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onkeydown), ALL_NO_PREFIX);
+ ATTR_ONFOCUSIN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onfocusin), ALL_NO_PREFIX);
+ ATTR_ONMOUSEUP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onmouseup), ALL_NO_PREFIX);
+ ATTR_INPUTMODE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::inputmode), ALL_NO_PREFIX);
+ ATTR_ONROWEXIT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onrowexit), ALL_NO_PREFIX);
+ ATTR_MATHCOLOR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::mathcolor), ALL_NO_PREFIX);
+ ATTR_MASKUNITS = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::maskunits, nsHtml5Atoms::maskUnits), ALL_NO_PREFIX);
+ ATTR_MAXLENGTH = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::maxlength), ALL_NO_PREFIX);
+ ATTR_LINEBREAK = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::linebreak), ALL_NO_PREFIX);
+ ATTR_TRANSFORM = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::transform), ALL_NO_PREFIX);
+ ATTR_V_HANGING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::v_hanging), ALL_NO_PREFIX);
+ ATTR_VALUETYPE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::valuetype), ALL_NO_PREFIX);
+ ATTR_POINTSATZ = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::pointsatz, nsHtml5Atoms::pointsAtZ), ALL_NO_PREFIX);
+ ATTR_POINTSATX = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::pointsatx, nsHtml5Atoms::pointsAtX), ALL_NO_PREFIX);
+ ATTR_POINTSATY = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::pointsaty, nsHtml5Atoms::pointsAtY), ALL_NO_PREFIX);
+ ATTR_SYMMETRIC = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::symmetric), ALL_NO_PREFIX);
+ ATTR_SCROLLING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::scrolling), ALL_NO_PREFIX);
+ ATTR_REPEATDUR = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::repeatdur, nsHtml5Atoms::repeatDur), ALL_NO_PREFIX);
+ ATTR_SELECTION = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::selection), ALL_NO_PREFIX);
+ ATTR_SEPARATOR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::separator), ALL_NO_PREFIX);
+ ATTR_XML_SPACE = new nsHtml5AttributeName(XML_NS, COLONIFIED_LOCAL(nsHtml5Atoms::xml_space, nsHtml5Atoms::space), XML_PREFIX);
+ ATTR_AUTOSUBMIT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::autosubmit), ALL_NO_PREFIX);
+ ATTR_ALPHABETIC = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::alphabetic), ALL_NO_PREFIX);
+ ATTR_ACTIONTYPE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::actiontype), ALL_NO_PREFIX);
+ ATTR_ACCUMULATE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::accumulate), ALL_NO_PREFIX);
+ ATTR_ARIA_LEVEL = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_level), ALL_NO_PREFIX);
+ ATTR_COLUMNSPAN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::columnspan), ALL_NO_PREFIX);
+ ATTR_CAP_HEIGHT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::cap_height), ALL_NO_PREFIX);
+ ATTR_BACKGROUND = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::background), ALL_NO_PREFIX);
+ ATTR_GLYPH_NAME = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::glyph_name), ALL_NO_PREFIX);
+ ATTR_GROUPALIGN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::groupalign), ALL_NO_PREFIX);
+ ATTR_FONTFAMILY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::fontfamily), ALL_NO_PREFIX);
+ ATTR_FONTWEIGHT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::fontweight), ALL_NO_PREFIX);
+ ATTR_FONT_STYLE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::font_style), ALL_NO_PREFIX);
+ ATTR_KEYSPLINES = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::keysplines, nsHtml5Atoms::keySplines), ALL_NO_PREFIX);
+ ATTR_HTTP_EQUIV = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::http_equiv), ALL_NO_PREFIX);
+ ATTR_ONACTIVATE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onactivate), ALL_NO_PREFIX);
+ ATTR_OCCURRENCE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::occurrence), ALL_NO_PREFIX);
+ ATTR_IRRELEVANT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::irrelevant), ALL_NO_PREFIX);
+ ATTR_ONDBLCLICK = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ondblclick), ALL_NO_PREFIX);
+ ATTR_ONDRAGDROP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ondragdrop), ALL_NO_PREFIX);
+ ATTR_ONKEYPRESS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onkeypress), ALL_NO_PREFIX);
+ ATTR_ONROWENTER = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onrowenter), ALL_NO_PREFIX);
+ ATTR_ONDRAGOVER = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ondragover), ALL_NO_PREFIX);
+ ATTR_ONFOCUSOUT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onfocusout), ALL_NO_PREFIX);
+ ATTR_ONMOUSEOUT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onmouseout), ALL_NO_PREFIX);
+ ATTR_NUMOCTAVES = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::numoctaves, nsHtml5Atoms::numOctaves), ALL_NO_PREFIX);
+ ATTR_MARKER_MID = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::marker_mid), ALL_NO_PREFIX);
+ ATTR_MARKER_END = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::marker_end), ALL_NO_PREFIX);
+ ATTR_TEXTLENGTH = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::textlength, nsHtml5Atoms::textLength), ALL_NO_PREFIX);
+ ATTR_VISIBILITY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::visibility), ALL_NO_PREFIX);
+ ATTR_VIEWTARGET = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::viewtarget, nsHtml5Atoms::viewTarget), ALL_NO_PREFIX);
+ ATTR_VERT_ADV_Y = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::vert_adv_y), ALL_NO_PREFIX);
+ ATTR_PATHLENGTH = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::pathlength, nsHtml5Atoms::pathLength), ALL_NO_PREFIX);
+ ATTR_REPEAT_MAX = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::repeat_max), ALL_NO_PREFIX);
+ ATTR_RADIOGROUP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::radiogroup), ALL_NO_PREFIX);
+ ATTR_STOP_COLOR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::stop_color), ALL_NO_PREFIX);
+ ATTR_SEPARATORS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::separators), ALL_NO_PREFIX);
+ ATTR_REPEAT_MIN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::repeat_min), ALL_NO_PREFIX);
+ ATTR_ROWSPACING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::rowspacing), ALL_NO_PREFIX);
+ ATTR_ZOOMANDPAN = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::zoomandpan, nsHtml5Atoms::zoomAndPan), ALL_NO_PREFIX);
+ ATTR_XLINK_TYPE = new nsHtml5AttributeName(XLINK_NS, COLONIFIED_LOCAL(nsHtml5Atoms::xlink_type, nsHtml5Atoms::type), XLINK_PREFIX);
+ ATTR_XLINK_ROLE = new nsHtml5AttributeName(XLINK_NS, COLONIFIED_LOCAL(nsHtml5Atoms::xlink_role, nsHtml5Atoms::role), XLINK_PREFIX);
+ ATTR_XLINK_HREF = new nsHtml5AttributeName(XLINK_NS, COLONIFIED_LOCAL(nsHtml5Atoms::xlink_href, nsHtml5Atoms::href), XLINK_PREFIX);
+ ATTR_XLINK_SHOW = new nsHtml5AttributeName(XLINK_NS, COLONIFIED_LOCAL(nsHtml5Atoms::xlink_show, nsHtml5Atoms::show), XLINK_PREFIX);
+ ATTR_ACCENTUNDER = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::accentunder), ALL_NO_PREFIX);
+ ATTR_ARIA_SECRET = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_secret), ALL_NO_PREFIX);
+ ATTR_ARIA_ATOMIC = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_atomic), ALL_NO_PREFIX);
+ ATTR_ARIA_HIDDEN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_hidden), ALL_NO_PREFIX);
+ ATTR_ARIA_FLOWTO = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_flowto), ALL_NO_PREFIX);
+ ATTR_ARABIC_FORM = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::arabic_form), ALL_NO_PREFIX);
+ ATTR_CELLPADDING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::cellpadding), ALL_NO_PREFIX);
+ ATTR_CELLSPACING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::cellspacing), ALL_NO_PREFIX);
+ ATTR_COLUMNWIDTH = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::columnwidth), ALL_NO_PREFIX);
+ ATTR_CROSSORIGIN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::crossorigin), ALL_NO_PREFIX);
+ ATTR_COLUMNALIGN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::columnalign), ALL_NO_PREFIX);
+ ATTR_COLUMNLINES = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::columnlines), ALL_NO_PREFIX);
+ ATTR_CONTEXTMENU = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::contextmenu), ALL_NO_PREFIX);
+ ATTR_BASEPROFILE = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::baseprofile, nsHtml5Atoms::baseProfile), ALL_NO_PREFIX);
+ ATTR_FONT_FAMILY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::font_family), ALL_NO_PREFIX);
+ ATTR_FRAMEBORDER = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::frameborder), ALL_NO_PREFIX);
+ ATTR_FILTERUNITS = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::filterunits, nsHtml5Atoms::filterUnits), ALL_NO_PREFIX);
+ ATTR_FLOOD_COLOR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::flood_color), ALL_NO_PREFIX);
+ ATTR_FONT_WEIGHT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::font_weight), ALL_NO_PREFIX);
+ ATTR_HORIZ_ADV_X = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::horiz_adv_x), ALL_NO_PREFIX);
+ ATTR_ONDRAGLEAVE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ondragleave), ALL_NO_PREFIX);
+ ATTR_ONMOUSEMOVE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onmousemove), ALL_NO_PREFIX);
+ ATTR_ORIENTATION = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::orientation), ALL_NO_PREFIX);
+ ATTR_ONMOUSEDOWN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onmousedown), ALL_NO_PREFIX);
+ ATTR_ONMOUSEOVER = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onmouseover), ALL_NO_PREFIX);
+ ATTR_ONDRAGENTER = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ondragenter), ALL_NO_PREFIX);
+ ATTR_IDEOGRAPHIC = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ideographic), ALL_NO_PREFIX);
+ ATTR_ONBEFORECUT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onbeforecut), ALL_NO_PREFIX);
+ ATTR_ONFORMINPUT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onforminput), ALL_NO_PREFIX);
+ ATTR_ONDRAGSTART = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ondragstart), ALL_NO_PREFIX);
+ ATTR_ONMOVESTART = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onmovestart), ALL_NO_PREFIX);
+ ATTR_MARKERUNITS = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::markerunits, nsHtml5Atoms::markerUnits), ALL_NO_PREFIX);
+ ATTR_MATHVARIANT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::mathvariant), ALL_NO_PREFIX);
+ ATTR_MARGINWIDTH = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::marginwidth), ALL_NO_PREFIX);
+ ATTR_MARKERWIDTH = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::markerwidth, nsHtml5Atoms::markerWidth), ALL_NO_PREFIX);
+ ATTR_TEXT_ANCHOR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::text_anchor), ALL_NO_PREFIX);
+ ATTR_TABLEVALUES = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::tablevalues, nsHtml5Atoms::tableValues), ALL_NO_PREFIX);
+ ATTR_SCRIPTLEVEL = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::scriptlevel), ALL_NO_PREFIX);
+ ATTR_REPEATCOUNT = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::repeatcount, nsHtml5Atoms::repeatCount), ALL_NO_PREFIX);
+ ATTR_STITCHTILES = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::stitchtiles, nsHtml5Atoms::stitchTiles), ALL_NO_PREFIX);
+ ATTR_STARTOFFSET = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::startoffset, nsHtml5Atoms::startOffset), ALL_NO_PREFIX);
+ ATTR_SCROLLDELAY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::scrolldelay), ALL_NO_PREFIX);
+ ATTR_XMLNS_XLINK = new nsHtml5AttributeName(XMLNS_NS, COLONIFIED_LOCAL(nsHtml5Atoms::xmlns_xlink, nsHtml5Atoms::xlink), XMLNS_PREFIX);
+ ATTR_XLINK_TITLE = new nsHtml5AttributeName(XLINK_NS, COLONIFIED_LOCAL(nsHtml5Atoms::xlink_title, nsHtml5Atoms::title), XLINK_PREFIX);
+ ATTR_ARIA_INVALID = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_invalid), ALL_NO_PREFIX);
+ ATTR_ARIA_PRESSED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_pressed), ALL_NO_PREFIX);
+ ATTR_ARIA_CHECKED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_checked), ALL_NO_PREFIX);
+ ATTR_AUTOCOMPLETE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::autocomplete), ALL_NO_PREFIX);
+ ATTR_ARIA_SETSIZE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_setsize), ALL_NO_PREFIX);
+ ATTR_ARIA_CHANNEL = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_channel), ALL_NO_PREFIX);
+ ATTR_EQUALCOLUMNS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::equalcolumns), ALL_NO_PREFIX);
+ ATTR_DISPLAYSTYLE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::displaystyle), ALL_NO_PREFIX);
+ ATTR_DATAFORMATAS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::dataformatas), ALL_NO_PREFIX);
+ ATTR_FILL_OPACITY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::fill_opacity), ALL_NO_PREFIX);
+ ATTR_FONT_VARIANT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::font_variant), ALL_NO_PREFIX);
+ ATTR_FONT_STRETCH = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::font_stretch), ALL_NO_PREFIX);
+ ATTR_FRAMESPACING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::framespacing), ALL_NO_PREFIX);
+ ATTR_KERNELMATRIX = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::kernelmatrix, nsHtml5Atoms::kernelMatrix), ALL_NO_PREFIX);
+ ATTR_ONDEACTIVATE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ondeactivate), ALL_NO_PREFIX);
+ ATTR_ONROWSDELETE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onrowsdelete), ALL_NO_PREFIX);
+ ATTR_ONMOUSELEAVE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onmouseleave), ALL_NO_PREFIX);
+ ATTR_ONFORMCHANGE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onformchange), ALL_NO_PREFIX);
+ ATTR_ONCELLCHANGE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::oncellchange), ALL_NO_PREFIX);
+ ATTR_ONMOUSEWHEEL = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onmousewheel), ALL_NO_PREFIX);
+ ATTR_ONMOUSEENTER = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onmouseenter), ALL_NO_PREFIX);
+ ATTR_ONAFTERPRINT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onafterprint), ALL_NO_PREFIX);
+ ATTR_ONBEFORECOPY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onbeforecopy), ALL_NO_PREFIX);
+ ATTR_MARGINHEIGHT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::marginheight), ALL_NO_PREFIX);
+ ATTR_MARKERHEIGHT = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::markerheight, nsHtml5Atoms::markerHeight), ALL_NO_PREFIX);
+ ATTR_MARKER_START = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::marker_start), ALL_NO_PREFIX);
+ ATTR_MATHEMATICAL = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::mathematical), ALL_NO_PREFIX);
+ ATTR_LENGTHADJUST = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::lengthadjust, nsHtml5Atoms::lengthAdjust), ALL_NO_PREFIX);
+ ATTR_UNSELECTABLE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::unselectable), ALL_NO_PREFIX);
+ ATTR_UNICODE_BIDI = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::unicode_bidi), ALL_NO_PREFIX);
+ ATTR_UNITS_PER_EM = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::units_per_em), ALL_NO_PREFIX);
+ ATTR_WORD_SPACING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::word_spacing), ALL_NO_PREFIX);
+ ATTR_WRITING_MODE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::writing_mode), ALL_NO_PREFIX);
+ ATTR_V_ALPHABETIC = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::v_alphabetic), ALL_NO_PREFIX);
+ ATTR_PATTERNUNITS = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::patternunits, nsHtml5Atoms::patternUnits), ALL_NO_PREFIX);
+ ATTR_SPREADMETHOD = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::spreadmethod, nsHtml5Atoms::spreadMethod), ALL_NO_PREFIX);
+ ATTR_SURFACESCALE = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::surfacescale, nsHtml5Atoms::surfaceScale), ALL_NO_PREFIX);
+ ATTR_STROKE_WIDTH = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::stroke_width), ALL_NO_PREFIX);
+ ATTR_REPEAT_START = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::repeat_start), ALL_NO_PREFIX);
+ ATTR_STDDEVIATION = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::stddeviation, nsHtml5Atoms::stdDeviation), ALL_NO_PREFIX);
+ ATTR_STOP_OPACITY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::stop_opacity), ALL_NO_PREFIX);
+ ATTR_ARIA_CONTROLS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_controls), ALL_NO_PREFIX);
+ ATTR_ARIA_HASPOPUP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_haspopup), ALL_NO_PREFIX);
+ ATTR_ACCENT_HEIGHT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::accent_height), ALL_NO_PREFIX);
+ ATTR_ARIA_VALUENOW = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_valuenow), ALL_NO_PREFIX);
+ ATTR_ARIA_RELEVANT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_relevant), ALL_NO_PREFIX);
+ ATTR_ARIA_POSINSET = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_posinset), ALL_NO_PREFIX);
+ ATTR_ARIA_VALUEMAX = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_valuemax), ALL_NO_PREFIX);
+ ATTR_ARIA_READONLY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_readonly), ALL_NO_PREFIX);
+ ATTR_ARIA_SELECTED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_selected), ALL_NO_PREFIX);
+ ATTR_ARIA_REQUIRED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_required), ALL_NO_PREFIX);
+ ATTR_ARIA_EXPANDED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_expanded), ALL_NO_PREFIX);
+ ATTR_ARIA_DISABLED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_disabled), ALL_NO_PREFIX);
+ ATTR_ATTRIBUTETYPE = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::attributetype, nsHtml5Atoms::attributeType), ALL_NO_PREFIX);
+ ATTR_ATTRIBUTENAME = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::attributename, nsHtml5Atoms::attributeName), ALL_NO_PREFIX);
+ ATTR_ARIA_DATATYPE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_datatype), ALL_NO_PREFIX);
+ ATTR_ARIA_VALUEMIN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_valuemin), ALL_NO_PREFIX);
+ ATTR_BASEFREQUENCY = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::basefrequency, nsHtml5Atoms::baseFrequency), ALL_NO_PREFIX);
+ ATTR_COLUMNSPACING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::columnspacing), ALL_NO_PREFIX);
+ ATTR_COLOR_PROFILE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::color_profile), ALL_NO_PREFIX);
+ ATTR_CLIPPATHUNITS = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::clippathunits, nsHtml5Atoms::clipPathUnits), ALL_NO_PREFIX);
+ ATTR_DEFINITIONURL = new nsHtml5AttributeName(ALL_NO_NS, MATH_DIFFERENT(nsHtml5Atoms::definitionurl, nsHtml5Atoms::definitionURL), ALL_NO_PREFIX);
+ ATTR_GRADIENTUNITS = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::gradientunits, nsHtml5Atoms::gradientUnits), ALL_NO_PREFIX);
+ ATTR_FLOOD_OPACITY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::flood_opacity), ALL_NO_PREFIX);
+ ATTR_ONAFTERUPDATE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onafterupdate), ALL_NO_PREFIX);
+ ATTR_ONERRORUPDATE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onerrorupdate), ALL_NO_PREFIX);
+ ATTR_ONBEFOREPASTE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onbeforepaste), ALL_NO_PREFIX);
+ ATTR_ONLOSECAPTURE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onlosecapture), ALL_NO_PREFIX);
+ ATTR_ONCONTEXTMENU = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::oncontextmenu), ALL_NO_PREFIX);
+ ATTR_ONSELECTSTART = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onselectstart), ALL_NO_PREFIX);
+ ATTR_ONBEFOREPRINT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onbeforeprint), ALL_NO_PREFIX);
+ ATTR_MOVABLELIMITS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::movablelimits), ALL_NO_PREFIX);
+ ATTR_LINETHICKNESS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::linethickness), ALL_NO_PREFIX);
+ ATTR_UNICODE_RANGE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::unicode_range), ALL_NO_PREFIX);
+ ATTR_THINMATHSPACE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::thinmathspace), ALL_NO_PREFIX);
+ ATTR_VERT_ORIGIN_X = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::vert_origin_x), ALL_NO_PREFIX);
+ ATTR_VERT_ORIGIN_Y = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::vert_origin_y), ALL_NO_PREFIX);
+ ATTR_V_IDEOGRAPHIC = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::v_ideographic), ALL_NO_PREFIX);
+ ATTR_PRESERVEALPHA = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::preservealpha, nsHtml5Atoms::preserveAlpha), ALL_NO_PREFIX);
+ ATTR_SCRIPTMINSIZE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::scriptminsize), ALL_NO_PREFIX);
+ ATTR_SPECIFICATION = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::specification), ALL_NO_PREFIX);
+ ATTR_XLINK_ACTUATE = new nsHtml5AttributeName(XLINK_NS, COLONIFIED_LOCAL(nsHtml5Atoms::xlink_actuate, nsHtml5Atoms::actuate), XLINK_PREFIX);
+ ATTR_XLINK_ARCROLE = new nsHtml5AttributeName(XLINK_NS, COLONIFIED_LOCAL(nsHtml5Atoms::xlink_arcrole, nsHtml5Atoms::arcrole), XLINK_PREFIX);
+ ATTR_ACCEPT_CHARSET = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::accept_charset), ALL_NO_PREFIX);
+ ATTR_ALIGNMENTSCOPE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::alignmentscope), ALL_NO_PREFIX);
+ ATTR_ARIA_MULTILINE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_multiline), ALL_NO_PREFIX);
+ ATTR_BASELINE_SHIFT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::baseline_shift), ALL_NO_PREFIX);
+ ATTR_HORIZ_ORIGIN_X = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::horiz_origin_x), ALL_NO_PREFIX);
+ ATTR_HORIZ_ORIGIN_Y = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::horiz_origin_y), ALL_NO_PREFIX);
+ ATTR_ONBEFOREUPDATE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onbeforeupdate), ALL_NO_PREFIX);
+ ATTR_ONFILTERCHANGE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onfilterchange), ALL_NO_PREFIX);
+ ATTR_ONROWSINSERTED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onrowsinserted), ALL_NO_PREFIX);
+ ATTR_ONBEFOREUNLOAD = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onbeforeunload), ALL_NO_PREFIX);
+ ATTR_MATHBACKGROUND = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::mathbackground), ALL_NO_PREFIX);
+ ATTR_LETTER_SPACING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::letter_spacing), ALL_NO_PREFIX);
+ ATTR_LIGHTING_COLOR = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::lighting_color), ALL_NO_PREFIX);
+ ATTR_THICKMATHSPACE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::thickmathspace), ALL_NO_PREFIX);
+ ATTR_TEXT_RENDERING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::text_rendering), ALL_NO_PREFIX);
+ ATTR_V_MATHEMATICAL = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::v_mathematical), ALL_NO_PREFIX);
+ ATTR_POINTER_EVENTS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::pointer_events), ALL_NO_PREFIX);
+ ATTR_PRIMITIVEUNITS = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::primitiveunits, nsHtml5Atoms::primitiveUnits), ALL_NO_PREFIX);
+ ATTR_REFERRERPOLICY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::referrerpolicy), ALL_NO_PREFIX);
+ ATTR_SYSTEMLANGUAGE = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::systemlanguage, nsHtml5Atoms::systemLanguage), ALL_NO_PREFIX);
+ ATTR_STROKE_LINECAP = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::stroke_linecap), ALL_NO_PREFIX);
+ ATTR_SUBSCRIPTSHIFT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::subscriptshift), ALL_NO_PREFIX);
+ ATTR_STROKE_OPACITY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::stroke_opacity), ALL_NO_PREFIX);
+ ATTR_ARIA_DROPEFFECT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_dropeffect), ALL_NO_PREFIX);
+ ATTR_ARIA_LABELLEDBY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_labelledby), ALL_NO_PREFIX);
+ ATTR_ARIA_TEMPLATEID = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_templateid), ALL_NO_PREFIX);
+ ATTR_COLOR_RENDERING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::color_rendering), ALL_NO_PREFIX);
+ ATTR_CONTENTEDITABLE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::contenteditable), ALL_NO_PREFIX);
+ ATTR_DIFFUSECONSTANT = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::diffuseconstant, nsHtml5Atoms::diffuseConstant), ALL_NO_PREFIX);
+ ATTR_ONDATAAVAILABLE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ondataavailable), ALL_NO_PREFIX);
+ ATTR_ONCONTROLSELECT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::oncontrolselect), ALL_NO_PREFIX);
+ ATTR_IMAGE_RENDERING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::image_rendering), ALL_NO_PREFIX);
+ ATTR_MEDIUMMATHSPACE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::mediummathspace), ALL_NO_PREFIX);
+ ATTR_TEXT_DECORATION = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::text_decoration), ALL_NO_PREFIX);
+ ATTR_SHAPE_RENDERING = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::shape_rendering), ALL_NO_PREFIX);
+ ATTR_STROKE_LINEJOIN = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::stroke_linejoin), ALL_NO_PREFIX);
+ ATTR_REPEAT_TEMPLATE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::repeat_template), ALL_NO_PREFIX);
+ ATTR_ARIA_DESCRIBEDBY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_describedby), ALL_NO_PREFIX);
+ ATTR_FONT_SIZE_ADJUST = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::font_size_adjust), ALL_NO_PREFIX);
+ ATTR_KERNELUNITLENGTH = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::kernelunitlength, nsHtml5Atoms::kernelUnitLength), ALL_NO_PREFIX);
+ ATTR_ONBEFOREACTIVATE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onbeforeactivate), ALL_NO_PREFIX);
+ ATTR_ONPROPERTYCHANGE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onpropertychange), ALL_NO_PREFIX);
+ ATTR_ONDATASETCHANGED = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ondatasetchanged), ALL_NO_PREFIX);
+ ATTR_MASKCONTENTUNITS = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::maskcontentunits, nsHtml5Atoms::maskContentUnits), ALL_NO_PREFIX);
+ ATTR_PATTERNTRANSFORM = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::patterntransform, nsHtml5Atoms::patternTransform), ALL_NO_PREFIX);
+ ATTR_REQUIREDFEATURES = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::requiredfeatures, nsHtml5Atoms::requiredFeatures), ALL_NO_PREFIX);
+ ATTR_RENDERING_INTENT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::rendering_intent), ALL_NO_PREFIX);
+ ATTR_SPECULAREXPONENT = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::specularexponent, nsHtml5Atoms::specularExponent), ALL_NO_PREFIX);
+ ATTR_SPECULARCONSTANT = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::specularconstant, nsHtml5Atoms::specularConstant), ALL_NO_PREFIX);
+ ATTR_SUPERSCRIPTSHIFT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::superscriptshift), ALL_NO_PREFIX);
+ ATTR_STROKE_DASHARRAY = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::stroke_dasharray), ALL_NO_PREFIX);
+ ATTR_XCHANNELSELECTOR = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::xchannelselector, nsHtml5Atoms::xChannelSelector), ALL_NO_PREFIX);
+ ATTR_YCHANNELSELECTOR = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::ychannelselector, nsHtml5Atoms::yChannelSelector), ALL_NO_PREFIX);
+ ATTR_ARIA_AUTOCOMPLETE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_autocomplete), ALL_NO_PREFIX);
+ ATTR_ENABLE_BACKGROUND = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::enable_background), ALL_NO_PREFIX);
+ ATTR_DOMINANT_BASELINE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::dominant_baseline), ALL_NO_PREFIX);
+ ATTR_GRADIENTTRANSFORM = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::gradienttransform, nsHtml5Atoms::gradientTransform), ALL_NO_PREFIX);
+ ATTR_ONBEFORDEACTIVATE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onbefordeactivate), ALL_NO_PREFIX);
+ ATTR_ONDATASETCOMPLETE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::ondatasetcomplete), ALL_NO_PREFIX);
+ ATTR_OVERLINE_POSITION = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::overline_position), ALL_NO_PREFIX);
+ ATTR_ONBEFOREEDITFOCUS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onbeforeeditfocus), ALL_NO_PREFIX);
+ ATTR_LIMITINGCONEANGLE = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::limitingconeangle, nsHtml5Atoms::limitingConeAngle), ALL_NO_PREFIX);
+ ATTR_VERYTHINMATHSPACE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::verythinmathspace), ALL_NO_PREFIX);
+ ATTR_STROKE_DASHOFFSET = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::stroke_dashoffset), ALL_NO_PREFIX);
+ ATTR_STROKE_MITERLIMIT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::stroke_miterlimit), ALL_NO_PREFIX);
+ ATTR_ALIGNMENT_BASELINE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::alignment_baseline), ALL_NO_PREFIX);
+ ATTR_ONREADYSTATECHANGE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::onreadystatechange), ALL_NO_PREFIX);
+ ATTR_OVERLINE_THICKNESS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::overline_thickness), ALL_NO_PREFIX);
+ ATTR_UNDERLINE_POSITION = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::underline_position), ALL_NO_PREFIX);
+ ATTR_VERYTHICKMATHSPACE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::verythickmathspace), ALL_NO_PREFIX);
+ ATTR_REQUIREDEXTENSIONS = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::requiredextensions, nsHtml5Atoms::requiredExtensions), ALL_NO_PREFIX);
+ ATTR_COLOR_INTERPOLATION = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::color_interpolation), ALL_NO_PREFIX);
+ ATTR_UNDERLINE_THICKNESS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::underline_thickness), ALL_NO_PREFIX);
+ ATTR_PRESERVEASPECTRATIO = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::preserveaspectratio, nsHtml5Atoms::preserveAspectRatio), ALL_NO_PREFIX);
+ ATTR_PATTERNCONTENTUNITS = new nsHtml5AttributeName(ALL_NO_NS, SVG_DIFFERENT(nsHtml5Atoms::patterncontentunits, nsHtml5Atoms::patternContentUnits), ALL_NO_PREFIX);
+ ATTR_ARIA_MULTISELECTABLE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_multiselectable), ALL_NO_PREFIX);
+ ATTR_SCRIPTSIZEMULTIPLIER = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::scriptsizemultiplier), ALL_NO_PREFIX);
+ ATTR_ARIA_ACTIVEDESCENDANT = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::aria_activedescendant), ALL_NO_PREFIX);
+ ATTR_VERYVERYTHINMATHSPACE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::veryverythinmathspace), ALL_NO_PREFIX);
+ ATTR_VERYVERYTHICKMATHSPACE = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::veryverythickmathspace), ALL_NO_PREFIX);
+ ATTR_STRIKETHROUGH_POSITION = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::strikethrough_position), ALL_NO_PREFIX);
+ ATTR_STRIKETHROUGH_THICKNESS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::strikethrough_thickness), ALL_NO_PREFIX);
+ ATTR_GLYPH_ORIENTATION_VERTICAL = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::glyph_orientation_vertical), ALL_NO_PREFIX);
+ ATTR_COLOR_INTERPOLATION_FILTERS = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::color_interpolation_filters), ALL_NO_PREFIX);
+ ATTR_GLYPH_ORIENTATION_HORIZONTAL = new nsHtml5AttributeName(ALL_NO_NS, SAME_LOCAL(nsHtml5Atoms::glyph_orientation_horizontal), ALL_NO_PREFIX);
+ ATTRIBUTE_NAMES = new nsHtml5AttributeName*[583];
+ ATTRIBUTE_NAMES[0] = ATTR_D;
+ ATTRIBUTE_NAMES[1] = ATTR_K;
+ ATTRIBUTE_NAMES[2] = ATTR_R;
+ ATTRIBUTE_NAMES[3] = ATTR_X;
+ ATTRIBUTE_NAMES[4] = ATTR_Y;
+ ATTRIBUTE_NAMES[5] = ATTR_Z;
+ ATTRIBUTE_NAMES[6] = ATTR_BY;
+ ATTRIBUTE_NAMES[7] = ATTR_CX;
+ ATTRIBUTE_NAMES[8] = ATTR_CY;
+ ATTRIBUTE_NAMES[9] = ATTR_DX;
+ ATTRIBUTE_NAMES[10] = ATTR_DY;
+ ATTRIBUTE_NAMES[11] = ATTR_G2;
+ ATTRIBUTE_NAMES[12] = ATTR_G1;
+ ATTRIBUTE_NAMES[13] = ATTR_FX;
+ ATTRIBUTE_NAMES[14] = ATTR_FY;
+ ATTRIBUTE_NAMES[15] = ATTR_K4;
+ ATTRIBUTE_NAMES[16] = ATTR_K2;
+ ATTRIBUTE_NAMES[17] = ATTR_K3;
+ ATTRIBUTE_NAMES[18] = ATTR_K1;
+ ATTRIBUTE_NAMES[19] = ATTR_ID;
+ ATTRIBUTE_NAMES[20] = ATTR_IN;
+ ATTRIBUTE_NAMES[21] = ATTR_U2;
+ ATTRIBUTE_NAMES[22] = ATTR_U1;
+ ATTRIBUTE_NAMES[23] = ATTR_RT;
+ ATTRIBUTE_NAMES[24] = ATTR_RX;
+ ATTRIBUTE_NAMES[25] = ATTR_RY;
+ ATTRIBUTE_NAMES[26] = ATTR_TO;
+ ATTRIBUTE_NAMES[27] = ATTR_Y2;
+ ATTRIBUTE_NAMES[28] = ATTR_Y1;
+ ATTRIBUTE_NAMES[29] = ATTR_X1;
+ ATTRIBUTE_NAMES[30] = ATTR_X2;
+ ATTRIBUTE_NAMES[31] = ATTR_ALT;
+ ATTRIBUTE_NAMES[32] = ATTR_DIR;
+ ATTRIBUTE_NAMES[33] = ATTR_DUR;
+ ATTRIBUTE_NAMES[34] = ATTR_END;
+ ATTRIBUTE_NAMES[35] = ATTR_FOR;
+ ATTRIBUTE_NAMES[36] = ATTR_IN2;
+ ATTRIBUTE_NAMES[37] = ATTR_MAX;
+ ATTRIBUTE_NAMES[38] = ATTR_MIN;
+ ATTRIBUTE_NAMES[39] = ATTR_LOW;
+ ATTRIBUTE_NAMES[40] = ATTR_REL;
+ ATTRIBUTE_NAMES[41] = ATTR_REV;
+ ATTRIBUTE_NAMES[42] = ATTR_SRC;
+ ATTRIBUTE_NAMES[43] = ATTR_AXIS;
+ ATTRIBUTE_NAMES[44] = ATTR_ABBR;
+ ATTRIBUTE_NAMES[45] = ATTR_BBOX;
+ ATTRIBUTE_NAMES[46] = ATTR_CITE;
+ ATTRIBUTE_NAMES[47] = ATTR_CODE;
+ ATTRIBUTE_NAMES[48] = ATTR_BIAS;
+ ATTRIBUTE_NAMES[49] = ATTR_COLS;
+ ATTRIBUTE_NAMES[50] = ATTR_CLIP;
+ ATTRIBUTE_NAMES[51] = ATTR_CHAR;
+ ATTRIBUTE_NAMES[52] = ATTR_BASE;
+ ATTRIBUTE_NAMES[53] = ATTR_EDGE;
+ ATTRIBUTE_NAMES[54] = ATTR_DATA;
+ ATTRIBUTE_NAMES[55] = ATTR_FILL;
+ ATTRIBUTE_NAMES[56] = ATTR_FROM;
+ ATTRIBUTE_NAMES[57] = ATTR_FORM;
+ ATTRIBUTE_NAMES[58] = ATTR_FACE;
+ ATTRIBUTE_NAMES[59] = ATTR_HIGH;
+ ATTRIBUTE_NAMES[60] = ATTR_HREF;
+ ATTRIBUTE_NAMES[61] = ATTR_OPEN;
+ ATTRIBUTE_NAMES[62] = ATTR_ICON;
+ ATTRIBUTE_NAMES[63] = ATTR_NAME;
+ ATTRIBUTE_NAMES[64] = ATTR_MODE;
+ ATTRIBUTE_NAMES[65] = ATTR_MASK;
+ ATTRIBUTE_NAMES[66] = ATTR_LINK;
+ ATTRIBUTE_NAMES[67] = ATTR_LANG;
+ ATTRIBUTE_NAMES[68] = ATTR_LOOP;
+ ATTRIBUTE_NAMES[69] = ATTR_LIST;
+ ATTRIBUTE_NAMES[70] = ATTR_TYPE;
+ ATTRIBUTE_NAMES[71] = ATTR_WHEN;
+ ATTRIBUTE_NAMES[72] = ATTR_WRAP;
+ ATTRIBUTE_NAMES[73] = ATTR_TEXT;
+ ATTRIBUTE_NAMES[74] = ATTR_PATH;
+ ATTRIBUTE_NAMES[75] = ATTR_PING;
+ ATTRIBUTE_NAMES[76] = ATTR_REFX;
+ ATTRIBUTE_NAMES[77] = ATTR_REFY;
+ ATTRIBUTE_NAMES[78] = ATTR_SIZE;
+ ATTRIBUTE_NAMES[79] = ATTR_SEED;
+ ATTRIBUTE_NAMES[80] = ATTR_ROWS;
+ ATTRIBUTE_NAMES[81] = ATTR_SPAN;
+ ATTRIBUTE_NAMES[82] = ATTR_STEP;
+ ATTRIBUTE_NAMES[83] = ATTR_ROLE;
+ ATTRIBUTE_NAMES[84] = ATTR_XREF;
+ ATTRIBUTE_NAMES[85] = ATTR_ASYNC;
+ ATTRIBUTE_NAMES[86] = ATTR_ALINK;
+ ATTRIBUTE_NAMES[87] = ATTR_ALIGN;
+ ATTRIBUTE_NAMES[88] = ATTR_CLOSE;
+ ATTRIBUTE_NAMES[89] = ATTR_COLOR;
+ ATTRIBUTE_NAMES[90] = ATTR_CLASS;
+ ATTRIBUTE_NAMES[91] = ATTR_CLEAR;
+ ATTRIBUTE_NAMES[92] = ATTR_BEGIN;
+ ATTRIBUTE_NAMES[93] = ATTR_DEPTH;
+ ATTRIBUTE_NAMES[94] = ATTR_DEFER;
+ ATTRIBUTE_NAMES[95] = ATTR_FENCE;
+ ATTRIBUTE_NAMES[96] = ATTR_FRAME;
+ ATTRIBUTE_NAMES[97] = ATTR_ISMAP;
+ ATTRIBUTE_NAMES[98] = ATTR_ONEND;
+ ATTRIBUTE_NAMES[99] = ATTR_INDEX;
+ ATTRIBUTE_NAMES[100] = ATTR_ORDER;
+ ATTRIBUTE_NAMES[101] = ATTR_OTHER;
+ ATTRIBUTE_NAMES[102] = ATTR_ONCUT;
+ ATTRIBUTE_NAMES[103] = ATTR_NARGS;
+ ATTRIBUTE_NAMES[104] = ATTR_MEDIA;
+ ATTRIBUTE_NAMES[105] = ATTR_LABEL;
+ ATTRIBUTE_NAMES[106] = ATTR_LOCAL;
+ ATTRIBUTE_NAMES[107] = ATTR_WIDTH;
+ ATTRIBUTE_NAMES[108] = ATTR_TITLE;
+ ATTRIBUTE_NAMES[109] = ATTR_VLINK;
+ ATTRIBUTE_NAMES[110] = ATTR_VALUE;
+ ATTRIBUTE_NAMES[111] = ATTR_SLOPE;
+ ATTRIBUTE_NAMES[112] = ATTR_SHAPE;
+ ATTRIBUTE_NAMES[113] = ATTR_SCOPE;
+ ATTRIBUTE_NAMES[114] = ATTR_SCALE;
+ ATTRIBUTE_NAMES[115] = ATTR_SPEED;
+ ATTRIBUTE_NAMES[116] = ATTR_STYLE;
+ ATTRIBUTE_NAMES[117] = ATTR_RULES;
+ ATTRIBUTE_NAMES[118] = ATTR_STEMH;
+ ATTRIBUTE_NAMES[119] = ATTR_SIZES;
+ ATTRIBUTE_NAMES[120] = ATTR_STEMV;
+ ATTRIBUTE_NAMES[121] = ATTR_START;
+ ATTRIBUTE_NAMES[122] = ATTR_XMLNS;
+ ATTRIBUTE_NAMES[123] = ATTR_ACCEPT;
+ ATTRIBUTE_NAMES[124] = ATTR_ACCENT;
+ ATTRIBUTE_NAMES[125] = ATTR_ASCENT;
+ ATTRIBUTE_NAMES[126] = ATTR_ACTIVE;
+ ATTRIBUTE_NAMES[127] = ATTR_ALTIMG;
+ ATTRIBUTE_NAMES[128] = ATTR_ACTION;
+ ATTRIBUTE_NAMES[129] = ATTR_BORDER;
+ ATTRIBUTE_NAMES[130] = ATTR_CURSOR;
+ ATTRIBUTE_NAMES[131] = ATTR_COORDS;
+ ATTRIBUTE_NAMES[132] = ATTR_FILTER;
+ ATTRIBUTE_NAMES[133] = ATTR_FORMAT;
+ ATTRIBUTE_NAMES[134] = ATTR_HIDDEN;
+ ATTRIBUTE_NAMES[135] = ATTR_HSPACE;
+ ATTRIBUTE_NAMES[136] = ATTR_HEIGHT;
+ ATTRIBUTE_NAMES[137] = ATTR_ONMOVE;
+ ATTRIBUTE_NAMES[138] = ATTR_ONLOAD;
+ ATTRIBUTE_NAMES[139] = ATTR_ONDRAG;
+ ATTRIBUTE_NAMES[140] = ATTR_ORIGIN;
+ ATTRIBUTE_NAMES[141] = ATTR_ONZOOM;
+ ATTRIBUTE_NAMES[142] = ATTR_ONHELP;
+ ATTRIBUTE_NAMES[143] = ATTR_ONSTOP;
+ ATTRIBUTE_NAMES[144] = ATTR_ONDROP;
+ ATTRIBUTE_NAMES[145] = ATTR_ONBLUR;
+ ATTRIBUTE_NAMES[146] = ATTR_OBJECT;
+ ATTRIBUTE_NAMES[147] = ATTR_OFFSET;
+ ATTRIBUTE_NAMES[148] = ATTR_ORIENT;
+ ATTRIBUTE_NAMES[149] = ATTR_ONCOPY;
+ ATTRIBUTE_NAMES[150] = ATTR_NOWRAP;
+ ATTRIBUTE_NAMES[151] = ATTR_NOHREF;
+ ATTRIBUTE_NAMES[152] = ATTR_MACROS;
+ ATTRIBUTE_NAMES[153] = ATTR_METHOD;
+ ATTRIBUTE_NAMES[154] = ATTR_LOWSRC;
+ ATTRIBUTE_NAMES[155] = ATTR_LSPACE;
+ ATTRIBUTE_NAMES[156] = ATTR_LQUOTE;
+ ATTRIBUTE_NAMES[157] = ATTR_USEMAP;
+ ATTRIBUTE_NAMES[158] = ATTR_WIDTHS;
+ ATTRIBUTE_NAMES[159] = ATTR_TARGET;
+ ATTRIBUTE_NAMES[160] = ATTR_VALUES;
+ ATTRIBUTE_NAMES[161] = ATTR_VALIGN;
+ ATTRIBUTE_NAMES[162] = ATTR_VSPACE;
+ ATTRIBUTE_NAMES[163] = ATTR_POSTER;
+ ATTRIBUTE_NAMES[164] = ATTR_POINTS;
+ ATTRIBUTE_NAMES[165] = ATTR_PROMPT;
+ ATTRIBUTE_NAMES[166] = ATTR_SRCDOC;
+ ATTRIBUTE_NAMES[167] = ATTR_SCOPED;
+ ATTRIBUTE_NAMES[168] = ATTR_STRING;
+ ATTRIBUTE_NAMES[169] = ATTR_SCHEME;
+ ATTRIBUTE_NAMES[170] = ATTR_STROKE;
+ ATTRIBUTE_NAMES[171] = ATTR_RADIUS;
+ ATTRIBUTE_NAMES[172] = ATTR_RESULT;
+ ATTRIBUTE_NAMES[173] = ATTR_REPEAT;
+ ATTRIBUTE_NAMES[174] = ATTR_SRCSET;
+ ATTRIBUTE_NAMES[175] = ATTR_RSPACE;
+ ATTRIBUTE_NAMES[176] = ATTR_ROTATE;
+ ATTRIBUTE_NAMES[177] = ATTR_RQUOTE;
+ ATTRIBUTE_NAMES[178] = ATTR_ALTTEXT;
+ ATTRIBUTE_NAMES[179] = ATTR_ARCHIVE;
+ ATTRIBUTE_NAMES[180] = ATTR_AZIMUTH;
+ ATTRIBUTE_NAMES[181] = ATTR_CLOSURE;
+ ATTRIBUTE_NAMES[182] = ATTR_CHECKED;
+ ATTRIBUTE_NAMES[183] = ATTR_CLASSID;
+ ATTRIBUTE_NAMES[184] = ATTR_CHAROFF;
+ ATTRIBUTE_NAMES[185] = ATTR_BGCOLOR;
+ ATTRIBUTE_NAMES[186] = ATTR_COLSPAN;
+ ATTRIBUTE_NAMES[187] = ATTR_CHARSET;
+ ATTRIBUTE_NAMES[188] = ATTR_COMPACT;
+ ATTRIBUTE_NAMES[189] = ATTR_CONTENT;
+ ATTRIBUTE_NAMES[190] = ATTR_ENCTYPE;
+ ATTRIBUTE_NAMES[191] = ATTR_DATASRC;
+ ATTRIBUTE_NAMES[192] = ATTR_DATAFLD;
+ ATTRIBUTE_NAMES[193] = ATTR_DECLARE;
+ ATTRIBUTE_NAMES[194] = ATTR_DISPLAY;
+ ATTRIBUTE_NAMES[195] = ATTR_DIVISOR;
+ ATTRIBUTE_NAMES[196] = ATTR_DEFAULT;
+ ATTRIBUTE_NAMES[197] = ATTR_DESCENT;
+ ATTRIBUTE_NAMES[198] = ATTR_KERNING;
+ ATTRIBUTE_NAMES[199] = ATTR_HANGING;
+ ATTRIBUTE_NAMES[200] = ATTR_HEADERS;
+ ATTRIBUTE_NAMES[201] = ATTR_ONPASTE;
+ ATTRIBUTE_NAMES[202] = ATTR_ONCLICK;
+ ATTRIBUTE_NAMES[203] = ATTR_OPTIMUM;
+ ATTRIBUTE_NAMES[204] = ATTR_ONBEGIN;
+ ATTRIBUTE_NAMES[205] = ATTR_ONKEYUP;
+ ATTRIBUTE_NAMES[206] = ATTR_ONFOCUS;
+ ATTRIBUTE_NAMES[207] = ATTR_ONERROR;
+ ATTRIBUTE_NAMES[208] = ATTR_ONINPUT;
+ ATTRIBUTE_NAMES[209] = ATTR_ONABORT;
+ ATTRIBUTE_NAMES[210] = ATTR_ONSTART;
+ ATTRIBUTE_NAMES[211] = ATTR_ONRESET;
+ ATTRIBUTE_NAMES[212] = ATTR_OPACITY;
+ ATTRIBUTE_NAMES[213] = ATTR_NOSHADE;
+ ATTRIBUTE_NAMES[214] = ATTR_MINSIZE;
+ ATTRIBUTE_NAMES[215] = ATTR_MAXSIZE;
+ ATTRIBUTE_NAMES[216] = ATTR_LARGEOP;
+ ATTRIBUTE_NAMES[217] = ATTR_UNICODE;
+ ATTRIBUTE_NAMES[218] = ATTR_TARGETX;
+ ATTRIBUTE_NAMES[219] = ATTR_TARGETY;
+ ATTRIBUTE_NAMES[220] = ATTR_VIEWBOX;
+ ATTRIBUTE_NAMES[221] = ATTR_VERSION;
+ ATTRIBUTE_NAMES[222] = ATTR_PATTERN;
+ ATTRIBUTE_NAMES[223] = ATTR_PROFILE;
+ ATTRIBUTE_NAMES[224] = ATTR_SPACING;
+ ATTRIBUTE_NAMES[225] = ATTR_RESTART;
+ ATTRIBUTE_NAMES[226] = ATTR_ROWSPAN;
+ ATTRIBUTE_NAMES[227] = ATTR_SANDBOX;
+ ATTRIBUTE_NAMES[228] = ATTR_SUMMARY;
+ ATTRIBUTE_NAMES[229] = ATTR_STANDBY;
+ ATTRIBUTE_NAMES[230] = ATTR_REPLACE;
+ ATTRIBUTE_NAMES[231] = ATTR_AUTOPLAY;
+ ATTRIBUTE_NAMES[232] = ATTR_ADDITIVE;
+ ATTRIBUTE_NAMES[233] = ATTR_CALCMODE;
+ ATTRIBUTE_NAMES[234] = ATTR_CODETYPE;
+ ATTRIBUTE_NAMES[235] = ATTR_CODEBASE;
+ ATTRIBUTE_NAMES[236] = ATTR_CONTROLS;
+ ATTRIBUTE_NAMES[237] = ATTR_BEVELLED;
+ ATTRIBUTE_NAMES[238] = ATTR_BASELINE;
+ ATTRIBUTE_NAMES[239] = ATTR_EXPONENT;
+ ATTRIBUTE_NAMES[240] = ATTR_EDGEMODE;
+ ATTRIBUTE_NAMES[241] = ATTR_ENCODING;
+ ATTRIBUTE_NAMES[242] = ATTR_GLYPHREF;
+ ATTRIBUTE_NAMES[243] = ATTR_DATETIME;
+ ATTRIBUTE_NAMES[244] = ATTR_DISABLED;
+ ATTRIBUTE_NAMES[245] = ATTR_FONTSIZE;
+ ATTRIBUTE_NAMES[246] = ATTR_KEYTIMES;
+ ATTRIBUTE_NAMES[247] = ATTR_PANOSE_1;
+ ATTRIBUTE_NAMES[248] = ATTR_HREFLANG;
+ ATTRIBUTE_NAMES[249] = ATTR_ONRESIZE;
+ ATTRIBUTE_NAMES[250] = ATTR_ONCHANGE;
+ ATTRIBUTE_NAMES[251] = ATTR_ONBOUNCE;
+ ATTRIBUTE_NAMES[252] = ATTR_ONUNLOAD;
+ ATTRIBUTE_NAMES[253] = ATTR_ONFINISH;
+ ATTRIBUTE_NAMES[254] = ATTR_ONSCROLL;
+ ATTRIBUTE_NAMES[255] = ATTR_OPERATOR;
+ ATTRIBUTE_NAMES[256] = ATTR_OVERFLOW;
+ ATTRIBUTE_NAMES[257] = ATTR_ONSUBMIT;
+ ATTRIBUTE_NAMES[258] = ATTR_ONREPEAT;
+ ATTRIBUTE_NAMES[259] = ATTR_ONSELECT;
+ ATTRIBUTE_NAMES[260] = ATTR_NOTATION;
+ ATTRIBUTE_NAMES[261] = ATTR_NORESIZE;
+ ATTRIBUTE_NAMES[262] = ATTR_MANIFEST;
+ ATTRIBUTE_NAMES[263] = ATTR_MATHSIZE;
+ ATTRIBUTE_NAMES[264] = ATTR_MULTIPLE;
+ ATTRIBUTE_NAMES[265] = ATTR_LONGDESC;
+ ATTRIBUTE_NAMES[266] = ATTR_LANGUAGE;
+ ATTRIBUTE_NAMES[267] = ATTR_TEMPLATE;
+ ATTRIBUTE_NAMES[268] = ATTR_TABINDEX;
+ ATTRIBUTE_NAMES[269] = ATTR_PROPERTY;
+ ATTRIBUTE_NAMES[270] = ATTR_READONLY;
+ ATTRIBUTE_NAMES[271] = ATTR_SELECTED;
+ ATTRIBUTE_NAMES[272] = ATTR_ROWLINES;
+ ATTRIBUTE_NAMES[273] = ATTR_SEAMLESS;
+ ATTRIBUTE_NAMES[274] = ATTR_ROWALIGN;
+ ATTRIBUTE_NAMES[275] = ATTR_STRETCHY;
+ ATTRIBUTE_NAMES[276] = ATTR_REQUIRED;
+ ATTRIBUTE_NAMES[277] = ATTR_XML_BASE;
+ ATTRIBUTE_NAMES[278] = ATTR_XML_LANG;
+ ATTRIBUTE_NAMES[279] = ATTR_X_HEIGHT;
+ ATTRIBUTE_NAMES[280] = ATTR_ARIA_OWNS;
+ ATTRIBUTE_NAMES[281] = ATTR_AUTOFOCUS;
+ ATTRIBUTE_NAMES[282] = ATTR_ARIA_SORT;
+ ATTRIBUTE_NAMES[283] = ATTR_ACCESSKEY;
+ ATTRIBUTE_NAMES[284] = ATTR_ARIA_BUSY;
+ ATTRIBUTE_NAMES[285] = ATTR_ARIA_GRAB;
+ ATTRIBUTE_NAMES[286] = ATTR_AMPLITUDE;
+ ATTRIBUTE_NAMES[287] = ATTR_ARIA_LIVE;
+ ATTRIBUTE_NAMES[288] = ATTR_CLIP_RULE;
+ ATTRIBUTE_NAMES[289] = ATTR_CLIP_PATH;
+ ATTRIBUTE_NAMES[290] = ATTR_EQUALROWS;
+ ATTRIBUTE_NAMES[291] = ATTR_ELEVATION;
+ ATTRIBUTE_NAMES[292] = ATTR_DIRECTION;
+ ATTRIBUTE_NAMES[293] = ATTR_DRAGGABLE;
+ ATTRIBUTE_NAMES[294] = ATTR_FILL_RULE;
+ ATTRIBUTE_NAMES[295] = ATTR_FONTSTYLE;
+ ATTRIBUTE_NAMES[296] = ATTR_FONT_SIZE;
+ ATTRIBUTE_NAMES[297] = ATTR_KEYSYSTEM;
+ ATTRIBUTE_NAMES[298] = ATTR_KEYPOINTS;
+ ATTRIBUTE_NAMES[299] = ATTR_HIDEFOCUS;
+ ATTRIBUTE_NAMES[300] = ATTR_ONMESSAGE;
+ ATTRIBUTE_NAMES[301] = ATTR_INTERCEPT;
+ ATTRIBUTE_NAMES[302] = ATTR_ONDRAGEND;
+ ATTRIBUTE_NAMES[303] = ATTR_ONMOVEEND;
+ ATTRIBUTE_NAMES[304] = ATTR_ONINVALID;
+ ATTRIBUTE_NAMES[305] = ATTR_INTEGRITY;
+ ATTRIBUTE_NAMES[306] = ATTR_ONKEYDOWN;
+ ATTRIBUTE_NAMES[307] = ATTR_ONFOCUSIN;
+ ATTRIBUTE_NAMES[308] = ATTR_ONMOUSEUP;
+ ATTRIBUTE_NAMES[309] = ATTR_INPUTMODE;
+ ATTRIBUTE_NAMES[310] = ATTR_ONROWEXIT;
+ ATTRIBUTE_NAMES[311] = ATTR_MATHCOLOR;
+ ATTRIBUTE_NAMES[312] = ATTR_MASKUNITS;
+ ATTRIBUTE_NAMES[313] = ATTR_MAXLENGTH;
+ ATTRIBUTE_NAMES[314] = ATTR_LINEBREAK;
+ ATTRIBUTE_NAMES[315] = ATTR_TRANSFORM;
+ ATTRIBUTE_NAMES[316] = ATTR_V_HANGING;
+ ATTRIBUTE_NAMES[317] = ATTR_VALUETYPE;
+ ATTRIBUTE_NAMES[318] = ATTR_POINTSATZ;
+ ATTRIBUTE_NAMES[319] = ATTR_POINTSATX;
+ ATTRIBUTE_NAMES[320] = ATTR_POINTSATY;
+ ATTRIBUTE_NAMES[321] = ATTR_SYMMETRIC;
+ ATTRIBUTE_NAMES[322] = ATTR_SCROLLING;
+ ATTRIBUTE_NAMES[323] = ATTR_REPEATDUR;
+ ATTRIBUTE_NAMES[324] = ATTR_SELECTION;
+ ATTRIBUTE_NAMES[325] = ATTR_SEPARATOR;
+ ATTRIBUTE_NAMES[326] = ATTR_XML_SPACE;
+ ATTRIBUTE_NAMES[327] = ATTR_AUTOSUBMIT;
+ ATTRIBUTE_NAMES[328] = ATTR_ALPHABETIC;
+ ATTRIBUTE_NAMES[329] = ATTR_ACTIONTYPE;
+ ATTRIBUTE_NAMES[330] = ATTR_ACCUMULATE;
+ ATTRIBUTE_NAMES[331] = ATTR_ARIA_LEVEL;
+ ATTRIBUTE_NAMES[332] = ATTR_COLUMNSPAN;
+ ATTRIBUTE_NAMES[333] = ATTR_CAP_HEIGHT;
+ ATTRIBUTE_NAMES[334] = ATTR_BACKGROUND;
+ ATTRIBUTE_NAMES[335] = ATTR_GLYPH_NAME;
+ ATTRIBUTE_NAMES[336] = ATTR_GROUPALIGN;
+ ATTRIBUTE_NAMES[337] = ATTR_FONTFAMILY;
+ ATTRIBUTE_NAMES[338] = ATTR_FONTWEIGHT;
+ ATTRIBUTE_NAMES[339] = ATTR_FONT_STYLE;
+ ATTRIBUTE_NAMES[340] = ATTR_KEYSPLINES;
+ ATTRIBUTE_NAMES[341] = ATTR_HTTP_EQUIV;
+ ATTRIBUTE_NAMES[342] = ATTR_ONACTIVATE;
+ ATTRIBUTE_NAMES[343] = ATTR_OCCURRENCE;
+ ATTRIBUTE_NAMES[344] = ATTR_IRRELEVANT;
+ ATTRIBUTE_NAMES[345] = ATTR_ONDBLCLICK;
+ ATTRIBUTE_NAMES[346] = ATTR_ONDRAGDROP;
+ ATTRIBUTE_NAMES[347] = ATTR_ONKEYPRESS;
+ ATTRIBUTE_NAMES[348] = ATTR_ONROWENTER;
+ ATTRIBUTE_NAMES[349] = ATTR_ONDRAGOVER;
+ ATTRIBUTE_NAMES[350] = ATTR_ONFOCUSOUT;
+ ATTRIBUTE_NAMES[351] = ATTR_ONMOUSEOUT;
+ ATTRIBUTE_NAMES[352] = ATTR_NUMOCTAVES;
+ ATTRIBUTE_NAMES[353] = ATTR_MARKER_MID;
+ ATTRIBUTE_NAMES[354] = ATTR_MARKER_END;
+ ATTRIBUTE_NAMES[355] = ATTR_TEXTLENGTH;
+ ATTRIBUTE_NAMES[356] = ATTR_VISIBILITY;
+ ATTRIBUTE_NAMES[357] = ATTR_VIEWTARGET;
+ ATTRIBUTE_NAMES[358] = ATTR_VERT_ADV_Y;
+ ATTRIBUTE_NAMES[359] = ATTR_PATHLENGTH;
+ ATTRIBUTE_NAMES[360] = ATTR_REPEAT_MAX;
+ ATTRIBUTE_NAMES[361] = ATTR_RADIOGROUP;
+ ATTRIBUTE_NAMES[362] = ATTR_STOP_COLOR;
+ ATTRIBUTE_NAMES[363] = ATTR_SEPARATORS;
+ ATTRIBUTE_NAMES[364] = ATTR_REPEAT_MIN;
+ ATTRIBUTE_NAMES[365] = ATTR_ROWSPACING;
+ ATTRIBUTE_NAMES[366] = ATTR_ZOOMANDPAN;
+ ATTRIBUTE_NAMES[367] = ATTR_XLINK_TYPE;
+ ATTRIBUTE_NAMES[368] = ATTR_XLINK_ROLE;
+ ATTRIBUTE_NAMES[369] = ATTR_XLINK_HREF;
+ ATTRIBUTE_NAMES[370] = ATTR_XLINK_SHOW;
+ ATTRIBUTE_NAMES[371] = ATTR_ACCENTUNDER;
+ ATTRIBUTE_NAMES[372] = ATTR_ARIA_SECRET;
+ ATTRIBUTE_NAMES[373] = ATTR_ARIA_ATOMIC;
+ ATTRIBUTE_NAMES[374] = ATTR_ARIA_HIDDEN;
+ ATTRIBUTE_NAMES[375] = ATTR_ARIA_FLOWTO;
+ ATTRIBUTE_NAMES[376] = ATTR_ARABIC_FORM;
+ ATTRIBUTE_NAMES[377] = ATTR_CELLPADDING;
+ ATTRIBUTE_NAMES[378] = ATTR_CELLSPACING;
+ ATTRIBUTE_NAMES[379] = ATTR_COLUMNWIDTH;
+ ATTRIBUTE_NAMES[380] = ATTR_CROSSORIGIN;
+ ATTRIBUTE_NAMES[381] = ATTR_COLUMNALIGN;
+ ATTRIBUTE_NAMES[382] = ATTR_COLUMNLINES;
+ ATTRIBUTE_NAMES[383] = ATTR_CONTEXTMENU;
+ ATTRIBUTE_NAMES[384] = ATTR_BASEPROFILE;
+ ATTRIBUTE_NAMES[385] = ATTR_FONT_FAMILY;
+ ATTRIBUTE_NAMES[386] = ATTR_FRAMEBORDER;
+ ATTRIBUTE_NAMES[387] = ATTR_FILTERUNITS;
+ ATTRIBUTE_NAMES[388] = ATTR_FLOOD_COLOR;
+ ATTRIBUTE_NAMES[389] = ATTR_FONT_WEIGHT;
+ ATTRIBUTE_NAMES[390] = ATTR_HORIZ_ADV_X;
+ ATTRIBUTE_NAMES[391] = ATTR_ONDRAGLEAVE;
+ ATTRIBUTE_NAMES[392] = ATTR_ONMOUSEMOVE;
+ ATTRIBUTE_NAMES[393] = ATTR_ORIENTATION;
+ ATTRIBUTE_NAMES[394] = ATTR_ONMOUSEDOWN;
+ ATTRIBUTE_NAMES[395] = ATTR_ONMOUSEOVER;
+ ATTRIBUTE_NAMES[396] = ATTR_ONDRAGENTER;
+ ATTRIBUTE_NAMES[397] = ATTR_IDEOGRAPHIC;
+ ATTRIBUTE_NAMES[398] = ATTR_ONBEFORECUT;
+ ATTRIBUTE_NAMES[399] = ATTR_ONFORMINPUT;
+ ATTRIBUTE_NAMES[400] = ATTR_ONDRAGSTART;
+ ATTRIBUTE_NAMES[401] = ATTR_ONMOVESTART;
+ ATTRIBUTE_NAMES[402] = ATTR_MARKERUNITS;
+ ATTRIBUTE_NAMES[403] = ATTR_MATHVARIANT;
+ ATTRIBUTE_NAMES[404] = ATTR_MARGINWIDTH;
+ ATTRIBUTE_NAMES[405] = ATTR_MARKERWIDTH;
+ ATTRIBUTE_NAMES[406] = ATTR_TEXT_ANCHOR;
+ ATTRIBUTE_NAMES[407] = ATTR_TABLEVALUES;
+ ATTRIBUTE_NAMES[408] = ATTR_SCRIPTLEVEL;
+ ATTRIBUTE_NAMES[409] = ATTR_REPEATCOUNT;
+ ATTRIBUTE_NAMES[410] = ATTR_STITCHTILES;
+ ATTRIBUTE_NAMES[411] = ATTR_STARTOFFSET;
+ ATTRIBUTE_NAMES[412] = ATTR_SCROLLDELAY;
+ ATTRIBUTE_NAMES[413] = ATTR_XMLNS_XLINK;
+ ATTRIBUTE_NAMES[414] = ATTR_XLINK_TITLE;
+ ATTRIBUTE_NAMES[415] = ATTR_ARIA_INVALID;
+ ATTRIBUTE_NAMES[416] = ATTR_ARIA_PRESSED;
+ ATTRIBUTE_NAMES[417] = ATTR_ARIA_CHECKED;
+ ATTRIBUTE_NAMES[418] = ATTR_AUTOCOMPLETE;
+ ATTRIBUTE_NAMES[419] = ATTR_ARIA_SETSIZE;
+ ATTRIBUTE_NAMES[420] = ATTR_ARIA_CHANNEL;
+ ATTRIBUTE_NAMES[421] = ATTR_EQUALCOLUMNS;
+ ATTRIBUTE_NAMES[422] = ATTR_DISPLAYSTYLE;
+ ATTRIBUTE_NAMES[423] = ATTR_DATAFORMATAS;
+ ATTRIBUTE_NAMES[424] = ATTR_FILL_OPACITY;
+ ATTRIBUTE_NAMES[425] = ATTR_FONT_VARIANT;
+ ATTRIBUTE_NAMES[426] = ATTR_FONT_STRETCH;
+ ATTRIBUTE_NAMES[427] = ATTR_FRAMESPACING;
+ ATTRIBUTE_NAMES[428] = ATTR_KERNELMATRIX;
+ ATTRIBUTE_NAMES[429] = ATTR_ONDEACTIVATE;
+ ATTRIBUTE_NAMES[430] = ATTR_ONROWSDELETE;
+ ATTRIBUTE_NAMES[431] = ATTR_ONMOUSELEAVE;
+ ATTRIBUTE_NAMES[432] = ATTR_ONFORMCHANGE;
+ ATTRIBUTE_NAMES[433] = ATTR_ONCELLCHANGE;
+ ATTRIBUTE_NAMES[434] = ATTR_ONMOUSEWHEEL;
+ ATTRIBUTE_NAMES[435] = ATTR_ONMOUSEENTER;
+ ATTRIBUTE_NAMES[436] = ATTR_ONAFTERPRINT;
+ ATTRIBUTE_NAMES[437] = ATTR_ONBEFORECOPY;
+ ATTRIBUTE_NAMES[438] = ATTR_MARGINHEIGHT;
+ ATTRIBUTE_NAMES[439] = ATTR_MARKERHEIGHT;
+ ATTRIBUTE_NAMES[440] = ATTR_MARKER_START;
+ ATTRIBUTE_NAMES[441] = ATTR_MATHEMATICAL;
+ ATTRIBUTE_NAMES[442] = ATTR_LENGTHADJUST;
+ ATTRIBUTE_NAMES[443] = ATTR_UNSELECTABLE;
+ ATTRIBUTE_NAMES[444] = ATTR_UNICODE_BIDI;
+ ATTRIBUTE_NAMES[445] = ATTR_UNITS_PER_EM;
+ ATTRIBUTE_NAMES[446] = ATTR_WORD_SPACING;
+ ATTRIBUTE_NAMES[447] = ATTR_WRITING_MODE;
+ ATTRIBUTE_NAMES[448] = ATTR_V_ALPHABETIC;
+ ATTRIBUTE_NAMES[449] = ATTR_PATTERNUNITS;
+ ATTRIBUTE_NAMES[450] = ATTR_SPREADMETHOD;
+ ATTRIBUTE_NAMES[451] = ATTR_SURFACESCALE;
+ ATTRIBUTE_NAMES[452] = ATTR_STROKE_WIDTH;
+ ATTRIBUTE_NAMES[453] = ATTR_REPEAT_START;
+ ATTRIBUTE_NAMES[454] = ATTR_STDDEVIATION;
+ ATTRIBUTE_NAMES[455] = ATTR_STOP_OPACITY;
+ ATTRIBUTE_NAMES[456] = ATTR_ARIA_CONTROLS;
+ ATTRIBUTE_NAMES[457] = ATTR_ARIA_HASPOPUP;
+ ATTRIBUTE_NAMES[458] = ATTR_ACCENT_HEIGHT;
+ ATTRIBUTE_NAMES[459] = ATTR_ARIA_VALUENOW;
+ ATTRIBUTE_NAMES[460] = ATTR_ARIA_RELEVANT;
+ ATTRIBUTE_NAMES[461] = ATTR_ARIA_POSINSET;
+ ATTRIBUTE_NAMES[462] = ATTR_ARIA_VALUEMAX;
+ ATTRIBUTE_NAMES[463] = ATTR_ARIA_READONLY;
+ ATTRIBUTE_NAMES[464] = ATTR_ARIA_SELECTED;
+ ATTRIBUTE_NAMES[465] = ATTR_ARIA_REQUIRED;
+ ATTRIBUTE_NAMES[466] = ATTR_ARIA_EXPANDED;
+ ATTRIBUTE_NAMES[467] = ATTR_ARIA_DISABLED;
+ ATTRIBUTE_NAMES[468] = ATTR_ATTRIBUTETYPE;
+ ATTRIBUTE_NAMES[469] = ATTR_ATTRIBUTENAME;
+ ATTRIBUTE_NAMES[470] = ATTR_ARIA_DATATYPE;
+ ATTRIBUTE_NAMES[471] = ATTR_ARIA_VALUEMIN;
+ ATTRIBUTE_NAMES[472] = ATTR_BASEFREQUENCY;
+ ATTRIBUTE_NAMES[473] = ATTR_COLUMNSPACING;
+ ATTRIBUTE_NAMES[474] = ATTR_COLOR_PROFILE;
+ ATTRIBUTE_NAMES[475] = ATTR_CLIPPATHUNITS;
+ ATTRIBUTE_NAMES[476] = ATTR_DEFINITIONURL;
+ ATTRIBUTE_NAMES[477] = ATTR_GRADIENTUNITS;
+ ATTRIBUTE_NAMES[478] = ATTR_FLOOD_OPACITY;
+ ATTRIBUTE_NAMES[479] = ATTR_ONAFTERUPDATE;
+ ATTRIBUTE_NAMES[480] = ATTR_ONERRORUPDATE;
+ ATTRIBUTE_NAMES[481] = ATTR_ONBEFOREPASTE;
+ ATTRIBUTE_NAMES[482] = ATTR_ONLOSECAPTURE;
+ ATTRIBUTE_NAMES[483] = ATTR_ONCONTEXTMENU;
+ ATTRIBUTE_NAMES[484] = ATTR_ONSELECTSTART;
+ ATTRIBUTE_NAMES[485] = ATTR_ONBEFOREPRINT;
+ ATTRIBUTE_NAMES[486] = ATTR_MOVABLELIMITS;
+ ATTRIBUTE_NAMES[487] = ATTR_LINETHICKNESS;
+ ATTRIBUTE_NAMES[488] = ATTR_UNICODE_RANGE;
+ ATTRIBUTE_NAMES[489] = ATTR_THINMATHSPACE;
+ ATTRIBUTE_NAMES[490] = ATTR_VERT_ORIGIN_X;
+ ATTRIBUTE_NAMES[491] = ATTR_VERT_ORIGIN_Y;
+ ATTRIBUTE_NAMES[492] = ATTR_V_IDEOGRAPHIC;
+ ATTRIBUTE_NAMES[493] = ATTR_PRESERVEALPHA;
+ ATTRIBUTE_NAMES[494] = ATTR_SCRIPTMINSIZE;
+ ATTRIBUTE_NAMES[495] = ATTR_SPECIFICATION;
+ ATTRIBUTE_NAMES[496] = ATTR_XLINK_ACTUATE;
+ ATTRIBUTE_NAMES[497] = ATTR_XLINK_ARCROLE;
+ ATTRIBUTE_NAMES[498] = ATTR_ACCEPT_CHARSET;
+ ATTRIBUTE_NAMES[499] = ATTR_ALIGNMENTSCOPE;
+ ATTRIBUTE_NAMES[500] = ATTR_ARIA_MULTILINE;
+ ATTRIBUTE_NAMES[501] = ATTR_BASELINE_SHIFT;
+ ATTRIBUTE_NAMES[502] = ATTR_HORIZ_ORIGIN_X;
+ ATTRIBUTE_NAMES[503] = ATTR_HORIZ_ORIGIN_Y;
+ ATTRIBUTE_NAMES[504] = ATTR_ONBEFOREUPDATE;
+ ATTRIBUTE_NAMES[505] = ATTR_ONFILTERCHANGE;
+ ATTRIBUTE_NAMES[506] = ATTR_ONROWSINSERTED;
+ ATTRIBUTE_NAMES[507] = ATTR_ONBEFOREUNLOAD;
+ ATTRIBUTE_NAMES[508] = ATTR_MATHBACKGROUND;
+ ATTRIBUTE_NAMES[509] = ATTR_LETTER_SPACING;
+ ATTRIBUTE_NAMES[510] = ATTR_LIGHTING_COLOR;
+ ATTRIBUTE_NAMES[511] = ATTR_THICKMATHSPACE;
+ ATTRIBUTE_NAMES[512] = ATTR_TEXT_RENDERING;
+ ATTRIBUTE_NAMES[513] = ATTR_V_MATHEMATICAL;
+ ATTRIBUTE_NAMES[514] = ATTR_POINTER_EVENTS;
+ ATTRIBUTE_NAMES[515] = ATTR_PRIMITIVEUNITS;
+ ATTRIBUTE_NAMES[516] = ATTR_REFERRERPOLICY;
+ ATTRIBUTE_NAMES[517] = ATTR_SYSTEMLANGUAGE;
+ ATTRIBUTE_NAMES[518] = ATTR_STROKE_LINECAP;
+ ATTRIBUTE_NAMES[519] = ATTR_SUBSCRIPTSHIFT;
+ ATTRIBUTE_NAMES[520] = ATTR_STROKE_OPACITY;
+ ATTRIBUTE_NAMES[521] = ATTR_ARIA_DROPEFFECT;
+ ATTRIBUTE_NAMES[522] = ATTR_ARIA_LABELLEDBY;
+ ATTRIBUTE_NAMES[523] = ATTR_ARIA_TEMPLATEID;
+ ATTRIBUTE_NAMES[524] = ATTR_COLOR_RENDERING;
+ ATTRIBUTE_NAMES[525] = ATTR_CONTENTEDITABLE;
+ ATTRIBUTE_NAMES[526] = ATTR_DIFFUSECONSTANT;
+ ATTRIBUTE_NAMES[527] = ATTR_ONDATAAVAILABLE;
+ ATTRIBUTE_NAMES[528] = ATTR_ONCONTROLSELECT;
+ ATTRIBUTE_NAMES[529] = ATTR_IMAGE_RENDERING;
+ ATTRIBUTE_NAMES[530] = ATTR_MEDIUMMATHSPACE;
+ ATTRIBUTE_NAMES[531] = ATTR_TEXT_DECORATION;
+ ATTRIBUTE_NAMES[532] = ATTR_SHAPE_RENDERING;
+ ATTRIBUTE_NAMES[533] = ATTR_STROKE_LINEJOIN;
+ ATTRIBUTE_NAMES[534] = ATTR_REPEAT_TEMPLATE;
+ ATTRIBUTE_NAMES[535] = ATTR_ARIA_DESCRIBEDBY;
+ ATTRIBUTE_NAMES[536] = ATTR_FONT_SIZE_ADJUST;
+ ATTRIBUTE_NAMES[537] = ATTR_KERNELUNITLENGTH;
+ ATTRIBUTE_NAMES[538] = ATTR_ONBEFOREACTIVATE;
+ ATTRIBUTE_NAMES[539] = ATTR_ONPROPERTYCHANGE;
+ ATTRIBUTE_NAMES[540] = ATTR_ONDATASETCHANGED;
+ ATTRIBUTE_NAMES[541] = ATTR_MASKCONTENTUNITS;
+ ATTRIBUTE_NAMES[542] = ATTR_PATTERNTRANSFORM;
+ ATTRIBUTE_NAMES[543] = ATTR_REQUIREDFEATURES;
+ ATTRIBUTE_NAMES[544] = ATTR_RENDERING_INTENT;
+ ATTRIBUTE_NAMES[545] = ATTR_SPECULAREXPONENT;
+ ATTRIBUTE_NAMES[546] = ATTR_SPECULARCONSTANT;
+ ATTRIBUTE_NAMES[547] = ATTR_SUPERSCRIPTSHIFT;
+ ATTRIBUTE_NAMES[548] = ATTR_STROKE_DASHARRAY;
+ ATTRIBUTE_NAMES[549] = ATTR_XCHANNELSELECTOR;
+ ATTRIBUTE_NAMES[550] = ATTR_YCHANNELSELECTOR;
+ ATTRIBUTE_NAMES[551] = ATTR_ARIA_AUTOCOMPLETE;
+ ATTRIBUTE_NAMES[552] = ATTR_ENABLE_BACKGROUND;
+ ATTRIBUTE_NAMES[553] = ATTR_DOMINANT_BASELINE;
+ ATTRIBUTE_NAMES[554] = ATTR_GRADIENTTRANSFORM;
+ ATTRIBUTE_NAMES[555] = ATTR_ONBEFORDEACTIVATE;
+ ATTRIBUTE_NAMES[556] = ATTR_ONDATASETCOMPLETE;
+ ATTRIBUTE_NAMES[557] = ATTR_OVERLINE_POSITION;
+ ATTRIBUTE_NAMES[558] = ATTR_ONBEFOREEDITFOCUS;
+ ATTRIBUTE_NAMES[559] = ATTR_LIMITINGCONEANGLE;
+ ATTRIBUTE_NAMES[560] = ATTR_VERYTHINMATHSPACE;
+ ATTRIBUTE_NAMES[561] = ATTR_STROKE_DASHOFFSET;
+ ATTRIBUTE_NAMES[562] = ATTR_STROKE_MITERLIMIT;
+ ATTRIBUTE_NAMES[563] = ATTR_ALIGNMENT_BASELINE;
+ ATTRIBUTE_NAMES[564] = ATTR_ONREADYSTATECHANGE;
+ ATTRIBUTE_NAMES[565] = ATTR_OVERLINE_THICKNESS;
+ ATTRIBUTE_NAMES[566] = ATTR_UNDERLINE_POSITION;
+ ATTRIBUTE_NAMES[567] = ATTR_VERYTHICKMATHSPACE;
+ ATTRIBUTE_NAMES[568] = ATTR_REQUIREDEXTENSIONS;
+ ATTRIBUTE_NAMES[569] = ATTR_COLOR_INTERPOLATION;
+ ATTRIBUTE_NAMES[570] = ATTR_UNDERLINE_THICKNESS;
+ ATTRIBUTE_NAMES[571] = ATTR_PRESERVEASPECTRATIO;
+ ATTRIBUTE_NAMES[572] = ATTR_PATTERNCONTENTUNITS;
+ ATTRIBUTE_NAMES[573] = ATTR_ARIA_MULTISELECTABLE;
+ ATTRIBUTE_NAMES[574] = ATTR_SCRIPTSIZEMULTIPLIER;
+ ATTRIBUTE_NAMES[575] = ATTR_ARIA_ACTIVEDESCENDANT;
+ ATTRIBUTE_NAMES[576] = ATTR_VERYVERYTHINMATHSPACE;
+ ATTRIBUTE_NAMES[577] = ATTR_VERYVERYTHICKMATHSPACE;
+ ATTRIBUTE_NAMES[578] = ATTR_STRIKETHROUGH_POSITION;
+ ATTRIBUTE_NAMES[579] = ATTR_STRIKETHROUGH_THICKNESS;
+ ATTRIBUTE_NAMES[580] = ATTR_GLYPH_ORIENTATION_VERTICAL;
+ ATTRIBUTE_NAMES[581] = ATTR_COLOR_INTERPOLATION_FILTERS;
+ ATTRIBUTE_NAMES[582] = ATTR_GLYPH_ORIENTATION_HORIZONTAL;
+}
+
+void
+nsHtml5AttributeName::releaseStatics()
+{
+ delete[] ALL_NO_NS;
+ delete[] XMLNS_NS;
+ delete[] XML_NS;
+ delete[] XLINK_NS;
+ delete[] ALL_NO_PREFIX;
+ delete[] XMLNS_PREFIX;
+ delete[] XLINK_PREFIX;
+ delete[] XML_PREFIX;
+ delete ATTR_D;
+ delete ATTR_K;
+ delete ATTR_R;
+ delete ATTR_X;
+ delete ATTR_Y;
+ delete ATTR_Z;
+ delete ATTR_BY;
+ delete ATTR_CX;
+ delete ATTR_CY;
+ delete ATTR_DX;
+ delete ATTR_DY;
+ delete ATTR_G2;
+ delete ATTR_G1;
+ delete ATTR_FX;
+ delete ATTR_FY;
+ delete ATTR_K4;
+ delete ATTR_K2;
+ delete ATTR_K3;
+ delete ATTR_K1;
+ delete ATTR_ID;
+ delete ATTR_IN;
+ delete ATTR_U2;
+ delete ATTR_U1;
+ delete ATTR_RT;
+ delete ATTR_RX;
+ delete ATTR_RY;
+ delete ATTR_TO;
+ delete ATTR_Y2;
+ delete ATTR_Y1;
+ delete ATTR_X1;
+ delete ATTR_X2;
+ delete ATTR_ALT;
+ delete ATTR_DIR;
+ delete ATTR_DUR;
+ delete ATTR_END;
+ delete ATTR_FOR;
+ delete ATTR_IN2;
+ delete ATTR_MAX;
+ delete ATTR_MIN;
+ delete ATTR_LOW;
+ delete ATTR_REL;
+ delete ATTR_REV;
+ delete ATTR_SRC;
+ delete ATTR_AXIS;
+ delete ATTR_ABBR;
+ delete ATTR_BBOX;
+ delete ATTR_CITE;
+ delete ATTR_CODE;
+ delete ATTR_BIAS;
+ delete ATTR_COLS;
+ delete ATTR_CLIP;
+ delete ATTR_CHAR;
+ delete ATTR_BASE;
+ delete ATTR_EDGE;
+ delete ATTR_DATA;
+ delete ATTR_FILL;
+ delete ATTR_FROM;
+ delete ATTR_FORM;
+ delete ATTR_FACE;
+ delete ATTR_HIGH;
+ delete ATTR_HREF;
+ delete ATTR_OPEN;
+ delete ATTR_ICON;
+ delete ATTR_NAME;
+ delete ATTR_MODE;
+ delete ATTR_MASK;
+ delete ATTR_LINK;
+ delete ATTR_LANG;
+ delete ATTR_LOOP;
+ delete ATTR_LIST;
+ delete ATTR_TYPE;
+ delete ATTR_WHEN;
+ delete ATTR_WRAP;
+ delete ATTR_TEXT;
+ delete ATTR_PATH;
+ delete ATTR_PING;
+ delete ATTR_REFX;
+ delete ATTR_REFY;
+ delete ATTR_SIZE;
+ delete ATTR_SEED;
+ delete ATTR_ROWS;
+ delete ATTR_SPAN;
+ delete ATTR_STEP;
+ delete ATTR_ROLE;
+ delete ATTR_XREF;
+ delete ATTR_ASYNC;
+ delete ATTR_ALINK;
+ delete ATTR_ALIGN;
+ delete ATTR_CLOSE;
+ delete ATTR_COLOR;
+ delete ATTR_CLASS;
+ delete ATTR_CLEAR;
+ delete ATTR_BEGIN;
+ delete ATTR_DEPTH;
+ delete ATTR_DEFER;
+ delete ATTR_FENCE;
+ delete ATTR_FRAME;
+ delete ATTR_ISMAP;
+ delete ATTR_ONEND;
+ delete ATTR_INDEX;
+ delete ATTR_ORDER;
+ delete ATTR_OTHER;
+ delete ATTR_ONCUT;
+ delete ATTR_NARGS;
+ delete ATTR_MEDIA;
+ delete ATTR_LABEL;
+ delete ATTR_LOCAL;
+ delete ATTR_WIDTH;
+ delete ATTR_TITLE;
+ delete ATTR_VLINK;
+ delete ATTR_VALUE;
+ delete ATTR_SLOPE;
+ delete ATTR_SHAPE;
+ delete ATTR_SCOPE;
+ delete ATTR_SCALE;
+ delete ATTR_SPEED;
+ delete ATTR_STYLE;
+ delete ATTR_RULES;
+ delete ATTR_STEMH;
+ delete ATTR_SIZES;
+ delete ATTR_STEMV;
+ delete ATTR_START;
+ delete ATTR_XMLNS;
+ delete ATTR_ACCEPT;
+ delete ATTR_ACCENT;
+ delete ATTR_ASCENT;
+ delete ATTR_ACTIVE;
+ delete ATTR_ALTIMG;
+ delete ATTR_ACTION;
+ delete ATTR_BORDER;
+ delete ATTR_CURSOR;
+ delete ATTR_COORDS;
+ delete ATTR_FILTER;
+ delete ATTR_FORMAT;
+ delete ATTR_HIDDEN;
+ delete ATTR_HSPACE;
+ delete ATTR_HEIGHT;
+ delete ATTR_ONMOVE;
+ delete ATTR_ONLOAD;
+ delete ATTR_ONDRAG;
+ delete ATTR_ORIGIN;
+ delete ATTR_ONZOOM;
+ delete ATTR_ONHELP;
+ delete ATTR_ONSTOP;
+ delete ATTR_ONDROP;
+ delete ATTR_ONBLUR;
+ delete ATTR_OBJECT;
+ delete ATTR_OFFSET;
+ delete ATTR_ORIENT;
+ delete ATTR_ONCOPY;
+ delete ATTR_NOWRAP;
+ delete ATTR_NOHREF;
+ delete ATTR_MACROS;
+ delete ATTR_METHOD;
+ delete ATTR_LOWSRC;
+ delete ATTR_LSPACE;
+ delete ATTR_LQUOTE;
+ delete ATTR_USEMAP;
+ delete ATTR_WIDTHS;
+ delete ATTR_TARGET;
+ delete ATTR_VALUES;
+ delete ATTR_VALIGN;
+ delete ATTR_VSPACE;
+ delete ATTR_POSTER;
+ delete ATTR_POINTS;
+ delete ATTR_PROMPT;
+ delete ATTR_SRCDOC;
+ delete ATTR_SCOPED;
+ delete ATTR_STRING;
+ delete ATTR_SCHEME;
+ delete ATTR_STROKE;
+ delete ATTR_RADIUS;
+ delete ATTR_RESULT;
+ delete ATTR_REPEAT;
+ delete ATTR_SRCSET;
+ delete ATTR_RSPACE;
+ delete ATTR_ROTATE;
+ delete ATTR_RQUOTE;
+ delete ATTR_ALTTEXT;
+ delete ATTR_ARCHIVE;
+ delete ATTR_AZIMUTH;
+ delete ATTR_CLOSURE;
+ delete ATTR_CHECKED;
+ delete ATTR_CLASSID;
+ delete ATTR_CHAROFF;
+ delete ATTR_BGCOLOR;
+ delete ATTR_COLSPAN;
+ delete ATTR_CHARSET;
+ delete ATTR_COMPACT;
+ delete ATTR_CONTENT;
+ delete ATTR_ENCTYPE;
+ delete ATTR_DATASRC;
+ delete ATTR_DATAFLD;
+ delete ATTR_DECLARE;
+ delete ATTR_DISPLAY;
+ delete ATTR_DIVISOR;
+ delete ATTR_DEFAULT;
+ delete ATTR_DESCENT;
+ delete ATTR_KERNING;
+ delete ATTR_HANGING;
+ delete ATTR_HEADERS;
+ delete ATTR_ONPASTE;
+ delete ATTR_ONCLICK;
+ delete ATTR_OPTIMUM;
+ delete ATTR_ONBEGIN;
+ delete ATTR_ONKEYUP;
+ delete ATTR_ONFOCUS;
+ delete ATTR_ONERROR;
+ delete ATTR_ONINPUT;
+ delete ATTR_ONABORT;
+ delete ATTR_ONSTART;
+ delete ATTR_ONRESET;
+ delete ATTR_OPACITY;
+ delete ATTR_NOSHADE;
+ delete ATTR_MINSIZE;
+ delete ATTR_MAXSIZE;
+ delete ATTR_LARGEOP;
+ delete ATTR_UNICODE;
+ delete ATTR_TARGETX;
+ delete ATTR_TARGETY;
+ delete ATTR_VIEWBOX;
+ delete ATTR_VERSION;
+ delete ATTR_PATTERN;
+ delete ATTR_PROFILE;
+ delete ATTR_SPACING;
+ delete ATTR_RESTART;
+ delete ATTR_ROWSPAN;
+ delete ATTR_SANDBOX;
+ delete ATTR_SUMMARY;
+ delete ATTR_STANDBY;
+ delete ATTR_REPLACE;
+ delete ATTR_AUTOPLAY;
+ delete ATTR_ADDITIVE;
+ delete ATTR_CALCMODE;
+ delete ATTR_CODETYPE;
+ delete ATTR_CODEBASE;
+ delete ATTR_CONTROLS;
+ delete ATTR_BEVELLED;
+ delete ATTR_BASELINE;
+ delete ATTR_EXPONENT;
+ delete ATTR_EDGEMODE;
+ delete ATTR_ENCODING;
+ delete ATTR_GLYPHREF;
+ delete ATTR_DATETIME;
+ delete ATTR_DISABLED;
+ delete ATTR_FONTSIZE;
+ delete ATTR_KEYTIMES;
+ delete ATTR_PANOSE_1;
+ delete ATTR_HREFLANG;
+ delete ATTR_ONRESIZE;
+ delete ATTR_ONCHANGE;
+ delete ATTR_ONBOUNCE;
+ delete ATTR_ONUNLOAD;
+ delete ATTR_ONFINISH;
+ delete ATTR_ONSCROLL;
+ delete ATTR_OPERATOR;
+ delete ATTR_OVERFLOW;
+ delete ATTR_ONSUBMIT;
+ delete ATTR_ONREPEAT;
+ delete ATTR_ONSELECT;
+ delete ATTR_NOTATION;
+ delete ATTR_NORESIZE;
+ delete ATTR_MANIFEST;
+ delete ATTR_MATHSIZE;
+ delete ATTR_MULTIPLE;
+ delete ATTR_LONGDESC;
+ delete ATTR_LANGUAGE;
+ delete ATTR_TEMPLATE;
+ delete ATTR_TABINDEX;
+ delete ATTR_PROPERTY;
+ delete ATTR_READONLY;
+ delete ATTR_SELECTED;
+ delete ATTR_ROWLINES;
+ delete ATTR_SEAMLESS;
+ delete ATTR_ROWALIGN;
+ delete ATTR_STRETCHY;
+ delete ATTR_REQUIRED;
+ delete ATTR_XML_BASE;
+ delete ATTR_XML_LANG;
+ delete ATTR_X_HEIGHT;
+ delete ATTR_ARIA_OWNS;
+ delete ATTR_AUTOFOCUS;
+ delete ATTR_ARIA_SORT;
+ delete ATTR_ACCESSKEY;
+ delete ATTR_ARIA_BUSY;
+ delete ATTR_ARIA_GRAB;
+ delete ATTR_AMPLITUDE;
+ delete ATTR_ARIA_LIVE;
+ delete ATTR_CLIP_RULE;
+ delete ATTR_CLIP_PATH;
+ delete ATTR_EQUALROWS;
+ delete ATTR_ELEVATION;
+ delete ATTR_DIRECTION;
+ delete ATTR_DRAGGABLE;
+ delete ATTR_FILL_RULE;
+ delete ATTR_FONTSTYLE;
+ delete ATTR_FONT_SIZE;
+ delete ATTR_KEYSYSTEM;
+ delete ATTR_KEYPOINTS;
+ delete ATTR_HIDEFOCUS;
+ delete ATTR_ONMESSAGE;
+ delete ATTR_INTERCEPT;
+ delete ATTR_ONDRAGEND;
+ delete ATTR_ONMOVEEND;
+ delete ATTR_ONINVALID;
+ delete ATTR_INTEGRITY;
+ delete ATTR_ONKEYDOWN;
+ delete ATTR_ONFOCUSIN;
+ delete ATTR_ONMOUSEUP;
+ delete ATTR_INPUTMODE;
+ delete ATTR_ONROWEXIT;
+ delete ATTR_MATHCOLOR;
+ delete ATTR_MASKUNITS;
+ delete ATTR_MAXLENGTH;
+ delete ATTR_LINEBREAK;
+ delete ATTR_TRANSFORM;
+ delete ATTR_V_HANGING;
+ delete ATTR_VALUETYPE;
+ delete ATTR_POINTSATZ;
+ delete ATTR_POINTSATX;
+ delete ATTR_POINTSATY;
+ delete ATTR_SYMMETRIC;
+ delete ATTR_SCROLLING;
+ delete ATTR_REPEATDUR;
+ delete ATTR_SELECTION;
+ delete ATTR_SEPARATOR;
+ delete ATTR_XML_SPACE;
+ delete ATTR_AUTOSUBMIT;
+ delete ATTR_ALPHABETIC;
+ delete ATTR_ACTIONTYPE;
+ delete ATTR_ACCUMULATE;
+ delete ATTR_ARIA_LEVEL;
+ delete ATTR_COLUMNSPAN;
+ delete ATTR_CAP_HEIGHT;
+ delete ATTR_BACKGROUND;
+ delete ATTR_GLYPH_NAME;
+ delete ATTR_GROUPALIGN;
+ delete ATTR_FONTFAMILY;
+ delete ATTR_FONTWEIGHT;
+ delete ATTR_FONT_STYLE;
+ delete ATTR_KEYSPLINES;
+ delete ATTR_HTTP_EQUIV;
+ delete ATTR_ONACTIVATE;
+ delete ATTR_OCCURRENCE;
+ delete ATTR_IRRELEVANT;
+ delete ATTR_ONDBLCLICK;
+ delete ATTR_ONDRAGDROP;
+ delete ATTR_ONKEYPRESS;
+ delete ATTR_ONROWENTER;
+ delete ATTR_ONDRAGOVER;
+ delete ATTR_ONFOCUSOUT;
+ delete ATTR_ONMOUSEOUT;
+ delete ATTR_NUMOCTAVES;
+ delete ATTR_MARKER_MID;
+ delete ATTR_MARKER_END;
+ delete ATTR_TEXTLENGTH;
+ delete ATTR_VISIBILITY;
+ delete ATTR_VIEWTARGET;
+ delete ATTR_VERT_ADV_Y;
+ delete ATTR_PATHLENGTH;
+ delete ATTR_REPEAT_MAX;
+ delete ATTR_RADIOGROUP;
+ delete ATTR_STOP_COLOR;
+ delete ATTR_SEPARATORS;
+ delete ATTR_REPEAT_MIN;
+ delete ATTR_ROWSPACING;
+ delete ATTR_ZOOMANDPAN;
+ delete ATTR_XLINK_TYPE;
+ delete ATTR_XLINK_ROLE;
+ delete ATTR_XLINK_HREF;
+ delete ATTR_XLINK_SHOW;
+ delete ATTR_ACCENTUNDER;
+ delete ATTR_ARIA_SECRET;
+ delete ATTR_ARIA_ATOMIC;
+ delete ATTR_ARIA_HIDDEN;
+ delete ATTR_ARIA_FLOWTO;
+ delete ATTR_ARABIC_FORM;
+ delete ATTR_CELLPADDING;
+ delete ATTR_CELLSPACING;
+ delete ATTR_COLUMNWIDTH;
+ delete ATTR_CROSSORIGIN;
+ delete ATTR_COLUMNALIGN;
+ delete ATTR_COLUMNLINES;
+ delete ATTR_CONTEXTMENU;
+ delete ATTR_BASEPROFILE;
+ delete ATTR_FONT_FAMILY;
+ delete ATTR_FRAMEBORDER;
+ delete ATTR_FILTERUNITS;
+ delete ATTR_FLOOD_COLOR;
+ delete ATTR_FONT_WEIGHT;
+ delete ATTR_HORIZ_ADV_X;
+ delete ATTR_ONDRAGLEAVE;
+ delete ATTR_ONMOUSEMOVE;
+ delete ATTR_ORIENTATION;
+ delete ATTR_ONMOUSEDOWN;
+ delete ATTR_ONMOUSEOVER;
+ delete ATTR_ONDRAGENTER;
+ delete ATTR_IDEOGRAPHIC;
+ delete ATTR_ONBEFORECUT;
+ delete ATTR_ONFORMINPUT;
+ delete ATTR_ONDRAGSTART;
+ delete ATTR_ONMOVESTART;
+ delete ATTR_MARKERUNITS;
+ delete ATTR_MATHVARIANT;
+ delete ATTR_MARGINWIDTH;
+ delete ATTR_MARKERWIDTH;
+ delete ATTR_TEXT_ANCHOR;
+ delete ATTR_TABLEVALUES;
+ delete ATTR_SCRIPTLEVEL;
+ delete ATTR_REPEATCOUNT;
+ delete ATTR_STITCHTILES;
+ delete ATTR_STARTOFFSET;
+ delete ATTR_SCROLLDELAY;
+ delete ATTR_XMLNS_XLINK;
+ delete ATTR_XLINK_TITLE;
+ delete ATTR_ARIA_INVALID;
+ delete ATTR_ARIA_PRESSED;
+ delete ATTR_ARIA_CHECKED;
+ delete ATTR_AUTOCOMPLETE;
+ delete ATTR_ARIA_SETSIZE;
+ delete ATTR_ARIA_CHANNEL;
+ delete ATTR_EQUALCOLUMNS;
+ delete ATTR_DISPLAYSTYLE;
+ delete ATTR_DATAFORMATAS;
+ delete ATTR_FILL_OPACITY;
+ delete ATTR_FONT_VARIANT;
+ delete ATTR_FONT_STRETCH;
+ delete ATTR_FRAMESPACING;
+ delete ATTR_KERNELMATRIX;
+ delete ATTR_ONDEACTIVATE;
+ delete ATTR_ONROWSDELETE;
+ delete ATTR_ONMOUSELEAVE;
+ delete ATTR_ONFORMCHANGE;
+ delete ATTR_ONCELLCHANGE;
+ delete ATTR_ONMOUSEWHEEL;
+ delete ATTR_ONMOUSEENTER;
+ delete ATTR_ONAFTERPRINT;
+ delete ATTR_ONBEFORECOPY;
+ delete ATTR_MARGINHEIGHT;
+ delete ATTR_MARKERHEIGHT;
+ delete ATTR_MARKER_START;
+ delete ATTR_MATHEMATICAL;
+ delete ATTR_LENGTHADJUST;
+ delete ATTR_UNSELECTABLE;
+ delete ATTR_UNICODE_BIDI;
+ delete ATTR_UNITS_PER_EM;
+ delete ATTR_WORD_SPACING;
+ delete ATTR_WRITING_MODE;
+ delete ATTR_V_ALPHABETIC;
+ delete ATTR_PATTERNUNITS;
+ delete ATTR_SPREADMETHOD;
+ delete ATTR_SURFACESCALE;
+ delete ATTR_STROKE_WIDTH;
+ delete ATTR_REPEAT_START;
+ delete ATTR_STDDEVIATION;
+ delete ATTR_STOP_OPACITY;
+ delete ATTR_ARIA_CONTROLS;
+ delete ATTR_ARIA_HASPOPUP;
+ delete ATTR_ACCENT_HEIGHT;
+ delete ATTR_ARIA_VALUENOW;
+ delete ATTR_ARIA_RELEVANT;
+ delete ATTR_ARIA_POSINSET;
+ delete ATTR_ARIA_VALUEMAX;
+ delete ATTR_ARIA_READONLY;
+ delete ATTR_ARIA_SELECTED;
+ delete ATTR_ARIA_REQUIRED;
+ delete ATTR_ARIA_EXPANDED;
+ delete ATTR_ARIA_DISABLED;
+ delete ATTR_ATTRIBUTETYPE;
+ delete ATTR_ATTRIBUTENAME;
+ delete ATTR_ARIA_DATATYPE;
+ delete ATTR_ARIA_VALUEMIN;
+ delete ATTR_BASEFREQUENCY;
+ delete ATTR_COLUMNSPACING;
+ delete ATTR_COLOR_PROFILE;
+ delete ATTR_CLIPPATHUNITS;
+ delete ATTR_DEFINITIONURL;
+ delete ATTR_GRADIENTUNITS;
+ delete ATTR_FLOOD_OPACITY;
+ delete ATTR_ONAFTERUPDATE;
+ delete ATTR_ONERRORUPDATE;
+ delete ATTR_ONBEFOREPASTE;
+ delete ATTR_ONLOSECAPTURE;
+ delete ATTR_ONCONTEXTMENU;
+ delete ATTR_ONSELECTSTART;
+ delete ATTR_ONBEFOREPRINT;
+ delete ATTR_MOVABLELIMITS;
+ delete ATTR_LINETHICKNESS;
+ delete ATTR_UNICODE_RANGE;
+ delete ATTR_THINMATHSPACE;
+ delete ATTR_VERT_ORIGIN_X;
+ delete ATTR_VERT_ORIGIN_Y;
+ delete ATTR_V_IDEOGRAPHIC;
+ delete ATTR_PRESERVEALPHA;
+ delete ATTR_SCRIPTMINSIZE;
+ delete ATTR_SPECIFICATION;
+ delete ATTR_XLINK_ACTUATE;
+ delete ATTR_XLINK_ARCROLE;
+ delete ATTR_ACCEPT_CHARSET;
+ delete ATTR_ALIGNMENTSCOPE;
+ delete ATTR_ARIA_MULTILINE;
+ delete ATTR_BASELINE_SHIFT;
+ delete ATTR_HORIZ_ORIGIN_X;
+ delete ATTR_HORIZ_ORIGIN_Y;
+ delete ATTR_ONBEFOREUPDATE;
+ delete ATTR_ONFILTERCHANGE;
+ delete ATTR_ONROWSINSERTED;
+ delete ATTR_ONBEFOREUNLOAD;
+ delete ATTR_MATHBACKGROUND;
+ delete ATTR_LETTER_SPACING;
+ delete ATTR_LIGHTING_COLOR;
+ delete ATTR_THICKMATHSPACE;
+ delete ATTR_TEXT_RENDERING;
+ delete ATTR_V_MATHEMATICAL;
+ delete ATTR_POINTER_EVENTS;
+ delete ATTR_PRIMITIVEUNITS;
+ delete ATTR_REFERRERPOLICY;
+ delete ATTR_SYSTEMLANGUAGE;
+ delete ATTR_STROKE_LINECAP;
+ delete ATTR_SUBSCRIPTSHIFT;
+ delete ATTR_STROKE_OPACITY;
+ delete ATTR_ARIA_DROPEFFECT;
+ delete ATTR_ARIA_LABELLEDBY;
+ delete ATTR_ARIA_TEMPLATEID;
+ delete ATTR_COLOR_RENDERING;
+ delete ATTR_CONTENTEDITABLE;
+ delete ATTR_DIFFUSECONSTANT;
+ delete ATTR_ONDATAAVAILABLE;
+ delete ATTR_ONCONTROLSELECT;
+ delete ATTR_IMAGE_RENDERING;
+ delete ATTR_MEDIUMMATHSPACE;
+ delete ATTR_TEXT_DECORATION;
+ delete ATTR_SHAPE_RENDERING;
+ delete ATTR_STROKE_LINEJOIN;
+ delete ATTR_REPEAT_TEMPLATE;
+ delete ATTR_ARIA_DESCRIBEDBY;
+ delete ATTR_FONT_SIZE_ADJUST;
+ delete ATTR_KERNELUNITLENGTH;
+ delete ATTR_ONBEFOREACTIVATE;
+ delete ATTR_ONPROPERTYCHANGE;
+ delete ATTR_ONDATASETCHANGED;
+ delete ATTR_MASKCONTENTUNITS;
+ delete ATTR_PATTERNTRANSFORM;
+ delete ATTR_REQUIREDFEATURES;
+ delete ATTR_RENDERING_INTENT;
+ delete ATTR_SPECULAREXPONENT;
+ delete ATTR_SPECULARCONSTANT;
+ delete ATTR_SUPERSCRIPTSHIFT;
+ delete ATTR_STROKE_DASHARRAY;
+ delete ATTR_XCHANNELSELECTOR;
+ delete ATTR_YCHANNELSELECTOR;
+ delete ATTR_ARIA_AUTOCOMPLETE;
+ delete ATTR_ENABLE_BACKGROUND;
+ delete ATTR_DOMINANT_BASELINE;
+ delete ATTR_GRADIENTTRANSFORM;
+ delete ATTR_ONBEFORDEACTIVATE;
+ delete ATTR_ONDATASETCOMPLETE;
+ delete ATTR_OVERLINE_POSITION;
+ delete ATTR_ONBEFOREEDITFOCUS;
+ delete ATTR_LIMITINGCONEANGLE;
+ delete ATTR_VERYTHINMATHSPACE;
+ delete ATTR_STROKE_DASHOFFSET;
+ delete ATTR_STROKE_MITERLIMIT;
+ delete ATTR_ALIGNMENT_BASELINE;
+ delete ATTR_ONREADYSTATECHANGE;
+ delete ATTR_OVERLINE_THICKNESS;
+ delete ATTR_UNDERLINE_POSITION;
+ delete ATTR_VERYTHICKMATHSPACE;
+ delete ATTR_REQUIREDEXTENSIONS;
+ delete ATTR_COLOR_INTERPOLATION;
+ delete ATTR_UNDERLINE_THICKNESS;
+ delete ATTR_PRESERVEASPECTRATIO;
+ delete ATTR_PATTERNCONTENTUNITS;
+ delete ATTR_ARIA_MULTISELECTABLE;
+ delete ATTR_SCRIPTSIZEMULTIPLIER;
+ delete ATTR_ARIA_ACTIVEDESCENDANT;
+ delete ATTR_VERYVERYTHINMATHSPACE;
+ delete ATTR_VERYVERYTHICKMATHSPACE;
+ delete ATTR_STRIKETHROUGH_POSITION;
+ delete ATTR_STRIKETHROUGH_THICKNESS;
+ delete ATTR_GLYPH_ORIENTATION_VERTICAL;
+ delete ATTR_COLOR_INTERPOLATION_FILTERS;
+ delete ATTR_GLYPH_ORIENTATION_HORIZONTAL;
+ delete[] ATTRIBUTE_NAMES;
+}
+
+
diff --git a/parser/html/nsHtml5AttributeName.h b/parser/html/nsHtml5AttributeName.h
new file mode 100644
index 000000000..748dcf3c9
--- /dev/null
+++ b/parser/html/nsHtml5AttributeName.h
@@ -0,0 +1,692 @@
+/*
+ * Copyright (c) 2008-2011 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit AttributeName.java instead and regenerate.
+ */
+
+#ifndef nsHtml5AttributeName_h
+#define nsHtml5AttributeName_h
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5ByteReadable.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
+
+class nsHtml5StreamParser;
+
+class nsHtml5Tokenizer;
+class nsHtml5TreeBuilder;
+class nsHtml5MetaScanner;
+class nsHtml5ElementName;
+class nsHtml5HtmlAttributes;
+class nsHtml5UTF16Buffer;
+class nsHtml5StateSnapshot;
+class nsHtml5Portability;
+
+
+class nsHtml5AttributeName
+{
+ public:
+ static int32_t* ALL_NO_NS;
+ private:
+ static int32_t* XMLNS_NS;
+ static int32_t* XML_NS;
+ static int32_t* XLINK_NS;
+ public:
+ static nsIAtom** ALL_NO_PREFIX;
+ private:
+ static nsIAtom** XMLNS_PREFIX;
+ static nsIAtom** XLINK_PREFIX;
+ static nsIAtom** XML_PREFIX;
+ static nsIAtom** SVG_DIFFERENT(nsIAtom* name, nsIAtom* camel);
+ static nsIAtom** MATH_DIFFERENT(nsIAtom* name, nsIAtom* camel);
+ static nsIAtom** COLONIFIED_LOCAL(nsIAtom* name, nsIAtom* suffix);
+ public:
+ static nsIAtom** SAME_LOCAL(nsIAtom* name);
+ static nsHtml5AttributeName* nameByBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5AtomTable* interner);
+ private:
+ static int32_t bufToHash(char16_t* buf, int32_t len);
+ int32_t* uri;
+ nsIAtom** local;
+ nsIAtom** prefix;
+ protected:
+ nsHtml5AttributeName(int32_t* uri, nsIAtom** local, nsIAtom** prefix);
+ private:
+ static nsHtml5AttributeName* createAttributeName(nsIAtom* name);
+ public:
+ virtual void release();
+ virtual ~nsHtml5AttributeName();
+ virtual nsHtml5AttributeName* cloneAttributeName(nsHtml5AtomTable* interner);
+ int32_t getUri(int32_t mode);
+ nsIAtom* getLocal(int32_t mode);
+ nsIAtom* getPrefix(int32_t mode);
+ bool equalsAnother(nsHtml5AttributeName* another);
+ static nsHtml5AttributeName* ATTR_D;
+ static nsHtml5AttributeName* ATTR_K;
+ static nsHtml5AttributeName* ATTR_R;
+ static nsHtml5AttributeName* ATTR_X;
+ static nsHtml5AttributeName* ATTR_Y;
+ static nsHtml5AttributeName* ATTR_Z;
+ static nsHtml5AttributeName* ATTR_BY;
+ static nsHtml5AttributeName* ATTR_CX;
+ static nsHtml5AttributeName* ATTR_CY;
+ static nsHtml5AttributeName* ATTR_DX;
+ static nsHtml5AttributeName* ATTR_DY;
+ static nsHtml5AttributeName* ATTR_G2;
+ static nsHtml5AttributeName* ATTR_G1;
+ static nsHtml5AttributeName* ATTR_FX;
+ static nsHtml5AttributeName* ATTR_FY;
+ static nsHtml5AttributeName* ATTR_K4;
+ static nsHtml5AttributeName* ATTR_K2;
+ static nsHtml5AttributeName* ATTR_K3;
+ static nsHtml5AttributeName* ATTR_K1;
+ static nsHtml5AttributeName* ATTR_ID;
+ static nsHtml5AttributeName* ATTR_IN;
+ static nsHtml5AttributeName* ATTR_U2;
+ static nsHtml5AttributeName* ATTR_U1;
+ static nsHtml5AttributeName* ATTR_RT;
+ static nsHtml5AttributeName* ATTR_RX;
+ static nsHtml5AttributeName* ATTR_RY;
+ static nsHtml5AttributeName* ATTR_TO;
+ static nsHtml5AttributeName* ATTR_Y2;
+ static nsHtml5AttributeName* ATTR_Y1;
+ static nsHtml5AttributeName* ATTR_X1;
+ static nsHtml5AttributeName* ATTR_X2;
+ static nsHtml5AttributeName* ATTR_ALT;
+ static nsHtml5AttributeName* ATTR_DIR;
+ static nsHtml5AttributeName* ATTR_DUR;
+ static nsHtml5AttributeName* ATTR_END;
+ static nsHtml5AttributeName* ATTR_FOR;
+ static nsHtml5AttributeName* ATTR_IN2;
+ static nsHtml5AttributeName* ATTR_MAX;
+ static nsHtml5AttributeName* ATTR_MIN;
+ static nsHtml5AttributeName* ATTR_LOW;
+ static nsHtml5AttributeName* ATTR_REL;
+ static nsHtml5AttributeName* ATTR_REV;
+ static nsHtml5AttributeName* ATTR_SRC;
+ static nsHtml5AttributeName* ATTR_AXIS;
+ static nsHtml5AttributeName* ATTR_ABBR;
+ static nsHtml5AttributeName* ATTR_BBOX;
+ static nsHtml5AttributeName* ATTR_CITE;
+ static nsHtml5AttributeName* ATTR_CODE;
+ static nsHtml5AttributeName* ATTR_BIAS;
+ static nsHtml5AttributeName* ATTR_COLS;
+ static nsHtml5AttributeName* ATTR_CLIP;
+ static nsHtml5AttributeName* ATTR_CHAR;
+ static nsHtml5AttributeName* ATTR_BASE;
+ static nsHtml5AttributeName* ATTR_EDGE;
+ static nsHtml5AttributeName* ATTR_DATA;
+ static nsHtml5AttributeName* ATTR_FILL;
+ static nsHtml5AttributeName* ATTR_FROM;
+ static nsHtml5AttributeName* ATTR_FORM;
+ static nsHtml5AttributeName* ATTR_FACE;
+ static nsHtml5AttributeName* ATTR_HIGH;
+ static nsHtml5AttributeName* ATTR_HREF;
+ static nsHtml5AttributeName* ATTR_OPEN;
+ static nsHtml5AttributeName* ATTR_ICON;
+ static nsHtml5AttributeName* ATTR_NAME;
+ static nsHtml5AttributeName* ATTR_MODE;
+ static nsHtml5AttributeName* ATTR_MASK;
+ static nsHtml5AttributeName* ATTR_LINK;
+ static nsHtml5AttributeName* ATTR_LANG;
+ static nsHtml5AttributeName* ATTR_LOOP;
+ static nsHtml5AttributeName* ATTR_LIST;
+ static nsHtml5AttributeName* ATTR_TYPE;
+ static nsHtml5AttributeName* ATTR_WHEN;
+ static nsHtml5AttributeName* ATTR_WRAP;
+ static nsHtml5AttributeName* ATTR_TEXT;
+ static nsHtml5AttributeName* ATTR_PATH;
+ static nsHtml5AttributeName* ATTR_PING;
+ static nsHtml5AttributeName* ATTR_REFX;
+ static nsHtml5AttributeName* ATTR_REFY;
+ static nsHtml5AttributeName* ATTR_SIZE;
+ static nsHtml5AttributeName* ATTR_SEED;
+ static nsHtml5AttributeName* ATTR_ROWS;
+ static nsHtml5AttributeName* ATTR_SPAN;
+ static nsHtml5AttributeName* ATTR_STEP;
+ static nsHtml5AttributeName* ATTR_ROLE;
+ static nsHtml5AttributeName* ATTR_XREF;
+ static nsHtml5AttributeName* ATTR_ASYNC;
+ static nsHtml5AttributeName* ATTR_ALINK;
+ static nsHtml5AttributeName* ATTR_ALIGN;
+ static nsHtml5AttributeName* ATTR_CLOSE;
+ static nsHtml5AttributeName* ATTR_COLOR;
+ static nsHtml5AttributeName* ATTR_CLASS;
+ static nsHtml5AttributeName* ATTR_CLEAR;
+ static nsHtml5AttributeName* ATTR_BEGIN;
+ static nsHtml5AttributeName* ATTR_DEPTH;
+ static nsHtml5AttributeName* ATTR_DEFER;
+ static nsHtml5AttributeName* ATTR_FENCE;
+ static nsHtml5AttributeName* ATTR_FRAME;
+ static nsHtml5AttributeName* ATTR_ISMAP;
+ static nsHtml5AttributeName* ATTR_ONEND;
+ static nsHtml5AttributeName* ATTR_INDEX;
+ static nsHtml5AttributeName* ATTR_ORDER;
+ static nsHtml5AttributeName* ATTR_OTHER;
+ static nsHtml5AttributeName* ATTR_ONCUT;
+ static nsHtml5AttributeName* ATTR_NARGS;
+ static nsHtml5AttributeName* ATTR_MEDIA;
+ static nsHtml5AttributeName* ATTR_LABEL;
+ static nsHtml5AttributeName* ATTR_LOCAL;
+ static nsHtml5AttributeName* ATTR_WIDTH;
+ static nsHtml5AttributeName* ATTR_TITLE;
+ static nsHtml5AttributeName* ATTR_VLINK;
+ static nsHtml5AttributeName* ATTR_VALUE;
+ static nsHtml5AttributeName* ATTR_SLOPE;
+ static nsHtml5AttributeName* ATTR_SHAPE;
+ static nsHtml5AttributeName* ATTR_SCOPE;
+ static nsHtml5AttributeName* ATTR_SCALE;
+ static nsHtml5AttributeName* ATTR_SPEED;
+ static nsHtml5AttributeName* ATTR_STYLE;
+ static nsHtml5AttributeName* ATTR_RULES;
+ static nsHtml5AttributeName* ATTR_STEMH;
+ static nsHtml5AttributeName* ATTR_SIZES;
+ static nsHtml5AttributeName* ATTR_STEMV;
+ static nsHtml5AttributeName* ATTR_START;
+ static nsHtml5AttributeName* ATTR_XMLNS;
+ static nsHtml5AttributeName* ATTR_ACCEPT;
+ static nsHtml5AttributeName* ATTR_ACCENT;
+ static nsHtml5AttributeName* ATTR_ASCENT;
+ static nsHtml5AttributeName* ATTR_ACTIVE;
+ static nsHtml5AttributeName* ATTR_ALTIMG;
+ static nsHtml5AttributeName* ATTR_ACTION;
+ static nsHtml5AttributeName* ATTR_BORDER;
+ static nsHtml5AttributeName* ATTR_CURSOR;
+ static nsHtml5AttributeName* ATTR_COORDS;
+ static nsHtml5AttributeName* ATTR_FILTER;
+ static nsHtml5AttributeName* ATTR_FORMAT;
+ static nsHtml5AttributeName* ATTR_HIDDEN;
+ static nsHtml5AttributeName* ATTR_HSPACE;
+ static nsHtml5AttributeName* ATTR_HEIGHT;
+ static nsHtml5AttributeName* ATTR_ONMOVE;
+ static nsHtml5AttributeName* ATTR_ONLOAD;
+ static nsHtml5AttributeName* ATTR_ONDRAG;
+ static nsHtml5AttributeName* ATTR_ORIGIN;
+ static nsHtml5AttributeName* ATTR_ONZOOM;
+ static nsHtml5AttributeName* ATTR_ONHELP;
+ static nsHtml5AttributeName* ATTR_ONSTOP;
+ static nsHtml5AttributeName* ATTR_ONDROP;
+ static nsHtml5AttributeName* ATTR_ONBLUR;
+ static nsHtml5AttributeName* ATTR_OBJECT;
+ static nsHtml5AttributeName* ATTR_OFFSET;
+ static nsHtml5AttributeName* ATTR_ORIENT;
+ static nsHtml5AttributeName* ATTR_ONCOPY;
+ static nsHtml5AttributeName* ATTR_NOWRAP;
+ static nsHtml5AttributeName* ATTR_NOHREF;
+ static nsHtml5AttributeName* ATTR_MACROS;
+ static nsHtml5AttributeName* ATTR_METHOD;
+ static nsHtml5AttributeName* ATTR_LOWSRC;
+ static nsHtml5AttributeName* ATTR_LSPACE;
+ static nsHtml5AttributeName* ATTR_LQUOTE;
+ static nsHtml5AttributeName* ATTR_USEMAP;
+ static nsHtml5AttributeName* ATTR_WIDTHS;
+ static nsHtml5AttributeName* ATTR_TARGET;
+ static nsHtml5AttributeName* ATTR_VALUES;
+ static nsHtml5AttributeName* ATTR_VALIGN;
+ static nsHtml5AttributeName* ATTR_VSPACE;
+ static nsHtml5AttributeName* ATTR_POSTER;
+ static nsHtml5AttributeName* ATTR_POINTS;
+ static nsHtml5AttributeName* ATTR_PROMPT;
+ static nsHtml5AttributeName* ATTR_SRCDOC;
+ static nsHtml5AttributeName* ATTR_SCOPED;
+ static nsHtml5AttributeName* ATTR_STRING;
+ static nsHtml5AttributeName* ATTR_SCHEME;
+ static nsHtml5AttributeName* ATTR_STROKE;
+ static nsHtml5AttributeName* ATTR_RADIUS;
+ static nsHtml5AttributeName* ATTR_RESULT;
+ static nsHtml5AttributeName* ATTR_REPEAT;
+ static nsHtml5AttributeName* ATTR_SRCSET;
+ static nsHtml5AttributeName* ATTR_RSPACE;
+ static nsHtml5AttributeName* ATTR_ROTATE;
+ static nsHtml5AttributeName* ATTR_RQUOTE;
+ static nsHtml5AttributeName* ATTR_ALTTEXT;
+ static nsHtml5AttributeName* ATTR_ARCHIVE;
+ static nsHtml5AttributeName* ATTR_AZIMUTH;
+ static nsHtml5AttributeName* ATTR_CLOSURE;
+ static nsHtml5AttributeName* ATTR_CHECKED;
+ static nsHtml5AttributeName* ATTR_CLASSID;
+ static nsHtml5AttributeName* ATTR_CHAROFF;
+ static nsHtml5AttributeName* ATTR_BGCOLOR;
+ static nsHtml5AttributeName* ATTR_COLSPAN;
+ static nsHtml5AttributeName* ATTR_CHARSET;
+ static nsHtml5AttributeName* ATTR_COMPACT;
+ static nsHtml5AttributeName* ATTR_CONTENT;
+ static nsHtml5AttributeName* ATTR_ENCTYPE;
+ static nsHtml5AttributeName* ATTR_DATASRC;
+ static nsHtml5AttributeName* ATTR_DATAFLD;
+ static nsHtml5AttributeName* ATTR_DECLARE;
+ static nsHtml5AttributeName* ATTR_DISPLAY;
+ static nsHtml5AttributeName* ATTR_DIVISOR;
+ static nsHtml5AttributeName* ATTR_DEFAULT;
+ static nsHtml5AttributeName* ATTR_DESCENT;
+ static nsHtml5AttributeName* ATTR_KERNING;
+ static nsHtml5AttributeName* ATTR_HANGING;
+ static nsHtml5AttributeName* ATTR_HEADERS;
+ static nsHtml5AttributeName* ATTR_ONPASTE;
+ static nsHtml5AttributeName* ATTR_ONCLICK;
+ static nsHtml5AttributeName* ATTR_OPTIMUM;
+ static nsHtml5AttributeName* ATTR_ONBEGIN;
+ static nsHtml5AttributeName* ATTR_ONKEYUP;
+ static nsHtml5AttributeName* ATTR_ONFOCUS;
+ static nsHtml5AttributeName* ATTR_ONERROR;
+ static nsHtml5AttributeName* ATTR_ONINPUT;
+ static nsHtml5AttributeName* ATTR_ONABORT;
+ static nsHtml5AttributeName* ATTR_ONSTART;
+ static nsHtml5AttributeName* ATTR_ONRESET;
+ static nsHtml5AttributeName* ATTR_OPACITY;
+ static nsHtml5AttributeName* ATTR_NOSHADE;
+ static nsHtml5AttributeName* ATTR_MINSIZE;
+ static nsHtml5AttributeName* ATTR_MAXSIZE;
+ static nsHtml5AttributeName* ATTR_LARGEOP;
+ static nsHtml5AttributeName* ATTR_UNICODE;
+ static nsHtml5AttributeName* ATTR_TARGETX;
+ static nsHtml5AttributeName* ATTR_TARGETY;
+ static nsHtml5AttributeName* ATTR_VIEWBOX;
+ static nsHtml5AttributeName* ATTR_VERSION;
+ static nsHtml5AttributeName* ATTR_PATTERN;
+ static nsHtml5AttributeName* ATTR_PROFILE;
+ static nsHtml5AttributeName* ATTR_SPACING;
+ static nsHtml5AttributeName* ATTR_RESTART;
+ static nsHtml5AttributeName* ATTR_ROWSPAN;
+ static nsHtml5AttributeName* ATTR_SANDBOX;
+ static nsHtml5AttributeName* ATTR_SUMMARY;
+ static nsHtml5AttributeName* ATTR_STANDBY;
+ static nsHtml5AttributeName* ATTR_REPLACE;
+ static nsHtml5AttributeName* ATTR_AUTOPLAY;
+ static nsHtml5AttributeName* ATTR_ADDITIVE;
+ static nsHtml5AttributeName* ATTR_CALCMODE;
+ static nsHtml5AttributeName* ATTR_CODETYPE;
+ static nsHtml5AttributeName* ATTR_CODEBASE;
+ static nsHtml5AttributeName* ATTR_CONTROLS;
+ static nsHtml5AttributeName* ATTR_BEVELLED;
+ static nsHtml5AttributeName* ATTR_BASELINE;
+ static nsHtml5AttributeName* ATTR_EXPONENT;
+ static nsHtml5AttributeName* ATTR_EDGEMODE;
+ static nsHtml5AttributeName* ATTR_ENCODING;
+ static nsHtml5AttributeName* ATTR_GLYPHREF;
+ static nsHtml5AttributeName* ATTR_DATETIME;
+ static nsHtml5AttributeName* ATTR_DISABLED;
+ static nsHtml5AttributeName* ATTR_FONTSIZE;
+ static nsHtml5AttributeName* ATTR_KEYTIMES;
+ static nsHtml5AttributeName* ATTR_PANOSE_1;
+ static nsHtml5AttributeName* ATTR_HREFLANG;
+ static nsHtml5AttributeName* ATTR_ONRESIZE;
+ static nsHtml5AttributeName* ATTR_ONCHANGE;
+ static nsHtml5AttributeName* ATTR_ONBOUNCE;
+ static nsHtml5AttributeName* ATTR_ONUNLOAD;
+ static nsHtml5AttributeName* ATTR_ONFINISH;
+ static nsHtml5AttributeName* ATTR_ONSCROLL;
+ static nsHtml5AttributeName* ATTR_OPERATOR;
+ static nsHtml5AttributeName* ATTR_OVERFLOW;
+ static nsHtml5AttributeName* ATTR_ONSUBMIT;
+ static nsHtml5AttributeName* ATTR_ONREPEAT;
+ static nsHtml5AttributeName* ATTR_ONSELECT;
+ static nsHtml5AttributeName* ATTR_NOTATION;
+ static nsHtml5AttributeName* ATTR_NORESIZE;
+ static nsHtml5AttributeName* ATTR_MANIFEST;
+ static nsHtml5AttributeName* ATTR_MATHSIZE;
+ static nsHtml5AttributeName* ATTR_MULTIPLE;
+ static nsHtml5AttributeName* ATTR_LONGDESC;
+ static nsHtml5AttributeName* ATTR_LANGUAGE;
+ static nsHtml5AttributeName* ATTR_TEMPLATE;
+ static nsHtml5AttributeName* ATTR_TABINDEX;
+ static nsHtml5AttributeName* ATTR_PROPERTY;
+ static nsHtml5AttributeName* ATTR_READONLY;
+ static nsHtml5AttributeName* ATTR_SELECTED;
+ static nsHtml5AttributeName* ATTR_ROWLINES;
+ static nsHtml5AttributeName* ATTR_SEAMLESS;
+ static nsHtml5AttributeName* ATTR_ROWALIGN;
+ static nsHtml5AttributeName* ATTR_STRETCHY;
+ static nsHtml5AttributeName* ATTR_REQUIRED;
+ static nsHtml5AttributeName* ATTR_XML_BASE;
+ static nsHtml5AttributeName* ATTR_XML_LANG;
+ static nsHtml5AttributeName* ATTR_X_HEIGHT;
+ static nsHtml5AttributeName* ATTR_ARIA_OWNS;
+ static nsHtml5AttributeName* ATTR_AUTOFOCUS;
+ static nsHtml5AttributeName* ATTR_ARIA_SORT;
+ static nsHtml5AttributeName* ATTR_ACCESSKEY;
+ static nsHtml5AttributeName* ATTR_ARIA_BUSY;
+ static nsHtml5AttributeName* ATTR_ARIA_GRAB;
+ static nsHtml5AttributeName* ATTR_AMPLITUDE;
+ static nsHtml5AttributeName* ATTR_ARIA_LIVE;
+ static nsHtml5AttributeName* ATTR_CLIP_RULE;
+ static nsHtml5AttributeName* ATTR_CLIP_PATH;
+ static nsHtml5AttributeName* ATTR_EQUALROWS;
+ static nsHtml5AttributeName* ATTR_ELEVATION;
+ static nsHtml5AttributeName* ATTR_DIRECTION;
+ static nsHtml5AttributeName* ATTR_DRAGGABLE;
+ static nsHtml5AttributeName* ATTR_FILL_RULE;
+ static nsHtml5AttributeName* ATTR_FONTSTYLE;
+ static nsHtml5AttributeName* ATTR_FONT_SIZE;
+ static nsHtml5AttributeName* ATTR_KEYSYSTEM;
+ static nsHtml5AttributeName* ATTR_KEYPOINTS;
+ static nsHtml5AttributeName* ATTR_HIDEFOCUS;
+ static nsHtml5AttributeName* ATTR_ONMESSAGE;
+ static nsHtml5AttributeName* ATTR_INTERCEPT;
+ static nsHtml5AttributeName* ATTR_ONDRAGEND;
+ static nsHtml5AttributeName* ATTR_ONMOVEEND;
+ static nsHtml5AttributeName* ATTR_ONINVALID;
+ static nsHtml5AttributeName* ATTR_INTEGRITY;
+ static nsHtml5AttributeName* ATTR_ONKEYDOWN;
+ static nsHtml5AttributeName* ATTR_ONFOCUSIN;
+ static nsHtml5AttributeName* ATTR_ONMOUSEUP;
+ static nsHtml5AttributeName* ATTR_INPUTMODE;
+ static nsHtml5AttributeName* ATTR_ONROWEXIT;
+ static nsHtml5AttributeName* ATTR_MATHCOLOR;
+ static nsHtml5AttributeName* ATTR_MASKUNITS;
+ static nsHtml5AttributeName* ATTR_MAXLENGTH;
+ static nsHtml5AttributeName* ATTR_LINEBREAK;
+ static nsHtml5AttributeName* ATTR_TRANSFORM;
+ static nsHtml5AttributeName* ATTR_V_HANGING;
+ static nsHtml5AttributeName* ATTR_VALUETYPE;
+ static nsHtml5AttributeName* ATTR_POINTSATZ;
+ static nsHtml5AttributeName* ATTR_POINTSATX;
+ static nsHtml5AttributeName* ATTR_POINTSATY;
+ static nsHtml5AttributeName* ATTR_SYMMETRIC;
+ static nsHtml5AttributeName* ATTR_SCROLLING;
+ static nsHtml5AttributeName* ATTR_REPEATDUR;
+ static nsHtml5AttributeName* ATTR_SELECTION;
+ static nsHtml5AttributeName* ATTR_SEPARATOR;
+ static nsHtml5AttributeName* ATTR_XML_SPACE;
+ static nsHtml5AttributeName* ATTR_AUTOSUBMIT;
+ static nsHtml5AttributeName* ATTR_ALPHABETIC;
+ static nsHtml5AttributeName* ATTR_ACTIONTYPE;
+ static nsHtml5AttributeName* ATTR_ACCUMULATE;
+ static nsHtml5AttributeName* ATTR_ARIA_LEVEL;
+ static nsHtml5AttributeName* ATTR_COLUMNSPAN;
+ static nsHtml5AttributeName* ATTR_CAP_HEIGHT;
+ static nsHtml5AttributeName* ATTR_BACKGROUND;
+ static nsHtml5AttributeName* ATTR_GLYPH_NAME;
+ static nsHtml5AttributeName* ATTR_GROUPALIGN;
+ static nsHtml5AttributeName* ATTR_FONTFAMILY;
+ static nsHtml5AttributeName* ATTR_FONTWEIGHT;
+ static nsHtml5AttributeName* ATTR_FONT_STYLE;
+ static nsHtml5AttributeName* ATTR_KEYSPLINES;
+ static nsHtml5AttributeName* ATTR_HTTP_EQUIV;
+ static nsHtml5AttributeName* ATTR_ONACTIVATE;
+ static nsHtml5AttributeName* ATTR_OCCURRENCE;
+ static nsHtml5AttributeName* ATTR_IRRELEVANT;
+ static nsHtml5AttributeName* ATTR_ONDBLCLICK;
+ static nsHtml5AttributeName* ATTR_ONDRAGDROP;
+ static nsHtml5AttributeName* ATTR_ONKEYPRESS;
+ static nsHtml5AttributeName* ATTR_ONROWENTER;
+ static nsHtml5AttributeName* ATTR_ONDRAGOVER;
+ static nsHtml5AttributeName* ATTR_ONFOCUSOUT;
+ static nsHtml5AttributeName* ATTR_ONMOUSEOUT;
+ static nsHtml5AttributeName* ATTR_NUMOCTAVES;
+ static nsHtml5AttributeName* ATTR_MARKER_MID;
+ static nsHtml5AttributeName* ATTR_MARKER_END;
+ static nsHtml5AttributeName* ATTR_TEXTLENGTH;
+ static nsHtml5AttributeName* ATTR_VISIBILITY;
+ static nsHtml5AttributeName* ATTR_VIEWTARGET;
+ static nsHtml5AttributeName* ATTR_VERT_ADV_Y;
+ static nsHtml5AttributeName* ATTR_PATHLENGTH;
+ static nsHtml5AttributeName* ATTR_REPEAT_MAX;
+ static nsHtml5AttributeName* ATTR_RADIOGROUP;
+ static nsHtml5AttributeName* ATTR_STOP_COLOR;
+ static nsHtml5AttributeName* ATTR_SEPARATORS;
+ static nsHtml5AttributeName* ATTR_REPEAT_MIN;
+ static nsHtml5AttributeName* ATTR_ROWSPACING;
+ static nsHtml5AttributeName* ATTR_ZOOMANDPAN;
+ static nsHtml5AttributeName* ATTR_XLINK_TYPE;
+ static nsHtml5AttributeName* ATTR_XLINK_ROLE;
+ static nsHtml5AttributeName* ATTR_XLINK_HREF;
+ static nsHtml5AttributeName* ATTR_XLINK_SHOW;
+ static nsHtml5AttributeName* ATTR_ACCENTUNDER;
+ static nsHtml5AttributeName* ATTR_ARIA_SECRET;
+ static nsHtml5AttributeName* ATTR_ARIA_ATOMIC;
+ static nsHtml5AttributeName* ATTR_ARIA_HIDDEN;
+ static nsHtml5AttributeName* ATTR_ARIA_FLOWTO;
+ static nsHtml5AttributeName* ATTR_ARABIC_FORM;
+ static nsHtml5AttributeName* ATTR_CELLPADDING;
+ static nsHtml5AttributeName* ATTR_CELLSPACING;
+ static nsHtml5AttributeName* ATTR_COLUMNWIDTH;
+ static nsHtml5AttributeName* ATTR_CROSSORIGIN;
+ static nsHtml5AttributeName* ATTR_COLUMNALIGN;
+ static nsHtml5AttributeName* ATTR_COLUMNLINES;
+ static nsHtml5AttributeName* ATTR_CONTEXTMENU;
+ static nsHtml5AttributeName* ATTR_BASEPROFILE;
+ static nsHtml5AttributeName* ATTR_FONT_FAMILY;
+ static nsHtml5AttributeName* ATTR_FRAMEBORDER;
+ static nsHtml5AttributeName* ATTR_FILTERUNITS;
+ static nsHtml5AttributeName* ATTR_FLOOD_COLOR;
+ static nsHtml5AttributeName* ATTR_FONT_WEIGHT;
+ static nsHtml5AttributeName* ATTR_HORIZ_ADV_X;
+ static nsHtml5AttributeName* ATTR_ONDRAGLEAVE;
+ static nsHtml5AttributeName* ATTR_ONMOUSEMOVE;
+ static nsHtml5AttributeName* ATTR_ORIENTATION;
+ static nsHtml5AttributeName* ATTR_ONMOUSEDOWN;
+ static nsHtml5AttributeName* ATTR_ONMOUSEOVER;
+ static nsHtml5AttributeName* ATTR_ONDRAGENTER;
+ static nsHtml5AttributeName* ATTR_IDEOGRAPHIC;
+ static nsHtml5AttributeName* ATTR_ONBEFORECUT;
+ static nsHtml5AttributeName* ATTR_ONFORMINPUT;
+ static nsHtml5AttributeName* ATTR_ONDRAGSTART;
+ static nsHtml5AttributeName* ATTR_ONMOVESTART;
+ static nsHtml5AttributeName* ATTR_MARKERUNITS;
+ static nsHtml5AttributeName* ATTR_MATHVARIANT;
+ static nsHtml5AttributeName* ATTR_MARGINWIDTH;
+ static nsHtml5AttributeName* ATTR_MARKERWIDTH;
+ static nsHtml5AttributeName* ATTR_TEXT_ANCHOR;
+ static nsHtml5AttributeName* ATTR_TABLEVALUES;
+ static nsHtml5AttributeName* ATTR_SCRIPTLEVEL;
+ static nsHtml5AttributeName* ATTR_REPEATCOUNT;
+ static nsHtml5AttributeName* ATTR_STITCHTILES;
+ static nsHtml5AttributeName* ATTR_STARTOFFSET;
+ static nsHtml5AttributeName* ATTR_SCROLLDELAY;
+ static nsHtml5AttributeName* ATTR_XMLNS_XLINK;
+ static nsHtml5AttributeName* ATTR_XLINK_TITLE;
+ static nsHtml5AttributeName* ATTR_ARIA_INVALID;
+ static nsHtml5AttributeName* ATTR_ARIA_PRESSED;
+ static nsHtml5AttributeName* ATTR_ARIA_CHECKED;
+ static nsHtml5AttributeName* ATTR_AUTOCOMPLETE;
+ static nsHtml5AttributeName* ATTR_ARIA_SETSIZE;
+ static nsHtml5AttributeName* ATTR_ARIA_CHANNEL;
+ static nsHtml5AttributeName* ATTR_EQUALCOLUMNS;
+ static nsHtml5AttributeName* ATTR_DISPLAYSTYLE;
+ static nsHtml5AttributeName* ATTR_DATAFORMATAS;
+ static nsHtml5AttributeName* ATTR_FILL_OPACITY;
+ static nsHtml5AttributeName* ATTR_FONT_VARIANT;
+ static nsHtml5AttributeName* ATTR_FONT_STRETCH;
+ static nsHtml5AttributeName* ATTR_FRAMESPACING;
+ static nsHtml5AttributeName* ATTR_KERNELMATRIX;
+ static nsHtml5AttributeName* ATTR_ONDEACTIVATE;
+ static nsHtml5AttributeName* ATTR_ONROWSDELETE;
+ static nsHtml5AttributeName* ATTR_ONMOUSELEAVE;
+ static nsHtml5AttributeName* ATTR_ONFORMCHANGE;
+ static nsHtml5AttributeName* ATTR_ONCELLCHANGE;
+ static nsHtml5AttributeName* ATTR_ONMOUSEWHEEL;
+ static nsHtml5AttributeName* ATTR_ONMOUSEENTER;
+ static nsHtml5AttributeName* ATTR_ONAFTERPRINT;
+ static nsHtml5AttributeName* ATTR_ONBEFORECOPY;
+ static nsHtml5AttributeName* ATTR_MARGINHEIGHT;
+ static nsHtml5AttributeName* ATTR_MARKERHEIGHT;
+ static nsHtml5AttributeName* ATTR_MARKER_START;
+ static nsHtml5AttributeName* ATTR_MATHEMATICAL;
+ static nsHtml5AttributeName* ATTR_LENGTHADJUST;
+ static nsHtml5AttributeName* ATTR_UNSELECTABLE;
+ static nsHtml5AttributeName* ATTR_UNICODE_BIDI;
+ static nsHtml5AttributeName* ATTR_UNITS_PER_EM;
+ static nsHtml5AttributeName* ATTR_WORD_SPACING;
+ static nsHtml5AttributeName* ATTR_WRITING_MODE;
+ static nsHtml5AttributeName* ATTR_V_ALPHABETIC;
+ static nsHtml5AttributeName* ATTR_PATTERNUNITS;
+ static nsHtml5AttributeName* ATTR_SPREADMETHOD;
+ static nsHtml5AttributeName* ATTR_SURFACESCALE;
+ static nsHtml5AttributeName* ATTR_STROKE_WIDTH;
+ static nsHtml5AttributeName* ATTR_REPEAT_START;
+ static nsHtml5AttributeName* ATTR_STDDEVIATION;
+ static nsHtml5AttributeName* ATTR_STOP_OPACITY;
+ static nsHtml5AttributeName* ATTR_ARIA_CONTROLS;
+ static nsHtml5AttributeName* ATTR_ARIA_HASPOPUP;
+ static nsHtml5AttributeName* ATTR_ACCENT_HEIGHT;
+ static nsHtml5AttributeName* ATTR_ARIA_VALUENOW;
+ static nsHtml5AttributeName* ATTR_ARIA_RELEVANT;
+ static nsHtml5AttributeName* ATTR_ARIA_POSINSET;
+ static nsHtml5AttributeName* ATTR_ARIA_VALUEMAX;
+ static nsHtml5AttributeName* ATTR_ARIA_READONLY;
+ static nsHtml5AttributeName* ATTR_ARIA_SELECTED;
+ static nsHtml5AttributeName* ATTR_ARIA_REQUIRED;
+ static nsHtml5AttributeName* ATTR_ARIA_EXPANDED;
+ static nsHtml5AttributeName* ATTR_ARIA_DISABLED;
+ static nsHtml5AttributeName* ATTR_ATTRIBUTETYPE;
+ static nsHtml5AttributeName* ATTR_ATTRIBUTENAME;
+ static nsHtml5AttributeName* ATTR_ARIA_DATATYPE;
+ static nsHtml5AttributeName* ATTR_ARIA_VALUEMIN;
+ static nsHtml5AttributeName* ATTR_BASEFREQUENCY;
+ static nsHtml5AttributeName* ATTR_COLUMNSPACING;
+ static nsHtml5AttributeName* ATTR_COLOR_PROFILE;
+ static nsHtml5AttributeName* ATTR_CLIPPATHUNITS;
+ static nsHtml5AttributeName* ATTR_DEFINITIONURL;
+ static nsHtml5AttributeName* ATTR_GRADIENTUNITS;
+ static nsHtml5AttributeName* ATTR_FLOOD_OPACITY;
+ static nsHtml5AttributeName* ATTR_ONAFTERUPDATE;
+ static nsHtml5AttributeName* ATTR_ONERRORUPDATE;
+ static nsHtml5AttributeName* ATTR_ONBEFOREPASTE;
+ static nsHtml5AttributeName* ATTR_ONLOSECAPTURE;
+ static nsHtml5AttributeName* ATTR_ONCONTEXTMENU;
+ static nsHtml5AttributeName* ATTR_ONSELECTSTART;
+ static nsHtml5AttributeName* ATTR_ONBEFOREPRINT;
+ static nsHtml5AttributeName* ATTR_MOVABLELIMITS;
+ static nsHtml5AttributeName* ATTR_LINETHICKNESS;
+ static nsHtml5AttributeName* ATTR_UNICODE_RANGE;
+ static nsHtml5AttributeName* ATTR_THINMATHSPACE;
+ static nsHtml5AttributeName* ATTR_VERT_ORIGIN_X;
+ static nsHtml5AttributeName* ATTR_VERT_ORIGIN_Y;
+ static nsHtml5AttributeName* ATTR_V_IDEOGRAPHIC;
+ static nsHtml5AttributeName* ATTR_PRESERVEALPHA;
+ static nsHtml5AttributeName* ATTR_SCRIPTMINSIZE;
+ static nsHtml5AttributeName* ATTR_SPECIFICATION;
+ static nsHtml5AttributeName* ATTR_XLINK_ACTUATE;
+ static nsHtml5AttributeName* ATTR_XLINK_ARCROLE;
+ static nsHtml5AttributeName* ATTR_ACCEPT_CHARSET;
+ static nsHtml5AttributeName* ATTR_ALIGNMENTSCOPE;
+ static nsHtml5AttributeName* ATTR_ARIA_MULTILINE;
+ static nsHtml5AttributeName* ATTR_BASELINE_SHIFT;
+ static nsHtml5AttributeName* ATTR_HORIZ_ORIGIN_X;
+ static nsHtml5AttributeName* ATTR_HORIZ_ORIGIN_Y;
+ static nsHtml5AttributeName* ATTR_ONBEFOREUPDATE;
+ static nsHtml5AttributeName* ATTR_ONFILTERCHANGE;
+ static nsHtml5AttributeName* ATTR_ONROWSINSERTED;
+ static nsHtml5AttributeName* ATTR_ONBEFOREUNLOAD;
+ static nsHtml5AttributeName* ATTR_MATHBACKGROUND;
+ static nsHtml5AttributeName* ATTR_LETTER_SPACING;
+ static nsHtml5AttributeName* ATTR_LIGHTING_COLOR;
+ static nsHtml5AttributeName* ATTR_THICKMATHSPACE;
+ static nsHtml5AttributeName* ATTR_TEXT_RENDERING;
+ static nsHtml5AttributeName* ATTR_V_MATHEMATICAL;
+ static nsHtml5AttributeName* ATTR_POINTER_EVENTS;
+ static nsHtml5AttributeName* ATTR_PRIMITIVEUNITS;
+ static nsHtml5AttributeName* ATTR_REFERRERPOLICY;
+ static nsHtml5AttributeName* ATTR_SYSTEMLANGUAGE;
+ static nsHtml5AttributeName* ATTR_STROKE_LINECAP;
+ static nsHtml5AttributeName* ATTR_SUBSCRIPTSHIFT;
+ static nsHtml5AttributeName* ATTR_STROKE_OPACITY;
+ static nsHtml5AttributeName* ATTR_ARIA_DROPEFFECT;
+ static nsHtml5AttributeName* ATTR_ARIA_LABELLEDBY;
+ static nsHtml5AttributeName* ATTR_ARIA_TEMPLATEID;
+ static nsHtml5AttributeName* ATTR_COLOR_RENDERING;
+ static nsHtml5AttributeName* ATTR_CONTENTEDITABLE;
+ static nsHtml5AttributeName* ATTR_DIFFUSECONSTANT;
+ static nsHtml5AttributeName* ATTR_ONDATAAVAILABLE;
+ static nsHtml5AttributeName* ATTR_ONCONTROLSELECT;
+ static nsHtml5AttributeName* ATTR_IMAGE_RENDERING;
+ static nsHtml5AttributeName* ATTR_MEDIUMMATHSPACE;
+ static nsHtml5AttributeName* ATTR_TEXT_DECORATION;
+ static nsHtml5AttributeName* ATTR_SHAPE_RENDERING;
+ static nsHtml5AttributeName* ATTR_STROKE_LINEJOIN;
+ static nsHtml5AttributeName* ATTR_REPEAT_TEMPLATE;
+ static nsHtml5AttributeName* ATTR_ARIA_DESCRIBEDBY;
+ static nsHtml5AttributeName* ATTR_FONT_SIZE_ADJUST;
+ static nsHtml5AttributeName* ATTR_KERNELUNITLENGTH;
+ static nsHtml5AttributeName* ATTR_ONBEFOREACTIVATE;
+ static nsHtml5AttributeName* ATTR_ONPROPERTYCHANGE;
+ static nsHtml5AttributeName* ATTR_ONDATASETCHANGED;
+ static nsHtml5AttributeName* ATTR_MASKCONTENTUNITS;
+ static nsHtml5AttributeName* ATTR_PATTERNTRANSFORM;
+ static nsHtml5AttributeName* ATTR_REQUIREDFEATURES;
+ static nsHtml5AttributeName* ATTR_RENDERING_INTENT;
+ static nsHtml5AttributeName* ATTR_SPECULAREXPONENT;
+ static nsHtml5AttributeName* ATTR_SPECULARCONSTANT;
+ static nsHtml5AttributeName* ATTR_SUPERSCRIPTSHIFT;
+ static nsHtml5AttributeName* ATTR_STROKE_DASHARRAY;
+ static nsHtml5AttributeName* ATTR_XCHANNELSELECTOR;
+ static nsHtml5AttributeName* ATTR_YCHANNELSELECTOR;
+ static nsHtml5AttributeName* ATTR_ARIA_AUTOCOMPLETE;
+ static nsHtml5AttributeName* ATTR_ENABLE_BACKGROUND;
+ static nsHtml5AttributeName* ATTR_DOMINANT_BASELINE;
+ static nsHtml5AttributeName* ATTR_GRADIENTTRANSFORM;
+ static nsHtml5AttributeName* ATTR_ONBEFORDEACTIVATE;
+ static nsHtml5AttributeName* ATTR_ONDATASETCOMPLETE;
+ static nsHtml5AttributeName* ATTR_OVERLINE_POSITION;
+ static nsHtml5AttributeName* ATTR_ONBEFOREEDITFOCUS;
+ static nsHtml5AttributeName* ATTR_LIMITINGCONEANGLE;
+ static nsHtml5AttributeName* ATTR_VERYTHINMATHSPACE;
+ static nsHtml5AttributeName* ATTR_STROKE_DASHOFFSET;
+ static nsHtml5AttributeName* ATTR_STROKE_MITERLIMIT;
+ static nsHtml5AttributeName* ATTR_ALIGNMENT_BASELINE;
+ static nsHtml5AttributeName* ATTR_ONREADYSTATECHANGE;
+ static nsHtml5AttributeName* ATTR_OVERLINE_THICKNESS;
+ static nsHtml5AttributeName* ATTR_UNDERLINE_POSITION;
+ static nsHtml5AttributeName* ATTR_VERYTHICKMATHSPACE;
+ static nsHtml5AttributeName* ATTR_REQUIREDEXTENSIONS;
+ static nsHtml5AttributeName* ATTR_COLOR_INTERPOLATION;
+ static nsHtml5AttributeName* ATTR_UNDERLINE_THICKNESS;
+ static nsHtml5AttributeName* ATTR_PRESERVEASPECTRATIO;
+ static nsHtml5AttributeName* ATTR_PATTERNCONTENTUNITS;
+ static nsHtml5AttributeName* ATTR_ARIA_MULTISELECTABLE;
+ static nsHtml5AttributeName* ATTR_SCRIPTSIZEMULTIPLIER;
+ static nsHtml5AttributeName* ATTR_ARIA_ACTIVEDESCENDANT;
+ static nsHtml5AttributeName* ATTR_VERYVERYTHINMATHSPACE;
+ static nsHtml5AttributeName* ATTR_VERYVERYTHICKMATHSPACE;
+ static nsHtml5AttributeName* ATTR_STRIKETHROUGH_POSITION;
+ static nsHtml5AttributeName* ATTR_STRIKETHROUGH_THICKNESS;
+ static nsHtml5AttributeName* ATTR_GLYPH_ORIENTATION_VERTICAL;
+ static nsHtml5AttributeName* ATTR_COLOR_INTERPOLATION_FILTERS;
+ static nsHtml5AttributeName* ATTR_GLYPH_ORIENTATION_HORIZONTAL;
+ private:
+ static nsHtml5AttributeName** ATTRIBUTE_NAMES;
+ static staticJArray<int32_t,int32_t> ATTRIBUTE_HASHES;
+ public:
+ static void initializeStatics();
+ static void releaseStatics();
+};
+
+#define NS_HTML5ATTRIBUTE_NAME_HTML 0
+#define NS_HTML5ATTRIBUTE_NAME_MATHML 1
+#define NS_HTML5ATTRIBUTE_NAME_SVG 2
+
+
+#endif
+
diff --git a/parser/html/nsHtml5ByteReadable.h b/parser/html/nsHtml5ByteReadable.h
new file mode 100644
index 000000000..7b6103ccf
--- /dev/null
+++ b/parser/html/nsHtml5ByteReadable.h
@@ -0,0 +1,33 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5ByteReadable_h
+#define nsHtml5ByteReadable_h
+
+/**
+ * A weak reference wrapper around a byte array.
+ */
+class nsHtml5ByteReadable
+{
+ public:
+
+ nsHtml5ByteReadable(const uint8_t* aCurrent, const uint8_t* aEnd)
+ : current(aCurrent),
+ end(aEnd)
+ {
+ }
+
+ inline int32_t read() {
+ if (current < end) {
+ return *(current++);
+ } else {
+ return -1;
+ }
+ }
+
+ private:
+ const uint8_t* current;
+ const uint8_t* end;
+};
+#endif
diff --git a/parser/html/nsHtml5DependentUTF16Buffer.cpp b/parser/html/nsHtml5DependentUTF16Buffer.cpp
new file mode 100644
index 000000000..ed2211611
--- /dev/null
+++ b/parser/html/nsHtml5DependentUTF16Buffer.cpp
@@ -0,0 +1,33 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5DependentUTF16Buffer.h"
+
+nsHtml5DependentUTF16Buffer::nsHtml5DependentUTF16Buffer(const nsAString& aToWrap)
+ : nsHtml5UTF16Buffer(const_cast<char16_t*> (aToWrap.BeginReading()),
+ aToWrap.Length())
+{
+ MOZ_COUNT_CTOR(nsHtml5DependentUTF16Buffer);
+}
+
+nsHtml5DependentUTF16Buffer::~nsHtml5DependentUTF16Buffer()
+{
+ MOZ_COUNT_DTOR(nsHtml5DependentUTF16Buffer);
+}
+
+already_AddRefed<nsHtml5OwningUTF16Buffer>
+nsHtml5DependentUTF16Buffer::FalliblyCopyAsOwningBuffer()
+{
+ int32_t newLength = getEnd() - getStart();
+ RefPtr<nsHtml5OwningUTF16Buffer> newObj =
+ nsHtml5OwningUTF16Buffer::FalliblyCreate(newLength);
+ if (!newObj) {
+ return nullptr;
+ }
+ newObj->setEnd(newLength);
+ memcpy(newObj->getBuffer(),
+ getBuffer() + getStart(),
+ newLength * sizeof(char16_t));
+ return newObj.forget();
+}
diff --git a/parser/html/nsHtml5DependentUTF16Buffer.h b/parser/html/nsHtml5DependentUTF16Buffer.h
new file mode 100644
index 000000000..038d331c0
--- /dev/null
+++ b/parser/html/nsHtml5DependentUTF16Buffer.h
@@ -0,0 +1,31 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5DependentUTF16Buffer_h
+#define nsHtml5DependentUTF16Buffer_h
+
+#include "nscore.h"
+#include "nsHtml5OwningUTF16Buffer.h"
+
+class MOZ_STACK_CLASS nsHtml5DependentUTF16Buffer : public nsHtml5UTF16Buffer
+{
+ public:
+ /**
+ * Wraps a string without taking ownership of the buffer. aToWrap MUST NOT
+ * go away or be shortened while nsHtml5DependentUTF16Buffer is in use.
+ */
+ explicit nsHtml5DependentUTF16Buffer(const nsAString& aToWrap);
+
+ ~nsHtml5DependentUTF16Buffer();
+
+ /**
+ * Copies the currently unconsumed part of this buffer into a new
+ * heap-allocated nsHtml5OwningUTF16Buffer. The new object is allocated
+ * with a fallible allocator. If the allocation fails, nullptr is returned.
+ * @return heap-allocated copy or nullptr if memory allocation failed
+ */
+ already_AddRefed<nsHtml5OwningUTF16Buffer> FalliblyCopyAsOwningBuffer();
+};
+
+#endif // nsHtml5DependentUTF16Buffer_h
diff --git a/parser/html/nsHtml5DocumentBuilder.cpp b/parser/html/nsHtml5DocumentBuilder.cpp
new file mode 100644
index 000000000..ba8a333c4
--- /dev/null
+++ b/parser/html/nsHtml5DocumentBuilder.cpp
@@ -0,0 +1,120 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 et tw=78: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5DocumentBuilder.h"
+
+#include "nsIStyleSheetLinkingElement.h"
+#include "nsStyleLinkElement.h"
+#include "nsScriptLoader.h"
+#include "nsIHTMLDocument.h"
+
+NS_IMPL_CYCLE_COLLECTION_INHERITED(nsHtml5DocumentBuilder, nsContentSink,
+ mOwnedElements)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsHtml5DocumentBuilder)
+NS_INTERFACE_MAP_END_INHERITING(nsContentSink)
+
+NS_IMPL_ADDREF_INHERITED(nsHtml5DocumentBuilder, nsContentSink)
+NS_IMPL_RELEASE_INHERITED(nsHtml5DocumentBuilder, nsContentSink)
+
+nsHtml5DocumentBuilder::nsHtml5DocumentBuilder(bool aRunsToCompletion)
+{
+ mRunsToCompletion = aRunsToCompletion;
+}
+
+nsresult
+nsHtml5DocumentBuilder::Init(nsIDocument* aDoc,
+ nsIURI* aURI,
+ nsISupports* aContainer,
+ nsIChannel* aChannel)
+{
+ return nsContentSink::Init(aDoc, aURI, aContainer, aChannel);
+}
+
+nsHtml5DocumentBuilder::~nsHtml5DocumentBuilder()
+{
+}
+
+nsresult
+nsHtml5DocumentBuilder::MarkAsBroken(nsresult aReason)
+{
+ mBroken = aReason;
+ return aReason;
+}
+
+void
+nsHtml5DocumentBuilder::SetDocumentCharsetAndSource(nsACString& aCharset, int32_t aCharsetSource)
+{
+ if (mDocument) {
+ mDocument->SetDocumentCharacterSetSource(aCharsetSource);
+ mDocument->SetDocumentCharacterSet(aCharset);
+ }
+}
+
+void
+nsHtml5DocumentBuilder::UpdateStyleSheet(nsIContent* aElement)
+{
+ // Break out of the doc update created by Flush() to zap a runnable
+ // waiting to call UpdateStyleSheet without the right observer
+ EndDocUpdate();
+
+ if (MOZ_UNLIKELY(!mParser)) {
+ // EndDocUpdate ran stuff that called nsIParser::Terminate()
+ return;
+ }
+
+ nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(aElement));
+ NS_ASSERTION(ssle, "Node didn't QI to style.");
+
+ ssle->SetEnableUpdates(true);
+
+ bool willNotify;
+ bool isAlternate;
+ nsresult rv = ssle->UpdateStyleSheet(mRunsToCompletion ? nullptr : this,
+ &willNotify,
+ &isAlternate);
+ if (NS_SUCCEEDED(rv) && willNotify && !isAlternate && !mRunsToCompletion) {
+ ++mPendingSheetCount;
+ mScriptLoader->AddParserBlockingScriptExecutionBlocker();
+ }
+
+ // Re-open update
+ BeginDocUpdate();
+}
+
+void
+nsHtml5DocumentBuilder::SetDocumentMode(nsHtml5DocumentMode m)
+{
+ nsCompatibility mode = eCompatibility_NavQuirks;
+ switch (m) {
+ case STANDARDS_MODE:
+ mode = eCompatibility_FullStandards;
+ break;
+ case ALMOST_STANDARDS_MODE:
+ mode = eCompatibility_AlmostStandards;
+ break;
+ case QUIRKS_MODE:
+ mode = eCompatibility_NavQuirks;
+ break;
+ }
+ nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(mDocument);
+ NS_ASSERTION(htmlDocument, "Document didn't QI into HTML document.");
+ htmlDocument->SetCompatibilityMode(mode);
+}
+
+// nsContentSink overrides
+
+void
+nsHtml5DocumentBuilder::UpdateChildCounts()
+{
+ // No-op
+}
+
+nsresult
+nsHtml5DocumentBuilder::FlushTags()
+{
+ return NS_OK;
+}
diff --git a/parser/html/nsHtml5DocumentBuilder.h b/parser/html/nsHtml5DocumentBuilder.h
new file mode 100644
index 000000000..86a02ff8c
--- /dev/null
+++ b/parser/html/nsHtml5DocumentBuilder.h
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 et tw=78: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5DocumentBuilder_h
+#define nsHtml5DocumentBuilder_h
+
+#include "nsContentSink.h"
+#include "nsHtml5DocumentMode.h"
+#include "nsIDocument.h"
+#include "nsIContent.h"
+
+typedef nsIContent* nsIContentPtr;
+
+enum eHtml5FlushState {
+ eNotFlushing = 0, // not flushing
+ eInFlush = 1, // the Flush() method is on the call stack
+ eInDocUpdate = 2, // inside an update batch on the document
+ eNotifying = 3 // flushing pending append notifications
+};
+
+class nsHtml5DocumentBuilder : public nsContentSink
+{
+public:
+ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHtml5DocumentBuilder,
+ nsContentSink)
+
+ NS_DECL_ISUPPORTS_INHERITED
+
+ inline void HoldElement(already_AddRefed<nsIContent> aContent)
+ {
+ *(mOwnedElements.AppendElement()) = aContent;
+ }
+
+ nsresult Init(nsIDocument* aDoc, nsIURI* aURI,
+ nsISupports* aContainer, nsIChannel* aChannel);
+
+ // Getters and setters for fields from nsContentSink
+ nsIDocument* GetDocument()
+ {
+ return mDocument;
+ }
+
+ nsNodeInfoManager* GetNodeInfoManager()
+ {
+ return mNodeInfoManager;
+ }
+
+ /**
+ * Marks this parser as broken and tells the stream parser (if any) to
+ * terminate.
+ *
+ * @return aReason for convenience
+ */
+ virtual nsresult MarkAsBroken(nsresult aReason);
+
+ /**
+ * Checks if this parser is broken. Returns a non-NS_OK (i.e. non-0)
+ * value if broken.
+ */
+ inline nsresult IsBroken()
+ {
+ return mBroken;
+ }
+
+ inline void BeginDocUpdate()
+ {
+ NS_PRECONDITION(mFlushState == eInFlush, "Tried to double-open update.");
+ NS_PRECONDITION(mParser, "Started update without parser.");
+ mFlushState = eInDocUpdate;
+ mDocument->BeginUpdate(UPDATE_CONTENT_MODEL);
+ }
+
+ inline void EndDocUpdate()
+ {
+ NS_PRECONDITION(mFlushState != eNotifying, "mFlushState out of sync");
+ if (mFlushState == eInDocUpdate) {
+ mFlushState = eInFlush;
+ mDocument->EndUpdate(UPDATE_CONTENT_MODEL);
+ }
+ }
+
+ bool IsInDocUpdate()
+ {
+ return mFlushState == eInDocUpdate;
+ }
+
+ void SetDocumentCharsetAndSource(nsACString& aCharset, int32_t aCharsetSource);
+
+ /**
+ * Sets up style sheet load / parse
+ */
+ void UpdateStyleSheet(nsIContent* aElement);
+
+ void SetDocumentMode(nsHtml5DocumentMode m);
+
+ void SetNodeInfoManager(nsNodeInfoManager* aManager)
+ {
+ mNodeInfoManager = aManager;
+ }
+
+ // nsContentSink methods
+ virtual void UpdateChildCounts() override;
+ virtual nsresult FlushTags() override;
+
+protected:
+
+ explicit nsHtml5DocumentBuilder(bool aRunsToCompletion);
+ virtual ~nsHtml5DocumentBuilder();
+
+protected:
+ AutoTArray<nsCOMPtr<nsIContent>, 32> mOwnedElements;
+ /**
+ * Non-NS_OK if this parser should refuse to process any more input.
+ * For example, the parser needs to be marked as broken if it drops some
+ * input due to a memory allocation failure. In such a case, the whole
+ * parser needs to be marked as broken, because some input has been lost
+ * and parsing more input could lead to a DOM where pieces of HTML source
+ * that weren't supposed to become scripts become scripts.
+ *
+ * Since NS_OK is actually 0, zeroing operator new takes care of
+ * initializing this.
+ */
+ nsresult mBroken;
+ eHtml5FlushState mFlushState;
+};
+
+#endif // nsHtml5DocumentBuilder_h
diff --git a/parser/html/nsHtml5DocumentMode.h b/parser/html/nsHtml5DocumentMode.h
new file mode 100644
index 000000000..b6acee5c9
--- /dev/null
+++ b/parser/html/nsHtml5DocumentMode.h
@@ -0,0 +1,14 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5DocumentMode_h
+#define nsHtml5DocumentMode_h
+
+enum nsHtml5DocumentMode {
+ STANDARDS_MODE,
+ ALMOST_STANDARDS_MODE,
+ QUIRKS_MODE
+};
+
+#endif // nsHtml5DocumentMode_h
diff --git a/parser/html/nsHtml5ElementName.cpp b/parser/html/nsHtml5ElementName.cpp
new file mode 100644
index 000000000..1aa6f11ce
--- /dev/null
+++ b/parser/html/nsHtml5ElementName.cpp
@@ -0,0 +1,1743 @@
+/*
+ * Copyright (c) 2008-2014 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit ElementName.java instead and regenerate.
+ */
+
+#define nsHtml5ElementName_cpp__
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5ByteReadable.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
+
+#include "nsHtml5Tokenizer.h"
+#include "nsHtml5TreeBuilder.h"
+#include "nsHtml5MetaScanner.h"
+#include "nsHtml5AttributeName.h"
+#include "nsHtml5HtmlAttributes.h"
+#include "nsHtml5StackNode.h"
+#include "nsHtml5UTF16Buffer.h"
+#include "nsHtml5StateSnapshot.h"
+#include "nsHtml5Portability.h"
+
+#include "nsHtml5ElementName.h"
+#include "nsHtml5ReleasableElementName.h"
+
+nsHtml5ElementName* nsHtml5ElementName::ELT_NULL_ELEMENT_NAME = nullptr;
+int32_t
+nsHtml5ElementName::getGroup()
+{
+ return flags & NS_HTML5ELEMENT_NAME_GROUP_MASK;
+}
+
+bool
+nsHtml5ElementName::isCustom()
+{
+ return (flags & NS_HTML5ELEMENT_NAME_CUSTOM);
+}
+
+nsHtml5ElementName*
+nsHtml5ElementName::elementNameByBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5AtomTable* interner)
+{
+ int32_t hash = nsHtml5ElementName::bufToHash(buf, length);
+ int32_t index = nsHtml5ElementName::ELEMENT_HASHES.binarySearch(hash);
+ if (index < 0) {
+ return new nsHtml5ReleasableElementName(nsHtml5Portability::newLocalNameFromBuffer(buf, offset, length, interner));
+ } else {
+ nsHtml5ElementName* elementName = nsHtml5ElementName::ELEMENT_NAMES[index];
+ nsIAtom* name = elementName->name;
+ if (!nsHtml5Portability::localEqualsBuffer(name, buf, offset, length)) {
+ return new nsHtml5ReleasableElementName(nsHtml5Portability::newLocalNameFromBuffer(buf, offset, length, interner));
+ }
+ return elementName;
+ }
+}
+
+int32_t
+nsHtml5ElementName::bufToHash(char16_t* buf, int32_t len)
+{
+ int32_t hash = len;
+ hash <<= 5;
+ hash += buf[0] - 0x60;
+ int32_t j = len;
+ for (int32_t i = 0; i < 4 && j > 0; i++) {
+ j--;
+ hash <<= 5;
+ hash += buf[j] - 0x60;
+ }
+ return hash;
+}
+
+
+nsHtml5ElementName::nsHtml5ElementName(nsIAtom* name, nsIAtom* camelCaseName, int32_t flags)
+ : name(name),
+ camelCaseName(camelCaseName),
+ flags(flags)
+{
+ MOZ_COUNT_CTOR(nsHtml5ElementName);
+}
+
+
+nsHtml5ElementName::nsHtml5ElementName(nsIAtom* name)
+ : name(name),
+ camelCaseName(name),
+ flags(NS_HTML5TREE_BUILDER_OTHER | NS_HTML5ELEMENT_NAME_CUSTOM)
+{
+ MOZ_COUNT_CTOR(nsHtml5ElementName);
+}
+
+void
+nsHtml5ElementName::release()
+{
+}
+
+
+nsHtml5ElementName::~nsHtml5ElementName()
+{
+ MOZ_COUNT_DTOR(nsHtml5ElementName);
+}
+
+nsHtml5ElementName*
+nsHtml5ElementName::cloneElementName(nsHtml5AtomTable* interner)
+{
+ return this;
+}
+
+nsHtml5ElementName* nsHtml5ElementName::ELT_A = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_B = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_G = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_I = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_P = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_Q = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_S = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_U = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_BR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CI = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DD = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DL = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_EM = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_EQ = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_H1 = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_H2 = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_H3 = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_H4 = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_H5 = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_H6 = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_GT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_HR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_IN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LI = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MI = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MO = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_OL = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_OR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PI = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_RB = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_RP = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_RT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TD = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_UL = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_AND = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ARG = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ABS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_BIG = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_BDO = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CSC = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_COL = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_COS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_COT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DEL = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DFN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DIR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DIV = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_EXP = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_GCD = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_GEQ = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_IMG = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_INS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_INT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_KBD = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LOG = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LCM = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LEQ = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MTD = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MIN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MAP = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MTR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MAX = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_NEQ = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_NOT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_NAV = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PRE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_RTC = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_REM = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SUB = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SEC = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SVG = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SUM = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SIN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SEP = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SUP = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SET = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TAN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_USE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_VAR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_WBR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_XMP = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_XOR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_AREA = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ABBR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_BASE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_BVAR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_BODY = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CARD = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CODE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CITE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CSCH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_COSH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_COTH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CURL = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DESC = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DIFF = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DEFS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FORM = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FONT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_GRAD = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_HEAD = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_HTML = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LINE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LINK = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LIST = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_META = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MSUB = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MODE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MATH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MARK = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MASK = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MEAN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MAIN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MSUP = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MENU = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MROW = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_NONE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_NOBR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_NEST = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PATH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PLUS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_RULE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_REAL = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_RELN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_RECT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ROOT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_RUBY = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SECH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SINH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SPAN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SAMP = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_STOP = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SDEV = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TIME = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TRUE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TREF = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TANH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TEXT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_VIEW = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ASIDE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_AUDIO = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_APPLY = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_EMBED = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FRAME = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FALSE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FLOOR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_GLYPH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_HKERN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_IMAGE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_IDENT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_INPUT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LABEL = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LIMIT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MFRAC = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MPATH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_METER = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MOVER = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MINUS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MROOT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MSQRT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MTEXT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_NOTIN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PIECE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PARAM = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_POWER = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_REALS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_STYLE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SMALL = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_THEAD = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TABLE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TITLE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TRACK = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TSPAN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TIMES = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TFOOT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TBODY = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_UNION = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_VKERN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_VIDEO = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ARCSEC = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ARCCSC = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ARCTAN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ARCSIN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ARCCOS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_APPLET = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ARCCOT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_APPROX = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_BUTTON = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CIRCLE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CENTER = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CURSOR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CANVAS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DIVIDE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DEGREE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DOMAIN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_EXISTS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FETILE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FIGURE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FORALL = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FILTER = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FOOTER = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_HGROUP = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_HEADER = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_IFRAME = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_KEYGEN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LAMBDA = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LEGEND = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MSPACE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MTABLE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MSTYLE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MGLYPH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MEDIAN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MUNDER = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MARKER = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MERROR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MOMENT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MATRIX = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_OPTION = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_OBJECT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_OUTPUT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PRIMES = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SOURCE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_STRIKE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_STRONG = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SWITCH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SYMBOL = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SELECT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SUBSET = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SCRIPT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TBREAK = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_VECTOR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ARTICLE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ANIMATE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ARCSECH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ARCCSCH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ARCTANH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ARCSINH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ARCCOSH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ARCCOTH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ACRONYM = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ADDRESS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_BGSOUND = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_COMPOSE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CEILING = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CSYMBOL = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CAPTION = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DISCARD = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DECLARE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DETAILS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ELLIPSE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEFUNCA = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEFUNCB = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEBLEND = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEFLOOD = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEIMAGE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEMERGE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEFUNCG = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEFUNCR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_HANDLER = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_INVERSE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_IMPLIES = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ISINDEX = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LOGBASE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LISTING = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MFENCED = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MPADDED = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MARQUEE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MACTION = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MSUBSUP = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_NOEMBED = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_POLYGON = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PATTERN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PICTURE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PRODUCT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SETDIFF = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SECTION = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SUMMARY = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TENDSTO = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_UPLIMIT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ALTGLYPH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_BASEFONT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CLIPPATH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CODOMAIN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_COLGROUP = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_EMPTYSET = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FACTOROF = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FIELDSET = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FRAMESET = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEOFFSET = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_GLYPHREF = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_INTERVAL = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_INTEGERS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_INFINITY = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LISTENER = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LOWLIMIT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_METADATA = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MENCLOSE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MENUITEM = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MPHANTOM = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_NOFRAMES = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_NOSCRIPT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_OPTGROUP = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_POLYLINE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PREFETCH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PROGRESS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PRSUBSET = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_QUOTIENT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SELECTOR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TEXTAREA = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TEMPLATE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TEXTPATH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_VARIANCE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ANIMATION = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CONJUGATE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CONDITION = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_COMPLEXES = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FONT_FACE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FACTORIAL = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_INTERSECT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_IMAGINARY = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LAPLACIAN = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MATRIXROW = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_NOTSUBSET = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_OTHERWISE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PIECEWISE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PLAINTEXT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_RATIONALS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SEMANTICS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_TRANSPOSE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ANNOTATION = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_BLOCKQUOTE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DIVERGENCE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_EULERGAMMA = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_EQUIVALENT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FIGCAPTION = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_IMAGINARYI = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MALIGNMARK = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MUNDEROVER = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MLABELEDTR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_NOTANUMBER = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SOLIDCOLOR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ALTGLYPHDEF = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DETERMINANT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEMERGENODE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FECOMPOSITE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FESPOTLIGHT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MALIGNGROUP = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MPRESCRIPTS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MOMENTABOUT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_NOTPRSUBSET = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_PARTIALDIFF = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ALTGLYPHITEM = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ANIMATECOLOR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DATATEMPLATE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_EXPONENTIALE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FETURBULENCE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEPOINTLIGHT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEDROPSHADOW = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEMORPHOLOGY = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_OUTERPRODUCT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ANIMATEMOTION = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_COLOR_PROFILE = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FONT_FACE_SRC = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FONT_FACE_URI = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FOREIGNOBJECT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FECOLORMATRIX = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MISSING_GLYPH = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_MMULTISCRIPTS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_SCALARPRODUCT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_VECTORPRODUCT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ANNOTATION_XML = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DEFINITION_SRC = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FONT_FACE_NAME = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEGAUSSIANBLUR = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEDISTANTLIGHT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_LINEARGRADIENT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_NATURALNUMBERS = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_RADIALGRADIENT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_ANIMATETRANSFORM = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_CARTESIANPRODUCT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FONT_FACE_FORMAT = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FECONVOLVEMATRIX = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEDIFFUSELIGHTING = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FEDISPLACEMENTMAP = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FESPECULARLIGHTING = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_DOMAINOFAPPLICATION = nullptr;
+nsHtml5ElementName* nsHtml5ElementName::ELT_FECOMPONENTTRANSFER = nullptr;
+nsHtml5ElementName** nsHtml5ElementName::ELEMENT_NAMES = 0;
+static int32_t const ELEMENT_HASHES_DATA[] = { 1057, 1090, 1255, 1321, 1552, 1585, 1651, 1717, 68162, 68899, 69059, 69764, 70020, 70276, 71077, 71205, 72134, 72232, 72264, 72296, 72328, 72360, 72392, 73351, 74312, 75209, 78124, 78284, 78476, 79149, 79309, 79341, 79469, 81295, 81487, 82224, 84050, 84498, 84626, 86164, 86292, 86612, 86676, 87445, 3183041, 3186241, 3198017, 3218722, 3226754, 3247715, 3256803, 3263971, 3264995, 3289252, 3291332, 3295524, 3299620, 3326725, 3379303, 3392679, 3448233, 3460553, 3461577, 3510347, 3546604, 3552364, 3556524, 3576461, 3586349, 3588141, 3590797, 3596333, 3622062, 3625454, 3627054, 3675728, 3739282, 3749042, 3771059, 3771571, 3776211, 3782323, 3782963, 3784883, 3785395, 3788979, 3815476, 3839605, 3885110, 3917911, 3948984, 3951096, 135304769, 135858241, 136498210, 136906434, 137138658, 137512995, 137531875, 137548067, 137629283, 137645539, 137646563, 137775779, 138529956, 138615076, 139040932, 140954086, 141179366, 141690439, 142738600, 143013512, 146979116, 147175724, 147475756, 147902637, 147936877, 148017645, 148131885, 148228141, 148229165, 148309165, 148317229, 148395629, 148551853, 148618829, 149076462, 149490158, 149572782, 151277616, 151639440, 153268914, 153486514, 153563314, 153750706, 153763314, 153914034, 154406067, 154417459, 154600979, 154678323, 154680979, 154866835, 155366708, 155375188, 155391572, 155465780, 155869364, 158045494, 168988979, 169321621, 169652752, 173151309, 174240818, 174247297, 174669292, 175391532, 176638123, 177380397, 177879204, 177886734, 180753473, 181020073, 181503558, 181686320, 181999237, 181999311, 182048201, 182074866, 182078003, 182083764, 182920847, 184716457, 184976961, 185145071, 187281445, 187872052, 188100653, 188875944, 188919873, 188920457, 189107250, 189203987, 189371817, 189414886, 189567458, 190266670, 191318187, 191337609, 202479203, 202493027, 202835587, 202843747, 203013219, 203036048, 203045987, 203177552, 203898516, 204648562, 205067918, 205078130, 205096654, 205689142, 205690439, 205988909, 207213161, 207794484, 207800999, 208023602, 208213644, 208213647, 210261490, 210310273, 210940978, 213325049, 213946445, 214055079, 215125040, 215134273, 215135028, 215237420, 215418148, 215553166, 215553394, 215563858, 215627949, 215754324, 217529652, 217713834, 217732628, 218731945, 221417045, 221424946, 221493746, 221515401, 221658189, 221908140, 221910626, 221921586, 222659762, 225001091, 236105833, 236113965, 236194995, 236195427, 236206132, 236206387, 236211683, 236212707, 236381647, 236571826, 237124271, 238210544, 238270764, 238435405, 238501172, 239224867, 239257644, 239710497, 240307721, 241208789, 241241557, 241318060, 241319404, 241343533, 241344069, 241405397, 241765845, 243864964, 244502085, 244946220, 245109902, 247647266, 247707956, 248648814, 248648836, 248682161, 248986932, 249058914, 249697357, 252132601, 252135604, 251841204, 252317348, 255007012, 255278388, 255641645, 256365156, 257566121, 269763372, 271202790, 271863856, 272049197, 272127474, 274339449, 274939471, 275388004, 275388005, 275388006, 275977800, 278267602, 278513831, 278712622, 281613765, 281683369, 282120228, 282250732, 282498697, 282508942, 283743649, 283787570, 284710386, 285391148, 285478533, 285854898, 285873762, 286931113, 288964227, 289445441, 289591340, 289689648, 291671489, 303512884, 305319975, 305610036, 305764101, 308448294, 308675890, 312085683, 312264750, 315032867, 316391000, 317331042, 317902135, 318950711, 319447220, 321499182, 322538804, 323145200, 337067316, 337826293, 339905989, 340833697, 341457068, 342310196, 345302593, 349554733, 349771471, 349786245, 350819405, 356072847, 370349192, 373962798, 375558638, 375574835, 376053993, 383276530, 383373833, 383407586, 384439906, 386079012, 404133513, 404307343, 407031852, 408072233, 409112005, 409608425, 409713793, 409771500, 419040932, 437730612, 439529766, 442616365, 442813037, 443157674, 443295316, 450118444, 450482697, 456789668, 459935396, 471217869, 474073645, 476230702, 476665218, 476717289, 483014825, 485083298, 489306281, 538364390, 540675748, 543819186, 543958612, 576960820, 577242548, 610515252, 642202932, 644420819 };
+staticJArray<int32_t,int32_t> nsHtml5ElementName::ELEMENT_HASHES = { ELEMENT_HASHES_DATA, MOZ_ARRAY_LENGTH(ELEMENT_HASHES_DATA) };
+void
+nsHtml5ElementName::initializeStatics()
+{
+ ELT_NULL_ELEMENT_NAME = new nsHtml5ElementName(nullptr);
+ ELT_A = new nsHtml5ElementName(nsHtml5Atoms::a, nsHtml5Atoms::a, NS_HTML5TREE_BUILDER_A);
+ ELT_B = new nsHtml5ElementName(nsHtml5Atoms::b, nsHtml5Atoms::b, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ ELT_G = new nsHtml5ElementName(nsHtml5Atoms::g, nsHtml5Atoms::g, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_I = new nsHtml5ElementName(nsHtml5Atoms::i, nsHtml5Atoms::i, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ ELT_P = new nsHtml5ElementName(nsHtml5Atoms::p, nsHtml5Atoms::p, NS_HTML5TREE_BUILDER_P | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_Q = new nsHtml5ElementName(nsHtml5Atoms::q, nsHtml5Atoms::q, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_S = new nsHtml5ElementName(nsHtml5Atoms::s, nsHtml5Atoms::s, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ ELT_U = new nsHtml5ElementName(nsHtml5Atoms::u, nsHtml5Atoms::u, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ ELT_BR = new nsHtml5ElementName(nsHtml5Atoms::br, nsHtml5Atoms::br, NS_HTML5TREE_BUILDER_BR | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_CI = new nsHtml5ElementName(nsHtml5Atoms::ci, nsHtml5Atoms::ci, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_CN = new nsHtml5ElementName(nsHtml5Atoms::cn, nsHtml5Atoms::cn, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_DD = new nsHtml5ElementName(nsHtml5Atoms::dd, nsHtml5Atoms::dd, NS_HTML5TREE_BUILDER_DD_OR_DT | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_DL = new nsHtml5ElementName(nsHtml5Atoms::dl, nsHtml5Atoms::dl, NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_DT = new nsHtml5ElementName(nsHtml5Atoms::dt, nsHtml5Atoms::dt, NS_HTML5TREE_BUILDER_DD_OR_DT | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_EM = new nsHtml5ElementName(nsHtml5Atoms::em, nsHtml5Atoms::em, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ ELT_EQ = new nsHtml5ElementName(nsHtml5Atoms::eq, nsHtml5Atoms::eq, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FN = new nsHtml5ElementName(nsHtml5Atoms::fn, nsHtml5Atoms::fn, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_H1 = new nsHtml5ElementName(nsHtml5Atoms::h1, nsHtml5Atoms::h1, NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_H2 = new nsHtml5ElementName(nsHtml5Atoms::h2, nsHtml5Atoms::h2, NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_H3 = new nsHtml5ElementName(nsHtml5Atoms::h3, nsHtml5Atoms::h3, NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_H4 = new nsHtml5ElementName(nsHtml5Atoms::h4, nsHtml5Atoms::h4, NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_H5 = new nsHtml5ElementName(nsHtml5Atoms::h5, nsHtml5Atoms::h5, NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_H6 = new nsHtml5ElementName(nsHtml5Atoms::h6, nsHtml5Atoms::h6, NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_GT = new nsHtml5ElementName(nsHtml5Atoms::gt, nsHtml5Atoms::gt, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_HR = new nsHtml5ElementName(nsHtml5Atoms::hr, nsHtml5Atoms::hr, NS_HTML5TREE_BUILDER_HR | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_IN = new nsHtml5ElementName(nsHtml5Atoms::in, nsHtml5Atoms::in, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_LI = new nsHtml5ElementName(nsHtml5Atoms::li, nsHtml5Atoms::li, NS_HTML5TREE_BUILDER_LI | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_LN = new nsHtml5ElementName(nsHtml5Atoms::ln, nsHtml5Atoms::ln, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_LT = new nsHtml5ElementName(nsHtml5Atoms::lt, nsHtml5Atoms::lt, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MI = new nsHtml5ElementName(nsHtml5Atoms::mi, nsHtml5Atoms::mi, NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT | NS_HTML5ELEMENT_NAME_SCOPING_AS_MATHML);
+ ELT_MN = new nsHtml5ElementName(nsHtml5Atoms::mn, nsHtml5Atoms::mn, NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT | NS_HTML5ELEMENT_NAME_SCOPING_AS_MATHML);
+ ELT_MO = new nsHtml5ElementName(nsHtml5Atoms::mo, nsHtml5Atoms::mo, NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT | NS_HTML5ELEMENT_NAME_SCOPING_AS_MATHML);
+ ELT_MS = new nsHtml5ElementName(nsHtml5Atoms::ms, nsHtml5Atoms::ms, NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT | NS_HTML5ELEMENT_NAME_SCOPING_AS_MATHML);
+ ELT_OL = new nsHtml5ElementName(nsHtml5Atoms::ol, nsHtml5Atoms::ol, NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_OR = new nsHtml5ElementName(nsHtml5Atoms::or_, nsHtml5Atoms::or_, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_PI = new nsHtml5ElementName(nsHtml5Atoms::pi, nsHtml5Atoms::pi, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_RB = new nsHtml5ElementName(nsHtml5Atoms::rb, nsHtml5Atoms::rb, NS_HTML5TREE_BUILDER_RB_OR_RTC | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_RP = new nsHtml5ElementName(nsHtml5Atoms::rp, nsHtml5Atoms::rp, NS_HTML5TREE_BUILDER_RT_OR_RP | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_RT = new nsHtml5ElementName(nsHtml5Atoms::rt, nsHtml5Atoms::rt, NS_HTML5TREE_BUILDER_RT_OR_RP | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_TD = new nsHtml5ElementName(nsHtml5Atoms::td, nsHtml5Atoms::td, NS_HTML5TREE_BUILDER_TD_OR_TH | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_SCOPING | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_TH = new nsHtml5ElementName(nsHtml5Atoms::th, nsHtml5Atoms::th, NS_HTML5TREE_BUILDER_TD_OR_TH | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_SCOPING | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_TR = new nsHtml5ElementName(nsHtml5Atoms::tr, nsHtml5Atoms::tr, NS_HTML5TREE_BUILDER_TR | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_FOSTER_PARENTING | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_TT = new nsHtml5ElementName(nsHtml5Atoms::tt, nsHtml5Atoms::tt, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ ELT_UL = new nsHtml5ElementName(nsHtml5Atoms::ul, nsHtml5Atoms::ul, NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_AND = new nsHtml5ElementName(nsHtml5Atoms::and_, nsHtml5Atoms::and_, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ARG = new nsHtml5ElementName(nsHtml5Atoms::arg, nsHtml5Atoms::arg, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ABS = new nsHtml5ElementName(nsHtml5Atoms::abs, nsHtml5Atoms::abs, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_BIG = new nsHtml5ElementName(nsHtml5Atoms::big, nsHtml5Atoms::big, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ ELT_BDO = new nsHtml5ElementName(nsHtml5Atoms::bdo, nsHtml5Atoms::bdo, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_CSC = new nsHtml5ElementName(nsHtml5Atoms::csc, nsHtml5Atoms::csc, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_COL = new nsHtml5ElementName(nsHtml5Atoms::col, nsHtml5Atoms::col, NS_HTML5TREE_BUILDER_COL | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_COS = new nsHtml5ElementName(nsHtml5Atoms::cos, nsHtml5Atoms::cos, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_COT = new nsHtml5ElementName(nsHtml5Atoms::cot, nsHtml5Atoms::cot, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_DEL = new nsHtml5ElementName(nsHtml5Atoms::del, nsHtml5Atoms::del, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_DFN = new nsHtml5ElementName(nsHtml5Atoms::dfn, nsHtml5Atoms::dfn, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_DIR = new nsHtml5ElementName(nsHtml5Atoms::dir, nsHtml5Atoms::dir, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_DIV = new nsHtml5ElementName(nsHtml5Atoms::div, nsHtml5Atoms::div, NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_EXP = new nsHtml5ElementName(nsHtml5Atoms::exp, nsHtml5Atoms::exp, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_GCD = new nsHtml5ElementName(nsHtml5Atoms::gcd, nsHtml5Atoms::gcd, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_GEQ = new nsHtml5ElementName(nsHtml5Atoms::geq, nsHtml5Atoms::geq, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_IMG = new nsHtml5ElementName(nsHtml5Atoms::img, nsHtml5Atoms::img, NS_HTML5TREE_BUILDER_IMG | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_INS = new nsHtml5ElementName(nsHtml5Atoms::ins, nsHtml5Atoms::ins, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_INT = new nsHtml5ElementName(nsHtml5Atoms::int_, nsHtml5Atoms::int_, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_KBD = new nsHtml5ElementName(nsHtml5Atoms::kbd, nsHtml5Atoms::kbd, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_LOG = new nsHtml5ElementName(nsHtml5Atoms::log, nsHtml5Atoms::log, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_LCM = new nsHtml5ElementName(nsHtml5Atoms::lcm, nsHtml5Atoms::lcm, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_LEQ = new nsHtml5ElementName(nsHtml5Atoms::leq, nsHtml5Atoms::leq, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MTD = new nsHtml5ElementName(nsHtml5Atoms::mtd, nsHtml5Atoms::mtd, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MIN = new nsHtml5ElementName(nsHtml5Atoms::min, nsHtml5Atoms::min, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MAP = new nsHtml5ElementName(nsHtml5Atoms::map, nsHtml5Atoms::map, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MTR = new nsHtml5ElementName(nsHtml5Atoms::mtr, nsHtml5Atoms::mtr, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MAX = new nsHtml5ElementName(nsHtml5Atoms::max, nsHtml5Atoms::max, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_NEQ = new nsHtml5ElementName(nsHtml5Atoms::neq, nsHtml5Atoms::neq, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_NOT = new nsHtml5ElementName(nsHtml5Atoms::not_, nsHtml5Atoms::not_, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_NAV = new nsHtml5ElementName(nsHtml5Atoms::nav, nsHtml5Atoms::nav, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_PRE = new nsHtml5ElementName(nsHtml5Atoms::pre, nsHtml5Atoms::pre, NS_HTML5TREE_BUILDER_PRE_OR_LISTING | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_RTC = new nsHtml5ElementName(nsHtml5Atoms::rtc, nsHtml5Atoms::rtc, NS_HTML5TREE_BUILDER_RB_OR_RTC | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_REM = new nsHtml5ElementName(nsHtml5Atoms::rem, nsHtml5Atoms::rem, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SUB = new nsHtml5ElementName(nsHtml5Atoms::sub, nsHtml5Atoms::sub, NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
+ ELT_SEC = new nsHtml5ElementName(nsHtml5Atoms::sec, nsHtml5Atoms::sec, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SVG = new nsHtml5ElementName(nsHtml5Atoms::svg, nsHtml5Atoms::svg, NS_HTML5TREE_BUILDER_SVG);
+ ELT_SUM = new nsHtml5ElementName(nsHtml5Atoms::sum, nsHtml5Atoms::sum, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SIN = new nsHtml5ElementName(nsHtml5Atoms::sin, nsHtml5Atoms::sin, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SEP = new nsHtml5ElementName(nsHtml5Atoms::sep, nsHtml5Atoms::sep, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SUP = new nsHtml5ElementName(nsHtml5Atoms::sup, nsHtml5Atoms::sup, NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
+ ELT_SET = new nsHtml5ElementName(nsHtml5Atoms::set, nsHtml5Atoms::set, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_TAN = new nsHtml5ElementName(nsHtml5Atoms::tan, nsHtml5Atoms::tan, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_USE = new nsHtml5ElementName(nsHtml5Atoms::use, nsHtml5Atoms::use, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_VAR = new nsHtml5ElementName(nsHtml5Atoms::var, nsHtml5Atoms::var, NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
+ ELT_WBR = new nsHtml5ElementName(nsHtml5Atoms::wbr, nsHtml5Atoms::wbr, NS_HTML5TREE_BUILDER_AREA_OR_WBR | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_XMP = new nsHtml5ElementName(nsHtml5Atoms::xmp, nsHtml5Atoms::xmp, NS_HTML5TREE_BUILDER_XMP | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_XOR = new nsHtml5ElementName(nsHtml5Atoms::xor_, nsHtml5Atoms::xor_, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_AREA = new nsHtml5ElementName(nsHtml5Atoms::area, nsHtml5Atoms::area, NS_HTML5TREE_BUILDER_AREA_OR_WBR | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_ABBR = new nsHtml5ElementName(nsHtml5Atoms::abbr, nsHtml5Atoms::abbr, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_BASE = new nsHtml5ElementName(nsHtml5Atoms::base, nsHtml5Atoms::base, NS_HTML5TREE_BUILDER_BASE | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_BVAR = new nsHtml5ElementName(nsHtml5Atoms::bvar, nsHtml5Atoms::bvar, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_BODY = new nsHtml5ElementName(nsHtml5Atoms::body, nsHtml5Atoms::body, NS_HTML5TREE_BUILDER_BODY | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_CARD = new nsHtml5ElementName(nsHtml5Atoms::card, nsHtml5Atoms::card, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_CODE = new nsHtml5ElementName(nsHtml5Atoms::code, nsHtml5Atoms::code, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ ELT_CITE = new nsHtml5ElementName(nsHtml5Atoms::cite, nsHtml5Atoms::cite, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_CSCH = new nsHtml5ElementName(nsHtml5Atoms::csch, nsHtml5Atoms::csch, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_COSH = new nsHtml5ElementName(nsHtml5Atoms::cosh, nsHtml5Atoms::cosh, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_COTH = new nsHtml5ElementName(nsHtml5Atoms::coth, nsHtml5Atoms::coth, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_CURL = new nsHtml5ElementName(nsHtml5Atoms::curl, nsHtml5Atoms::curl, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_DESC = new nsHtml5ElementName(nsHtml5Atoms::desc, nsHtml5Atoms::desc, NS_HTML5TREE_BUILDER_FOREIGNOBJECT_OR_DESC | NS_HTML5ELEMENT_NAME_SCOPING_AS_SVG);
+ ELT_DIFF = new nsHtml5ElementName(nsHtml5Atoms::diff, nsHtml5Atoms::diff, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_DEFS = new nsHtml5ElementName(nsHtml5Atoms::defs, nsHtml5Atoms::defs, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FORM = new nsHtml5ElementName(nsHtml5Atoms::form, nsHtml5Atoms::form, NS_HTML5TREE_BUILDER_FORM | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_FONT = new nsHtml5ElementName(nsHtml5Atoms::font, nsHtml5Atoms::font, NS_HTML5TREE_BUILDER_FONT);
+ ELT_GRAD = new nsHtml5ElementName(nsHtml5Atoms::grad, nsHtml5Atoms::grad, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_HEAD = new nsHtml5ElementName(nsHtml5Atoms::head, nsHtml5Atoms::head, NS_HTML5TREE_BUILDER_HEAD | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_HTML = new nsHtml5ElementName(nsHtml5Atoms::html, nsHtml5Atoms::html, NS_HTML5TREE_BUILDER_HTML | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_SCOPING | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_LINE = new nsHtml5ElementName(nsHtml5Atoms::line, nsHtml5Atoms::line, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_LINK = new nsHtml5ElementName(nsHtml5Atoms::link, nsHtml5Atoms::link, NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_LIST = new nsHtml5ElementName(nsHtml5Atoms::list, nsHtml5Atoms::list, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_META = new nsHtml5ElementName(nsHtml5Atoms::meta, nsHtml5Atoms::meta, NS_HTML5TREE_BUILDER_META | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_MSUB = new nsHtml5ElementName(nsHtml5Atoms::msub, nsHtml5Atoms::msub, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MODE = new nsHtml5ElementName(nsHtml5Atoms::mode, nsHtml5Atoms::mode, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MATH = new nsHtml5ElementName(nsHtml5Atoms::math, nsHtml5Atoms::math, NS_HTML5TREE_BUILDER_MATH);
+ ELT_MARK = new nsHtml5ElementName(nsHtml5Atoms::mark, nsHtml5Atoms::mark, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MASK = new nsHtml5ElementName(nsHtml5Atoms::mask, nsHtml5Atoms::mask, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MEAN = new nsHtml5ElementName(nsHtml5Atoms::mean, nsHtml5Atoms::mean, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MAIN = new nsHtml5ElementName(nsHtml5Atoms::main, nsHtml5Atoms::main, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_MSUP = new nsHtml5ElementName(nsHtml5Atoms::msup, nsHtml5Atoms::msup, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MENU = new nsHtml5ElementName(nsHtml5Atoms::menu, nsHtml5Atoms::menu, NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_MROW = new nsHtml5ElementName(nsHtml5Atoms::mrow, nsHtml5Atoms::mrow, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_NONE = new nsHtml5ElementName(nsHtml5Atoms::none, nsHtml5Atoms::none, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_NOBR = new nsHtml5ElementName(nsHtml5Atoms::nobr, nsHtml5Atoms::nobr, NS_HTML5TREE_BUILDER_NOBR);
+ ELT_NEST = new nsHtml5ElementName(nsHtml5Atoms::nest, nsHtml5Atoms::nest, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_PATH = new nsHtml5ElementName(nsHtml5Atoms::path, nsHtml5Atoms::path, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_PLUS = new nsHtml5ElementName(nsHtml5Atoms::plus, nsHtml5Atoms::plus, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_RULE = new nsHtml5ElementName(nsHtml5Atoms::rule, nsHtml5Atoms::rule, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_REAL = new nsHtml5ElementName(nsHtml5Atoms::real, nsHtml5Atoms::real, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_RELN = new nsHtml5ElementName(nsHtml5Atoms::reln, nsHtml5Atoms::reln, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_RECT = new nsHtml5ElementName(nsHtml5Atoms::rect, nsHtml5Atoms::rect, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ROOT = new nsHtml5ElementName(nsHtml5Atoms::root, nsHtml5Atoms::root, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_RUBY = new nsHtml5ElementName(nsHtml5Atoms::ruby, nsHtml5Atoms::ruby, NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
+ ELT_SECH = new nsHtml5ElementName(nsHtml5Atoms::sech, nsHtml5Atoms::sech, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SINH = new nsHtml5ElementName(nsHtml5Atoms::sinh, nsHtml5Atoms::sinh, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SPAN = new nsHtml5ElementName(nsHtml5Atoms::span, nsHtml5Atoms::span, NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
+ ELT_SAMP = new nsHtml5ElementName(nsHtml5Atoms::samp, nsHtml5Atoms::samp, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_STOP = new nsHtml5ElementName(nsHtml5Atoms::stop, nsHtml5Atoms::stop, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SDEV = new nsHtml5ElementName(nsHtml5Atoms::sdev, nsHtml5Atoms::sdev, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_TIME = new nsHtml5ElementName(nsHtml5Atoms::time, nsHtml5Atoms::time, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_TRUE = new nsHtml5ElementName(nsHtml5Atoms::true_, nsHtml5Atoms::true_, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_TREF = new nsHtml5ElementName(nsHtml5Atoms::tref, nsHtml5Atoms::tref, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_TANH = new nsHtml5ElementName(nsHtml5Atoms::tanh, nsHtml5Atoms::tanh, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_TEXT = new nsHtml5ElementName(nsHtml5Atoms::text, nsHtml5Atoms::text, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_VIEW = new nsHtml5ElementName(nsHtml5Atoms::view, nsHtml5Atoms::view, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ASIDE = new nsHtml5ElementName(nsHtml5Atoms::aside, nsHtml5Atoms::aside, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_AUDIO = new nsHtml5ElementName(nsHtml5Atoms::audio, nsHtml5Atoms::audio, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_APPLY = new nsHtml5ElementName(nsHtml5Atoms::apply, nsHtml5Atoms::apply, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_EMBED = new nsHtml5ElementName(nsHtml5Atoms::embed, nsHtml5Atoms::embed, NS_HTML5TREE_BUILDER_EMBED | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_FRAME = new nsHtml5ElementName(nsHtml5Atoms::frame, nsHtml5Atoms::frame, NS_HTML5TREE_BUILDER_FRAME | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_FALSE = new nsHtml5ElementName(nsHtml5Atoms::false_, nsHtml5Atoms::false_, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FLOOR = new nsHtml5ElementName(nsHtml5Atoms::floor, nsHtml5Atoms::floor, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_GLYPH = new nsHtml5ElementName(nsHtml5Atoms::glyph, nsHtml5Atoms::glyph, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_HKERN = new nsHtml5ElementName(nsHtml5Atoms::hkern, nsHtml5Atoms::hkern, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_IMAGE = new nsHtml5ElementName(nsHtml5Atoms::image, nsHtml5Atoms::image, NS_HTML5TREE_BUILDER_IMAGE);
+ ELT_IDENT = new nsHtml5ElementName(nsHtml5Atoms::ident, nsHtml5Atoms::ident, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_INPUT = new nsHtml5ElementName(nsHtml5Atoms::input, nsHtml5Atoms::input, NS_HTML5TREE_BUILDER_INPUT | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_LABEL = new nsHtml5ElementName(nsHtml5Atoms::label, nsHtml5Atoms::label, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_LIMIT = new nsHtml5ElementName(nsHtml5Atoms::limit, nsHtml5Atoms::limit, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MFRAC = new nsHtml5ElementName(nsHtml5Atoms::mfrac, nsHtml5Atoms::mfrac, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MPATH = new nsHtml5ElementName(nsHtml5Atoms::mpath, nsHtml5Atoms::mpath, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_METER = new nsHtml5ElementName(nsHtml5Atoms::meter, nsHtml5Atoms::meter, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MOVER = new nsHtml5ElementName(nsHtml5Atoms::mover, nsHtml5Atoms::mover, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MINUS = new nsHtml5ElementName(nsHtml5Atoms::minus, nsHtml5Atoms::minus, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MROOT = new nsHtml5ElementName(nsHtml5Atoms::mroot, nsHtml5Atoms::mroot, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MSQRT = new nsHtml5ElementName(nsHtml5Atoms::msqrt, nsHtml5Atoms::msqrt, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MTEXT = new nsHtml5ElementName(nsHtml5Atoms::mtext, nsHtml5Atoms::mtext, NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT | NS_HTML5ELEMENT_NAME_SCOPING_AS_MATHML);
+ ELT_NOTIN = new nsHtml5ElementName(nsHtml5Atoms::notin, nsHtml5Atoms::notin, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_PIECE = new nsHtml5ElementName(nsHtml5Atoms::piece, nsHtml5Atoms::piece, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_PARAM = new nsHtml5ElementName(nsHtml5Atoms::param, nsHtml5Atoms::param, NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE_OR_TRACK | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_POWER = new nsHtml5ElementName(nsHtml5Atoms::power, nsHtml5Atoms::power, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_REALS = new nsHtml5ElementName(nsHtml5Atoms::reals, nsHtml5Atoms::reals, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_STYLE = new nsHtml5ElementName(nsHtml5Atoms::style, nsHtml5Atoms::style, NS_HTML5TREE_BUILDER_STYLE | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_SMALL = new nsHtml5ElementName(nsHtml5Atoms::small_, nsHtml5Atoms::small_, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ ELT_THEAD = new nsHtml5ElementName(nsHtml5Atoms::thead, nsHtml5Atoms::thead, NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_FOSTER_PARENTING | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_TABLE = new nsHtml5ElementName(nsHtml5Atoms::table, nsHtml5Atoms::table, NS_HTML5TREE_BUILDER_TABLE | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_FOSTER_PARENTING | NS_HTML5ELEMENT_NAME_SCOPING);
+ ELT_TITLE = new nsHtml5ElementName(nsHtml5Atoms::title, nsHtml5Atoms::title, NS_HTML5TREE_BUILDER_TITLE | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_SCOPING_AS_SVG);
+ ELT_TRACK = new nsHtml5ElementName(nsHtml5Atoms::track, nsHtml5Atoms::track, NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE_OR_TRACK | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_TSPAN = new nsHtml5ElementName(nsHtml5Atoms::tspan, nsHtml5Atoms::tspan, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_TIMES = new nsHtml5ElementName(nsHtml5Atoms::times, nsHtml5Atoms::times, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_TFOOT = new nsHtml5ElementName(nsHtml5Atoms::tfoot, nsHtml5Atoms::tfoot, NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_FOSTER_PARENTING | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_TBODY = new nsHtml5ElementName(nsHtml5Atoms::tbody, nsHtml5Atoms::tbody, NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_FOSTER_PARENTING | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_UNION = new nsHtml5ElementName(nsHtml5Atoms::union_, nsHtml5Atoms::union_, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_VKERN = new nsHtml5ElementName(nsHtml5Atoms::vkern, nsHtml5Atoms::vkern, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_VIDEO = new nsHtml5ElementName(nsHtml5Atoms::video, nsHtml5Atoms::video, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ARCSEC = new nsHtml5ElementName(nsHtml5Atoms::arcsec, nsHtml5Atoms::arcsec, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ARCCSC = new nsHtml5ElementName(nsHtml5Atoms::arccsc, nsHtml5Atoms::arccsc, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ARCTAN = new nsHtml5ElementName(nsHtml5Atoms::arctan, nsHtml5Atoms::arctan, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ARCSIN = new nsHtml5ElementName(nsHtml5Atoms::arcsin, nsHtml5Atoms::arcsin, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ARCCOS = new nsHtml5ElementName(nsHtml5Atoms::arccos, nsHtml5Atoms::arccos, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_APPLET = new nsHtml5ElementName(nsHtml5Atoms::applet, nsHtml5Atoms::applet, NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_SCOPING);
+ ELT_ARCCOT = new nsHtml5ElementName(nsHtml5Atoms::arccot, nsHtml5Atoms::arccot, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_APPROX = new nsHtml5ElementName(nsHtml5Atoms::approx, nsHtml5Atoms::approx, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_BUTTON = new nsHtml5ElementName(nsHtml5Atoms::button, nsHtml5Atoms::button, NS_HTML5TREE_BUILDER_BUTTON | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_CIRCLE = new nsHtml5ElementName(nsHtml5Atoms::circle, nsHtml5Atoms::circle, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_CENTER = new nsHtml5ElementName(nsHtml5Atoms::center, nsHtml5Atoms::center, NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_CURSOR = new nsHtml5ElementName(nsHtml5Atoms::cursor, nsHtml5Atoms::cursor, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_CANVAS = new nsHtml5ElementName(nsHtml5Atoms::canvas, nsHtml5Atoms::canvas, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_DIVIDE = new nsHtml5ElementName(nsHtml5Atoms::divide, nsHtml5Atoms::divide, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_DEGREE = new nsHtml5ElementName(nsHtml5Atoms::degree, nsHtml5Atoms::degree, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_DOMAIN = new nsHtml5ElementName(nsHtml5Atoms::domain, nsHtml5Atoms::domain, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_EXISTS = new nsHtml5ElementName(nsHtml5Atoms::exists, nsHtml5Atoms::exists, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FETILE = new nsHtml5ElementName(nsHtml5Atoms::fetile, nsHtml5Atoms::feTile, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FIGURE = new nsHtml5ElementName(nsHtml5Atoms::figure, nsHtml5Atoms::figure, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_FORALL = new nsHtml5ElementName(nsHtml5Atoms::forall, nsHtml5Atoms::forall, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FILTER = new nsHtml5ElementName(nsHtml5Atoms::filter, nsHtml5Atoms::filter, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FOOTER = new nsHtml5ElementName(nsHtml5Atoms::footer, nsHtml5Atoms::footer, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_HGROUP = new nsHtml5ElementName(nsHtml5Atoms::hgroup, nsHtml5Atoms::hgroup, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_HEADER = new nsHtml5ElementName(nsHtml5Atoms::header, nsHtml5Atoms::header, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_IFRAME = new nsHtml5ElementName(nsHtml5Atoms::iframe, nsHtml5Atoms::iframe, NS_HTML5TREE_BUILDER_IFRAME | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_KEYGEN = new nsHtml5ElementName(nsHtml5Atoms::keygen, nsHtml5Atoms::keygen, NS_HTML5TREE_BUILDER_KEYGEN);
+ ELT_LAMBDA = new nsHtml5ElementName(nsHtml5Atoms::lambda, nsHtml5Atoms::lambda, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_LEGEND = new nsHtml5ElementName(nsHtml5Atoms::legend, nsHtml5Atoms::legend, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MSPACE = new nsHtml5ElementName(nsHtml5Atoms::mspace, nsHtml5Atoms::mspace, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MTABLE = new nsHtml5ElementName(nsHtml5Atoms::mtable, nsHtml5Atoms::mtable, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MSTYLE = new nsHtml5ElementName(nsHtml5Atoms::mstyle, nsHtml5Atoms::mstyle, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MGLYPH = new nsHtml5ElementName(nsHtml5Atoms::mglyph, nsHtml5Atoms::mglyph, NS_HTML5TREE_BUILDER_MGLYPH_OR_MALIGNMARK);
+ ELT_MEDIAN = new nsHtml5ElementName(nsHtml5Atoms::median, nsHtml5Atoms::median, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MUNDER = new nsHtml5ElementName(nsHtml5Atoms::munder, nsHtml5Atoms::munder, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MARKER = new nsHtml5ElementName(nsHtml5Atoms::marker, nsHtml5Atoms::marker, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MERROR = new nsHtml5ElementName(nsHtml5Atoms::merror, nsHtml5Atoms::merror, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MOMENT = new nsHtml5ElementName(nsHtml5Atoms::moment, nsHtml5Atoms::moment, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MATRIX = new nsHtml5ElementName(nsHtml5Atoms::matrix, nsHtml5Atoms::matrix, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_OPTION = new nsHtml5ElementName(nsHtml5Atoms::option, nsHtml5Atoms::option, NS_HTML5TREE_BUILDER_OPTION | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_OBJECT = new nsHtml5ElementName(nsHtml5Atoms::object, nsHtml5Atoms::object, NS_HTML5TREE_BUILDER_OBJECT | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_SCOPING);
+ ELT_OUTPUT = new nsHtml5ElementName(nsHtml5Atoms::output, nsHtml5Atoms::output, NS_HTML5TREE_BUILDER_OUTPUT);
+ ELT_PRIMES = new nsHtml5ElementName(nsHtml5Atoms::primes, nsHtml5Atoms::primes, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SOURCE = new nsHtml5ElementName(nsHtml5Atoms::source, nsHtml5Atoms::source, NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE_OR_TRACK);
+ ELT_STRIKE = new nsHtml5ElementName(nsHtml5Atoms::strike, nsHtml5Atoms::strike, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ ELT_STRONG = new nsHtml5ElementName(nsHtml5Atoms::strong, nsHtml5Atoms::strong, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+ ELT_SWITCH = new nsHtml5ElementName(nsHtml5Atoms::switch_, nsHtml5Atoms::switch_, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SYMBOL = new nsHtml5ElementName(nsHtml5Atoms::symbol, nsHtml5Atoms::symbol, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SELECT = new nsHtml5ElementName(nsHtml5Atoms::select, nsHtml5Atoms::select, NS_HTML5TREE_BUILDER_SELECT | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_SUBSET = new nsHtml5ElementName(nsHtml5Atoms::subset, nsHtml5Atoms::subset, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SCRIPT = new nsHtml5ElementName(nsHtml5Atoms::script, nsHtml5Atoms::script, NS_HTML5TREE_BUILDER_SCRIPT | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_TBREAK = new nsHtml5ElementName(nsHtml5Atoms::tbreak, nsHtml5Atoms::tbreak, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_VECTOR = new nsHtml5ElementName(nsHtml5Atoms::vector, nsHtml5Atoms::vector, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ARTICLE = new nsHtml5ElementName(nsHtml5Atoms::article, nsHtml5Atoms::article, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_ANIMATE = new nsHtml5ElementName(nsHtml5Atoms::animate, nsHtml5Atoms::animate, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ARCSECH = new nsHtml5ElementName(nsHtml5Atoms::arcsech, nsHtml5Atoms::arcsech, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ARCCSCH = new nsHtml5ElementName(nsHtml5Atoms::arccsch, nsHtml5Atoms::arccsch, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ARCTANH = new nsHtml5ElementName(nsHtml5Atoms::arctanh, nsHtml5Atoms::arctanh, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ARCSINH = new nsHtml5ElementName(nsHtml5Atoms::arcsinh, nsHtml5Atoms::arcsinh, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ARCCOSH = new nsHtml5ElementName(nsHtml5Atoms::arccosh, nsHtml5Atoms::arccosh, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ARCCOTH = new nsHtml5ElementName(nsHtml5Atoms::arccoth, nsHtml5Atoms::arccoth, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ACRONYM = new nsHtml5ElementName(nsHtml5Atoms::acronym, nsHtml5Atoms::acronym, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ADDRESS = new nsHtml5ElementName(nsHtml5Atoms::address, nsHtml5Atoms::address, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_BGSOUND = new nsHtml5ElementName(nsHtml5Atoms::bgsound, nsHtml5Atoms::bgsound, NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_COMPOSE = new nsHtml5ElementName(nsHtml5Atoms::compose, nsHtml5Atoms::compose, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_CEILING = new nsHtml5ElementName(nsHtml5Atoms::ceiling, nsHtml5Atoms::ceiling, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_CSYMBOL = new nsHtml5ElementName(nsHtml5Atoms::csymbol, nsHtml5Atoms::csymbol, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_CAPTION = new nsHtml5ElementName(nsHtml5Atoms::caption, nsHtml5Atoms::caption, NS_HTML5TREE_BUILDER_CAPTION | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_SCOPING);
+ ELT_DISCARD = new nsHtml5ElementName(nsHtml5Atoms::discard, nsHtml5Atoms::discard, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_DECLARE = new nsHtml5ElementName(nsHtml5Atoms::declare, nsHtml5Atoms::declare, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_DETAILS = new nsHtml5ElementName(nsHtml5Atoms::details, nsHtml5Atoms::details, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_ELLIPSE = new nsHtml5ElementName(nsHtml5Atoms::ellipse, nsHtml5Atoms::ellipse, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEFUNCA = new nsHtml5ElementName(nsHtml5Atoms::fefunca, nsHtml5Atoms::feFuncA, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEFUNCB = new nsHtml5ElementName(nsHtml5Atoms::fefuncb, nsHtml5Atoms::feFuncB, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEBLEND = new nsHtml5ElementName(nsHtml5Atoms::feblend, nsHtml5Atoms::feBlend, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEFLOOD = new nsHtml5ElementName(nsHtml5Atoms::feflood, nsHtml5Atoms::feFlood, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEIMAGE = new nsHtml5ElementName(nsHtml5Atoms::feimage, nsHtml5Atoms::feImage, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEMERGE = new nsHtml5ElementName(nsHtml5Atoms::femerge, nsHtml5Atoms::feMerge, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEFUNCG = new nsHtml5ElementName(nsHtml5Atoms::fefuncg, nsHtml5Atoms::feFuncG, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEFUNCR = new nsHtml5ElementName(nsHtml5Atoms::fefuncr, nsHtml5Atoms::feFuncR, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_HANDLER = new nsHtml5ElementName(nsHtml5Atoms::handler, nsHtml5Atoms::handler, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_INVERSE = new nsHtml5ElementName(nsHtml5Atoms::inverse, nsHtml5Atoms::inverse, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_IMPLIES = new nsHtml5ElementName(nsHtml5Atoms::implies, nsHtml5Atoms::implies, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ISINDEX = new nsHtml5ElementName(nsHtml5Atoms::isindex, nsHtml5Atoms::isindex, NS_HTML5TREE_BUILDER_ISINDEX | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_LOGBASE = new nsHtml5ElementName(nsHtml5Atoms::logbase, nsHtml5Atoms::logbase, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_LISTING = new nsHtml5ElementName(nsHtml5Atoms::listing, nsHtml5Atoms::listing, NS_HTML5TREE_BUILDER_PRE_OR_LISTING | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_MFENCED = new nsHtml5ElementName(nsHtml5Atoms::mfenced, nsHtml5Atoms::mfenced, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MPADDED = new nsHtml5ElementName(nsHtml5Atoms::mpadded, nsHtml5Atoms::mpadded, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MARQUEE = new nsHtml5ElementName(nsHtml5Atoms::marquee, nsHtml5Atoms::marquee, NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_SCOPING);
+ ELT_MACTION = new nsHtml5ElementName(nsHtml5Atoms::maction, nsHtml5Atoms::maction, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MSUBSUP = new nsHtml5ElementName(nsHtml5Atoms::msubsup, nsHtml5Atoms::msubsup, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_NOEMBED = new nsHtml5ElementName(nsHtml5Atoms::noembed, nsHtml5Atoms::noembed, NS_HTML5TREE_BUILDER_NOEMBED | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_POLYGON = new nsHtml5ElementName(nsHtml5Atoms::polygon, nsHtml5Atoms::polygon, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_PATTERN = new nsHtml5ElementName(nsHtml5Atoms::pattern, nsHtml5Atoms::pattern, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_PICTURE = new nsHtml5ElementName(nsHtml5Atoms::picture, nsHtml5Atoms::picture, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_PRODUCT = new nsHtml5ElementName(nsHtml5Atoms::product, nsHtml5Atoms::product, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SETDIFF = new nsHtml5ElementName(nsHtml5Atoms::setdiff, nsHtml5Atoms::setdiff, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SECTION = new nsHtml5ElementName(nsHtml5Atoms::section, nsHtml5Atoms::section, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_SUMMARY = new nsHtml5ElementName(nsHtml5Atoms::summary, nsHtml5Atoms::summary, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_TENDSTO = new nsHtml5ElementName(nsHtml5Atoms::tendsto, nsHtml5Atoms::tendsto, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_UPLIMIT = new nsHtml5ElementName(nsHtml5Atoms::uplimit, nsHtml5Atoms::uplimit, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ALTGLYPH = new nsHtml5ElementName(nsHtml5Atoms::altglyph, nsHtml5Atoms::altGlyph, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_BASEFONT = new nsHtml5ElementName(nsHtml5Atoms::basefont, nsHtml5Atoms::basefont, NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_CLIPPATH = new nsHtml5ElementName(nsHtml5Atoms::clippath, nsHtml5Atoms::clipPath, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_CODOMAIN = new nsHtml5ElementName(nsHtml5Atoms::codomain, nsHtml5Atoms::codomain, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_COLGROUP = new nsHtml5ElementName(nsHtml5Atoms::colgroup, nsHtml5Atoms::colgroup, NS_HTML5TREE_BUILDER_COLGROUP | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_EMPTYSET = new nsHtml5ElementName(nsHtml5Atoms::emptyset, nsHtml5Atoms::emptyset, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FACTOROF = new nsHtml5ElementName(nsHtml5Atoms::factorof, nsHtml5Atoms::factorof, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FIELDSET = new nsHtml5ElementName(nsHtml5Atoms::fieldset, nsHtml5Atoms::fieldset, NS_HTML5TREE_BUILDER_FIELDSET | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_FRAMESET = new nsHtml5ElementName(nsHtml5Atoms::frameset, nsHtml5Atoms::frameset, NS_HTML5TREE_BUILDER_FRAMESET | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_FEOFFSET = new nsHtml5ElementName(nsHtml5Atoms::feoffset, nsHtml5Atoms::feOffset, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_GLYPHREF = new nsHtml5ElementName(nsHtml5Atoms::glyphref, nsHtml5Atoms::glyphRef, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_INTERVAL = new nsHtml5ElementName(nsHtml5Atoms::interval, nsHtml5Atoms::interval, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_INTEGERS = new nsHtml5ElementName(nsHtml5Atoms::integers, nsHtml5Atoms::integers, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_INFINITY = new nsHtml5ElementName(nsHtml5Atoms::infinity, nsHtml5Atoms::infinity, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_LISTENER = new nsHtml5ElementName(nsHtml5Atoms::listener, nsHtml5Atoms::listener, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_LOWLIMIT = new nsHtml5ElementName(nsHtml5Atoms::lowlimit, nsHtml5Atoms::lowlimit, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_METADATA = new nsHtml5ElementName(nsHtml5Atoms::metadata, nsHtml5Atoms::metadata, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MENCLOSE = new nsHtml5ElementName(nsHtml5Atoms::menclose, nsHtml5Atoms::menclose, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MENUITEM = new nsHtml5ElementName(nsHtml5Atoms::menuitem, nsHtml5Atoms::menuitem, NS_HTML5TREE_BUILDER_MENUITEM);
+ ELT_MPHANTOM = new nsHtml5ElementName(nsHtml5Atoms::mphantom, nsHtml5Atoms::mphantom, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_NOFRAMES = new nsHtml5ElementName(nsHtml5Atoms::noframes, nsHtml5Atoms::noframes, NS_HTML5TREE_BUILDER_NOFRAMES | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_NOSCRIPT = new nsHtml5ElementName(nsHtml5Atoms::noscript, nsHtml5Atoms::noscript, NS_HTML5TREE_BUILDER_NOSCRIPT | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_OPTGROUP = new nsHtml5ElementName(nsHtml5Atoms::optgroup, nsHtml5Atoms::optgroup, NS_HTML5TREE_BUILDER_OPTGROUP | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ ELT_POLYLINE = new nsHtml5ElementName(nsHtml5Atoms::polyline, nsHtml5Atoms::polyline, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_PREFETCH = new nsHtml5ElementName(nsHtml5Atoms::prefetch, nsHtml5Atoms::prefetch, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_PROGRESS = new nsHtml5ElementName(nsHtml5Atoms::progress, nsHtml5Atoms::progress, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_PRSUBSET = new nsHtml5ElementName(nsHtml5Atoms::prsubset, nsHtml5Atoms::prsubset, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_QUOTIENT = new nsHtml5ElementName(nsHtml5Atoms::quotient, nsHtml5Atoms::quotient, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SELECTOR = new nsHtml5ElementName(nsHtml5Atoms::selector, nsHtml5Atoms::selector, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_TEXTAREA = new nsHtml5ElementName(nsHtml5Atoms::textarea, nsHtml5Atoms::textarea, NS_HTML5TREE_BUILDER_TEXTAREA | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_TEMPLATE = new nsHtml5ElementName(nsHtml5Atoms::template_, nsHtml5Atoms::template_, NS_HTML5TREE_BUILDER_TEMPLATE | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_SCOPING);
+ ELT_TEXTPATH = new nsHtml5ElementName(nsHtml5Atoms::textpath, nsHtml5Atoms::textPath, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_VARIANCE = new nsHtml5ElementName(nsHtml5Atoms::variance, nsHtml5Atoms::variance, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ANIMATION = new nsHtml5ElementName(nsHtml5Atoms::animation, nsHtml5Atoms::animation, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_CONJUGATE = new nsHtml5ElementName(nsHtml5Atoms::conjugate, nsHtml5Atoms::conjugate, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_CONDITION = new nsHtml5ElementName(nsHtml5Atoms::condition, nsHtml5Atoms::condition, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_COMPLEXES = new nsHtml5ElementName(nsHtml5Atoms::complexes, nsHtml5Atoms::complexes, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FONT_FACE = new nsHtml5ElementName(nsHtml5Atoms::font_face, nsHtml5Atoms::font_face, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FACTORIAL = new nsHtml5ElementName(nsHtml5Atoms::factorial, nsHtml5Atoms::factorial, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_INTERSECT = new nsHtml5ElementName(nsHtml5Atoms::intersect, nsHtml5Atoms::intersect, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_IMAGINARY = new nsHtml5ElementName(nsHtml5Atoms::imaginary, nsHtml5Atoms::imaginary, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_LAPLACIAN = new nsHtml5ElementName(nsHtml5Atoms::laplacian, nsHtml5Atoms::laplacian, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MATRIXROW = new nsHtml5ElementName(nsHtml5Atoms::matrixrow, nsHtml5Atoms::matrixrow, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_NOTSUBSET = new nsHtml5ElementName(nsHtml5Atoms::notsubset, nsHtml5Atoms::notsubset, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_OTHERWISE = new nsHtml5ElementName(nsHtml5Atoms::otherwise, nsHtml5Atoms::otherwise, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_PIECEWISE = new nsHtml5ElementName(nsHtml5Atoms::piecewise, nsHtml5Atoms::piecewise, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_PLAINTEXT = new nsHtml5ElementName(nsHtml5Atoms::plaintext, nsHtml5Atoms::plaintext, NS_HTML5TREE_BUILDER_PLAINTEXT | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_RATIONALS = new nsHtml5ElementName(nsHtml5Atoms::rationals, nsHtml5Atoms::rationals, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SEMANTICS = new nsHtml5ElementName(nsHtml5Atoms::semantics, nsHtml5Atoms::semantics, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_TRANSPOSE = new nsHtml5ElementName(nsHtml5Atoms::transpose, nsHtml5Atoms::transpose, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ANNOTATION = new nsHtml5ElementName(nsHtml5Atoms::annotation, nsHtml5Atoms::annotation, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_BLOCKQUOTE = new nsHtml5ElementName(nsHtml5Atoms::blockquote, nsHtml5Atoms::blockquote, NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_DIVERGENCE = new nsHtml5ElementName(nsHtml5Atoms::divergence, nsHtml5Atoms::divergence, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_EULERGAMMA = new nsHtml5ElementName(nsHtml5Atoms::eulergamma, nsHtml5Atoms::eulergamma, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_EQUIVALENT = new nsHtml5ElementName(nsHtml5Atoms::equivalent, nsHtml5Atoms::equivalent, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FIGCAPTION = new nsHtml5ElementName(nsHtml5Atoms::figcaption, nsHtml5Atoms::figcaption, NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY | NS_HTML5ELEMENT_NAME_SPECIAL);
+ ELT_IMAGINARYI = new nsHtml5ElementName(nsHtml5Atoms::imaginaryi, nsHtml5Atoms::imaginaryi, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MALIGNMARK = new nsHtml5ElementName(nsHtml5Atoms::malignmark, nsHtml5Atoms::malignmark, NS_HTML5TREE_BUILDER_MGLYPH_OR_MALIGNMARK);
+ ELT_MUNDEROVER = new nsHtml5ElementName(nsHtml5Atoms::munderover, nsHtml5Atoms::munderover, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MLABELEDTR = new nsHtml5ElementName(nsHtml5Atoms::mlabeledtr, nsHtml5Atoms::mlabeledtr, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_NOTANUMBER = new nsHtml5ElementName(nsHtml5Atoms::notanumber, nsHtml5Atoms::notanumber, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SOLIDCOLOR = new nsHtml5ElementName(nsHtml5Atoms::solidcolor, nsHtml5Atoms::solidcolor, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ALTGLYPHDEF = new nsHtml5ElementName(nsHtml5Atoms::altglyphdef, nsHtml5Atoms::altGlyphDef, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_DETERMINANT = new nsHtml5ElementName(nsHtml5Atoms::determinant, nsHtml5Atoms::determinant, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEMERGENODE = new nsHtml5ElementName(nsHtml5Atoms::femergenode, nsHtml5Atoms::feMergeNode, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FECOMPOSITE = new nsHtml5ElementName(nsHtml5Atoms::fecomposite, nsHtml5Atoms::feComposite, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FESPOTLIGHT = new nsHtml5ElementName(nsHtml5Atoms::fespotlight, nsHtml5Atoms::feSpotLight, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MALIGNGROUP = new nsHtml5ElementName(nsHtml5Atoms::maligngroup, nsHtml5Atoms::maligngroup, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MPRESCRIPTS = new nsHtml5ElementName(nsHtml5Atoms::mprescripts, nsHtml5Atoms::mprescripts, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MOMENTABOUT = new nsHtml5ElementName(nsHtml5Atoms::momentabout, nsHtml5Atoms::momentabout, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_NOTPRSUBSET = new nsHtml5ElementName(nsHtml5Atoms::notprsubset, nsHtml5Atoms::notprsubset, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_PARTIALDIFF = new nsHtml5ElementName(nsHtml5Atoms::partialdiff, nsHtml5Atoms::partialdiff, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ALTGLYPHITEM = new nsHtml5ElementName(nsHtml5Atoms::altglyphitem, nsHtml5Atoms::altGlyphItem, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ANIMATECOLOR = new nsHtml5ElementName(nsHtml5Atoms::animatecolor, nsHtml5Atoms::animateColor, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_DATATEMPLATE = new nsHtml5ElementName(nsHtml5Atoms::datatemplate, nsHtml5Atoms::datatemplate, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_EXPONENTIALE = new nsHtml5ElementName(nsHtml5Atoms::exponentiale, nsHtml5Atoms::exponentiale, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FETURBULENCE = new nsHtml5ElementName(nsHtml5Atoms::feturbulence, nsHtml5Atoms::feTurbulence, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEPOINTLIGHT = new nsHtml5ElementName(nsHtml5Atoms::fepointlight, nsHtml5Atoms::fePointLight, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEDROPSHADOW = new nsHtml5ElementName(nsHtml5Atoms::fedropshadow, nsHtml5Atoms::feDropShadow, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEMORPHOLOGY = new nsHtml5ElementName(nsHtml5Atoms::femorphology, nsHtml5Atoms::feMorphology, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_OUTERPRODUCT = new nsHtml5ElementName(nsHtml5Atoms::outerproduct, nsHtml5Atoms::outerproduct, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ANIMATEMOTION = new nsHtml5ElementName(nsHtml5Atoms::animatemotion, nsHtml5Atoms::animateMotion, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_COLOR_PROFILE = new nsHtml5ElementName(nsHtml5Atoms::color_profile, nsHtml5Atoms::color_profile, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FONT_FACE_SRC = new nsHtml5ElementName(nsHtml5Atoms::font_face_src, nsHtml5Atoms::font_face_src, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FONT_FACE_URI = new nsHtml5ElementName(nsHtml5Atoms::font_face_uri, nsHtml5Atoms::font_face_uri, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FOREIGNOBJECT = new nsHtml5ElementName(nsHtml5Atoms::foreignobject, nsHtml5Atoms::foreignObject, NS_HTML5TREE_BUILDER_FOREIGNOBJECT_OR_DESC | NS_HTML5ELEMENT_NAME_SCOPING_AS_SVG);
+ ELT_FECOLORMATRIX = new nsHtml5ElementName(nsHtml5Atoms::fecolormatrix, nsHtml5Atoms::feColorMatrix, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MISSING_GLYPH = new nsHtml5ElementName(nsHtml5Atoms::missing_glyph, nsHtml5Atoms::missing_glyph, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_MMULTISCRIPTS = new nsHtml5ElementName(nsHtml5Atoms::mmultiscripts, nsHtml5Atoms::mmultiscripts, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_SCALARPRODUCT = new nsHtml5ElementName(nsHtml5Atoms::scalarproduct, nsHtml5Atoms::scalarproduct, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_VECTORPRODUCT = new nsHtml5ElementName(nsHtml5Atoms::vectorproduct, nsHtml5Atoms::vectorproduct, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ANNOTATION_XML = new nsHtml5ElementName(nsHtml5Atoms::annotation_xml, nsHtml5Atoms::annotation_xml, NS_HTML5TREE_BUILDER_ANNOTATION_XML | NS_HTML5ELEMENT_NAME_SCOPING_AS_MATHML);
+ ELT_DEFINITION_SRC = new nsHtml5ElementName(nsHtml5Atoms::definition_src, nsHtml5Atoms::definition_src, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FONT_FACE_NAME = new nsHtml5ElementName(nsHtml5Atoms::font_face_name, nsHtml5Atoms::font_face_name, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEGAUSSIANBLUR = new nsHtml5ElementName(nsHtml5Atoms::fegaussianblur, nsHtml5Atoms::feGaussianBlur, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEDISTANTLIGHT = new nsHtml5ElementName(nsHtml5Atoms::fedistantlight, nsHtml5Atoms::feDistantLight, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_LINEARGRADIENT = new nsHtml5ElementName(nsHtml5Atoms::lineargradient, nsHtml5Atoms::linearGradient, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_NATURALNUMBERS = new nsHtml5ElementName(nsHtml5Atoms::naturalnumbers, nsHtml5Atoms::naturalnumbers, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_RADIALGRADIENT = new nsHtml5ElementName(nsHtml5Atoms::radialgradient, nsHtml5Atoms::radialGradient, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_ANIMATETRANSFORM = new nsHtml5ElementName(nsHtml5Atoms::animatetransform, nsHtml5Atoms::animateTransform, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_CARTESIANPRODUCT = new nsHtml5ElementName(nsHtml5Atoms::cartesianproduct, nsHtml5Atoms::cartesianproduct, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FONT_FACE_FORMAT = new nsHtml5ElementName(nsHtml5Atoms::font_face_format, nsHtml5Atoms::font_face_format, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FECONVOLVEMATRIX = new nsHtml5ElementName(nsHtml5Atoms::feconvolvematrix, nsHtml5Atoms::feConvolveMatrix, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEDIFFUSELIGHTING = new nsHtml5ElementName(nsHtml5Atoms::fediffuselighting, nsHtml5Atoms::feDiffuseLighting, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FEDISPLACEMENTMAP = new nsHtml5ElementName(nsHtml5Atoms::fedisplacementmap, nsHtml5Atoms::feDisplacementMap, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FESPECULARLIGHTING = new nsHtml5ElementName(nsHtml5Atoms::fespecularlighting, nsHtml5Atoms::feSpecularLighting, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_DOMAINOFAPPLICATION = new nsHtml5ElementName(nsHtml5Atoms::domainofapplication, nsHtml5Atoms::domainofapplication, NS_HTML5TREE_BUILDER_OTHER);
+ ELT_FECOMPONENTTRANSFER = new nsHtml5ElementName(nsHtml5Atoms::fecomponenttransfer, nsHtml5Atoms::feComponentTransfer, NS_HTML5TREE_BUILDER_OTHER);
+ ELEMENT_NAMES = new nsHtml5ElementName*[397];
+ ELEMENT_NAMES[0] = ELT_A;
+ ELEMENT_NAMES[1] = ELT_B;
+ ELEMENT_NAMES[2] = ELT_G;
+ ELEMENT_NAMES[3] = ELT_I;
+ ELEMENT_NAMES[4] = ELT_P;
+ ELEMENT_NAMES[5] = ELT_Q;
+ ELEMENT_NAMES[6] = ELT_S;
+ ELEMENT_NAMES[7] = ELT_U;
+ ELEMENT_NAMES[8] = ELT_BR;
+ ELEMENT_NAMES[9] = ELT_CI;
+ ELEMENT_NAMES[10] = ELT_CN;
+ ELEMENT_NAMES[11] = ELT_DD;
+ ELEMENT_NAMES[12] = ELT_DL;
+ ELEMENT_NAMES[13] = ELT_DT;
+ ELEMENT_NAMES[14] = ELT_EM;
+ ELEMENT_NAMES[15] = ELT_EQ;
+ ELEMENT_NAMES[16] = ELT_FN;
+ ELEMENT_NAMES[17] = ELT_H1;
+ ELEMENT_NAMES[18] = ELT_H2;
+ ELEMENT_NAMES[19] = ELT_H3;
+ ELEMENT_NAMES[20] = ELT_H4;
+ ELEMENT_NAMES[21] = ELT_H5;
+ ELEMENT_NAMES[22] = ELT_H6;
+ ELEMENT_NAMES[23] = ELT_GT;
+ ELEMENT_NAMES[24] = ELT_HR;
+ ELEMENT_NAMES[25] = ELT_IN;
+ ELEMENT_NAMES[26] = ELT_LI;
+ ELEMENT_NAMES[27] = ELT_LN;
+ ELEMENT_NAMES[28] = ELT_LT;
+ ELEMENT_NAMES[29] = ELT_MI;
+ ELEMENT_NAMES[30] = ELT_MN;
+ ELEMENT_NAMES[31] = ELT_MO;
+ ELEMENT_NAMES[32] = ELT_MS;
+ ELEMENT_NAMES[33] = ELT_OL;
+ ELEMENT_NAMES[34] = ELT_OR;
+ ELEMENT_NAMES[35] = ELT_PI;
+ ELEMENT_NAMES[36] = ELT_RB;
+ ELEMENT_NAMES[37] = ELT_RP;
+ ELEMENT_NAMES[38] = ELT_RT;
+ ELEMENT_NAMES[39] = ELT_TD;
+ ELEMENT_NAMES[40] = ELT_TH;
+ ELEMENT_NAMES[41] = ELT_TR;
+ ELEMENT_NAMES[42] = ELT_TT;
+ ELEMENT_NAMES[43] = ELT_UL;
+ ELEMENT_NAMES[44] = ELT_AND;
+ ELEMENT_NAMES[45] = ELT_ARG;
+ ELEMENT_NAMES[46] = ELT_ABS;
+ ELEMENT_NAMES[47] = ELT_BIG;
+ ELEMENT_NAMES[48] = ELT_BDO;
+ ELEMENT_NAMES[49] = ELT_CSC;
+ ELEMENT_NAMES[50] = ELT_COL;
+ ELEMENT_NAMES[51] = ELT_COS;
+ ELEMENT_NAMES[52] = ELT_COT;
+ ELEMENT_NAMES[53] = ELT_DEL;
+ ELEMENT_NAMES[54] = ELT_DFN;
+ ELEMENT_NAMES[55] = ELT_DIR;
+ ELEMENT_NAMES[56] = ELT_DIV;
+ ELEMENT_NAMES[57] = ELT_EXP;
+ ELEMENT_NAMES[58] = ELT_GCD;
+ ELEMENT_NAMES[59] = ELT_GEQ;
+ ELEMENT_NAMES[60] = ELT_IMG;
+ ELEMENT_NAMES[61] = ELT_INS;
+ ELEMENT_NAMES[62] = ELT_INT;
+ ELEMENT_NAMES[63] = ELT_KBD;
+ ELEMENT_NAMES[64] = ELT_LOG;
+ ELEMENT_NAMES[65] = ELT_LCM;
+ ELEMENT_NAMES[66] = ELT_LEQ;
+ ELEMENT_NAMES[67] = ELT_MTD;
+ ELEMENT_NAMES[68] = ELT_MIN;
+ ELEMENT_NAMES[69] = ELT_MAP;
+ ELEMENT_NAMES[70] = ELT_MTR;
+ ELEMENT_NAMES[71] = ELT_MAX;
+ ELEMENT_NAMES[72] = ELT_NEQ;
+ ELEMENT_NAMES[73] = ELT_NOT;
+ ELEMENT_NAMES[74] = ELT_NAV;
+ ELEMENT_NAMES[75] = ELT_PRE;
+ ELEMENT_NAMES[76] = ELT_RTC;
+ ELEMENT_NAMES[77] = ELT_REM;
+ ELEMENT_NAMES[78] = ELT_SUB;
+ ELEMENT_NAMES[79] = ELT_SEC;
+ ELEMENT_NAMES[80] = ELT_SVG;
+ ELEMENT_NAMES[81] = ELT_SUM;
+ ELEMENT_NAMES[82] = ELT_SIN;
+ ELEMENT_NAMES[83] = ELT_SEP;
+ ELEMENT_NAMES[84] = ELT_SUP;
+ ELEMENT_NAMES[85] = ELT_SET;
+ ELEMENT_NAMES[86] = ELT_TAN;
+ ELEMENT_NAMES[87] = ELT_USE;
+ ELEMENT_NAMES[88] = ELT_VAR;
+ ELEMENT_NAMES[89] = ELT_WBR;
+ ELEMENT_NAMES[90] = ELT_XMP;
+ ELEMENT_NAMES[91] = ELT_XOR;
+ ELEMENT_NAMES[92] = ELT_AREA;
+ ELEMENT_NAMES[93] = ELT_ABBR;
+ ELEMENT_NAMES[94] = ELT_BASE;
+ ELEMENT_NAMES[95] = ELT_BVAR;
+ ELEMENT_NAMES[96] = ELT_BODY;
+ ELEMENT_NAMES[97] = ELT_CARD;
+ ELEMENT_NAMES[98] = ELT_CODE;
+ ELEMENT_NAMES[99] = ELT_CITE;
+ ELEMENT_NAMES[100] = ELT_CSCH;
+ ELEMENT_NAMES[101] = ELT_COSH;
+ ELEMENT_NAMES[102] = ELT_COTH;
+ ELEMENT_NAMES[103] = ELT_CURL;
+ ELEMENT_NAMES[104] = ELT_DESC;
+ ELEMENT_NAMES[105] = ELT_DIFF;
+ ELEMENT_NAMES[106] = ELT_DEFS;
+ ELEMENT_NAMES[107] = ELT_FORM;
+ ELEMENT_NAMES[108] = ELT_FONT;
+ ELEMENT_NAMES[109] = ELT_GRAD;
+ ELEMENT_NAMES[110] = ELT_HEAD;
+ ELEMENT_NAMES[111] = ELT_HTML;
+ ELEMENT_NAMES[112] = ELT_LINE;
+ ELEMENT_NAMES[113] = ELT_LINK;
+ ELEMENT_NAMES[114] = ELT_LIST;
+ ELEMENT_NAMES[115] = ELT_META;
+ ELEMENT_NAMES[116] = ELT_MSUB;
+ ELEMENT_NAMES[117] = ELT_MODE;
+ ELEMENT_NAMES[118] = ELT_MATH;
+ ELEMENT_NAMES[119] = ELT_MARK;
+ ELEMENT_NAMES[120] = ELT_MASK;
+ ELEMENT_NAMES[121] = ELT_MEAN;
+ ELEMENT_NAMES[122] = ELT_MAIN;
+ ELEMENT_NAMES[123] = ELT_MSUP;
+ ELEMENT_NAMES[124] = ELT_MENU;
+ ELEMENT_NAMES[125] = ELT_MROW;
+ ELEMENT_NAMES[126] = ELT_NONE;
+ ELEMENT_NAMES[127] = ELT_NOBR;
+ ELEMENT_NAMES[128] = ELT_NEST;
+ ELEMENT_NAMES[129] = ELT_PATH;
+ ELEMENT_NAMES[130] = ELT_PLUS;
+ ELEMENT_NAMES[131] = ELT_RULE;
+ ELEMENT_NAMES[132] = ELT_REAL;
+ ELEMENT_NAMES[133] = ELT_RELN;
+ ELEMENT_NAMES[134] = ELT_RECT;
+ ELEMENT_NAMES[135] = ELT_ROOT;
+ ELEMENT_NAMES[136] = ELT_RUBY;
+ ELEMENT_NAMES[137] = ELT_SECH;
+ ELEMENT_NAMES[138] = ELT_SINH;
+ ELEMENT_NAMES[139] = ELT_SPAN;
+ ELEMENT_NAMES[140] = ELT_SAMP;
+ ELEMENT_NAMES[141] = ELT_STOP;
+ ELEMENT_NAMES[142] = ELT_SDEV;
+ ELEMENT_NAMES[143] = ELT_TIME;
+ ELEMENT_NAMES[144] = ELT_TRUE;
+ ELEMENT_NAMES[145] = ELT_TREF;
+ ELEMENT_NAMES[146] = ELT_TANH;
+ ELEMENT_NAMES[147] = ELT_TEXT;
+ ELEMENT_NAMES[148] = ELT_VIEW;
+ ELEMENT_NAMES[149] = ELT_ASIDE;
+ ELEMENT_NAMES[150] = ELT_AUDIO;
+ ELEMENT_NAMES[151] = ELT_APPLY;
+ ELEMENT_NAMES[152] = ELT_EMBED;
+ ELEMENT_NAMES[153] = ELT_FRAME;
+ ELEMENT_NAMES[154] = ELT_FALSE;
+ ELEMENT_NAMES[155] = ELT_FLOOR;
+ ELEMENT_NAMES[156] = ELT_GLYPH;
+ ELEMENT_NAMES[157] = ELT_HKERN;
+ ELEMENT_NAMES[158] = ELT_IMAGE;
+ ELEMENT_NAMES[159] = ELT_IDENT;
+ ELEMENT_NAMES[160] = ELT_INPUT;
+ ELEMENT_NAMES[161] = ELT_LABEL;
+ ELEMENT_NAMES[162] = ELT_LIMIT;
+ ELEMENT_NAMES[163] = ELT_MFRAC;
+ ELEMENT_NAMES[164] = ELT_MPATH;
+ ELEMENT_NAMES[165] = ELT_METER;
+ ELEMENT_NAMES[166] = ELT_MOVER;
+ ELEMENT_NAMES[167] = ELT_MINUS;
+ ELEMENT_NAMES[168] = ELT_MROOT;
+ ELEMENT_NAMES[169] = ELT_MSQRT;
+ ELEMENT_NAMES[170] = ELT_MTEXT;
+ ELEMENT_NAMES[171] = ELT_NOTIN;
+ ELEMENT_NAMES[172] = ELT_PIECE;
+ ELEMENT_NAMES[173] = ELT_PARAM;
+ ELEMENT_NAMES[174] = ELT_POWER;
+ ELEMENT_NAMES[175] = ELT_REALS;
+ ELEMENT_NAMES[176] = ELT_STYLE;
+ ELEMENT_NAMES[177] = ELT_SMALL;
+ ELEMENT_NAMES[178] = ELT_THEAD;
+ ELEMENT_NAMES[179] = ELT_TABLE;
+ ELEMENT_NAMES[180] = ELT_TITLE;
+ ELEMENT_NAMES[181] = ELT_TRACK;
+ ELEMENT_NAMES[182] = ELT_TSPAN;
+ ELEMENT_NAMES[183] = ELT_TIMES;
+ ELEMENT_NAMES[184] = ELT_TFOOT;
+ ELEMENT_NAMES[185] = ELT_TBODY;
+ ELEMENT_NAMES[186] = ELT_UNION;
+ ELEMENT_NAMES[187] = ELT_VKERN;
+ ELEMENT_NAMES[188] = ELT_VIDEO;
+ ELEMENT_NAMES[189] = ELT_ARCSEC;
+ ELEMENT_NAMES[190] = ELT_ARCCSC;
+ ELEMENT_NAMES[191] = ELT_ARCTAN;
+ ELEMENT_NAMES[192] = ELT_ARCSIN;
+ ELEMENT_NAMES[193] = ELT_ARCCOS;
+ ELEMENT_NAMES[194] = ELT_APPLET;
+ ELEMENT_NAMES[195] = ELT_ARCCOT;
+ ELEMENT_NAMES[196] = ELT_APPROX;
+ ELEMENT_NAMES[197] = ELT_BUTTON;
+ ELEMENT_NAMES[198] = ELT_CIRCLE;
+ ELEMENT_NAMES[199] = ELT_CENTER;
+ ELEMENT_NAMES[200] = ELT_CURSOR;
+ ELEMENT_NAMES[201] = ELT_CANVAS;
+ ELEMENT_NAMES[202] = ELT_DIVIDE;
+ ELEMENT_NAMES[203] = ELT_DEGREE;
+ ELEMENT_NAMES[204] = ELT_DOMAIN;
+ ELEMENT_NAMES[205] = ELT_EXISTS;
+ ELEMENT_NAMES[206] = ELT_FETILE;
+ ELEMENT_NAMES[207] = ELT_FIGURE;
+ ELEMENT_NAMES[208] = ELT_FORALL;
+ ELEMENT_NAMES[209] = ELT_FILTER;
+ ELEMENT_NAMES[210] = ELT_FOOTER;
+ ELEMENT_NAMES[211] = ELT_HGROUP;
+ ELEMENT_NAMES[212] = ELT_HEADER;
+ ELEMENT_NAMES[213] = ELT_IFRAME;
+ ELEMENT_NAMES[214] = ELT_KEYGEN;
+ ELEMENT_NAMES[215] = ELT_LAMBDA;
+ ELEMENT_NAMES[216] = ELT_LEGEND;
+ ELEMENT_NAMES[217] = ELT_MSPACE;
+ ELEMENT_NAMES[218] = ELT_MTABLE;
+ ELEMENT_NAMES[219] = ELT_MSTYLE;
+ ELEMENT_NAMES[220] = ELT_MGLYPH;
+ ELEMENT_NAMES[221] = ELT_MEDIAN;
+ ELEMENT_NAMES[222] = ELT_MUNDER;
+ ELEMENT_NAMES[223] = ELT_MARKER;
+ ELEMENT_NAMES[224] = ELT_MERROR;
+ ELEMENT_NAMES[225] = ELT_MOMENT;
+ ELEMENT_NAMES[226] = ELT_MATRIX;
+ ELEMENT_NAMES[227] = ELT_OPTION;
+ ELEMENT_NAMES[228] = ELT_OBJECT;
+ ELEMENT_NAMES[229] = ELT_OUTPUT;
+ ELEMENT_NAMES[230] = ELT_PRIMES;
+ ELEMENT_NAMES[231] = ELT_SOURCE;
+ ELEMENT_NAMES[232] = ELT_STRIKE;
+ ELEMENT_NAMES[233] = ELT_STRONG;
+ ELEMENT_NAMES[234] = ELT_SWITCH;
+ ELEMENT_NAMES[235] = ELT_SYMBOL;
+ ELEMENT_NAMES[236] = ELT_SELECT;
+ ELEMENT_NAMES[237] = ELT_SUBSET;
+ ELEMENT_NAMES[238] = ELT_SCRIPT;
+ ELEMENT_NAMES[239] = ELT_TBREAK;
+ ELEMENT_NAMES[240] = ELT_VECTOR;
+ ELEMENT_NAMES[241] = ELT_ARTICLE;
+ ELEMENT_NAMES[242] = ELT_ANIMATE;
+ ELEMENT_NAMES[243] = ELT_ARCSECH;
+ ELEMENT_NAMES[244] = ELT_ARCCSCH;
+ ELEMENT_NAMES[245] = ELT_ARCTANH;
+ ELEMENT_NAMES[246] = ELT_ARCSINH;
+ ELEMENT_NAMES[247] = ELT_ARCCOSH;
+ ELEMENT_NAMES[248] = ELT_ARCCOTH;
+ ELEMENT_NAMES[249] = ELT_ACRONYM;
+ ELEMENT_NAMES[250] = ELT_ADDRESS;
+ ELEMENT_NAMES[251] = ELT_BGSOUND;
+ ELEMENT_NAMES[252] = ELT_COMPOSE;
+ ELEMENT_NAMES[253] = ELT_CEILING;
+ ELEMENT_NAMES[254] = ELT_CSYMBOL;
+ ELEMENT_NAMES[255] = ELT_CAPTION;
+ ELEMENT_NAMES[256] = ELT_DISCARD;
+ ELEMENT_NAMES[257] = ELT_DECLARE;
+ ELEMENT_NAMES[258] = ELT_DETAILS;
+ ELEMENT_NAMES[259] = ELT_ELLIPSE;
+ ELEMENT_NAMES[260] = ELT_FEFUNCA;
+ ELEMENT_NAMES[261] = ELT_FEFUNCB;
+ ELEMENT_NAMES[262] = ELT_FEBLEND;
+ ELEMENT_NAMES[263] = ELT_FEFLOOD;
+ ELEMENT_NAMES[264] = ELT_FEIMAGE;
+ ELEMENT_NAMES[265] = ELT_FEMERGE;
+ ELEMENT_NAMES[266] = ELT_FEFUNCG;
+ ELEMENT_NAMES[267] = ELT_FEFUNCR;
+ ELEMENT_NAMES[268] = ELT_HANDLER;
+ ELEMENT_NAMES[269] = ELT_INVERSE;
+ ELEMENT_NAMES[270] = ELT_IMPLIES;
+ ELEMENT_NAMES[271] = ELT_ISINDEX;
+ ELEMENT_NAMES[272] = ELT_LOGBASE;
+ ELEMENT_NAMES[273] = ELT_LISTING;
+ ELEMENT_NAMES[274] = ELT_MFENCED;
+ ELEMENT_NAMES[275] = ELT_MPADDED;
+ ELEMENT_NAMES[276] = ELT_MARQUEE;
+ ELEMENT_NAMES[277] = ELT_MACTION;
+ ELEMENT_NAMES[278] = ELT_MSUBSUP;
+ ELEMENT_NAMES[279] = ELT_NOEMBED;
+ ELEMENT_NAMES[280] = ELT_POLYGON;
+ ELEMENT_NAMES[281] = ELT_PATTERN;
+ ELEMENT_NAMES[282] = ELT_PICTURE;
+ ELEMENT_NAMES[283] = ELT_PRODUCT;
+ ELEMENT_NAMES[284] = ELT_SETDIFF;
+ ELEMENT_NAMES[285] = ELT_SECTION;
+ ELEMENT_NAMES[286] = ELT_SUMMARY;
+ ELEMENT_NAMES[287] = ELT_TENDSTO;
+ ELEMENT_NAMES[288] = ELT_UPLIMIT;
+ ELEMENT_NAMES[289] = ELT_ALTGLYPH;
+ ELEMENT_NAMES[290] = ELT_BASEFONT;
+ ELEMENT_NAMES[291] = ELT_CLIPPATH;
+ ELEMENT_NAMES[292] = ELT_CODOMAIN;
+ ELEMENT_NAMES[293] = ELT_COLGROUP;
+ ELEMENT_NAMES[294] = ELT_EMPTYSET;
+ ELEMENT_NAMES[295] = ELT_FACTOROF;
+ ELEMENT_NAMES[296] = ELT_FIELDSET;
+ ELEMENT_NAMES[297] = ELT_FRAMESET;
+ ELEMENT_NAMES[298] = ELT_FEOFFSET;
+ ELEMENT_NAMES[299] = ELT_GLYPHREF;
+ ELEMENT_NAMES[300] = ELT_INTERVAL;
+ ELEMENT_NAMES[301] = ELT_INTEGERS;
+ ELEMENT_NAMES[302] = ELT_INFINITY;
+ ELEMENT_NAMES[303] = ELT_LISTENER;
+ ELEMENT_NAMES[304] = ELT_LOWLIMIT;
+ ELEMENT_NAMES[305] = ELT_METADATA;
+ ELEMENT_NAMES[306] = ELT_MENCLOSE;
+ ELEMENT_NAMES[307] = ELT_MENUITEM;
+ ELEMENT_NAMES[308] = ELT_MPHANTOM;
+ ELEMENT_NAMES[309] = ELT_NOFRAMES;
+ ELEMENT_NAMES[310] = ELT_NOSCRIPT;
+ ELEMENT_NAMES[311] = ELT_OPTGROUP;
+ ELEMENT_NAMES[312] = ELT_POLYLINE;
+ ELEMENT_NAMES[313] = ELT_PREFETCH;
+ ELEMENT_NAMES[314] = ELT_PROGRESS;
+ ELEMENT_NAMES[315] = ELT_PRSUBSET;
+ ELEMENT_NAMES[316] = ELT_QUOTIENT;
+ ELEMENT_NAMES[317] = ELT_SELECTOR;
+ ELEMENT_NAMES[318] = ELT_TEXTAREA;
+ ELEMENT_NAMES[319] = ELT_TEMPLATE;
+ ELEMENT_NAMES[320] = ELT_TEXTPATH;
+ ELEMENT_NAMES[321] = ELT_VARIANCE;
+ ELEMENT_NAMES[322] = ELT_ANIMATION;
+ ELEMENT_NAMES[323] = ELT_CONJUGATE;
+ ELEMENT_NAMES[324] = ELT_CONDITION;
+ ELEMENT_NAMES[325] = ELT_COMPLEXES;
+ ELEMENT_NAMES[326] = ELT_FONT_FACE;
+ ELEMENT_NAMES[327] = ELT_FACTORIAL;
+ ELEMENT_NAMES[328] = ELT_INTERSECT;
+ ELEMENT_NAMES[329] = ELT_IMAGINARY;
+ ELEMENT_NAMES[330] = ELT_LAPLACIAN;
+ ELEMENT_NAMES[331] = ELT_MATRIXROW;
+ ELEMENT_NAMES[332] = ELT_NOTSUBSET;
+ ELEMENT_NAMES[333] = ELT_OTHERWISE;
+ ELEMENT_NAMES[334] = ELT_PIECEWISE;
+ ELEMENT_NAMES[335] = ELT_PLAINTEXT;
+ ELEMENT_NAMES[336] = ELT_RATIONALS;
+ ELEMENT_NAMES[337] = ELT_SEMANTICS;
+ ELEMENT_NAMES[338] = ELT_TRANSPOSE;
+ ELEMENT_NAMES[339] = ELT_ANNOTATION;
+ ELEMENT_NAMES[340] = ELT_BLOCKQUOTE;
+ ELEMENT_NAMES[341] = ELT_DIVERGENCE;
+ ELEMENT_NAMES[342] = ELT_EULERGAMMA;
+ ELEMENT_NAMES[343] = ELT_EQUIVALENT;
+ ELEMENT_NAMES[344] = ELT_FIGCAPTION;
+ ELEMENT_NAMES[345] = ELT_IMAGINARYI;
+ ELEMENT_NAMES[346] = ELT_MALIGNMARK;
+ ELEMENT_NAMES[347] = ELT_MUNDEROVER;
+ ELEMENT_NAMES[348] = ELT_MLABELEDTR;
+ ELEMENT_NAMES[349] = ELT_NOTANUMBER;
+ ELEMENT_NAMES[350] = ELT_SOLIDCOLOR;
+ ELEMENT_NAMES[351] = ELT_ALTGLYPHDEF;
+ ELEMENT_NAMES[352] = ELT_DETERMINANT;
+ ELEMENT_NAMES[353] = ELT_FEMERGENODE;
+ ELEMENT_NAMES[354] = ELT_FECOMPOSITE;
+ ELEMENT_NAMES[355] = ELT_FESPOTLIGHT;
+ ELEMENT_NAMES[356] = ELT_MALIGNGROUP;
+ ELEMENT_NAMES[357] = ELT_MPRESCRIPTS;
+ ELEMENT_NAMES[358] = ELT_MOMENTABOUT;
+ ELEMENT_NAMES[359] = ELT_NOTPRSUBSET;
+ ELEMENT_NAMES[360] = ELT_PARTIALDIFF;
+ ELEMENT_NAMES[361] = ELT_ALTGLYPHITEM;
+ ELEMENT_NAMES[362] = ELT_ANIMATECOLOR;
+ ELEMENT_NAMES[363] = ELT_DATATEMPLATE;
+ ELEMENT_NAMES[364] = ELT_EXPONENTIALE;
+ ELEMENT_NAMES[365] = ELT_FETURBULENCE;
+ ELEMENT_NAMES[366] = ELT_FEPOINTLIGHT;
+ ELEMENT_NAMES[367] = ELT_FEDROPSHADOW;
+ ELEMENT_NAMES[368] = ELT_FEMORPHOLOGY;
+ ELEMENT_NAMES[369] = ELT_OUTERPRODUCT;
+ ELEMENT_NAMES[370] = ELT_ANIMATEMOTION;
+ ELEMENT_NAMES[371] = ELT_COLOR_PROFILE;
+ ELEMENT_NAMES[372] = ELT_FONT_FACE_SRC;
+ ELEMENT_NAMES[373] = ELT_FONT_FACE_URI;
+ ELEMENT_NAMES[374] = ELT_FOREIGNOBJECT;
+ ELEMENT_NAMES[375] = ELT_FECOLORMATRIX;
+ ELEMENT_NAMES[376] = ELT_MISSING_GLYPH;
+ ELEMENT_NAMES[377] = ELT_MMULTISCRIPTS;
+ ELEMENT_NAMES[378] = ELT_SCALARPRODUCT;
+ ELEMENT_NAMES[379] = ELT_VECTORPRODUCT;
+ ELEMENT_NAMES[380] = ELT_ANNOTATION_XML;
+ ELEMENT_NAMES[381] = ELT_DEFINITION_SRC;
+ ELEMENT_NAMES[382] = ELT_FONT_FACE_NAME;
+ ELEMENT_NAMES[383] = ELT_FEGAUSSIANBLUR;
+ ELEMENT_NAMES[384] = ELT_FEDISTANTLIGHT;
+ ELEMENT_NAMES[385] = ELT_LINEARGRADIENT;
+ ELEMENT_NAMES[386] = ELT_NATURALNUMBERS;
+ ELEMENT_NAMES[387] = ELT_RADIALGRADIENT;
+ ELEMENT_NAMES[388] = ELT_ANIMATETRANSFORM;
+ ELEMENT_NAMES[389] = ELT_CARTESIANPRODUCT;
+ ELEMENT_NAMES[390] = ELT_FONT_FACE_FORMAT;
+ ELEMENT_NAMES[391] = ELT_FECONVOLVEMATRIX;
+ ELEMENT_NAMES[392] = ELT_FEDIFFUSELIGHTING;
+ ELEMENT_NAMES[393] = ELT_FEDISPLACEMENTMAP;
+ ELEMENT_NAMES[394] = ELT_FESPECULARLIGHTING;
+ ELEMENT_NAMES[395] = ELT_DOMAINOFAPPLICATION;
+ ELEMENT_NAMES[396] = ELT_FECOMPONENTTRANSFER;
+}
+
+void
+nsHtml5ElementName::releaseStatics()
+{
+ delete ELT_NULL_ELEMENT_NAME;
+ delete ELT_A;
+ delete ELT_B;
+ delete ELT_G;
+ delete ELT_I;
+ delete ELT_P;
+ delete ELT_Q;
+ delete ELT_S;
+ delete ELT_U;
+ delete ELT_BR;
+ delete ELT_CI;
+ delete ELT_CN;
+ delete ELT_DD;
+ delete ELT_DL;
+ delete ELT_DT;
+ delete ELT_EM;
+ delete ELT_EQ;
+ delete ELT_FN;
+ delete ELT_H1;
+ delete ELT_H2;
+ delete ELT_H3;
+ delete ELT_H4;
+ delete ELT_H5;
+ delete ELT_H6;
+ delete ELT_GT;
+ delete ELT_HR;
+ delete ELT_IN;
+ delete ELT_LI;
+ delete ELT_LN;
+ delete ELT_LT;
+ delete ELT_MI;
+ delete ELT_MN;
+ delete ELT_MO;
+ delete ELT_MS;
+ delete ELT_OL;
+ delete ELT_OR;
+ delete ELT_PI;
+ delete ELT_RB;
+ delete ELT_RP;
+ delete ELT_RT;
+ delete ELT_TD;
+ delete ELT_TH;
+ delete ELT_TR;
+ delete ELT_TT;
+ delete ELT_UL;
+ delete ELT_AND;
+ delete ELT_ARG;
+ delete ELT_ABS;
+ delete ELT_BIG;
+ delete ELT_BDO;
+ delete ELT_CSC;
+ delete ELT_COL;
+ delete ELT_COS;
+ delete ELT_COT;
+ delete ELT_DEL;
+ delete ELT_DFN;
+ delete ELT_DIR;
+ delete ELT_DIV;
+ delete ELT_EXP;
+ delete ELT_GCD;
+ delete ELT_GEQ;
+ delete ELT_IMG;
+ delete ELT_INS;
+ delete ELT_INT;
+ delete ELT_KBD;
+ delete ELT_LOG;
+ delete ELT_LCM;
+ delete ELT_LEQ;
+ delete ELT_MTD;
+ delete ELT_MIN;
+ delete ELT_MAP;
+ delete ELT_MTR;
+ delete ELT_MAX;
+ delete ELT_NEQ;
+ delete ELT_NOT;
+ delete ELT_NAV;
+ delete ELT_PRE;
+ delete ELT_RTC;
+ delete ELT_REM;
+ delete ELT_SUB;
+ delete ELT_SEC;
+ delete ELT_SVG;
+ delete ELT_SUM;
+ delete ELT_SIN;
+ delete ELT_SEP;
+ delete ELT_SUP;
+ delete ELT_SET;
+ delete ELT_TAN;
+ delete ELT_USE;
+ delete ELT_VAR;
+ delete ELT_WBR;
+ delete ELT_XMP;
+ delete ELT_XOR;
+ delete ELT_AREA;
+ delete ELT_ABBR;
+ delete ELT_BASE;
+ delete ELT_BVAR;
+ delete ELT_BODY;
+ delete ELT_CARD;
+ delete ELT_CODE;
+ delete ELT_CITE;
+ delete ELT_CSCH;
+ delete ELT_COSH;
+ delete ELT_COTH;
+ delete ELT_CURL;
+ delete ELT_DESC;
+ delete ELT_DIFF;
+ delete ELT_DEFS;
+ delete ELT_FORM;
+ delete ELT_FONT;
+ delete ELT_GRAD;
+ delete ELT_HEAD;
+ delete ELT_HTML;
+ delete ELT_LINE;
+ delete ELT_LINK;
+ delete ELT_LIST;
+ delete ELT_META;
+ delete ELT_MSUB;
+ delete ELT_MODE;
+ delete ELT_MATH;
+ delete ELT_MARK;
+ delete ELT_MASK;
+ delete ELT_MEAN;
+ delete ELT_MAIN;
+ delete ELT_MSUP;
+ delete ELT_MENU;
+ delete ELT_MROW;
+ delete ELT_NONE;
+ delete ELT_NOBR;
+ delete ELT_NEST;
+ delete ELT_PATH;
+ delete ELT_PLUS;
+ delete ELT_RULE;
+ delete ELT_REAL;
+ delete ELT_RELN;
+ delete ELT_RECT;
+ delete ELT_ROOT;
+ delete ELT_RUBY;
+ delete ELT_SECH;
+ delete ELT_SINH;
+ delete ELT_SPAN;
+ delete ELT_SAMP;
+ delete ELT_STOP;
+ delete ELT_SDEV;
+ delete ELT_TIME;
+ delete ELT_TRUE;
+ delete ELT_TREF;
+ delete ELT_TANH;
+ delete ELT_TEXT;
+ delete ELT_VIEW;
+ delete ELT_ASIDE;
+ delete ELT_AUDIO;
+ delete ELT_APPLY;
+ delete ELT_EMBED;
+ delete ELT_FRAME;
+ delete ELT_FALSE;
+ delete ELT_FLOOR;
+ delete ELT_GLYPH;
+ delete ELT_HKERN;
+ delete ELT_IMAGE;
+ delete ELT_IDENT;
+ delete ELT_INPUT;
+ delete ELT_LABEL;
+ delete ELT_LIMIT;
+ delete ELT_MFRAC;
+ delete ELT_MPATH;
+ delete ELT_METER;
+ delete ELT_MOVER;
+ delete ELT_MINUS;
+ delete ELT_MROOT;
+ delete ELT_MSQRT;
+ delete ELT_MTEXT;
+ delete ELT_NOTIN;
+ delete ELT_PIECE;
+ delete ELT_PARAM;
+ delete ELT_POWER;
+ delete ELT_REALS;
+ delete ELT_STYLE;
+ delete ELT_SMALL;
+ delete ELT_THEAD;
+ delete ELT_TABLE;
+ delete ELT_TITLE;
+ delete ELT_TRACK;
+ delete ELT_TSPAN;
+ delete ELT_TIMES;
+ delete ELT_TFOOT;
+ delete ELT_TBODY;
+ delete ELT_UNION;
+ delete ELT_VKERN;
+ delete ELT_VIDEO;
+ delete ELT_ARCSEC;
+ delete ELT_ARCCSC;
+ delete ELT_ARCTAN;
+ delete ELT_ARCSIN;
+ delete ELT_ARCCOS;
+ delete ELT_APPLET;
+ delete ELT_ARCCOT;
+ delete ELT_APPROX;
+ delete ELT_BUTTON;
+ delete ELT_CIRCLE;
+ delete ELT_CENTER;
+ delete ELT_CURSOR;
+ delete ELT_CANVAS;
+ delete ELT_DIVIDE;
+ delete ELT_DEGREE;
+ delete ELT_DOMAIN;
+ delete ELT_EXISTS;
+ delete ELT_FETILE;
+ delete ELT_FIGURE;
+ delete ELT_FORALL;
+ delete ELT_FILTER;
+ delete ELT_FOOTER;
+ delete ELT_HGROUP;
+ delete ELT_HEADER;
+ delete ELT_IFRAME;
+ delete ELT_KEYGEN;
+ delete ELT_LAMBDA;
+ delete ELT_LEGEND;
+ delete ELT_MSPACE;
+ delete ELT_MTABLE;
+ delete ELT_MSTYLE;
+ delete ELT_MGLYPH;
+ delete ELT_MEDIAN;
+ delete ELT_MUNDER;
+ delete ELT_MARKER;
+ delete ELT_MERROR;
+ delete ELT_MOMENT;
+ delete ELT_MATRIX;
+ delete ELT_OPTION;
+ delete ELT_OBJECT;
+ delete ELT_OUTPUT;
+ delete ELT_PRIMES;
+ delete ELT_SOURCE;
+ delete ELT_STRIKE;
+ delete ELT_STRONG;
+ delete ELT_SWITCH;
+ delete ELT_SYMBOL;
+ delete ELT_SELECT;
+ delete ELT_SUBSET;
+ delete ELT_SCRIPT;
+ delete ELT_TBREAK;
+ delete ELT_VECTOR;
+ delete ELT_ARTICLE;
+ delete ELT_ANIMATE;
+ delete ELT_ARCSECH;
+ delete ELT_ARCCSCH;
+ delete ELT_ARCTANH;
+ delete ELT_ARCSINH;
+ delete ELT_ARCCOSH;
+ delete ELT_ARCCOTH;
+ delete ELT_ACRONYM;
+ delete ELT_ADDRESS;
+ delete ELT_BGSOUND;
+ delete ELT_COMPOSE;
+ delete ELT_CEILING;
+ delete ELT_CSYMBOL;
+ delete ELT_CAPTION;
+ delete ELT_DISCARD;
+ delete ELT_DECLARE;
+ delete ELT_DETAILS;
+ delete ELT_ELLIPSE;
+ delete ELT_FEFUNCA;
+ delete ELT_FEFUNCB;
+ delete ELT_FEBLEND;
+ delete ELT_FEFLOOD;
+ delete ELT_FEIMAGE;
+ delete ELT_FEMERGE;
+ delete ELT_FEFUNCG;
+ delete ELT_FEFUNCR;
+ delete ELT_HANDLER;
+ delete ELT_INVERSE;
+ delete ELT_IMPLIES;
+ delete ELT_ISINDEX;
+ delete ELT_LOGBASE;
+ delete ELT_LISTING;
+ delete ELT_MFENCED;
+ delete ELT_MPADDED;
+ delete ELT_MARQUEE;
+ delete ELT_MACTION;
+ delete ELT_MSUBSUP;
+ delete ELT_NOEMBED;
+ delete ELT_POLYGON;
+ delete ELT_PATTERN;
+ delete ELT_PICTURE;
+ delete ELT_PRODUCT;
+ delete ELT_SETDIFF;
+ delete ELT_SECTION;
+ delete ELT_SUMMARY;
+ delete ELT_TENDSTO;
+ delete ELT_UPLIMIT;
+ delete ELT_ALTGLYPH;
+ delete ELT_BASEFONT;
+ delete ELT_CLIPPATH;
+ delete ELT_CODOMAIN;
+ delete ELT_COLGROUP;
+ delete ELT_EMPTYSET;
+ delete ELT_FACTOROF;
+ delete ELT_FIELDSET;
+ delete ELT_FRAMESET;
+ delete ELT_FEOFFSET;
+ delete ELT_GLYPHREF;
+ delete ELT_INTERVAL;
+ delete ELT_INTEGERS;
+ delete ELT_INFINITY;
+ delete ELT_LISTENER;
+ delete ELT_LOWLIMIT;
+ delete ELT_METADATA;
+ delete ELT_MENCLOSE;
+ delete ELT_MENUITEM;
+ delete ELT_MPHANTOM;
+ delete ELT_NOFRAMES;
+ delete ELT_NOSCRIPT;
+ delete ELT_OPTGROUP;
+ delete ELT_POLYLINE;
+ delete ELT_PREFETCH;
+ delete ELT_PROGRESS;
+ delete ELT_PRSUBSET;
+ delete ELT_QUOTIENT;
+ delete ELT_SELECTOR;
+ delete ELT_TEXTAREA;
+ delete ELT_TEMPLATE;
+ delete ELT_TEXTPATH;
+ delete ELT_VARIANCE;
+ delete ELT_ANIMATION;
+ delete ELT_CONJUGATE;
+ delete ELT_CONDITION;
+ delete ELT_COMPLEXES;
+ delete ELT_FONT_FACE;
+ delete ELT_FACTORIAL;
+ delete ELT_INTERSECT;
+ delete ELT_IMAGINARY;
+ delete ELT_LAPLACIAN;
+ delete ELT_MATRIXROW;
+ delete ELT_NOTSUBSET;
+ delete ELT_OTHERWISE;
+ delete ELT_PIECEWISE;
+ delete ELT_PLAINTEXT;
+ delete ELT_RATIONALS;
+ delete ELT_SEMANTICS;
+ delete ELT_TRANSPOSE;
+ delete ELT_ANNOTATION;
+ delete ELT_BLOCKQUOTE;
+ delete ELT_DIVERGENCE;
+ delete ELT_EULERGAMMA;
+ delete ELT_EQUIVALENT;
+ delete ELT_FIGCAPTION;
+ delete ELT_IMAGINARYI;
+ delete ELT_MALIGNMARK;
+ delete ELT_MUNDEROVER;
+ delete ELT_MLABELEDTR;
+ delete ELT_NOTANUMBER;
+ delete ELT_SOLIDCOLOR;
+ delete ELT_ALTGLYPHDEF;
+ delete ELT_DETERMINANT;
+ delete ELT_FEMERGENODE;
+ delete ELT_FECOMPOSITE;
+ delete ELT_FESPOTLIGHT;
+ delete ELT_MALIGNGROUP;
+ delete ELT_MPRESCRIPTS;
+ delete ELT_MOMENTABOUT;
+ delete ELT_NOTPRSUBSET;
+ delete ELT_PARTIALDIFF;
+ delete ELT_ALTGLYPHITEM;
+ delete ELT_ANIMATECOLOR;
+ delete ELT_DATATEMPLATE;
+ delete ELT_EXPONENTIALE;
+ delete ELT_FETURBULENCE;
+ delete ELT_FEPOINTLIGHT;
+ delete ELT_FEDROPSHADOW;
+ delete ELT_FEMORPHOLOGY;
+ delete ELT_OUTERPRODUCT;
+ delete ELT_ANIMATEMOTION;
+ delete ELT_COLOR_PROFILE;
+ delete ELT_FONT_FACE_SRC;
+ delete ELT_FONT_FACE_URI;
+ delete ELT_FOREIGNOBJECT;
+ delete ELT_FECOLORMATRIX;
+ delete ELT_MISSING_GLYPH;
+ delete ELT_MMULTISCRIPTS;
+ delete ELT_SCALARPRODUCT;
+ delete ELT_VECTORPRODUCT;
+ delete ELT_ANNOTATION_XML;
+ delete ELT_DEFINITION_SRC;
+ delete ELT_FONT_FACE_NAME;
+ delete ELT_FEGAUSSIANBLUR;
+ delete ELT_FEDISTANTLIGHT;
+ delete ELT_LINEARGRADIENT;
+ delete ELT_NATURALNUMBERS;
+ delete ELT_RADIALGRADIENT;
+ delete ELT_ANIMATETRANSFORM;
+ delete ELT_CARTESIANPRODUCT;
+ delete ELT_FONT_FACE_FORMAT;
+ delete ELT_FECONVOLVEMATRIX;
+ delete ELT_FEDIFFUSELIGHTING;
+ delete ELT_FEDISPLACEMENTMAP;
+ delete ELT_FESPECULARLIGHTING;
+ delete ELT_DOMAINOFAPPLICATION;
+ delete ELT_FECOMPONENTTRANSFER;
+ delete[] ELEMENT_NAMES;
+}
+
+
diff --git a/parser/html/nsHtml5ElementName.h b/parser/html/nsHtml5ElementName.h
new file mode 100644
index 000000000..b4df323a6
--- /dev/null
+++ b/parser/html/nsHtml5ElementName.h
@@ -0,0 +1,499 @@
+/*
+ * Copyright (c) 2008-2014 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit ElementName.java instead and regenerate.
+ */
+
+#ifndef nsHtml5ElementName_h
+#define nsHtml5ElementName_h
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5ByteReadable.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
+
+class nsHtml5StreamParser;
+
+class nsHtml5Tokenizer;
+class nsHtml5TreeBuilder;
+class nsHtml5MetaScanner;
+class nsHtml5AttributeName;
+class nsHtml5HtmlAttributes;
+class nsHtml5UTF16Buffer;
+class nsHtml5StateSnapshot;
+class nsHtml5Portability;
+
+
+class nsHtml5ElementName
+{
+ public:
+ static nsHtml5ElementName* ELT_NULL_ELEMENT_NAME;
+ nsIAtom* name;
+ nsIAtom* camelCaseName;
+ int32_t flags;
+ inline int32_t getFlags()
+ {
+ return flags;
+ }
+
+ int32_t getGroup();
+ bool isCustom();
+ static nsHtml5ElementName* elementNameByBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5AtomTable* interner);
+ private:
+ static int32_t bufToHash(char16_t* buf, int32_t len);
+ nsHtml5ElementName(nsIAtom* name, nsIAtom* camelCaseName, int32_t flags);
+ protected:
+ explicit nsHtml5ElementName(nsIAtom* name);
+ public:
+ virtual void release();
+ virtual ~nsHtml5ElementName();
+ virtual nsHtml5ElementName* cloneElementName(nsHtml5AtomTable* interner);
+ static nsHtml5ElementName* ELT_A;
+ static nsHtml5ElementName* ELT_B;
+ static nsHtml5ElementName* ELT_G;
+ static nsHtml5ElementName* ELT_I;
+ static nsHtml5ElementName* ELT_P;
+ static nsHtml5ElementName* ELT_Q;
+ static nsHtml5ElementName* ELT_S;
+ static nsHtml5ElementName* ELT_U;
+ static nsHtml5ElementName* ELT_BR;
+ static nsHtml5ElementName* ELT_CI;
+ static nsHtml5ElementName* ELT_CN;
+ static nsHtml5ElementName* ELT_DD;
+ static nsHtml5ElementName* ELT_DL;
+ static nsHtml5ElementName* ELT_DT;
+ static nsHtml5ElementName* ELT_EM;
+ static nsHtml5ElementName* ELT_EQ;
+ static nsHtml5ElementName* ELT_FN;
+ static nsHtml5ElementName* ELT_H1;
+ static nsHtml5ElementName* ELT_H2;
+ static nsHtml5ElementName* ELT_H3;
+ static nsHtml5ElementName* ELT_H4;
+ static nsHtml5ElementName* ELT_H5;
+ static nsHtml5ElementName* ELT_H6;
+ static nsHtml5ElementName* ELT_GT;
+ static nsHtml5ElementName* ELT_HR;
+ static nsHtml5ElementName* ELT_IN;
+ static nsHtml5ElementName* ELT_LI;
+ static nsHtml5ElementName* ELT_LN;
+ static nsHtml5ElementName* ELT_LT;
+ static nsHtml5ElementName* ELT_MI;
+ static nsHtml5ElementName* ELT_MN;
+ static nsHtml5ElementName* ELT_MO;
+ static nsHtml5ElementName* ELT_MS;
+ static nsHtml5ElementName* ELT_OL;
+ static nsHtml5ElementName* ELT_OR;
+ static nsHtml5ElementName* ELT_PI;
+ static nsHtml5ElementName* ELT_RB;
+ static nsHtml5ElementName* ELT_RP;
+ static nsHtml5ElementName* ELT_RT;
+ static nsHtml5ElementName* ELT_TD;
+ static nsHtml5ElementName* ELT_TH;
+ static nsHtml5ElementName* ELT_TR;
+ static nsHtml5ElementName* ELT_TT;
+ static nsHtml5ElementName* ELT_UL;
+ static nsHtml5ElementName* ELT_AND;
+ static nsHtml5ElementName* ELT_ARG;
+ static nsHtml5ElementName* ELT_ABS;
+ static nsHtml5ElementName* ELT_BIG;
+ static nsHtml5ElementName* ELT_BDO;
+ static nsHtml5ElementName* ELT_CSC;
+ static nsHtml5ElementName* ELT_COL;
+ static nsHtml5ElementName* ELT_COS;
+ static nsHtml5ElementName* ELT_COT;
+ static nsHtml5ElementName* ELT_DEL;
+ static nsHtml5ElementName* ELT_DFN;
+ static nsHtml5ElementName* ELT_DIR;
+ static nsHtml5ElementName* ELT_DIV;
+ static nsHtml5ElementName* ELT_EXP;
+ static nsHtml5ElementName* ELT_GCD;
+ static nsHtml5ElementName* ELT_GEQ;
+ static nsHtml5ElementName* ELT_IMG;
+ static nsHtml5ElementName* ELT_INS;
+ static nsHtml5ElementName* ELT_INT;
+ static nsHtml5ElementName* ELT_KBD;
+ static nsHtml5ElementName* ELT_LOG;
+ static nsHtml5ElementName* ELT_LCM;
+ static nsHtml5ElementName* ELT_LEQ;
+ static nsHtml5ElementName* ELT_MTD;
+ static nsHtml5ElementName* ELT_MIN;
+ static nsHtml5ElementName* ELT_MAP;
+ static nsHtml5ElementName* ELT_MTR;
+ static nsHtml5ElementName* ELT_MAX;
+ static nsHtml5ElementName* ELT_NEQ;
+ static nsHtml5ElementName* ELT_NOT;
+ static nsHtml5ElementName* ELT_NAV;
+ static nsHtml5ElementName* ELT_PRE;
+ static nsHtml5ElementName* ELT_RTC;
+ static nsHtml5ElementName* ELT_REM;
+ static nsHtml5ElementName* ELT_SUB;
+ static nsHtml5ElementName* ELT_SEC;
+ static nsHtml5ElementName* ELT_SVG;
+ static nsHtml5ElementName* ELT_SUM;
+ static nsHtml5ElementName* ELT_SIN;
+ static nsHtml5ElementName* ELT_SEP;
+ static nsHtml5ElementName* ELT_SUP;
+ static nsHtml5ElementName* ELT_SET;
+ static nsHtml5ElementName* ELT_TAN;
+ static nsHtml5ElementName* ELT_USE;
+ static nsHtml5ElementName* ELT_VAR;
+ static nsHtml5ElementName* ELT_WBR;
+ static nsHtml5ElementName* ELT_XMP;
+ static nsHtml5ElementName* ELT_XOR;
+ static nsHtml5ElementName* ELT_AREA;
+ static nsHtml5ElementName* ELT_ABBR;
+ static nsHtml5ElementName* ELT_BASE;
+ static nsHtml5ElementName* ELT_BVAR;
+ static nsHtml5ElementName* ELT_BODY;
+ static nsHtml5ElementName* ELT_CARD;
+ static nsHtml5ElementName* ELT_CODE;
+ static nsHtml5ElementName* ELT_CITE;
+ static nsHtml5ElementName* ELT_CSCH;
+ static nsHtml5ElementName* ELT_COSH;
+ static nsHtml5ElementName* ELT_COTH;
+ static nsHtml5ElementName* ELT_CURL;
+ static nsHtml5ElementName* ELT_DESC;
+ static nsHtml5ElementName* ELT_DIFF;
+ static nsHtml5ElementName* ELT_DEFS;
+ static nsHtml5ElementName* ELT_FORM;
+ static nsHtml5ElementName* ELT_FONT;
+ static nsHtml5ElementName* ELT_GRAD;
+ static nsHtml5ElementName* ELT_HEAD;
+ static nsHtml5ElementName* ELT_HTML;
+ static nsHtml5ElementName* ELT_LINE;
+ static nsHtml5ElementName* ELT_LINK;
+ static nsHtml5ElementName* ELT_LIST;
+ static nsHtml5ElementName* ELT_META;
+ static nsHtml5ElementName* ELT_MSUB;
+ static nsHtml5ElementName* ELT_MODE;
+ static nsHtml5ElementName* ELT_MATH;
+ static nsHtml5ElementName* ELT_MARK;
+ static nsHtml5ElementName* ELT_MASK;
+ static nsHtml5ElementName* ELT_MEAN;
+ static nsHtml5ElementName* ELT_MAIN;
+ static nsHtml5ElementName* ELT_MSUP;
+ static nsHtml5ElementName* ELT_MENU;
+ static nsHtml5ElementName* ELT_MROW;
+ static nsHtml5ElementName* ELT_NONE;
+ static nsHtml5ElementName* ELT_NOBR;
+ static nsHtml5ElementName* ELT_NEST;
+ static nsHtml5ElementName* ELT_PATH;
+ static nsHtml5ElementName* ELT_PLUS;
+ static nsHtml5ElementName* ELT_RULE;
+ static nsHtml5ElementName* ELT_REAL;
+ static nsHtml5ElementName* ELT_RELN;
+ static nsHtml5ElementName* ELT_RECT;
+ static nsHtml5ElementName* ELT_ROOT;
+ static nsHtml5ElementName* ELT_RUBY;
+ static nsHtml5ElementName* ELT_SECH;
+ static nsHtml5ElementName* ELT_SINH;
+ static nsHtml5ElementName* ELT_SPAN;
+ static nsHtml5ElementName* ELT_SAMP;
+ static nsHtml5ElementName* ELT_STOP;
+ static nsHtml5ElementName* ELT_SDEV;
+ static nsHtml5ElementName* ELT_TIME;
+ static nsHtml5ElementName* ELT_TRUE;
+ static nsHtml5ElementName* ELT_TREF;
+ static nsHtml5ElementName* ELT_TANH;
+ static nsHtml5ElementName* ELT_TEXT;
+ static nsHtml5ElementName* ELT_VIEW;
+ static nsHtml5ElementName* ELT_ASIDE;
+ static nsHtml5ElementName* ELT_AUDIO;
+ static nsHtml5ElementName* ELT_APPLY;
+ static nsHtml5ElementName* ELT_EMBED;
+ static nsHtml5ElementName* ELT_FRAME;
+ static nsHtml5ElementName* ELT_FALSE;
+ static nsHtml5ElementName* ELT_FLOOR;
+ static nsHtml5ElementName* ELT_GLYPH;
+ static nsHtml5ElementName* ELT_HKERN;
+ static nsHtml5ElementName* ELT_IMAGE;
+ static nsHtml5ElementName* ELT_IDENT;
+ static nsHtml5ElementName* ELT_INPUT;
+ static nsHtml5ElementName* ELT_LABEL;
+ static nsHtml5ElementName* ELT_LIMIT;
+ static nsHtml5ElementName* ELT_MFRAC;
+ static nsHtml5ElementName* ELT_MPATH;
+ static nsHtml5ElementName* ELT_METER;
+ static nsHtml5ElementName* ELT_MOVER;
+ static nsHtml5ElementName* ELT_MINUS;
+ static nsHtml5ElementName* ELT_MROOT;
+ static nsHtml5ElementName* ELT_MSQRT;
+ static nsHtml5ElementName* ELT_MTEXT;
+ static nsHtml5ElementName* ELT_NOTIN;
+ static nsHtml5ElementName* ELT_PIECE;
+ static nsHtml5ElementName* ELT_PARAM;
+ static nsHtml5ElementName* ELT_POWER;
+ static nsHtml5ElementName* ELT_REALS;
+ static nsHtml5ElementName* ELT_STYLE;
+ static nsHtml5ElementName* ELT_SMALL;
+ static nsHtml5ElementName* ELT_THEAD;
+ static nsHtml5ElementName* ELT_TABLE;
+ static nsHtml5ElementName* ELT_TITLE;
+ static nsHtml5ElementName* ELT_TRACK;
+ static nsHtml5ElementName* ELT_TSPAN;
+ static nsHtml5ElementName* ELT_TIMES;
+ static nsHtml5ElementName* ELT_TFOOT;
+ static nsHtml5ElementName* ELT_TBODY;
+ static nsHtml5ElementName* ELT_UNION;
+ static nsHtml5ElementName* ELT_VKERN;
+ static nsHtml5ElementName* ELT_VIDEO;
+ static nsHtml5ElementName* ELT_ARCSEC;
+ static nsHtml5ElementName* ELT_ARCCSC;
+ static nsHtml5ElementName* ELT_ARCTAN;
+ static nsHtml5ElementName* ELT_ARCSIN;
+ static nsHtml5ElementName* ELT_ARCCOS;
+ static nsHtml5ElementName* ELT_APPLET;
+ static nsHtml5ElementName* ELT_ARCCOT;
+ static nsHtml5ElementName* ELT_APPROX;
+ static nsHtml5ElementName* ELT_BUTTON;
+ static nsHtml5ElementName* ELT_CIRCLE;
+ static nsHtml5ElementName* ELT_CENTER;
+ static nsHtml5ElementName* ELT_CURSOR;
+ static nsHtml5ElementName* ELT_CANVAS;
+ static nsHtml5ElementName* ELT_DIVIDE;
+ static nsHtml5ElementName* ELT_DEGREE;
+ static nsHtml5ElementName* ELT_DOMAIN;
+ static nsHtml5ElementName* ELT_EXISTS;
+ static nsHtml5ElementName* ELT_FETILE;
+ static nsHtml5ElementName* ELT_FIGURE;
+ static nsHtml5ElementName* ELT_FORALL;
+ static nsHtml5ElementName* ELT_FILTER;
+ static nsHtml5ElementName* ELT_FOOTER;
+ static nsHtml5ElementName* ELT_HGROUP;
+ static nsHtml5ElementName* ELT_HEADER;
+ static nsHtml5ElementName* ELT_IFRAME;
+ static nsHtml5ElementName* ELT_KEYGEN;
+ static nsHtml5ElementName* ELT_LAMBDA;
+ static nsHtml5ElementName* ELT_LEGEND;
+ static nsHtml5ElementName* ELT_MSPACE;
+ static nsHtml5ElementName* ELT_MTABLE;
+ static nsHtml5ElementName* ELT_MSTYLE;
+ static nsHtml5ElementName* ELT_MGLYPH;
+ static nsHtml5ElementName* ELT_MEDIAN;
+ static nsHtml5ElementName* ELT_MUNDER;
+ static nsHtml5ElementName* ELT_MARKER;
+ static nsHtml5ElementName* ELT_MERROR;
+ static nsHtml5ElementName* ELT_MOMENT;
+ static nsHtml5ElementName* ELT_MATRIX;
+ static nsHtml5ElementName* ELT_OPTION;
+ static nsHtml5ElementName* ELT_OBJECT;
+ static nsHtml5ElementName* ELT_OUTPUT;
+ static nsHtml5ElementName* ELT_PRIMES;
+ static nsHtml5ElementName* ELT_SOURCE;
+ static nsHtml5ElementName* ELT_STRIKE;
+ static nsHtml5ElementName* ELT_STRONG;
+ static nsHtml5ElementName* ELT_SWITCH;
+ static nsHtml5ElementName* ELT_SYMBOL;
+ static nsHtml5ElementName* ELT_SELECT;
+ static nsHtml5ElementName* ELT_SUBSET;
+ static nsHtml5ElementName* ELT_SCRIPT;
+ static nsHtml5ElementName* ELT_TBREAK;
+ static nsHtml5ElementName* ELT_VECTOR;
+ static nsHtml5ElementName* ELT_ARTICLE;
+ static nsHtml5ElementName* ELT_ANIMATE;
+ static nsHtml5ElementName* ELT_ARCSECH;
+ static nsHtml5ElementName* ELT_ARCCSCH;
+ static nsHtml5ElementName* ELT_ARCTANH;
+ static nsHtml5ElementName* ELT_ARCSINH;
+ static nsHtml5ElementName* ELT_ARCCOSH;
+ static nsHtml5ElementName* ELT_ARCCOTH;
+ static nsHtml5ElementName* ELT_ACRONYM;
+ static nsHtml5ElementName* ELT_ADDRESS;
+ static nsHtml5ElementName* ELT_BGSOUND;
+ static nsHtml5ElementName* ELT_COMPOSE;
+ static nsHtml5ElementName* ELT_CEILING;
+ static nsHtml5ElementName* ELT_CSYMBOL;
+ static nsHtml5ElementName* ELT_CAPTION;
+ static nsHtml5ElementName* ELT_DISCARD;
+ static nsHtml5ElementName* ELT_DECLARE;
+ static nsHtml5ElementName* ELT_DETAILS;
+ static nsHtml5ElementName* ELT_ELLIPSE;
+ static nsHtml5ElementName* ELT_FEFUNCA;
+ static nsHtml5ElementName* ELT_FEFUNCB;
+ static nsHtml5ElementName* ELT_FEBLEND;
+ static nsHtml5ElementName* ELT_FEFLOOD;
+ static nsHtml5ElementName* ELT_FEIMAGE;
+ static nsHtml5ElementName* ELT_FEMERGE;
+ static nsHtml5ElementName* ELT_FEFUNCG;
+ static nsHtml5ElementName* ELT_FEFUNCR;
+ static nsHtml5ElementName* ELT_HANDLER;
+ static nsHtml5ElementName* ELT_INVERSE;
+ static nsHtml5ElementName* ELT_IMPLIES;
+ static nsHtml5ElementName* ELT_ISINDEX;
+ static nsHtml5ElementName* ELT_LOGBASE;
+ static nsHtml5ElementName* ELT_LISTING;
+ static nsHtml5ElementName* ELT_MFENCED;
+ static nsHtml5ElementName* ELT_MPADDED;
+ static nsHtml5ElementName* ELT_MARQUEE;
+ static nsHtml5ElementName* ELT_MACTION;
+ static nsHtml5ElementName* ELT_MSUBSUP;
+ static nsHtml5ElementName* ELT_NOEMBED;
+ static nsHtml5ElementName* ELT_POLYGON;
+ static nsHtml5ElementName* ELT_PATTERN;
+ static nsHtml5ElementName* ELT_PICTURE;
+ static nsHtml5ElementName* ELT_PRODUCT;
+ static nsHtml5ElementName* ELT_SETDIFF;
+ static nsHtml5ElementName* ELT_SECTION;
+ static nsHtml5ElementName* ELT_SUMMARY;
+ static nsHtml5ElementName* ELT_TENDSTO;
+ static nsHtml5ElementName* ELT_UPLIMIT;
+ static nsHtml5ElementName* ELT_ALTGLYPH;
+ static nsHtml5ElementName* ELT_BASEFONT;
+ static nsHtml5ElementName* ELT_CLIPPATH;
+ static nsHtml5ElementName* ELT_CODOMAIN;
+ static nsHtml5ElementName* ELT_COLGROUP;
+ static nsHtml5ElementName* ELT_EMPTYSET;
+ static nsHtml5ElementName* ELT_FACTOROF;
+ static nsHtml5ElementName* ELT_FIELDSET;
+ static nsHtml5ElementName* ELT_FRAMESET;
+ static nsHtml5ElementName* ELT_FEOFFSET;
+ static nsHtml5ElementName* ELT_GLYPHREF;
+ static nsHtml5ElementName* ELT_INTERVAL;
+ static nsHtml5ElementName* ELT_INTEGERS;
+ static nsHtml5ElementName* ELT_INFINITY;
+ static nsHtml5ElementName* ELT_LISTENER;
+ static nsHtml5ElementName* ELT_LOWLIMIT;
+ static nsHtml5ElementName* ELT_METADATA;
+ static nsHtml5ElementName* ELT_MENCLOSE;
+ static nsHtml5ElementName* ELT_MENUITEM;
+ static nsHtml5ElementName* ELT_MPHANTOM;
+ static nsHtml5ElementName* ELT_NOFRAMES;
+ static nsHtml5ElementName* ELT_NOSCRIPT;
+ static nsHtml5ElementName* ELT_OPTGROUP;
+ static nsHtml5ElementName* ELT_POLYLINE;
+ static nsHtml5ElementName* ELT_PREFETCH;
+ static nsHtml5ElementName* ELT_PROGRESS;
+ static nsHtml5ElementName* ELT_PRSUBSET;
+ static nsHtml5ElementName* ELT_QUOTIENT;
+ static nsHtml5ElementName* ELT_SELECTOR;
+ static nsHtml5ElementName* ELT_TEXTAREA;
+ static nsHtml5ElementName* ELT_TEMPLATE;
+ static nsHtml5ElementName* ELT_TEXTPATH;
+ static nsHtml5ElementName* ELT_VARIANCE;
+ static nsHtml5ElementName* ELT_ANIMATION;
+ static nsHtml5ElementName* ELT_CONJUGATE;
+ static nsHtml5ElementName* ELT_CONDITION;
+ static nsHtml5ElementName* ELT_COMPLEXES;
+ static nsHtml5ElementName* ELT_FONT_FACE;
+ static nsHtml5ElementName* ELT_FACTORIAL;
+ static nsHtml5ElementName* ELT_INTERSECT;
+ static nsHtml5ElementName* ELT_IMAGINARY;
+ static nsHtml5ElementName* ELT_LAPLACIAN;
+ static nsHtml5ElementName* ELT_MATRIXROW;
+ static nsHtml5ElementName* ELT_NOTSUBSET;
+ static nsHtml5ElementName* ELT_OTHERWISE;
+ static nsHtml5ElementName* ELT_PIECEWISE;
+ static nsHtml5ElementName* ELT_PLAINTEXT;
+ static nsHtml5ElementName* ELT_RATIONALS;
+ static nsHtml5ElementName* ELT_SEMANTICS;
+ static nsHtml5ElementName* ELT_TRANSPOSE;
+ static nsHtml5ElementName* ELT_ANNOTATION;
+ static nsHtml5ElementName* ELT_BLOCKQUOTE;
+ static nsHtml5ElementName* ELT_DIVERGENCE;
+ static nsHtml5ElementName* ELT_EULERGAMMA;
+ static nsHtml5ElementName* ELT_EQUIVALENT;
+ static nsHtml5ElementName* ELT_FIGCAPTION;
+ static nsHtml5ElementName* ELT_IMAGINARYI;
+ static nsHtml5ElementName* ELT_MALIGNMARK;
+ static nsHtml5ElementName* ELT_MUNDEROVER;
+ static nsHtml5ElementName* ELT_MLABELEDTR;
+ static nsHtml5ElementName* ELT_NOTANUMBER;
+ static nsHtml5ElementName* ELT_SOLIDCOLOR;
+ static nsHtml5ElementName* ELT_ALTGLYPHDEF;
+ static nsHtml5ElementName* ELT_DETERMINANT;
+ static nsHtml5ElementName* ELT_FEMERGENODE;
+ static nsHtml5ElementName* ELT_FECOMPOSITE;
+ static nsHtml5ElementName* ELT_FESPOTLIGHT;
+ static nsHtml5ElementName* ELT_MALIGNGROUP;
+ static nsHtml5ElementName* ELT_MPRESCRIPTS;
+ static nsHtml5ElementName* ELT_MOMENTABOUT;
+ static nsHtml5ElementName* ELT_NOTPRSUBSET;
+ static nsHtml5ElementName* ELT_PARTIALDIFF;
+ static nsHtml5ElementName* ELT_ALTGLYPHITEM;
+ static nsHtml5ElementName* ELT_ANIMATECOLOR;
+ static nsHtml5ElementName* ELT_DATATEMPLATE;
+ static nsHtml5ElementName* ELT_EXPONENTIALE;
+ static nsHtml5ElementName* ELT_FETURBULENCE;
+ static nsHtml5ElementName* ELT_FEPOINTLIGHT;
+ static nsHtml5ElementName* ELT_FEDROPSHADOW;
+ static nsHtml5ElementName* ELT_FEMORPHOLOGY;
+ static nsHtml5ElementName* ELT_OUTERPRODUCT;
+ static nsHtml5ElementName* ELT_ANIMATEMOTION;
+ static nsHtml5ElementName* ELT_COLOR_PROFILE;
+ static nsHtml5ElementName* ELT_FONT_FACE_SRC;
+ static nsHtml5ElementName* ELT_FONT_FACE_URI;
+ static nsHtml5ElementName* ELT_FOREIGNOBJECT;
+ static nsHtml5ElementName* ELT_FECOLORMATRIX;
+ static nsHtml5ElementName* ELT_MISSING_GLYPH;
+ static nsHtml5ElementName* ELT_MMULTISCRIPTS;
+ static nsHtml5ElementName* ELT_SCALARPRODUCT;
+ static nsHtml5ElementName* ELT_VECTORPRODUCT;
+ static nsHtml5ElementName* ELT_ANNOTATION_XML;
+ static nsHtml5ElementName* ELT_DEFINITION_SRC;
+ static nsHtml5ElementName* ELT_FONT_FACE_NAME;
+ static nsHtml5ElementName* ELT_FEGAUSSIANBLUR;
+ static nsHtml5ElementName* ELT_FEDISTANTLIGHT;
+ static nsHtml5ElementName* ELT_LINEARGRADIENT;
+ static nsHtml5ElementName* ELT_NATURALNUMBERS;
+ static nsHtml5ElementName* ELT_RADIALGRADIENT;
+ static nsHtml5ElementName* ELT_ANIMATETRANSFORM;
+ static nsHtml5ElementName* ELT_CARTESIANPRODUCT;
+ static nsHtml5ElementName* ELT_FONT_FACE_FORMAT;
+ static nsHtml5ElementName* ELT_FECONVOLVEMATRIX;
+ static nsHtml5ElementName* ELT_FEDIFFUSELIGHTING;
+ static nsHtml5ElementName* ELT_FEDISPLACEMENTMAP;
+ static nsHtml5ElementName* ELT_FESPECULARLIGHTING;
+ static nsHtml5ElementName* ELT_DOMAINOFAPPLICATION;
+ static nsHtml5ElementName* ELT_FECOMPONENTTRANSFER;
+ private:
+ static nsHtml5ElementName** ELEMENT_NAMES;
+ static staticJArray<int32_t,int32_t> ELEMENT_HASHES;
+ public:
+ static void initializeStatics();
+ static void releaseStatics();
+};
+
+#define NS_HTML5ELEMENT_NAME_GROUP_MASK 127
+#define NS_HTML5ELEMENT_NAME_CUSTOM (1 << 30)
+#define NS_HTML5ELEMENT_NAME_SPECIAL (1 << 29)
+#define NS_HTML5ELEMENT_NAME_FOSTER_PARENTING (1 << 28)
+#define NS_HTML5ELEMENT_NAME_SCOPING (1 << 27)
+#define NS_HTML5ELEMENT_NAME_SCOPING_AS_SVG (1 << 26)
+#define NS_HTML5ELEMENT_NAME_SCOPING_AS_MATHML (1 << 25)
+#define NS_HTML5ELEMENT_NAME_HTML_INTEGRATION_POINT (1 << 24)
+#define NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG (1 << 23)
+
+
+#endif
+
diff --git a/parser/html/nsHtml5Highlighter.cpp b/parser/html/nsHtml5Highlighter.cpp
new file mode 100644
index 000000000..259803ee1
--- /dev/null
+++ b/parser/html/nsHtml5Highlighter.cpp
@@ -0,0 +1,802 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5Highlighter.h"
+#include "nsDebug.h"
+#include "nsHtml5Tokenizer.h"
+#include "nsHtml5AttributeName.h"
+#include "nsString.h"
+#include "nsThreadUtils.h"
+#include "nsHtml5ViewSourceUtils.h"
+
+#include "mozilla/Attributes.h"
+#include "mozilla/Preferences.h"
+
+using namespace mozilla;
+
+// The old code had a limit of 16 tokens. 1300 is a number picked my measuring
+// the size of 16 tokens on cnn.com.
+#define NS_HTML5_HIGHLIGHTER_PRE_BREAK_THRESHOLD 1300
+
+char16_t nsHtml5Highlighter::sComment[] =
+ { 'c', 'o', 'm', 'm', 'e', 'n', 't', 0 };
+
+char16_t nsHtml5Highlighter::sCdata[] =
+ { 'c', 'd', 'a', 't', 'a', 0 };
+
+char16_t nsHtml5Highlighter::sEntity[] =
+ { 'e', 'n', 't', 'i', 't', 'y', 0 };
+
+char16_t nsHtml5Highlighter::sEndTag[] =
+ { 'e', 'n', 'd', '-', 't', 'a', 'g', 0 };
+
+char16_t nsHtml5Highlighter::sStartTag[] =
+ { 's', 't', 'a', 'r', 't', '-', 't', 'a', 'g', 0 };
+
+char16_t nsHtml5Highlighter::sAttributeName[] =
+ { 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', '-', 'n', 'a', 'm', 'e', 0 };
+
+char16_t nsHtml5Highlighter::sAttributeValue[] =
+ { 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', '-',
+ 'v', 'a', 'l', 'u', 'e', 0 };
+
+char16_t nsHtml5Highlighter::sDoctype[] =
+ { 'd', 'o', 'c', 't', 'y', 'p', 'e', 0 };
+
+char16_t nsHtml5Highlighter::sPi[] =
+ { 'p', 'i', 0 };
+
+nsHtml5Highlighter::nsHtml5Highlighter(nsAHtml5TreeOpSink* aOpSink)
+ : mState(NS_HTML5TOKENIZER_DATA)
+ , mCStart(INT32_MAX)
+ , mPos(0)
+ , mLineNumber(1)
+ , mInlinesOpen(0)
+ , mInCharacters(false)
+ , mBuffer(nullptr)
+ , mOpSink(aOpSink)
+ , mCurrentRun(nullptr)
+ , mAmpersand(nullptr)
+ , mSlash(nullptr)
+ , mHandles(MakeUnique<nsIContent*[]>(NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH))
+ , mHandlesUsed(0)
+ , mSeenBase(false)
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+}
+
+nsHtml5Highlighter::~nsHtml5Highlighter()
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+}
+
+void
+nsHtml5Highlighter::Start(const nsAutoString& aTitle)
+{
+ // Doctype
+ mOpQueue.AppendElement()->Init(nsGkAtoms::html, EmptyString(), EmptyString());
+
+ mOpQueue.AppendElement()->Init(STANDARDS_MODE);
+
+ nsIContent** root = CreateElement(nsHtml5Atoms::html, nullptr, nullptr);
+ mOpQueue.AppendElement()->Init(eTreeOpAppendToDocument, root);
+ mStack.AppendElement(root);
+
+ Push(nsGkAtoms::head, nullptr);
+
+ Push(nsGkAtoms::title, nullptr);
+ // XUL will add the "Source of: " prefix.
+ uint32_t length = aTitle.Length();
+ if (length > INT32_MAX) {
+ length = INT32_MAX;
+ }
+ AppendCharacters(aTitle.get(), 0, (int32_t)length);
+ Pop(); // title
+
+ Push(nsGkAtoms::link, nsHtml5ViewSourceUtils::NewLinkAttributes());
+
+ mOpQueue.AppendElement()->Init(eTreeOpUpdateStyleSheet, CurrentNode());
+
+ Pop(); // link
+
+ Pop(); // head
+
+ Push(nsGkAtoms::body, nsHtml5ViewSourceUtils::NewBodyAttributes());
+
+ nsHtml5HtmlAttributes* preAttrs = new nsHtml5HtmlAttributes(0);
+ nsString* preId = new nsString(NS_LITERAL_STRING("line1"));
+ preAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, preId, -1);
+ Push(nsGkAtoms::pre, preAttrs);
+
+ StartCharacters();
+
+ mOpQueue.AppendElement()->Init(eTreeOpStartLayout);
+}
+
+int32_t
+nsHtml5Highlighter::Transition(int32_t aState, bool aReconsume, int32_t aPos)
+{
+ mPos = aPos;
+ switch (mState) {
+ case NS_HTML5TOKENIZER_SCRIPT_DATA:
+ case NS_HTML5TOKENIZER_RAWTEXT:
+ case NS_HTML5TOKENIZER_RCDATA:
+ case NS_HTML5TOKENIZER_DATA:
+ // We can transition on < and on &. Either way, we don't yet know the
+ // role of the token, so open a span without class.
+ if (aState == NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE) {
+ StartSpan();
+ // Start another span for highlighting the ampersand
+ StartSpan();
+ mAmpersand = CurrentNode();
+ } else {
+ EndCharactersAndStartMarkupRun();
+ }
+ break;
+ case NS_HTML5TOKENIZER_TAG_OPEN:
+ switch (aState) {
+ case NS_HTML5TOKENIZER_TAG_NAME:
+ StartSpan(sStartTag);
+ break;
+ case NS_HTML5TOKENIZER_DATA:
+ FinishTag(); // DATA
+ break;
+ case NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION:
+ AddClass(sPi);
+ break;
+ }
+ break;
+ case NS_HTML5TOKENIZER_TAG_NAME:
+ switch (aState) {
+ case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
+ EndSpanOrA(); // NS_HTML5TOKENIZER_TAG_NAME
+ break;
+ case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
+ EndSpanOrA(); // NS_HTML5TOKENIZER_TAG_NAME
+ StartSpan(); // for highlighting the slash
+ mSlash = CurrentNode();
+ break;
+ default:
+ FinishTag();
+ break;
+ }
+ break;
+ case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
+ switch (aState) {
+ case NS_HTML5TOKENIZER_ATTRIBUTE_NAME:
+ StartSpan(sAttributeName);
+ break;
+ case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
+ StartSpan(); // for highlighting the slash
+ mSlash = CurrentNode();
+ break;
+ default:
+ FinishTag();
+ break;
+ }
+ break;
+ case NS_HTML5TOKENIZER_ATTRIBUTE_NAME:
+ switch (aState) {
+ case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME:
+ case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE:
+ EndSpanOrA(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
+ break;
+ case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
+ EndSpanOrA(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
+ StartSpan(); // for highlighting the slash
+ mSlash = CurrentNode();
+ break;
+ default:
+ FinishTag();
+ break;
+ }
+ break;
+ case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE:
+ switch (aState) {
+ case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED:
+ case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED:
+ FlushCurrent();
+ StartA();
+ break;
+ case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED:
+ StartA();
+ break;
+ default:
+ FinishTag();
+ break;
+ }
+ break;
+ case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED:
+ case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED:
+ switch (aState) {
+ case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED:
+ EndSpanOrA();
+ break;
+ case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
+ StartSpan();
+ StartSpan(); // for ampersand itself
+ mAmpersand = CurrentNode();
+ break;
+ default:
+ NS_NOTREACHED("Impossible transition.");
+ break;
+ }
+ break;
+ case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED:
+ switch (aState) {
+ case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
+ break;
+ case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
+ StartSpan(); // for highlighting the slash
+ mSlash = CurrentNode();
+ break;
+ default:
+ FinishTag();
+ break;
+ }
+ break;
+ case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
+ EndSpanOrA(); // end the slash highlight
+ switch (aState) {
+ case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
+ break;
+ default:
+ FinishTag();
+ break;
+ }
+ break;
+ case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED:
+ switch (aState) {
+ case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
+ EndSpanOrA();
+ break;
+ case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
+ StartSpan();
+ StartSpan(); // for ampersand itself
+ mAmpersand = CurrentNode();
+ break;
+ default:
+ FinishTag();
+ break;
+ }
+ break;
+ case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME:
+ switch (aState) {
+ case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
+ StartSpan(); // for highlighting the slash
+ mSlash = CurrentNode();
+ break;
+ case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE:
+ break;
+ case NS_HTML5TOKENIZER_ATTRIBUTE_NAME:
+ StartSpan(sAttributeName);
+ break;
+ default:
+ FinishTag();
+ break;
+ }
+ break;
+ // most comment states are omitted, because they don't matter to
+ // highlighting
+ case NS_HTML5TOKENIZER_COMMENT_START:
+ case NS_HTML5TOKENIZER_COMMENT_END:
+ case NS_HTML5TOKENIZER_COMMENT_END_BANG:
+ case NS_HTML5TOKENIZER_COMMENT_START_DASH:
+ case NS_HTML5TOKENIZER_BOGUS_COMMENT:
+ case NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN:
+ if (aState == NS_HTML5TOKENIZER_DATA) {
+ AddClass(sComment);
+ FinishTag();
+ }
+ break;
+ // most cdata states are omitted, because they don't matter to
+ // highlighting
+ case NS_HTML5TOKENIZER_CDATA_RSQB_RSQB:
+ if (aState == NS_HTML5TOKENIZER_DATA) {
+ AddClass(sCdata);
+ FinishTag();
+ }
+ break;
+ case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
+ EndSpanOrA(); // the span for the ampersand
+ switch (aState) {
+ case NS_HTML5TOKENIZER_CONSUME_NCR:
+ case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP:
+ break;
+ default:
+ // not actually a character reference
+ EndSpanOrA();
+ break;
+ }
+ break;
+ case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP:
+ if (aState == NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL) {
+ break;
+ }
+ // not actually a character reference
+ EndSpanOrA();
+ break;
+ case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL:
+ if (!aReconsume) {
+ FlushCurrent();
+ }
+ EndSpanOrA();
+ break;
+ case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP:
+ case NS_HTML5TOKENIZER_HEX_NCR_LOOP:
+ switch (aState) {
+ case NS_HTML5TOKENIZER_HANDLE_NCR_VALUE:
+ AddClass(sEntity);
+ FlushCurrent();
+ break;
+ case NS_HTML5TOKENIZER_HANDLE_NCR_VALUE_RECONSUME:
+ AddClass(sEntity);
+ break;
+ }
+ EndSpanOrA();
+ break;
+ case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN:
+ switch (aState) {
+ case NS_HTML5TOKENIZER_DATA:
+ FinishTag();
+ break;
+ case NS_HTML5TOKENIZER_TAG_NAME:
+ StartSpan(sEndTag);
+ break;
+ }
+ break;
+ case NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN:
+ if (aState == NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME) {
+ FlushCurrent();
+ StartSpan(); // don't know if it is "end-tag" yet :-(
+ break;
+ }
+ EndSpanOrA();
+ StartCharacters();
+ break;
+ case NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME:
+ switch (aState) {
+ case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
+ AddClass(sEndTag);
+ EndSpanOrA();
+ break;
+ case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
+ AddClass(sEndTag);
+ EndSpanOrA();
+ StartSpan(); // for highlighting the slash
+ mSlash = CurrentNode();
+ break;
+ case NS_HTML5TOKENIZER_DATA: // yes, as a result of emitting the token
+ AddClass(sEndTag);
+ FinishTag();
+ break;
+ default:
+ FinishTag();
+ break;
+ }
+ break;
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:
+ if (aState == NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME) {
+ FlushCurrent();
+ StartSpan(); // don't know if it is "end-tag" yet :-(
+ break;
+ }
+ FinishTag();
+ break;
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH:
+ if (aState == NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN) {
+ EndCharactersAndStartMarkupRun();
+ }
+ break;
+ // Lots of double escape states omitted, because they don't highlight.
+ // Likewise, only doctype states that can emit the doctype are of
+ // interest. Otherwise, the transition out of bogus comment deals.
+ case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME:
+ case NS_HTML5TOKENIZER_DOCTYPE_NAME:
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME:
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD:
+ case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
+ case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
+ case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
+ case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
+ case NS_HTML5TOKENIZER_BOGUS_DOCTYPE:
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD:
+ case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
+ case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
+ case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
+ if (aState == NS_HTML5TOKENIZER_DATA) {
+ AddClass(sDoctype);
+ FinishTag();
+ }
+ break;
+ case NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION_QUESTION_MARK:
+ if (aState == NS_HTML5TOKENIZER_DATA) {
+ FinishTag();
+ }
+ break;
+ default:
+ break;
+ }
+ mState = aState;
+ return aState;
+}
+
+void
+nsHtml5Highlighter::End()
+{
+ switch (mState) {
+ case NS_HTML5TOKENIZER_COMMENT_END:
+ case NS_HTML5TOKENIZER_COMMENT_END_BANG:
+ case NS_HTML5TOKENIZER_COMMENT_START_DASH:
+ case NS_HTML5TOKENIZER_BOGUS_COMMENT:
+ case NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN:
+ AddClass(sComment);
+ break;
+ case NS_HTML5TOKENIZER_CDATA_RSQB_RSQB:
+ AddClass(sCdata);
+ break;
+ case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP:
+ case NS_HTML5TOKENIZER_HEX_NCR_LOOP:
+ // XXX need tokenizer help here
+ break;
+ case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME:
+ case NS_HTML5TOKENIZER_DOCTYPE_NAME:
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME:
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD:
+ case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
+ case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
+ case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
+ case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
+ case NS_HTML5TOKENIZER_BOGUS_DOCTYPE:
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD:
+ case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
+ case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
+ case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
+ AddClass(sDoctype);
+ break;
+ default:
+ break;
+ }
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpStreamEnded);
+ FlushOps();
+}
+
+void
+nsHtml5Highlighter::SetBuffer(nsHtml5UTF16Buffer* aBuffer)
+{
+ NS_PRECONDITION(!mBuffer, "Old buffer still here!");
+ mBuffer = aBuffer;
+ mCStart = aBuffer->getStart();
+}
+
+void
+nsHtml5Highlighter::DropBuffer(int32_t aPos)
+{
+ NS_PRECONDITION(mBuffer, "No buffer to drop!");
+ mPos = aPos;
+ FlushChars();
+ mBuffer = nullptr;
+}
+
+void
+nsHtml5Highlighter::StartSpan()
+{
+ FlushChars();
+ Push(nsGkAtoms::span, nullptr);
+ ++mInlinesOpen;
+}
+
+void
+nsHtml5Highlighter::StartSpan(const char16_t* aClass)
+{
+ StartSpan();
+ AddClass(aClass);
+}
+
+void
+nsHtml5Highlighter::EndSpanOrA()
+{
+ FlushChars();
+ Pop();
+ --mInlinesOpen;
+}
+
+void
+nsHtml5Highlighter::StartCharacters()
+{
+ NS_PRECONDITION(!mInCharacters, "Already in characters!");
+ FlushChars();
+ Push(nsGkAtoms::span, nullptr);
+ mCurrentRun = CurrentNode();
+ mInCharacters = true;
+}
+
+void
+nsHtml5Highlighter::EndCharactersAndStartMarkupRun()
+{
+ NS_PRECONDITION(mInCharacters, "Not in characters!");
+ FlushChars();
+ Pop();
+ mInCharacters = false;
+ // Now start markup run
+ StartSpan();
+ mCurrentRun = CurrentNode();
+}
+
+void
+nsHtml5Highlighter::StartA()
+{
+ FlushChars();
+ Push(nsGkAtoms::a, nullptr);
+ AddClass(sAttributeValue);
+ ++mInlinesOpen;
+}
+
+void
+nsHtml5Highlighter::FinishTag()
+{
+ while (mInlinesOpen > 1) {
+ EndSpanOrA();
+ }
+ FlushCurrent(); // >
+ EndSpanOrA(); // DATA
+ NS_ASSERTION(!mInlinesOpen, "mInlinesOpen got out of sync!");
+ StartCharacters();
+}
+
+void
+nsHtml5Highlighter::FlushChars()
+{
+ if (mCStart < mPos) {
+ char16_t* buf = mBuffer->getBuffer();
+ int32_t i = mCStart;
+ while (i < mPos) {
+ char16_t c = buf[i];
+ switch (c) {
+ case '\r':
+ // The input this code sees has been normalized so that there are
+ // CR breaks and LF breaks but no CRLF breaks. Overwrite CR with LF
+ // to show consistent LF line breaks to layout. It is OK to mutate
+ // the input data, because there are no reparses in the View Source
+ // case, so we won't need the original data in the buffer anymore.
+ buf[i] = '\n';
+ MOZ_FALLTHROUGH;
+ case '\n': {
+ ++i;
+ if (mCStart < i) {
+ int32_t len = i - mCStart;
+ AppendCharacters(buf, mCStart, len);
+ mCStart = i;
+ }
+ ++mLineNumber;
+ Push(nsGkAtoms::span, nullptr);
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->InitAddLineNumberId(CurrentNode(), mLineNumber);
+ Pop();
+ break;
+ }
+ default:
+ ++i;
+ break;
+ }
+ }
+ if (mCStart < mPos) {
+ int32_t len = mPos - mCStart;
+ AppendCharacters(buf, mCStart, len);
+ mCStart = mPos;
+ }
+ }
+}
+
+void
+nsHtml5Highlighter::FlushCurrent()
+{
+ mPos++;
+ FlushChars();
+}
+
+bool
+nsHtml5Highlighter::FlushOps()
+{
+ bool hasOps = !mOpQueue.IsEmpty();
+ if (hasOps) {
+ mOpSink->MoveOpsFrom(mOpQueue);
+ }
+ return hasOps;
+}
+
+void
+nsHtml5Highlighter::MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
+ nsString* aValue)
+{
+ if (!(nsHtml5AttributeName::ATTR_HREF == aName ||
+ nsHtml5AttributeName::ATTR_SRC == aName ||
+ nsHtml5AttributeName::ATTR_ACTION == aName ||
+ nsHtml5AttributeName::ATTR_CITE == aName ||
+ nsHtml5AttributeName::ATTR_BACKGROUND == aName ||
+ nsHtml5AttributeName::ATTR_LONGDESC == aName ||
+ nsHtml5AttributeName::ATTR_XLINK_HREF == aName ||
+ nsHtml5AttributeName::ATTR_DEFINITIONURL == aName)) {
+ return;
+ }
+ AddViewSourceHref(*aValue);
+}
+
+void
+nsHtml5Highlighter::CompletedNamedCharacterReference()
+{
+ AddClass(sEntity);
+}
+
+nsIContent**
+nsHtml5Highlighter::AllocateContentHandle()
+{
+ if (mHandlesUsed == NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH) {
+ mOldHandles.AppendElement(Move(mHandles));
+ mHandles = MakeUnique<nsIContent*[]>(NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH);
+ mHandlesUsed = 0;
+ }
+#ifdef DEBUG
+ mHandles[mHandlesUsed] = reinterpret_cast<nsIContent*>(uintptr_t(0xC0DEDBAD));
+#endif
+ return &mHandles[mHandlesUsed++];
+}
+
+nsIContent**
+nsHtml5Highlighter::CreateElement(nsIAtom* aName,
+ nsHtml5HtmlAttributes* aAttributes,
+ nsIContent** aIntendedParent)
+{
+ NS_PRECONDITION(aName, "Got null name.");
+ nsIContent** content = AllocateContentHandle();
+ mOpQueue.AppendElement()->Init(kNameSpaceID_XHTML,
+ aName,
+ aAttributes,
+ content,
+ aIntendedParent,
+ true);
+ return content;
+}
+
+nsIContent**
+nsHtml5Highlighter::CurrentNode()
+{
+ NS_PRECONDITION(mStack.Length() >= 1, "Must have something on stack.");
+ return mStack[mStack.Length() - 1];
+}
+
+void
+nsHtml5Highlighter::Push(nsIAtom* aName,
+ nsHtml5HtmlAttributes* aAttributes)
+{
+ NS_PRECONDITION(mStack.Length() >= 1, "Pushing without root.");
+ nsIContent** elt = CreateElement(aName, aAttributes, CurrentNode()); // Don't inline below!
+ mOpQueue.AppendElement()->Init(eTreeOpAppend, elt, CurrentNode());
+ mStack.AppendElement(elt);
+}
+
+void
+nsHtml5Highlighter::Pop()
+{
+ NS_PRECONDITION(mStack.Length() >= 2, "Popping when stack too short.");
+ mStack.RemoveElementAt(mStack.Length() - 1);
+}
+
+void
+nsHtml5Highlighter::AppendCharacters(const char16_t* aBuffer,
+ int32_t aStart,
+ int32_t aLength)
+{
+ NS_PRECONDITION(aBuffer, "Null buffer");
+
+ char16_t* bufferCopy = new char16_t[aLength];
+ memcpy(bufferCopy, aBuffer + aStart, aLength * sizeof(char16_t));
+
+ mOpQueue.AppendElement()->Init(eTreeOpAppendText,
+ bufferCopy,
+ aLength,
+ CurrentNode());
+}
+
+
+void
+nsHtml5Highlighter::AddClass(const char16_t* aClass)
+{
+ mOpQueue.AppendElement()->InitAddClass(CurrentNode(), aClass);
+}
+
+void
+nsHtml5Highlighter::AddViewSourceHref(const nsString& aValue)
+{
+ char16_t* bufferCopy = new char16_t[aValue.Length() + 1];
+ memcpy(bufferCopy, aValue.get(), aValue.Length() * sizeof(char16_t));
+ bufferCopy[aValue.Length()] = 0;
+
+ mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceHref,
+ bufferCopy,
+ aValue.Length(),
+ CurrentNode());
+}
+
+void
+nsHtml5Highlighter::AddBase(const nsString& aValue)
+{
+ if(mSeenBase) {
+ return;
+ }
+ mSeenBase = true;
+ char16_t* bufferCopy = new char16_t[aValue.Length() + 1];
+ memcpy(bufferCopy, aValue.get(), aValue.Length() * sizeof(char16_t));
+ bufferCopy[aValue.Length()] = 0;
+
+ mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceBase,
+ bufferCopy,
+ aValue.Length());
+}
+
+void
+nsHtml5Highlighter::AddErrorToCurrentNode(const char* aMsgId)
+{
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(CurrentNode(), aMsgId);
+}
+
+void
+nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId)
+{
+ NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(mCurrentRun, aMsgId);
+}
+
+void
+nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId,
+ nsIAtom* aName)
+{
+ NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(mCurrentRun, aMsgId, aName);
+}
+
+void
+nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId,
+ nsIAtom* aName,
+ nsIAtom* aOther)
+{
+ NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(mCurrentRun, aMsgId, aName, aOther);
+}
+
+void
+nsHtml5Highlighter::AddErrorToCurrentAmpersand(const char* aMsgId)
+{
+ NS_PRECONDITION(mAmpersand, "Adding error to ampersand without one!");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(mAmpersand, aMsgId);
+}
+
+void
+nsHtml5Highlighter::AddErrorToCurrentSlash(const char* aMsgId)
+{
+ NS_PRECONDITION(mSlash, "Adding error to slash without one!");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(mSlash, aMsgId);
+}
diff --git a/parser/html/nsHtml5Highlighter.h b/parser/html/nsHtml5Highlighter.h
new file mode 100644
index 000000000..e9474869e
--- /dev/null
+++ b/parser/html/nsHtml5Highlighter.h
@@ -0,0 +1,413 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef nsHtml5Highlighter_h
+#define nsHtml5Highlighter_h
+
+#include "nsCOMPtr.h"
+#include "nsHtml5TreeOperation.h"
+#include "nsHtml5UTF16Buffer.h"
+#include "nsHtml5TreeOperation.h"
+#include "nsAHtml5TreeOpSink.h"
+
+#define NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH 512
+
+/**
+ * A state machine for generating HTML for display in View Source based on
+ * the transitions the tokenizer makes on the source being viewed.
+ */
+class nsHtml5Highlighter
+{
+ public:
+ /**
+ * The constructor.
+ *
+ * @param aOpSink the sink for the tree ops generated by this highlighter
+ */
+ explicit nsHtml5Highlighter(nsAHtml5TreeOpSink* aOpSink);
+
+ /**
+ * The destructor.
+ */
+ ~nsHtml5Highlighter();
+
+ /**
+ * Starts the generated document.
+ */
+ void Start(const nsAutoString& aTitle);
+
+ /**
+ * Report a tokenizer state transition.
+ *
+ * @param aState the state being transitioned to
+ * @param aReconsume whether this is a reconsuming transition
+ * @param aPos the tokenizer's current position into the buffer
+ */
+ int32_t Transition(int32_t aState, bool aReconsume, int32_t aPos);
+
+ /**
+ * Report end of file.
+ */
+ void End();
+
+ /**
+ * Set the current buffer being tokenized
+ */
+ void SetBuffer(nsHtml5UTF16Buffer* aBuffer);
+
+ /**
+ * Let go of the buffer being tokenized but first, flush text from it.
+ *
+ * @param aPos the first UTF-16 code unit not to flush
+ */
+ void DropBuffer(int32_t aPos);
+
+ /**
+ * Flush the tree ops into the sink.
+ *
+ * @return true if there were ops to flush
+ */
+ bool FlushOps();
+
+ /**
+ * Linkify the current attribute value if the attribute name is one of
+ * known URL attributes. (When executing tree ops, javascript: URLs will
+ * not be linkified, though.)
+ *
+ * @param aName the name of the attribute
+ * @param aValue the value of the attribute
+ */
+ void MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
+ nsString* aValue);
+
+ /**
+ * Inform the highlighter that the tokenizer successfully completed a
+ * named character reference.
+ */
+ void CompletedNamedCharacterReference();
+
+ /**
+ * Adds an error annotation to the node that's currently on top of
+ * mStack.
+ *
+ * @param aMsgId the id of the message in the property file
+ */
+ void AddErrorToCurrentNode(const char* aMsgId);
+
+ /**
+ * Adds an error annotation to the node that corresponds to the most
+ * recently opened markup declaration/tag span, character reference or
+ * run of text.
+ *
+ * @param aMsgId the id of the message in the property file
+ */
+ void AddErrorToCurrentRun(const char* aMsgId);
+
+ /**
+ * Adds an error annotation to the node that corresponds to the most
+ * recently opened markup declaration/tag span, character reference or
+ * run of text with one atom to use when formatting the message.
+ *
+ * @param aMsgId the id of the message in the property file
+ * @param aName the atom
+ */
+ void AddErrorToCurrentRun(const char* aMsgId, nsIAtom* aName);
+
+ /**
+ * Adds an error annotation to the node that corresponds to the most
+ * recently opened markup declaration/tag span, character reference or
+ * run of text with two atoms to use when formatting the message.
+ *
+ * @param aMsgId the id of the message in the property file
+ * @param aName the first atom
+ * @param aOther the second atom
+ */
+ void AddErrorToCurrentRun(const char* aMsgId,
+ nsIAtom* aName,
+ nsIAtom* aOther);
+
+ /**
+ * Adds an error annotation to the node that corresponds to the most
+ * recent potentially character reference-starting ampersand.
+ *
+ * @param aMsgId the id of the message in the property file
+ */
+ void AddErrorToCurrentAmpersand(const char* aMsgId);
+
+ /**
+ * Adds an error annotation to the node that corresponds to the most
+ * recent potentially self-closing slash.
+ *
+ * @param aMsgId the id of the message in the property file
+ */
+ void AddErrorToCurrentSlash(const char* aMsgId);
+
+ /**
+ * Enqueues a tree op for adding base to the urls with the view-source:
+ *
+ * @param aValue the base URL to add
+ */
+ void AddBase(const nsString& aValue);
+
+ private:
+
+ /**
+ * Starts a span with no class.
+ */
+ void StartSpan();
+
+ /**
+ * Starts a <span> and sets the class attribute on it.
+ *
+ * @param aClass the class to set (MUST be a static string that does not
+ * need to be released!)
+ */
+ void StartSpan(const char16_t* aClass);
+
+ /**
+ * End the current <span> or <a> in the highlighter output.
+ */
+ void EndSpanOrA();
+
+ /**
+ * Starts a wrapper around a run of characters.
+ */
+ void StartCharacters();
+
+ /**
+ * Ends a wrapper around a run of characters.
+ */
+ void EndCharactersAndStartMarkupRun();
+
+ /**
+ * Starts an <a>.
+ */
+ void StartA();
+
+ /**
+ * Flushes characters up to but not including the current one.
+ */
+ void FlushChars();
+
+ /**
+ * Flushes characters up to and including the current one.
+ */
+ void FlushCurrent();
+
+ /**
+ * Finishes highlighting a tag in the input data by closing the open
+ * <span> and <a> elements in the highlighter output and then starts
+ * another <span> for potentially highlighting characters potentially
+ * appearing next.
+ */
+ void FinishTag();
+
+ /**
+ * Adds a class attribute to the current node.
+ *
+ * @param aClass the class to set (MUST be a static string that does not
+ * need to be released!)
+ */
+ void AddClass(const char16_t* aClass);
+
+ /**
+ * Allocates a handle for an element.
+ *
+ * See the documentation for nsHtml5TreeBuilder::AllocateContentHandle()
+ * in nsHtml5TreeBuilderHSupplement.h.
+ *
+ * @return the handle
+ */
+ nsIContent** AllocateContentHandle();
+
+ /**
+ * Enqueues an element creation tree operation.
+ *
+ * @param aName the name of the element
+ * @param aAttributes the attribute holder (ownership will be taken) or
+ * nullptr for no attributes
+ * @param aIntendedParent the intended parent node for the created element
+ * @return the handle for the element that will be created
+ */
+ nsIContent** CreateElement(nsIAtom* aName,
+ nsHtml5HtmlAttributes* aAttributes,
+ nsIContent** aIntendedParent);
+
+ /**
+ * Gets the handle for the current node. May be called only after the
+ * root element has been set.
+ *
+ * @return the handle for the current node
+ */
+ nsIContent** CurrentNode();
+
+ /**
+ * Create an element and push it (its handle) on the stack.
+ *
+ * @param aName the name of the element
+ * @param aAttributes the attribute holder (ownership will be taken) or
+ * nullptr for no attributes
+ */
+ void Push(nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes);
+
+ /**
+ * Pops the current node off the stack.
+ */
+ void Pop();
+
+ /**
+ * Appends text content to the current node.
+ *
+ * @param aBuffer the buffer to copy from
+ * @param aStart the index of the first code unit to copy
+ * @param aLength the number of code units to copy
+ */
+ void AppendCharacters(const char16_t* aBuffer,
+ int32_t aStart,
+ int32_t aLength);
+
+ /**
+ * Enqueues a tree op for adding an href attribute with the view-source:
+ * URL scheme to the current node.
+ *
+ * @param aValue the (potentially relative) URL to link to
+ */
+ void AddViewSourceHref(const nsString& aValue);
+
+ /**
+ * The state we are transitioning away from.
+ */
+ int32_t mState;
+
+ /**
+ * The index of the first UTF-16 code unit in mBuffer that hasn't been
+ * flushed yet.
+ */
+ int32_t mCStart;
+
+ /**
+ * The position of the code unit in mBuffer that caused the current
+ * transition.
+ */
+ int32_t mPos;
+
+ /**
+ * The current line number.
+ */
+ int32_t mLineNumber;
+
+ /**
+ * The number of inline elements open inside the <pre> excluding the
+ * span potentially wrapping a run of characters.
+ */
+ int32_t mInlinesOpen;
+
+ /**
+ * Whether there's a span wrapping a run of characters (excluding CDATA
+ * section) open.
+ */
+ bool mInCharacters;
+
+ /**
+ * The current buffer being tokenized.
+ */
+ nsHtml5UTF16Buffer* mBuffer;
+
+ /**
+ * The outgoing tree op queue.
+ */
+ nsTArray<nsHtml5TreeOperation> mOpQueue;
+
+ /**
+ * The tree op stage for the tree op executor.
+ */
+ nsAHtml5TreeOpSink* mOpSink;
+
+ /**
+ * The most recently opened markup declaration/tag or run of characters.
+ */
+ nsIContent** mCurrentRun;
+
+ /**
+ * The most recent ampersand in a place where character references were
+ * allowed.
+ */
+ nsIContent** mAmpersand;
+
+ /**
+ * The most recent slash that might become a self-closing slash.
+ */
+ nsIContent** mSlash;
+
+ /**
+ * Memory for element handles.
+ */
+ mozilla::UniquePtr<nsIContent*[]> mHandles;
+
+ /**
+ * Number of handles used in mHandles
+ */
+ int32_t mHandlesUsed;
+
+ /**
+ * A holder for old contents of mHandles
+ */
+ nsTArray<mozilla::UniquePtr<nsIContent*[]>> mOldHandles;
+
+ /**
+ * The element stack.
+ */
+ nsTArray<nsIContent**> mStack;
+
+ /**
+ * The string "comment"
+ */
+ static char16_t sComment[];
+
+ /**
+ * The string "cdata"
+ */
+ static char16_t sCdata[];
+
+ /**
+ * The string "start-tag"
+ */
+ static char16_t sStartTag[];
+
+ /**
+ * The string "attribute-name"
+ */
+ static char16_t sAttributeName[];
+
+ /**
+ * The string "attribute-value"
+ */
+ static char16_t sAttributeValue[];
+
+ /**
+ * The string "end-tag"
+ */
+ static char16_t sEndTag[];
+
+ /**
+ * The string "doctype"
+ */
+ static char16_t sDoctype[];
+
+ /**
+ * The string "entity"
+ */
+ static char16_t sEntity[];
+
+ /**
+ * The string "pi"
+ */
+ static char16_t sPi[];
+
+ /**
+ * Whether base is already visited once.
+ */
+ bool mSeenBase;
+};
+
+#endif // nsHtml5Highlighter_h
diff --git a/parser/html/nsHtml5HtmlAttributes.cpp b/parser/html/nsHtml5HtmlAttributes.cpp
new file mode 100644
index 000000000..d515f381d
--- /dev/null
+++ b/parser/html/nsHtml5HtmlAttributes.cpp
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 2008-2011 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit HtmlAttributes.java instead and regenerate.
+ */
+
+#define nsHtml5HtmlAttributes_cpp__
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5ByteReadable.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
+
+#include "nsHtml5Tokenizer.h"
+#include "nsHtml5TreeBuilder.h"
+#include "nsHtml5MetaScanner.h"
+#include "nsHtml5AttributeName.h"
+#include "nsHtml5ElementName.h"
+#include "nsHtml5StackNode.h"
+#include "nsHtml5UTF16Buffer.h"
+#include "nsHtml5StateSnapshot.h"
+#include "nsHtml5Portability.h"
+
+#include "nsHtml5HtmlAttributes.h"
+
+nsHtml5HtmlAttributes* nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES = nullptr;
+
+nsHtml5HtmlAttributes::nsHtml5HtmlAttributes(int32_t mode)
+ : mode(mode),
+ length(0),
+ names(jArray<nsHtml5AttributeName*,int32_t>::newJArray(8)),
+ values(jArray<nsString*,int32_t>::newJArray(8)),
+ lines(jArray<int32_t,int32_t>::newJArray(8))
+{
+ MOZ_COUNT_CTOR(nsHtml5HtmlAttributes);
+}
+
+
+nsHtml5HtmlAttributes::~nsHtml5HtmlAttributes()
+{
+ MOZ_COUNT_DTOR(nsHtml5HtmlAttributes);
+ clear(0);
+}
+
+int32_t
+nsHtml5HtmlAttributes::getIndex(nsHtml5AttributeName* name)
+{
+ for (int32_t i = 0; i < length; i++) {
+ if (names[i] == name) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+nsString*
+nsHtml5HtmlAttributes::getValue(nsHtml5AttributeName* name)
+{
+ int32_t index = getIndex(name);
+ if (index == -1) {
+ return nullptr;
+ } else {
+ return getValueNoBoundsCheck(index);
+ }
+}
+
+int32_t
+nsHtml5HtmlAttributes::getLength()
+{
+ return length;
+}
+
+nsIAtom*
+nsHtml5HtmlAttributes::getLocalNameNoBoundsCheck(int32_t index)
+{
+ MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
+ return names[index]->getLocal(mode);
+}
+
+int32_t
+nsHtml5HtmlAttributes::getURINoBoundsCheck(int32_t index)
+{
+ MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
+ return names[index]->getUri(mode);
+}
+
+nsIAtom*
+nsHtml5HtmlAttributes::getPrefixNoBoundsCheck(int32_t index)
+{
+ MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
+ return names[index]->getPrefix(mode);
+}
+
+nsString*
+nsHtml5HtmlAttributes::getValueNoBoundsCheck(int32_t index)
+{
+ MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
+ return values[index];
+}
+
+nsHtml5AttributeName*
+nsHtml5HtmlAttributes::getAttributeNameNoBoundsCheck(int32_t index)
+{
+ MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
+ return names[index];
+}
+
+int32_t
+nsHtml5HtmlAttributes::getLineNoBoundsCheck(int32_t index)
+{
+ MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
+ return lines[index];
+}
+
+void
+nsHtml5HtmlAttributes::addAttribute(nsHtml5AttributeName* name, nsString* value, int32_t line)
+{
+ if (names.length == length) {
+ int32_t newLen = length << 1;
+ jArray<nsHtml5AttributeName*,int32_t> newNames = jArray<nsHtml5AttributeName*,int32_t>::newJArray(newLen);
+ nsHtml5ArrayCopy::arraycopy(names, newNames, names.length);
+ names = newNames;
+ jArray<nsString*,int32_t> newValues = jArray<nsString*,int32_t>::newJArray(newLen);
+ nsHtml5ArrayCopy::arraycopy(values, newValues, values.length);
+ values = newValues;
+ jArray<int32_t,int32_t> newLines = jArray<int32_t,int32_t>::newJArray(newLen);
+ nsHtml5ArrayCopy::arraycopy(lines, newLines, lines.length);
+ lines = newLines;
+ }
+ names[length] = name;
+ values[length] = value;
+ lines[length] = line;
+ length++;
+}
+
+void
+nsHtml5HtmlAttributes::clear(int32_t m)
+{
+ for (int32_t i = 0; i < length; i++) {
+ names[i]->release();
+ names[i] = nullptr;
+ nsHtml5Portability::releaseString(values[i]);
+ values[i] = nullptr;
+ }
+ length = 0;
+ mode = m;
+}
+
+void
+nsHtml5HtmlAttributes::releaseValue(int32_t i)
+{
+ nsHtml5Portability::releaseString(values[i]);
+}
+
+void
+nsHtml5HtmlAttributes::clearWithoutReleasingContents()
+{
+ for (int32_t i = 0; i < length; i++) {
+ names[i] = nullptr;
+ values[i] = nullptr;
+ }
+ length = 0;
+}
+
+bool
+nsHtml5HtmlAttributes::contains(nsHtml5AttributeName* name)
+{
+ for (int32_t i = 0; i < length; i++) {
+ if (name->equalsAnother(names[i])) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void
+nsHtml5HtmlAttributes::adjustForMath()
+{
+ mode = NS_HTML5ATTRIBUTE_NAME_MATHML;
+}
+
+void
+nsHtml5HtmlAttributes::adjustForSvg()
+{
+ mode = NS_HTML5ATTRIBUTE_NAME_SVG;
+}
+
+nsHtml5HtmlAttributes*
+nsHtml5HtmlAttributes::cloneAttributes(nsHtml5AtomTable* interner)
+{
+ MOZ_ASSERT((!length) || !mode || mode == 3);
+ nsHtml5HtmlAttributes* clone = new nsHtml5HtmlAttributes(0);
+ for (int32_t i = 0; i < length; i++) {
+ clone->addAttribute(names[i]->cloneAttributeName(interner), nsHtml5Portability::newStringFromString(values[i]), lines[i]);
+ }
+ return clone;
+}
+
+bool
+nsHtml5HtmlAttributes::equalsAnother(nsHtml5HtmlAttributes* other)
+{
+ MOZ_ASSERT(!mode || mode == 3, "Trying to compare attributes in foreign content.");
+ int32_t otherLength = other->getLength();
+ if (length != otherLength) {
+ return false;
+ }
+ for (int32_t i = 0; i < length; i++) {
+ bool found = false;
+ nsIAtom* ownLocal = names[i]->getLocal(NS_HTML5ATTRIBUTE_NAME_HTML);
+ for (int32_t j = 0; j < otherLength; j++) {
+ if (ownLocal == other->names[j]->getLocal(NS_HTML5ATTRIBUTE_NAME_HTML)) {
+ found = true;
+ if (!nsHtml5Portability::stringEqualsString(values[i], other->values[j])) {
+ return false;
+ }
+ }
+ }
+ if (!found) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void
+nsHtml5HtmlAttributes::initializeStatics()
+{
+ EMPTY_ATTRIBUTES = new nsHtml5HtmlAttributes(NS_HTML5ATTRIBUTE_NAME_HTML);
+}
+
+void
+nsHtml5HtmlAttributes::releaseStatics()
+{
+ delete EMPTY_ATTRIBUTES;
+}
+
+
diff --git a/parser/html/nsHtml5HtmlAttributes.h b/parser/html/nsHtml5HtmlAttributes.h
new file mode 100644
index 000000000..c02d0a08c
--- /dev/null
+++ b/parser/html/nsHtml5HtmlAttributes.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 2008-2011 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit HtmlAttributes.java instead and regenerate.
+ */
+
+#ifndef nsHtml5HtmlAttributes_h
+#define nsHtml5HtmlAttributes_h
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5ByteReadable.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
+
+class nsHtml5StreamParser;
+
+class nsHtml5Tokenizer;
+class nsHtml5TreeBuilder;
+class nsHtml5MetaScanner;
+class nsHtml5AttributeName;
+class nsHtml5ElementName;
+class nsHtml5UTF16Buffer;
+class nsHtml5StateSnapshot;
+class nsHtml5Portability;
+
+
+class nsHtml5HtmlAttributes
+{
+ public:
+ static nsHtml5HtmlAttributes* EMPTY_ATTRIBUTES;
+ private:
+ int32_t mode;
+ int32_t length;
+ autoJArray<nsHtml5AttributeName*,int32_t> names;
+ autoJArray<nsString*,int32_t> values;
+ autoJArray<int32_t,int32_t> lines;
+ public:
+ explicit nsHtml5HtmlAttributes(int32_t mode);
+ ~nsHtml5HtmlAttributes();
+ int32_t getIndex(nsHtml5AttributeName* name);
+ nsString* getValue(nsHtml5AttributeName* name);
+ int32_t getLength();
+ nsIAtom* getLocalNameNoBoundsCheck(int32_t index);
+ int32_t getURINoBoundsCheck(int32_t index);
+ nsIAtom* getPrefixNoBoundsCheck(int32_t index);
+ nsString* getValueNoBoundsCheck(int32_t index);
+ nsHtml5AttributeName* getAttributeNameNoBoundsCheck(int32_t index);
+ int32_t getLineNoBoundsCheck(int32_t index);
+ void addAttribute(nsHtml5AttributeName* name, nsString* value, int32_t line);
+ void clear(int32_t m);
+ void releaseValue(int32_t i);
+ void clearWithoutReleasingContents();
+ bool contains(nsHtml5AttributeName* name);
+ void adjustForMath();
+ void adjustForSvg();
+ nsHtml5HtmlAttributes* cloneAttributes(nsHtml5AtomTable* interner);
+ bool equalsAnother(nsHtml5HtmlAttributes* other);
+ static void initializeStatics();
+ static void releaseStatics();
+};
+
+
+
+#endif
+
diff --git a/parser/html/nsHtml5Macros.h b/parser/html/nsHtml5Macros.h
new file mode 100644
index 000000000..5abc848b9
--- /dev/null
+++ b/parser/html/nsHtml5Macros.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef nsHtml5Macros_h
+#define nsHtml5Macros_h
+
+#define NS_HTML5_CONTINUE(target) \
+ goto target
+
+#define NS_HTML5_BREAK(target) \
+ goto target ## _end
+
+#endif /* nsHtml5Macros_h */
diff --git a/parser/html/nsHtml5MetaScanner.cpp b/parser/html/nsHtml5MetaScanner.cpp
new file mode 100644
index 000000000..d39eacd9b
--- /dev/null
+++ b/parser/html/nsHtml5MetaScanner.cpp
@@ -0,0 +1,812 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 2008-2015 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit MetaScanner.java instead and regenerate.
+ */
+
+#define nsHtml5MetaScanner_cpp__
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5ByteReadable.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
+
+#include "nsHtml5Tokenizer.h"
+#include "nsHtml5TreeBuilder.h"
+#include "nsHtml5AttributeName.h"
+#include "nsHtml5ElementName.h"
+#include "nsHtml5HtmlAttributes.h"
+#include "nsHtml5StackNode.h"
+#include "nsHtml5UTF16Buffer.h"
+#include "nsHtml5StateSnapshot.h"
+#include "nsHtml5Portability.h"
+
+#include "nsHtml5MetaScanner.h"
+
+static char16_t const CHARSET_DATA[] = { 'h', 'a', 'r', 's', 'e', 't' };
+staticJArray<char16_t,int32_t> nsHtml5MetaScanner::CHARSET = { CHARSET_DATA, MOZ_ARRAY_LENGTH(CHARSET_DATA) };
+static char16_t const CONTENT_DATA[] = { 'o', 'n', 't', 'e', 'n', 't' };
+staticJArray<char16_t,int32_t> nsHtml5MetaScanner::CONTENT = { CONTENT_DATA, MOZ_ARRAY_LENGTH(CONTENT_DATA) };
+static char16_t const HTTP_EQUIV_DATA[] = { 't', 't', 'p', '-', 'e', 'q', 'u', 'i', 'v' };
+staticJArray<char16_t,int32_t> nsHtml5MetaScanner::HTTP_EQUIV = { HTTP_EQUIV_DATA, MOZ_ARRAY_LENGTH(HTTP_EQUIV_DATA) };
+static char16_t const CONTENT_TYPE_DATA[] = { 'c', 'o', 'n', 't', 'e', 'n', 't', '-', 't', 'y', 'p', 'e' };
+staticJArray<char16_t,int32_t> nsHtml5MetaScanner::CONTENT_TYPE = { CONTENT_TYPE_DATA, MOZ_ARRAY_LENGTH(CONTENT_TYPE_DATA) };
+
+nsHtml5MetaScanner::nsHtml5MetaScanner(nsHtml5TreeBuilder* tb)
+ : readable(nullptr),
+ metaState(NS_HTML5META_SCANNER_NO),
+ contentIndex(INT32_MAX),
+ charsetIndex(INT32_MAX),
+ httpEquivIndex(INT32_MAX),
+ contentTypeIndex(INT32_MAX),
+ stateSave(NS_HTML5META_SCANNER_DATA),
+ strBufLen(0),
+ strBuf(jArray<char16_t,int32_t>::newJArray(36)),
+ content(nullptr),
+ charset(nullptr),
+ httpEquivState(NS_HTML5META_SCANNER_HTTP_EQUIV_NOT_SEEN),
+ treeBuilder(tb)
+{
+ MOZ_COUNT_CTOR(nsHtml5MetaScanner);
+}
+
+
+nsHtml5MetaScanner::~nsHtml5MetaScanner()
+{
+ MOZ_COUNT_DTOR(nsHtml5MetaScanner);
+ nsHtml5Portability::releaseString(content);
+ nsHtml5Portability::releaseString(charset);
+}
+
+void
+nsHtml5MetaScanner::stateLoop(int32_t state)
+{
+ int32_t c = -1;
+ bool reconsume = false;
+ stateloop: for (; ; ) {
+ switch(state) {
+ case NS_HTML5META_SCANNER_DATA: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ c = read();
+ }
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '<': {
+ state = NS_HTML5META_SCANNER_TAG_OPEN;
+ NS_HTML5_BREAK(dataloop);
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+ dataloop_end: ;
+ }
+ case NS_HTML5META_SCANNER_TAG_OPEN: {
+ for (; ; ) {
+ c = read();
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case 'm':
+ case 'M': {
+ metaState = NS_HTML5META_SCANNER_M;
+ state = NS_HTML5META_SCANNER_TAG_NAME;
+ NS_HTML5_BREAK(tagopenloop);
+ }
+ case '!': {
+ state = NS_HTML5META_SCANNER_MARKUP_DECLARATION_OPEN;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\?':
+ case '/': {
+ state = NS_HTML5META_SCANNER_SCAN_UNTIL_GT;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ state = NS_HTML5META_SCANNER_DATA;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
+ metaState = NS_HTML5META_SCANNER_NO;
+ state = NS_HTML5META_SCANNER_TAG_NAME;
+ NS_HTML5_BREAK(tagopenloop);
+ }
+ state = NS_HTML5META_SCANNER_DATA;
+ reconsume = true;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ tagopenloop_end: ;
+ }
+ case NS_HTML5META_SCANNER_TAG_NAME: {
+ for (; ; ) {
+ c = read();
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\f': {
+ state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME;
+ NS_HTML5_BREAK(tagnameloop);
+ }
+ case '/': {
+ state = NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ state = NS_HTML5META_SCANNER_DATA;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case 'e':
+ case 'E': {
+ if (metaState == NS_HTML5META_SCANNER_M) {
+ metaState = NS_HTML5META_SCANNER_E;
+ } else {
+ metaState = NS_HTML5META_SCANNER_NO;
+ }
+ continue;
+ }
+ case 't':
+ case 'T': {
+ if (metaState == NS_HTML5META_SCANNER_E) {
+ metaState = NS_HTML5META_SCANNER_T;
+ } else {
+ metaState = NS_HTML5META_SCANNER_NO;
+ }
+ continue;
+ }
+ case 'a':
+ case 'A': {
+ if (metaState == NS_HTML5META_SCANNER_T) {
+ metaState = NS_HTML5META_SCANNER_A;
+ } else {
+ metaState = NS_HTML5META_SCANNER_NO;
+ }
+ continue;
+ }
+ default: {
+ metaState = NS_HTML5META_SCANNER_NO;
+ continue;
+ }
+ }
+ }
+ tagnameloop_end: ;
+ }
+ case NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ c = read();
+ }
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\f': {
+ continue;
+ }
+ case '/': {
+ state = NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ if (handleTag()) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ state = NS_HTML5META_SCANNER_DATA;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case 'c':
+ case 'C': {
+ contentIndex = 0;
+ charsetIndex = 0;
+ httpEquivIndex = INT32_MAX;
+ contentTypeIndex = INT32_MAX;
+ state = NS_HTML5META_SCANNER_ATTRIBUTE_NAME;
+ NS_HTML5_BREAK(beforeattributenameloop);
+ }
+ case 'h':
+ case 'H': {
+ contentIndex = INT32_MAX;
+ charsetIndex = INT32_MAX;
+ httpEquivIndex = 0;
+ contentTypeIndex = INT32_MAX;
+ state = NS_HTML5META_SCANNER_ATTRIBUTE_NAME;
+ NS_HTML5_BREAK(beforeattributenameloop);
+ }
+ default: {
+ contentIndex = INT32_MAX;
+ charsetIndex = INT32_MAX;
+ httpEquivIndex = INT32_MAX;
+ contentTypeIndex = INT32_MAX;
+ state = NS_HTML5META_SCANNER_ATTRIBUTE_NAME;
+ NS_HTML5_BREAK(beforeattributenameloop);
+ }
+ }
+ }
+ beforeattributenameloop_end: ;
+ }
+ case NS_HTML5META_SCANNER_ATTRIBUTE_NAME: {
+ for (; ; ) {
+ c = read();
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\f': {
+ state = NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_NAME;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '/': {
+ state = NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '=': {
+ strBufLen = 0;
+ contentTypeIndex = 0;
+ state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_VALUE;
+ NS_HTML5_BREAK(attributenameloop);
+ }
+ case '>': {
+ if (handleTag()) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ state = NS_HTML5META_SCANNER_DATA;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ if (metaState == NS_HTML5META_SCANNER_A) {
+ if (c >= 'A' && c <= 'Z') {
+ c += 0x20;
+ }
+ if (contentIndex < CONTENT.length && c == CONTENT[contentIndex]) {
+ ++contentIndex;
+ } else {
+ contentIndex = INT32_MAX;
+ }
+ if (charsetIndex < CHARSET.length && c == CHARSET[charsetIndex]) {
+ ++charsetIndex;
+ } else {
+ charsetIndex = INT32_MAX;
+ }
+ if (httpEquivIndex < HTTP_EQUIV.length && c == HTTP_EQUIV[httpEquivIndex]) {
+ ++httpEquivIndex;
+ } else {
+ httpEquivIndex = INT32_MAX;
+ }
+ }
+ continue;
+ }
+ }
+ }
+ attributenameloop_end: ;
+ }
+ case NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_VALUE: {
+ for (; ; ) {
+ c = read();
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\f': {
+ continue;
+ }
+ case '\"': {
+ state = NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_DOUBLE_QUOTED;
+ NS_HTML5_BREAK(beforeattributevalueloop);
+ }
+ case '\'': {
+ state = NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_SINGLE_QUOTED;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ if (handleTag()) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ state = NS_HTML5META_SCANNER_DATA;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ handleCharInAttributeValue(c);
+ state = NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_UNQUOTED;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ beforeattributevalueloop_end: ;
+ }
+ case NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ c = read();
+ }
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\"': {
+ handleAttributeValue();
+ state = NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_VALUE_QUOTED;
+ NS_HTML5_BREAK(attributevaluedoublequotedloop);
+ }
+ default: {
+ handleCharInAttributeValue(c);
+ continue;
+ }
+ }
+ }
+ attributevaluedoublequotedloop_end: ;
+ }
+ case NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_VALUE_QUOTED: {
+ for (; ; ) {
+ c = read();
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\f': {
+ state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '/': {
+ state = NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG;
+ NS_HTML5_BREAK(afterattributevaluequotedloop);
+ }
+ case '>': {
+ if (handleTag()) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ state = NS_HTML5META_SCANNER_DATA;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME;
+ reconsume = true;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ afterattributevaluequotedloop_end: ;
+ }
+ case NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG: {
+ c = read();
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '>': {
+ if (handleTag()) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ state = NS_HTML5META_SCANNER_DATA;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME;
+ reconsume = true;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ case NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_UNQUOTED: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ c = read();
+ }
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\f': {
+ handleAttributeValue();
+ state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ handleAttributeValue();
+ if (handleTag()) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ state = NS_HTML5META_SCANNER_DATA;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ handleCharInAttributeValue(c);
+ continue;
+ }
+ }
+ }
+ }
+ case NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_NAME: {
+ for (; ; ) {
+ c = read();
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\f': {
+ continue;
+ }
+ case '/': {
+ handleAttributeValue();
+ state = NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '=': {
+ strBufLen = 0;
+ contentTypeIndex = 0;
+ state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_VALUE;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ handleAttributeValue();
+ if (handleTag()) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ state = NS_HTML5META_SCANNER_DATA;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case 'c':
+ case 'C': {
+ contentIndex = 0;
+ charsetIndex = 0;
+ state = NS_HTML5META_SCANNER_ATTRIBUTE_NAME;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ contentIndex = INT32_MAX;
+ charsetIndex = INT32_MAX;
+ state = NS_HTML5META_SCANNER_ATTRIBUTE_NAME;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ }
+ case NS_HTML5META_SCANNER_MARKUP_DECLARATION_OPEN: {
+ for (; ; ) {
+ c = read();
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '-': {
+ state = NS_HTML5META_SCANNER_MARKUP_DECLARATION_HYPHEN;
+ NS_HTML5_BREAK(markupdeclarationopenloop);
+ }
+ default: {
+ state = NS_HTML5META_SCANNER_SCAN_UNTIL_GT;
+ reconsume = true;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ markupdeclarationopenloop_end: ;
+ }
+ case NS_HTML5META_SCANNER_MARKUP_DECLARATION_HYPHEN: {
+ for (; ; ) {
+ c = read();
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '-': {
+ state = NS_HTML5META_SCANNER_COMMENT_START;
+ NS_HTML5_BREAK(markupdeclarationhyphenloop);
+ }
+ default: {
+ state = NS_HTML5META_SCANNER_SCAN_UNTIL_GT;
+ reconsume = true;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ markupdeclarationhyphenloop_end: ;
+ }
+ case NS_HTML5META_SCANNER_COMMENT_START: {
+ for (; ; ) {
+ c = read();
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '-': {
+ state = NS_HTML5META_SCANNER_COMMENT_START_DASH;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ state = NS_HTML5META_SCANNER_DATA;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ state = NS_HTML5META_SCANNER_COMMENT;
+ NS_HTML5_BREAK(commentstartloop);
+ }
+ }
+ }
+ commentstartloop_end: ;
+ }
+ case NS_HTML5META_SCANNER_COMMENT: {
+ for (; ; ) {
+ c = read();
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '-': {
+ state = NS_HTML5META_SCANNER_COMMENT_END_DASH;
+ NS_HTML5_BREAK(commentloop);
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+ commentloop_end: ;
+ }
+ case NS_HTML5META_SCANNER_COMMENT_END_DASH: {
+ for (; ; ) {
+ c = read();
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '-': {
+ state = NS_HTML5META_SCANNER_COMMENT_END;
+ NS_HTML5_BREAK(commentenddashloop);
+ }
+ default: {
+ state = NS_HTML5META_SCANNER_COMMENT;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ commentenddashloop_end: ;
+ }
+ case NS_HTML5META_SCANNER_COMMENT_END: {
+ for (; ; ) {
+ c = read();
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '>': {
+ state = NS_HTML5META_SCANNER_DATA;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '-': {
+ continue;
+ }
+ default: {
+ state = NS_HTML5META_SCANNER_COMMENT;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ }
+ case NS_HTML5META_SCANNER_COMMENT_START_DASH: {
+ c = read();
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '-': {
+ state = NS_HTML5META_SCANNER_COMMENT_END;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ state = NS_HTML5META_SCANNER_DATA;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ state = NS_HTML5META_SCANNER_COMMENT;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ case NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_SINGLE_QUOTED: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ c = read();
+ }
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\'': {
+ handleAttributeValue();
+ state = NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_VALUE_QUOTED;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ handleCharInAttributeValue(c);
+ continue;
+ }
+ }
+ }
+ }
+ case NS_HTML5META_SCANNER_SCAN_UNTIL_GT: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ c = read();
+ }
+ switch(c) {
+ case -1: {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '>': {
+ state = NS_HTML5META_SCANNER_DATA;
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+ }
+ }
+ }
+ stateloop_end: ;
+ stateSave = state;
+}
+
+void
+nsHtml5MetaScanner::handleCharInAttributeValue(int32_t c)
+{
+ if (metaState == NS_HTML5META_SCANNER_A) {
+ if (contentIndex == CONTENT.length || charsetIndex == CHARSET.length) {
+ addToBuffer(c);
+ } else if (httpEquivIndex == HTTP_EQUIV.length) {
+ if (contentTypeIndex < CONTENT_TYPE.length && toAsciiLowerCase(c) == CONTENT_TYPE[contentTypeIndex]) {
+ ++contentTypeIndex;
+ } else {
+ contentTypeIndex = INT32_MAX;
+ }
+ }
+ }
+}
+
+void
+nsHtml5MetaScanner::addToBuffer(int32_t c)
+{
+ if (strBufLen == strBuf.length) {
+ jArray<char16_t,int32_t> newBuf = jArray<char16_t,int32_t>::newJArray(strBuf.length + (strBuf.length << 1));
+ nsHtml5ArrayCopy::arraycopy(strBuf, newBuf, strBuf.length);
+ strBuf = newBuf;
+ }
+ strBuf[strBufLen++] = (char16_t) c;
+}
+
+void
+nsHtml5MetaScanner::handleAttributeValue()
+{
+ if (metaState != NS_HTML5META_SCANNER_A) {
+ return;
+ }
+ if (contentIndex == CONTENT.length && !content) {
+ content = nsHtml5Portability::newStringFromBuffer(strBuf, 0, strBufLen, treeBuilder);
+ return;
+ }
+ if (charsetIndex == CHARSET.length && !charset) {
+ charset = nsHtml5Portability::newStringFromBuffer(strBuf, 0, strBufLen, treeBuilder);
+ return;
+ }
+ if (httpEquivIndex == HTTP_EQUIV.length && httpEquivState == NS_HTML5META_SCANNER_HTTP_EQUIV_NOT_SEEN) {
+ httpEquivState = (contentTypeIndex == CONTENT_TYPE.length) ? NS_HTML5META_SCANNER_HTTP_EQUIV_CONTENT_TYPE : NS_HTML5META_SCANNER_HTTP_EQUIV_OTHER;
+ return;
+ }
+}
+
+bool
+nsHtml5MetaScanner::handleTag()
+{
+ bool stop = handleTagInner();
+ nsHtml5Portability::releaseString(content);
+ content = nullptr;
+ nsHtml5Portability::releaseString(charset);
+ charset = nullptr;
+ httpEquivState = NS_HTML5META_SCANNER_HTTP_EQUIV_NOT_SEEN;
+ return stop;
+}
+
+bool
+nsHtml5MetaScanner::handleTagInner()
+{
+ if (!!charset && tryCharset(charset)) {
+ return true;
+ }
+ if (!!content && httpEquivState == NS_HTML5META_SCANNER_HTTP_EQUIV_CONTENT_TYPE) {
+ nsString* extract = nsHtml5TreeBuilder::extractCharsetFromContent(content, treeBuilder);
+ if (!extract) {
+ return false;
+ }
+ bool success = tryCharset(extract);
+ nsHtml5Portability::releaseString(extract);
+ return success;
+ }
+ return false;
+}
+
+void
+nsHtml5MetaScanner::initializeStatics()
+{
+}
+
+void
+nsHtml5MetaScanner::releaseStatics()
+{
+}
+
+
+#include "nsHtml5MetaScannerCppSupplement.h"
+
diff --git a/parser/html/nsHtml5MetaScanner.h b/parser/html/nsHtml5MetaScanner.h
new file mode 100644
index 000000000..4e0ad7647
--- /dev/null
+++ b/parser/html/nsHtml5MetaScanner.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 2008-2015 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit MetaScanner.java instead and regenerate.
+ */
+
+#ifndef nsHtml5MetaScanner_h
+#define nsHtml5MetaScanner_h
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5ByteReadable.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
+
+class nsHtml5StreamParser;
+
+class nsHtml5Tokenizer;
+class nsHtml5TreeBuilder;
+class nsHtml5AttributeName;
+class nsHtml5ElementName;
+class nsHtml5HtmlAttributes;
+class nsHtml5UTF16Buffer;
+class nsHtml5StateSnapshot;
+class nsHtml5Portability;
+
+
+class nsHtml5MetaScanner
+{
+ private:
+ static staticJArray<char16_t,int32_t> CHARSET;
+ static staticJArray<char16_t,int32_t> CONTENT;
+ static staticJArray<char16_t,int32_t> HTTP_EQUIV;
+ static staticJArray<char16_t,int32_t> CONTENT_TYPE;
+ protected:
+ nsHtml5ByteReadable* readable;
+ private:
+ int32_t metaState;
+ int32_t contentIndex;
+ int32_t charsetIndex;
+ int32_t httpEquivIndex;
+ int32_t contentTypeIndex;
+ protected:
+ int32_t stateSave;
+ private:
+ int32_t strBufLen;
+ autoJArray<char16_t,int32_t> strBuf;
+ nsString* content;
+ nsString* charset;
+ int32_t httpEquivState;
+ nsHtml5TreeBuilder* treeBuilder;
+ public:
+ explicit nsHtml5MetaScanner(nsHtml5TreeBuilder* tb);
+ ~nsHtml5MetaScanner();
+ protected:
+ void stateLoop(int32_t state);
+ private:
+ void handleCharInAttributeValue(int32_t c);
+ inline int32_t toAsciiLowerCase(int32_t c)
+ {
+ if (c >= 'A' && c <= 'Z') {
+ return c + 0x20;
+ }
+ return c;
+ }
+
+ void addToBuffer(int32_t c);
+ void handleAttributeValue();
+ bool handleTag();
+ bool handleTagInner();
+ protected:
+ bool tryCharset(nsString* encoding);
+ public:
+ static void initializeStatics();
+ static void releaseStatics();
+
+#include "nsHtml5MetaScannerHSupplement.h"
+};
+
+#define NS_HTML5META_SCANNER_NO 0
+#define NS_HTML5META_SCANNER_M 1
+#define NS_HTML5META_SCANNER_E 2
+#define NS_HTML5META_SCANNER_T 3
+#define NS_HTML5META_SCANNER_A 4
+#define NS_HTML5META_SCANNER_DATA 0
+#define NS_HTML5META_SCANNER_TAG_OPEN 1
+#define NS_HTML5META_SCANNER_SCAN_UNTIL_GT 2
+#define NS_HTML5META_SCANNER_TAG_NAME 3
+#define NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME 4
+#define NS_HTML5META_SCANNER_ATTRIBUTE_NAME 5
+#define NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_NAME 6
+#define NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_VALUE 7
+#define NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_DOUBLE_QUOTED 8
+#define NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_SINGLE_QUOTED 9
+#define NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_UNQUOTED 10
+#define NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_VALUE_QUOTED 11
+#define NS_HTML5META_SCANNER_MARKUP_DECLARATION_OPEN 13
+#define NS_HTML5META_SCANNER_MARKUP_DECLARATION_HYPHEN 14
+#define NS_HTML5META_SCANNER_COMMENT_START 15
+#define NS_HTML5META_SCANNER_COMMENT_START_DASH 16
+#define NS_HTML5META_SCANNER_COMMENT 17
+#define NS_HTML5META_SCANNER_COMMENT_END_DASH 18
+#define NS_HTML5META_SCANNER_COMMENT_END 19
+#define NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG 20
+#define NS_HTML5META_SCANNER_HTTP_EQUIV_NOT_SEEN 0
+#define NS_HTML5META_SCANNER_HTTP_EQUIV_CONTENT_TYPE 1
+#define NS_HTML5META_SCANNER_HTTP_EQUIV_OTHER 2
+
+
+#endif
+
diff --git a/parser/html/nsHtml5MetaScannerCppSupplement.h b/parser/html/nsHtml5MetaScannerCppSupplement.h
new file mode 100644
index 000000000..5e7033777
--- /dev/null
+++ b/parser/html/nsHtml5MetaScannerCppSupplement.h
@@ -0,0 +1,45 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsEncoderDecoderUtils.h"
+#include "nsISupportsImpl.h"
+
+#include "mozilla/dom/EncodingUtils.h"
+
+using mozilla::dom::EncodingUtils;
+
+void
+nsHtml5MetaScanner::sniff(nsHtml5ByteReadable* bytes, nsACString& charset)
+{
+ readable = bytes;
+ stateLoop(stateSave);
+ readable = nullptr;
+ charset.Assign(mCharset);
+}
+
+bool
+nsHtml5MetaScanner::tryCharset(nsString* charset)
+{
+ // This code needs to stay in sync with
+ // nsHtml5StreamParser::internalEncodingDeclaration. Unfortunately, the
+ // trickery with member fields here leads to some copy-paste reuse. :-(
+ nsAutoCString label;
+ CopyUTF16toUTF8(*charset, label);
+ nsAutoCString encoding;
+ if (!EncodingUtils::FindEncodingForLabel(label, encoding)) {
+ return false;
+ }
+ if (encoding.EqualsLiteral("UTF-16BE") ||
+ encoding.EqualsLiteral("UTF-16LE")) {
+ mCharset.AssignLiteral("UTF-8");
+ return true;
+ }
+ if (encoding.EqualsLiteral("x-user-defined")) {
+ // WebKit/Blink hack for Indian and Armenian legacy sites
+ mCharset.AssignLiteral("windows-1252");
+ return true;
+ }
+ mCharset.Assign(encoding);
+ return true;
+}
diff --git a/parser/html/nsHtml5MetaScannerHSupplement.h b/parser/html/nsHtml5MetaScannerHSupplement.h
new file mode 100644
index 000000000..b1bcbb671
--- /dev/null
+++ b/parser/html/nsHtml5MetaScannerHSupplement.h
@@ -0,0 +1,12 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+private:
+ nsCString mCharset;
+ inline int32_t read()
+ {
+ return readable->read();
+ }
+public:
+ void sniff(nsHtml5ByteReadable* bytes, nsACString& charset);
diff --git a/parser/html/nsHtml5Module.cpp b/parser/html/nsHtml5Module.cpp
new file mode 100644
index 000000000..cc019d035
--- /dev/null
+++ b/parser/html/nsHtml5Module.cpp
@@ -0,0 +1,137 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5AttributeName.h"
+#include "nsHtml5ElementName.h"
+#include "nsHtml5HtmlAttributes.h"
+#include "nsHtml5NamedCharacters.h"
+#include "nsHtml5Portability.h"
+#include "nsHtml5StackNode.h"
+#include "nsHtml5Tokenizer.h"
+#include "nsHtml5TreeBuilder.h"
+#include "nsHtml5UTF16Buffer.h"
+#include "nsHtml5Module.h"
+#include "nsIObserverService.h"
+#include "nsIServiceManager.h"
+#include "mozilla/Services.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/Attributes.h"
+
+using namespace mozilla;
+
+// static
+bool nsHtml5Module::sOffMainThread = true;
+nsIThread* nsHtml5Module::sStreamParserThread = nullptr;
+nsIThread* nsHtml5Module::sMainThread = nullptr;
+
+// static
+void
+nsHtml5Module::InitializeStatics()
+{
+ Preferences::AddBoolVarCache(&sOffMainThread, "html5.offmainthread");
+ nsHtml5AttributeName::initializeStatics();
+ nsHtml5ElementName::initializeStatics();
+ nsHtml5HtmlAttributes::initializeStatics();
+ nsHtml5NamedCharacters::initializeStatics();
+ nsHtml5Portability::initializeStatics();
+ nsHtml5StackNode::initializeStatics();
+ nsHtml5Tokenizer::initializeStatics();
+ nsHtml5TreeBuilder::initializeStatics();
+ nsHtml5UTF16Buffer::initializeStatics();
+ nsHtml5StreamParser::InitializeStatics();
+ nsHtml5TreeOpExecutor::InitializeStatics();
+#ifdef DEBUG
+ sNsHtml5ModuleInitialized = true;
+#endif
+}
+
+// static
+void
+nsHtml5Module::ReleaseStatics()
+{
+#ifdef DEBUG
+ sNsHtml5ModuleInitialized = false;
+#endif
+ nsHtml5AttributeName::releaseStatics();
+ nsHtml5ElementName::releaseStatics();
+ nsHtml5HtmlAttributes::releaseStatics();
+ nsHtml5NamedCharacters::releaseStatics();
+ nsHtml5Portability::releaseStatics();
+ nsHtml5StackNode::releaseStatics();
+ nsHtml5Tokenizer::releaseStatics();
+ nsHtml5TreeBuilder::releaseStatics();
+ nsHtml5UTF16Buffer::releaseStatics();
+ NS_IF_RELEASE(sStreamParserThread);
+ NS_IF_RELEASE(sMainThread);
+}
+
+// static
+already_AddRefed<nsIParser>
+nsHtml5Module::NewHtml5Parser()
+{
+ MOZ_ASSERT(sNsHtml5ModuleInitialized, "nsHtml5Module not initialized.");
+ nsCOMPtr<nsIParser> rv = new nsHtml5Parser();
+ return rv.forget();
+}
+
+// static
+nsresult
+nsHtml5Module::Initialize(nsIParser* aParser, nsIDocument* aDoc, nsIURI* aURI, nsISupports* aContainer, nsIChannel* aChannel)
+{
+ MOZ_ASSERT(sNsHtml5ModuleInitialized, "nsHtml5Module not initialized.");
+ nsHtml5Parser* parser = static_cast<nsHtml5Parser*> (aParser);
+ return parser->Initialize(aDoc, aURI, aContainer, aChannel);
+}
+
+class nsHtml5ParserThreadTerminator final : public nsIObserver
+{
+ public:
+ NS_DECL_ISUPPORTS
+ explicit nsHtml5ParserThreadTerminator(nsIThread* aThread)
+ : mThread(aThread)
+ {}
+ NS_IMETHOD Observe(nsISupports *, const char *topic, const char16_t *) override
+ {
+ NS_ASSERTION(!strcmp(topic, "xpcom-shutdown-threads"),
+ "Unexpected topic");
+ if (mThread) {
+ mThread->Shutdown();
+ mThread = nullptr;
+ }
+ return NS_OK;
+ }
+ private:
+ ~nsHtml5ParserThreadTerminator() {}
+
+ nsCOMPtr<nsIThread> mThread;
+};
+
+NS_IMPL_ISUPPORTS(nsHtml5ParserThreadTerminator, nsIObserver)
+
+// static
+nsIThread*
+nsHtml5Module::GetStreamParserThread()
+{
+ if (sOffMainThread) {
+ if (!sStreamParserThread) {
+ NS_NewNamedThread("HTML5 Parser", &sStreamParserThread);
+ NS_ASSERTION(sStreamParserThread, "Thread creation failed!");
+ nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
+ NS_ASSERTION(os, "do_GetService failed");
+ os->AddObserver(new nsHtml5ParserThreadTerminator(sStreamParserThread),
+ "xpcom-shutdown-threads",
+ false);
+ }
+ return sStreamParserThread;
+ }
+ if (!sMainThread) {
+ NS_GetMainThread(&sMainThread);
+ NS_ASSERTION(sMainThread, "Main thread getter failed");
+ }
+ return sMainThread;
+}
+
+#ifdef DEBUG
+bool nsHtml5Module::sNsHtml5ModuleInitialized = false;
+#endif
diff --git a/parser/html/nsHtml5Module.h b/parser/html/nsHtml5Module.h
new file mode 100644
index 000000000..e667b0a2e
--- /dev/null
+++ b/parser/html/nsHtml5Module.h
@@ -0,0 +1,28 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5Module_h
+#define nsHtml5Module_h
+
+#include "nsIParser.h"
+#include "nsIThread.h"
+
+class nsHtml5Module
+{
+ public:
+ static void InitializeStatics();
+ static void ReleaseStatics();
+ static already_AddRefed<nsIParser> NewHtml5Parser();
+ static nsresult Initialize(nsIParser* aParser, nsIDocument* aDoc, nsIURI* aURI, nsISupports* aContainer, nsIChannel* aChannel);
+ static nsIThread* GetStreamParserThread();
+ static bool sOffMainThread;
+ private:
+#ifdef DEBUG
+ static bool sNsHtml5ModuleInitialized;
+#endif
+ static nsIThread* sStreamParserThread;
+ static nsIThread* sMainThread;
+};
+
+#endif // nsHtml5Module_h
diff --git a/parser/html/nsHtml5NamedCharacters.cpp b/parser/html/nsHtml5NamedCharacters.cpp
new file mode 100644
index 000000000..302dbf5c9
--- /dev/null
+++ b/parser/html/nsHtml5NamedCharacters.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2008-2010 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#define nsHtml5NamedCharacters_cpp_
+#include "jArray.h"
+#include "nscore.h"
+#include "nsDebug.h"
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/Logging.h"
+
+#include "nsHtml5NamedCharacters.h"
+
+const char16_t nsHtml5NamedCharacters::VALUES[][2] = {
+#define NAMED_CHARACTER_REFERENCE(N, CHARS, LEN, FLAG, VALUE) \
+{ VALUE },
+#include "nsHtml5NamedCharactersInclude.h"
+#undef NAMED_CHARACTER_REFERENCE
+{0, 0} };
+
+char16_t** nsHtml5NamedCharacters::WINDOWS_1252;
+static char16_t const WINDOWS_1252_DATA[] = {
+ 0x20AC,
+ 0x0081,
+ 0x201A,
+ 0x0192,
+ 0x201E,
+ 0x2026,
+ 0x2020,
+ 0x2021,
+ 0x02C6,
+ 0x2030,
+ 0x0160,
+ 0x2039,
+ 0x0152,
+ 0x008D,
+ 0x017D,
+ 0x008F,
+ 0x0090,
+ 0x2018,
+ 0x2019,
+ 0x201C,
+ 0x201D,
+ 0x2022,
+ 0x2013,
+ 0x2014,
+ 0x02DC,
+ 0x2122,
+ 0x0161,
+ 0x203A,
+ 0x0153,
+ 0x009D,
+ 0x017E,
+ 0x0178
+};
+
+/**
+ * To avoid having lots of pointers in the |charData| array, below,
+ * which would cause us to have to do lots of relocations at library
+ * load time, store all the string data for the names in one big array.
+ * Then use tricks with enums to help us build an array that contains
+ * the positions of each within the big arrays.
+ */
+
+static const int8_t ALL_NAMES[] = {
+#define NAMED_CHARACTER_REFERENCE(N, CHARS, LEN, FLAG, VALUE) \
+CHARS ,
+#include "nsHtml5NamedCharactersInclude.h"
+#undef NAMED_CHARACTER_REFERENCE
+};
+
+enum NamePositions {
+ DUMMY_INITIAL_NAME_POSITION = 0,
+/* enums don't take up space, so generate _START and _END */
+#define NAMED_CHARACTER_REFERENCE(N, CHARS, LEN, FLAG, VALUE) \
+NAME_##N##_DUMMY, /* automatically one higher than previous */ \
+NAME_##N##_START = NAME_##N##_DUMMY - 1, \
+NAME_##N##_END = NAME_##N##_START + LEN + FLAG,
+#include "nsHtml5NamedCharactersInclude.h"
+#undef NAMED_CHARACTER_REFERENCE
+ DUMMY_FINAL_NAME_VALUE
+};
+
+static_assert(MOZ_ARRAY_LENGTH(ALL_NAMES) < 0x10000, "Start positions should fit in 16 bits");
+
+const nsHtml5CharacterName nsHtml5NamedCharacters::NAMES[] = {
+#ifdef DEBUG
+ #define NAMED_CHARACTER_REFERENCE(N, CHARS, LEN, FLAG, VALUE) \
+{ NAME_##N##_START, LEN, N },
+#else
+ #define NAMED_CHARACTER_REFERENCE(N, CHARS, LEN, FLAG, VALUE) \
+{ NAME_##N##_START, LEN, },
+#endif
+#include "nsHtml5NamedCharactersInclude.h"
+#undef NAMED_CHARACTER_REFERENCE
+};
+
+int32_t
+nsHtml5CharacterName::length() const
+{
+ return nameLen;
+}
+
+char16_t
+nsHtml5CharacterName::charAt(int32_t index) const
+{
+ return static_cast<char16_t> (ALL_NAMES[nameStart + index]);
+}
+
+void
+nsHtml5NamedCharacters::initializeStatics()
+{
+ WINDOWS_1252 = new char16_t*[32];
+ for (int32_t i = 0; i < 32; ++i) {
+ WINDOWS_1252[i] = (char16_t*)&(WINDOWS_1252_DATA[i]);
+ }
+}
+
+void
+nsHtml5NamedCharacters::releaseStatics()
+{
+ delete[] WINDOWS_1252;
+}
diff --git a/parser/html/nsHtml5NamedCharacters.h b/parser/html/nsHtml5NamedCharacters.h
new file mode 100644
index 000000000..9c6cc3a9b
--- /dev/null
+++ b/parser/html/nsHtml5NamedCharacters.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2008-2010 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef nsHtml5NamedCharacters_h
+#define nsHtml5NamedCharacters_h
+
+#include "jArray.h"
+#include "nscore.h"
+#include "nsDebug.h"
+#include "mozilla/Logging.h"
+#include "nsMemory.h"
+
+struct nsHtml5CharacterName {
+ uint16_t nameStart;
+ uint16_t nameLen;
+ #ifdef DEBUG
+ int32_t n;
+ #endif
+ int32_t length() const;
+ char16_t charAt(int32_t index) const;
+};
+
+class nsHtml5NamedCharacters
+{
+ public:
+ static const nsHtml5CharacterName NAMES[];
+ static const char16_t VALUES[][2];
+ static char16_t** WINDOWS_1252;
+ static void initializeStatics();
+ static void releaseStatics();
+};
+
+#endif // nsHtml5NamedCharacters_h
diff --git a/parser/html/nsHtml5NamedCharactersAccel.cpp b/parser/html/nsHtml5NamedCharactersAccel.cpp
new file mode 100644
index 000000000..e9c42d71b
--- /dev/null
+++ b/parser/html/nsHtml5NamedCharactersAccel.cpp
@@ -0,0 +1,313 @@
+/*
+ * Copyright 2004-2010 Apple Computer, Inc., Mozilla Foundation, and Opera
+ * Software ASA.
+ *
+ * You are granted a license to use, reproduce and create derivative works of
+ * this document.
+ */
+
+
+#include "nsHtml5NamedCharactersAccel.h"
+
+static int32_t const HILO_ACCEL_65[] = {
+0, 0, 0, 0, 0, 0, 0, 12386493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40174181, 0, 0, 0, 0, 60162966, 0, 0, 0, 75367550, 0, 0, 0, 82183396, 0, 0, 0, 0, 0, 115148507, 0, 0, 135989275, 139397199, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_66[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28770743, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82248935, 0, 0, 0, 0, 0, 115214046, 0, 0, 0, 139528272, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_68[] = {
+0, 0, 0, 4980811, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38470219, 0, 0, 0, 0, 0, 0, 0, 0, 64553944, 0, 0, 0, 0, 0, 0, 0, 92145022, 0, 0, 0, 0, 0, 0, 0, 0, 139593810, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_69[] = {
+65536, 0, 0, 0, 0, 0, 0, 0, 13172937, 0, 0, 0, 0, 0, 25297282, 0, 0, 28901816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71500866, 0, 0, 0, 0, 82380008, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_71[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94897574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_72[] = {
+0, 0, 2555943, 0, 0, 0, 0, 0, 0, 0, 15532269, 0, 0, 0, 0, 0, 0, 0, 31785444, 34406924, 0, 0, 0, 0, 0, 40895088, 0, 0, 0, 60228503, 0, 0, 0, 0, 0, 0, 0, 82445546, 0, 0, 0, 0, 0, 115279583, 0, 0, 136054812, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_73[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40239718, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_74[] = {
+0, 0, 0, 5046349, 0, 0, 10944679, 0, 13238474, 0, 15597806, 16056565, 0, 20578618, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_76[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95225257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_77[] = {
+196610, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_78[] = {
+0, 0, 0, 0, 8454273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46072511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_79[] = {
+0, 0, 2687016, 0, 0, 0, 0, 0, 13304011, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31850982, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_82[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34472462, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95290798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_83[] = {
+0, 0, 0, 5111886, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34603535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105776718, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_84[] = {
+0, 0, 0, 0, 8585346, 0, 11075752, 0, 0, 0, 0, 16187638, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_85[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28508594, 0, 0, 0, 0, 0, 0, 0, 40305255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_86[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95421871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_90[] = {
+0, 0, 0, 5177423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_97[] = {
+327684, 1900571, 2949162, 5374032, 8716420, 0, 11206826, 12517566, 13435084, 0, 15663343, 16515320, 19988785, 20644155, 25428355, 27197855, 0, 29163962, 31916519, 34734609, 36045347, 0, 0, 0, 40436328, 40960625, 41615994, 46596800, 54264627, 60556184, 64750554, 68879387, 71763012, 75826303, 77268122, 0, 81462490, 83952875, 92865919, 96142769, 105973327, 110167691, 0, 116917984, 121833283, 132253665, 136251421, 140707923, 0, 0, 144574620, 145361066
+};
+
+static int32_t const HILO_ACCEL_98[] = {
+393222, 0, 0, 0, 0, 0, 11272364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36176423, 38535756, 0, 0, 0, 0, 41681532, 46727880, 0, 60687261, 0, 0, 71828552, 75891846, 0, 0, 0, 84411650, 0, 96404924, 0, 0, 0, 117376761, 121898820, 132319203, 136382496, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_99[] = {
+589831, 1966110, 3276846, 5505107, 8978566, 10420383, 11468973, 12583104, 13631694, 15139046, 15794416, 16711933, 20054322, 20840764, 25624965, 27263392, 0, 29360574, 32244200, 34931219, 36373033, 38601293, 39584348, 0, 40567402, 41091698, 42205821, 46858954, 54723389, 60818335, 65143773, 68944924, 71959625, 75957383, 77530268, 80938194, 81593564, 84739337, 92997002, 96863680, 106235474, 110233234, 0, 117704448, 122816325, 132515812, 136579106, 140773476, 142149753, 143001732, 144705695, 145492139
+};
+
+static int32_t const HILO_ACCEL_100[] = {
+0, 0, 3342387, 0, 9044106, 0, 11534512, 0, 13697233, 0, 0, 0, 0, 0, 25690504, 0, 0, 0, 0, 0, 36438572, 38732366, 0, 0, 0, 41157236, 0, 46924492, 54788932, 61080481, 65209315, 0, 72025163, 0, 0, 0, 0, 85132558, 93062540, 96929223, 106563158, 0, 0, 118032133, 123012947, 132581351, 136775717, 140839013, 0, 143067271, 0, 145557677
+};
+
+static int32_t const HILO_ACCEL_101[] = {
+0, 2162719, 3473460, 5636181, 0, 0, 0, 0, 0, 0, 0, 18809088, 20185395, 21299519, 0, 0, 0, 29622721, 0, 0, 0, 39256656, 39649885, 0, 0, 41288309, 42336901, 47448781, 55182149, 61342629, 65274852, 69010461, 72811596, 76219528, 77726880, 0, 0, 86967572, 93128077, 97650120, 106628699, 110560915, 0, 118490890, 123733846, 132646888, 0, 141232230, 142411898, 0, 144836769, 145688750
+};
+
+static int32_t const HILO_ACCEL_102[] = {
+655370, 2228258, 3538998, 5701719, 9109643, 10485920, 11600049, 12648641, 13762770, 15204584, 15859954, 18874656, 20250933, 21365062, 25756041, 27328929, 28574132, 29688261, 32309741, 34996758, 36504109, 39322200, 39715422, 39912033, 40632940, 41353847, 42467975, 47514325, 55247691, 61473705, 65405925, 69272606, 72877144, 76285068, 77857955, 81003732, 81659102, 87164208, 93193614, 97715667, 106759772, 110626456, 114296528, 118687505, 123864929, 132712425, 136906792, 141297772, 142477438, 143132808, 144902307, 145754288
+};
+
+static int32_t const HILO_ACCEL_103[] = {
+786443, 0, 0, 0, 9240716, 0, 11665586, 0, 13893843, 0, 0, 0, 0, 0, 25887114, 0, 0, 0, 0, 0, 36635182, 0, 0, 0, 0, 0, 42599049, 0, 0, 0, 65733607, 0, 73008217, 0, 77989029, 0, 81724639, 87295283, 0, 98305492, 107021918, 0, 0, 0, 0, 0, 137037866, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_104[] = {
+0, 0, 3604535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27394466, 0, 29753798, 32571886, 35258903, 0, 0, 0, 0, 0, 0, 0, 0, 55509836, 61604779, 0, 0, 0, 0, 0, 0, 81790176, 87557429, 93259151, 98502109, 107152994, 110888601, 0, 119015188, 124323683, 133498858, 137234476, 0, 0, 143263881, 0, 145819825
+};
+
+static int32_t const HILO_ACCEL_105[] = {
+0, 0, 3866680, 6160472, 0, 10616993, 0, 12714178, 0, 0, 0, 0, 20316470, 0, 0, 27460003, 0, 31261127, 32637426, 35521051, 0, 0, 0, 39977570, 0, 0, 0, 48366294, 56492880, 62391213, 0, 69338146, 73073755, 0, 78316711, 0, 0, 0, 93980048, 98764256, 107218532, 111085213, 114362065, 119736089, 125241194, 133957622, 0, 0, 0, 143329419, 144967844, 145885362
+};
+
+static int32_t const HILO_ACCEL_106[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62456761, 0, 69403683, 73139292, 0, 78382252, 0, 81855713, 87622969, 0, 98829796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_107[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48431843, 0, 0, 0, 0, 0, 76416141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_108[] = {
+851981, 0, 4063292, 0, 9306254, 0, 0, 0, 0, 0, 0, 19005729, 0, 0, 0, 27525540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42795659, 49152740, 56623967, 62587834, 66061292, 69600292, 73401437, 0, 0, 0, 0, 87950650, 94111131, 99878373, 107546213, 112002720, 0, 119932708, 125306744, 0, 137496623, 141363309, 0, 143460492, 0, 0
+};
+
+static int32_t const HILO_ACCEL_109[] = {
+917518, 0, 0, 0, 9502863, 0, 0, 0, 14155989, 0, 0, 19071267, 0, 0, 26083724, 0, 0, 0, 32702963, 0, 36700720, 0, 0, 0, 0, 0, 43057806, 0, 0, 0, 66520049, 0, 0, 0, 78841005, 81069269, 0, 88147263, 0, 99943925, 107873898, 112068270, 0, 120063783, 125831033, 0, 137693235, 0, 0, 143526030, 0, 0
+};
+
+static int32_t const HILO_ACCEL_110[] = {
+983055, 0, 0, 0, 0, 0, 0, 0, 14483673, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37093937, 0, 0, 0, 0, 0, 44565138, 49349359, 0, 0, 66651128, 69665831, 73860193, 0, 79561908, 0, 0, 88606018, 94176669, 0, 0, 0, 0, 120129321, 0, 0, 0, 141494382, 0, 143591567, 0, 0
+};
+
+static int32_t const HILO_ACCEL_111[] = {
+1114128, 2293795, 4587583, 8257631, 9633938, 10813603, 11731123, 12845251, 14680286, 15270121, 15925491, 19661092, 20382007, 24969543, 26149263, 27656613, 28639669, 31392222, 32768500, 35586591, 37225015, 39387737, 39780959, 40043107, 40698477, 41419384, 44696233, 52495090, 57738081, 63439804, 66782202, 69927976, 73925736, 76809359, 79824063, 81134806, 81921250, 89785673, 94307742, 100795894, 107939439, 112330415, 114427602, 120588074, 126158721, 134416381, 137824310, 141559920, 142542975, 143853712, 145033381, 145950899
+};
+
+static int32_t const HILO_ACCEL_112[] = {
+1179666, 0, 0, 0, 9699476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26280336, 0, 0, 0, 0, 0, 38076985, 0, 0, 0, 0, 0, 45220523, 52560674, 0, 0, 67175420, 69993516, 0, 0, 79889603, 0, 0, 89916763, 94373280, 101451267, 108136048, 0, 114493139, 120784689, 126355334, 134481924, 138414136, 141625457, 142608512, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_113[] = {
+0, 0, 0, 0, 9896085, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33292789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67830786, 0, 0, 0, 80020676, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127403913, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_114[] = {
+1310739, 2359332, 4653127, 0, 0, 0, 12189876, 0, 0, 0, 0, 0, 0, 0, 26345874, 28246439, 0, 31457760, 0, 35652128, 38142534, 0, 0, 0, 0, 0, 45351603, 52757283, 57869170, 63636425, 67961868, 71304237, 73991273, 0, 0, 0, 0, 90309981, 0, 101910029, 108988019, 114034355, 0, 120850228, 127469465, 135464965, 138741825, 141690994, 142739585, 143984788, 0, 0
+};
+
+static int32_t const HILO_ACCEL_115[] = {
+1441813, 2424869, 4718664, 8388735, 10027160, 10879142, 12255419, 12976325, 14745825, 15401194, 15991028, 19857709, 20447544, 25035134, 26542483, 28377520, 28705206, 31588833, 33358333, 35783201, 38208071, 39453274, 39846496, 40108644, 40764014, 41484921, 45613749, 53216038, 58196852, 63898572, 68158478, 71369793, 74253418, 77005973, 80479430, 81265879, 81986787, 90965347, 94504353, 103679508, 109250176, 114165453, 114558676, 121243445, 127731610, 135727124, 138807366, 142018675, 142805123, 144115862, 145098918, 146016436
+};
+
+static int32_t const HILO_ACCEL_116[] = {
+1572887, 0, 0, 0, 10092698, 0, 12320956, 0, 14811362, 0, 0, 19923248, 0, 25166207, 26739094, 0, 0, 0, 33423870, 0, 38273608, 0, 0, 0, 0, 0, 45744825, 0, 58262393, 64095184, 68355089, 0, 75170926, 0, 80610509, 0, 0, 91817325, 0, 104203823, 109512324, 0, 0, 121636667, 128059294, 0, 139069511, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_117[] = {
+1703961, 2490406, 4849737, 0, 10223771, 0, 0, 13107399, 15007971, 15466732, 0, 0, 20513081, 25231745, 26870169, 0, 0, 31654371, 34275839, 0, 38404681, 0, 0, 0, 40829551, 0, 45875899, 53609261, 59900794, 64226259, 68551700, 0, 0, 0, 80807119, 81331417, 0, 91948410, 94700963, 104465975, 109643400, 114230991, 114951893, 121702209, 131663779, 0, 139266123, 0, 0, 144246936, 145295527, 0
+};
+
+static int32_t const HILO_ACCEL_118[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27132315, 0, 0, 0, 0, 0, 0, 39518811, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75302012, 0, 0, 0, 0, 92079484, 0, 105383483, 109708938, 0, 0, 0, 0, 0, 0, 0, 0, 144312474, 0, 0
+};
+
+static int32_t const HILO_ACCEL_119[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46006973, 0, 60031891, 64291797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105711177, 0, 0, 0, 0, 131991514, 135923736, 139331662, 0, 0, 144378011, 0, 146147509
+};
+
+static int32_t const HILO_ACCEL_120[] = {
+0, 0, 0, 0, 10354845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68813847, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121767746, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_121[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60097429, 0, 0, 0, 0, 77137048, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int32_t const HILO_ACCEL_122[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64422870, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132122591, 0, 0, 142084216, 0, 0, 0, 0
+};
+
+const int32_t* const nsHtml5NamedCharactersAccel::HILO_ACCEL[] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ HILO_ACCEL_65,
+ HILO_ACCEL_66,
+ 0,
+ HILO_ACCEL_68,
+ HILO_ACCEL_69,
+ 0,
+ HILO_ACCEL_71,
+ HILO_ACCEL_72,
+ HILO_ACCEL_73,
+ HILO_ACCEL_74,
+ 0,
+ HILO_ACCEL_76,
+ HILO_ACCEL_77,
+ HILO_ACCEL_78,
+ HILO_ACCEL_79,
+ 0,
+ 0,
+ HILO_ACCEL_82,
+ HILO_ACCEL_83,
+ HILO_ACCEL_84,
+ HILO_ACCEL_85,
+ HILO_ACCEL_86,
+ 0,
+ 0,
+ 0,
+ HILO_ACCEL_90,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ HILO_ACCEL_97,
+ HILO_ACCEL_98,
+ HILO_ACCEL_99,
+ HILO_ACCEL_100,
+ HILO_ACCEL_101,
+ HILO_ACCEL_102,
+ HILO_ACCEL_103,
+ HILO_ACCEL_104,
+ HILO_ACCEL_105,
+ HILO_ACCEL_106,
+ HILO_ACCEL_107,
+ HILO_ACCEL_108,
+ HILO_ACCEL_109,
+ HILO_ACCEL_110,
+ HILO_ACCEL_111,
+ HILO_ACCEL_112,
+ HILO_ACCEL_113,
+ HILO_ACCEL_114,
+ HILO_ACCEL_115,
+ HILO_ACCEL_116,
+ HILO_ACCEL_117,
+ HILO_ACCEL_118,
+ HILO_ACCEL_119,
+ HILO_ACCEL_120,
+ HILO_ACCEL_121,
+ HILO_ACCEL_122
+};
+
diff --git a/parser/html/nsHtml5NamedCharactersAccel.h b/parser/html/nsHtml5NamedCharactersAccel.h
new file mode 100644
index 000000000..8e6df8ebb
--- /dev/null
+++ b/parser/html/nsHtml5NamedCharactersAccel.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2004-2010 Apple Computer, Inc., Mozilla Foundation, and Opera
+ * Software ASA.
+ *
+ * You are granted a license to use, reproduce and create derivative works of
+ * this document.
+ */
+
+#ifndef nsHtml5NamedCharactersAccel_h
+#define nsHtml5NamedCharactersAccel_h
+
+#include "jArray.h"
+#include "nscore.h"
+#include "nsDebug.h"
+#include "mozilla/Logging.h"
+#include "nsMemory.h"
+
+class nsHtml5NamedCharactersAccel
+{
+ public:
+ static const int32_t* const HILO_ACCEL[];
+};
+
+#endif // nsHtml5NamedCharactersAccel_h
diff --git a/parser/html/nsHtml5NamedCharactersInclude.h b/parser/html/nsHtml5NamedCharactersInclude.h
new file mode 100644
index 000000000..0a6b0c11e
--- /dev/null
+++ b/parser/html/nsHtml5NamedCharactersInclude.h
@@ -0,0 +1,2266 @@
+/*
+ * Copyright 2004-2010 Apple Computer, Inc., Mozilla Foundation, and Opera
+ * Software ASA.
+ *
+ * You are granted a license to use, reproduce and create derivative works of
+ * this document.
+ */
+
+/* Data generated from the table of named character references found at
+ *
+ * http://www.whatwg.org/specs/web-apps/current-work/multipage/named-character-references.html#named-character-references
+ *
+ * Files that #include this file must #define NAMED_CHARACTER_REFERENCE as a
+ * macro of four parameters:
+ *
+ * 1. a unique integer N identifying the Nth [0,1,..] macro expansion in this file,
+ * 2. a comma-separated sequence of characters comprising the character name,
+ * without the first two letters or 0 if the sequence would be empty.
+ * See Tokenizer.java.
+ * 3. the length of this sequence of characters,
+ * 4. placeholder flag (0 if argument #is not a placeholder and 1 if it is),
+ * 5. a comma-separated sequence of char16_t literals corresponding
+ * to the code-point(s) of the named character.
+ *
+ * The macro expansion doesn't have to refer to all or any of these parameters,
+ * but common sense dictates that it should involve at least one of them.
+ */
+
+// This #define allows the NAMED_CHARACTER_REFERENCE macro to accept comma-
+// separated sequences as single macro arguments. Using commas directly would
+// split the sequence into multiple macro arguments.
+#define _ ,
+
+NAMED_CHARACTER_REFERENCE(0, /* A E */ 'l' _ 'i' _ 'g', 3, 0, 0x00c6 _ 0)
+NAMED_CHARACTER_REFERENCE(1, /* A E */ 'l' _ 'i' _ 'g' _ ';', 4, 0, 0x00c6 _ 0)
+NAMED_CHARACTER_REFERENCE(2, /* A M */ 'P', 1, 0, 0x0026 _ 0)
+NAMED_CHARACTER_REFERENCE(3, /* A M */ 'P' _ ';', 2, 0, 0x0026 _ 0)
+NAMED_CHARACTER_REFERENCE(4, /* A a */ 'c' _ 'u' _ 't' _ 'e', 4, 0, 0x00c1 _ 0)
+NAMED_CHARACTER_REFERENCE(5, /* A a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x00c1 _ 0)
+NAMED_CHARACTER_REFERENCE(6, /* A b */ 'r' _ 'e' _ 'v' _ 'e' _ ';', 5, 0, 0x0102 _ 0)
+NAMED_CHARACTER_REFERENCE(7, /* A c */ 'i' _ 'r' _ 'c', 3, 0, 0x00c2 _ 0)
+NAMED_CHARACTER_REFERENCE(8, /* A c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x00c2 _ 0)
+NAMED_CHARACTER_REFERENCE(9, /* A c */ 'y' _ ';', 2, 0, 0x0410 _ 0)
+NAMED_CHARACTER_REFERENCE(10, /* A f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd04)
+NAMED_CHARACTER_REFERENCE(11, /* A g */ 'r' _ 'a' _ 'v' _ 'e', 4, 0, 0x00c0 _ 0)
+NAMED_CHARACTER_REFERENCE(12, /* A g */ 'r' _ 'a' _ 'v' _ 'e' _ ';', 5, 0, 0x00c0 _ 0)
+NAMED_CHARACTER_REFERENCE(13, /* A l */ 'p' _ 'h' _ 'a' _ ';', 4, 0, 0x0391 _ 0)
+NAMED_CHARACTER_REFERENCE(14, /* A m */ 'a' _ 'c' _ 'r' _ ';', 4, 0, 0x0100 _ 0)
+NAMED_CHARACTER_REFERENCE(15, /* A n */ 'd' _ ';', 2, 0, 0x2a53 _ 0)
+NAMED_CHARACTER_REFERENCE(16, /* A o */ 'g' _ 'o' _ 'n' _ ';', 4, 0, 0x0104 _ 0)
+NAMED_CHARACTER_REFERENCE(17, /* A o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd38)
+NAMED_CHARACTER_REFERENCE(18, /* A p */ 'p' _ 'l' _ 'y' _ 'F' _ 'u' _ 'n' _ 'c' _ 't' _ 'i' _ 'o' _ 'n' _ ';', 12, 0, 0x2061 _ 0)
+NAMED_CHARACTER_REFERENCE(19, /* A r */ 'i' _ 'n' _ 'g', 3, 0, 0x00c5 _ 0)
+NAMED_CHARACTER_REFERENCE(20, /* A r */ 'i' _ 'n' _ 'g' _ ';', 4, 0, 0x00c5 _ 0)
+NAMED_CHARACTER_REFERENCE(21, /* A s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdc9c)
+NAMED_CHARACTER_REFERENCE(22, /* A s */ 's' _ 'i' _ 'g' _ 'n' _ ';', 5, 0, 0x2254 _ 0)
+NAMED_CHARACTER_REFERENCE(23, /* A t */ 'i' _ 'l' _ 'd' _ 'e', 4, 0, 0x00c3 _ 0)
+NAMED_CHARACTER_REFERENCE(24, /* A t */ 'i' _ 'l' _ 'd' _ 'e' _ ';', 5, 0, 0x00c3 _ 0)
+NAMED_CHARACTER_REFERENCE(25, /* A u */ 'm' _ 'l', 2, 0, 0x00c4 _ 0)
+NAMED_CHARACTER_REFERENCE(26, /* A u */ 'm' _ 'l' _ ';', 3, 0, 0x00c4 _ 0)
+NAMED_CHARACTER_REFERENCE(27, /* B a */ 'c' _ 'k' _ 's' _ 'l' _ 'a' _ 's' _ 'h' _ ';', 8, 0, 0x2216 _ 0)
+NAMED_CHARACTER_REFERENCE(28, /* B a */ 'r' _ 'v' _ ';', 3, 0, 0x2ae7 _ 0)
+NAMED_CHARACTER_REFERENCE(29, /* B a */ 'r' _ 'w' _ 'e' _ 'd' _ ';', 5, 0, 0x2306 _ 0)
+NAMED_CHARACTER_REFERENCE(30, /* B c */ 'y' _ ';', 2, 0, 0x0411 _ 0)
+NAMED_CHARACTER_REFERENCE(31, /* B e */ 'c' _ 'a' _ 'u' _ 's' _ 'e' _ ';', 6, 0, 0x2235 _ 0)
+NAMED_CHARACTER_REFERENCE(32, /* B e */ 'r' _ 'n' _ 'o' _ 'u' _ 'l' _ 'l' _ 'i' _ 's' _ ';', 9, 0, 0x212c _ 0)
+NAMED_CHARACTER_REFERENCE(33, /* B e */ 't' _ 'a' _ ';', 3, 0, 0x0392 _ 0)
+NAMED_CHARACTER_REFERENCE(34, /* B f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd05)
+NAMED_CHARACTER_REFERENCE(35, /* B o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd39)
+NAMED_CHARACTER_REFERENCE(36, /* B r */ 'e' _ 'v' _ 'e' _ ';', 4, 0, 0x02d8 _ 0)
+NAMED_CHARACTER_REFERENCE(37, /* B s */ 'c' _ 'r' _ ';', 3, 0, 0x212c _ 0)
+NAMED_CHARACTER_REFERENCE(38, /* B u */ 'm' _ 'p' _ 'e' _ 'q' _ ';', 5, 0, 0x224e _ 0)
+NAMED_CHARACTER_REFERENCE(39, /* C H */ 'c' _ 'y' _ ';', 3, 0, 0x0427 _ 0)
+NAMED_CHARACTER_REFERENCE(40, /* C O */ 'P' _ 'Y', 2, 0, 0x00a9 _ 0)
+NAMED_CHARACTER_REFERENCE(41, /* C O */ 'P' _ 'Y' _ ';', 3, 0, 0x00a9 _ 0)
+NAMED_CHARACTER_REFERENCE(42, /* C a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x0106 _ 0)
+NAMED_CHARACTER_REFERENCE(43, /* C a */ 'p' _ ';', 2, 0, 0x22d2 _ 0)
+NAMED_CHARACTER_REFERENCE(44, /* C a */ 'p' _ 'i' _ 't' _ 'a' _ 'l' _ 'D' _ 'i' _ 'f' _ 'f' _ 'e' _ 'r' _ 'e' _ 'n' _ 't' _ 'i' _ 'a' _ 'l' _ 'D' _ ';', 19, 0, 0x2145 _ 0)
+NAMED_CHARACTER_REFERENCE(45, /* C a */ 'y' _ 'l' _ 'e' _ 'y' _ 's' _ ';', 6, 0, 0x212d _ 0)
+NAMED_CHARACTER_REFERENCE(46, /* C c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x010c _ 0)
+NAMED_CHARACTER_REFERENCE(47, /* C c */ 'e' _ 'd' _ 'i' _ 'l', 4, 0, 0x00c7 _ 0)
+NAMED_CHARACTER_REFERENCE(48, /* C c */ 'e' _ 'd' _ 'i' _ 'l' _ ';', 5, 0, 0x00c7 _ 0)
+NAMED_CHARACTER_REFERENCE(49, /* C c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x0108 _ 0)
+NAMED_CHARACTER_REFERENCE(50, /* C c */ 'o' _ 'n' _ 'i' _ 'n' _ 't' _ ';', 6, 0, 0x2230 _ 0)
+NAMED_CHARACTER_REFERENCE(51, /* C d */ 'o' _ 't' _ ';', 3, 0, 0x010a _ 0)
+NAMED_CHARACTER_REFERENCE(52, /* C e */ 'd' _ 'i' _ 'l' _ 'l' _ 'a' _ ';', 6, 0, 0x00b8 _ 0)
+NAMED_CHARACTER_REFERENCE(53, /* C e */ 'n' _ 't' _ 'e' _ 'r' _ 'D' _ 'o' _ 't' _ ';', 8, 0, 0x00b7 _ 0)
+NAMED_CHARACTER_REFERENCE(54, /* C f */ 'r' _ ';', 2, 0, 0x212d _ 0)
+NAMED_CHARACTER_REFERENCE(55, /* C h */ 'i' _ ';', 2, 0, 0x03a7 _ 0)
+NAMED_CHARACTER_REFERENCE(56, /* C i */ 'r' _ 'c' _ 'l' _ 'e' _ 'D' _ 'o' _ 't' _ ';', 8, 0, 0x2299 _ 0)
+NAMED_CHARACTER_REFERENCE(57, /* C i */ 'r' _ 'c' _ 'l' _ 'e' _ 'M' _ 'i' _ 'n' _ 'u' _ 's' _ ';', 10, 0, 0x2296 _ 0)
+NAMED_CHARACTER_REFERENCE(58, /* C i */ 'r' _ 'c' _ 'l' _ 'e' _ 'P' _ 'l' _ 'u' _ 's' _ ';', 9, 0, 0x2295 _ 0)
+NAMED_CHARACTER_REFERENCE(59, /* C i */ 'r' _ 'c' _ 'l' _ 'e' _ 'T' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 10, 0, 0x2297 _ 0)
+NAMED_CHARACTER_REFERENCE(60, /* C l */ 'o' _ 'c' _ 'k' _ 'w' _ 'i' _ 's' _ 'e' _ 'C' _ 'o' _ 'n' _ 't' _ 'o' _ 'u' _ 'r' _ 'I' _ 'n' _ 't' _ 'e' _ 'g' _ 'r' _ 'a' _ 'l' _ ';', 23, 0, 0x2232 _ 0)
+NAMED_CHARACTER_REFERENCE(61, /* C l */ 'o' _ 's' _ 'e' _ 'C' _ 'u' _ 'r' _ 'l' _ 'y' _ 'D' _ 'o' _ 'u' _ 'b' _ 'l' _ 'e' _ 'Q' _ 'u' _ 'o' _ 't' _ 'e' _ ';', 20, 0, 0x201d _ 0)
+NAMED_CHARACTER_REFERENCE(62, /* C l */ 'o' _ 's' _ 'e' _ 'C' _ 'u' _ 'r' _ 'l' _ 'y' _ 'Q' _ 'u' _ 'o' _ 't' _ 'e' _ ';', 14, 0, 0x2019 _ 0)
+NAMED_CHARACTER_REFERENCE(63, /* C o */ 'l' _ 'o' _ 'n' _ ';', 4, 0, 0x2237 _ 0)
+NAMED_CHARACTER_REFERENCE(64, /* C o */ 'l' _ 'o' _ 'n' _ 'e' _ ';', 5, 0, 0x2a74 _ 0)
+NAMED_CHARACTER_REFERENCE(65, /* C o */ 'n' _ 'g' _ 'r' _ 'u' _ 'e' _ 'n' _ 't' _ ';', 8, 0, 0x2261 _ 0)
+NAMED_CHARACTER_REFERENCE(66, /* C o */ 'n' _ 'i' _ 'n' _ 't' _ ';', 5, 0, 0x222f _ 0)
+NAMED_CHARACTER_REFERENCE(67, /* C o */ 'n' _ 't' _ 'o' _ 'u' _ 'r' _ 'I' _ 'n' _ 't' _ 'e' _ 'g' _ 'r' _ 'a' _ 'l' _ ';', 14, 0, 0x222e _ 0)
+NAMED_CHARACTER_REFERENCE(68, /* C o */ 'p' _ 'f' _ ';', 3, 0, 0x2102 _ 0)
+NAMED_CHARACTER_REFERENCE(69, /* C o */ 'p' _ 'r' _ 'o' _ 'd' _ 'u' _ 'c' _ 't' _ ';', 8, 0, 0x2210 _ 0)
+NAMED_CHARACTER_REFERENCE(70, /* C o */ 'u' _ 'n' _ 't' _ 'e' _ 'r' _ 'C' _ 'l' _ 'o' _ 'c' _ 'k' _ 'w' _ 'i' _ 's' _ 'e' _ 'C' _ 'o' _ 'n' _ 't' _ 'o' _ 'u' _ 'r' _ 'I' _ 'n' _ 't' _ 'e' _ 'g' _ 'r' _ 'a' _ 'l' _ ';', 30, 0, 0x2233 _ 0)
+NAMED_CHARACTER_REFERENCE(71, /* C r */ 'o' _ 's' _ 's' _ ';', 4, 0, 0x2a2f _ 0)
+NAMED_CHARACTER_REFERENCE(72, /* C s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdc9e)
+NAMED_CHARACTER_REFERENCE(73, /* C u */ 'p' _ ';', 2, 0, 0x22d3 _ 0)
+NAMED_CHARACTER_REFERENCE(74, /* C u */ 'p' _ 'C' _ 'a' _ 'p' _ ';', 5, 0, 0x224d _ 0)
+NAMED_CHARACTER_REFERENCE(75, /* D D */ ';', 1, 0, 0x2145 _ 0)
+NAMED_CHARACTER_REFERENCE(76, /* D D */ 'o' _ 't' _ 'r' _ 'a' _ 'h' _ 'd' _ ';', 7, 0, 0x2911 _ 0)
+NAMED_CHARACTER_REFERENCE(77, /* D J */ 'c' _ 'y' _ ';', 3, 0, 0x0402 _ 0)
+NAMED_CHARACTER_REFERENCE(78, /* D S */ 'c' _ 'y' _ ';', 3, 0, 0x0405 _ 0)
+NAMED_CHARACTER_REFERENCE(79, /* D Z */ 'c' _ 'y' _ ';', 3, 0, 0x040f _ 0)
+NAMED_CHARACTER_REFERENCE(80, /* D a */ 'g' _ 'g' _ 'e' _ 'r' _ ';', 5, 0, 0x2021 _ 0)
+NAMED_CHARACTER_REFERENCE(81, /* D a */ 'r' _ 'r' _ ';', 3, 0, 0x21a1 _ 0)
+NAMED_CHARACTER_REFERENCE(82, /* D a */ 's' _ 'h' _ 'v' _ ';', 4, 0, 0x2ae4 _ 0)
+NAMED_CHARACTER_REFERENCE(83, /* D c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x010e _ 0)
+NAMED_CHARACTER_REFERENCE(84, /* D c */ 'y' _ ';', 2, 0, 0x0414 _ 0)
+NAMED_CHARACTER_REFERENCE(85, /* D e */ 'l' _ ';', 2, 0, 0x2207 _ 0)
+NAMED_CHARACTER_REFERENCE(86, /* D e */ 'l' _ 't' _ 'a' _ ';', 4, 0, 0x0394 _ 0)
+NAMED_CHARACTER_REFERENCE(87, /* D f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd07)
+NAMED_CHARACTER_REFERENCE(88, /* D i */ 'a' _ 'c' _ 'r' _ 'i' _ 't' _ 'i' _ 'c' _ 'a' _ 'l' _ 'A' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 15, 0, 0x00b4 _ 0)
+NAMED_CHARACTER_REFERENCE(89, /* D i */ 'a' _ 'c' _ 'r' _ 'i' _ 't' _ 'i' _ 'c' _ 'a' _ 'l' _ 'D' _ 'o' _ 't' _ ';', 13, 0, 0x02d9 _ 0)
+NAMED_CHARACTER_REFERENCE(90, /* D i */ 'a' _ 'c' _ 'r' _ 'i' _ 't' _ 'i' _ 'c' _ 'a' _ 'l' _ 'D' _ 'o' _ 'u' _ 'b' _ 'l' _ 'e' _ 'A' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 21, 0, 0x02dd _ 0)
+NAMED_CHARACTER_REFERENCE(91, /* D i */ 'a' _ 'c' _ 'r' _ 'i' _ 't' _ 'i' _ 'c' _ 'a' _ 'l' _ 'G' _ 'r' _ 'a' _ 'v' _ 'e' _ ';', 15, 0, 0x0060 _ 0)
+NAMED_CHARACTER_REFERENCE(92, /* D i */ 'a' _ 'c' _ 'r' _ 'i' _ 't' _ 'i' _ 'c' _ 'a' _ 'l' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 15, 0, 0x02dc _ 0)
+NAMED_CHARACTER_REFERENCE(93, /* D i */ 'a' _ 'm' _ 'o' _ 'n' _ 'd' _ ';', 6, 0, 0x22c4 _ 0)
+NAMED_CHARACTER_REFERENCE(94, /* D i */ 'f' _ 'f' _ 'e' _ 'r' _ 'e' _ 'n' _ 't' _ 'i' _ 'a' _ 'l' _ 'D' _ ';', 12, 0, 0x2146 _ 0)
+NAMED_CHARACTER_REFERENCE(95, /* D o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd3b)
+NAMED_CHARACTER_REFERENCE(96, /* D o */ 't' _ ';', 2, 0, 0x00a8 _ 0)
+NAMED_CHARACTER_REFERENCE(97, /* D o */ 't' _ 'D' _ 'o' _ 't' _ ';', 5, 0, 0x20dc _ 0)
+NAMED_CHARACTER_REFERENCE(98, /* D o */ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 7, 0, 0x2250 _ 0)
+NAMED_CHARACTER_REFERENCE(99, /* D o */ 'u' _ 'b' _ 'l' _ 'e' _ 'C' _ 'o' _ 'n' _ 't' _ 'o' _ 'u' _ 'r' _ 'I' _ 'n' _ 't' _ 'e' _ 'g' _ 'r' _ 'a' _ 'l' _ ';', 20, 0, 0x222f _ 0)
+NAMED_CHARACTER_REFERENCE(100, /* D o */ 'u' _ 'b' _ 'l' _ 'e' _ 'D' _ 'o' _ 't' _ ';', 8, 0, 0x00a8 _ 0)
+NAMED_CHARACTER_REFERENCE(101, /* D o */ 'u' _ 'b' _ 'l' _ 'e' _ 'D' _ 'o' _ 'w' _ 'n' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 14, 0, 0x21d3 _ 0)
+NAMED_CHARACTER_REFERENCE(102, /* D o */ 'u' _ 'b' _ 'l' _ 'e' _ 'L' _ 'e' _ 'f' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 14, 0, 0x21d0 _ 0)
+NAMED_CHARACTER_REFERENCE(103, /* D o */ 'u' _ 'b' _ 'l' _ 'e' _ 'L' _ 'e' _ 'f' _ 't' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 19, 0, 0x21d4 _ 0)
+NAMED_CHARACTER_REFERENCE(104, /* D o */ 'u' _ 'b' _ 'l' _ 'e' _ 'L' _ 'e' _ 'f' _ 't' _ 'T' _ 'e' _ 'e' _ ';', 12, 0, 0x2ae4 _ 0)
+NAMED_CHARACTER_REFERENCE(105, /* D o */ 'u' _ 'b' _ 'l' _ 'e' _ 'L' _ 'o' _ 'n' _ 'g' _ 'L' _ 'e' _ 'f' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 18, 0, 0x27f8 _ 0)
+NAMED_CHARACTER_REFERENCE(106, /* D o */ 'u' _ 'b' _ 'l' _ 'e' _ 'L' _ 'o' _ 'n' _ 'g' _ 'L' _ 'e' _ 'f' _ 't' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 23, 0, 0x27fa _ 0)
+NAMED_CHARACTER_REFERENCE(107, /* D o */ 'u' _ 'b' _ 'l' _ 'e' _ 'L' _ 'o' _ 'n' _ 'g' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 19, 0, 0x27f9 _ 0)
+NAMED_CHARACTER_REFERENCE(108, /* D o */ 'u' _ 'b' _ 'l' _ 'e' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 15, 0, 0x21d2 _ 0)
+NAMED_CHARACTER_REFERENCE(109, /* D o */ 'u' _ 'b' _ 'l' _ 'e' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'T' _ 'e' _ 'e' _ ';', 13, 0, 0x22a8 _ 0)
+NAMED_CHARACTER_REFERENCE(110, /* D o */ 'u' _ 'b' _ 'l' _ 'e' _ 'U' _ 'p' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 12, 0, 0x21d1 _ 0)
+NAMED_CHARACTER_REFERENCE(111, /* D o */ 'u' _ 'b' _ 'l' _ 'e' _ 'U' _ 'p' _ 'D' _ 'o' _ 'w' _ 'n' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 16, 0, 0x21d5 _ 0)
+NAMED_CHARACTER_REFERENCE(112, /* D o */ 'u' _ 'b' _ 'l' _ 'e' _ 'V' _ 'e' _ 'r' _ 't' _ 'i' _ 'c' _ 'a' _ 'l' _ 'B' _ 'a' _ 'r' _ ';', 16, 0, 0x2225 _ 0)
+NAMED_CHARACTER_REFERENCE(113, /* D o */ 'w' _ 'n' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 8, 0, 0x2193 _ 0)
+NAMED_CHARACTER_REFERENCE(114, /* D o */ 'w' _ 'n' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ 'B' _ 'a' _ 'r' _ ';', 11, 0, 0x2913 _ 0)
+NAMED_CHARACTER_REFERENCE(115, /* D o */ 'w' _ 'n' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ 'U' _ 'p' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 15, 0, 0x21f5 _ 0)
+NAMED_CHARACTER_REFERENCE(116, /* D o */ 'w' _ 'n' _ 'B' _ 'r' _ 'e' _ 'v' _ 'e' _ ';', 8, 0, 0x0311 _ 0)
+NAMED_CHARACTER_REFERENCE(117, /* D o */ 'w' _ 'n' _ 'L' _ 'e' _ 'f' _ 't' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 18, 0, 0x2950 _ 0)
+NAMED_CHARACTER_REFERENCE(118, /* D o */ 'w' _ 'n' _ 'L' _ 'e' _ 'f' _ 't' _ 'T' _ 'e' _ 'e' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 16, 0, 0x295e _ 0)
+NAMED_CHARACTER_REFERENCE(119, /* D o */ 'w' _ 'n' _ 'L' _ 'e' _ 'f' _ 't' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 13, 0, 0x21bd _ 0)
+NAMED_CHARACTER_REFERENCE(120, /* D o */ 'w' _ 'n' _ 'L' _ 'e' _ 'f' _ 't' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ 'B' _ 'a' _ 'r' _ ';', 16, 0, 0x2956 _ 0)
+NAMED_CHARACTER_REFERENCE(121, /* D o */ 'w' _ 'n' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'T' _ 'e' _ 'e' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 17, 0, 0x295f _ 0)
+NAMED_CHARACTER_REFERENCE(122, /* D o */ 'w' _ 'n' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 14, 0, 0x21c1 _ 0)
+NAMED_CHARACTER_REFERENCE(123, /* D o */ 'w' _ 'n' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ 'B' _ 'a' _ 'r' _ ';', 17, 0, 0x2957 _ 0)
+NAMED_CHARACTER_REFERENCE(124, /* D o */ 'w' _ 'n' _ 'T' _ 'e' _ 'e' _ ';', 6, 0, 0x22a4 _ 0)
+NAMED_CHARACTER_REFERENCE(125, /* D o */ 'w' _ 'n' _ 'T' _ 'e' _ 'e' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 11, 0, 0x21a7 _ 0)
+NAMED_CHARACTER_REFERENCE(126, /* D o */ 'w' _ 'n' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 8, 0, 0x21d3 _ 0)
+NAMED_CHARACTER_REFERENCE(127, /* D s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdc9f)
+NAMED_CHARACTER_REFERENCE(128, /* D s */ 't' _ 'r' _ 'o' _ 'k' _ ';', 5, 0, 0x0110 _ 0)
+NAMED_CHARACTER_REFERENCE(129, /* E N */ 'G' _ ';', 2, 0, 0x014a _ 0)
+NAMED_CHARACTER_REFERENCE(130, /* E T */ 'H', 1, 0, 0x00d0 _ 0)
+NAMED_CHARACTER_REFERENCE(131, /* E T */ 'H' _ ';', 2, 0, 0x00d0 _ 0)
+NAMED_CHARACTER_REFERENCE(132, /* E a */ 'c' _ 'u' _ 't' _ 'e', 4, 0, 0x00c9 _ 0)
+NAMED_CHARACTER_REFERENCE(133, /* E a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x00c9 _ 0)
+NAMED_CHARACTER_REFERENCE(134, /* E c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x011a _ 0)
+NAMED_CHARACTER_REFERENCE(135, /* E c */ 'i' _ 'r' _ 'c', 3, 0, 0x00ca _ 0)
+NAMED_CHARACTER_REFERENCE(136, /* E c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x00ca _ 0)
+NAMED_CHARACTER_REFERENCE(137, /* E c */ 'y' _ ';', 2, 0, 0x042d _ 0)
+NAMED_CHARACTER_REFERENCE(138, /* E d */ 'o' _ 't' _ ';', 3, 0, 0x0116 _ 0)
+NAMED_CHARACTER_REFERENCE(139, /* E f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd08)
+NAMED_CHARACTER_REFERENCE(140, /* E g */ 'r' _ 'a' _ 'v' _ 'e', 4, 0, 0x00c8 _ 0)
+NAMED_CHARACTER_REFERENCE(141, /* E g */ 'r' _ 'a' _ 'v' _ 'e' _ ';', 5, 0, 0x00c8 _ 0)
+NAMED_CHARACTER_REFERENCE(142, /* E l */ 'e' _ 'm' _ 'e' _ 'n' _ 't' _ ';', 6, 0, 0x2208 _ 0)
+NAMED_CHARACTER_REFERENCE(143, /* E m */ 'a' _ 'c' _ 'r' _ ';', 4, 0, 0x0112 _ 0)
+NAMED_CHARACTER_REFERENCE(144, /* E m */ 'p' _ 't' _ 'y' _ 'S' _ 'm' _ 'a' _ 'l' _ 'l' _ 'S' _ 'q' _ 'u' _ 'a' _ 'r' _ 'e' _ ';', 15, 0, 0x25fb _ 0)
+NAMED_CHARACTER_REFERENCE(145, /* E m */ 'p' _ 't' _ 'y' _ 'V' _ 'e' _ 'r' _ 'y' _ 'S' _ 'm' _ 'a' _ 'l' _ 'l' _ 'S' _ 'q' _ 'u' _ 'a' _ 'r' _ 'e' _ ';', 19, 0, 0x25ab _ 0)
+NAMED_CHARACTER_REFERENCE(146, /* E o */ 'g' _ 'o' _ 'n' _ ';', 4, 0, 0x0118 _ 0)
+NAMED_CHARACTER_REFERENCE(147, /* E o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd3c)
+NAMED_CHARACTER_REFERENCE(148, /* E p */ 's' _ 'i' _ 'l' _ 'o' _ 'n' _ ';', 6, 0, 0x0395 _ 0)
+NAMED_CHARACTER_REFERENCE(149, /* E q */ 'u' _ 'a' _ 'l' _ ';', 4, 0, 0x2a75 _ 0)
+NAMED_CHARACTER_REFERENCE(150, /* E q */ 'u' _ 'a' _ 'l' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 9, 0, 0x2242 _ 0)
+NAMED_CHARACTER_REFERENCE(151, /* E q */ 'u' _ 'i' _ 'l' _ 'i' _ 'b' _ 'r' _ 'i' _ 'u' _ 'm' _ ';', 10, 0, 0x21cc _ 0)
+NAMED_CHARACTER_REFERENCE(152, /* E s */ 'c' _ 'r' _ ';', 3, 0, 0x2130 _ 0)
+NAMED_CHARACTER_REFERENCE(153, /* E s */ 'i' _ 'm' _ ';', 3, 0, 0x2a73 _ 0)
+NAMED_CHARACTER_REFERENCE(154, /* E t */ 'a' _ ';', 2, 0, 0x0397 _ 0)
+NAMED_CHARACTER_REFERENCE(155, /* E u */ 'm' _ 'l', 2, 0, 0x00cb _ 0)
+NAMED_CHARACTER_REFERENCE(156, /* E u */ 'm' _ 'l' _ ';', 3, 0, 0x00cb _ 0)
+NAMED_CHARACTER_REFERENCE(157, /* E x */ 'i' _ 's' _ 't' _ 's' _ ';', 5, 0, 0x2203 _ 0)
+NAMED_CHARACTER_REFERENCE(158, /* E x */ 'p' _ 'o' _ 'n' _ 'e' _ 'n' _ 't' _ 'i' _ 'a' _ 'l' _ 'E' _ ';', 11, 0, 0x2147 _ 0)
+NAMED_CHARACTER_REFERENCE(159, /* F c */ 'y' _ ';', 2, 0, 0x0424 _ 0)
+NAMED_CHARACTER_REFERENCE(160, /* F f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd09)
+NAMED_CHARACTER_REFERENCE(161, /* F i */ 'l' _ 'l' _ 'e' _ 'd' _ 'S' _ 'm' _ 'a' _ 'l' _ 'l' _ 'S' _ 'q' _ 'u' _ 'a' _ 'r' _ 'e' _ ';', 16, 0, 0x25fc _ 0)
+NAMED_CHARACTER_REFERENCE(162, /* F i */ 'l' _ 'l' _ 'e' _ 'd' _ 'V' _ 'e' _ 'r' _ 'y' _ 'S' _ 'm' _ 'a' _ 'l' _ 'l' _ 'S' _ 'q' _ 'u' _ 'a' _ 'r' _ 'e' _ ';', 20, 0, 0x25aa _ 0)
+NAMED_CHARACTER_REFERENCE(163, /* F o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd3d)
+NAMED_CHARACTER_REFERENCE(164, /* F o */ 'r' _ 'A' _ 'l' _ 'l' _ ';', 5, 0, 0x2200 _ 0)
+NAMED_CHARACTER_REFERENCE(165, /* F o */ 'u' _ 'r' _ 'i' _ 'e' _ 'r' _ 't' _ 'r' _ 'f' _ ';', 9, 0, 0x2131 _ 0)
+NAMED_CHARACTER_REFERENCE(166, /* F s */ 'c' _ 'r' _ ';', 3, 0, 0x2131 _ 0)
+NAMED_CHARACTER_REFERENCE(167, /* G J */ 'c' _ 'y' _ ';', 3, 0, 0x0403 _ 0)
+NAMED_CHARACTER_REFERENCE(168, /* G T */ 0, 0, 1, 0x003e _ 0)
+NAMED_CHARACTER_REFERENCE(169, /* G T */ ';', 1, 0, 0x003e _ 0)
+NAMED_CHARACTER_REFERENCE(170, /* G a */ 'm' _ 'm' _ 'a' _ ';', 4, 0, 0x0393 _ 0)
+NAMED_CHARACTER_REFERENCE(171, /* G a */ 'm' _ 'm' _ 'a' _ 'd' _ ';', 5, 0, 0x03dc _ 0)
+NAMED_CHARACTER_REFERENCE(172, /* G b */ 'r' _ 'e' _ 'v' _ 'e' _ ';', 5, 0, 0x011e _ 0)
+NAMED_CHARACTER_REFERENCE(173, /* G c */ 'e' _ 'd' _ 'i' _ 'l' _ ';', 5, 0, 0x0122 _ 0)
+NAMED_CHARACTER_REFERENCE(174, /* G c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x011c _ 0)
+NAMED_CHARACTER_REFERENCE(175, /* G c */ 'y' _ ';', 2, 0, 0x0413 _ 0)
+NAMED_CHARACTER_REFERENCE(176, /* G d */ 'o' _ 't' _ ';', 3, 0, 0x0120 _ 0)
+NAMED_CHARACTER_REFERENCE(177, /* G f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd0a)
+NAMED_CHARACTER_REFERENCE(178, /* G g */ ';', 1, 0, 0x22d9 _ 0)
+NAMED_CHARACTER_REFERENCE(179, /* G o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd3e)
+NAMED_CHARACTER_REFERENCE(180, /* G r */ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 11, 0, 0x2265 _ 0)
+NAMED_CHARACTER_REFERENCE(181, /* G r */ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ 'L' _ 'e' _ 's' _ 's' _ ';', 15, 0, 0x22db _ 0)
+NAMED_CHARACTER_REFERENCE(182, /* G r */ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ 'F' _ 'u' _ 'l' _ 'l' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 15, 0, 0x2267 _ 0)
+NAMED_CHARACTER_REFERENCE(183, /* G r */ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ ';', 13, 0, 0x2aa2 _ 0)
+NAMED_CHARACTER_REFERENCE(184, /* G r */ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ 'L' _ 'e' _ 's' _ 's' _ ';', 10, 0, 0x2277 _ 0)
+NAMED_CHARACTER_REFERENCE(185, /* G r */ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ 'S' _ 'l' _ 'a' _ 'n' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 16, 0, 0x2a7e _ 0)
+NAMED_CHARACTER_REFERENCE(186, /* G r */ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 11, 0, 0x2273 _ 0)
+NAMED_CHARACTER_REFERENCE(187, /* G s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdca2)
+NAMED_CHARACTER_REFERENCE(188, /* G t */ ';', 1, 0, 0x226b _ 0)
+NAMED_CHARACTER_REFERENCE(189, /* H A */ 'R' _ 'D' _ 'c' _ 'y' _ ';', 5, 0, 0x042a _ 0)
+NAMED_CHARACTER_REFERENCE(190, /* H a */ 'c' _ 'e' _ 'k' _ ';', 4, 0, 0x02c7 _ 0)
+NAMED_CHARACTER_REFERENCE(191, /* H a */ 't' _ ';', 2, 0, 0x005e _ 0)
+NAMED_CHARACTER_REFERENCE(192, /* H c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x0124 _ 0)
+NAMED_CHARACTER_REFERENCE(193, /* H f */ 'r' _ ';', 2, 0, 0x210c _ 0)
+NAMED_CHARACTER_REFERENCE(194, /* H i */ 'l' _ 'b' _ 'e' _ 'r' _ 't' _ 'S' _ 'p' _ 'a' _ 'c' _ 'e' _ ';', 11, 0, 0x210b _ 0)
+NAMED_CHARACTER_REFERENCE(195, /* H o */ 'p' _ 'f' _ ';', 3, 0, 0x210d _ 0)
+NAMED_CHARACTER_REFERENCE(196, /* H o */ 'r' _ 'i' _ 'z' _ 'o' _ 'n' _ 't' _ 'a' _ 'l' _ 'L' _ 'i' _ 'n' _ 'e' _ ';', 13, 0, 0x2500 _ 0)
+NAMED_CHARACTER_REFERENCE(197, /* H s */ 'c' _ 'r' _ ';', 3, 0, 0x210b _ 0)
+NAMED_CHARACTER_REFERENCE(198, /* H s */ 't' _ 'r' _ 'o' _ 'k' _ ';', 5, 0, 0x0126 _ 0)
+NAMED_CHARACTER_REFERENCE(199, /* H u */ 'm' _ 'p' _ 'D' _ 'o' _ 'w' _ 'n' _ 'H' _ 'u' _ 'm' _ 'p' _ ';', 11, 0, 0x224e _ 0)
+NAMED_CHARACTER_REFERENCE(200, /* H u */ 'm' _ 'p' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 8, 0, 0x224f _ 0)
+NAMED_CHARACTER_REFERENCE(201, /* I E */ 'c' _ 'y' _ ';', 3, 0, 0x0415 _ 0)
+NAMED_CHARACTER_REFERENCE(202, /* I J */ 'l' _ 'i' _ 'g' _ ';', 4, 0, 0x0132 _ 0)
+NAMED_CHARACTER_REFERENCE(203, /* I O */ 'c' _ 'y' _ ';', 3, 0, 0x0401 _ 0)
+NAMED_CHARACTER_REFERENCE(204, /* I a */ 'c' _ 'u' _ 't' _ 'e', 4, 0, 0x00cd _ 0)
+NAMED_CHARACTER_REFERENCE(205, /* I a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x00cd _ 0)
+NAMED_CHARACTER_REFERENCE(206, /* I c */ 'i' _ 'r' _ 'c', 3, 0, 0x00ce _ 0)
+NAMED_CHARACTER_REFERENCE(207, /* I c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x00ce _ 0)
+NAMED_CHARACTER_REFERENCE(208, /* I c */ 'y' _ ';', 2, 0, 0x0418 _ 0)
+NAMED_CHARACTER_REFERENCE(209, /* I d */ 'o' _ 't' _ ';', 3, 0, 0x0130 _ 0)
+NAMED_CHARACTER_REFERENCE(210, /* I f */ 'r' _ ';', 2, 0, 0x2111 _ 0)
+NAMED_CHARACTER_REFERENCE(211, /* I g */ 'r' _ 'a' _ 'v' _ 'e', 4, 0, 0x00cc _ 0)
+NAMED_CHARACTER_REFERENCE(212, /* I g */ 'r' _ 'a' _ 'v' _ 'e' _ ';', 5, 0, 0x00cc _ 0)
+NAMED_CHARACTER_REFERENCE(213, /* I m */ ';', 1, 0, 0x2111 _ 0)
+NAMED_CHARACTER_REFERENCE(214, /* I m */ 'a' _ 'c' _ 'r' _ ';', 4, 0, 0x012a _ 0)
+NAMED_CHARACTER_REFERENCE(215, /* I m */ 'a' _ 'g' _ 'i' _ 'n' _ 'a' _ 'r' _ 'y' _ 'I' _ ';', 9, 0, 0x2148 _ 0)
+NAMED_CHARACTER_REFERENCE(216, /* I m */ 'p' _ 'l' _ 'i' _ 'e' _ 's' _ ';', 6, 0, 0x21d2 _ 0)
+NAMED_CHARACTER_REFERENCE(217, /* I n */ 't' _ ';', 2, 0, 0x222c _ 0)
+NAMED_CHARACTER_REFERENCE(218, /* I n */ 't' _ 'e' _ 'g' _ 'r' _ 'a' _ 'l' _ ';', 7, 0, 0x222b _ 0)
+NAMED_CHARACTER_REFERENCE(219, /* I n */ 't' _ 'e' _ 'r' _ 's' _ 'e' _ 'c' _ 't' _ 'i' _ 'o' _ 'n' _ ';', 11, 0, 0x22c2 _ 0)
+NAMED_CHARACTER_REFERENCE(220, /* I n */ 'v' _ 'i' _ 's' _ 'i' _ 'b' _ 'l' _ 'e' _ 'C' _ 'o' _ 'm' _ 'm' _ 'a' _ ';', 13, 0, 0x2063 _ 0)
+NAMED_CHARACTER_REFERENCE(221, /* I n */ 'v' _ 'i' _ 's' _ 'i' _ 'b' _ 'l' _ 'e' _ 'T' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 13, 0, 0x2062 _ 0)
+NAMED_CHARACTER_REFERENCE(222, /* I o */ 'g' _ 'o' _ 'n' _ ';', 4, 0, 0x012e _ 0)
+NAMED_CHARACTER_REFERENCE(223, /* I o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd40)
+NAMED_CHARACTER_REFERENCE(224, /* I o */ 't' _ 'a' _ ';', 3, 0, 0x0399 _ 0)
+NAMED_CHARACTER_REFERENCE(225, /* I s */ 'c' _ 'r' _ ';', 3, 0, 0x2110 _ 0)
+NAMED_CHARACTER_REFERENCE(226, /* I t */ 'i' _ 'l' _ 'd' _ 'e' _ ';', 5, 0, 0x0128 _ 0)
+NAMED_CHARACTER_REFERENCE(227, /* I u */ 'k' _ 'c' _ 'y' _ ';', 4, 0, 0x0406 _ 0)
+NAMED_CHARACTER_REFERENCE(228, /* I u */ 'm' _ 'l', 2, 0, 0x00cf _ 0)
+NAMED_CHARACTER_REFERENCE(229, /* I u */ 'm' _ 'l' _ ';', 3, 0, 0x00cf _ 0)
+NAMED_CHARACTER_REFERENCE(230, /* J c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x0134 _ 0)
+NAMED_CHARACTER_REFERENCE(231, /* J c */ 'y' _ ';', 2, 0, 0x0419 _ 0)
+NAMED_CHARACTER_REFERENCE(232, /* J f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd0d)
+NAMED_CHARACTER_REFERENCE(233, /* J o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd41)
+NAMED_CHARACTER_REFERENCE(234, /* J s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdca5)
+NAMED_CHARACTER_REFERENCE(235, /* J s */ 'e' _ 'r' _ 'c' _ 'y' _ ';', 5, 0, 0x0408 _ 0)
+NAMED_CHARACTER_REFERENCE(236, /* J u */ 'k' _ 'c' _ 'y' _ ';', 4, 0, 0x0404 _ 0)
+NAMED_CHARACTER_REFERENCE(237, /* K H */ 'c' _ 'y' _ ';', 3, 0, 0x0425 _ 0)
+NAMED_CHARACTER_REFERENCE(238, /* K J */ 'c' _ 'y' _ ';', 3, 0, 0x040c _ 0)
+NAMED_CHARACTER_REFERENCE(239, /* K a */ 'p' _ 'p' _ 'a' _ ';', 4, 0, 0x039a _ 0)
+NAMED_CHARACTER_REFERENCE(240, /* K c */ 'e' _ 'd' _ 'i' _ 'l' _ ';', 5, 0, 0x0136 _ 0)
+NAMED_CHARACTER_REFERENCE(241, /* K c */ 'y' _ ';', 2, 0, 0x041a _ 0)
+NAMED_CHARACTER_REFERENCE(242, /* K f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd0e)
+NAMED_CHARACTER_REFERENCE(243, /* K o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd42)
+NAMED_CHARACTER_REFERENCE(244, /* K s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdca6)
+NAMED_CHARACTER_REFERENCE(245, /* L J */ 'c' _ 'y' _ ';', 3, 0, 0x0409 _ 0)
+NAMED_CHARACTER_REFERENCE(246, /* L T */ 0, 0, 1, 0x003c _ 0)
+NAMED_CHARACTER_REFERENCE(247, /* L T */ ';', 1, 0, 0x003c _ 0)
+NAMED_CHARACTER_REFERENCE(248, /* L a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x0139 _ 0)
+NAMED_CHARACTER_REFERENCE(249, /* L a */ 'm' _ 'b' _ 'd' _ 'a' _ ';', 5, 0, 0x039b _ 0)
+NAMED_CHARACTER_REFERENCE(250, /* L a */ 'n' _ 'g' _ ';', 3, 0, 0x27ea _ 0)
+NAMED_CHARACTER_REFERENCE(251, /* L a */ 'p' _ 'l' _ 'a' _ 'c' _ 'e' _ 't' _ 'r' _ 'f' _ ';', 9, 0, 0x2112 _ 0)
+NAMED_CHARACTER_REFERENCE(252, /* L a */ 'r' _ 'r' _ ';', 3, 0, 0x219e _ 0)
+NAMED_CHARACTER_REFERENCE(253, /* L c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x013d _ 0)
+NAMED_CHARACTER_REFERENCE(254, /* L c */ 'e' _ 'd' _ 'i' _ 'l' _ ';', 5, 0, 0x013b _ 0)
+NAMED_CHARACTER_REFERENCE(255, /* L c */ 'y' _ ';', 2, 0, 0x041b _ 0)
+NAMED_CHARACTER_REFERENCE(256, /* L e */ 'f' _ 't' _ 'A' _ 'n' _ 'g' _ 'l' _ 'e' _ 'B' _ 'r' _ 'a' _ 'c' _ 'k' _ 'e' _ 't' _ ';', 15, 0, 0x27e8 _ 0)
+NAMED_CHARACTER_REFERENCE(257, /* L e */ 'f' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 8, 0, 0x2190 _ 0)
+NAMED_CHARACTER_REFERENCE(258, /* L e */ 'f' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ 'B' _ 'a' _ 'r' _ ';', 11, 0, 0x21e4 _ 0)
+NAMED_CHARACTER_REFERENCE(259, /* L e */ 'f' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 18, 0, 0x21c6 _ 0)
+NAMED_CHARACTER_REFERENCE(260, /* L e */ 'f' _ 't' _ 'C' _ 'e' _ 'i' _ 'l' _ 'i' _ 'n' _ 'g' _ ';', 10, 0, 0x2308 _ 0)
+NAMED_CHARACTER_REFERENCE(261, /* L e */ 'f' _ 't' _ 'D' _ 'o' _ 'u' _ 'b' _ 'l' _ 'e' _ 'B' _ 'r' _ 'a' _ 'c' _ 'k' _ 'e' _ 't' _ ';', 16, 0, 0x27e6 _ 0)
+NAMED_CHARACTER_REFERENCE(262, /* L e */ 'f' _ 't' _ 'D' _ 'o' _ 'w' _ 'n' _ 'T' _ 'e' _ 'e' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 16, 0, 0x2961 _ 0)
+NAMED_CHARACTER_REFERENCE(263, /* L e */ 'f' _ 't' _ 'D' _ 'o' _ 'w' _ 'n' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 13, 0, 0x21c3 _ 0)
+NAMED_CHARACTER_REFERENCE(264, /* L e */ 'f' _ 't' _ 'D' _ 'o' _ 'w' _ 'n' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ 'B' _ 'a' _ 'r' _ ';', 16, 0, 0x2959 _ 0)
+NAMED_CHARACTER_REFERENCE(265, /* L e */ 'f' _ 't' _ 'F' _ 'l' _ 'o' _ 'o' _ 'r' _ ';', 8, 0, 0x230a _ 0)
+NAMED_CHARACTER_REFERENCE(266, /* L e */ 'f' _ 't' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 13, 0, 0x2194 _ 0)
+NAMED_CHARACTER_REFERENCE(267, /* L e */ 'f' _ 't' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 14, 0, 0x294e _ 0)
+NAMED_CHARACTER_REFERENCE(268, /* L e */ 'f' _ 't' _ 'T' _ 'e' _ 'e' _ ';', 6, 0, 0x22a3 _ 0)
+NAMED_CHARACTER_REFERENCE(269, /* L e */ 'f' _ 't' _ 'T' _ 'e' _ 'e' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 11, 0, 0x21a4 _ 0)
+NAMED_CHARACTER_REFERENCE(270, /* L e */ 'f' _ 't' _ 'T' _ 'e' _ 'e' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 12, 0, 0x295a _ 0)
+NAMED_CHARACTER_REFERENCE(271, /* L e */ 'f' _ 't' _ 'T' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 11, 0, 0x22b2 _ 0)
+NAMED_CHARACTER_REFERENCE(272, /* L e */ 'f' _ 't' _ 'T' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'B' _ 'a' _ 'r' _ ';', 14, 0, 0x29cf _ 0)
+NAMED_CHARACTER_REFERENCE(273, /* L e */ 'f' _ 't' _ 'T' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 16, 0, 0x22b4 _ 0)
+NAMED_CHARACTER_REFERENCE(274, /* L e */ 'f' _ 't' _ 'U' _ 'p' _ 'D' _ 'o' _ 'w' _ 'n' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 15, 0, 0x2951 _ 0)
+NAMED_CHARACTER_REFERENCE(275, /* L e */ 'f' _ 't' _ 'U' _ 'p' _ 'T' _ 'e' _ 'e' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 14, 0, 0x2960 _ 0)
+NAMED_CHARACTER_REFERENCE(276, /* L e */ 'f' _ 't' _ 'U' _ 'p' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 11, 0, 0x21bf _ 0)
+NAMED_CHARACTER_REFERENCE(277, /* L e */ 'f' _ 't' _ 'U' _ 'p' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ 'B' _ 'a' _ 'r' _ ';', 14, 0, 0x2958 _ 0)
+NAMED_CHARACTER_REFERENCE(278, /* L e */ 'f' _ 't' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 9, 0, 0x21bc _ 0)
+NAMED_CHARACTER_REFERENCE(279, /* L e */ 'f' _ 't' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ 'B' _ 'a' _ 'r' _ ';', 12, 0, 0x2952 _ 0)
+NAMED_CHARACTER_REFERENCE(280, /* L e */ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 8, 0, 0x21d0 _ 0)
+NAMED_CHARACTER_REFERENCE(281, /* L e */ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 13, 0, 0x21d4 _ 0)
+NAMED_CHARACTER_REFERENCE(282, /* L e */ 's' _ 's' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ ';', 15, 0, 0x22da _ 0)
+NAMED_CHARACTER_REFERENCE(283, /* L e */ 's' _ 's' _ 'F' _ 'u' _ 'l' _ 'l' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 12, 0, 0x2266 _ 0)
+NAMED_CHARACTER_REFERENCE(284, /* L e */ 's' _ 's' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ ';', 10, 0, 0x2276 _ 0)
+NAMED_CHARACTER_REFERENCE(285, /* L e */ 's' _ 's' _ 'L' _ 'e' _ 's' _ 's' _ ';', 7, 0, 0x2aa1 _ 0)
+NAMED_CHARACTER_REFERENCE(286, /* L e */ 's' _ 's' _ 'S' _ 'l' _ 'a' _ 'n' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 13, 0, 0x2a7d _ 0)
+NAMED_CHARACTER_REFERENCE(287, /* L e */ 's' _ 's' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 8, 0, 0x2272 _ 0)
+NAMED_CHARACTER_REFERENCE(288, /* L f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd0f)
+NAMED_CHARACTER_REFERENCE(289, /* L l */ ';', 1, 0, 0x22d8 _ 0)
+NAMED_CHARACTER_REFERENCE(290, /* L l */ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 9, 0, 0x21da _ 0)
+NAMED_CHARACTER_REFERENCE(291, /* L m */ 'i' _ 'd' _ 'o' _ 't' _ ';', 5, 0, 0x013f _ 0)
+NAMED_CHARACTER_REFERENCE(292, /* L o */ 'n' _ 'g' _ 'L' _ 'e' _ 'f' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 12, 0, 0x27f5 _ 0)
+NAMED_CHARACTER_REFERENCE(293, /* L o */ 'n' _ 'g' _ 'L' _ 'e' _ 'f' _ 't' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 17, 0, 0x27f7 _ 0)
+NAMED_CHARACTER_REFERENCE(294, /* L o */ 'n' _ 'g' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 13, 0, 0x27f6 _ 0)
+NAMED_CHARACTER_REFERENCE(295, /* L o */ 'n' _ 'g' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 12, 0, 0x27f8 _ 0)
+NAMED_CHARACTER_REFERENCE(296, /* L o */ 'n' _ 'g' _ 'l' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 17, 0, 0x27fa _ 0)
+NAMED_CHARACTER_REFERENCE(297, /* L o */ 'n' _ 'g' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 13, 0, 0x27f9 _ 0)
+NAMED_CHARACTER_REFERENCE(298, /* L o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd43)
+NAMED_CHARACTER_REFERENCE(299, /* L o */ 'w' _ 'e' _ 'r' _ 'L' _ 'e' _ 'f' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 13, 0, 0x2199 _ 0)
+NAMED_CHARACTER_REFERENCE(300, /* L o */ 'w' _ 'e' _ 'r' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 14, 0, 0x2198 _ 0)
+NAMED_CHARACTER_REFERENCE(301, /* L s */ 'c' _ 'r' _ ';', 3, 0, 0x2112 _ 0)
+NAMED_CHARACTER_REFERENCE(302, /* L s */ 'h' _ ';', 2, 0, 0x21b0 _ 0)
+NAMED_CHARACTER_REFERENCE(303, /* L s */ 't' _ 'r' _ 'o' _ 'k' _ ';', 5, 0, 0x0141 _ 0)
+NAMED_CHARACTER_REFERENCE(304, /* L t */ ';', 1, 0, 0x226a _ 0)
+NAMED_CHARACTER_REFERENCE(305, /* M a */ 'p' _ ';', 2, 0, 0x2905 _ 0)
+NAMED_CHARACTER_REFERENCE(306, /* M c */ 'y' _ ';', 2, 0, 0x041c _ 0)
+NAMED_CHARACTER_REFERENCE(307, /* M e */ 'd' _ 'i' _ 'u' _ 'm' _ 'S' _ 'p' _ 'a' _ 'c' _ 'e' _ ';', 10, 0, 0x205f _ 0)
+NAMED_CHARACTER_REFERENCE(308, /* M e */ 'l' _ 'l' _ 'i' _ 'n' _ 't' _ 'r' _ 'f' _ ';', 8, 0, 0x2133 _ 0)
+NAMED_CHARACTER_REFERENCE(309, /* M f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd10)
+NAMED_CHARACTER_REFERENCE(310, /* M i */ 'n' _ 'u' _ 's' _ 'P' _ 'l' _ 'u' _ 's' _ ';', 8, 0, 0x2213 _ 0)
+NAMED_CHARACTER_REFERENCE(311, /* M o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd44)
+NAMED_CHARACTER_REFERENCE(312, /* M s */ 'c' _ 'r' _ ';', 3, 0, 0x2133 _ 0)
+NAMED_CHARACTER_REFERENCE(313, /* M u */ ';', 1, 0, 0x039c _ 0)
+NAMED_CHARACTER_REFERENCE(314, /* N J */ 'c' _ 'y' _ ';', 3, 0, 0x040a _ 0)
+NAMED_CHARACTER_REFERENCE(315, /* N a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x0143 _ 0)
+NAMED_CHARACTER_REFERENCE(316, /* N c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x0147 _ 0)
+NAMED_CHARACTER_REFERENCE(317, /* N c */ 'e' _ 'd' _ 'i' _ 'l' _ ';', 5, 0, 0x0145 _ 0)
+NAMED_CHARACTER_REFERENCE(318, /* N c */ 'y' _ ';', 2, 0, 0x041d _ 0)
+NAMED_CHARACTER_REFERENCE(319, /* N e */ 'g' _ 'a' _ 't' _ 'i' _ 'v' _ 'e' _ 'M' _ 'e' _ 'd' _ 'i' _ 'u' _ 'm' _ 'S' _ 'p' _ 'a' _ 'c' _ 'e' _ ';', 18, 0, 0x200b _ 0)
+NAMED_CHARACTER_REFERENCE(320, /* N e */ 'g' _ 'a' _ 't' _ 'i' _ 'v' _ 'e' _ 'T' _ 'h' _ 'i' _ 'c' _ 'k' _ 'S' _ 'p' _ 'a' _ 'c' _ 'e' _ ';', 17, 0, 0x200b _ 0)
+NAMED_CHARACTER_REFERENCE(321, /* N e */ 'g' _ 'a' _ 't' _ 'i' _ 'v' _ 'e' _ 'T' _ 'h' _ 'i' _ 'n' _ 'S' _ 'p' _ 'a' _ 'c' _ 'e' _ ';', 16, 0, 0x200b _ 0)
+NAMED_CHARACTER_REFERENCE(322, /* N e */ 'g' _ 'a' _ 't' _ 'i' _ 'v' _ 'e' _ 'V' _ 'e' _ 'r' _ 'y' _ 'T' _ 'h' _ 'i' _ 'n' _ 'S' _ 'p' _ 'a' _ 'c' _ 'e' _ ';', 20, 0, 0x200b _ 0)
+NAMED_CHARACTER_REFERENCE(323, /* N e */ 's' _ 't' _ 'e' _ 'd' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ ';', 19, 0, 0x226b _ 0)
+NAMED_CHARACTER_REFERENCE(324, /* N e */ 's' _ 't' _ 'e' _ 'd' _ 'L' _ 'e' _ 's' _ 's' _ 'L' _ 'e' _ 's' _ 's' _ ';', 13, 0, 0x226a _ 0)
+NAMED_CHARACTER_REFERENCE(325, /* N e */ 'w' _ 'L' _ 'i' _ 'n' _ 'e' _ ';', 6, 0, 0x000a _ 0)
+NAMED_CHARACTER_REFERENCE(326, /* N f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd11)
+NAMED_CHARACTER_REFERENCE(327, /* N o */ 'B' _ 'r' _ 'e' _ 'a' _ 'k' _ ';', 6, 0, 0x2060 _ 0)
+NAMED_CHARACTER_REFERENCE(328, /* N o */ 'n' _ 'B' _ 'r' _ 'e' _ 'a' _ 'k' _ 'i' _ 'n' _ 'g' _ 'S' _ 'p' _ 'a' _ 'c' _ 'e' _ ';', 15, 0, 0x00a0 _ 0)
+NAMED_CHARACTER_REFERENCE(329, /* N o */ 'p' _ 'f' _ ';', 3, 0, 0x2115 _ 0)
+NAMED_CHARACTER_REFERENCE(330, /* N o */ 't' _ ';', 2, 0, 0x2aec _ 0)
+NAMED_CHARACTER_REFERENCE(331, /* N o */ 't' _ 'C' _ 'o' _ 'n' _ 'g' _ 'r' _ 'u' _ 'e' _ 'n' _ 't' _ ';', 11, 0, 0x2262 _ 0)
+NAMED_CHARACTER_REFERENCE(332, /* N o */ 't' _ 'C' _ 'u' _ 'p' _ 'C' _ 'a' _ 'p' _ ';', 8, 0, 0x226d _ 0)
+NAMED_CHARACTER_REFERENCE(333, /* N o */ 't' _ 'D' _ 'o' _ 'u' _ 'b' _ 'l' _ 'e' _ 'V' _ 'e' _ 'r' _ 't' _ 'i' _ 'c' _ 'a' _ 'l' _ 'B' _ 'a' _ 'r' _ ';', 19, 0, 0x2226 _ 0)
+NAMED_CHARACTER_REFERENCE(334, /* N o */ 't' _ 'E' _ 'l' _ 'e' _ 'm' _ 'e' _ 'n' _ 't' _ ';', 9, 0, 0x2209 _ 0)
+NAMED_CHARACTER_REFERENCE(335, /* N o */ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 7, 0, 0x2260 _ 0)
+NAMED_CHARACTER_REFERENCE(336, /* N o */ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 12, 0, 0x2242 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(337, /* N o */ 't' _ 'E' _ 'x' _ 'i' _ 's' _ 't' _ 's' _ ';', 8, 0, 0x2204 _ 0)
+NAMED_CHARACTER_REFERENCE(338, /* N o */ 't' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ ';', 9, 0, 0x226f _ 0)
+NAMED_CHARACTER_REFERENCE(339, /* N o */ 't' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 14, 0, 0x2271 _ 0)
+NAMED_CHARACTER_REFERENCE(340, /* N o */ 't' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ 'F' _ 'u' _ 'l' _ 'l' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 18, 0, 0x2267 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(341, /* N o */ 't' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ ';', 16, 0, 0x226b _ 0x0338)
+NAMED_CHARACTER_REFERENCE(342, /* N o */ 't' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ 'L' _ 'e' _ 's' _ 's' _ ';', 13, 0, 0x2279 _ 0)
+NAMED_CHARACTER_REFERENCE(343, /* N o */ 't' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ 'S' _ 'l' _ 'a' _ 'n' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 19, 0, 0x2a7e _ 0x0338)
+NAMED_CHARACTER_REFERENCE(344, /* N o */ 't' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 14, 0, 0x2275 _ 0)
+NAMED_CHARACTER_REFERENCE(345, /* N o */ 't' _ 'H' _ 'u' _ 'm' _ 'p' _ 'D' _ 'o' _ 'w' _ 'n' _ 'H' _ 'u' _ 'm' _ 'p' _ ';', 14, 0, 0x224e _ 0x0338)
+NAMED_CHARACTER_REFERENCE(346, /* N o */ 't' _ 'H' _ 'u' _ 'm' _ 'p' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 11, 0, 0x224f _ 0x0338)
+NAMED_CHARACTER_REFERENCE(347, /* N o */ 't' _ 'L' _ 'e' _ 'f' _ 't' _ 'T' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 14, 0, 0x22ea _ 0)
+NAMED_CHARACTER_REFERENCE(348, /* N o */ 't' _ 'L' _ 'e' _ 'f' _ 't' _ 'T' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'B' _ 'a' _ 'r' _ ';', 17, 0, 0x29cf _ 0x0338)
+NAMED_CHARACTER_REFERENCE(349, /* N o */ 't' _ 'L' _ 'e' _ 'f' _ 't' _ 'T' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 19, 0, 0x22ec _ 0)
+NAMED_CHARACTER_REFERENCE(350, /* N o */ 't' _ 'L' _ 'e' _ 's' _ 's' _ ';', 6, 0, 0x226e _ 0)
+NAMED_CHARACTER_REFERENCE(351, /* N o */ 't' _ 'L' _ 'e' _ 's' _ 's' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 11, 0, 0x2270 _ 0)
+NAMED_CHARACTER_REFERENCE(352, /* N o */ 't' _ 'L' _ 'e' _ 's' _ 's' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ ';', 13, 0, 0x2278 _ 0)
+NAMED_CHARACTER_REFERENCE(353, /* N o */ 't' _ 'L' _ 'e' _ 's' _ 's' _ 'L' _ 'e' _ 's' _ 's' _ ';', 10, 0, 0x226a _ 0x0338)
+NAMED_CHARACTER_REFERENCE(354, /* N o */ 't' _ 'L' _ 'e' _ 's' _ 's' _ 'S' _ 'l' _ 'a' _ 'n' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 16, 0, 0x2a7d _ 0x0338)
+NAMED_CHARACTER_REFERENCE(355, /* N o */ 't' _ 'L' _ 'e' _ 's' _ 's' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 11, 0, 0x2274 _ 0)
+NAMED_CHARACTER_REFERENCE(356, /* N o */ 't' _ 'N' _ 'e' _ 's' _ 't' _ 'e' _ 'd' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ 'G' _ 'r' _ 'e' _ 'a' _ 't' _ 'e' _ 'r' _ ';', 22, 0, 0x2aa2 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(357, /* N o */ 't' _ 'N' _ 'e' _ 's' _ 't' _ 'e' _ 'd' _ 'L' _ 'e' _ 's' _ 's' _ 'L' _ 'e' _ 's' _ 's' _ ';', 16, 0, 0x2aa1 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(358, /* N o */ 't' _ 'P' _ 'r' _ 'e' _ 'c' _ 'e' _ 'd' _ 'e' _ 's' _ ';', 10, 0, 0x2280 _ 0)
+NAMED_CHARACTER_REFERENCE(359, /* N o */ 't' _ 'P' _ 'r' _ 'e' _ 'c' _ 'e' _ 'd' _ 'e' _ 's' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 15, 0, 0x2aaf _ 0x0338)
+NAMED_CHARACTER_REFERENCE(360, /* N o */ 't' _ 'P' _ 'r' _ 'e' _ 'c' _ 'e' _ 'd' _ 'e' _ 's' _ 'S' _ 'l' _ 'a' _ 'n' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 20, 0, 0x22e0 _ 0)
+NAMED_CHARACTER_REFERENCE(361, /* N o */ 't' _ 'R' _ 'e' _ 'v' _ 'e' _ 'r' _ 's' _ 'e' _ 'E' _ 'l' _ 'e' _ 'm' _ 'e' _ 'n' _ 't' _ ';', 16, 0, 0x220c _ 0)
+NAMED_CHARACTER_REFERENCE(362, /* N o */ 't' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'T' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 15, 0, 0x22eb _ 0)
+NAMED_CHARACTER_REFERENCE(363, /* N o */ 't' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'T' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'B' _ 'a' _ 'r' _ ';', 18, 0, 0x29d0 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(364, /* N o */ 't' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'T' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 20, 0, 0x22ed _ 0)
+NAMED_CHARACTER_REFERENCE(365, /* N o */ 't' _ 'S' _ 'q' _ 'u' _ 'a' _ 'r' _ 'e' _ 'S' _ 'u' _ 'b' _ 's' _ 'e' _ 't' _ ';', 14, 0, 0x228f _ 0x0338)
+NAMED_CHARACTER_REFERENCE(366, /* N o */ 't' _ 'S' _ 'q' _ 'u' _ 'a' _ 'r' _ 'e' _ 'S' _ 'u' _ 'b' _ 's' _ 'e' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 19, 0, 0x22e2 _ 0)
+NAMED_CHARACTER_REFERENCE(367, /* N o */ 't' _ 'S' _ 'q' _ 'u' _ 'a' _ 'r' _ 'e' _ 'S' _ 'u' _ 'p' _ 'e' _ 'r' _ 's' _ 'e' _ 't' _ ';', 16, 0, 0x2290 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(368, /* N o */ 't' _ 'S' _ 'q' _ 'u' _ 'a' _ 'r' _ 'e' _ 'S' _ 'u' _ 'p' _ 'e' _ 'r' _ 's' _ 'e' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 21, 0, 0x22e3 _ 0)
+NAMED_CHARACTER_REFERENCE(369, /* N o */ 't' _ 'S' _ 'u' _ 'b' _ 's' _ 'e' _ 't' _ ';', 8, 0, 0x2282 _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(370, /* N o */ 't' _ 'S' _ 'u' _ 'b' _ 's' _ 'e' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 13, 0, 0x2288 _ 0)
+NAMED_CHARACTER_REFERENCE(371, /* N o */ 't' _ 'S' _ 'u' _ 'c' _ 'c' _ 'e' _ 'e' _ 'd' _ 's' _ ';', 10, 0, 0x2281 _ 0)
+NAMED_CHARACTER_REFERENCE(372, /* N o */ 't' _ 'S' _ 'u' _ 'c' _ 'c' _ 'e' _ 'e' _ 'd' _ 's' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 15, 0, 0x2ab0 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(373, /* N o */ 't' _ 'S' _ 'u' _ 'c' _ 'c' _ 'e' _ 'e' _ 'd' _ 's' _ 'S' _ 'l' _ 'a' _ 'n' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 20, 0, 0x22e1 _ 0)
+NAMED_CHARACTER_REFERENCE(374, /* N o */ 't' _ 'S' _ 'u' _ 'c' _ 'c' _ 'e' _ 'e' _ 'd' _ 's' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 15, 0, 0x227f _ 0x0338)
+NAMED_CHARACTER_REFERENCE(375, /* N o */ 't' _ 'S' _ 'u' _ 'p' _ 'e' _ 'r' _ 's' _ 'e' _ 't' _ ';', 10, 0, 0x2283 _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(376, /* N o */ 't' _ 'S' _ 'u' _ 'p' _ 'e' _ 'r' _ 's' _ 'e' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 15, 0, 0x2289 _ 0)
+NAMED_CHARACTER_REFERENCE(377, /* N o */ 't' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 7, 0, 0x2241 _ 0)
+NAMED_CHARACTER_REFERENCE(378, /* N o */ 't' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 12, 0, 0x2244 _ 0)
+NAMED_CHARACTER_REFERENCE(379, /* N o */ 't' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ 'F' _ 'u' _ 'l' _ 'l' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 16, 0, 0x2247 _ 0)
+NAMED_CHARACTER_REFERENCE(380, /* N o */ 't' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 12, 0, 0x2249 _ 0)
+NAMED_CHARACTER_REFERENCE(381, /* N o */ 't' _ 'V' _ 'e' _ 'r' _ 't' _ 'i' _ 'c' _ 'a' _ 'l' _ 'B' _ 'a' _ 'r' _ ';', 13, 0, 0x2224 _ 0)
+NAMED_CHARACTER_REFERENCE(382, /* N s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdca9)
+NAMED_CHARACTER_REFERENCE(383, /* N t */ 'i' _ 'l' _ 'd' _ 'e', 4, 0, 0x00d1 _ 0)
+NAMED_CHARACTER_REFERENCE(384, /* N t */ 'i' _ 'l' _ 'd' _ 'e' _ ';', 5, 0, 0x00d1 _ 0)
+NAMED_CHARACTER_REFERENCE(385, /* N u */ ';', 1, 0, 0x039d _ 0)
+NAMED_CHARACTER_REFERENCE(386, /* O E */ 'l' _ 'i' _ 'g' _ ';', 4, 0, 0x0152 _ 0)
+NAMED_CHARACTER_REFERENCE(387, /* O a */ 'c' _ 'u' _ 't' _ 'e', 4, 0, 0x00d3 _ 0)
+NAMED_CHARACTER_REFERENCE(388, /* O a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x00d3 _ 0)
+NAMED_CHARACTER_REFERENCE(389, /* O c */ 'i' _ 'r' _ 'c', 3, 0, 0x00d4 _ 0)
+NAMED_CHARACTER_REFERENCE(390, /* O c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x00d4 _ 0)
+NAMED_CHARACTER_REFERENCE(391, /* O c */ 'y' _ ';', 2, 0, 0x041e _ 0)
+NAMED_CHARACTER_REFERENCE(392, /* O d */ 'b' _ 'l' _ 'a' _ 'c' _ ';', 5, 0, 0x0150 _ 0)
+NAMED_CHARACTER_REFERENCE(393, /* O f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd12)
+NAMED_CHARACTER_REFERENCE(394, /* O g */ 'r' _ 'a' _ 'v' _ 'e', 4, 0, 0x00d2 _ 0)
+NAMED_CHARACTER_REFERENCE(395, /* O g */ 'r' _ 'a' _ 'v' _ 'e' _ ';', 5, 0, 0x00d2 _ 0)
+NAMED_CHARACTER_REFERENCE(396, /* O m */ 'a' _ 'c' _ 'r' _ ';', 4, 0, 0x014c _ 0)
+NAMED_CHARACTER_REFERENCE(397, /* O m */ 'e' _ 'g' _ 'a' _ ';', 4, 0, 0x03a9 _ 0)
+NAMED_CHARACTER_REFERENCE(398, /* O m */ 'i' _ 'c' _ 'r' _ 'o' _ 'n' _ ';', 6, 0, 0x039f _ 0)
+NAMED_CHARACTER_REFERENCE(399, /* O o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd46)
+NAMED_CHARACTER_REFERENCE(400, /* O p */ 'e' _ 'n' _ 'C' _ 'u' _ 'r' _ 'l' _ 'y' _ 'D' _ 'o' _ 'u' _ 'b' _ 'l' _ 'e' _ 'Q' _ 'u' _ 'o' _ 't' _ 'e' _ ';', 19, 0, 0x201c _ 0)
+NAMED_CHARACTER_REFERENCE(401, /* O p */ 'e' _ 'n' _ 'C' _ 'u' _ 'r' _ 'l' _ 'y' _ 'Q' _ 'u' _ 'o' _ 't' _ 'e' _ ';', 13, 0, 0x2018 _ 0)
+NAMED_CHARACTER_REFERENCE(402, /* O r */ ';', 1, 0, 0x2a54 _ 0)
+NAMED_CHARACTER_REFERENCE(403, /* O s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcaa)
+NAMED_CHARACTER_REFERENCE(404, /* O s */ 'l' _ 'a' _ 's' _ 'h', 4, 0, 0x00d8 _ 0)
+NAMED_CHARACTER_REFERENCE(405, /* O s */ 'l' _ 'a' _ 's' _ 'h' _ ';', 5, 0, 0x00d8 _ 0)
+NAMED_CHARACTER_REFERENCE(406, /* O t */ 'i' _ 'l' _ 'd' _ 'e', 4, 0, 0x00d5 _ 0)
+NAMED_CHARACTER_REFERENCE(407, /* O t */ 'i' _ 'l' _ 'd' _ 'e' _ ';', 5, 0, 0x00d5 _ 0)
+NAMED_CHARACTER_REFERENCE(408, /* O t */ 'i' _ 'm' _ 'e' _ 's' _ ';', 5, 0, 0x2a37 _ 0)
+NAMED_CHARACTER_REFERENCE(409, /* O u */ 'm' _ 'l', 2, 0, 0x00d6 _ 0)
+NAMED_CHARACTER_REFERENCE(410, /* O u */ 'm' _ 'l' _ ';', 3, 0, 0x00d6 _ 0)
+NAMED_CHARACTER_REFERENCE(411, /* O v */ 'e' _ 'r' _ 'B' _ 'a' _ 'r' _ ';', 6, 0, 0x203e _ 0)
+NAMED_CHARACTER_REFERENCE(412, /* O v */ 'e' _ 'r' _ 'B' _ 'r' _ 'a' _ 'c' _ 'e' _ ';', 8, 0, 0x23de _ 0)
+NAMED_CHARACTER_REFERENCE(413, /* O v */ 'e' _ 'r' _ 'B' _ 'r' _ 'a' _ 'c' _ 'k' _ 'e' _ 't' _ ';', 10, 0, 0x23b4 _ 0)
+NAMED_CHARACTER_REFERENCE(414, /* O v */ 'e' _ 'r' _ 'P' _ 'a' _ 'r' _ 'e' _ 'n' _ 't' _ 'h' _ 'e' _ 's' _ 'i' _ 's' _ ';', 14, 0, 0x23dc _ 0)
+NAMED_CHARACTER_REFERENCE(415, /* P a */ 'r' _ 't' _ 'i' _ 'a' _ 'l' _ 'D' _ ';', 7, 0, 0x2202 _ 0)
+NAMED_CHARACTER_REFERENCE(416, /* P c */ 'y' _ ';', 2, 0, 0x041f _ 0)
+NAMED_CHARACTER_REFERENCE(417, /* P f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd13)
+NAMED_CHARACTER_REFERENCE(418, /* P h */ 'i' _ ';', 2, 0, 0x03a6 _ 0)
+NAMED_CHARACTER_REFERENCE(419, /* P i */ ';', 1, 0, 0x03a0 _ 0)
+NAMED_CHARACTER_REFERENCE(420, /* P l */ 'u' _ 's' _ 'M' _ 'i' _ 'n' _ 'u' _ 's' _ ';', 8, 0, 0x00b1 _ 0)
+NAMED_CHARACTER_REFERENCE(421, /* P o */ 'i' _ 'n' _ 'c' _ 'a' _ 'r' _ 'e' _ 'p' _ 'l' _ 'a' _ 'n' _ 'e' _ ';', 12, 0, 0x210c _ 0)
+NAMED_CHARACTER_REFERENCE(422, /* P o */ 'p' _ 'f' _ ';', 3, 0, 0x2119 _ 0)
+NAMED_CHARACTER_REFERENCE(423, /* P r */ ';', 1, 0, 0x2abb _ 0)
+NAMED_CHARACTER_REFERENCE(424, /* P r */ 'e' _ 'c' _ 'e' _ 'd' _ 'e' _ 's' _ ';', 7, 0, 0x227a _ 0)
+NAMED_CHARACTER_REFERENCE(425, /* P r */ 'e' _ 'c' _ 'e' _ 'd' _ 'e' _ 's' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 12, 0, 0x2aaf _ 0)
+NAMED_CHARACTER_REFERENCE(426, /* P r */ 'e' _ 'c' _ 'e' _ 'd' _ 'e' _ 's' _ 'S' _ 'l' _ 'a' _ 'n' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 17, 0, 0x227c _ 0)
+NAMED_CHARACTER_REFERENCE(427, /* P r */ 'e' _ 'c' _ 'e' _ 'd' _ 'e' _ 's' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 12, 0, 0x227e _ 0)
+NAMED_CHARACTER_REFERENCE(428, /* P r */ 'i' _ 'm' _ 'e' _ ';', 4, 0, 0x2033 _ 0)
+NAMED_CHARACTER_REFERENCE(429, /* P r */ 'o' _ 'd' _ 'u' _ 'c' _ 't' _ ';', 6, 0, 0x220f _ 0)
+NAMED_CHARACTER_REFERENCE(430, /* P r */ 'o' _ 'p' _ 'o' _ 'r' _ 't' _ 'i' _ 'o' _ 'n' _ ';', 9, 0, 0x2237 _ 0)
+NAMED_CHARACTER_REFERENCE(431, /* P r */ 'o' _ 'p' _ 'o' _ 'r' _ 't' _ 'i' _ 'o' _ 'n' _ 'a' _ 'l' _ ';', 11, 0, 0x221d _ 0)
+NAMED_CHARACTER_REFERENCE(432, /* P s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcab)
+NAMED_CHARACTER_REFERENCE(433, /* P s */ 'i' _ ';', 2, 0, 0x03a8 _ 0)
+NAMED_CHARACTER_REFERENCE(434, /* Q U */ 'O' _ 'T', 2, 0, 0x0022 _ 0)
+NAMED_CHARACTER_REFERENCE(435, /* Q U */ 'O' _ 'T' _ ';', 3, 0, 0x0022 _ 0)
+NAMED_CHARACTER_REFERENCE(436, /* Q f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd14)
+NAMED_CHARACTER_REFERENCE(437, /* Q o */ 'p' _ 'f' _ ';', 3, 0, 0x211a _ 0)
+NAMED_CHARACTER_REFERENCE(438, /* Q s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcac)
+NAMED_CHARACTER_REFERENCE(439, /* R B */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x2910 _ 0)
+NAMED_CHARACTER_REFERENCE(440, /* R E */ 'G', 1, 0, 0x00ae _ 0)
+NAMED_CHARACTER_REFERENCE(441, /* R E */ 'G' _ ';', 2, 0, 0x00ae _ 0)
+NAMED_CHARACTER_REFERENCE(442, /* R a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x0154 _ 0)
+NAMED_CHARACTER_REFERENCE(443, /* R a */ 'n' _ 'g' _ ';', 3, 0, 0x27eb _ 0)
+NAMED_CHARACTER_REFERENCE(444, /* R a */ 'r' _ 'r' _ ';', 3, 0, 0x21a0 _ 0)
+NAMED_CHARACTER_REFERENCE(445, /* R a */ 'r' _ 'r' _ 't' _ 'l' _ ';', 5, 0, 0x2916 _ 0)
+NAMED_CHARACTER_REFERENCE(446, /* R c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x0158 _ 0)
+NAMED_CHARACTER_REFERENCE(447, /* R c */ 'e' _ 'd' _ 'i' _ 'l' _ ';', 5, 0, 0x0156 _ 0)
+NAMED_CHARACTER_REFERENCE(448, /* R c */ 'y' _ ';', 2, 0, 0x0420 _ 0)
+NAMED_CHARACTER_REFERENCE(449, /* R e */ ';', 1, 0, 0x211c _ 0)
+NAMED_CHARACTER_REFERENCE(450, /* R e */ 'v' _ 'e' _ 'r' _ 's' _ 'e' _ 'E' _ 'l' _ 'e' _ 'm' _ 'e' _ 'n' _ 't' _ ';', 13, 0, 0x220b _ 0)
+NAMED_CHARACTER_REFERENCE(451, /* R e */ 'v' _ 'e' _ 'r' _ 's' _ 'e' _ 'E' _ 'q' _ 'u' _ 'i' _ 'l' _ 'i' _ 'b' _ 'r' _ 'i' _ 'u' _ 'm' _ ';', 17, 0, 0x21cb _ 0)
+NAMED_CHARACTER_REFERENCE(452, /* R e */ 'v' _ 'e' _ 'r' _ 's' _ 'e' _ 'U' _ 'p' _ 'E' _ 'q' _ 'u' _ 'i' _ 'l' _ 'i' _ 'b' _ 'r' _ 'i' _ 'u' _ 'm' _ ';', 19, 0, 0x296f _ 0)
+NAMED_CHARACTER_REFERENCE(453, /* R f */ 'r' _ ';', 2, 0, 0x211c _ 0)
+NAMED_CHARACTER_REFERENCE(454, /* R h */ 'o' _ ';', 2, 0, 0x03a1 _ 0)
+NAMED_CHARACTER_REFERENCE(455, /* R i */ 'g' _ 'h' _ 't' _ 'A' _ 'n' _ 'g' _ 'l' _ 'e' _ 'B' _ 'r' _ 'a' _ 'c' _ 'k' _ 'e' _ 't' _ ';', 16, 0, 0x27e9 _ 0)
+NAMED_CHARACTER_REFERENCE(456, /* R i */ 'g' _ 'h' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 9, 0, 0x2192 _ 0)
+NAMED_CHARACTER_REFERENCE(457, /* R i */ 'g' _ 'h' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ 'B' _ 'a' _ 'r' _ ';', 12, 0, 0x21e5 _ 0)
+NAMED_CHARACTER_REFERENCE(458, /* R i */ 'g' _ 'h' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ 'L' _ 'e' _ 'f' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 18, 0, 0x21c4 _ 0)
+NAMED_CHARACTER_REFERENCE(459, /* R i */ 'g' _ 'h' _ 't' _ 'C' _ 'e' _ 'i' _ 'l' _ 'i' _ 'n' _ 'g' _ ';', 11, 0, 0x2309 _ 0)
+NAMED_CHARACTER_REFERENCE(460, /* R i */ 'g' _ 'h' _ 't' _ 'D' _ 'o' _ 'u' _ 'b' _ 'l' _ 'e' _ 'B' _ 'r' _ 'a' _ 'c' _ 'k' _ 'e' _ 't' _ ';', 17, 0, 0x27e7 _ 0)
+NAMED_CHARACTER_REFERENCE(461, /* R i */ 'g' _ 'h' _ 't' _ 'D' _ 'o' _ 'w' _ 'n' _ 'T' _ 'e' _ 'e' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 17, 0, 0x295d _ 0)
+NAMED_CHARACTER_REFERENCE(462, /* R i */ 'g' _ 'h' _ 't' _ 'D' _ 'o' _ 'w' _ 'n' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 14, 0, 0x21c2 _ 0)
+NAMED_CHARACTER_REFERENCE(463, /* R i */ 'g' _ 'h' _ 't' _ 'D' _ 'o' _ 'w' _ 'n' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ 'B' _ 'a' _ 'r' _ ';', 17, 0, 0x2955 _ 0)
+NAMED_CHARACTER_REFERENCE(464, /* R i */ 'g' _ 'h' _ 't' _ 'F' _ 'l' _ 'o' _ 'o' _ 'r' _ ';', 9, 0, 0x230b _ 0)
+NAMED_CHARACTER_REFERENCE(465, /* R i */ 'g' _ 'h' _ 't' _ 'T' _ 'e' _ 'e' _ ';', 7, 0, 0x22a2 _ 0)
+NAMED_CHARACTER_REFERENCE(466, /* R i */ 'g' _ 'h' _ 't' _ 'T' _ 'e' _ 'e' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 12, 0, 0x21a6 _ 0)
+NAMED_CHARACTER_REFERENCE(467, /* R i */ 'g' _ 'h' _ 't' _ 'T' _ 'e' _ 'e' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 13, 0, 0x295b _ 0)
+NAMED_CHARACTER_REFERENCE(468, /* R i */ 'g' _ 'h' _ 't' _ 'T' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 12, 0, 0x22b3 _ 0)
+NAMED_CHARACTER_REFERENCE(469, /* R i */ 'g' _ 'h' _ 't' _ 'T' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'B' _ 'a' _ 'r' _ ';', 15, 0, 0x29d0 _ 0)
+NAMED_CHARACTER_REFERENCE(470, /* R i */ 'g' _ 'h' _ 't' _ 'T' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 17, 0, 0x22b5 _ 0)
+NAMED_CHARACTER_REFERENCE(471, /* R i */ 'g' _ 'h' _ 't' _ 'U' _ 'p' _ 'D' _ 'o' _ 'w' _ 'n' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 16, 0, 0x294f _ 0)
+NAMED_CHARACTER_REFERENCE(472, /* R i */ 'g' _ 'h' _ 't' _ 'U' _ 'p' _ 'T' _ 'e' _ 'e' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 15, 0, 0x295c _ 0)
+NAMED_CHARACTER_REFERENCE(473, /* R i */ 'g' _ 'h' _ 't' _ 'U' _ 'p' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 12, 0, 0x21be _ 0)
+NAMED_CHARACTER_REFERENCE(474, /* R i */ 'g' _ 'h' _ 't' _ 'U' _ 'p' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ 'B' _ 'a' _ 'r' _ ';', 15, 0, 0x2954 _ 0)
+NAMED_CHARACTER_REFERENCE(475, /* R i */ 'g' _ 'h' _ 't' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ ';', 10, 0, 0x21c0 _ 0)
+NAMED_CHARACTER_REFERENCE(476, /* R i */ 'g' _ 'h' _ 't' _ 'V' _ 'e' _ 'c' _ 't' _ 'o' _ 'r' _ 'B' _ 'a' _ 'r' _ ';', 13, 0, 0x2953 _ 0)
+NAMED_CHARACTER_REFERENCE(477, /* R i */ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 9, 0, 0x21d2 _ 0)
+NAMED_CHARACTER_REFERENCE(478, /* R o */ 'p' _ 'f' _ ';', 3, 0, 0x211d _ 0)
+NAMED_CHARACTER_REFERENCE(479, /* R o */ 'u' _ 'n' _ 'd' _ 'I' _ 'm' _ 'p' _ 'l' _ 'i' _ 'e' _ 's' _ ';', 11, 0, 0x2970 _ 0)
+NAMED_CHARACTER_REFERENCE(480, /* R r */ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 10, 0, 0x21db _ 0)
+NAMED_CHARACTER_REFERENCE(481, /* R s */ 'c' _ 'r' _ ';', 3, 0, 0x211b _ 0)
+NAMED_CHARACTER_REFERENCE(482, /* R s */ 'h' _ ';', 2, 0, 0x21b1 _ 0)
+NAMED_CHARACTER_REFERENCE(483, /* R u */ 'l' _ 'e' _ 'D' _ 'e' _ 'l' _ 'a' _ 'y' _ 'e' _ 'd' _ ';', 10, 0, 0x29f4 _ 0)
+NAMED_CHARACTER_REFERENCE(484, /* S H */ 'C' _ 'H' _ 'c' _ 'y' _ ';', 5, 0, 0x0429 _ 0)
+NAMED_CHARACTER_REFERENCE(485, /* S H */ 'c' _ 'y' _ ';', 3, 0, 0x0428 _ 0)
+NAMED_CHARACTER_REFERENCE(486, /* S O */ 'F' _ 'T' _ 'c' _ 'y' _ ';', 5, 0, 0x042c _ 0)
+NAMED_CHARACTER_REFERENCE(487, /* S a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x015a _ 0)
+NAMED_CHARACTER_REFERENCE(488, /* S c */ ';', 1, 0, 0x2abc _ 0)
+NAMED_CHARACTER_REFERENCE(489, /* S c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x0160 _ 0)
+NAMED_CHARACTER_REFERENCE(490, /* S c */ 'e' _ 'd' _ 'i' _ 'l' _ ';', 5, 0, 0x015e _ 0)
+NAMED_CHARACTER_REFERENCE(491, /* S c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x015c _ 0)
+NAMED_CHARACTER_REFERENCE(492, /* S c */ 'y' _ ';', 2, 0, 0x0421 _ 0)
+NAMED_CHARACTER_REFERENCE(493, /* S f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd16)
+NAMED_CHARACTER_REFERENCE(494, /* S h */ 'o' _ 'r' _ 't' _ 'D' _ 'o' _ 'w' _ 'n' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 13, 0, 0x2193 _ 0)
+NAMED_CHARACTER_REFERENCE(495, /* S h */ 'o' _ 'r' _ 't' _ 'L' _ 'e' _ 'f' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 13, 0, 0x2190 _ 0)
+NAMED_CHARACTER_REFERENCE(496, /* S h */ 'o' _ 'r' _ 't' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 14, 0, 0x2192 _ 0)
+NAMED_CHARACTER_REFERENCE(497, /* S h */ 'o' _ 'r' _ 't' _ 'U' _ 'p' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 11, 0, 0x2191 _ 0)
+NAMED_CHARACTER_REFERENCE(498, /* S i */ 'g' _ 'm' _ 'a' _ ';', 4, 0, 0x03a3 _ 0)
+NAMED_CHARACTER_REFERENCE(499, /* S m */ 'a' _ 'l' _ 'l' _ 'C' _ 'i' _ 'r' _ 'c' _ 'l' _ 'e' _ ';', 10, 0, 0x2218 _ 0)
+NAMED_CHARACTER_REFERENCE(500, /* S o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd4a)
+NAMED_CHARACTER_REFERENCE(501, /* S q */ 'r' _ 't' _ ';', 3, 0, 0x221a _ 0)
+NAMED_CHARACTER_REFERENCE(502, /* S q */ 'u' _ 'a' _ 'r' _ 'e' _ ';', 5, 0, 0x25a1 _ 0)
+NAMED_CHARACTER_REFERENCE(503, /* S q */ 'u' _ 'a' _ 'r' _ 'e' _ 'I' _ 'n' _ 't' _ 'e' _ 'r' _ 's' _ 'e' _ 'c' _ 't' _ 'i' _ 'o' _ 'n' _ ';', 17, 0, 0x2293 _ 0)
+NAMED_CHARACTER_REFERENCE(504, /* S q */ 'u' _ 'a' _ 'r' _ 'e' _ 'S' _ 'u' _ 'b' _ 's' _ 'e' _ 't' _ ';', 11, 0, 0x228f _ 0)
+NAMED_CHARACTER_REFERENCE(505, /* S q */ 'u' _ 'a' _ 'r' _ 'e' _ 'S' _ 'u' _ 'b' _ 's' _ 'e' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 16, 0, 0x2291 _ 0)
+NAMED_CHARACTER_REFERENCE(506, /* S q */ 'u' _ 'a' _ 'r' _ 'e' _ 'S' _ 'u' _ 'p' _ 'e' _ 'r' _ 's' _ 'e' _ 't' _ ';', 13, 0, 0x2290 _ 0)
+NAMED_CHARACTER_REFERENCE(507, /* S q */ 'u' _ 'a' _ 'r' _ 'e' _ 'S' _ 'u' _ 'p' _ 'e' _ 'r' _ 's' _ 'e' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 18, 0, 0x2292 _ 0)
+NAMED_CHARACTER_REFERENCE(508, /* S q */ 'u' _ 'a' _ 'r' _ 'e' _ 'U' _ 'n' _ 'i' _ 'o' _ 'n' _ ';', 10, 0, 0x2294 _ 0)
+NAMED_CHARACTER_REFERENCE(509, /* S s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcae)
+NAMED_CHARACTER_REFERENCE(510, /* S t */ 'a' _ 'r' _ ';', 3, 0, 0x22c6 _ 0)
+NAMED_CHARACTER_REFERENCE(511, /* S u */ 'b' _ ';', 2, 0, 0x22d0 _ 0)
+NAMED_CHARACTER_REFERENCE(512, /* S u */ 'b' _ 's' _ 'e' _ 't' _ ';', 5, 0, 0x22d0 _ 0)
+NAMED_CHARACTER_REFERENCE(513, /* S u */ 'b' _ 's' _ 'e' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 10, 0, 0x2286 _ 0)
+NAMED_CHARACTER_REFERENCE(514, /* S u */ 'c' _ 'c' _ 'e' _ 'e' _ 'd' _ 's' _ ';', 7, 0, 0x227b _ 0)
+NAMED_CHARACTER_REFERENCE(515, /* S u */ 'c' _ 'c' _ 'e' _ 'e' _ 'd' _ 's' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 12, 0, 0x2ab0 _ 0)
+NAMED_CHARACTER_REFERENCE(516, /* S u */ 'c' _ 'c' _ 'e' _ 'e' _ 'd' _ 's' _ 'S' _ 'l' _ 'a' _ 'n' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 17, 0, 0x227d _ 0)
+NAMED_CHARACTER_REFERENCE(517, /* S u */ 'c' _ 'c' _ 'e' _ 'e' _ 'd' _ 's' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 12, 0, 0x227f _ 0)
+NAMED_CHARACTER_REFERENCE(518, /* S u */ 'c' _ 'h' _ 'T' _ 'h' _ 'a' _ 't' _ ';', 7, 0, 0x220b _ 0)
+NAMED_CHARACTER_REFERENCE(519, /* S u */ 'm' _ ';', 2, 0, 0x2211 _ 0)
+NAMED_CHARACTER_REFERENCE(520, /* S u */ 'p' _ ';', 2, 0, 0x22d1 _ 0)
+NAMED_CHARACTER_REFERENCE(521, /* S u */ 'p' _ 'e' _ 'r' _ 's' _ 'e' _ 't' _ ';', 7, 0, 0x2283 _ 0)
+NAMED_CHARACTER_REFERENCE(522, /* S u */ 'p' _ 'e' _ 'r' _ 's' _ 'e' _ 't' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 12, 0, 0x2287 _ 0)
+NAMED_CHARACTER_REFERENCE(523, /* S u */ 'p' _ 's' _ 'e' _ 't' _ ';', 5, 0, 0x22d1 _ 0)
+NAMED_CHARACTER_REFERENCE(524, /* T H */ 'O' _ 'R' _ 'N', 3, 0, 0x00de _ 0)
+NAMED_CHARACTER_REFERENCE(525, /* T H */ 'O' _ 'R' _ 'N' _ ';', 4, 0, 0x00de _ 0)
+NAMED_CHARACTER_REFERENCE(526, /* T R */ 'A' _ 'D' _ 'E' _ ';', 4, 0, 0x2122 _ 0)
+NAMED_CHARACTER_REFERENCE(527, /* T S */ 'H' _ 'c' _ 'y' _ ';', 4, 0, 0x040b _ 0)
+NAMED_CHARACTER_REFERENCE(528, /* T S */ 'c' _ 'y' _ ';', 3, 0, 0x0426 _ 0)
+NAMED_CHARACTER_REFERENCE(529, /* T a */ 'b' _ ';', 2, 0, 0x0009 _ 0)
+NAMED_CHARACTER_REFERENCE(530, /* T a */ 'u' _ ';', 2, 0, 0x03a4 _ 0)
+NAMED_CHARACTER_REFERENCE(531, /* T c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x0164 _ 0)
+NAMED_CHARACTER_REFERENCE(532, /* T c */ 'e' _ 'd' _ 'i' _ 'l' _ ';', 5, 0, 0x0162 _ 0)
+NAMED_CHARACTER_REFERENCE(533, /* T c */ 'y' _ ';', 2, 0, 0x0422 _ 0)
+NAMED_CHARACTER_REFERENCE(534, /* T f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd17)
+NAMED_CHARACTER_REFERENCE(535, /* T h */ 'e' _ 'r' _ 'e' _ 'f' _ 'o' _ 'r' _ 'e' _ ';', 8, 0, 0x2234 _ 0)
+NAMED_CHARACTER_REFERENCE(536, /* T h */ 'e' _ 't' _ 'a' _ ';', 4, 0, 0x0398 _ 0)
+NAMED_CHARACTER_REFERENCE(537, /* T h */ 'i' _ 'c' _ 'k' _ 'S' _ 'p' _ 'a' _ 'c' _ 'e' _ ';', 9, 0, 0x205f _ 0x200a)
+NAMED_CHARACTER_REFERENCE(538, /* T h */ 'i' _ 'n' _ 'S' _ 'p' _ 'a' _ 'c' _ 'e' _ ';', 8, 0, 0x2009 _ 0)
+NAMED_CHARACTER_REFERENCE(539, /* T i */ 'l' _ 'd' _ 'e' _ ';', 4, 0, 0x223c _ 0)
+NAMED_CHARACTER_REFERENCE(540, /* T i */ 'l' _ 'd' _ 'e' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 9, 0, 0x2243 _ 0)
+NAMED_CHARACTER_REFERENCE(541, /* T i */ 'l' _ 'd' _ 'e' _ 'F' _ 'u' _ 'l' _ 'l' _ 'E' _ 'q' _ 'u' _ 'a' _ 'l' _ ';', 13, 0, 0x2245 _ 0)
+NAMED_CHARACTER_REFERENCE(542, /* T i */ 'l' _ 'd' _ 'e' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 9, 0, 0x2248 _ 0)
+NAMED_CHARACTER_REFERENCE(543, /* T o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd4b)
+NAMED_CHARACTER_REFERENCE(544, /* T r */ 'i' _ 'p' _ 'l' _ 'e' _ 'D' _ 'o' _ 't' _ ';', 8, 0, 0x20db _ 0)
+NAMED_CHARACTER_REFERENCE(545, /* T s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcaf)
+NAMED_CHARACTER_REFERENCE(546, /* T s */ 't' _ 'r' _ 'o' _ 'k' _ ';', 5, 0, 0x0166 _ 0)
+NAMED_CHARACTER_REFERENCE(547, /* U a */ 'c' _ 'u' _ 't' _ 'e', 4, 0, 0x00da _ 0)
+NAMED_CHARACTER_REFERENCE(548, /* U a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x00da _ 0)
+NAMED_CHARACTER_REFERENCE(549, /* U a */ 'r' _ 'r' _ ';', 3, 0, 0x219f _ 0)
+NAMED_CHARACTER_REFERENCE(550, /* U a */ 'r' _ 'r' _ 'o' _ 'c' _ 'i' _ 'r' _ ';', 7, 0, 0x2949 _ 0)
+NAMED_CHARACTER_REFERENCE(551, /* U b */ 'r' _ 'c' _ 'y' _ ';', 4, 0, 0x040e _ 0)
+NAMED_CHARACTER_REFERENCE(552, /* U b */ 'r' _ 'e' _ 'v' _ 'e' _ ';', 5, 0, 0x016c _ 0)
+NAMED_CHARACTER_REFERENCE(553, /* U c */ 'i' _ 'r' _ 'c', 3, 0, 0x00db _ 0)
+NAMED_CHARACTER_REFERENCE(554, /* U c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x00db _ 0)
+NAMED_CHARACTER_REFERENCE(555, /* U c */ 'y' _ ';', 2, 0, 0x0423 _ 0)
+NAMED_CHARACTER_REFERENCE(556, /* U d */ 'b' _ 'l' _ 'a' _ 'c' _ ';', 5, 0, 0x0170 _ 0)
+NAMED_CHARACTER_REFERENCE(557, /* U f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd18)
+NAMED_CHARACTER_REFERENCE(558, /* U g */ 'r' _ 'a' _ 'v' _ 'e', 4, 0, 0x00d9 _ 0)
+NAMED_CHARACTER_REFERENCE(559, /* U g */ 'r' _ 'a' _ 'v' _ 'e' _ ';', 5, 0, 0x00d9 _ 0)
+NAMED_CHARACTER_REFERENCE(560, /* U m */ 'a' _ 'c' _ 'r' _ ';', 4, 0, 0x016a _ 0)
+NAMED_CHARACTER_REFERENCE(561, /* U n */ 'd' _ 'e' _ 'r' _ 'B' _ 'a' _ 'r' _ ';', 7, 0, 0x005f _ 0)
+NAMED_CHARACTER_REFERENCE(562, /* U n */ 'd' _ 'e' _ 'r' _ 'B' _ 'r' _ 'a' _ 'c' _ 'e' _ ';', 9, 0, 0x23df _ 0)
+NAMED_CHARACTER_REFERENCE(563, /* U n */ 'd' _ 'e' _ 'r' _ 'B' _ 'r' _ 'a' _ 'c' _ 'k' _ 'e' _ 't' _ ';', 11, 0, 0x23b5 _ 0)
+NAMED_CHARACTER_REFERENCE(564, /* U n */ 'd' _ 'e' _ 'r' _ 'P' _ 'a' _ 'r' _ 'e' _ 'n' _ 't' _ 'h' _ 'e' _ 's' _ 'i' _ 's' _ ';', 15, 0, 0x23dd _ 0)
+NAMED_CHARACTER_REFERENCE(565, /* U n */ 'i' _ 'o' _ 'n' _ ';', 4, 0, 0x22c3 _ 0)
+NAMED_CHARACTER_REFERENCE(566, /* U n */ 'i' _ 'o' _ 'n' _ 'P' _ 'l' _ 'u' _ 's' _ ';', 8, 0, 0x228e _ 0)
+NAMED_CHARACTER_REFERENCE(567, /* U o */ 'g' _ 'o' _ 'n' _ ';', 4, 0, 0x0172 _ 0)
+NAMED_CHARACTER_REFERENCE(568, /* U o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd4c)
+NAMED_CHARACTER_REFERENCE(569, /* U p */ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 6, 0, 0x2191 _ 0)
+NAMED_CHARACTER_REFERENCE(570, /* U p */ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ 'B' _ 'a' _ 'r' _ ';', 9, 0, 0x2912 _ 0)
+NAMED_CHARACTER_REFERENCE(571, /* U p */ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ 'D' _ 'o' _ 'w' _ 'n' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 15, 0, 0x21c5 _ 0)
+NAMED_CHARACTER_REFERENCE(572, /* U p */ 'D' _ 'o' _ 'w' _ 'n' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 10, 0, 0x2195 _ 0)
+NAMED_CHARACTER_REFERENCE(573, /* U p */ 'E' _ 'q' _ 'u' _ 'i' _ 'l' _ 'i' _ 'b' _ 'r' _ 'i' _ 'u' _ 'm' _ ';', 12, 0, 0x296e _ 0)
+NAMED_CHARACTER_REFERENCE(574, /* U p */ 'T' _ 'e' _ 'e' _ ';', 4, 0, 0x22a5 _ 0)
+NAMED_CHARACTER_REFERENCE(575, /* U p */ 'T' _ 'e' _ 'e' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 9, 0, 0x21a5 _ 0)
+NAMED_CHARACTER_REFERENCE(576, /* U p */ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 6, 0, 0x21d1 _ 0)
+NAMED_CHARACTER_REFERENCE(577, /* U p */ 'd' _ 'o' _ 'w' _ 'n' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 10, 0, 0x21d5 _ 0)
+NAMED_CHARACTER_REFERENCE(578, /* U p */ 'p' _ 'e' _ 'r' _ 'L' _ 'e' _ 'f' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 13, 0, 0x2196 _ 0)
+NAMED_CHARACTER_REFERENCE(579, /* U p */ 'p' _ 'e' _ 'r' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'A' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 14, 0, 0x2197 _ 0)
+NAMED_CHARACTER_REFERENCE(580, /* U p */ 's' _ 'i' _ ';', 3, 0, 0x03d2 _ 0)
+NAMED_CHARACTER_REFERENCE(581, /* U p */ 's' _ 'i' _ 'l' _ 'o' _ 'n' _ ';', 6, 0, 0x03a5 _ 0)
+NAMED_CHARACTER_REFERENCE(582, /* U r */ 'i' _ 'n' _ 'g' _ ';', 4, 0, 0x016e _ 0)
+NAMED_CHARACTER_REFERENCE(583, /* U s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcb0)
+NAMED_CHARACTER_REFERENCE(584, /* U t */ 'i' _ 'l' _ 'd' _ 'e' _ ';', 5, 0, 0x0168 _ 0)
+NAMED_CHARACTER_REFERENCE(585, /* U u */ 'm' _ 'l', 2, 0, 0x00dc _ 0)
+NAMED_CHARACTER_REFERENCE(586, /* U u */ 'm' _ 'l' _ ';', 3, 0, 0x00dc _ 0)
+NAMED_CHARACTER_REFERENCE(587, /* V D */ 'a' _ 's' _ 'h' _ ';', 4, 0, 0x22ab _ 0)
+NAMED_CHARACTER_REFERENCE(588, /* V b */ 'a' _ 'r' _ ';', 3, 0, 0x2aeb _ 0)
+NAMED_CHARACTER_REFERENCE(589, /* V c */ 'y' _ ';', 2, 0, 0x0412 _ 0)
+NAMED_CHARACTER_REFERENCE(590, /* V d */ 'a' _ 's' _ 'h' _ ';', 4, 0, 0x22a9 _ 0)
+NAMED_CHARACTER_REFERENCE(591, /* V d */ 'a' _ 's' _ 'h' _ 'l' _ ';', 5, 0, 0x2ae6 _ 0)
+NAMED_CHARACTER_REFERENCE(592, /* V e */ 'e' _ ';', 2, 0, 0x22c1 _ 0)
+NAMED_CHARACTER_REFERENCE(593, /* V e */ 'r' _ 'b' _ 'a' _ 'r' _ ';', 5, 0, 0x2016 _ 0)
+NAMED_CHARACTER_REFERENCE(594, /* V e */ 'r' _ 't' _ ';', 3, 0, 0x2016 _ 0)
+NAMED_CHARACTER_REFERENCE(595, /* V e */ 'r' _ 't' _ 'i' _ 'c' _ 'a' _ 'l' _ 'B' _ 'a' _ 'r' _ ';', 10, 0, 0x2223 _ 0)
+NAMED_CHARACTER_REFERENCE(596, /* V e */ 'r' _ 't' _ 'i' _ 'c' _ 'a' _ 'l' _ 'L' _ 'i' _ 'n' _ 'e' _ ';', 11, 0, 0x007c _ 0)
+NAMED_CHARACTER_REFERENCE(597, /* V e */ 'r' _ 't' _ 'i' _ 'c' _ 'a' _ 'l' _ 'S' _ 'e' _ 'p' _ 'a' _ 'r' _ 'a' _ 't' _ 'o' _ 'r' _ ';', 16, 0, 0x2758 _ 0)
+NAMED_CHARACTER_REFERENCE(598, /* V e */ 'r' _ 't' _ 'i' _ 'c' _ 'a' _ 'l' _ 'T' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 12, 0, 0x2240 _ 0)
+NAMED_CHARACTER_REFERENCE(599, /* V e */ 'r' _ 'y' _ 'T' _ 'h' _ 'i' _ 'n' _ 'S' _ 'p' _ 'a' _ 'c' _ 'e' _ ';', 12, 0, 0x200a _ 0)
+NAMED_CHARACTER_REFERENCE(600, /* V f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd19)
+NAMED_CHARACTER_REFERENCE(601, /* V o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd4d)
+NAMED_CHARACTER_REFERENCE(602, /* V s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcb1)
+NAMED_CHARACTER_REFERENCE(603, /* V v */ 'd' _ 'a' _ 's' _ 'h' _ ';', 5, 0, 0x22aa _ 0)
+NAMED_CHARACTER_REFERENCE(604, /* W c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x0174 _ 0)
+NAMED_CHARACTER_REFERENCE(605, /* W e */ 'd' _ 'g' _ 'e' _ ';', 4, 0, 0x22c0 _ 0)
+NAMED_CHARACTER_REFERENCE(606, /* W f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd1a)
+NAMED_CHARACTER_REFERENCE(607, /* W o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd4e)
+NAMED_CHARACTER_REFERENCE(608, /* W s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcb2)
+NAMED_CHARACTER_REFERENCE(609, /* X f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd1b)
+NAMED_CHARACTER_REFERENCE(610, /* X i */ ';', 1, 0, 0x039e _ 0)
+NAMED_CHARACTER_REFERENCE(611, /* X o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd4f)
+NAMED_CHARACTER_REFERENCE(612, /* X s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcb3)
+NAMED_CHARACTER_REFERENCE(613, /* Y A */ 'c' _ 'y' _ ';', 3, 0, 0x042f _ 0)
+NAMED_CHARACTER_REFERENCE(614, /* Y I */ 'c' _ 'y' _ ';', 3, 0, 0x0407 _ 0)
+NAMED_CHARACTER_REFERENCE(615, /* Y U */ 'c' _ 'y' _ ';', 3, 0, 0x042e _ 0)
+NAMED_CHARACTER_REFERENCE(616, /* Y a */ 'c' _ 'u' _ 't' _ 'e', 4, 0, 0x00dd _ 0)
+NAMED_CHARACTER_REFERENCE(617, /* Y a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x00dd _ 0)
+NAMED_CHARACTER_REFERENCE(618, /* Y c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x0176 _ 0)
+NAMED_CHARACTER_REFERENCE(619, /* Y c */ 'y' _ ';', 2, 0, 0x042b _ 0)
+NAMED_CHARACTER_REFERENCE(620, /* Y f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd1c)
+NAMED_CHARACTER_REFERENCE(621, /* Y o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd50)
+NAMED_CHARACTER_REFERENCE(622, /* Y s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcb4)
+NAMED_CHARACTER_REFERENCE(623, /* Y u */ 'm' _ 'l' _ ';', 3, 0, 0x0178 _ 0)
+NAMED_CHARACTER_REFERENCE(624, /* Z H */ 'c' _ 'y' _ ';', 3, 0, 0x0416 _ 0)
+NAMED_CHARACTER_REFERENCE(625, /* Z a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x0179 _ 0)
+NAMED_CHARACTER_REFERENCE(626, /* Z c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x017d _ 0)
+NAMED_CHARACTER_REFERENCE(627, /* Z c */ 'y' _ ';', 2, 0, 0x0417 _ 0)
+NAMED_CHARACTER_REFERENCE(628, /* Z d */ 'o' _ 't' _ ';', 3, 0, 0x017b _ 0)
+NAMED_CHARACTER_REFERENCE(629, /* Z e */ 'r' _ 'o' _ 'W' _ 'i' _ 'd' _ 't' _ 'h' _ 'S' _ 'p' _ 'a' _ 'c' _ 'e' _ ';', 13, 0, 0x200b _ 0)
+NAMED_CHARACTER_REFERENCE(630, /* Z e */ 't' _ 'a' _ ';', 3, 0, 0x0396 _ 0)
+NAMED_CHARACTER_REFERENCE(631, /* Z f */ 'r' _ ';', 2, 0, 0x2128 _ 0)
+NAMED_CHARACTER_REFERENCE(632, /* Z o */ 'p' _ 'f' _ ';', 3, 0, 0x2124 _ 0)
+NAMED_CHARACTER_REFERENCE(633, /* Z s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcb5)
+NAMED_CHARACTER_REFERENCE(634, /* a a */ 'c' _ 'u' _ 't' _ 'e', 4, 0, 0x00e1 _ 0)
+NAMED_CHARACTER_REFERENCE(635, /* a a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x00e1 _ 0)
+NAMED_CHARACTER_REFERENCE(636, /* a b */ 'r' _ 'e' _ 'v' _ 'e' _ ';', 5, 0, 0x0103 _ 0)
+NAMED_CHARACTER_REFERENCE(637, /* a c */ ';', 1, 0, 0x223e _ 0)
+NAMED_CHARACTER_REFERENCE(638, /* a c */ 'E' _ ';', 2, 0, 0x223e _ 0x0333)
+NAMED_CHARACTER_REFERENCE(639, /* a c */ 'd' _ ';', 2, 0, 0x223f _ 0)
+NAMED_CHARACTER_REFERENCE(640, /* a c */ 'i' _ 'r' _ 'c', 3, 0, 0x00e2 _ 0)
+NAMED_CHARACTER_REFERENCE(641, /* a c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x00e2 _ 0)
+NAMED_CHARACTER_REFERENCE(642, /* a c */ 'u' _ 't' _ 'e', 3, 0, 0x00b4 _ 0)
+NAMED_CHARACTER_REFERENCE(643, /* a c */ 'u' _ 't' _ 'e' _ ';', 4, 0, 0x00b4 _ 0)
+NAMED_CHARACTER_REFERENCE(644, /* a c */ 'y' _ ';', 2, 0, 0x0430 _ 0)
+NAMED_CHARACTER_REFERENCE(645, /* a e */ 'l' _ 'i' _ 'g', 3, 0, 0x00e6 _ 0)
+NAMED_CHARACTER_REFERENCE(646, /* a e */ 'l' _ 'i' _ 'g' _ ';', 4, 0, 0x00e6 _ 0)
+NAMED_CHARACTER_REFERENCE(647, /* a f */ ';', 1, 0, 0x2061 _ 0)
+NAMED_CHARACTER_REFERENCE(648, /* a f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd1e)
+NAMED_CHARACTER_REFERENCE(649, /* a g */ 'r' _ 'a' _ 'v' _ 'e', 4, 0, 0x00e0 _ 0)
+NAMED_CHARACTER_REFERENCE(650, /* a g */ 'r' _ 'a' _ 'v' _ 'e' _ ';', 5, 0, 0x00e0 _ 0)
+NAMED_CHARACTER_REFERENCE(651, /* a l */ 'e' _ 'f' _ 's' _ 'y' _ 'm' _ ';', 6, 0, 0x2135 _ 0)
+NAMED_CHARACTER_REFERENCE(652, /* a l */ 'e' _ 'p' _ 'h' _ ';', 4, 0, 0x2135 _ 0)
+NAMED_CHARACTER_REFERENCE(653, /* a l */ 'p' _ 'h' _ 'a' _ ';', 4, 0, 0x03b1 _ 0)
+NAMED_CHARACTER_REFERENCE(654, /* a m */ 'a' _ 'c' _ 'r' _ ';', 4, 0, 0x0101 _ 0)
+NAMED_CHARACTER_REFERENCE(655, /* a m */ 'a' _ 'l' _ 'g' _ ';', 4, 0, 0x2a3f _ 0)
+NAMED_CHARACTER_REFERENCE(656, /* a m */ 'p', 1, 0, 0x0026 _ 0)
+NAMED_CHARACTER_REFERENCE(657, /* a m */ 'p' _ ';', 2, 0, 0x0026 _ 0)
+NAMED_CHARACTER_REFERENCE(658, /* a n */ 'd' _ ';', 2, 0, 0x2227 _ 0)
+NAMED_CHARACTER_REFERENCE(659, /* a n */ 'd' _ 'a' _ 'n' _ 'd' _ ';', 5, 0, 0x2a55 _ 0)
+NAMED_CHARACTER_REFERENCE(660, /* a n */ 'd' _ 'd' _ ';', 3, 0, 0x2a5c _ 0)
+NAMED_CHARACTER_REFERENCE(661, /* a n */ 'd' _ 's' _ 'l' _ 'o' _ 'p' _ 'e' _ ';', 7, 0, 0x2a58 _ 0)
+NAMED_CHARACTER_REFERENCE(662, /* a n */ 'd' _ 'v' _ ';', 3, 0, 0x2a5a _ 0)
+NAMED_CHARACTER_REFERENCE(663, /* a n */ 'g' _ ';', 2, 0, 0x2220 _ 0)
+NAMED_CHARACTER_REFERENCE(664, /* a n */ 'g' _ 'e' _ ';', 3, 0, 0x29a4 _ 0)
+NAMED_CHARACTER_REFERENCE(665, /* a n */ 'g' _ 'l' _ 'e' _ ';', 4, 0, 0x2220 _ 0)
+NAMED_CHARACTER_REFERENCE(666, /* a n */ 'g' _ 'm' _ 's' _ 'd' _ ';', 5, 0, 0x2221 _ 0)
+NAMED_CHARACTER_REFERENCE(667, /* a n */ 'g' _ 'm' _ 's' _ 'd' _ 'a' _ 'a' _ ';', 7, 0, 0x29a8 _ 0)
+NAMED_CHARACTER_REFERENCE(668, /* a n */ 'g' _ 'm' _ 's' _ 'd' _ 'a' _ 'b' _ ';', 7, 0, 0x29a9 _ 0)
+NAMED_CHARACTER_REFERENCE(669, /* a n */ 'g' _ 'm' _ 's' _ 'd' _ 'a' _ 'c' _ ';', 7, 0, 0x29aa _ 0)
+NAMED_CHARACTER_REFERENCE(670, /* a n */ 'g' _ 'm' _ 's' _ 'd' _ 'a' _ 'd' _ ';', 7, 0, 0x29ab _ 0)
+NAMED_CHARACTER_REFERENCE(671, /* a n */ 'g' _ 'm' _ 's' _ 'd' _ 'a' _ 'e' _ ';', 7, 0, 0x29ac _ 0)
+NAMED_CHARACTER_REFERENCE(672, /* a n */ 'g' _ 'm' _ 's' _ 'd' _ 'a' _ 'f' _ ';', 7, 0, 0x29ad _ 0)
+NAMED_CHARACTER_REFERENCE(673, /* a n */ 'g' _ 'm' _ 's' _ 'd' _ 'a' _ 'g' _ ';', 7, 0, 0x29ae _ 0)
+NAMED_CHARACTER_REFERENCE(674, /* a n */ 'g' _ 'm' _ 's' _ 'd' _ 'a' _ 'h' _ ';', 7, 0, 0x29af _ 0)
+NAMED_CHARACTER_REFERENCE(675, /* a n */ 'g' _ 'r' _ 't' _ ';', 4, 0, 0x221f _ 0)
+NAMED_CHARACTER_REFERENCE(676, /* a n */ 'g' _ 'r' _ 't' _ 'v' _ 'b' _ ';', 6, 0, 0x22be _ 0)
+NAMED_CHARACTER_REFERENCE(677, /* a n */ 'g' _ 'r' _ 't' _ 'v' _ 'b' _ 'd' _ ';', 7, 0, 0x299d _ 0)
+NAMED_CHARACTER_REFERENCE(678, /* a n */ 'g' _ 's' _ 'p' _ 'h' _ ';', 5, 0, 0x2222 _ 0)
+NAMED_CHARACTER_REFERENCE(679, /* a n */ 'g' _ 's' _ 't' _ ';', 4, 0, 0x00c5 _ 0)
+NAMED_CHARACTER_REFERENCE(680, /* a n */ 'g' _ 'z' _ 'a' _ 'r' _ 'r' _ ';', 6, 0, 0x237c _ 0)
+NAMED_CHARACTER_REFERENCE(681, /* a o */ 'g' _ 'o' _ 'n' _ ';', 4, 0, 0x0105 _ 0)
+NAMED_CHARACTER_REFERENCE(682, /* a o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd52)
+NAMED_CHARACTER_REFERENCE(683, /* a p */ ';', 1, 0, 0x2248 _ 0)
+NAMED_CHARACTER_REFERENCE(684, /* a p */ 'E' _ ';', 2, 0, 0x2a70 _ 0)
+NAMED_CHARACTER_REFERENCE(685, /* a p */ 'a' _ 'c' _ 'i' _ 'r' _ ';', 5, 0, 0x2a6f _ 0)
+NAMED_CHARACTER_REFERENCE(686, /* a p */ 'e' _ ';', 2, 0, 0x224a _ 0)
+NAMED_CHARACTER_REFERENCE(687, /* a p */ 'i' _ 'd' _ ';', 3, 0, 0x224b _ 0)
+NAMED_CHARACTER_REFERENCE(688, /* a p */ 'o' _ 's' _ ';', 3, 0, 0x0027 _ 0)
+NAMED_CHARACTER_REFERENCE(689, /* a p */ 'p' _ 'r' _ 'o' _ 'x' _ ';', 5, 0, 0x2248 _ 0)
+NAMED_CHARACTER_REFERENCE(690, /* a p */ 'p' _ 'r' _ 'o' _ 'x' _ 'e' _ 'q' _ ';', 7, 0, 0x224a _ 0)
+NAMED_CHARACTER_REFERENCE(691, /* a r */ 'i' _ 'n' _ 'g', 3, 0, 0x00e5 _ 0)
+NAMED_CHARACTER_REFERENCE(692, /* a r */ 'i' _ 'n' _ 'g' _ ';', 4, 0, 0x00e5 _ 0)
+NAMED_CHARACTER_REFERENCE(693, /* a s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcb6)
+NAMED_CHARACTER_REFERENCE(694, /* a s */ 't' _ ';', 2, 0, 0x002a _ 0)
+NAMED_CHARACTER_REFERENCE(695, /* a s */ 'y' _ 'm' _ 'p' _ ';', 4, 0, 0x2248 _ 0)
+NAMED_CHARACTER_REFERENCE(696, /* a s */ 'y' _ 'm' _ 'p' _ 'e' _ 'q' _ ';', 6, 0, 0x224d _ 0)
+NAMED_CHARACTER_REFERENCE(697, /* a t */ 'i' _ 'l' _ 'd' _ 'e', 4, 0, 0x00e3 _ 0)
+NAMED_CHARACTER_REFERENCE(698, /* a t */ 'i' _ 'l' _ 'd' _ 'e' _ ';', 5, 0, 0x00e3 _ 0)
+NAMED_CHARACTER_REFERENCE(699, /* a u */ 'm' _ 'l', 2, 0, 0x00e4 _ 0)
+NAMED_CHARACTER_REFERENCE(700, /* a u */ 'm' _ 'l' _ ';', 3, 0, 0x00e4 _ 0)
+NAMED_CHARACTER_REFERENCE(701, /* a w */ 'c' _ 'o' _ 'n' _ 'i' _ 'n' _ 't' _ ';', 7, 0, 0x2233 _ 0)
+NAMED_CHARACTER_REFERENCE(702, /* a w */ 'i' _ 'n' _ 't' _ ';', 4, 0, 0x2a11 _ 0)
+NAMED_CHARACTER_REFERENCE(703, /* b N */ 'o' _ 't' _ ';', 3, 0, 0x2aed _ 0)
+NAMED_CHARACTER_REFERENCE(704, /* b a */ 'c' _ 'k' _ 'c' _ 'o' _ 'n' _ 'g' _ ';', 7, 0, 0x224c _ 0)
+NAMED_CHARACTER_REFERENCE(705, /* b a */ 'c' _ 'k' _ 'e' _ 'p' _ 's' _ 'i' _ 'l' _ 'o' _ 'n' _ ';', 10, 0, 0x03f6 _ 0)
+NAMED_CHARACTER_REFERENCE(706, /* b a */ 'c' _ 'k' _ 'p' _ 'r' _ 'i' _ 'm' _ 'e' _ ';', 8, 0, 0x2035 _ 0)
+NAMED_CHARACTER_REFERENCE(707, /* b a */ 'c' _ 'k' _ 's' _ 'i' _ 'm' _ ';', 6, 0, 0x223d _ 0)
+NAMED_CHARACTER_REFERENCE(708, /* b a */ 'c' _ 'k' _ 's' _ 'i' _ 'm' _ 'e' _ 'q' _ ';', 8, 0, 0x22cd _ 0)
+NAMED_CHARACTER_REFERENCE(709, /* b a */ 'r' _ 'v' _ 'e' _ 'e' _ ';', 5, 0, 0x22bd _ 0)
+NAMED_CHARACTER_REFERENCE(710, /* b a */ 'r' _ 'w' _ 'e' _ 'd' _ ';', 5, 0, 0x2305 _ 0)
+NAMED_CHARACTER_REFERENCE(711, /* b a */ 'r' _ 'w' _ 'e' _ 'd' _ 'g' _ 'e' _ ';', 7, 0, 0x2305 _ 0)
+NAMED_CHARACTER_REFERENCE(712, /* b b */ 'r' _ 'k' _ ';', 3, 0, 0x23b5 _ 0)
+NAMED_CHARACTER_REFERENCE(713, /* b b */ 'r' _ 'k' _ 't' _ 'b' _ 'r' _ 'k' _ ';', 7, 0, 0x23b6 _ 0)
+NAMED_CHARACTER_REFERENCE(714, /* b c */ 'o' _ 'n' _ 'g' _ ';', 4, 0, 0x224c _ 0)
+NAMED_CHARACTER_REFERENCE(715, /* b c */ 'y' _ ';', 2, 0, 0x0431 _ 0)
+NAMED_CHARACTER_REFERENCE(716, /* b d */ 'q' _ 'u' _ 'o' _ ';', 4, 0, 0x201e _ 0)
+NAMED_CHARACTER_REFERENCE(717, /* b e */ 'c' _ 'a' _ 'u' _ 's' _ ';', 5, 0, 0x2235 _ 0)
+NAMED_CHARACTER_REFERENCE(718, /* b e */ 'c' _ 'a' _ 'u' _ 's' _ 'e' _ ';', 6, 0, 0x2235 _ 0)
+NAMED_CHARACTER_REFERENCE(719, /* b e */ 'm' _ 'p' _ 't' _ 'y' _ 'v' _ ';', 6, 0, 0x29b0 _ 0)
+NAMED_CHARACTER_REFERENCE(720, /* b e */ 'p' _ 's' _ 'i' _ ';', 4, 0, 0x03f6 _ 0)
+NAMED_CHARACTER_REFERENCE(721, /* b e */ 'r' _ 'n' _ 'o' _ 'u' _ ';', 5, 0, 0x212c _ 0)
+NAMED_CHARACTER_REFERENCE(722, /* b e */ 't' _ 'a' _ ';', 3, 0, 0x03b2 _ 0)
+NAMED_CHARACTER_REFERENCE(723, /* b e */ 't' _ 'h' _ ';', 3, 0, 0x2136 _ 0)
+NAMED_CHARACTER_REFERENCE(724, /* b e */ 't' _ 'w' _ 'e' _ 'e' _ 'n' _ ';', 6, 0, 0x226c _ 0)
+NAMED_CHARACTER_REFERENCE(725, /* b f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd1f)
+NAMED_CHARACTER_REFERENCE(726, /* b i */ 'g' _ 'c' _ 'a' _ 'p' _ ';', 5, 0, 0x22c2 _ 0)
+NAMED_CHARACTER_REFERENCE(727, /* b i */ 'g' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0, 0x25ef _ 0)
+NAMED_CHARACTER_REFERENCE(728, /* b i */ 'g' _ 'c' _ 'u' _ 'p' _ ';', 5, 0, 0x22c3 _ 0)
+NAMED_CHARACTER_REFERENCE(729, /* b i */ 'g' _ 'o' _ 'd' _ 'o' _ 't' _ ';', 6, 0, 0x2a00 _ 0)
+NAMED_CHARACTER_REFERENCE(730, /* b i */ 'g' _ 'o' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 7, 0, 0x2a01 _ 0)
+NAMED_CHARACTER_REFERENCE(731, /* b i */ 'g' _ 'o' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 8, 0, 0x2a02 _ 0)
+NAMED_CHARACTER_REFERENCE(732, /* b i */ 'g' _ 's' _ 'q' _ 'c' _ 'u' _ 'p' _ ';', 7, 0, 0x2a06 _ 0)
+NAMED_CHARACTER_REFERENCE(733, /* b i */ 'g' _ 's' _ 't' _ 'a' _ 'r' _ ';', 6, 0, 0x2605 _ 0)
+NAMED_CHARACTER_REFERENCE(734, /* b i */ 'g' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'd' _ 'o' _ 'w' _ 'n' _ ';', 14, 0, 0x25bd _ 0)
+NAMED_CHARACTER_REFERENCE(735, /* b i */ 'g' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'u' _ 'p' _ ';', 12, 0, 0x25b3 _ 0)
+NAMED_CHARACTER_REFERENCE(736, /* b i */ 'g' _ 'u' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 7, 0, 0x2a04 _ 0)
+NAMED_CHARACTER_REFERENCE(737, /* b i */ 'g' _ 'v' _ 'e' _ 'e' _ ';', 5, 0, 0x22c1 _ 0)
+NAMED_CHARACTER_REFERENCE(738, /* b i */ 'g' _ 'w' _ 'e' _ 'd' _ 'g' _ 'e' _ ';', 7, 0, 0x22c0 _ 0)
+NAMED_CHARACTER_REFERENCE(739, /* b k */ 'a' _ 'r' _ 'o' _ 'w' _ ';', 5, 0, 0x290d _ 0)
+NAMED_CHARACTER_REFERENCE(740, /* b l */ 'a' _ 'c' _ 'k' _ 'l' _ 'o' _ 'z' _ 'e' _ 'n' _ 'g' _ 'e' _ ';', 11, 0, 0x29eb _ 0)
+NAMED_CHARACTER_REFERENCE(741, /* b l */ 'a' _ 'c' _ 'k' _ 's' _ 'q' _ 'u' _ 'a' _ 'r' _ 'e' _ ';', 10, 0, 0x25aa _ 0)
+NAMED_CHARACTER_REFERENCE(742, /* b l */ 'a' _ 'c' _ 'k' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 12, 0, 0x25b4 _ 0)
+NAMED_CHARACTER_REFERENCE(743, /* b l */ 'a' _ 'c' _ 'k' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'd' _ 'o' _ 'w' _ 'n' _ ';', 16, 0, 0x25be _ 0)
+NAMED_CHARACTER_REFERENCE(744, /* b l */ 'a' _ 'c' _ 'k' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 16, 0, 0x25c2 _ 0)
+NAMED_CHARACTER_REFERENCE(745, /* b l */ 'a' _ 'c' _ 'k' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 17, 0, 0x25b8 _ 0)
+NAMED_CHARACTER_REFERENCE(746, /* b l */ 'a' _ 'n' _ 'k' _ ';', 4, 0, 0x2423 _ 0)
+NAMED_CHARACTER_REFERENCE(747, /* b l */ 'k' _ '1' _ '2' _ ';', 4, 0, 0x2592 _ 0)
+NAMED_CHARACTER_REFERENCE(748, /* b l */ 'k' _ '1' _ '4' _ ';', 4, 0, 0x2591 _ 0)
+NAMED_CHARACTER_REFERENCE(749, /* b l */ 'k' _ '3' _ '4' _ ';', 4, 0, 0x2593 _ 0)
+NAMED_CHARACTER_REFERENCE(750, /* b l */ 'o' _ 'c' _ 'k' _ ';', 4, 0, 0x2588 _ 0)
+NAMED_CHARACTER_REFERENCE(751, /* b n */ 'e' _ ';', 2, 0, 0x003d _ 0x20e5)
+NAMED_CHARACTER_REFERENCE(752, /* b n */ 'e' _ 'q' _ 'u' _ 'i' _ 'v' _ ';', 6, 0, 0x2261 _ 0x20e5)
+NAMED_CHARACTER_REFERENCE(753, /* b n */ 'o' _ 't' _ ';', 3, 0, 0x2310 _ 0)
+NAMED_CHARACTER_REFERENCE(754, /* b o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd53)
+NAMED_CHARACTER_REFERENCE(755, /* b o */ 't' _ ';', 2, 0, 0x22a5 _ 0)
+NAMED_CHARACTER_REFERENCE(756, /* b o */ 't' _ 't' _ 'o' _ 'm' _ ';', 5, 0, 0x22a5 _ 0)
+NAMED_CHARACTER_REFERENCE(757, /* b o */ 'w' _ 't' _ 'i' _ 'e' _ ';', 5, 0, 0x22c8 _ 0)
+NAMED_CHARACTER_REFERENCE(758, /* b o */ 'x' _ 'D' _ 'L' _ ';', 4, 0, 0x2557 _ 0)
+NAMED_CHARACTER_REFERENCE(759, /* b o */ 'x' _ 'D' _ 'R' _ ';', 4, 0, 0x2554 _ 0)
+NAMED_CHARACTER_REFERENCE(760, /* b o */ 'x' _ 'D' _ 'l' _ ';', 4, 0, 0x2556 _ 0)
+NAMED_CHARACTER_REFERENCE(761, /* b o */ 'x' _ 'D' _ 'r' _ ';', 4, 0, 0x2553 _ 0)
+NAMED_CHARACTER_REFERENCE(762, /* b o */ 'x' _ 'H' _ ';', 3, 0, 0x2550 _ 0)
+NAMED_CHARACTER_REFERENCE(763, /* b o */ 'x' _ 'H' _ 'D' _ ';', 4, 0, 0x2566 _ 0)
+NAMED_CHARACTER_REFERENCE(764, /* b o */ 'x' _ 'H' _ 'U' _ ';', 4, 0, 0x2569 _ 0)
+NAMED_CHARACTER_REFERENCE(765, /* b o */ 'x' _ 'H' _ 'd' _ ';', 4, 0, 0x2564 _ 0)
+NAMED_CHARACTER_REFERENCE(766, /* b o */ 'x' _ 'H' _ 'u' _ ';', 4, 0, 0x2567 _ 0)
+NAMED_CHARACTER_REFERENCE(767, /* b o */ 'x' _ 'U' _ 'L' _ ';', 4, 0, 0x255d _ 0)
+NAMED_CHARACTER_REFERENCE(768, /* b o */ 'x' _ 'U' _ 'R' _ ';', 4, 0, 0x255a _ 0)
+NAMED_CHARACTER_REFERENCE(769, /* b o */ 'x' _ 'U' _ 'l' _ ';', 4, 0, 0x255c _ 0)
+NAMED_CHARACTER_REFERENCE(770, /* b o */ 'x' _ 'U' _ 'r' _ ';', 4, 0, 0x2559 _ 0)
+NAMED_CHARACTER_REFERENCE(771, /* b o */ 'x' _ 'V' _ ';', 3, 0, 0x2551 _ 0)
+NAMED_CHARACTER_REFERENCE(772, /* b o */ 'x' _ 'V' _ 'H' _ ';', 4, 0, 0x256c _ 0)
+NAMED_CHARACTER_REFERENCE(773, /* b o */ 'x' _ 'V' _ 'L' _ ';', 4, 0, 0x2563 _ 0)
+NAMED_CHARACTER_REFERENCE(774, /* b o */ 'x' _ 'V' _ 'R' _ ';', 4, 0, 0x2560 _ 0)
+NAMED_CHARACTER_REFERENCE(775, /* b o */ 'x' _ 'V' _ 'h' _ ';', 4, 0, 0x256b _ 0)
+NAMED_CHARACTER_REFERENCE(776, /* b o */ 'x' _ 'V' _ 'l' _ ';', 4, 0, 0x2562 _ 0)
+NAMED_CHARACTER_REFERENCE(777, /* b o */ 'x' _ 'V' _ 'r' _ ';', 4, 0, 0x255f _ 0)
+NAMED_CHARACTER_REFERENCE(778, /* b o */ 'x' _ 'b' _ 'o' _ 'x' _ ';', 5, 0, 0x29c9 _ 0)
+NAMED_CHARACTER_REFERENCE(779, /* b o */ 'x' _ 'd' _ 'L' _ ';', 4, 0, 0x2555 _ 0)
+NAMED_CHARACTER_REFERENCE(780, /* b o */ 'x' _ 'd' _ 'R' _ ';', 4, 0, 0x2552 _ 0)
+NAMED_CHARACTER_REFERENCE(781, /* b o */ 'x' _ 'd' _ 'l' _ ';', 4, 0, 0x2510 _ 0)
+NAMED_CHARACTER_REFERENCE(782, /* b o */ 'x' _ 'd' _ 'r' _ ';', 4, 0, 0x250c _ 0)
+NAMED_CHARACTER_REFERENCE(783, /* b o */ 'x' _ 'h' _ ';', 3, 0, 0x2500 _ 0)
+NAMED_CHARACTER_REFERENCE(784, /* b o */ 'x' _ 'h' _ 'D' _ ';', 4, 0, 0x2565 _ 0)
+NAMED_CHARACTER_REFERENCE(785, /* b o */ 'x' _ 'h' _ 'U' _ ';', 4, 0, 0x2568 _ 0)
+NAMED_CHARACTER_REFERENCE(786, /* b o */ 'x' _ 'h' _ 'd' _ ';', 4, 0, 0x252c _ 0)
+NAMED_CHARACTER_REFERENCE(787, /* b o */ 'x' _ 'h' _ 'u' _ ';', 4, 0, 0x2534 _ 0)
+NAMED_CHARACTER_REFERENCE(788, /* b o */ 'x' _ 'm' _ 'i' _ 'n' _ 'u' _ 's' _ ';', 7, 0, 0x229f _ 0)
+NAMED_CHARACTER_REFERENCE(789, /* b o */ 'x' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 6, 0, 0x229e _ 0)
+NAMED_CHARACTER_REFERENCE(790, /* b o */ 'x' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 7, 0, 0x22a0 _ 0)
+NAMED_CHARACTER_REFERENCE(791, /* b o */ 'x' _ 'u' _ 'L' _ ';', 4, 0, 0x255b _ 0)
+NAMED_CHARACTER_REFERENCE(792, /* b o */ 'x' _ 'u' _ 'R' _ ';', 4, 0, 0x2558 _ 0)
+NAMED_CHARACTER_REFERENCE(793, /* b o */ 'x' _ 'u' _ 'l' _ ';', 4, 0, 0x2518 _ 0)
+NAMED_CHARACTER_REFERENCE(794, /* b o */ 'x' _ 'u' _ 'r' _ ';', 4, 0, 0x2514 _ 0)
+NAMED_CHARACTER_REFERENCE(795, /* b o */ 'x' _ 'v' _ ';', 3, 0, 0x2502 _ 0)
+NAMED_CHARACTER_REFERENCE(796, /* b o */ 'x' _ 'v' _ 'H' _ ';', 4, 0, 0x256a _ 0)
+NAMED_CHARACTER_REFERENCE(797, /* b o */ 'x' _ 'v' _ 'L' _ ';', 4, 0, 0x2561 _ 0)
+NAMED_CHARACTER_REFERENCE(798, /* b o */ 'x' _ 'v' _ 'R' _ ';', 4, 0, 0x255e _ 0)
+NAMED_CHARACTER_REFERENCE(799, /* b o */ 'x' _ 'v' _ 'h' _ ';', 4, 0, 0x253c _ 0)
+NAMED_CHARACTER_REFERENCE(800, /* b o */ 'x' _ 'v' _ 'l' _ ';', 4, 0, 0x2524 _ 0)
+NAMED_CHARACTER_REFERENCE(801, /* b o */ 'x' _ 'v' _ 'r' _ ';', 4, 0, 0x251c _ 0)
+NAMED_CHARACTER_REFERENCE(802, /* b p */ 'r' _ 'i' _ 'm' _ 'e' _ ';', 5, 0, 0x2035 _ 0)
+NAMED_CHARACTER_REFERENCE(803, /* b r */ 'e' _ 'v' _ 'e' _ ';', 4, 0, 0x02d8 _ 0)
+NAMED_CHARACTER_REFERENCE(804, /* b r */ 'v' _ 'b' _ 'a' _ 'r', 4, 0, 0x00a6 _ 0)
+NAMED_CHARACTER_REFERENCE(805, /* b r */ 'v' _ 'b' _ 'a' _ 'r' _ ';', 5, 0, 0x00a6 _ 0)
+NAMED_CHARACTER_REFERENCE(806, /* b s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcb7)
+NAMED_CHARACTER_REFERENCE(807, /* b s */ 'e' _ 'm' _ 'i' _ ';', 4, 0, 0x204f _ 0)
+NAMED_CHARACTER_REFERENCE(808, /* b s */ 'i' _ 'm' _ ';', 3, 0, 0x223d _ 0)
+NAMED_CHARACTER_REFERENCE(809, /* b s */ 'i' _ 'm' _ 'e' _ ';', 4, 0, 0x22cd _ 0)
+NAMED_CHARACTER_REFERENCE(810, /* b s */ 'o' _ 'l' _ ';', 3, 0, 0x005c _ 0)
+NAMED_CHARACTER_REFERENCE(811, /* b s */ 'o' _ 'l' _ 'b' _ ';', 4, 0, 0x29c5 _ 0)
+NAMED_CHARACTER_REFERENCE(812, /* b s */ 'o' _ 'l' _ 'h' _ 's' _ 'u' _ 'b' _ ';', 7, 0, 0x27c8 _ 0)
+NAMED_CHARACTER_REFERENCE(813, /* b u */ 'l' _ 'l' _ ';', 3, 0, 0x2022 _ 0)
+NAMED_CHARACTER_REFERENCE(814, /* b u */ 'l' _ 'l' _ 'e' _ 't' _ ';', 5, 0, 0x2022 _ 0)
+NAMED_CHARACTER_REFERENCE(815, /* b u */ 'm' _ 'p' _ ';', 3, 0, 0x224e _ 0)
+NAMED_CHARACTER_REFERENCE(816, /* b u */ 'm' _ 'p' _ 'E' _ ';', 4, 0, 0x2aae _ 0)
+NAMED_CHARACTER_REFERENCE(817, /* b u */ 'm' _ 'p' _ 'e' _ ';', 4, 0, 0x224f _ 0)
+NAMED_CHARACTER_REFERENCE(818, /* b u */ 'm' _ 'p' _ 'e' _ 'q' _ ';', 5, 0, 0x224f _ 0)
+NAMED_CHARACTER_REFERENCE(819, /* c a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x0107 _ 0)
+NAMED_CHARACTER_REFERENCE(820, /* c a */ 'p' _ ';', 2, 0, 0x2229 _ 0)
+NAMED_CHARACTER_REFERENCE(821, /* c a */ 'p' _ 'a' _ 'n' _ 'd' _ ';', 5, 0, 0x2a44 _ 0)
+NAMED_CHARACTER_REFERENCE(822, /* c a */ 'p' _ 'b' _ 'r' _ 'c' _ 'u' _ 'p' _ ';', 7, 0, 0x2a49 _ 0)
+NAMED_CHARACTER_REFERENCE(823, /* c a */ 'p' _ 'c' _ 'a' _ 'p' _ ';', 5, 0, 0x2a4b _ 0)
+NAMED_CHARACTER_REFERENCE(824, /* c a */ 'p' _ 'c' _ 'u' _ 'p' _ ';', 5, 0, 0x2a47 _ 0)
+NAMED_CHARACTER_REFERENCE(825, /* c a */ 'p' _ 'd' _ 'o' _ 't' _ ';', 5, 0, 0x2a40 _ 0)
+NAMED_CHARACTER_REFERENCE(826, /* c a */ 'p' _ 's' _ ';', 3, 0, 0x2229 _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(827, /* c a */ 'r' _ 'e' _ 't' _ ';', 4, 0, 0x2041 _ 0)
+NAMED_CHARACTER_REFERENCE(828, /* c a */ 'r' _ 'o' _ 'n' _ ';', 4, 0, 0x02c7 _ 0)
+NAMED_CHARACTER_REFERENCE(829, /* c c */ 'a' _ 'p' _ 's' _ ';', 4, 0, 0x2a4d _ 0)
+NAMED_CHARACTER_REFERENCE(830, /* c c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x010d _ 0)
+NAMED_CHARACTER_REFERENCE(831, /* c c */ 'e' _ 'd' _ 'i' _ 'l', 4, 0, 0x00e7 _ 0)
+NAMED_CHARACTER_REFERENCE(832, /* c c */ 'e' _ 'd' _ 'i' _ 'l' _ ';', 5, 0, 0x00e7 _ 0)
+NAMED_CHARACTER_REFERENCE(833, /* c c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x0109 _ 0)
+NAMED_CHARACTER_REFERENCE(834, /* c c */ 'u' _ 'p' _ 's' _ ';', 4, 0, 0x2a4c _ 0)
+NAMED_CHARACTER_REFERENCE(835, /* c c */ 'u' _ 'p' _ 's' _ 's' _ 'm' _ ';', 6, 0, 0x2a50 _ 0)
+NAMED_CHARACTER_REFERENCE(836, /* c d */ 'o' _ 't' _ ';', 3, 0, 0x010b _ 0)
+NAMED_CHARACTER_REFERENCE(837, /* c e */ 'd' _ 'i' _ 'l', 3, 0, 0x00b8 _ 0)
+NAMED_CHARACTER_REFERENCE(838, /* c e */ 'd' _ 'i' _ 'l' _ ';', 4, 0, 0x00b8 _ 0)
+NAMED_CHARACTER_REFERENCE(839, /* c e */ 'm' _ 'p' _ 't' _ 'y' _ 'v' _ ';', 6, 0, 0x29b2 _ 0)
+NAMED_CHARACTER_REFERENCE(840, /* c e */ 'n' _ 't', 2, 0, 0x00a2 _ 0)
+NAMED_CHARACTER_REFERENCE(841, /* c e */ 'n' _ 't' _ ';', 3, 0, 0x00a2 _ 0)
+NAMED_CHARACTER_REFERENCE(842, /* c e */ 'n' _ 't' _ 'e' _ 'r' _ 'd' _ 'o' _ 't' _ ';', 8, 0, 0x00b7 _ 0)
+NAMED_CHARACTER_REFERENCE(843, /* c f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd20)
+NAMED_CHARACTER_REFERENCE(844, /* c h */ 'c' _ 'y' _ ';', 3, 0, 0x0447 _ 0)
+NAMED_CHARACTER_REFERENCE(845, /* c h */ 'e' _ 'c' _ 'k' _ ';', 4, 0, 0x2713 _ 0)
+NAMED_CHARACTER_REFERENCE(846, /* c h */ 'e' _ 'c' _ 'k' _ 'm' _ 'a' _ 'r' _ 'k' _ ';', 8, 0, 0x2713 _ 0)
+NAMED_CHARACTER_REFERENCE(847, /* c h */ 'i' _ ';', 2, 0, 0x03c7 _ 0)
+NAMED_CHARACTER_REFERENCE(848, /* c i */ 'r' _ ';', 2, 0, 0x25cb _ 0)
+NAMED_CHARACTER_REFERENCE(849, /* c i */ 'r' _ 'E' _ ';', 3, 0, 0x29c3 _ 0)
+NAMED_CHARACTER_REFERENCE(850, /* c i */ 'r' _ 'c' _ ';', 3, 0, 0x02c6 _ 0)
+NAMED_CHARACTER_REFERENCE(851, /* c i */ 'r' _ 'c' _ 'e' _ 'q' _ ';', 5, 0, 0x2257 _ 0)
+NAMED_CHARACTER_REFERENCE(852, /* c i */ 'r' _ 'c' _ 'l' _ 'e' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 14, 0, 0x21ba _ 0)
+NAMED_CHARACTER_REFERENCE(853, /* c i */ 'r' _ 'c' _ 'l' _ 'e' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 15, 0, 0x21bb _ 0)
+NAMED_CHARACTER_REFERENCE(854, /* c i */ 'r' _ 'c' _ 'l' _ 'e' _ 'd' _ 'R' _ ';', 7, 0, 0x00ae _ 0)
+NAMED_CHARACTER_REFERENCE(855, /* c i */ 'r' _ 'c' _ 'l' _ 'e' _ 'd' _ 'S' _ ';', 7, 0, 0x24c8 _ 0)
+NAMED_CHARACTER_REFERENCE(856, /* c i */ 'r' _ 'c' _ 'l' _ 'e' _ 'd' _ 'a' _ 's' _ 't' _ ';', 9, 0, 0x229b _ 0)
+NAMED_CHARACTER_REFERENCE(857, /* c i */ 'r' _ 'c' _ 'l' _ 'e' _ 'd' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 10, 0, 0x229a _ 0)
+NAMED_CHARACTER_REFERENCE(858, /* c i */ 'r' _ 'c' _ 'l' _ 'e' _ 'd' _ 'd' _ 'a' _ 's' _ 'h' _ ';', 10, 0, 0x229d _ 0)
+NAMED_CHARACTER_REFERENCE(859, /* c i */ 'r' _ 'e' _ ';', 3, 0, 0x2257 _ 0)
+NAMED_CHARACTER_REFERENCE(860, /* c i */ 'r' _ 'f' _ 'n' _ 'i' _ 'n' _ 't' _ ';', 7, 0, 0x2a10 _ 0)
+NAMED_CHARACTER_REFERENCE(861, /* c i */ 'r' _ 'm' _ 'i' _ 'd' _ ';', 5, 0, 0x2aef _ 0)
+NAMED_CHARACTER_REFERENCE(862, /* c i */ 'r' _ 's' _ 'c' _ 'i' _ 'r' _ ';', 6, 0, 0x29c2 _ 0)
+NAMED_CHARACTER_REFERENCE(863, /* c l */ 'u' _ 'b' _ 's' _ ';', 4, 0, 0x2663 _ 0)
+NAMED_CHARACTER_REFERENCE(864, /* c l */ 'u' _ 'b' _ 's' _ 'u' _ 'i' _ 't' _ ';', 7, 0, 0x2663 _ 0)
+NAMED_CHARACTER_REFERENCE(865, /* c o */ 'l' _ 'o' _ 'n' _ ';', 4, 0, 0x003a _ 0)
+NAMED_CHARACTER_REFERENCE(866, /* c o */ 'l' _ 'o' _ 'n' _ 'e' _ ';', 5, 0, 0x2254 _ 0)
+NAMED_CHARACTER_REFERENCE(867, /* c o */ 'l' _ 'o' _ 'n' _ 'e' _ 'q' _ ';', 6, 0, 0x2254 _ 0)
+NAMED_CHARACTER_REFERENCE(868, /* c o */ 'm' _ 'm' _ 'a' _ ';', 4, 0, 0x002c _ 0)
+NAMED_CHARACTER_REFERENCE(869, /* c o */ 'm' _ 'm' _ 'a' _ 't' _ ';', 5, 0, 0x0040 _ 0)
+NAMED_CHARACTER_REFERENCE(870, /* c o */ 'm' _ 'p' _ ';', 3, 0, 0x2201 _ 0)
+NAMED_CHARACTER_REFERENCE(871, /* c o */ 'm' _ 'p' _ 'f' _ 'n' _ ';', 5, 0, 0x2218 _ 0)
+NAMED_CHARACTER_REFERENCE(872, /* c o */ 'm' _ 'p' _ 'l' _ 'e' _ 'm' _ 'e' _ 'n' _ 't' _ ';', 9, 0, 0x2201 _ 0)
+NAMED_CHARACTER_REFERENCE(873, /* c o */ 'm' _ 'p' _ 'l' _ 'e' _ 'x' _ 'e' _ 's' _ ';', 8, 0, 0x2102 _ 0)
+NAMED_CHARACTER_REFERENCE(874, /* c o */ 'n' _ 'g' _ ';', 3, 0, 0x2245 _ 0)
+NAMED_CHARACTER_REFERENCE(875, /* c o */ 'n' _ 'g' _ 'd' _ 'o' _ 't' _ ';', 6, 0, 0x2a6d _ 0)
+NAMED_CHARACTER_REFERENCE(876, /* c o */ 'n' _ 'i' _ 'n' _ 't' _ ';', 5, 0, 0x222e _ 0)
+NAMED_CHARACTER_REFERENCE(877, /* c o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd54)
+NAMED_CHARACTER_REFERENCE(878, /* c o */ 'p' _ 'r' _ 'o' _ 'd' _ ';', 5, 0, 0x2210 _ 0)
+NAMED_CHARACTER_REFERENCE(879, /* c o */ 'p' _ 'y', 2, 0, 0x00a9 _ 0)
+NAMED_CHARACTER_REFERENCE(880, /* c o */ 'p' _ 'y' _ ';', 3, 0, 0x00a9 _ 0)
+NAMED_CHARACTER_REFERENCE(881, /* c o */ 'p' _ 'y' _ 's' _ 'r' _ ';', 5, 0, 0x2117 _ 0)
+NAMED_CHARACTER_REFERENCE(882, /* c r */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21b5 _ 0)
+NAMED_CHARACTER_REFERENCE(883, /* c r */ 'o' _ 's' _ 's' _ ';', 4, 0, 0x2717 _ 0)
+NAMED_CHARACTER_REFERENCE(884, /* c s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcb8)
+NAMED_CHARACTER_REFERENCE(885, /* c s */ 'u' _ 'b' _ ';', 3, 0, 0x2acf _ 0)
+NAMED_CHARACTER_REFERENCE(886, /* c s */ 'u' _ 'b' _ 'e' _ ';', 4, 0, 0x2ad1 _ 0)
+NAMED_CHARACTER_REFERENCE(887, /* c s */ 'u' _ 'p' _ ';', 3, 0, 0x2ad0 _ 0)
+NAMED_CHARACTER_REFERENCE(888, /* c s */ 'u' _ 'p' _ 'e' _ ';', 4, 0, 0x2ad2 _ 0)
+NAMED_CHARACTER_REFERENCE(889, /* c t */ 'd' _ 'o' _ 't' _ ';', 4, 0, 0x22ef _ 0)
+NAMED_CHARACTER_REFERENCE(890, /* c u */ 'd' _ 'a' _ 'r' _ 'r' _ 'l' _ ';', 6, 0, 0x2938 _ 0)
+NAMED_CHARACTER_REFERENCE(891, /* c u */ 'd' _ 'a' _ 'r' _ 'r' _ 'r' _ ';', 6, 0, 0x2935 _ 0)
+NAMED_CHARACTER_REFERENCE(892, /* c u */ 'e' _ 'p' _ 'r' _ ';', 4, 0, 0x22de _ 0)
+NAMED_CHARACTER_REFERENCE(893, /* c u */ 'e' _ 's' _ 'c' _ ';', 4, 0, 0x22df _ 0)
+NAMED_CHARACTER_REFERENCE(894, /* c u */ 'l' _ 'a' _ 'r' _ 'r' _ ';', 5, 0, 0x21b6 _ 0)
+NAMED_CHARACTER_REFERENCE(895, /* c u */ 'l' _ 'a' _ 'r' _ 'r' _ 'p' _ ';', 6, 0, 0x293d _ 0)
+NAMED_CHARACTER_REFERENCE(896, /* c u */ 'p' _ ';', 2, 0, 0x222a _ 0)
+NAMED_CHARACTER_REFERENCE(897, /* c u */ 'p' _ 'b' _ 'r' _ 'c' _ 'a' _ 'p' _ ';', 7, 0, 0x2a48 _ 0)
+NAMED_CHARACTER_REFERENCE(898, /* c u */ 'p' _ 'c' _ 'a' _ 'p' _ ';', 5, 0, 0x2a46 _ 0)
+NAMED_CHARACTER_REFERENCE(899, /* c u */ 'p' _ 'c' _ 'u' _ 'p' _ ';', 5, 0, 0x2a4a _ 0)
+NAMED_CHARACTER_REFERENCE(900, /* c u */ 'p' _ 'd' _ 'o' _ 't' _ ';', 5, 0, 0x228d _ 0)
+NAMED_CHARACTER_REFERENCE(901, /* c u */ 'p' _ 'o' _ 'r' _ ';', 4, 0, 0x2a45 _ 0)
+NAMED_CHARACTER_REFERENCE(902, /* c u */ 'p' _ 's' _ ';', 3, 0, 0x222a _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(903, /* c u */ 'r' _ 'a' _ 'r' _ 'r' _ ';', 5, 0, 0x21b7 _ 0)
+NAMED_CHARACTER_REFERENCE(904, /* c u */ 'r' _ 'a' _ 'r' _ 'r' _ 'm' _ ';', 6, 0, 0x293c _ 0)
+NAMED_CHARACTER_REFERENCE(905, /* c u */ 'r' _ 'l' _ 'y' _ 'e' _ 'q' _ 'p' _ 'r' _ 'e' _ 'c' _ ';', 10, 0, 0x22de _ 0)
+NAMED_CHARACTER_REFERENCE(906, /* c u */ 'r' _ 'l' _ 'y' _ 'e' _ 'q' _ 's' _ 'u' _ 'c' _ 'c' _ ';', 10, 0, 0x22df _ 0)
+NAMED_CHARACTER_REFERENCE(907, /* c u */ 'r' _ 'l' _ 'y' _ 'v' _ 'e' _ 'e' _ ';', 7, 0, 0x22ce _ 0)
+NAMED_CHARACTER_REFERENCE(908, /* c u */ 'r' _ 'l' _ 'y' _ 'w' _ 'e' _ 'd' _ 'g' _ 'e' _ ';', 9, 0, 0x22cf _ 0)
+NAMED_CHARACTER_REFERENCE(909, /* c u */ 'r' _ 'r' _ 'e' _ 'n', 4, 0, 0x00a4 _ 0)
+NAMED_CHARACTER_REFERENCE(910, /* c u */ 'r' _ 'r' _ 'e' _ 'n' _ ';', 5, 0, 0x00a4 _ 0)
+NAMED_CHARACTER_REFERENCE(911, /* c u */ 'r' _ 'v' _ 'e' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 13, 0, 0x21b6 _ 0)
+NAMED_CHARACTER_REFERENCE(912, /* c u */ 'r' _ 'v' _ 'e' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 14, 0, 0x21b7 _ 0)
+NAMED_CHARACTER_REFERENCE(913, /* c u */ 'v' _ 'e' _ 'e' _ ';', 4, 0, 0x22ce _ 0)
+NAMED_CHARACTER_REFERENCE(914, /* c u */ 'w' _ 'e' _ 'd' _ ';', 4, 0, 0x22cf _ 0)
+NAMED_CHARACTER_REFERENCE(915, /* c w */ 'c' _ 'o' _ 'n' _ 'i' _ 'n' _ 't' _ ';', 7, 0, 0x2232 _ 0)
+NAMED_CHARACTER_REFERENCE(916, /* c w */ 'i' _ 'n' _ 't' _ ';', 4, 0, 0x2231 _ 0)
+NAMED_CHARACTER_REFERENCE(917, /* c y */ 'l' _ 'c' _ 't' _ 'y' _ ';', 5, 0, 0x232d _ 0)
+NAMED_CHARACTER_REFERENCE(918, /* d A */ 'r' _ 'r' _ ';', 3, 0, 0x21d3 _ 0)
+NAMED_CHARACTER_REFERENCE(919, /* d H */ 'a' _ 'r' _ ';', 3, 0, 0x2965 _ 0)
+NAMED_CHARACTER_REFERENCE(920, /* d a */ 'g' _ 'g' _ 'e' _ 'r' _ ';', 5, 0, 0x2020 _ 0)
+NAMED_CHARACTER_REFERENCE(921, /* d a */ 'l' _ 'e' _ 't' _ 'h' _ ';', 5, 0, 0x2138 _ 0)
+NAMED_CHARACTER_REFERENCE(922, /* d a */ 'r' _ 'r' _ ';', 3, 0, 0x2193 _ 0)
+NAMED_CHARACTER_REFERENCE(923, /* d a */ 's' _ 'h' _ ';', 3, 0, 0x2010 _ 0)
+NAMED_CHARACTER_REFERENCE(924, /* d a */ 's' _ 'h' _ 'v' _ ';', 4, 0, 0x22a3 _ 0)
+NAMED_CHARACTER_REFERENCE(925, /* d b */ 'k' _ 'a' _ 'r' _ 'o' _ 'w' _ ';', 6, 0, 0x290f _ 0)
+NAMED_CHARACTER_REFERENCE(926, /* d b */ 'l' _ 'a' _ 'c' _ ';', 4, 0, 0x02dd _ 0)
+NAMED_CHARACTER_REFERENCE(927, /* d c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x010f _ 0)
+NAMED_CHARACTER_REFERENCE(928, /* d c */ 'y' _ ';', 2, 0, 0x0434 _ 0)
+NAMED_CHARACTER_REFERENCE(929, /* d d */ ';', 1, 0, 0x2146 _ 0)
+NAMED_CHARACTER_REFERENCE(930, /* d d */ 'a' _ 'g' _ 'g' _ 'e' _ 'r' _ ';', 6, 0, 0x2021 _ 0)
+NAMED_CHARACTER_REFERENCE(931, /* d d */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21ca _ 0)
+NAMED_CHARACTER_REFERENCE(932, /* d d */ 'o' _ 't' _ 's' _ 'e' _ 'q' _ ';', 6, 0, 0x2a77 _ 0)
+NAMED_CHARACTER_REFERENCE(933, /* d e */ 'g', 1, 0, 0x00b0 _ 0)
+NAMED_CHARACTER_REFERENCE(934, /* d e */ 'g' _ ';', 2, 0, 0x00b0 _ 0)
+NAMED_CHARACTER_REFERENCE(935, /* d e */ 'l' _ 't' _ 'a' _ ';', 4, 0, 0x03b4 _ 0)
+NAMED_CHARACTER_REFERENCE(936, /* d e */ 'm' _ 'p' _ 't' _ 'y' _ 'v' _ ';', 6, 0, 0x29b1 _ 0)
+NAMED_CHARACTER_REFERENCE(937, /* d f */ 'i' _ 's' _ 'h' _ 't' _ ';', 5, 0, 0x297f _ 0)
+NAMED_CHARACTER_REFERENCE(938, /* d f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd21)
+NAMED_CHARACTER_REFERENCE(939, /* d h */ 'a' _ 'r' _ 'l' _ ';', 4, 0, 0x21c3 _ 0)
+NAMED_CHARACTER_REFERENCE(940, /* d h */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21c2 _ 0)
+NAMED_CHARACTER_REFERENCE(941, /* d i */ 'a' _ 'm' _ ';', 3, 0, 0x22c4 _ 0)
+NAMED_CHARACTER_REFERENCE(942, /* d i */ 'a' _ 'm' _ 'o' _ 'n' _ 'd' _ ';', 6, 0, 0x22c4 _ 0)
+NAMED_CHARACTER_REFERENCE(943, /* d i */ 'a' _ 'm' _ 'o' _ 'n' _ 'd' _ 's' _ 'u' _ 'i' _ 't' _ ';', 10, 0, 0x2666 _ 0)
+NAMED_CHARACTER_REFERENCE(944, /* d i */ 'a' _ 'm' _ 's' _ ';', 4, 0, 0x2666 _ 0)
+NAMED_CHARACTER_REFERENCE(945, /* d i */ 'e' _ ';', 2, 0, 0x00a8 _ 0)
+NAMED_CHARACTER_REFERENCE(946, /* d i */ 'g' _ 'a' _ 'm' _ 'm' _ 'a' _ ';', 6, 0, 0x03dd _ 0)
+NAMED_CHARACTER_REFERENCE(947, /* d i */ 's' _ 'i' _ 'n' _ ';', 4, 0, 0x22f2 _ 0)
+NAMED_CHARACTER_REFERENCE(948, /* d i */ 'v' _ ';', 2, 0, 0x00f7 _ 0)
+NAMED_CHARACTER_REFERENCE(949, /* d i */ 'v' _ 'i' _ 'd' _ 'e', 4, 0, 0x00f7 _ 0)
+NAMED_CHARACTER_REFERENCE(950, /* d i */ 'v' _ 'i' _ 'd' _ 'e' _ ';', 5, 0, 0x00f7 _ 0)
+NAMED_CHARACTER_REFERENCE(951, /* d i */ 'v' _ 'i' _ 'd' _ 'e' _ 'o' _ 'n' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 12, 0, 0x22c7 _ 0)
+NAMED_CHARACTER_REFERENCE(952, /* d i */ 'v' _ 'o' _ 'n' _ 'x' _ ';', 5, 0, 0x22c7 _ 0)
+NAMED_CHARACTER_REFERENCE(953, /* d j */ 'c' _ 'y' _ ';', 3, 0, 0x0452 _ 0)
+NAMED_CHARACTER_REFERENCE(954, /* d l */ 'c' _ 'o' _ 'r' _ 'n' _ ';', 5, 0, 0x231e _ 0)
+NAMED_CHARACTER_REFERENCE(955, /* d l */ 'c' _ 'r' _ 'o' _ 'p' _ ';', 5, 0, 0x230d _ 0)
+NAMED_CHARACTER_REFERENCE(956, /* d o */ 'l' _ 'l' _ 'a' _ 'r' _ ';', 5, 0, 0x0024 _ 0)
+NAMED_CHARACTER_REFERENCE(957, /* d o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd55)
+NAMED_CHARACTER_REFERENCE(958, /* d o */ 't' _ ';', 2, 0, 0x02d9 _ 0)
+NAMED_CHARACTER_REFERENCE(959, /* d o */ 't' _ 'e' _ 'q' _ ';', 4, 0, 0x2250 _ 0)
+NAMED_CHARACTER_REFERENCE(960, /* d o */ 't' _ 'e' _ 'q' _ 'd' _ 'o' _ 't' _ ';', 7, 0, 0x2251 _ 0)
+NAMED_CHARACTER_REFERENCE(961, /* d o */ 't' _ 'm' _ 'i' _ 'n' _ 'u' _ 's' _ ';', 7, 0, 0x2238 _ 0)
+NAMED_CHARACTER_REFERENCE(962, /* d o */ 't' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 6, 0, 0x2214 _ 0)
+NAMED_CHARACTER_REFERENCE(963, /* d o */ 't' _ 's' _ 'q' _ 'u' _ 'a' _ 'r' _ 'e' _ ';', 8, 0, 0x22a1 _ 0)
+NAMED_CHARACTER_REFERENCE(964, /* d o */ 'u' _ 'b' _ 'l' _ 'e' _ 'b' _ 'a' _ 'r' _ 'w' _ 'e' _ 'd' _ 'g' _ 'e' _ ';', 13, 0, 0x2306 _ 0)
+NAMED_CHARACTER_REFERENCE(965, /* d o */ 'w' _ 'n' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 8, 0, 0x2193 _ 0)
+NAMED_CHARACTER_REFERENCE(966, /* d o */ 'w' _ 'n' _ 'd' _ 'o' _ 'w' _ 'n' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 's' _ ';', 13, 0, 0x21ca _ 0)
+NAMED_CHARACTER_REFERENCE(967, /* d o */ 'w' _ 'n' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 14, 0, 0x21c3 _ 0)
+NAMED_CHARACTER_REFERENCE(968, /* d o */ 'w' _ 'n' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 15, 0, 0x21c2 _ 0)
+NAMED_CHARACTER_REFERENCE(969, /* d r */ 'b' _ 'k' _ 'a' _ 'r' _ 'o' _ 'w' _ ';', 7, 0, 0x2910 _ 0)
+NAMED_CHARACTER_REFERENCE(970, /* d r */ 'c' _ 'o' _ 'r' _ 'n' _ ';', 5, 0, 0x231f _ 0)
+NAMED_CHARACTER_REFERENCE(971, /* d r */ 'c' _ 'r' _ 'o' _ 'p' _ ';', 5, 0, 0x230c _ 0)
+NAMED_CHARACTER_REFERENCE(972, /* d s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcb9)
+NAMED_CHARACTER_REFERENCE(973, /* d s */ 'c' _ 'y' _ ';', 3, 0, 0x0455 _ 0)
+NAMED_CHARACTER_REFERENCE(974, /* d s */ 'o' _ 'l' _ ';', 3, 0, 0x29f6 _ 0)
+NAMED_CHARACTER_REFERENCE(975, /* d s */ 't' _ 'r' _ 'o' _ 'k' _ ';', 5, 0, 0x0111 _ 0)
+NAMED_CHARACTER_REFERENCE(976, /* d t */ 'd' _ 'o' _ 't' _ ';', 4, 0, 0x22f1 _ 0)
+NAMED_CHARACTER_REFERENCE(977, /* d t */ 'r' _ 'i' _ ';', 3, 0, 0x25bf _ 0)
+NAMED_CHARACTER_REFERENCE(978, /* d t */ 'r' _ 'i' _ 'f' _ ';', 4, 0, 0x25be _ 0)
+NAMED_CHARACTER_REFERENCE(979, /* d u */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21f5 _ 0)
+NAMED_CHARACTER_REFERENCE(980, /* d u */ 'h' _ 'a' _ 'r' _ ';', 4, 0, 0x296f _ 0)
+NAMED_CHARACTER_REFERENCE(981, /* d w */ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 6, 0, 0x29a6 _ 0)
+NAMED_CHARACTER_REFERENCE(982, /* d z */ 'c' _ 'y' _ ';', 3, 0, 0x045f _ 0)
+NAMED_CHARACTER_REFERENCE(983, /* d z */ 'i' _ 'g' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 7, 0, 0x27ff _ 0)
+NAMED_CHARACTER_REFERENCE(984, /* e D */ 'D' _ 'o' _ 't' _ ';', 4, 0, 0x2a77 _ 0)
+NAMED_CHARACTER_REFERENCE(985, /* e D */ 'o' _ 't' _ ';', 3, 0, 0x2251 _ 0)
+NAMED_CHARACTER_REFERENCE(986, /* e a */ 'c' _ 'u' _ 't' _ 'e', 4, 0, 0x00e9 _ 0)
+NAMED_CHARACTER_REFERENCE(987, /* e a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x00e9 _ 0)
+NAMED_CHARACTER_REFERENCE(988, /* e a */ 's' _ 't' _ 'e' _ 'r' _ ';', 5, 0, 0x2a6e _ 0)
+NAMED_CHARACTER_REFERENCE(989, /* e c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x011b _ 0)
+NAMED_CHARACTER_REFERENCE(990, /* e c */ 'i' _ 'r' _ ';', 3, 0, 0x2256 _ 0)
+NAMED_CHARACTER_REFERENCE(991, /* e c */ 'i' _ 'r' _ 'c', 3, 0, 0x00ea _ 0)
+NAMED_CHARACTER_REFERENCE(992, /* e c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x00ea _ 0)
+NAMED_CHARACTER_REFERENCE(993, /* e c */ 'o' _ 'l' _ 'o' _ 'n' _ ';', 5, 0, 0x2255 _ 0)
+NAMED_CHARACTER_REFERENCE(994, /* e c */ 'y' _ ';', 2, 0, 0x044d _ 0)
+NAMED_CHARACTER_REFERENCE(995, /* e d */ 'o' _ 't' _ ';', 3, 0, 0x0117 _ 0)
+NAMED_CHARACTER_REFERENCE(996, /* e e */ ';', 1, 0, 0x2147 _ 0)
+NAMED_CHARACTER_REFERENCE(997, /* e f */ 'D' _ 'o' _ 't' _ ';', 4, 0, 0x2252 _ 0)
+NAMED_CHARACTER_REFERENCE(998, /* e f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd22)
+NAMED_CHARACTER_REFERENCE(999, /* e g */ ';', 1, 0, 0x2a9a _ 0)
+NAMED_CHARACTER_REFERENCE(1000, /* e g */ 'r' _ 'a' _ 'v' _ 'e', 4, 0, 0x00e8 _ 0)
+NAMED_CHARACTER_REFERENCE(1001, /* e g */ 'r' _ 'a' _ 'v' _ 'e' _ ';', 5, 0, 0x00e8 _ 0)
+NAMED_CHARACTER_REFERENCE(1002, /* e g */ 's' _ ';', 2, 0, 0x2a96 _ 0)
+NAMED_CHARACTER_REFERENCE(1003, /* e g */ 's' _ 'd' _ 'o' _ 't' _ ';', 5, 0, 0x2a98 _ 0)
+NAMED_CHARACTER_REFERENCE(1004, /* e l */ ';', 1, 0, 0x2a99 _ 0)
+NAMED_CHARACTER_REFERENCE(1005, /* e l */ 'i' _ 'n' _ 't' _ 'e' _ 'r' _ 's' _ ';', 7, 0, 0x23e7 _ 0)
+NAMED_CHARACTER_REFERENCE(1006, /* e l */ 'l' _ ';', 2, 0, 0x2113 _ 0)
+NAMED_CHARACTER_REFERENCE(1007, /* e l */ 's' _ ';', 2, 0, 0x2a95 _ 0)
+NAMED_CHARACTER_REFERENCE(1008, /* e l */ 's' _ 'd' _ 'o' _ 't' _ ';', 5, 0, 0x2a97 _ 0)
+NAMED_CHARACTER_REFERENCE(1009, /* e m */ 'a' _ 'c' _ 'r' _ ';', 4, 0, 0x0113 _ 0)
+NAMED_CHARACTER_REFERENCE(1010, /* e m */ 'p' _ 't' _ 'y' _ ';', 4, 0, 0x2205 _ 0)
+NAMED_CHARACTER_REFERENCE(1011, /* e m */ 'p' _ 't' _ 'y' _ 's' _ 'e' _ 't' _ ';', 7, 0, 0x2205 _ 0)
+NAMED_CHARACTER_REFERENCE(1012, /* e m */ 'p' _ 't' _ 'y' _ 'v' _ ';', 5, 0, 0x2205 _ 0)
+NAMED_CHARACTER_REFERENCE(1013, /* e m */ 's' _ 'p' _ '1' _ '3' _ ';', 5, 0, 0x2004 _ 0)
+NAMED_CHARACTER_REFERENCE(1014, /* e m */ 's' _ 'p' _ '1' _ '4' _ ';', 5, 0, 0x2005 _ 0)
+NAMED_CHARACTER_REFERENCE(1015, /* e m */ 's' _ 'p' _ ';', 3, 0, 0x2003 _ 0)
+NAMED_CHARACTER_REFERENCE(1016, /* e n */ 'g' _ ';', 2, 0, 0x014b _ 0)
+NAMED_CHARACTER_REFERENCE(1017, /* e n */ 's' _ 'p' _ ';', 3, 0, 0x2002 _ 0)
+NAMED_CHARACTER_REFERENCE(1018, /* e o */ 'g' _ 'o' _ 'n' _ ';', 4, 0, 0x0119 _ 0)
+NAMED_CHARACTER_REFERENCE(1019, /* e o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd56)
+NAMED_CHARACTER_REFERENCE(1020, /* e p */ 'a' _ 'r' _ ';', 3, 0, 0x22d5 _ 0)
+NAMED_CHARACTER_REFERENCE(1021, /* e p */ 'a' _ 'r' _ 's' _ 'l' _ ';', 5, 0, 0x29e3 _ 0)
+NAMED_CHARACTER_REFERENCE(1022, /* e p */ 'l' _ 'u' _ 's' _ ';', 4, 0, 0x2a71 _ 0)
+NAMED_CHARACTER_REFERENCE(1023, /* e p */ 's' _ 'i' _ ';', 3, 0, 0x03b5 _ 0)
+NAMED_CHARACTER_REFERENCE(1024, /* e p */ 's' _ 'i' _ 'l' _ 'o' _ 'n' _ ';', 6, 0, 0x03b5 _ 0)
+NAMED_CHARACTER_REFERENCE(1025, /* e p */ 's' _ 'i' _ 'v' _ ';', 4, 0, 0x03f5 _ 0)
+NAMED_CHARACTER_REFERENCE(1026, /* e q */ 'c' _ 'i' _ 'r' _ 'c' _ ';', 5, 0, 0x2256 _ 0)
+NAMED_CHARACTER_REFERENCE(1027, /* e q */ 'c' _ 'o' _ 'l' _ 'o' _ 'n' _ ';', 6, 0, 0x2255 _ 0)
+NAMED_CHARACTER_REFERENCE(1028, /* e q */ 's' _ 'i' _ 'm' _ ';', 4, 0, 0x2242 _ 0)
+NAMED_CHARACTER_REFERENCE(1029, /* e q */ 's' _ 'l' _ 'a' _ 'n' _ 't' _ 'g' _ 't' _ 'r' _ ';', 9, 0, 0x2a96 _ 0)
+NAMED_CHARACTER_REFERENCE(1030, /* e q */ 's' _ 'l' _ 'a' _ 'n' _ 't' _ 'l' _ 'e' _ 's' _ 's' _ ';', 10, 0, 0x2a95 _ 0)
+NAMED_CHARACTER_REFERENCE(1031, /* e q */ 'u' _ 'a' _ 'l' _ 's' _ ';', 5, 0, 0x003d _ 0)
+NAMED_CHARACTER_REFERENCE(1032, /* e q */ 'u' _ 'e' _ 's' _ 't' _ ';', 5, 0, 0x225f _ 0)
+NAMED_CHARACTER_REFERENCE(1033, /* e q */ 'u' _ 'i' _ 'v' _ ';', 4, 0, 0x2261 _ 0)
+NAMED_CHARACTER_REFERENCE(1034, /* e q */ 'u' _ 'i' _ 'v' _ 'D' _ 'D' _ ';', 6, 0, 0x2a78 _ 0)
+NAMED_CHARACTER_REFERENCE(1035, /* e q */ 'v' _ 'p' _ 'a' _ 'r' _ 's' _ 'l' _ ';', 7, 0, 0x29e5 _ 0)
+NAMED_CHARACTER_REFERENCE(1036, /* e r */ 'D' _ 'o' _ 't' _ ';', 4, 0, 0x2253 _ 0)
+NAMED_CHARACTER_REFERENCE(1037, /* e r */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x2971 _ 0)
+NAMED_CHARACTER_REFERENCE(1038, /* e s */ 'c' _ 'r' _ ';', 3, 0, 0x212f _ 0)
+NAMED_CHARACTER_REFERENCE(1039, /* e s */ 'd' _ 'o' _ 't' _ ';', 4, 0, 0x2250 _ 0)
+NAMED_CHARACTER_REFERENCE(1040, /* e s */ 'i' _ 'm' _ ';', 3, 0, 0x2242 _ 0)
+NAMED_CHARACTER_REFERENCE(1041, /* e t */ 'a' _ ';', 2, 0, 0x03b7 _ 0)
+NAMED_CHARACTER_REFERENCE(1042, /* e t */ 'h', 1, 0, 0x00f0 _ 0)
+NAMED_CHARACTER_REFERENCE(1043, /* e t */ 'h' _ ';', 2, 0, 0x00f0 _ 0)
+NAMED_CHARACTER_REFERENCE(1044, /* e u */ 'm' _ 'l', 2, 0, 0x00eb _ 0)
+NAMED_CHARACTER_REFERENCE(1045, /* e u */ 'm' _ 'l' _ ';', 3, 0, 0x00eb _ 0)
+NAMED_CHARACTER_REFERENCE(1046, /* e u */ 'r' _ 'o' _ ';', 3, 0, 0x20ac _ 0)
+NAMED_CHARACTER_REFERENCE(1047, /* e x */ 'c' _ 'l' _ ';', 3, 0, 0x0021 _ 0)
+NAMED_CHARACTER_REFERENCE(1048, /* e x */ 'i' _ 's' _ 't' _ ';', 4, 0, 0x2203 _ 0)
+NAMED_CHARACTER_REFERENCE(1049, /* e x */ 'p' _ 'e' _ 'c' _ 't' _ 'a' _ 't' _ 'i' _ 'o' _ 'n' _ ';', 10, 0, 0x2130 _ 0)
+NAMED_CHARACTER_REFERENCE(1050, /* e x */ 'p' _ 'o' _ 'n' _ 'e' _ 'n' _ 't' _ 'i' _ 'a' _ 'l' _ 'e' _ ';', 11, 0, 0x2147 _ 0)
+NAMED_CHARACTER_REFERENCE(1051, /* f a */ 'l' _ 'l' _ 'i' _ 'n' _ 'g' _ 'd' _ 'o' _ 't' _ 's' _ 'e' _ 'q' _ ';', 12, 0, 0x2252 _ 0)
+NAMED_CHARACTER_REFERENCE(1052, /* f c */ 'y' _ ';', 2, 0, 0x0444 _ 0)
+NAMED_CHARACTER_REFERENCE(1053, /* f e */ 'm' _ 'a' _ 'l' _ 'e' _ ';', 5, 0, 0x2640 _ 0)
+NAMED_CHARACTER_REFERENCE(1054, /* f f */ 'i' _ 'l' _ 'i' _ 'g' _ ';', 5, 0, 0xfb03 _ 0)
+NAMED_CHARACTER_REFERENCE(1055, /* f f */ 'l' _ 'i' _ 'g' _ ';', 4, 0, 0xfb00 _ 0)
+NAMED_CHARACTER_REFERENCE(1056, /* f f */ 'l' _ 'l' _ 'i' _ 'g' _ ';', 5, 0, 0xfb04 _ 0)
+NAMED_CHARACTER_REFERENCE(1057, /* f f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd23)
+NAMED_CHARACTER_REFERENCE(1058, /* f i */ 'l' _ 'i' _ 'g' _ ';', 4, 0, 0xfb01 _ 0)
+NAMED_CHARACTER_REFERENCE(1059, /* f j */ 'l' _ 'i' _ 'g' _ ';', 4, 0, 0x0066 _ 0x006a)
+NAMED_CHARACTER_REFERENCE(1060, /* f l */ 'a' _ 't' _ ';', 3, 0, 0x266d _ 0)
+NAMED_CHARACTER_REFERENCE(1061, /* f l */ 'l' _ 'i' _ 'g' _ ';', 4, 0, 0xfb02 _ 0)
+NAMED_CHARACTER_REFERENCE(1062, /* f l */ 't' _ 'n' _ 's' _ ';', 4, 0, 0x25b1 _ 0)
+NAMED_CHARACTER_REFERENCE(1063, /* f n */ 'o' _ 'f' _ ';', 3, 0, 0x0192 _ 0)
+NAMED_CHARACTER_REFERENCE(1064, /* f o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd57)
+NAMED_CHARACTER_REFERENCE(1065, /* f o */ 'r' _ 'a' _ 'l' _ 'l' _ ';', 5, 0, 0x2200 _ 0)
+NAMED_CHARACTER_REFERENCE(1066, /* f o */ 'r' _ 'k' _ ';', 3, 0, 0x22d4 _ 0)
+NAMED_CHARACTER_REFERENCE(1067, /* f o */ 'r' _ 'k' _ 'v' _ ';', 4, 0, 0x2ad9 _ 0)
+NAMED_CHARACTER_REFERENCE(1068, /* f p */ 'a' _ 'r' _ 't' _ 'i' _ 'n' _ 't' _ ';', 7, 0, 0x2a0d _ 0)
+NAMED_CHARACTER_REFERENCE(1069, /* f r */ 'a' _ 'c' _ '1' _ '2', 4, 0, 0x00bd _ 0)
+NAMED_CHARACTER_REFERENCE(1070, /* f r */ 'a' _ 'c' _ '1' _ '2' _ ';', 5, 0, 0x00bd _ 0)
+NAMED_CHARACTER_REFERENCE(1071, /* f r */ 'a' _ 'c' _ '1' _ '3' _ ';', 5, 0, 0x2153 _ 0)
+NAMED_CHARACTER_REFERENCE(1072, /* f r */ 'a' _ 'c' _ '1' _ '4', 4, 0, 0x00bc _ 0)
+NAMED_CHARACTER_REFERENCE(1073, /* f r */ 'a' _ 'c' _ '1' _ '4' _ ';', 5, 0, 0x00bc _ 0)
+NAMED_CHARACTER_REFERENCE(1074, /* f r */ 'a' _ 'c' _ '1' _ '5' _ ';', 5, 0, 0x2155 _ 0)
+NAMED_CHARACTER_REFERENCE(1075, /* f r */ 'a' _ 'c' _ '1' _ '6' _ ';', 5, 0, 0x2159 _ 0)
+NAMED_CHARACTER_REFERENCE(1076, /* f r */ 'a' _ 'c' _ '1' _ '8' _ ';', 5, 0, 0x215b _ 0)
+NAMED_CHARACTER_REFERENCE(1077, /* f r */ 'a' _ 'c' _ '2' _ '3' _ ';', 5, 0, 0x2154 _ 0)
+NAMED_CHARACTER_REFERENCE(1078, /* f r */ 'a' _ 'c' _ '2' _ '5' _ ';', 5, 0, 0x2156 _ 0)
+NAMED_CHARACTER_REFERENCE(1079, /* f r */ 'a' _ 'c' _ '3' _ '4', 4, 0, 0x00be _ 0)
+NAMED_CHARACTER_REFERENCE(1080, /* f r */ 'a' _ 'c' _ '3' _ '4' _ ';', 5, 0, 0x00be _ 0)
+NAMED_CHARACTER_REFERENCE(1081, /* f r */ 'a' _ 'c' _ '3' _ '5' _ ';', 5, 0, 0x2157 _ 0)
+NAMED_CHARACTER_REFERENCE(1082, /* f r */ 'a' _ 'c' _ '3' _ '8' _ ';', 5, 0, 0x215c _ 0)
+NAMED_CHARACTER_REFERENCE(1083, /* f r */ 'a' _ 'c' _ '4' _ '5' _ ';', 5, 0, 0x2158 _ 0)
+NAMED_CHARACTER_REFERENCE(1084, /* f r */ 'a' _ 'c' _ '5' _ '6' _ ';', 5, 0, 0x215a _ 0)
+NAMED_CHARACTER_REFERENCE(1085, /* f r */ 'a' _ 'c' _ '5' _ '8' _ ';', 5, 0, 0x215d _ 0)
+NAMED_CHARACTER_REFERENCE(1086, /* f r */ 'a' _ 'c' _ '7' _ '8' _ ';', 5, 0, 0x215e _ 0)
+NAMED_CHARACTER_REFERENCE(1087, /* f r */ 'a' _ 's' _ 'l' _ ';', 4, 0, 0x2044 _ 0)
+NAMED_CHARACTER_REFERENCE(1088, /* f r */ 'o' _ 'w' _ 'n' _ ';', 4, 0, 0x2322 _ 0)
+NAMED_CHARACTER_REFERENCE(1089, /* f s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcbb)
+NAMED_CHARACTER_REFERENCE(1090, /* g E */ ';', 1, 0, 0x2267 _ 0)
+NAMED_CHARACTER_REFERENCE(1091, /* g E */ 'l' _ ';', 2, 0, 0x2a8c _ 0)
+NAMED_CHARACTER_REFERENCE(1092, /* g a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x01f5 _ 0)
+NAMED_CHARACTER_REFERENCE(1093, /* g a */ 'm' _ 'm' _ 'a' _ ';', 4, 0, 0x03b3 _ 0)
+NAMED_CHARACTER_REFERENCE(1094, /* g a */ 'm' _ 'm' _ 'a' _ 'd' _ ';', 5, 0, 0x03dd _ 0)
+NAMED_CHARACTER_REFERENCE(1095, /* g a */ 'p' _ ';', 2, 0, 0x2a86 _ 0)
+NAMED_CHARACTER_REFERENCE(1096, /* g b */ 'r' _ 'e' _ 'v' _ 'e' _ ';', 5, 0, 0x011f _ 0)
+NAMED_CHARACTER_REFERENCE(1097, /* g c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x011d _ 0)
+NAMED_CHARACTER_REFERENCE(1098, /* g c */ 'y' _ ';', 2, 0, 0x0433 _ 0)
+NAMED_CHARACTER_REFERENCE(1099, /* g d */ 'o' _ 't' _ ';', 3, 0, 0x0121 _ 0)
+NAMED_CHARACTER_REFERENCE(1100, /* g e */ ';', 1, 0, 0x2265 _ 0)
+NAMED_CHARACTER_REFERENCE(1101, /* g e */ 'l' _ ';', 2, 0, 0x22db _ 0)
+NAMED_CHARACTER_REFERENCE(1102, /* g e */ 'q' _ ';', 2, 0, 0x2265 _ 0)
+NAMED_CHARACTER_REFERENCE(1103, /* g e */ 'q' _ 'q' _ ';', 3, 0, 0x2267 _ 0)
+NAMED_CHARACTER_REFERENCE(1104, /* g e */ 'q' _ 's' _ 'l' _ 'a' _ 'n' _ 't' _ ';', 7, 0, 0x2a7e _ 0)
+NAMED_CHARACTER_REFERENCE(1105, /* g e */ 's' _ ';', 2, 0, 0x2a7e _ 0)
+NAMED_CHARACTER_REFERENCE(1106, /* g e */ 's' _ 'c' _ 'c' _ ';', 4, 0, 0x2aa9 _ 0)
+NAMED_CHARACTER_REFERENCE(1107, /* g e */ 's' _ 'd' _ 'o' _ 't' _ ';', 5, 0, 0x2a80 _ 0)
+NAMED_CHARACTER_REFERENCE(1108, /* g e */ 's' _ 'd' _ 'o' _ 't' _ 'o' _ ';', 6, 0, 0x2a82 _ 0)
+NAMED_CHARACTER_REFERENCE(1109, /* g e */ 's' _ 'd' _ 'o' _ 't' _ 'o' _ 'l' _ ';', 7, 0, 0x2a84 _ 0)
+NAMED_CHARACTER_REFERENCE(1110, /* g e */ 's' _ 'l' _ ';', 3, 0, 0x22db _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(1111, /* g e */ 's' _ 'l' _ 'e' _ 's' _ ';', 5, 0, 0x2a94 _ 0)
+NAMED_CHARACTER_REFERENCE(1112, /* g f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd24)
+NAMED_CHARACTER_REFERENCE(1113, /* g g */ ';', 1, 0, 0x226b _ 0)
+NAMED_CHARACTER_REFERENCE(1114, /* g g */ 'g' _ ';', 2, 0, 0x22d9 _ 0)
+NAMED_CHARACTER_REFERENCE(1115, /* g i */ 'm' _ 'e' _ 'l' _ ';', 4, 0, 0x2137 _ 0)
+NAMED_CHARACTER_REFERENCE(1116, /* g j */ 'c' _ 'y' _ ';', 3, 0, 0x0453 _ 0)
+NAMED_CHARACTER_REFERENCE(1117, /* g l */ ';', 1, 0, 0x2277 _ 0)
+NAMED_CHARACTER_REFERENCE(1118, /* g l */ 'E' _ ';', 2, 0, 0x2a92 _ 0)
+NAMED_CHARACTER_REFERENCE(1119, /* g l */ 'a' _ ';', 2, 0, 0x2aa5 _ 0)
+NAMED_CHARACTER_REFERENCE(1120, /* g l */ 'j' _ ';', 2, 0, 0x2aa4 _ 0)
+NAMED_CHARACTER_REFERENCE(1121, /* g n */ 'E' _ ';', 2, 0, 0x2269 _ 0)
+NAMED_CHARACTER_REFERENCE(1122, /* g n */ 'a' _ 'p' _ ';', 3, 0, 0x2a8a _ 0)
+NAMED_CHARACTER_REFERENCE(1123, /* g n */ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 7, 0, 0x2a8a _ 0)
+NAMED_CHARACTER_REFERENCE(1124, /* g n */ 'e' _ ';', 2, 0, 0x2a88 _ 0)
+NAMED_CHARACTER_REFERENCE(1125, /* g n */ 'e' _ 'q' _ ';', 3, 0, 0x2a88 _ 0)
+NAMED_CHARACTER_REFERENCE(1126, /* g n */ 'e' _ 'q' _ 'q' _ ';', 4, 0, 0x2269 _ 0)
+NAMED_CHARACTER_REFERENCE(1127, /* g n */ 's' _ 'i' _ 'm' _ ';', 4, 0, 0x22e7 _ 0)
+NAMED_CHARACTER_REFERENCE(1128, /* g o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd58)
+NAMED_CHARACTER_REFERENCE(1129, /* g r */ 'a' _ 'v' _ 'e' _ ';', 4, 0, 0x0060 _ 0)
+NAMED_CHARACTER_REFERENCE(1130, /* g s */ 'c' _ 'r' _ ';', 3, 0, 0x210a _ 0)
+NAMED_CHARACTER_REFERENCE(1131, /* g s */ 'i' _ 'm' _ ';', 3, 0, 0x2273 _ 0)
+NAMED_CHARACTER_REFERENCE(1132, /* g s */ 'i' _ 'm' _ 'e' _ ';', 4, 0, 0x2a8e _ 0)
+NAMED_CHARACTER_REFERENCE(1133, /* g s */ 'i' _ 'm' _ 'l' _ ';', 4, 0, 0x2a90 _ 0)
+NAMED_CHARACTER_REFERENCE(1134, /* g t */ 0, 0, 1, 0x003e _ 0)
+NAMED_CHARACTER_REFERENCE(1135, /* g t */ ';', 1, 0, 0x003e _ 0)
+NAMED_CHARACTER_REFERENCE(1136, /* g t */ 'c' _ 'c' _ ';', 3, 0, 0x2aa7 _ 0)
+NAMED_CHARACTER_REFERENCE(1137, /* g t */ 'c' _ 'i' _ 'r' _ ';', 4, 0, 0x2a7a _ 0)
+NAMED_CHARACTER_REFERENCE(1138, /* g t */ 'd' _ 'o' _ 't' _ ';', 4, 0, 0x22d7 _ 0)
+NAMED_CHARACTER_REFERENCE(1139, /* g t */ 'l' _ 'P' _ 'a' _ 'r' _ ';', 5, 0, 0x2995 _ 0)
+NAMED_CHARACTER_REFERENCE(1140, /* g t */ 'q' _ 'u' _ 'e' _ 's' _ 't' _ ';', 6, 0, 0x2a7c _ 0)
+NAMED_CHARACTER_REFERENCE(1141, /* g t */ 'r' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 8, 0, 0x2a86 _ 0)
+NAMED_CHARACTER_REFERENCE(1142, /* g t */ 'r' _ 'a' _ 'r' _ 'r' _ ';', 5, 0, 0x2978 _ 0)
+NAMED_CHARACTER_REFERENCE(1143, /* g t */ 'r' _ 'd' _ 'o' _ 't' _ ';', 5, 0, 0x22d7 _ 0)
+NAMED_CHARACTER_REFERENCE(1144, /* g t */ 'r' _ 'e' _ 'q' _ 'l' _ 'e' _ 's' _ 's' _ ';', 8, 0, 0x22db _ 0)
+NAMED_CHARACTER_REFERENCE(1145, /* g t */ 'r' _ 'e' _ 'q' _ 'q' _ 'l' _ 'e' _ 's' _ 's' _ ';', 9, 0, 0x2a8c _ 0)
+NAMED_CHARACTER_REFERENCE(1146, /* g t */ 'r' _ 'l' _ 'e' _ 's' _ 's' _ ';', 6, 0, 0x2277 _ 0)
+NAMED_CHARACTER_REFERENCE(1147, /* g t */ 'r' _ 's' _ 'i' _ 'm' _ ';', 5, 0, 0x2273 _ 0)
+NAMED_CHARACTER_REFERENCE(1148, /* g v */ 'e' _ 'r' _ 't' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 8, 0, 0x2269 _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(1149, /* g v */ 'n' _ 'E' _ ';', 3, 0, 0x2269 _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(1150, /* h A */ 'r' _ 'r' _ ';', 3, 0, 0x21d4 _ 0)
+NAMED_CHARACTER_REFERENCE(1151, /* h a */ 'i' _ 'r' _ 's' _ 'p' _ ';', 5, 0, 0x200a _ 0)
+NAMED_CHARACTER_REFERENCE(1152, /* h a */ 'l' _ 'f' _ ';', 3, 0, 0x00bd _ 0)
+NAMED_CHARACTER_REFERENCE(1153, /* h a */ 'm' _ 'i' _ 'l' _ 't' _ ';', 5, 0, 0x210b _ 0)
+NAMED_CHARACTER_REFERENCE(1154, /* h a */ 'r' _ 'd' _ 'c' _ 'y' _ ';', 5, 0, 0x044a _ 0)
+NAMED_CHARACTER_REFERENCE(1155, /* h a */ 'r' _ 'r' _ ';', 3, 0, 0x2194 _ 0)
+NAMED_CHARACTER_REFERENCE(1156, /* h a */ 'r' _ 'r' _ 'c' _ 'i' _ 'r' _ ';', 6, 0, 0x2948 _ 0)
+NAMED_CHARACTER_REFERENCE(1157, /* h a */ 'r' _ 'r' _ 'w' _ ';', 4, 0, 0x21ad _ 0)
+NAMED_CHARACTER_REFERENCE(1158, /* h b */ 'a' _ 'r' _ ';', 3, 0, 0x210f _ 0)
+NAMED_CHARACTER_REFERENCE(1159, /* h c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x0125 _ 0)
+NAMED_CHARACTER_REFERENCE(1160, /* h e */ 'a' _ 'r' _ 't' _ 's' _ ';', 5, 0, 0x2665 _ 0)
+NAMED_CHARACTER_REFERENCE(1161, /* h e */ 'a' _ 'r' _ 't' _ 's' _ 'u' _ 'i' _ 't' _ ';', 8, 0, 0x2665 _ 0)
+NAMED_CHARACTER_REFERENCE(1162, /* h e */ 'l' _ 'l' _ 'i' _ 'p' _ ';', 5, 0, 0x2026 _ 0)
+NAMED_CHARACTER_REFERENCE(1163, /* h e */ 'r' _ 'c' _ 'o' _ 'n' _ ';', 5, 0, 0x22b9 _ 0)
+NAMED_CHARACTER_REFERENCE(1164, /* h f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd25)
+NAMED_CHARACTER_REFERENCE(1165, /* h k */ 's' _ 'e' _ 'a' _ 'r' _ 'o' _ 'w' _ ';', 7, 0, 0x2925 _ 0)
+NAMED_CHARACTER_REFERENCE(1166, /* h k */ 's' _ 'w' _ 'a' _ 'r' _ 'o' _ 'w' _ ';', 7, 0, 0x2926 _ 0)
+NAMED_CHARACTER_REFERENCE(1167, /* h o */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21ff _ 0)
+NAMED_CHARACTER_REFERENCE(1168, /* h o */ 'm' _ 't' _ 'h' _ 't' _ ';', 5, 0, 0x223b _ 0)
+NAMED_CHARACTER_REFERENCE(1169, /* h o */ 'o' _ 'k' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 12, 0, 0x21a9 _ 0)
+NAMED_CHARACTER_REFERENCE(1170, /* h o */ 'o' _ 'k' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 13, 0, 0x21aa _ 0)
+NAMED_CHARACTER_REFERENCE(1171, /* h o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd59)
+NAMED_CHARACTER_REFERENCE(1172, /* h o */ 'r' _ 'b' _ 'a' _ 'r' _ ';', 5, 0, 0x2015 _ 0)
+NAMED_CHARACTER_REFERENCE(1173, /* h s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcbd)
+NAMED_CHARACTER_REFERENCE(1174, /* h s */ 'l' _ 'a' _ 's' _ 'h' _ ';', 5, 0, 0x210f _ 0)
+NAMED_CHARACTER_REFERENCE(1175, /* h s */ 't' _ 'r' _ 'o' _ 'k' _ ';', 5, 0, 0x0127 _ 0)
+NAMED_CHARACTER_REFERENCE(1176, /* h y */ 'b' _ 'u' _ 'l' _ 'l' _ ';', 5, 0, 0x2043 _ 0)
+NAMED_CHARACTER_REFERENCE(1177, /* h y */ 'p' _ 'h' _ 'e' _ 'n' _ ';', 5, 0, 0x2010 _ 0)
+NAMED_CHARACTER_REFERENCE(1178, /* i a */ 'c' _ 'u' _ 't' _ 'e', 4, 0, 0x00ed _ 0)
+NAMED_CHARACTER_REFERENCE(1179, /* i a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x00ed _ 0)
+NAMED_CHARACTER_REFERENCE(1180, /* i c */ ';', 1, 0, 0x2063 _ 0)
+NAMED_CHARACTER_REFERENCE(1181, /* i c */ 'i' _ 'r' _ 'c', 3, 0, 0x00ee _ 0)
+NAMED_CHARACTER_REFERENCE(1182, /* i c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x00ee _ 0)
+NAMED_CHARACTER_REFERENCE(1183, /* i c */ 'y' _ ';', 2, 0, 0x0438 _ 0)
+NAMED_CHARACTER_REFERENCE(1184, /* i e */ 'c' _ 'y' _ ';', 3, 0, 0x0435 _ 0)
+NAMED_CHARACTER_REFERENCE(1185, /* i e */ 'x' _ 'c' _ 'l', 3, 0, 0x00a1 _ 0)
+NAMED_CHARACTER_REFERENCE(1186, /* i e */ 'x' _ 'c' _ 'l' _ ';', 4, 0, 0x00a1 _ 0)
+NAMED_CHARACTER_REFERENCE(1187, /* i f */ 'f' _ ';', 2, 0, 0x21d4 _ 0)
+NAMED_CHARACTER_REFERENCE(1188, /* i f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd26)
+NAMED_CHARACTER_REFERENCE(1189, /* i g */ 'r' _ 'a' _ 'v' _ 'e', 4, 0, 0x00ec _ 0)
+NAMED_CHARACTER_REFERENCE(1190, /* i g */ 'r' _ 'a' _ 'v' _ 'e' _ ';', 5, 0, 0x00ec _ 0)
+NAMED_CHARACTER_REFERENCE(1191, /* i i */ ';', 1, 0, 0x2148 _ 0)
+NAMED_CHARACTER_REFERENCE(1192, /* i i */ 'i' _ 'i' _ 'n' _ 't' _ ';', 5, 0, 0x2a0c _ 0)
+NAMED_CHARACTER_REFERENCE(1193, /* i i */ 'i' _ 'n' _ 't' _ ';', 4, 0, 0x222d _ 0)
+NAMED_CHARACTER_REFERENCE(1194, /* i i */ 'n' _ 'f' _ 'i' _ 'n' _ ';', 5, 0, 0x29dc _ 0)
+NAMED_CHARACTER_REFERENCE(1195, /* i i */ 'o' _ 't' _ 'a' _ ';', 4, 0, 0x2129 _ 0)
+NAMED_CHARACTER_REFERENCE(1196, /* i j */ 'l' _ 'i' _ 'g' _ ';', 4, 0, 0x0133 _ 0)
+NAMED_CHARACTER_REFERENCE(1197, /* i m */ 'a' _ 'c' _ 'r' _ ';', 4, 0, 0x012b _ 0)
+NAMED_CHARACTER_REFERENCE(1198, /* i m */ 'a' _ 'g' _ 'e' _ ';', 4, 0, 0x2111 _ 0)
+NAMED_CHARACTER_REFERENCE(1199, /* i m */ 'a' _ 'g' _ 'l' _ 'i' _ 'n' _ 'e' _ ';', 7, 0, 0x2110 _ 0)
+NAMED_CHARACTER_REFERENCE(1200, /* i m */ 'a' _ 'g' _ 'p' _ 'a' _ 'r' _ 't' _ ';', 7, 0, 0x2111 _ 0)
+NAMED_CHARACTER_REFERENCE(1201, /* i m */ 'a' _ 't' _ 'h' _ ';', 4, 0, 0x0131 _ 0)
+NAMED_CHARACTER_REFERENCE(1202, /* i m */ 'o' _ 'f' _ ';', 3, 0, 0x22b7 _ 0)
+NAMED_CHARACTER_REFERENCE(1203, /* i m */ 'p' _ 'e' _ 'd' _ ';', 4, 0, 0x01b5 _ 0)
+NAMED_CHARACTER_REFERENCE(1204, /* i n */ ';', 1, 0, 0x2208 _ 0)
+NAMED_CHARACTER_REFERENCE(1205, /* i n */ 'c' _ 'a' _ 'r' _ 'e' _ ';', 5, 0, 0x2105 _ 0)
+NAMED_CHARACTER_REFERENCE(1206, /* i n */ 'f' _ 'i' _ 'n' _ ';', 4, 0, 0x221e _ 0)
+NAMED_CHARACTER_REFERENCE(1207, /* i n */ 'f' _ 'i' _ 'n' _ 't' _ 'i' _ 'e' _ ';', 7, 0, 0x29dd _ 0)
+NAMED_CHARACTER_REFERENCE(1208, /* i n */ 'o' _ 'd' _ 'o' _ 't' _ ';', 5, 0, 0x0131 _ 0)
+NAMED_CHARACTER_REFERENCE(1209, /* i n */ 't' _ ';', 2, 0, 0x222b _ 0)
+NAMED_CHARACTER_REFERENCE(1210, /* i n */ 't' _ 'c' _ 'a' _ 'l' _ ';', 5, 0, 0x22ba _ 0)
+NAMED_CHARACTER_REFERENCE(1211, /* i n */ 't' _ 'e' _ 'g' _ 'e' _ 'r' _ 's' _ ';', 7, 0, 0x2124 _ 0)
+NAMED_CHARACTER_REFERENCE(1212, /* i n */ 't' _ 'e' _ 'r' _ 'c' _ 'a' _ 'l' _ ';', 7, 0, 0x22ba _ 0)
+NAMED_CHARACTER_REFERENCE(1213, /* i n */ 't' _ 'l' _ 'a' _ 'r' _ 'h' _ 'k' _ ';', 7, 0, 0x2a17 _ 0)
+NAMED_CHARACTER_REFERENCE(1214, /* i n */ 't' _ 'p' _ 'r' _ 'o' _ 'd' _ ';', 6, 0, 0x2a3c _ 0)
+NAMED_CHARACTER_REFERENCE(1215, /* i o */ 'c' _ 'y' _ ';', 3, 0, 0x0451 _ 0)
+NAMED_CHARACTER_REFERENCE(1216, /* i o */ 'g' _ 'o' _ 'n' _ ';', 4, 0, 0x012f _ 0)
+NAMED_CHARACTER_REFERENCE(1217, /* i o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd5a)
+NAMED_CHARACTER_REFERENCE(1218, /* i o */ 't' _ 'a' _ ';', 3, 0, 0x03b9 _ 0)
+NAMED_CHARACTER_REFERENCE(1219, /* i p */ 'r' _ 'o' _ 'd' _ ';', 4, 0, 0x2a3c _ 0)
+NAMED_CHARACTER_REFERENCE(1220, /* i q */ 'u' _ 'e' _ 's' _ 't', 4, 0, 0x00bf _ 0)
+NAMED_CHARACTER_REFERENCE(1221, /* i q */ 'u' _ 'e' _ 's' _ 't' _ ';', 5, 0, 0x00bf _ 0)
+NAMED_CHARACTER_REFERENCE(1222, /* i s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcbe)
+NAMED_CHARACTER_REFERENCE(1223, /* i s */ 'i' _ 'n' _ ';', 3, 0, 0x2208 _ 0)
+NAMED_CHARACTER_REFERENCE(1224, /* i s */ 'i' _ 'n' _ 'E' _ ';', 4, 0, 0x22f9 _ 0)
+NAMED_CHARACTER_REFERENCE(1225, /* i s */ 'i' _ 'n' _ 'd' _ 'o' _ 't' _ ';', 6, 0, 0x22f5 _ 0)
+NAMED_CHARACTER_REFERENCE(1226, /* i s */ 'i' _ 'n' _ 's' _ ';', 4, 0, 0x22f4 _ 0)
+NAMED_CHARACTER_REFERENCE(1227, /* i s */ 'i' _ 'n' _ 's' _ 'v' _ ';', 5, 0, 0x22f3 _ 0)
+NAMED_CHARACTER_REFERENCE(1228, /* i s */ 'i' _ 'n' _ 'v' _ ';', 4, 0, 0x2208 _ 0)
+NAMED_CHARACTER_REFERENCE(1229, /* i t */ ';', 1, 0, 0x2062 _ 0)
+NAMED_CHARACTER_REFERENCE(1230, /* i t */ 'i' _ 'l' _ 'd' _ 'e' _ ';', 5, 0, 0x0129 _ 0)
+NAMED_CHARACTER_REFERENCE(1231, /* i u */ 'k' _ 'c' _ 'y' _ ';', 4, 0, 0x0456 _ 0)
+NAMED_CHARACTER_REFERENCE(1232, /* i u */ 'm' _ 'l', 2, 0, 0x00ef _ 0)
+NAMED_CHARACTER_REFERENCE(1233, /* i u */ 'm' _ 'l' _ ';', 3, 0, 0x00ef _ 0)
+NAMED_CHARACTER_REFERENCE(1234, /* j c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x0135 _ 0)
+NAMED_CHARACTER_REFERENCE(1235, /* j c */ 'y' _ ';', 2, 0, 0x0439 _ 0)
+NAMED_CHARACTER_REFERENCE(1236, /* j f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd27)
+NAMED_CHARACTER_REFERENCE(1237, /* j m */ 'a' _ 't' _ 'h' _ ';', 4, 0, 0x0237 _ 0)
+NAMED_CHARACTER_REFERENCE(1238, /* j o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd5b)
+NAMED_CHARACTER_REFERENCE(1239, /* j s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcbf)
+NAMED_CHARACTER_REFERENCE(1240, /* j s */ 'e' _ 'r' _ 'c' _ 'y' _ ';', 5, 0, 0x0458 _ 0)
+NAMED_CHARACTER_REFERENCE(1241, /* j u */ 'k' _ 'c' _ 'y' _ ';', 4, 0, 0x0454 _ 0)
+NAMED_CHARACTER_REFERENCE(1242, /* k a */ 'p' _ 'p' _ 'a' _ ';', 4, 0, 0x03ba _ 0)
+NAMED_CHARACTER_REFERENCE(1243, /* k a */ 'p' _ 'p' _ 'a' _ 'v' _ ';', 5, 0, 0x03f0 _ 0)
+NAMED_CHARACTER_REFERENCE(1244, /* k c */ 'e' _ 'd' _ 'i' _ 'l' _ ';', 5, 0, 0x0137 _ 0)
+NAMED_CHARACTER_REFERENCE(1245, /* k c */ 'y' _ ';', 2, 0, 0x043a _ 0)
+NAMED_CHARACTER_REFERENCE(1246, /* k f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd28)
+NAMED_CHARACTER_REFERENCE(1247, /* k g */ 'r' _ 'e' _ 'e' _ 'n' _ ';', 5, 0, 0x0138 _ 0)
+NAMED_CHARACTER_REFERENCE(1248, /* k h */ 'c' _ 'y' _ ';', 3, 0, 0x0445 _ 0)
+NAMED_CHARACTER_REFERENCE(1249, /* k j */ 'c' _ 'y' _ ';', 3, 0, 0x045c _ 0)
+NAMED_CHARACTER_REFERENCE(1250, /* k o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd5c)
+NAMED_CHARACTER_REFERENCE(1251, /* k s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcc0)
+NAMED_CHARACTER_REFERENCE(1252, /* l A */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21da _ 0)
+NAMED_CHARACTER_REFERENCE(1253, /* l A */ 'r' _ 'r' _ ';', 3, 0, 0x21d0 _ 0)
+NAMED_CHARACTER_REFERENCE(1254, /* l A */ 't' _ 'a' _ 'i' _ 'l' _ ';', 5, 0, 0x291b _ 0)
+NAMED_CHARACTER_REFERENCE(1255, /* l B */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x290e _ 0)
+NAMED_CHARACTER_REFERENCE(1256, /* l E */ ';', 1, 0, 0x2266 _ 0)
+NAMED_CHARACTER_REFERENCE(1257, /* l E */ 'g' _ ';', 2, 0, 0x2a8b _ 0)
+NAMED_CHARACTER_REFERENCE(1258, /* l H */ 'a' _ 'r' _ ';', 3, 0, 0x2962 _ 0)
+NAMED_CHARACTER_REFERENCE(1259, /* l a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x013a _ 0)
+NAMED_CHARACTER_REFERENCE(1260, /* l a */ 'e' _ 'm' _ 'p' _ 't' _ 'y' _ 'v' _ ';', 7, 0, 0x29b4 _ 0)
+NAMED_CHARACTER_REFERENCE(1261, /* l a */ 'g' _ 'r' _ 'a' _ 'n' _ ';', 5, 0, 0x2112 _ 0)
+NAMED_CHARACTER_REFERENCE(1262, /* l a */ 'm' _ 'b' _ 'd' _ 'a' _ ';', 5, 0, 0x03bb _ 0)
+NAMED_CHARACTER_REFERENCE(1263, /* l a */ 'n' _ 'g' _ ';', 3, 0, 0x27e8 _ 0)
+NAMED_CHARACTER_REFERENCE(1264, /* l a */ 'n' _ 'g' _ 'd' _ ';', 4, 0, 0x2991 _ 0)
+NAMED_CHARACTER_REFERENCE(1265, /* l a */ 'n' _ 'g' _ 'l' _ 'e' _ ';', 5, 0, 0x27e8 _ 0)
+NAMED_CHARACTER_REFERENCE(1266, /* l a */ 'p' _ ';', 2, 0, 0x2a85 _ 0)
+NAMED_CHARACTER_REFERENCE(1267, /* l a */ 'q' _ 'u' _ 'o', 3, 0, 0x00ab _ 0)
+NAMED_CHARACTER_REFERENCE(1268, /* l a */ 'q' _ 'u' _ 'o' _ ';', 4, 0, 0x00ab _ 0)
+NAMED_CHARACTER_REFERENCE(1269, /* l a */ 'r' _ 'r' _ ';', 3, 0, 0x2190 _ 0)
+NAMED_CHARACTER_REFERENCE(1270, /* l a */ 'r' _ 'r' _ 'b' _ ';', 4, 0, 0x21e4 _ 0)
+NAMED_CHARACTER_REFERENCE(1271, /* l a */ 'r' _ 'r' _ 'b' _ 'f' _ 's' _ ';', 6, 0, 0x291f _ 0)
+NAMED_CHARACTER_REFERENCE(1272, /* l a */ 'r' _ 'r' _ 'f' _ 's' _ ';', 5, 0, 0x291d _ 0)
+NAMED_CHARACTER_REFERENCE(1273, /* l a */ 'r' _ 'r' _ 'h' _ 'k' _ ';', 5, 0, 0x21a9 _ 0)
+NAMED_CHARACTER_REFERENCE(1274, /* l a */ 'r' _ 'r' _ 'l' _ 'p' _ ';', 5, 0, 0x21ab _ 0)
+NAMED_CHARACTER_REFERENCE(1275, /* l a */ 'r' _ 'r' _ 'p' _ 'l' _ ';', 5, 0, 0x2939 _ 0)
+NAMED_CHARACTER_REFERENCE(1276, /* l a */ 'r' _ 'r' _ 's' _ 'i' _ 'm' _ ';', 6, 0, 0x2973 _ 0)
+NAMED_CHARACTER_REFERENCE(1277, /* l a */ 'r' _ 'r' _ 't' _ 'l' _ ';', 5, 0, 0x21a2 _ 0)
+NAMED_CHARACTER_REFERENCE(1278, /* l a */ 't' _ ';', 2, 0, 0x2aab _ 0)
+NAMED_CHARACTER_REFERENCE(1279, /* l a */ 't' _ 'a' _ 'i' _ 'l' _ ';', 5, 0, 0x2919 _ 0)
+NAMED_CHARACTER_REFERENCE(1280, /* l a */ 't' _ 'e' _ ';', 3, 0, 0x2aad _ 0)
+NAMED_CHARACTER_REFERENCE(1281, /* l a */ 't' _ 'e' _ 's' _ ';', 4, 0, 0x2aad _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(1282, /* l b */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x290c _ 0)
+NAMED_CHARACTER_REFERENCE(1283, /* l b */ 'b' _ 'r' _ 'k' _ ';', 4, 0, 0x2772 _ 0)
+NAMED_CHARACTER_REFERENCE(1284, /* l b */ 'r' _ 'a' _ 'c' _ 'e' _ ';', 5, 0, 0x007b _ 0)
+NAMED_CHARACTER_REFERENCE(1285, /* l b */ 'r' _ 'a' _ 'c' _ 'k' _ ';', 5, 0, 0x005b _ 0)
+NAMED_CHARACTER_REFERENCE(1286, /* l b */ 'r' _ 'k' _ 'e' _ ';', 4, 0, 0x298b _ 0)
+NAMED_CHARACTER_REFERENCE(1287, /* l b */ 'r' _ 'k' _ 's' _ 'l' _ 'd' _ ';', 6, 0, 0x298f _ 0)
+NAMED_CHARACTER_REFERENCE(1288, /* l b */ 'r' _ 'k' _ 's' _ 'l' _ 'u' _ ';', 6, 0, 0x298d _ 0)
+NAMED_CHARACTER_REFERENCE(1289, /* l c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x013e _ 0)
+NAMED_CHARACTER_REFERENCE(1290, /* l c */ 'e' _ 'd' _ 'i' _ 'l' _ ';', 5, 0, 0x013c _ 0)
+NAMED_CHARACTER_REFERENCE(1291, /* l c */ 'e' _ 'i' _ 'l' _ ';', 4, 0, 0x2308 _ 0)
+NAMED_CHARACTER_REFERENCE(1292, /* l c */ 'u' _ 'b' _ ';', 3, 0, 0x007b _ 0)
+NAMED_CHARACTER_REFERENCE(1293, /* l c */ 'y' _ ';', 2, 0, 0x043b _ 0)
+NAMED_CHARACTER_REFERENCE(1294, /* l d */ 'c' _ 'a' _ ';', 3, 0, 0x2936 _ 0)
+NAMED_CHARACTER_REFERENCE(1295, /* l d */ 'q' _ 'u' _ 'o' _ ';', 4, 0, 0x201c _ 0)
+NAMED_CHARACTER_REFERENCE(1296, /* l d */ 'q' _ 'u' _ 'o' _ 'r' _ ';', 5, 0, 0x201e _ 0)
+NAMED_CHARACTER_REFERENCE(1297, /* l d */ 'r' _ 'd' _ 'h' _ 'a' _ 'r' _ ';', 6, 0, 0x2967 _ 0)
+NAMED_CHARACTER_REFERENCE(1298, /* l d */ 'r' _ 'u' _ 's' _ 'h' _ 'a' _ 'r' _ ';', 7, 0, 0x294b _ 0)
+NAMED_CHARACTER_REFERENCE(1299, /* l d */ 's' _ 'h' _ ';', 3, 0, 0x21b2 _ 0)
+NAMED_CHARACTER_REFERENCE(1300, /* l e */ ';', 1, 0, 0x2264 _ 0)
+NAMED_CHARACTER_REFERENCE(1301, /* l e */ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 8, 0, 0x2190 _ 0)
+NAMED_CHARACTER_REFERENCE(1302, /* l e */ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 't' _ 'a' _ 'i' _ 'l' _ ';', 12, 0, 0x21a2 _ 0)
+NAMED_CHARACTER_REFERENCE(1303, /* l e */ 'f' _ 't' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'd' _ 'o' _ 'w' _ 'n' _ ';', 14, 0, 0x21bd _ 0)
+NAMED_CHARACTER_REFERENCE(1304, /* l e */ 'f' _ 't' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'u' _ 'p' _ ';', 12, 0, 0x21bc _ 0)
+NAMED_CHARACTER_REFERENCE(1305, /* l e */ 'f' _ 't' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 's' _ ';', 13, 0, 0x21c7 _ 0)
+NAMED_CHARACTER_REFERENCE(1306, /* l e */ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 13, 0, 0x2194 _ 0)
+NAMED_CHARACTER_REFERENCE(1307, /* l e */ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 's' _ ';', 14, 0, 0x21c6 _ 0)
+NAMED_CHARACTER_REFERENCE(1308, /* l e */ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 's' _ ';', 16, 0, 0x21cb _ 0)
+NAMED_CHARACTER_REFERENCE(1309, /* l e */ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 's' _ 'q' _ 'u' _ 'i' _ 'g' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 18, 0, 0x21ad _ 0)
+NAMED_CHARACTER_REFERENCE(1310, /* l e */ 'f' _ 't' _ 't' _ 'h' _ 'r' _ 'e' _ 'e' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 13, 0, 0x22cb _ 0)
+NAMED_CHARACTER_REFERENCE(1311, /* l e */ 'g' _ ';', 2, 0, 0x22da _ 0)
+NAMED_CHARACTER_REFERENCE(1312, /* l e */ 'q' _ ';', 2, 0, 0x2264 _ 0)
+NAMED_CHARACTER_REFERENCE(1313, /* l e */ 'q' _ 'q' _ ';', 3, 0, 0x2266 _ 0)
+NAMED_CHARACTER_REFERENCE(1314, /* l e */ 'q' _ 's' _ 'l' _ 'a' _ 'n' _ 't' _ ';', 7, 0, 0x2a7d _ 0)
+NAMED_CHARACTER_REFERENCE(1315, /* l e */ 's' _ ';', 2, 0, 0x2a7d _ 0)
+NAMED_CHARACTER_REFERENCE(1316, /* l e */ 's' _ 'c' _ 'c' _ ';', 4, 0, 0x2aa8 _ 0)
+NAMED_CHARACTER_REFERENCE(1317, /* l e */ 's' _ 'd' _ 'o' _ 't' _ ';', 5, 0, 0x2a7f _ 0)
+NAMED_CHARACTER_REFERENCE(1318, /* l e */ 's' _ 'd' _ 'o' _ 't' _ 'o' _ ';', 6, 0, 0x2a81 _ 0)
+NAMED_CHARACTER_REFERENCE(1319, /* l e */ 's' _ 'd' _ 'o' _ 't' _ 'o' _ 'r' _ ';', 7, 0, 0x2a83 _ 0)
+NAMED_CHARACTER_REFERENCE(1320, /* l e */ 's' _ 'g' _ ';', 3, 0, 0x22da _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(1321, /* l e */ 's' _ 'g' _ 'e' _ 's' _ ';', 5, 0, 0x2a93 _ 0)
+NAMED_CHARACTER_REFERENCE(1322, /* l e */ 's' _ 's' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 9, 0, 0x2a85 _ 0)
+NAMED_CHARACTER_REFERENCE(1323, /* l e */ 's' _ 's' _ 'd' _ 'o' _ 't' _ ';', 6, 0, 0x22d6 _ 0)
+NAMED_CHARACTER_REFERENCE(1324, /* l e */ 's' _ 's' _ 'e' _ 'q' _ 'g' _ 't' _ 'r' _ ';', 8, 0, 0x22da _ 0)
+NAMED_CHARACTER_REFERENCE(1325, /* l e */ 's' _ 's' _ 'e' _ 'q' _ 'q' _ 'g' _ 't' _ 'r' _ ';', 9, 0, 0x2a8b _ 0)
+NAMED_CHARACTER_REFERENCE(1326, /* l e */ 's' _ 's' _ 'g' _ 't' _ 'r' _ ';', 6, 0, 0x2276 _ 0)
+NAMED_CHARACTER_REFERENCE(1327, /* l e */ 's' _ 's' _ 's' _ 'i' _ 'm' _ ';', 6, 0, 0x2272 _ 0)
+NAMED_CHARACTER_REFERENCE(1328, /* l f */ 'i' _ 's' _ 'h' _ 't' _ ';', 5, 0, 0x297c _ 0)
+NAMED_CHARACTER_REFERENCE(1329, /* l f */ 'l' _ 'o' _ 'o' _ 'r' _ ';', 5, 0, 0x230a _ 0)
+NAMED_CHARACTER_REFERENCE(1330, /* l f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd29)
+NAMED_CHARACTER_REFERENCE(1331, /* l g */ ';', 1, 0, 0x2276 _ 0)
+NAMED_CHARACTER_REFERENCE(1332, /* l g */ 'E' _ ';', 2, 0, 0x2a91 _ 0)
+NAMED_CHARACTER_REFERENCE(1333, /* l h */ 'a' _ 'r' _ 'd' _ ';', 4, 0, 0x21bd _ 0)
+NAMED_CHARACTER_REFERENCE(1334, /* l h */ 'a' _ 'r' _ 'u' _ ';', 4, 0, 0x21bc _ 0)
+NAMED_CHARACTER_REFERENCE(1335, /* l h */ 'a' _ 'r' _ 'u' _ 'l' _ ';', 5, 0, 0x296a _ 0)
+NAMED_CHARACTER_REFERENCE(1336, /* l h */ 'b' _ 'l' _ 'k' _ ';', 4, 0, 0x2584 _ 0)
+NAMED_CHARACTER_REFERENCE(1337, /* l j */ 'c' _ 'y' _ ';', 3, 0, 0x0459 _ 0)
+NAMED_CHARACTER_REFERENCE(1338, /* l l */ ';', 1, 0, 0x226a _ 0)
+NAMED_CHARACTER_REFERENCE(1339, /* l l */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21c7 _ 0)
+NAMED_CHARACTER_REFERENCE(1340, /* l l */ 'c' _ 'o' _ 'r' _ 'n' _ 'e' _ 'r' _ ';', 7, 0, 0x231e _ 0)
+NAMED_CHARACTER_REFERENCE(1341, /* l l */ 'h' _ 'a' _ 'r' _ 'd' _ ';', 5, 0, 0x296b _ 0)
+NAMED_CHARACTER_REFERENCE(1342, /* l l */ 't' _ 'r' _ 'i' _ ';', 4, 0, 0x25fa _ 0)
+NAMED_CHARACTER_REFERENCE(1343, /* l m */ 'i' _ 'd' _ 'o' _ 't' _ ';', 5, 0, 0x0140 _ 0)
+NAMED_CHARACTER_REFERENCE(1344, /* l m */ 'o' _ 'u' _ 's' _ 't' _ ';', 5, 0, 0x23b0 _ 0)
+NAMED_CHARACTER_REFERENCE(1345, /* l m */ 'o' _ 'u' _ 's' _ 't' _ 'a' _ 'c' _ 'h' _ 'e' _ ';', 9, 0, 0x23b0 _ 0)
+NAMED_CHARACTER_REFERENCE(1346, /* l n */ 'E' _ ';', 2, 0, 0x2268 _ 0)
+NAMED_CHARACTER_REFERENCE(1347, /* l n */ 'a' _ 'p' _ ';', 3, 0, 0x2a89 _ 0)
+NAMED_CHARACTER_REFERENCE(1348, /* l n */ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 7, 0, 0x2a89 _ 0)
+NAMED_CHARACTER_REFERENCE(1349, /* l n */ 'e' _ ';', 2, 0, 0x2a87 _ 0)
+NAMED_CHARACTER_REFERENCE(1350, /* l n */ 'e' _ 'q' _ ';', 3, 0, 0x2a87 _ 0)
+NAMED_CHARACTER_REFERENCE(1351, /* l n */ 'e' _ 'q' _ 'q' _ ';', 4, 0, 0x2268 _ 0)
+NAMED_CHARACTER_REFERENCE(1352, /* l n */ 's' _ 'i' _ 'm' _ ';', 4, 0, 0x22e6 _ 0)
+NAMED_CHARACTER_REFERENCE(1353, /* l o */ 'a' _ 'n' _ 'g' _ ';', 4, 0, 0x27ec _ 0)
+NAMED_CHARACTER_REFERENCE(1354, /* l o */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21fd _ 0)
+NAMED_CHARACTER_REFERENCE(1355, /* l o */ 'b' _ 'r' _ 'k' _ ';', 4, 0, 0x27e6 _ 0)
+NAMED_CHARACTER_REFERENCE(1356, /* l o */ 'n' _ 'g' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 12, 0, 0x27f5 _ 0)
+NAMED_CHARACTER_REFERENCE(1357, /* l o */ 'n' _ 'g' _ 'l' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 17, 0, 0x27f7 _ 0)
+NAMED_CHARACTER_REFERENCE(1358, /* l o */ 'n' _ 'g' _ 'm' _ 'a' _ 'p' _ 's' _ 't' _ 'o' _ ';', 9, 0, 0x27fc _ 0)
+NAMED_CHARACTER_REFERENCE(1359, /* l o */ 'n' _ 'g' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 13, 0, 0x27f6 _ 0)
+NAMED_CHARACTER_REFERENCE(1360, /* l o */ 'o' _ 'p' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 12, 0, 0x21ab _ 0)
+NAMED_CHARACTER_REFERENCE(1361, /* l o */ 'o' _ 'p' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 13, 0, 0x21ac _ 0)
+NAMED_CHARACTER_REFERENCE(1362, /* l o */ 'p' _ 'a' _ 'r' _ ';', 4, 0, 0x2985 _ 0)
+NAMED_CHARACTER_REFERENCE(1363, /* l o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd5d)
+NAMED_CHARACTER_REFERENCE(1364, /* l o */ 'p' _ 'l' _ 'u' _ 's' _ ';', 5, 0, 0x2a2d _ 0)
+NAMED_CHARACTER_REFERENCE(1365, /* l o */ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 6, 0, 0x2a34 _ 0)
+NAMED_CHARACTER_REFERENCE(1366, /* l o */ 'w' _ 'a' _ 's' _ 't' _ ';', 5, 0, 0x2217 _ 0)
+NAMED_CHARACTER_REFERENCE(1367, /* l o */ 'w' _ 'b' _ 'a' _ 'r' _ ';', 5, 0, 0x005f _ 0)
+NAMED_CHARACTER_REFERENCE(1368, /* l o */ 'z' _ ';', 2, 0, 0x25ca _ 0)
+NAMED_CHARACTER_REFERENCE(1369, /* l o */ 'z' _ 'e' _ 'n' _ 'g' _ 'e' _ ';', 6, 0, 0x25ca _ 0)
+NAMED_CHARACTER_REFERENCE(1370, /* l o */ 'z' _ 'f' _ ';', 3, 0, 0x29eb _ 0)
+NAMED_CHARACTER_REFERENCE(1371, /* l p */ 'a' _ 'r' _ ';', 3, 0, 0x0028 _ 0)
+NAMED_CHARACTER_REFERENCE(1372, /* l p */ 'a' _ 'r' _ 'l' _ 't' _ ';', 5, 0, 0x2993 _ 0)
+NAMED_CHARACTER_REFERENCE(1373, /* l r */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21c6 _ 0)
+NAMED_CHARACTER_REFERENCE(1374, /* l r */ 'c' _ 'o' _ 'r' _ 'n' _ 'e' _ 'r' _ ';', 7, 0, 0x231f _ 0)
+NAMED_CHARACTER_REFERENCE(1375, /* l r */ 'h' _ 'a' _ 'r' _ ';', 4, 0, 0x21cb _ 0)
+NAMED_CHARACTER_REFERENCE(1376, /* l r */ 'h' _ 'a' _ 'r' _ 'd' _ ';', 5, 0, 0x296d _ 0)
+NAMED_CHARACTER_REFERENCE(1377, /* l r */ 'm' _ ';', 2, 0, 0x200e _ 0)
+NAMED_CHARACTER_REFERENCE(1378, /* l r */ 't' _ 'r' _ 'i' _ ';', 4, 0, 0x22bf _ 0)
+NAMED_CHARACTER_REFERENCE(1379, /* l s */ 'a' _ 'q' _ 'u' _ 'o' _ ';', 5, 0, 0x2039 _ 0)
+NAMED_CHARACTER_REFERENCE(1380, /* l s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcc1)
+NAMED_CHARACTER_REFERENCE(1381, /* l s */ 'h' _ ';', 2, 0, 0x21b0 _ 0)
+NAMED_CHARACTER_REFERENCE(1382, /* l s */ 'i' _ 'm' _ ';', 3, 0, 0x2272 _ 0)
+NAMED_CHARACTER_REFERENCE(1383, /* l s */ 'i' _ 'm' _ 'e' _ ';', 4, 0, 0x2a8d _ 0)
+NAMED_CHARACTER_REFERENCE(1384, /* l s */ 'i' _ 'm' _ 'g' _ ';', 4, 0, 0x2a8f _ 0)
+NAMED_CHARACTER_REFERENCE(1385, /* l s */ 'q' _ 'b' _ ';', 3, 0, 0x005b _ 0)
+NAMED_CHARACTER_REFERENCE(1386, /* l s */ 'q' _ 'u' _ 'o' _ ';', 4, 0, 0x2018 _ 0)
+NAMED_CHARACTER_REFERENCE(1387, /* l s */ 'q' _ 'u' _ 'o' _ 'r' _ ';', 5, 0, 0x201a _ 0)
+NAMED_CHARACTER_REFERENCE(1388, /* l s */ 't' _ 'r' _ 'o' _ 'k' _ ';', 5, 0, 0x0142 _ 0)
+NAMED_CHARACTER_REFERENCE(1389, /* l t */ 0, 0, 1, 0x003c _ 0)
+NAMED_CHARACTER_REFERENCE(1390, /* l t */ ';', 1, 0, 0x003c _ 0)
+NAMED_CHARACTER_REFERENCE(1391, /* l t */ 'c' _ 'c' _ ';', 3, 0, 0x2aa6 _ 0)
+NAMED_CHARACTER_REFERENCE(1392, /* l t */ 'c' _ 'i' _ 'r' _ ';', 4, 0, 0x2a79 _ 0)
+NAMED_CHARACTER_REFERENCE(1393, /* l t */ 'd' _ 'o' _ 't' _ ';', 4, 0, 0x22d6 _ 0)
+NAMED_CHARACTER_REFERENCE(1394, /* l t */ 'h' _ 'r' _ 'e' _ 'e' _ ';', 5, 0, 0x22cb _ 0)
+NAMED_CHARACTER_REFERENCE(1395, /* l t */ 'i' _ 'm' _ 'e' _ 's' _ ';', 5, 0, 0x22c9 _ 0)
+NAMED_CHARACTER_REFERENCE(1396, /* l t */ 'l' _ 'a' _ 'r' _ 'r' _ ';', 5, 0, 0x2976 _ 0)
+NAMED_CHARACTER_REFERENCE(1397, /* l t */ 'q' _ 'u' _ 'e' _ 's' _ 't' _ ';', 6, 0, 0x2a7b _ 0)
+NAMED_CHARACTER_REFERENCE(1398, /* l t */ 'r' _ 'P' _ 'a' _ 'r' _ ';', 5, 0, 0x2996 _ 0)
+NAMED_CHARACTER_REFERENCE(1399, /* l t */ 'r' _ 'i' _ ';', 3, 0, 0x25c3 _ 0)
+NAMED_CHARACTER_REFERENCE(1400, /* l t */ 'r' _ 'i' _ 'e' _ ';', 4, 0, 0x22b4 _ 0)
+NAMED_CHARACTER_REFERENCE(1401, /* l t */ 'r' _ 'i' _ 'f' _ ';', 4, 0, 0x25c2 _ 0)
+NAMED_CHARACTER_REFERENCE(1402, /* l u */ 'r' _ 'd' _ 's' _ 'h' _ 'a' _ 'r' _ ';', 7, 0, 0x294a _ 0)
+NAMED_CHARACTER_REFERENCE(1403, /* l u */ 'r' _ 'u' _ 'h' _ 'a' _ 'r' _ ';', 6, 0, 0x2966 _ 0)
+NAMED_CHARACTER_REFERENCE(1404, /* l v */ 'e' _ 'r' _ 't' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 8, 0, 0x2268 _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(1405, /* l v */ 'n' _ 'E' _ ';', 3, 0, 0x2268 _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(1406, /* m D */ 'D' _ 'o' _ 't' _ ';', 4, 0, 0x223a _ 0)
+NAMED_CHARACTER_REFERENCE(1407, /* m a */ 'c' _ 'r', 2, 0, 0x00af _ 0)
+NAMED_CHARACTER_REFERENCE(1408, /* m a */ 'c' _ 'r' _ ';', 3, 0, 0x00af _ 0)
+NAMED_CHARACTER_REFERENCE(1409, /* m a */ 'l' _ 'e' _ ';', 3, 0, 0x2642 _ 0)
+NAMED_CHARACTER_REFERENCE(1410, /* m a */ 'l' _ 't' _ ';', 3, 0, 0x2720 _ 0)
+NAMED_CHARACTER_REFERENCE(1411, /* m a */ 'l' _ 't' _ 'e' _ 's' _ 'e' _ ';', 6, 0, 0x2720 _ 0)
+NAMED_CHARACTER_REFERENCE(1412, /* m a */ 'p' _ ';', 2, 0, 0x21a6 _ 0)
+NAMED_CHARACTER_REFERENCE(1413, /* m a */ 'p' _ 's' _ 't' _ 'o' _ ';', 5, 0, 0x21a6 _ 0)
+NAMED_CHARACTER_REFERENCE(1414, /* m a */ 'p' _ 's' _ 't' _ 'o' _ 'd' _ 'o' _ 'w' _ 'n' _ ';', 9, 0, 0x21a7 _ 0)
+NAMED_CHARACTER_REFERENCE(1415, /* m a */ 'p' _ 's' _ 't' _ 'o' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 9, 0, 0x21a4 _ 0)
+NAMED_CHARACTER_REFERENCE(1416, /* m a */ 'p' _ 's' _ 't' _ 'o' _ 'u' _ 'p' _ ';', 7, 0, 0x21a5 _ 0)
+NAMED_CHARACTER_REFERENCE(1417, /* m a */ 'r' _ 'k' _ 'e' _ 'r' _ ';', 5, 0, 0x25ae _ 0)
+NAMED_CHARACTER_REFERENCE(1418, /* m c */ 'o' _ 'm' _ 'm' _ 'a' _ ';', 5, 0, 0x2a29 _ 0)
+NAMED_CHARACTER_REFERENCE(1419, /* m c */ 'y' _ ';', 2, 0, 0x043c _ 0)
+NAMED_CHARACTER_REFERENCE(1420, /* m d */ 'a' _ 's' _ 'h' _ ';', 4, 0, 0x2014 _ 0)
+NAMED_CHARACTER_REFERENCE(1421, /* m e */ 'a' _ 's' _ 'u' _ 'r' _ 'e' _ 'd' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 12, 0, 0x2221 _ 0)
+NAMED_CHARACTER_REFERENCE(1422, /* m f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd2a)
+NAMED_CHARACTER_REFERENCE(1423, /* m h */ 'o' _ ';', 2, 0, 0x2127 _ 0)
+NAMED_CHARACTER_REFERENCE(1424, /* m i */ 'c' _ 'r' _ 'o', 3, 0, 0x00b5 _ 0)
+NAMED_CHARACTER_REFERENCE(1425, /* m i */ 'c' _ 'r' _ 'o' _ ';', 4, 0, 0x00b5 _ 0)
+NAMED_CHARACTER_REFERENCE(1426, /* m i */ 'd' _ ';', 2, 0, 0x2223 _ 0)
+NAMED_CHARACTER_REFERENCE(1427, /* m i */ 'd' _ 'a' _ 's' _ 't' _ ';', 5, 0, 0x002a _ 0)
+NAMED_CHARACTER_REFERENCE(1428, /* m i */ 'd' _ 'c' _ 'i' _ 'r' _ ';', 5, 0, 0x2af0 _ 0)
+NAMED_CHARACTER_REFERENCE(1429, /* m i */ 'd' _ 'd' _ 'o' _ 't', 4, 0, 0x00b7 _ 0)
+NAMED_CHARACTER_REFERENCE(1430, /* m i */ 'd' _ 'd' _ 'o' _ 't' _ ';', 5, 0, 0x00b7 _ 0)
+NAMED_CHARACTER_REFERENCE(1431, /* m i */ 'n' _ 'u' _ 's' _ ';', 4, 0, 0x2212 _ 0)
+NAMED_CHARACTER_REFERENCE(1432, /* m i */ 'n' _ 'u' _ 's' _ 'b' _ ';', 5, 0, 0x229f _ 0)
+NAMED_CHARACTER_REFERENCE(1433, /* m i */ 'n' _ 'u' _ 's' _ 'd' _ ';', 5, 0, 0x2238 _ 0)
+NAMED_CHARACTER_REFERENCE(1434, /* m i */ 'n' _ 'u' _ 's' _ 'd' _ 'u' _ ';', 6, 0, 0x2a2a _ 0)
+NAMED_CHARACTER_REFERENCE(1435, /* m l */ 'c' _ 'p' _ ';', 3, 0, 0x2adb _ 0)
+NAMED_CHARACTER_REFERENCE(1436, /* m l */ 'd' _ 'r' _ ';', 3, 0, 0x2026 _ 0)
+NAMED_CHARACTER_REFERENCE(1437, /* m n */ 'p' _ 'l' _ 'u' _ 's' _ ';', 5, 0, 0x2213 _ 0)
+NAMED_CHARACTER_REFERENCE(1438, /* m o */ 'd' _ 'e' _ 'l' _ 's' _ ';', 5, 0, 0x22a7 _ 0)
+NAMED_CHARACTER_REFERENCE(1439, /* m o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd5e)
+NAMED_CHARACTER_REFERENCE(1440, /* m p */ ';', 1, 0, 0x2213 _ 0)
+NAMED_CHARACTER_REFERENCE(1441, /* m s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcc2)
+NAMED_CHARACTER_REFERENCE(1442, /* m s */ 't' _ 'p' _ 'o' _ 's' _ ';', 5, 0, 0x223e _ 0)
+NAMED_CHARACTER_REFERENCE(1443, /* m u */ ';', 1, 0, 0x03bc _ 0)
+NAMED_CHARACTER_REFERENCE(1444, /* m u */ 'l' _ 't' _ 'i' _ 'm' _ 'a' _ 'p' _ ';', 7, 0, 0x22b8 _ 0)
+NAMED_CHARACTER_REFERENCE(1445, /* m u */ 'm' _ 'a' _ 'p' _ ';', 4, 0, 0x22b8 _ 0)
+NAMED_CHARACTER_REFERENCE(1446, /* n G */ 'g' _ ';', 2, 0, 0x22d9 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1447, /* n G */ 't' _ ';', 2, 0, 0x226b _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(1448, /* n G */ 't' _ 'v' _ ';', 3, 0, 0x226b _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1449, /* n L */ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 9, 0, 0x21cd _ 0)
+NAMED_CHARACTER_REFERENCE(1450, /* n L */ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 14, 0, 0x21ce _ 0)
+NAMED_CHARACTER_REFERENCE(1451, /* n L */ 'l' _ ';', 2, 0, 0x22d8 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1452, /* n L */ 't' _ ';', 2, 0, 0x226a _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(1453, /* n L */ 't' _ 'v' _ ';', 3, 0, 0x226a _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1454, /* n R */ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 10, 0, 0x21cf _ 0)
+NAMED_CHARACTER_REFERENCE(1455, /* n V */ 'D' _ 'a' _ 's' _ 'h' _ ';', 5, 0, 0x22af _ 0)
+NAMED_CHARACTER_REFERENCE(1456, /* n V */ 'd' _ 'a' _ 's' _ 'h' _ ';', 5, 0, 0x22ae _ 0)
+NAMED_CHARACTER_REFERENCE(1457, /* n a */ 'b' _ 'l' _ 'a' _ ';', 4, 0, 0x2207 _ 0)
+NAMED_CHARACTER_REFERENCE(1458, /* n a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x0144 _ 0)
+NAMED_CHARACTER_REFERENCE(1459, /* n a */ 'n' _ 'g' _ ';', 3, 0, 0x2220 _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(1460, /* n a */ 'p' _ ';', 2, 0, 0x2249 _ 0)
+NAMED_CHARACTER_REFERENCE(1461, /* n a */ 'p' _ 'E' _ ';', 3, 0, 0x2a70 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1462, /* n a */ 'p' _ 'i' _ 'd' _ ';', 4, 0, 0x224b _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1463, /* n a */ 'p' _ 'o' _ 's' _ ';', 4, 0, 0x0149 _ 0)
+NAMED_CHARACTER_REFERENCE(1464, /* n a */ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 6, 0, 0x2249 _ 0)
+NAMED_CHARACTER_REFERENCE(1465, /* n a */ 't' _ 'u' _ 'r' _ ';', 4, 0, 0x266e _ 0)
+NAMED_CHARACTER_REFERENCE(1466, /* n a */ 't' _ 'u' _ 'r' _ 'a' _ 'l' _ ';', 6, 0, 0x266e _ 0)
+NAMED_CHARACTER_REFERENCE(1467, /* n a */ 't' _ 'u' _ 'r' _ 'a' _ 'l' _ 's' _ ';', 7, 0, 0x2115 _ 0)
+NAMED_CHARACTER_REFERENCE(1468, /* n b */ 's' _ 'p', 2, 0, 0x00a0 _ 0)
+NAMED_CHARACTER_REFERENCE(1469, /* n b */ 's' _ 'p' _ ';', 3, 0, 0x00a0 _ 0)
+NAMED_CHARACTER_REFERENCE(1470, /* n b */ 'u' _ 'm' _ 'p' _ ';', 4, 0, 0x224e _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1471, /* n b */ 'u' _ 'm' _ 'p' _ 'e' _ ';', 5, 0, 0x224f _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1472, /* n c */ 'a' _ 'p' _ ';', 3, 0, 0x2a43 _ 0)
+NAMED_CHARACTER_REFERENCE(1473, /* n c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x0148 _ 0)
+NAMED_CHARACTER_REFERENCE(1474, /* n c */ 'e' _ 'd' _ 'i' _ 'l' _ ';', 5, 0, 0x0146 _ 0)
+NAMED_CHARACTER_REFERENCE(1475, /* n c */ 'o' _ 'n' _ 'g' _ ';', 4, 0, 0x2247 _ 0)
+NAMED_CHARACTER_REFERENCE(1476, /* n c */ 'o' _ 'n' _ 'g' _ 'd' _ 'o' _ 't' _ ';', 7, 0, 0x2a6d _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1477, /* n c */ 'u' _ 'p' _ ';', 3, 0, 0x2a42 _ 0)
+NAMED_CHARACTER_REFERENCE(1478, /* n c */ 'y' _ ';', 2, 0, 0x043d _ 0)
+NAMED_CHARACTER_REFERENCE(1479, /* n d */ 'a' _ 's' _ 'h' _ ';', 4, 0, 0x2013 _ 0)
+NAMED_CHARACTER_REFERENCE(1480, /* n e */ ';', 1, 0, 0x2260 _ 0)
+NAMED_CHARACTER_REFERENCE(1481, /* n e */ 'A' _ 'r' _ 'r' _ ';', 4, 0, 0x21d7 _ 0)
+NAMED_CHARACTER_REFERENCE(1482, /* n e */ 'a' _ 'r' _ 'h' _ 'k' _ ';', 5, 0, 0x2924 _ 0)
+NAMED_CHARACTER_REFERENCE(1483, /* n e */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x2197 _ 0)
+NAMED_CHARACTER_REFERENCE(1484, /* n e */ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 6, 0, 0x2197 _ 0)
+NAMED_CHARACTER_REFERENCE(1485, /* n e */ 'd' _ 'o' _ 't' _ ';', 4, 0, 0x2250 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1486, /* n e */ 'q' _ 'u' _ 'i' _ 'v' _ ';', 5, 0, 0x2262 _ 0)
+NAMED_CHARACTER_REFERENCE(1487, /* n e */ 's' _ 'e' _ 'a' _ 'r' _ ';', 5, 0, 0x2928 _ 0)
+NAMED_CHARACTER_REFERENCE(1488, /* n e */ 's' _ 'i' _ 'm' _ ';', 4, 0, 0x2242 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1489, /* n e */ 'x' _ 'i' _ 's' _ 't' _ ';', 5, 0, 0x2204 _ 0)
+NAMED_CHARACTER_REFERENCE(1490, /* n e */ 'x' _ 'i' _ 's' _ 't' _ 's' _ ';', 6, 0, 0x2204 _ 0)
+NAMED_CHARACTER_REFERENCE(1491, /* n f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd2b)
+NAMED_CHARACTER_REFERENCE(1492, /* n g */ 'E' _ ';', 2, 0, 0x2267 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1493, /* n g */ 'e' _ ';', 2, 0, 0x2271 _ 0)
+NAMED_CHARACTER_REFERENCE(1494, /* n g */ 'e' _ 'q' _ ';', 3, 0, 0x2271 _ 0)
+NAMED_CHARACTER_REFERENCE(1495, /* n g */ 'e' _ 'q' _ 'q' _ ';', 4, 0, 0x2267 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1496, /* n g */ 'e' _ 'q' _ 's' _ 'l' _ 'a' _ 'n' _ 't' _ ';', 8, 0, 0x2a7e _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1497, /* n g */ 'e' _ 's' _ ';', 3, 0, 0x2a7e _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1498, /* n g */ 's' _ 'i' _ 'm' _ ';', 4, 0, 0x2275 _ 0)
+NAMED_CHARACTER_REFERENCE(1499, /* n g */ 't' _ ';', 2, 0, 0x226f _ 0)
+NAMED_CHARACTER_REFERENCE(1500, /* n g */ 't' _ 'r' _ ';', 3, 0, 0x226f _ 0)
+NAMED_CHARACTER_REFERENCE(1501, /* n h */ 'A' _ 'r' _ 'r' _ ';', 4, 0, 0x21ce _ 0)
+NAMED_CHARACTER_REFERENCE(1502, /* n h */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21ae _ 0)
+NAMED_CHARACTER_REFERENCE(1503, /* n h */ 'p' _ 'a' _ 'r' _ ';', 4, 0, 0x2af2 _ 0)
+NAMED_CHARACTER_REFERENCE(1504, /* n i */ ';', 1, 0, 0x220b _ 0)
+NAMED_CHARACTER_REFERENCE(1505, /* n i */ 's' _ ';', 2, 0, 0x22fc _ 0)
+NAMED_CHARACTER_REFERENCE(1506, /* n i */ 's' _ 'd' _ ';', 3, 0, 0x22fa _ 0)
+NAMED_CHARACTER_REFERENCE(1507, /* n i */ 'v' _ ';', 2, 0, 0x220b _ 0)
+NAMED_CHARACTER_REFERENCE(1508, /* n j */ 'c' _ 'y' _ ';', 3, 0, 0x045a _ 0)
+NAMED_CHARACTER_REFERENCE(1509, /* n l */ 'A' _ 'r' _ 'r' _ ';', 4, 0, 0x21cd _ 0)
+NAMED_CHARACTER_REFERENCE(1510, /* n l */ 'E' _ ';', 2, 0, 0x2266 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1511, /* n l */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x219a _ 0)
+NAMED_CHARACTER_REFERENCE(1512, /* n l */ 'd' _ 'r' _ ';', 3, 0, 0x2025 _ 0)
+NAMED_CHARACTER_REFERENCE(1513, /* n l */ 'e' _ ';', 2, 0, 0x2270 _ 0)
+NAMED_CHARACTER_REFERENCE(1514, /* n l */ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 9, 0, 0x219a _ 0)
+NAMED_CHARACTER_REFERENCE(1515, /* n l */ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 14, 0, 0x21ae _ 0)
+NAMED_CHARACTER_REFERENCE(1516, /* n l */ 'e' _ 'q' _ ';', 3, 0, 0x2270 _ 0)
+NAMED_CHARACTER_REFERENCE(1517, /* n l */ 'e' _ 'q' _ 'q' _ ';', 4, 0, 0x2266 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1518, /* n l */ 'e' _ 'q' _ 's' _ 'l' _ 'a' _ 'n' _ 't' _ ';', 8, 0, 0x2a7d _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1519, /* n l */ 'e' _ 's' _ ';', 3, 0, 0x2a7d _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1520, /* n l */ 'e' _ 's' _ 's' _ ';', 4, 0, 0x226e _ 0)
+NAMED_CHARACTER_REFERENCE(1521, /* n l */ 's' _ 'i' _ 'm' _ ';', 4, 0, 0x2274 _ 0)
+NAMED_CHARACTER_REFERENCE(1522, /* n l */ 't' _ ';', 2, 0, 0x226e _ 0)
+NAMED_CHARACTER_REFERENCE(1523, /* n l */ 't' _ 'r' _ 'i' _ ';', 4, 0, 0x22ea _ 0)
+NAMED_CHARACTER_REFERENCE(1524, /* n l */ 't' _ 'r' _ 'i' _ 'e' _ ';', 5, 0, 0x22ec _ 0)
+NAMED_CHARACTER_REFERENCE(1525, /* n m */ 'i' _ 'd' _ ';', 3, 0, 0x2224 _ 0)
+NAMED_CHARACTER_REFERENCE(1526, /* n o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd5f)
+NAMED_CHARACTER_REFERENCE(1527, /* n o */ 't', 1, 0, 0x00ac _ 0)
+NAMED_CHARACTER_REFERENCE(1528, /* n o */ 't' _ ';', 2, 0, 0x00ac _ 0)
+NAMED_CHARACTER_REFERENCE(1529, /* n o */ 't' _ 'i' _ 'n' _ ';', 4, 0, 0x2209 _ 0)
+NAMED_CHARACTER_REFERENCE(1530, /* n o */ 't' _ 'i' _ 'n' _ 'E' _ ';', 5, 0, 0x22f9 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1531, /* n o */ 't' _ 'i' _ 'n' _ 'd' _ 'o' _ 't' _ ';', 7, 0, 0x22f5 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1532, /* n o */ 't' _ 'i' _ 'n' _ 'v' _ 'a' _ ';', 6, 0, 0x2209 _ 0)
+NAMED_CHARACTER_REFERENCE(1533, /* n o */ 't' _ 'i' _ 'n' _ 'v' _ 'b' _ ';', 6, 0, 0x22f7 _ 0)
+NAMED_CHARACTER_REFERENCE(1534, /* n o */ 't' _ 'i' _ 'n' _ 'v' _ 'c' _ ';', 6, 0, 0x22f6 _ 0)
+NAMED_CHARACTER_REFERENCE(1535, /* n o */ 't' _ 'n' _ 'i' _ ';', 4, 0, 0x220c _ 0)
+NAMED_CHARACTER_REFERENCE(1536, /* n o */ 't' _ 'n' _ 'i' _ 'v' _ 'a' _ ';', 6, 0, 0x220c _ 0)
+NAMED_CHARACTER_REFERENCE(1537, /* n o */ 't' _ 'n' _ 'i' _ 'v' _ 'b' _ ';', 6, 0, 0x22fe _ 0)
+NAMED_CHARACTER_REFERENCE(1538, /* n o */ 't' _ 'n' _ 'i' _ 'v' _ 'c' _ ';', 6, 0, 0x22fd _ 0)
+NAMED_CHARACTER_REFERENCE(1539, /* n p */ 'a' _ 'r' _ ';', 3, 0, 0x2226 _ 0)
+NAMED_CHARACTER_REFERENCE(1540, /* n p */ 'a' _ 'r' _ 'a' _ 'l' _ 'l' _ 'e' _ 'l' _ ';', 8, 0, 0x2226 _ 0)
+NAMED_CHARACTER_REFERENCE(1541, /* n p */ 'a' _ 'r' _ 's' _ 'l' _ ';', 5, 0, 0x2afd _ 0x20e5)
+NAMED_CHARACTER_REFERENCE(1542, /* n p */ 'a' _ 'r' _ 't' _ ';', 4, 0, 0x2202 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1543, /* n p */ 'o' _ 'l' _ 'i' _ 'n' _ 't' _ ';', 6, 0, 0x2a14 _ 0)
+NAMED_CHARACTER_REFERENCE(1544, /* n p */ 'r' _ ';', 2, 0, 0x2280 _ 0)
+NAMED_CHARACTER_REFERENCE(1545, /* n p */ 'r' _ 'c' _ 'u' _ 'e' _ ';', 5, 0, 0x22e0 _ 0)
+NAMED_CHARACTER_REFERENCE(1546, /* n p */ 'r' _ 'e' _ ';', 3, 0, 0x2aaf _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1547, /* n p */ 'r' _ 'e' _ 'c' _ ';', 4, 0, 0x2280 _ 0)
+NAMED_CHARACTER_REFERENCE(1548, /* n p */ 'r' _ 'e' _ 'c' _ 'e' _ 'q' _ ';', 6, 0, 0x2aaf _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1549, /* n r */ 'A' _ 'r' _ 'r' _ ';', 4, 0, 0x21cf _ 0)
+NAMED_CHARACTER_REFERENCE(1550, /* n r */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x219b _ 0)
+NAMED_CHARACTER_REFERENCE(1551, /* n r */ 'a' _ 'r' _ 'r' _ 'c' _ ';', 5, 0, 0x2933 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1552, /* n r */ 'a' _ 'r' _ 'r' _ 'w' _ ';', 5, 0, 0x219d _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1553, /* n r */ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 10, 0, 0x219b _ 0)
+NAMED_CHARACTER_REFERENCE(1554, /* n r */ 't' _ 'r' _ 'i' _ ';', 4, 0, 0x22eb _ 0)
+NAMED_CHARACTER_REFERENCE(1555, /* n r */ 't' _ 'r' _ 'i' _ 'e' _ ';', 5, 0, 0x22ed _ 0)
+NAMED_CHARACTER_REFERENCE(1556, /* n s */ 'c' _ ';', 2, 0, 0x2281 _ 0)
+NAMED_CHARACTER_REFERENCE(1557, /* n s */ 'c' _ 'c' _ 'u' _ 'e' _ ';', 5, 0, 0x22e1 _ 0)
+NAMED_CHARACTER_REFERENCE(1558, /* n s */ 'c' _ 'e' _ ';', 3, 0, 0x2ab0 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1559, /* n s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcc3)
+NAMED_CHARACTER_REFERENCE(1560, /* n s */ 'h' _ 'o' _ 'r' _ 't' _ 'm' _ 'i' _ 'd' _ ';', 8, 0, 0x2224 _ 0)
+NAMED_CHARACTER_REFERENCE(1561, /* n s */ 'h' _ 'o' _ 'r' _ 't' _ 'p' _ 'a' _ 'r' _ 'a' _ 'l' _ 'l' _ 'e' _ 'l' _ ';', 13, 0, 0x2226 _ 0)
+NAMED_CHARACTER_REFERENCE(1562, /* n s */ 'i' _ 'm' _ ';', 3, 0, 0x2241 _ 0)
+NAMED_CHARACTER_REFERENCE(1563, /* n s */ 'i' _ 'm' _ 'e' _ ';', 4, 0, 0x2244 _ 0)
+NAMED_CHARACTER_REFERENCE(1564, /* n s */ 'i' _ 'm' _ 'e' _ 'q' _ ';', 5, 0, 0x2244 _ 0)
+NAMED_CHARACTER_REFERENCE(1565, /* n s */ 'm' _ 'i' _ 'd' _ ';', 4, 0, 0x2224 _ 0)
+NAMED_CHARACTER_REFERENCE(1566, /* n s */ 'p' _ 'a' _ 'r' _ ';', 4, 0, 0x2226 _ 0)
+NAMED_CHARACTER_REFERENCE(1567, /* n s */ 'q' _ 's' _ 'u' _ 'b' _ 'e' _ ';', 6, 0, 0x22e2 _ 0)
+NAMED_CHARACTER_REFERENCE(1568, /* n s */ 'q' _ 's' _ 'u' _ 'p' _ 'e' _ ';', 6, 0, 0x22e3 _ 0)
+NAMED_CHARACTER_REFERENCE(1569, /* n s */ 'u' _ 'b' _ ';', 3, 0, 0x2284 _ 0)
+NAMED_CHARACTER_REFERENCE(1570, /* n s */ 'u' _ 'b' _ 'E' _ ';', 4, 0, 0x2ac5 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1571, /* n s */ 'u' _ 'b' _ 'e' _ ';', 4, 0, 0x2288 _ 0)
+NAMED_CHARACTER_REFERENCE(1572, /* n s */ 'u' _ 'b' _ 's' _ 'e' _ 't' _ ';', 6, 0, 0x2282 _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(1573, /* n s */ 'u' _ 'b' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ ';', 8, 0, 0x2288 _ 0)
+NAMED_CHARACTER_REFERENCE(1574, /* n s */ 'u' _ 'b' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ 'q' _ ';', 9, 0, 0x2ac5 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1575, /* n s */ 'u' _ 'c' _ 'c' _ ';', 4, 0, 0x2281 _ 0)
+NAMED_CHARACTER_REFERENCE(1576, /* n s */ 'u' _ 'c' _ 'c' _ 'e' _ 'q' _ ';', 6, 0, 0x2ab0 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1577, /* n s */ 'u' _ 'p' _ ';', 3, 0, 0x2285 _ 0)
+NAMED_CHARACTER_REFERENCE(1578, /* n s */ 'u' _ 'p' _ 'E' _ ';', 4, 0, 0x2ac6 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1579, /* n s */ 'u' _ 'p' _ 'e' _ ';', 4, 0, 0x2289 _ 0)
+NAMED_CHARACTER_REFERENCE(1580, /* n s */ 'u' _ 'p' _ 's' _ 'e' _ 't' _ ';', 6, 0, 0x2283 _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(1581, /* n s */ 'u' _ 'p' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ ';', 8, 0, 0x2289 _ 0)
+NAMED_CHARACTER_REFERENCE(1582, /* n s */ 'u' _ 'p' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ 'q' _ ';', 9, 0, 0x2ac6 _ 0x0338)
+NAMED_CHARACTER_REFERENCE(1583, /* n t */ 'g' _ 'l' _ ';', 3, 0, 0x2279 _ 0)
+NAMED_CHARACTER_REFERENCE(1584, /* n t */ 'i' _ 'l' _ 'd' _ 'e', 4, 0, 0x00f1 _ 0)
+NAMED_CHARACTER_REFERENCE(1585, /* n t */ 'i' _ 'l' _ 'd' _ 'e' _ ';', 5, 0, 0x00f1 _ 0)
+NAMED_CHARACTER_REFERENCE(1586, /* n t */ 'l' _ 'g' _ ';', 3, 0, 0x2278 _ 0)
+NAMED_CHARACTER_REFERENCE(1587, /* n t */ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 12, 0, 0x22ea _ 0)
+NAMED_CHARACTER_REFERENCE(1588, /* n t */ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ 'e' _ 'q' _ ';', 14, 0, 0x22ec _ 0)
+NAMED_CHARACTER_REFERENCE(1589, /* n t */ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 13, 0, 0x22eb _ 0)
+NAMED_CHARACTER_REFERENCE(1590, /* n t */ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'e' _ 'q' _ ';', 15, 0, 0x22ed _ 0)
+NAMED_CHARACTER_REFERENCE(1591, /* n u */ ';', 1, 0, 0x03bd _ 0)
+NAMED_CHARACTER_REFERENCE(1592, /* n u */ 'm' _ ';', 2, 0, 0x0023 _ 0)
+NAMED_CHARACTER_REFERENCE(1593, /* n u */ 'm' _ 'e' _ 'r' _ 'o' _ ';', 5, 0, 0x2116 _ 0)
+NAMED_CHARACTER_REFERENCE(1594, /* n u */ 'm' _ 's' _ 'p' _ ';', 4, 0, 0x2007 _ 0)
+NAMED_CHARACTER_REFERENCE(1595, /* n v */ 'D' _ 'a' _ 's' _ 'h' _ ';', 5, 0, 0x22ad _ 0)
+NAMED_CHARACTER_REFERENCE(1596, /* n v */ 'H' _ 'a' _ 'r' _ 'r' _ ';', 5, 0, 0x2904 _ 0)
+NAMED_CHARACTER_REFERENCE(1597, /* n v */ 'a' _ 'p' _ ';', 3, 0, 0x224d _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(1598, /* n v */ 'd' _ 'a' _ 's' _ 'h' _ ';', 5, 0, 0x22ac _ 0)
+NAMED_CHARACTER_REFERENCE(1599, /* n v */ 'g' _ 'e' _ ';', 3, 0, 0x2265 _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(1600, /* n v */ 'g' _ 't' _ ';', 3, 0, 0x003e _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(1601, /* n v */ 'i' _ 'n' _ 'f' _ 'i' _ 'n' _ ';', 6, 0, 0x29de _ 0)
+NAMED_CHARACTER_REFERENCE(1602, /* n v */ 'l' _ 'A' _ 'r' _ 'r' _ ';', 5, 0, 0x2902 _ 0)
+NAMED_CHARACTER_REFERENCE(1603, /* n v */ 'l' _ 'e' _ ';', 3, 0, 0x2264 _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(1604, /* n v */ 'l' _ 't' _ ';', 3, 0, 0x003c _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(1605, /* n v */ 'l' _ 't' _ 'r' _ 'i' _ 'e' _ ';', 6, 0, 0x22b4 _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(1606, /* n v */ 'r' _ 'A' _ 'r' _ 'r' _ ';', 5, 0, 0x2903 _ 0)
+NAMED_CHARACTER_REFERENCE(1607, /* n v */ 'r' _ 't' _ 'r' _ 'i' _ 'e' _ ';', 6, 0, 0x22b5 _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(1608, /* n v */ 's' _ 'i' _ 'm' _ ';', 4, 0, 0x223c _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(1609, /* n w */ 'A' _ 'r' _ 'r' _ ';', 4, 0, 0x21d6 _ 0)
+NAMED_CHARACTER_REFERENCE(1610, /* n w */ 'a' _ 'r' _ 'h' _ 'k' _ ';', 5, 0, 0x2923 _ 0)
+NAMED_CHARACTER_REFERENCE(1611, /* n w */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x2196 _ 0)
+NAMED_CHARACTER_REFERENCE(1612, /* n w */ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 6, 0, 0x2196 _ 0)
+NAMED_CHARACTER_REFERENCE(1613, /* n w */ 'n' _ 'e' _ 'a' _ 'r' _ ';', 5, 0, 0x2927 _ 0)
+NAMED_CHARACTER_REFERENCE(1614, /* o S */ ';', 1, 0, 0x24c8 _ 0)
+NAMED_CHARACTER_REFERENCE(1615, /* o a */ 'c' _ 'u' _ 't' _ 'e', 4, 0, 0x00f3 _ 0)
+NAMED_CHARACTER_REFERENCE(1616, /* o a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x00f3 _ 0)
+NAMED_CHARACTER_REFERENCE(1617, /* o a */ 's' _ 't' _ ';', 3, 0, 0x229b _ 0)
+NAMED_CHARACTER_REFERENCE(1618, /* o c */ 'i' _ 'r' _ ';', 3, 0, 0x229a _ 0)
+NAMED_CHARACTER_REFERENCE(1619, /* o c */ 'i' _ 'r' _ 'c', 3, 0, 0x00f4 _ 0)
+NAMED_CHARACTER_REFERENCE(1620, /* o c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x00f4 _ 0)
+NAMED_CHARACTER_REFERENCE(1621, /* o c */ 'y' _ ';', 2, 0, 0x043e _ 0)
+NAMED_CHARACTER_REFERENCE(1622, /* o d */ 'a' _ 's' _ 'h' _ ';', 4, 0, 0x229d _ 0)
+NAMED_CHARACTER_REFERENCE(1623, /* o d */ 'b' _ 'l' _ 'a' _ 'c' _ ';', 5, 0, 0x0151 _ 0)
+NAMED_CHARACTER_REFERENCE(1624, /* o d */ 'i' _ 'v' _ ';', 3, 0, 0x2a38 _ 0)
+NAMED_CHARACTER_REFERENCE(1625, /* o d */ 'o' _ 't' _ ';', 3, 0, 0x2299 _ 0)
+NAMED_CHARACTER_REFERENCE(1626, /* o d */ 's' _ 'o' _ 'l' _ 'd' _ ';', 5, 0, 0x29bc _ 0)
+NAMED_CHARACTER_REFERENCE(1627, /* o e */ 'l' _ 'i' _ 'g' _ ';', 4, 0, 0x0153 _ 0)
+NAMED_CHARACTER_REFERENCE(1628, /* o f */ 'c' _ 'i' _ 'r' _ ';', 4, 0, 0x29bf _ 0)
+NAMED_CHARACTER_REFERENCE(1629, /* o f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd2c)
+NAMED_CHARACTER_REFERENCE(1630, /* o g */ 'o' _ 'n' _ ';', 3, 0, 0x02db _ 0)
+NAMED_CHARACTER_REFERENCE(1631, /* o g */ 'r' _ 'a' _ 'v' _ 'e', 4, 0, 0x00f2 _ 0)
+NAMED_CHARACTER_REFERENCE(1632, /* o g */ 'r' _ 'a' _ 'v' _ 'e' _ ';', 5, 0, 0x00f2 _ 0)
+NAMED_CHARACTER_REFERENCE(1633, /* o g */ 't' _ ';', 2, 0, 0x29c1 _ 0)
+NAMED_CHARACTER_REFERENCE(1634, /* o h */ 'b' _ 'a' _ 'r' _ ';', 4, 0, 0x29b5 _ 0)
+NAMED_CHARACTER_REFERENCE(1635, /* o h */ 'm' _ ';', 2, 0, 0x03a9 _ 0)
+NAMED_CHARACTER_REFERENCE(1636, /* o i */ 'n' _ 't' _ ';', 3, 0, 0x222e _ 0)
+NAMED_CHARACTER_REFERENCE(1637, /* o l */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21ba _ 0)
+NAMED_CHARACTER_REFERENCE(1638, /* o l */ 'c' _ 'i' _ 'r' _ ';', 4, 0, 0x29be _ 0)
+NAMED_CHARACTER_REFERENCE(1639, /* o l */ 'c' _ 'r' _ 'o' _ 's' _ 's' _ ';', 6, 0, 0x29bb _ 0)
+NAMED_CHARACTER_REFERENCE(1640, /* o l */ 'i' _ 'n' _ 'e' _ ';', 4, 0, 0x203e _ 0)
+NAMED_CHARACTER_REFERENCE(1641, /* o l */ 't' _ ';', 2, 0, 0x29c0 _ 0)
+NAMED_CHARACTER_REFERENCE(1642, /* o m */ 'a' _ 'c' _ 'r' _ ';', 4, 0, 0x014d _ 0)
+NAMED_CHARACTER_REFERENCE(1643, /* o m */ 'e' _ 'g' _ 'a' _ ';', 4, 0, 0x03c9 _ 0)
+NAMED_CHARACTER_REFERENCE(1644, /* o m */ 'i' _ 'c' _ 'r' _ 'o' _ 'n' _ ';', 6, 0, 0x03bf _ 0)
+NAMED_CHARACTER_REFERENCE(1645, /* o m */ 'i' _ 'd' _ ';', 3, 0, 0x29b6 _ 0)
+NAMED_CHARACTER_REFERENCE(1646, /* o m */ 'i' _ 'n' _ 'u' _ 's' _ ';', 5, 0, 0x2296 _ 0)
+NAMED_CHARACTER_REFERENCE(1647, /* o o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd60)
+NAMED_CHARACTER_REFERENCE(1648, /* o p */ 'a' _ 'r' _ ';', 3, 0, 0x29b7 _ 0)
+NAMED_CHARACTER_REFERENCE(1649, /* o p */ 'e' _ 'r' _ 'p' _ ';', 4, 0, 0x29b9 _ 0)
+NAMED_CHARACTER_REFERENCE(1650, /* o p */ 'l' _ 'u' _ 's' _ ';', 4, 0, 0x2295 _ 0)
+NAMED_CHARACTER_REFERENCE(1651, /* o r */ ';', 1, 0, 0x2228 _ 0)
+NAMED_CHARACTER_REFERENCE(1652, /* o r */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21bb _ 0)
+NAMED_CHARACTER_REFERENCE(1653, /* o r */ 'd' _ ';', 2, 0, 0x2a5d _ 0)
+NAMED_CHARACTER_REFERENCE(1654, /* o r */ 'd' _ 'e' _ 'r' _ ';', 4, 0, 0x2134 _ 0)
+NAMED_CHARACTER_REFERENCE(1655, /* o r */ 'd' _ 'e' _ 'r' _ 'o' _ 'f' _ ';', 6, 0, 0x2134 _ 0)
+NAMED_CHARACTER_REFERENCE(1656, /* o r */ 'd' _ 'f', 2, 0, 0x00aa _ 0)
+NAMED_CHARACTER_REFERENCE(1657, /* o r */ 'd' _ 'f' _ ';', 3, 0, 0x00aa _ 0)
+NAMED_CHARACTER_REFERENCE(1658, /* o r */ 'd' _ 'm', 2, 0, 0x00ba _ 0)
+NAMED_CHARACTER_REFERENCE(1659, /* o r */ 'd' _ 'm' _ ';', 3, 0, 0x00ba _ 0)
+NAMED_CHARACTER_REFERENCE(1660, /* o r */ 'i' _ 'g' _ 'o' _ 'f' _ ';', 5, 0, 0x22b6 _ 0)
+NAMED_CHARACTER_REFERENCE(1661, /* o r */ 'o' _ 'r' _ ';', 3, 0, 0x2a56 _ 0)
+NAMED_CHARACTER_REFERENCE(1662, /* o r */ 's' _ 'l' _ 'o' _ 'p' _ 'e' _ ';', 6, 0, 0x2a57 _ 0)
+NAMED_CHARACTER_REFERENCE(1663, /* o r */ 'v' _ ';', 2, 0, 0x2a5b _ 0)
+NAMED_CHARACTER_REFERENCE(1664, /* o s */ 'c' _ 'r' _ ';', 3, 0, 0x2134 _ 0)
+NAMED_CHARACTER_REFERENCE(1665, /* o s */ 'l' _ 'a' _ 's' _ 'h', 4, 0, 0x00f8 _ 0)
+NAMED_CHARACTER_REFERENCE(1666, /* o s */ 'l' _ 'a' _ 's' _ 'h' _ ';', 5, 0, 0x00f8 _ 0)
+NAMED_CHARACTER_REFERENCE(1667, /* o s */ 'o' _ 'l' _ ';', 3, 0, 0x2298 _ 0)
+NAMED_CHARACTER_REFERENCE(1668, /* o t */ 'i' _ 'l' _ 'd' _ 'e', 4, 0, 0x00f5 _ 0)
+NAMED_CHARACTER_REFERENCE(1669, /* o t */ 'i' _ 'l' _ 'd' _ 'e' _ ';', 5, 0, 0x00f5 _ 0)
+NAMED_CHARACTER_REFERENCE(1670, /* o t */ 'i' _ 'm' _ 'e' _ 's' _ ';', 5, 0, 0x2297 _ 0)
+NAMED_CHARACTER_REFERENCE(1671, /* o t */ 'i' _ 'm' _ 'e' _ 's' _ 'a' _ 's' _ ';', 7, 0, 0x2a36 _ 0)
+NAMED_CHARACTER_REFERENCE(1672, /* o u */ 'm' _ 'l', 2, 0, 0x00f6 _ 0)
+NAMED_CHARACTER_REFERENCE(1673, /* o u */ 'm' _ 'l' _ ';', 3, 0, 0x00f6 _ 0)
+NAMED_CHARACTER_REFERENCE(1674, /* o v */ 'b' _ 'a' _ 'r' _ ';', 4, 0, 0x233d _ 0)
+NAMED_CHARACTER_REFERENCE(1675, /* p a */ 'r' _ ';', 2, 0, 0x2225 _ 0)
+NAMED_CHARACTER_REFERENCE(1676, /* p a */ 'r' _ 'a', 2, 0, 0x00b6 _ 0)
+NAMED_CHARACTER_REFERENCE(1677, /* p a */ 'r' _ 'a' _ ';', 3, 0, 0x00b6 _ 0)
+NAMED_CHARACTER_REFERENCE(1678, /* p a */ 'r' _ 'a' _ 'l' _ 'l' _ 'e' _ 'l' _ ';', 7, 0, 0x2225 _ 0)
+NAMED_CHARACTER_REFERENCE(1679, /* p a */ 'r' _ 's' _ 'i' _ 'm' _ ';', 5, 0, 0x2af3 _ 0)
+NAMED_CHARACTER_REFERENCE(1680, /* p a */ 'r' _ 's' _ 'l' _ ';', 4, 0, 0x2afd _ 0)
+NAMED_CHARACTER_REFERENCE(1681, /* p a */ 'r' _ 't' _ ';', 3, 0, 0x2202 _ 0)
+NAMED_CHARACTER_REFERENCE(1682, /* p c */ 'y' _ ';', 2, 0, 0x043f _ 0)
+NAMED_CHARACTER_REFERENCE(1683, /* p e */ 'r' _ 'c' _ 'n' _ 't' _ ';', 5, 0, 0x0025 _ 0)
+NAMED_CHARACTER_REFERENCE(1684, /* p e */ 'r' _ 'i' _ 'o' _ 'd' _ ';', 5, 0, 0x002e _ 0)
+NAMED_CHARACTER_REFERENCE(1685, /* p e */ 'r' _ 'm' _ 'i' _ 'l' _ ';', 5, 0, 0x2030 _ 0)
+NAMED_CHARACTER_REFERENCE(1686, /* p e */ 'r' _ 'p' _ ';', 3, 0, 0x22a5 _ 0)
+NAMED_CHARACTER_REFERENCE(1687, /* p e */ 'r' _ 't' _ 'e' _ 'n' _ 'k' _ ';', 6, 0, 0x2031 _ 0)
+NAMED_CHARACTER_REFERENCE(1688, /* p f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd2d)
+NAMED_CHARACTER_REFERENCE(1689, /* p h */ 'i' _ ';', 2, 0, 0x03c6 _ 0)
+NAMED_CHARACTER_REFERENCE(1690, /* p h */ 'i' _ 'v' _ ';', 3, 0, 0x03d5 _ 0)
+NAMED_CHARACTER_REFERENCE(1691, /* p h */ 'm' _ 'm' _ 'a' _ 't' _ ';', 5, 0, 0x2133 _ 0)
+NAMED_CHARACTER_REFERENCE(1692, /* p h */ 'o' _ 'n' _ 'e' _ ';', 4, 0, 0x260e _ 0)
+NAMED_CHARACTER_REFERENCE(1693, /* p i */ ';', 1, 0, 0x03c0 _ 0)
+NAMED_CHARACTER_REFERENCE(1694, /* p i */ 't' _ 'c' _ 'h' _ 'f' _ 'o' _ 'r' _ 'k' _ ';', 8, 0, 0x22d4 _ 0)
+NAMED_CHARACTER_REFERENCE(1695, /* p i */ 'v' _ ';', 2, 0, 0x03d6 _ 0)
+NAMED_CHARACTER_REFERENCE(1696, /* p l */ 'a' _ 'n' _ 'c' _ 'k' _ ';', 5, 0, 0x210f _ 0)
+NAMED_CHARACTER_REFERENCE(1697, /* p l */ 'a' _ 'n' _ 'c' _ 'k' _ 'h' _ ';', 6, 0, 0x210e _ 0)
+NAMED_CHARACTER_REFERENCE(1698, /* p l */ 'a' _ 'n' _ 'k' _ 'v' _ ';', 5, 0, 0x210f _ 0)
+NAMED_CHARACTER_REFERENCE(1699, /* p l */ 'u' _ 's' _ ';', 3, 0, 0x002b _ 0)
+NAMED_CHARACTER_REFERENCE(1700, /* p l */ 'u' _ 's' _ 'a' _ 'c' _ 'i' _ 'r' _ ';', 7, 0, 0x2a23 _ 0)
+NAMED_CHARACTER_REFERENCE(1701, /* p l */ 'u' _ 's' _ 'b' _ ';', 4, 0, 0x229e _ 0)
+NAMED_CHARACTER_REFERENCE(1702, /* p l */ 'u' _ 's' _ 'c' _ 'i' _ 'r' _ ';', 6, 0, 0x2a22 _ 0)
+NAMED_CHARACTER_REFERENCE(1703, /* p l */ 'u' _ 's' _ 'd' _ 'o' _ ';', 5, 0, 0x2214 _ 0)
+NAMED_CHARACTER_REFERENCE(1704, /* p l */ 'u' _ 's' _ 'd' _ 'u' _ ';', 5, 0, 0x2a25 _ 0)
+NAMED_CHARACTER_REFERENCE(1705, /* p l */ 'u' _ 's' _ 'e' _ ';', 4, 0, 0x2a72 _ 0)
+NAMED_CHARACTER_REFERENCE(1706, /* p l */ 'u' _ 's' _ 'm' _ 'n', 4, 0, 0x00b1 _ 0)
+NAMED_CHARACTER_REFERENCE(1707, /* p l */ 'u' _ 's' _ 'm' _ 'n' _ ';', 5, 0, 0x00b1 _ 0)
+NAMED_CHARACTER_REFERENCE(1708, /* p l */ 'u' _ 's' _ 's' _ 'i' _ 'm' _ ';', 6, 0, 0x2a26 _ 0)
+NAMED_CHARACTER_REFERENCE(1709, /* p l */ 'u' _ 's' _ 't' _ 'w' _ 'o' _ ';', 6, 0, 0x2a27 _ 0)
+NAMED_CHARACTER_REFERENCE(1710, /* p m */ ';', 1, 0, 0x00b1 _ 0)
+NAMED_CHARACTER_REFERENCE(1711, /* p o */ 'i' _ 'n' _ 't' _ 'i' _ 'n' _ 't' _ ';', 7, 0, 0x2a15 _ 0)
+NAMED_CHARACTER_REFERENCE(1712, /* p o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd61)
+NAMED_CHARACTER_REFERENCE(1713, /* p o */ 'u' _ 'n' _ 'd', 3, 0, 0x00a3 _ 0)
+NAMED_CHARACTER_REFERENCE(1714, /* p o */ 'u' _ 'n' _ 'd' _ ';', 4, 0, 0x00a3 _ 0)
+NAMED_CHARACTER_REFERENCE(1715, /* p r */ ';', 1, 0, 0x227a _ 0)
+NAMED_CHARACTER_REFERENCE(1716, /* p r */ 'E' _ ';', 2, 0, 0x2ab3 _ 0)
+NAMED_CHARACTER_REFERENCE(1717, /* p r */ 'a' _ 'p' _ ';', 3, 0, 0x2ab7 _ 0)
+NAMED_CHARACTER_REFERENCE(1718, /* p r */ 'c' _ 'u' _ 'e' _ ';', 4, 0, 0x227c _ 0)
+NAMED_CHARACTER_REFERENCE(1719, /* p r */ 'e' _ ';', 2, 0, 0x2aaf _ 0)
+NAMED_CHARACTER_REFERENCE(1720, /* p r */ 'e' _ 'c' _ ';', 3, 0, 0x227a _ 0)
+NAMED_CHARACTER_REFERENCE(1721, /* p r */ 'e' _ 'c' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 9, 0, 0x2ab7 _ 0)
+NAMED_CHARACTER_REFERENCE(1722, /* p r */ 'e' _ 'c' _ 'c' _ 'u' _ 'r' _ 'l' _ 'y' _ 'e' _ 'q' _ ';', 10, 0, 0x227c _ 0)
+NAMED_CHARACTER_REFERENCE(1723, /* p r */ 'e' _ 'c' _ 'e' _ 'q' _ ';', 5, 0, 0x2aaf _ 0)
+NAMED_CHARACTER_REFERENCE(1724, /* p r */ 'e' _ 'c' _ 'n' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 10, 0, 0x2ab9 _ 0)
+NAMED_CHARACTER_REFERENCE(1725, /* p r */ 'e' _ 'c' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 7, 0, 0x2ab5 _ 0)
+NAMED_CHARACTER_REFERENCE(1726, /* p r */ 'e' _ 'c' _ 'n' _ 's' _ 'i' _ 'm' _ ';', 7, 0, 0x22e8 _ 0)
+NAMED_CHARACTER_REFERENCE(1727, /* p r */ 'e' _ 'c' _ 's' _ 'i' _ 'm' _ ';', 6, 0, 0x227e _ 0)
+NAMED_CHARACTER_REFERENCE(1728, /* p r */ 'i' _ 'm' _ 'e' _ ';', 4, 0, 0x2032 _ 0)
+NAMED_CHARACTER_REFERENCE(1729, /* p r */ 'i' _ 'm' _ 'e' _ 's' _ ';', 5, 0, 0x2119 _ 0)
+NAMED_CHARACTER_REFERENCE(1730, /* p r */ 'n' _ 'E' _ ';', 3, 0, 0x2ab5 _ 0)
+NAMED_CHARACTER_REFERENCE(1731, /* p r */ 'n' _ 'a' _ 'p' _ ';', 4, 0, 0x2ab9 _ 0)
+NAMED_CHARACTER_REFERENCE(1732, /* p r */ 'n' _ 's' _ 'i' _ 'm' _ ';', 5, 0, 0x22e8 _ 0)
+NAMED_CHARACTER_REFERENCE(1733, /* p r */ 'o' _ 'd' _ ';', 3, 0, 0x220f _ 0)
+NAMED_CHARACTER_REFERENCE(1734, /* p r */ 'o' _ 'f' _ 'a' _ 'l' _ 'a' _ 'r' _ ';', 7, 0, 0x232e _ 0)
+NAMED_CHARACTER_REFERENCE(1735, /* p r */ 'o' _ 'f' _ 'l' _ 'i' _ 'n' _ 'e' _ ';', 7, 0, 0x2312 _ 0)
+NAMED_CHARACTER_REFERENCE(1736, /* p r */ 'o' _ 'f' _ 's' _ 'u' _ 'r' _ 'f' _ ';', 7, 0, 0x2313 _ 0)
+NAMED_CHARACTER_REFERENCE(1737, /* p r */ 'o' _ 'p' _ ';', 3, 0, 0x221d _ 0)
+NAMED_CHARACTER_REFERENCE(1738, /* p r */ 'o' _ 'p' _ 't' _ 'o' _ ';', 5, 0, 0x221d _ 0)
+NAMED_CHARACTER_REFERENCE(1739, /* p r */ 's' _ 'i' _ 'm' _ ';', 4, 0, 0x227e _ 0)
+NAMED_CHARACTER_REFERENCE(1740, /* p r */ 'u' _ 'r' _ 'e' _ 'l' _ ';', 5, 0, 0x22b0 _ 0)
+NAMED_CHARACTER_REFERENCE(1741, /* p s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcc5)
+NAMED_CHARACTER_REFERENCE(1742, /* p s */ 'i' _ ';', 2, 0, 0x03c8 _ 0)
+NAMED_CHARACTER_REFERENCE(1743, /* p u */ 'n' _ 'c' _ 's' _ 'p' _ ';', 5, 0, 0x2008 _ 0)
+NAMED_CHARACTER_REFERENCE(1744, /* q f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd2e)
+NAMED_CHARACTER_REFERENCE(1745, /* q i */ 'n' _ 't' _ ';', 3, 0, 0x2a0c _ 0)
+NAMED_CHARACTER_REFERENCE(1746, /* q o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd62)
+NAMED_CHARACTER_REFERENCE(1747, /* q p */ 'r' _ 'i' _ 'm' _ 'e' _ ';', 5, 0, 0x2057 _ 0)
+NAMED_CHARACTER_REFERENCE(1748, /* q s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcc6)
+NAMED_CHARACTER_REFERENCE(1749, /* q u */ 'a' _ 't' _ 'e' _ 'r' _ 'n' _ 'i' _ 'o' _ 'n' _ 's' _ ';', 10, 0, 0x210d _ 0)
+NAMED_CHARACTER_REFERENCE(1750, /* q u */ 'a' _ 't' _ 'i' _ 'n' _ 't' _ ';', 6, 0, 0x2a16 _ 0)
+NAMED_CHARACTER_REFERENCE(1751, /* q u */ 'e' _ 's' _ 't' _ ';', 4, 0, 0x003f _ 0)
+NAMED_CHARACTER_REFERENCE(1752, /* q u */ 'e' _ 's' _ 't' _ 'e' _ 'q' _ ';', 6, 0, 0x225f _ 0)
+NAMED_CHARACTER_REFERENCE(1753, /* q u */ 'o' _ 't', 2, 0, 0x0022 _ 0)
+NAMED_CHARACTER_REFERENCE(1754, /* q u */ 'o' _ 't' _ ';', 3, 0, 0x0022 _ 0)
+NAMED_CHARACTER_REFERENCE(1755, /* r A */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21db _ 0)
+NAMED_CHARACTER_REFERENCE(1756, /* r A */ 'r' _ 'r' _ ';', 3, 0, 0x21d2 _ 0)
+NAMED_CHARACTER_REFERENCE(1757, /* r A */ 't' _ 'a' _ 'i' _ 'l' _ ';', 5, 0, 0x291c _ 0)
+NAMED_CHARACTER_REFERENCE(1758, /* r B */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x290f _ 0)
+NAMED_CHARACTER_REFERENCE(1759, /* r H */ 'a' _ 'r' _ ';', 3, 0, 0x2964 _ 0)
+NAMED_CHARACTER_REFERENCE(1760, /* r a */ 'c' _ 'e' _ ';', 3, 0, 0x223d _ 0x0331)
+NAMED_CHARACTER_REFERENCE(1761, /* r a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x0155 _ 0)
+NAMED_CHARACTER_REFERENCE(1762, /* r a */ 'd' _ 'i' _ 'c' _ ';', 4, 0, 0x221a _ 0)
+NAMED_CHARACTER_REFERENCE(1763, /* r a */ 'e' _ 'm' _ 'p' _ 't' _ 'y' _ 'v' _ ';', 7, 0, 0x29b3 _ 0)
+NAMED_CHARACTER_REFERENCE(1764, /* r a */ 'n' _ 'g' _ ';', 3, 0, 0x27e9 _ 0)
+NAMED_CHARACTER_REFERENCE(1765, /* r a */ 'n' _ 'g' _ 'd' _ ';', 4, 0, 0x2992 _ 0)
+NAMED_CHARACTER_REFERENCE(1766, /* r a */ 'n' _ 'g' _ 'e' _ ';', 4, 0, 0x29a5 _ 0)
+NAMED_CHARACTER_REFERENCE(1767, /* r a */ 'n' _ 'g' _ 'l' _ 'e' _ ';', 5, 0, 0x27e9 _ 0)
+NAMED_CHARACTER_REFERENCE(1768, /* r a */ 'q' _ 'u' _ 'o', 3, 0, 0x00bb _ 0)
+NAMED_CHARACTER_REFERENCE(1769, /* r a */ 'q' _ 'u' _ 'o' _ ';', 4, 0, 0x00bb _ 0)
+NAMED_CHARACTER_REFERENCE(1770, /* r a */ 'r' _ 'r' _ ';', 3, 0, 0x2192 _ 0)
+NAMED_CHARACTER_REFERENCE(1771, /* r a */ 'r' _ 'r' _ 'a' _ 'p' _ ';', 5, 0, 0x2975 _ 0)
+NAMED_CHARACTER_REFERENCE(1772, /* r a */ 'r' _ 'r' _ 'b' _ ';', 4, 0, 0x21e5 _ 0)
+NAMED_CHARACTER_REFERENCE(1773, /* r a */ 'r' _ 'r' _ 'b' _ 'f' _ 's' _ ';', 6, 0, 0x2920 _ 0)
+NAMED_CHARACTER_REFERENCE(1774, /* r a */ 'r' _ 'r' _ 'c' _ ';', 4, 0, 0x2933 _ 0)
+NAMED_CHARACTER_REFERENCE(1775, /* r a */ 'r' _ 'r' _ 'f' _ 's' _ ';', 5, 0, 0x291e _ 0)
+NAMED_CHARACTER_REFERENCE(1776, /* r a */ 'r' _ 'r' _ 'h' _ 'k' _ ';', 5, 0, 0x21aa _ 0)
+NAMED_CHARACTER_REFERENCE(1777, /* r a */ 'r' _ 'r' _ 'l' _ 'p' _ ';', 5, 0, 0x21ac _ 0)
+NAMED_CHARACTER_REFERENCE(1778, /* r a */ 'r' _ 'r' _ 'p' _ 'l' _ ';', 5, 0, 0x2945 _ 0)
+NAMED_CHARACTER_REFERENCE(1779, /* r a */ 'r' _ 'r' _ 's' _ 'i' _ 'm' _ ';', 6, 0, 0x2974 _ 0)
+NAMED_CHARACTER_REFERENCE(1780, /* r a */ 'r' _ 'r' _ 't' _ 'l' _ ';', 5, 0, 0x21a3 _ 0)
+NAMED_CHARACTER_REFERENCE(1781, /* r a */ 'r' _ 'r' _ 'w' _ ';', 4, 0, 0x219d _ 0)
+NAMED_CHARACTER_REFERENCE(1782, /* r a */ 't' _ 'a' _ 'i' _ 'l' _ ';', 5, 0, 0x291a _ 0)
+NAMED_CHARACTER_REFERENCE(1783, /* r a */ 't' _ 'i' _ 'o' _ ';', 4, 0, 0x2236 _ 0)
+NAMED_CHARACTER_REFERENCE(1784, /* r a */ 't' _ 'i' _ 'o' _ 'n' _ 'a' _ 'l' _ 's' _ ';', 8, 0, 0x211a _ 0)
+NAMED_CHARACTER_REFERENCE(1785, /* r b */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x290d _ 0)
+NAMED_CHARACTER_REFERENCE(1786, /* r b */ 'b' _ 'r' _ 'k' _ ';', 4, 0, 0x2773 _ 0)
+NAMED_CHARACTER_REFERENCE(1787, /* r b */ 'r' _ 'a' _ 'c' _ 'e' _ ';', 5, 0, 0x007d _ 0)
+NAMED_CHARACTER_REFERENCE(1788, /* r b */ 'r' _ 'a' _ 'c' _ 'k' _ ';', 5, 0, 0x005d _ 0)
+NAMED_CHARACTER_REFERENCE(1789, /* r b */ 'r' _ 'k' _ 'e' _ ';', 4, 0, 0x298c _ 0)
+NAMED_CHARACTER_REFERENCE(1790, /* r b */ 'r' _ 'k' _ 's' _ 'l' _ 'd' _ ';', 6, 0, 0x298e _ 0)
+NAMED_CHARACTER_REFERENCE(1791, /* r b */ 'r' _ 'k' _ 's' _ 'l' _ 'u' _ ';', 6, 0, 0x2990 _ 0)
+NAMED_CHARACTER_REFERENCE(1792, /* r c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x0159 _ 0)
+NAMED_CHARACTER_REFERENCE(1793, /* r c */ 'e' _ 'd' _ 'i' _ 'l' _ ';', 5, 0, 0x0157 _ 0)
+NAMED_CHARACTER_REFERENCE(1794, /* r c */ 'e' _ 'i' _ 'l' _ ';', 4, 0, 0x2309 _ 0)
+NAMED_CHARACTER_REFERENCE(1795, /* r c */ 'u' _ 'b' _ ';', 3, 0, 0x007d _ 0)
+NAMED_CHARACTER_REFERENCE(1796, /* r c */ 'y' _ ';', 2, 0, 0x0440 _ 0)
+NAMED_CHARACTER_REFERENCE(1797, /* r d */ 'c' _ 'a' _ ';', 3, 0, 0x2937 _ 0)
+NAMED_CHARACTER_REFERENCE(1798, /* r d */ 'l' _ 'd' _ 'h' _ 'a' _ 'r' _ ';', 6, 0, 0x2969 _ 0)
+NAMED_CHARACTER_REFERENCE(1799, /* r d */ 'q' _ 'u' _ 'o' _ ';', 4, 0, 0x201d _ 0)
+NAMED_CHARACTER_REFERENCE(1800, /* r d */ 'q' _ 'u' _ 'o' _ 'r' _ ';', 5, 0, 0x201d _ 0)
+NAMED_CHARACTER_REFERENCE(1801, /* r d */ 's' _ 'h' _ ';', 3, 0, 0x21b3 _ 0)
+NAMED_CHARACTER_REFERENCE(1802, /* r e */ 'a' _ 'l' _ ';', 3, 0, 0x211c _ 0)
+NAMED_CHARACTER_REFERENCE(1803, /* r e */ 'a' _ 'l' _ 'i' _ 'n' _ 'e' _ ';', 6, 0, 0x211b _ 0)
+NAMED_CHARACTER_REFERENCE(1804, /* r e */ 'a' _ 'l' _ 'p' _ 'a' _ 'r' _ 't' _ ';', 7, 0, 0x211c _ 0)
+NAMED_CHARACTER_REFERENCE(1805, /* r e */ 'a' _ 'l' _ 's' _ ';', 4, 0, 0x211d _ 0)
+NAMED_CHARACTER_REFERENCE(1806, /* r e */ 'c' _ 't' _ ';', 3, 0, 0x25ad _ 0)
+NAMED_CHARACTER_REFERENCE(1807, /* r e */ 'g', 1, 0, 0x00ae _ 0)
+NAMED_CHARACTER_REFERENCE(1808, /* r e */ 'g' _ ';', 2, 0, 0x00ae _ 0)
+NAMED_CHARACTER_REFERENCE(1809, /* r f */ 'i' _ 's' _ 'h' _ 't' _ ';', 5, 0, 0x297d _ 0)
+NAMED_CHARACTER_REFERENCE(1810, /* r f */ 'l' _ 'o' _ 'o' _ 'r' _ ';', 5, 0, 0x230b _ 0)
+NAMED_CHARACTER_REFERENCE(1811, /* r f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd2f)
+NAMED_CHARACTER_REFERENCE(1812, /* r h */ 'a' _ 'r' _ 'd' _ ';', 4, 0, 0x21c1 _ 0)
+NAMED_CHARACTER_REFERENCE(1813, /* r h */ 'a' _ 'r' _ 'u' _ ';', 4, 0, 0x21c0 _ 0)
+NAMED_CHARACTER_REFERENCE(1814, /* r h */ 'a' _ 'r' _ 'u' _ 'l' _ ';', 5, 0, 0x296c _ 0)
+NAMED_CHARACTER_REFERENCE(1815, /* r h */ 'o' _ ';', 2, 0, 0x03c1 _ 0)
+NAMED_CHARACTER_REFERENCE(1816, /* r h */ 'o' _ 'v' _ ';', 3, 0, 0x03f1 _ 0)
+NAMED_CHARACTER_REFERENCE(1817, /* r i */ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 9, 0, 0x2192 _ 0)
+NAMED_CHARACTER_REFERENCE(1818, /* r i */ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 't' _ 'a' _ 'i' _ 'l' _ ';', 13, 0, 0x21a3 _ 0)
+NAMED_CHARACTER_REFERENCE(1819, /* r i */ 'g' _ 'h' _ 't' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'd' _ 'o' _ 'w' _ 'n' _ ';', 15, 0, 0x21c1 _ 0)
+NAMED_CHARACTER_REFERENCE(1820, /* r i */ 'g' _ 'h' _ 't' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'u' _ 'p' _ ';', 13, 0, 0x21c0 _ 0)
+NAMED_CHARACTER_REFERENCE(1821, /* r i */ 'g' _ 'h' _ 't' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 's' _ ';', 14, 0, 0x21c4 _ 0)
+NAMED_CHARACTER_REFERENCE(1822, /* r i */ 'g' _ 'h' _ 't' _ 'l' _ 'e' _ 'f' _ 't' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 's' _ ';', 16, 0, 0x21cc _ 0)
+NAMED_CHARACTER_REFERENCE(1823, /* r i */ 'g' _ 'h' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 's' _ ';', 15, 0, 0x21c9 _ 0)
+NAMED_CHARACTER_REFERENCE(1824, /* r i */ 'g' _ 'h' _ 't' _ 's' _ 'q' _ 'u' _ 'i' _ 'g' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 14, 0, 0x219d _ 0)
+NAMED_CHARACTER_REFERENCE(1825, /* r i */ 'g' _ 'h' _ 't' _ 't' _ 'h' _ 'r' _ 'e' _ 'e' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 14, 0, 0x22cc _ 0)
+NAMED_CHARACTER_REFERENCE(1826, /* r i */ 'n' _ 'g' _ ';', 3, 0, 0x02da _ 0)
+NAMED_CHARACTER_REFERENCE(1827, /* r i */ 's' _ 'i' _ 'n' _ 'g' _ 'd' _ 'o' _ 't' _ 's' _ 'e' _ 'q' _ ';', 11, 0, 0x2253 _ 0)
+NAMED_CHARACTER_REFERENCE(1828, /* r l */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21c4 _ 0)
+NAMED_CHARACTER_REFERENCE(1829, /* r l */ 'h' _ 'a' _ 'r' _ ';', 4, 0, 0x21cc _ 0)
+NAMED_CHARACTER_REFERENCE(1830, /* r l */ 'm' _ ';', 2, 0, 0x200f _ 0)
+NAMED_CHARACTER_REFERENCE(1831, /* r m */ 'o' _ 'u' _ 's' _ 't' _ ';', 5, 0, 0x23b1 _ 0)
+NAMED_CHARACTER_REFERENCE(1832, /* r m */ 'o' _ 'u' _ 's' _ 't' _ 'a' _ 'c' _ 'h' _ 'e' _ ';', 9, 0, 0x23b1 _ 0)
+NAMED_CHARACTER_REFERENCE(1833, /* r n */ 'm' _ 'i' _ 'd' _ ';', 4, 0, 0x2aee _ 0)
+NAMED_CHARACTER_REFERENCE(1834, /* r o */ 'a' _ 'n' _ 'g' _ ';', 4, 0, 0x27ed _ 0)
+NAMED_CHARACTER_REFERENCE(1835, /* r o */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21fe _ 0)
+NAMED_CHARACTER_REFERENCE(1836, /* r o */ 'b' _ 'r' _ 'k' _ ';', 4, 0, 0x27e7 _ 0)
+NAMED_CHARACTER_REFERENCE(1837, /* r o */ 'p' _ 'a' _ 'r' _ ';', 4, 0, 0x2986 _ 0)
+NAMED_CHARACTER_REFERENCE(1838, /* r o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd63)
+NAMED_CHARACTER_REFERENCE(1839, /* r o */ 'p' _ 'l' _ 'u' _ 's' _ ';', 5, 0, 0x2a2e _ 0)
+NAMED_CHARACTER_REFERENCE(1840, /* r o */ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 6, 0, 0x2a35 _ 0)
+NAMED_CHARACTER_REFERENCE(1841, /* r p */ 'a' _ 'r' _ ';', 3, 0, 0x0029 _ 0)
+NAMED_CHARACTER_REFERENCE(1842, /* r p */ 'a' _ 'r' _ 'g' _ 't' _ ';', 5, 0, 0x2994 _ 0)
+NAMED_CHARACTER_REFERENCE(1843, /* r p */ 'p' _ 'o' _ 'l' _ 'i' _ 'n' _ 't' _ ';', 7, 0, 0x2a12 _ 0)
+NAMED_CHARACTER_REFERENCE(1844, /* r r */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21c9 _ 0)
+NAMED_CHARACTER_REFERENCE(1845, /* r s */ 'a' _ 'q' _ 'u' _ 'o' _ ';', 5, 0, 0x203a _ 0)
+NAMED_CHARACTER_REFERENCE(1846, /* r s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcc7)
+NAMED_CHARACTER_REFERENCE(1847, /* r s */ 'h' _ ';', 2, 0, 0x21b1 _ 0)
+NAMED_CHARACTER_REFERENCE(1848, /* r s */ 'q' _ 'b' _ ';', 3, 0, 0x005d _ 0)
+NAMED_CHARACTER_REFERENCE(1849, /* r s */ 'q' _ 'u' _ 'o' _ ';', 4, 0, 0x2019 _ 0)
+NAMED_CHARACTER_REFERENCE(1850, /* r s */ 'q' _ 'u' _ 'o' _ 'r' _ ';', 5, 0, 0x2019 _ 0)
+NAMED_CHARACTER_REFERENCE(1851, /* r t */ 'h' _ 'r' _ 'e' _ 'e' _ ';', 5, 0, 0x22cc _ 0)
+NAMED_CHARACTER_REFERENCE(1852, /* r t */ 'i' _ 'm' _ 'e' _ 's' _ ';', 5, 0, 0x22ca _ 0)
+NAMED_CHARACTER_REFERENCE(1853, /* r t */ 'r' _ 'i' _ ';', 3, 0, 0x25b9 _ 0)
+NAMED_CHARACTER_REFERENCE(1854, /* r t */ 'r' _ 'i' _ 'e' _ ';', 4, 0, 0x22b5 _ 0)
+NAMED_CHARACTER_REFERENCE(1855, /* r t */ 'r' _ 'i' _ 'f' _ ';', 4, 0, 0x25b8 _ 0)
+NAMED_CHARACTER_REFERENCE(1856, /* r t */ 'r' _ 'i' _ 'l' _ 't' _ 'r' _ 'i' _ ';', 7, 0, 0x29ce _ 0)
+NAMED_CHARACTER_REFERENCE(1857, /* r u */ 'l' _ 'u' _ 'h' _ 'a' _ 'r' _ ';', 6, 0, 0x2968 _ 0)
+NAMED_CHARACTER_REFERENCE(1858, /* r x */ ';', 1, 0, 0x211e _ 0)
+NAMED_CHARACTER_REFERENCE(1859, /* s a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x015b _ 0)
+NAMED_CHARACTER_REFERENCE(1860, /* s b */ 'q' _ 'u' _ 'o' _ ';', 4, 0, 0x201a _ 0)
+NAMED_CHARACTER_REFERENCE(1861, /* s c */ ';', 1, 0, 0x227b _ 0)
+NAMED_CHARACTER_REFERENCE(1862, /* s c */ 'E' _ ';', 2, 0, 0x2ab4 _ 0)
+NAMED_CHARACTER_REFERENCE(1863, /* s c */ 'a' _ 'p' _ ';', 3, 0, 0x2ab8 _ 0)
+NAMED_CHARACTER_REFERENCE(1864, /* s c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x0161 _ 0)
+NAMED_CHARACTER_REFERENCE(1865, /* s c */ 'c' _ 'u' _ 'e' _ ';', 4, 0, 0x227d _ 0)
+NAMED_CHARACTER_REFERENCE(1866, /* s c */ 'e' _ ';', 2, 0, 0x2ab0 _ 0)
+NAMED_CHARACTER_REFERENCE(1867, /* s c */ 'e' _ 'd' _ 'i' _ 'l' _ ';', 5, 0, 0x015f _ 0)
+NAMED_CHARACTER_REFERENCE(1868, /* s c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x015d _ 0)
+NAMED_CHARACTER_REFERENCE(1869, /* s c */ 'n' _ 'E' _ ';', 3, 0, 0x2ab6 _ 0)
+NAMED_CHARACTER_REFERENCE(1870, /* s c */ 'n' _ 'a' _ 'p' _ ';', 4, 0, 0x2aba _ 0)
+NAMED_CHARACTER_REFERENCE(1871, /* s c */ 'n' _ 's' _ 'i' _ 'm' _ ';', 5, 0, 0x22e9 _ 0)
+NAMED_CHARACTER_REFERENCE(1872, /* s c */ 'p' _ 'o' _ 'l' _ 'i' _ 'n' _ 't' _ ';', 7, 0, 0x2a13 _ 0)
+NAMED_CHARACTER_REFERENCE(1873, /* s c */ 's' _ 'i' _ 'm' _ ';', 4, 0, 0x227f _ 0)
+NAMED_CHARACTER_REFERENCE(1874, /* s c */ 'y' _ ';', 2, 0, 0x0441 _ 0)
+NAMED_CHARACTER_REFERENCE(1875, /* s d */ 'o' _ 't' _ ';', 3, 0, 0x22c5 _ 0)
+NAMED_CHARACTER_REFERENCE(1876, /* s d */ 'o' _ 't' _ 'b' _ ';', 4, 0, 0x22a1 _ 0)
+NAMED_CHARACTER_REFERENCE(1877, /* s d */ 'o' _ 't' _ 'e' _ ';', 4, 0, 0x2a66 _ 0)
+NAMED_CHARACTER_REFERENCE(1878, /* s e */ 'A' _ 'r' _ 'r' _ ';', 4, 0, 0x21d8 _ 0)
+NAMED_CHARACTER_REFERENCE(1879, /* s e */ 'a' _ 'r' _ 'h' _ 'k' _ ';', 5, 0, 0x2925 _ 0)
+NAMED_CHARACTER_REFERENCE(1880, /* s e */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x2198 _ 0)
+NAMED_CHARACTER_REFERENCE(1881, /* s e */ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 6, 0, 0x2198 _ 0)
+NAMED_CHARACTER_REFERENCE(1882, /* s e */ 'c' _ 't', 2, 0, 0x00a7 _ 0)
+NAMED_CHARACTER_REFERENCE(1883, /* s e */ 'c' _ 't' _ ';', 3, 0, 0x00a7 _ 0)
+NAMED_CHARACTER_REFERENCE(1884, /* s e */ 'm' _ 'i' _ ';', 3, 0, 0x003b _ 0)
+NAMED_CHARACTER_REFERENCE(1885, /* s e */ 's' _ 'w' _ 'a' _ 'r' _ ';', 5, 0, 0x2929 _ 0)
+NAMED_CHARACTER_REFERENCE(1886, /* s e */ 't' _ 'm' _ 'i' _ 'n' _ 'u' _ 's' _ ';', 7, 0, 0x2216 _ 0)
+NAMED_CHARACTER_REFERENCE(1887, /* s e */ 't' _ 'm' _ 'n' _ ';', 4, 0, 0x2216 _ 0)
+NAMED_CHARACTER_REFERENCE(1888, /* s e */ 'x' _ 't' _ ';', 3, 0, 0x2736 _ 0)
+NAMED_CHARACTER_REFERENCE(1889, /* s f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd30)
+NAMED_CHARACTER_REFERENCE(1890, /* s f */ 'r' _ 'o' _ 'w' _ 'n' _ ';', 5, 0, 0x2322 _ 0)
+NAMED_CHARACTER_REFERENCE(1891, /* s h */ 'a' _ 'r' _ 'p' _ ';', 4, 0, 0x266f _ 0)
+NAMED_CHARACTER_REFERENCE(1892, /* s h */ 'c' _ 'h' _ 'c' _ 'y' _ ';', 5, 0, 0x0449 _ 0)
+NAMED_CHARACTER_REFERENCE(1893, /* s h */ 'c' _ 'y' _ ';', 3, 0, 0x0448 _ 0)
+NAMED_CHARACTER_REFERENCE(1894, /* s h */ 'o' _ 'r' _ 't' _ 'm' _ 'i' _ 'd' _ ';', 7, 0, 0x2223 _ 0)
+NAMED_CHARACTER_REFERENCE(1895, /* s h */ 'o' _ 'r' _ 't' _ 'p' _ 'a' _ 'r' _ 'a' _ 'l' _ 'l' _ 'e' _ 'l' _ ';', 12, 0, 0x2225 _ 0)
+NAMED_CHARACTER_REFERENCE(1896, /* s h */ 'y', 1, 0, 0x00ad _ 0)
+NAMED_CHARACTER_REFERENCE(1897, /* s h */ 'y' _ ';', 2, 0, 0x00ad _ 0)
+NAMED_CHARACTER_REFERENCE(1898, /* s i */ 'g' _ 'm' _ 'a' _ ';', 4, 0, 0x03c3 _ 0)
+NAMED_CHARACTER_REFERENCE(1899, /* s i */ 'g' _ 'm' _ 'a' _ 'f' _ ';', 5, 0, 0x03c2 _ 0)
+NAMED_CHARACTER_REFERENCE(1900, /* s i */ 'g' _ 'm' _ 'a' _ 'v' _ ';', 5, 0, 0x03c2 _ 0)
+NAMED_CHARACTER_REFERENCE(1901, /* s i */ 'm' _ ';', 2, 0, 0x223c _ 0)
+NAMED_CHARACTER_REFERENCE(1902, /* s i */ 'm' _ 'd' _ 'o' _ 't' _ ';', 5, 0, 0x2a6a _ 0)
+NAMED_CHARACTER_REFERENCE(1903, /* s i */ 'm' _ 'e' _ ';', 3, 0, 0x2243 _ 0)
+NAMED_CHARACTER_REFERENCE(1904, /* s i */ 'm' _ 'e' _ 'q' _ ';', 4, 0, 0x2243 _ 0)
+NAMED_CHARACTER_REFERENCE(1905, /* s i */ 'm' _ 'g' _ ';', 3, 0, 0x2a9e _ 0)
+NAMED_CHARACTER_REFERENCE(1906, /* s i */ 'm' _ 'g' _ 'E' _ ';', 4, 0, 0x2aa0 _ 0)
+NAMED_CHARACTER_REFERENCE(1907, /* s i */ 'm' _ 'l' _ ';', 3, 0, 0x2a9d _ 0)
+NAMED_CHARACTER_REFERENCE(1908, /* s i */ 'm' _ 'l' _ 'E' _ ';', 4, 0, 0x2a9f _ 0)
+NAMED_CHARACTER_REFERENCE(1909, /* s i */ 'm' _ 'n' _ 'e' _ ';', 4, 0, 0x2246 _ 0)
+NAMED_CHARACTER_REFERENCE(1910, /* s i */ 'm' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 6, 0, 0x2a24 _ 0)
+NAMED_CHARACTER_REFERENCE(1911, /* s i */ 'm' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 6, 0, 0x2972 _ 0)
+NAMED_CHARACTER_REFERENCE(1912, /* s l */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x2190 _ 0)
+NAMED_CHARACTER_REFERENCE(1913, /* s m */ 'a' _ 'l' _ 'l' _ 's' _ 'e' _ 't' _ 'm' _ 'i' _ 'n' _ 'u' _ 's' _ ';', 12, 0, 0x2216 _ 0)
+NAMED_CHARACTER_REFERENCE(1914, /* s m */ 'a' _ 's' _ 'h' _ 'p' _ ';', 5, 0, 0x2a33 _ 0)
+NAMED_CHARACTER_REFERENCE(1915, /* s m */ 'e' _ 'p' _ 'a' _ 'r' _ 's' _ 'l' _ ';', 7, 0, 0x29e4 _ 0)
+NAMED_CHARACTER_REFERENCE(1916, /* s m */ 'i' _ 'd' _ ';', 3, 0, 0x2223 _ 0)
+NAMED_CHARACTER_REFERENCE(1917, /* s m */ 'i' _ 'l' _ 'e' _ ';', 4, 0, 0x2323 _ 0)
+NAMED_CHARACTER_REFERENCE(1918, /* s m */ 't' _ ';', 2, 0, 0x2aaa _ 0)
+NAMED_CHARACTER_REFERENCE(1919, /* s m */ 't' _ 'e' _ ';', 3, 0, 0x2aac _ 0)
+NAMED_CHARACTER_REFERENCE(1920, /* s m */ 't' _ 'e' _ 's' _ ';', 4, 0, 0x2aac _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(1921, /* s o */ 'f' _ 't' _ 'c' _ 'y' _ ';', 5, 0, 0x044c _ 0)
+NAMED_CHARACTER_REFERENCE(1922, /* s o */ 'l' _ ';', 2, 0, 0x002f _ 0)
+NAMED_CHARACTER_REFERENCE(1923, /* s o */ 'l' _ 'b' _ ';', 3, 0, 0x29c4 _ 0)
+NAMED_CHARACTER_REFERENCE(1924, /* s o */ 'l' _ 'b' _ 'a' _ 'r' _ ';', 5, 0, 0x233f _ 0)
+NAMED_CHARACTER_REFERENCE(1925, /* s o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd64)
+NAMED_CHARACTER_REFERENCE(1926, /* s p */ 'a' _ 'd' _ 'e' _ 's' _ ';', 5, 0, 0x2660 _ 0)
+NAMED_CHARACTER_REFERENCE(1927, /* s p */ 'a' _ 'd' _ 'e' _ 's' _ 'u' _ 'i' _ 't' _ ';', 8, 0, 0x2660 _ 0)
+NAMED_CHARACTER_REFERENCE(1928, /* s p */ 'a' _ 'r' _ ';', 3, 0, 0x2225 _ 0)
+NAMED_CHARACTER_REFERENCE(1929, /* s q */ 'c' _ 'a' _ 'p' _ ';', 4, 0, 0x2293 _ 0)
+NAMED_CHARACTER_REFERENCE(1930, /* s q */ 'c' _ 'a' _ 'p' _ 's' _ ';', 5, 0, 0x2293 _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(1931, /* s q */ 'c' _ 'u' _ 'p' _ ';', 4, 0, 0x2294 _ 0)
+NAMED_CHARACTER_REFERENCE(1932, /* s q */ 'c' _ 'u' _ 'p' _ 's' _ ';', 5, 0, 0x2294 _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(1933, /* s q */ 's' _ 'u' _ 'b' _ ';', 4, 0, 0x228f _ 0)
+NAMED_CHARACTER_REFERENCE(1934, /* s q */ 's' _ 'u' _ 'b' _ 'e' _ ';', 5, 0, 0x2291 _ 0)
+NAMED_CHARACTER_REFERENCE(1935, /* s q */ 's' _ 'u' _ 'b' _ 's' _ 'e' _ 't' _ ';', 7, 0, 0x228f _ 0)
+NAMED_CHARACTER_REFERENCE(1936, /* s q */ 's' _ 'u' _ 'b' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ ';', 9, 0, 0x2291 _ 0)
+NAMED_CHARACTER_REFERENCE(1937, /* s q */ 's' _ 'u' _ 'p' _ ';', 4, 0, 0x2290 _ 0)
+NAMED_CHARACTER_REFERENCE(1938, /* s q */ 's' _ 'u' _ 'p' _ 'e' _ ';', 5, 0, 0x2292 _ 0)
+NAMED_CHARACTER_REFERENCE(1939, /* s q */ 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ ';', 7, 0, 0x2290 _ 0)
+NAMED_CHARACTER_REFERENCE(1940, /* s q */ 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ ';', 9, 0, 0x2292 _ 0)
+NAMED_CHARACTER_REFERENCE(1941, /* s q */ 'u' _ ';', 2, 0, 0x25a1 _ 0)
+NAMED_CHARACTER_REFERENCE(1942, /* s q */ 'u' _ 'a' _ 'r' _ 'e' _ ';', 5, 0, 0x25a1 _ 0)
+NAMED_CHARACTER_REFERENCE(1943, /* s q */ 'u' _ 'a' _ 'r' _ 'f' _ ';', 5, 0, 0x25aa _ 0)
+NAMED_CHARACTER_REFERENCE(1944, /* s q */ 'u' _ 'f' _ ';', 3, 0, 0x25aa _ 0)
+NAMED_CHARACTER_REFERENCE(1945, /* s r */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x2192 _ 0)
+NAMED_CHARACTER_REFERENCE(1946, /* s s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcc8)
+NAMED_CHARACTER_REFERENCE(1947, /* s s */ 'e' _ 't' _ 'm' _ 'n' _ ';', 5, 0, 0x2216 _ 0)
+NAMED_CHARACTER_REFERENCE(1948, /* s s */ 'm' _ 'i' _ 'l' _ 'e' _ ';', 5, 0, 0x2323 _ 0)
+NAMED_CHARACTER_REFERENCE(1949, /* s s */ 't' _ 'a' _ 'r' _ 'f' _ ';', 5, 0, 0x22c6 _ 0)
+NAMED_CHARACTER_REFERENCE(1950, /* s t */ 'a' _ 'r' _ ';', 3, 0, 0x2606 _ 0)
+NAMED_CHARACTER_REFERENCE(1951, /* s t */ 'a' _ 'r' _ 'f' _ ';', 4, 0, 0x2605 _ 0)
+NAMED_CHARACTER_REFERENCE(1952, /* s t */ 'r' _ 'a' _ 'i' _ 'g' _ 'h' _ 't' _ 'e' _ 'p' _ 's' _ 'i' _ 'l' _ 'o' _ 'n' _ ';', 14, 0, 0x03f5 _ 0)
+NAMED_CHARACTER_REFERENCE(1953, /* s t */ 'r' _ 'a' _ 'i' _ 'g' _ 'h' _ 't' _ 'p' _ 'h' _ 'i' _ ';', 10, 0, 0x03d5 _ 0)
+NAMED_CHARACTER_REFERENCE(1954, /* s t */ 'r' _ 'n' _ 's' _ ';', 4, 0, 0x00af _ 0)
+NAMED_CHARACTER_REFERENCE(1955, /* s u */ 'b' _ ';', 2, 0, 0x2282 _ 0)
+NAMED_CHARACTER_REFERENCE(1956, /* s u */ 'b' _ 'E' _ ';', 3, 0, 0x2ac5 _ 0)
+NAMED_CHARACTER_REFERENCE(1957, /* s u */ 'b' _ 'd' _ 'o' _ 't' _ ';', 5, 0, 0x2abd _ 0)
+NAMED_CHARACTER_REFERENCE(1958, /* s u */ 'b' _ 'e' _ ';', 3, 0, 0x2286 _ 0)
+NAMED_CHARACTER_REFERENCE(1959, /* s u */ 'b' _ 'e' _ 'd' _ 'o' _ 't' _ ';', 6, 0, 0x2ac3 _ 0)
+NAMED_CHARACTER_REFERENCE(1960, /* s u */ 'b' _ 'm' _ 'u' _ 'l' _ 't' _ ';', 6, 0, 0x2ac1 _ 0)
+NAMED_CHARACTER_REFERENCE(1961, /* s u */ 'b' _ 'n' _ 'E' _ ';', 4, 0, 0x2acb _ 0)
+NAMED_CHARACTER_REFERENCE(1962, /* s u */ 'b' _ 'n' _ 'e' _ ';', 4, 0, 0x228a _ 0)
+NAMED_CHARACTER_REFERENCE(1963, /* s u */ 'b' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 6, 0, 0x2abf _ 0)
+NAMED_CHARACTER_REFERENCE(1964, /* s u */ 'b' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 6, 0, 0x2979 _ 0)
+NAMED_CHARACTER_REFERENCE(1965, /* s u */ 'b' _ 's' _ 'e' _ 't' _ ';', 5, 0, 0x2282 _ 0)
+NAMED_CHARACTER_REFERENCE(1966, /* s u */ 'b' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ ';', 7, 0, 0x2286 _ 0)
+NAMED_CHARACTER_REFERENCE(1967, /* s u */ 'b' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ 'q' _ ';', 8, 0, 0x2ac5 _ 0)
+NAMED_CHARACTER_REFERENCE(1968, /* s u */ 'b' _ 's' _ 'e' _ 't' _ 'n' _ 'e' _ 'q' _ ';', 8, 0, 0x228a _ 0)
+NAMED_CHARACTER_REFERENCE(1969, /* s u */ 'b' _ 's' _ 'e' _ 't' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 9, 0, 0x2acb _ 0)
+NAMED_CHARACTER_REFERENCE(1970, /* s u */ 'b' _ 's' _ 'i' _ 'm' _ ';', 5, 0, 0x2ac7 _ 0)
+NAMED_CHARACTER_REFERENCE(1971, /* s u */ 'b' _ 's' _ 'u' _ 'b' _ ';', 5, 0, 0x2ad5 _ 0)
+NAMED_CHARACTER_REFERENCE(1972, /* s u */ 'b' _ 's' _ 'u' _ 'p' _ ';', 5, 0, 0x2ad3 _ 0)
+NAMED_CHARACTER_REFERENCE(1973, /* s u */ 'c' _ 'c' _ ';', 3, 0, 0x227b _ 0)
+NAMED_CHARACTER_REFERENCE(1974, /* s u */ 'c' _ 'c' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 9, 0, 0x2ab8 _ 0)
+NAMED_CHARACTER_REFERENCE(1975, /* s u */ 'c' _ 'c' _ 'c' _ 'u' _ 'r' _ 'l' _ 'y' _ 'e' _ 'q' _ ';', 10, 0, 0x227d _ 0)
+NAMED_CHARACTER_REFERENCE(1976, /* s u */ 'c' _ 'c' _ 'e' _ 'q' _ ';', 5, 0, 0x2ab0 _ 0)
+NAMED_CHARACTER_REFERENCE(1977, /* s u */ 'c' _ 'c' _ 'n' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 10, 0, 0x2aba _ 0)
+NAMED_CHARACTER_REFERENCE(1978, /* s u */ 'c' _ 'c' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 7, 0, 0x2ab6 _ 0)
+NAMED_CHARACTER_REFERENCE(1979, /* s u */ 'c' _ 'c' _ 'n' _ 's' _ 'i' _ 'm' _ ';', 7, 0, 0x22e9 _ 0)
+NAMED_CHARACTER_REFERENCE(1980, /* s u */ 'c' _ 'c' _ 's' _ 'i' _ 'm' _ ';', 6, 0, 0x227f _ 0)
+NAMED_CHARACTER_REFERENCE(1981, /* s u */ 'm' _ ';', 2, 0, 0x2211 _ 0)
+NAMED_CHARACTER_REFERENCE(1982, /* s u */ 'n' _ 'g' _ ';', 3, 0, 0x266a _ 0)
+NAMED_CHARACTER_REFERENCE(1983, /* s u */ 'p' _ '1', 2, 0, 0x00b9 _ 0)
+NAMED_CHARACTER_REFERENCE(1984, /* s u */ 'p' _ '1' _ ';', 3, 0, 0x00b9 _ 0)
+NAMED_CHARACTER_REFERENCE(1985, /* s u */ 'p' _ '2', 2, 0, 0x00b2 _ 0)
+NAMED_CHARACTER_REFERENCE(1986, /* s u */ 'p' _ '2' _ ';', 3, 0, 0x00b2 _ 0)
+NAMED_CHARACTER_REFERENCE(1987, /* s u */ 'p' _ '3', 2, 0, 0x00b3 _ 0)
+NAMED_CHARACTER_REFERENCE(1988, /* s u */ 'p' _ '3' _ ';', 3, 0, 0x00b3 _ 0)
+NAMED_CHARACTER_REFERENCE(1989, /* s u */ 'p' _ ';', 2, 0, 0x2283 _ 0)
+NAMED_CHARACTER_REFERENCE(1990, /* s u */ 'p' _ 'E' _ ';', 3, 0, 0x2ac6 _ 0)
+NAMED_CHARACTER_REFERENCE(1991, /* s u */ 'p' _ 'd' _ 'o' _ 't' _ ';', 5, 0, 0x2abe _ 0)
+NAMED_CHARACTER_REFERENCE(1992, /* s u */ 'p' _ 'd' _ 's' _ 'u' _ 'b' _ ';', 6, 0, 0x2ad8 _ 0)
+NAMED_CHARACTER_REFERENCE(1993, /* s u */ 'p' _ 'e' _ ';', 3, 0, 0x2287 _ 0)
+NAMED_CHARACTER_REFERENCE(1994, /* s u */ 'p' _ 'e' _ 'd' _ 'o' _ 't' _ ';', 6, 0, 0x2ac4 _ 0)
+NAMED_CHARACTER_REFERENCE(1995, /* s u */ 'p' _ 'h' _ 's' _ 'o' _ 'l' _ ';', 6, 0, 0x27c9 _ 0)
+NAMED_CHARACTER_REFERENCE(1996, /* s u */ 'p' _ 'h' _ 's' _ 'u' _ 'b' _ ';', 6, 0, 0x2ad7 _ 0)
+NAMED_CHARACTER_REFERENCE(1997, /* s u */ 'p' _ 'l' _ 'a' _ 'r' _ 'r' _ ';', 6, 0, 0x297b _ 0)
+NAMED_CHARACTER_REFERENCE(1998, /* s u */ 'p' _ 'm' _ 'u' _ 'l' _ 't' _ ';', 6, 0, 0x2ac2 _ 0)
+NAMED_CHARACTER_REFERENCE(1999, /* s u */ 'p' _ 'n' _ 'E' _ ';', 4, 0, 0x2acc _ 0)
+NAMED_CHARACTER_REFERENCE(2000, /* s u */ 'p' _ 'n' _ 'e' _ ';', 4, 0, 0x228b _ 0)
+NAMED_CHARACTER_REFERENCE(2001, /* s u */ 'p' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 6, 0, 0x2ac0 _ 0)
+NAMED_CHARACTER_REFERENCE(2002, /* s u */ 'p' _ 's' _ 'e' _ 't' _ ';', 5, 0, 0x2283 _ 0)
+NAMED_CHARACTER_REFERENCE(2003, /* s u */ 'p' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ ';', 7, 0, 0x2287 _ 0)
+NAMED_CHARACTER_REFERENCE(2004, /* s u */ 'p' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ 'q' _ ';', 8, 0, 0x2ac6 _ 0)
+NAMED_CHARACTER_REFERENCE(2005, /* s u */ 'p' _ 's' _ 'e' _ 't' _ 'n' _ 'e' _ 'q' _ ';', 8, 0, 0x228b _ 0)
+NAMED_CHARACTER_REFERENCE(2006, /* s u */ 'p' _ 's' _ 'e' _ 't' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 9, 0, 0x2acc _ 0)
+NAMED_CHARACTER_REFERENCE(2007, /* s u */ 'p' _ 's' _ 'i' _ 'm' _ ';', 5, 0, 0x2ac8 _ 0)
+NAMED_CHARACTER_REFERENCE(2008, /* s u */ 'p' _ 's' _ 'u' _ 'b' _ ';', 5, 0, 0x2ad4 _ 0)
+NAMED_CHARACTER_REFERENCE(2009, /* s u */ 'p' _ 's' _ 'u' _ 'p' _ ';', 5, 0, 0x2ad6 _ 0)
+NAMED_CHARACTER_REFERENCE(2010, /* s w */ 'A' _ 'r' _ 'r' _ ';', 4, 0, 0x21d9 _ 0)
+NAMED_CHARACTER_REFERENCE(2011, /* s w */ 'a' _ 'r' _ 'h' _ 'k' _ ';', 5, 0, 0x2926 _ 0)
+NAMED_CHARACTER_REFERENCE(2012, /* s w */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x2199 _ 0)
+NAMED_CHARACTER_REFERENCE(2013, /* s w */ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 6, 0, 0x2199 _ 0)
+NAMED_CHARACTER_REFERENCE(2014, /* s w */ 'n' _ 'w' _ 'a' _ 'r' _ ';', 5, 0, 0x292a _ 0)
+NAMED_CHARACTER_REFERENCE(2015, /* s z */ 'l' _ 'i' _ 'g', 3, 0, 0x00df _ 0)
+NAMED_CHARACTER_REFERENCE(2016, /* s z */ 'l' _ 'i' _ 'g' _ ';', 4, 0, 0x00df _ 0)
+NAMED_CHARACTER_REFERENCE(2017, /* t a */ 'r' _ 'g' _ 'e' _ 't' _ ';', 5, 0, 0x2316 _ 0)
+NAMED_CHARACTER_REFERENCE(2018, /* t a */ 'u' _ ';', 2, 0, 0x03c4 _ 0)
+NAMED_CHARACTER_REFERENCE(2019, /* t b */ 'r' _ 'k' _ ';', 3, 0, 0x23b4 _ 0)
+NAMED_CHARACTER_REFERENCE(2020, /* t c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x0165 _ 0)
+NAMED_CHARACTER_REFERENCE(2021, /* t c */ 'e' _ 'd' _ 'i' _ 'l' _ ';', 5, 0, 0x0163 _ 0)
+NAMED_CHARACTER_REFERENCE(2022, /* t c */ 'y' _ ';', 2, 0, 0x0442 _ 0)
+NAMED_CHARACTER_REFERENCE(2023, /* t d */ 'o' _ 't' _ ';', 3, 0, 0x20db _ 0)
+NAMED_CHARACTER_REFERENCE(2024, /* t e */ 'l' _ 'r' _ 'e' _ 'c' _ ';', 5, 0, 0x2315 _ 0)
+NAMED_CHARACTER_REFERENCE(2025, /* t f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd31)
+NAMED_CHARACTER_REFERENCE(2026, /* t h */ 'e' _ 'r' _ 'e' _ '4' _ ';', 5, 0, 0x2234 _ 0)
+NAMED_CHARACTER_REFERENCE(2027, /* t h */ 'e' _ 'r' _ 'e' _ 'f' _ 'o' _ 'r' _ 'e' _ ';', 8, 0, 0x2234 _ 0)
+NAMED_CHARACTER_REFERENCE(2028, /* t h */ 'e' _ 't' _ 'a' _ ';', 4, 0, 0x03b8 _ 0)
+NAMED_CHARACTER_REFERENCE(2029, /* t h */ 'e' _ 't' _ 'a' _ 's' _ 'y' _ 'm' _ ';', 7, 0, 0x03d1 _ 0)
+NAMED_CHARACTER_REFERENCE(2030, /* t h */ 'e' _ 't' _ 'a' _ 'v' _ ';', 5, 0, 0x03d1 _ 0)
+NAMED_CHARACTER_REFERENCE(2031, /* t h */ 'i' _ 'c' _ 'k' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 10, 0, 0x2248 _ 0)
+NAMED_CHARACTER_REFERENCE(2032, /* t h */ 'i' _ 'c' _ 'k' _ 's' _ 'i' _ 'm' _ ';', 7, 0, 0x223c _ 0)
+NAMED_CHARACTER_REFERENCE(2033, /* t h */ 'i' _ 'n' _ 's' _ 'p' _ ';', 5, 0, 0x2009 _ 0)
+NAMED_CHARACTER_REFERENCE(2034, /* t h */ 'k' _ 'a' _ 'p' _ ';', 4, 0, 0x2248 _ 0)
+NAMED_CHARACTER_REFERENCE(2035, /* t h */ 'k' _ 's' _ 'i' _ 'm' _ ';', 5, 0, 0x223c _ 0)
+NAMED_CHARACTER_REFERENCE(2036, /* t h */ 'o' _ 'r' _ 'n', 3, 0, 0x00fe _ 0)
+NAMED_CHARACTER_REFERENCE(2037, /* t h */ 'o' _ 'r' _ 'n' _ ';', 4, 0, 0x00fe _ 0)
+NAMED_CHARACTER_REFERENCE(2038, /* t i */ 'l' _ 'd' _ 'e' _ ';', 4, 0, 0x02dc _ 0)
+NAMED_CHARACTER_REFERENCE(2039, /* t i */ 'm' _ 'e' _ 's', 3, 0, 0x00d7 _ 0)
+NAMED_CHARACTER_REFERENCE(2040, /* t i */ 'm' _ 'e' _ 's' _ ';', 4, 0, 0x00d7 _ 0)
+NAMED_CHARACTER_REFERENCE(2041, /* t i */ 'm' _ 'e' _ 's' _ 'b' _ ';', 5, 0, 0x22a0 _ 0)
+NAMED_CHARACTER_REFERENCE(2042, /* t i */ 'm' _ 'e' _ 's' _ 'b' _ 'a' _ 'r' _ ';', 7, 0, 0x2a31 _ 0)
+NAMED_CHARACTER_REFERENCE(2043, /* t i */ 'm' _ 'e' _ 's' _ 'd' _ ';', 5, 0, 0x2a30 _ 0)
+NAMED_CHARACTER_REFERENCE(2044, /* t i */ 'n' _ 't' _ ';', 3, 0, 0x222d _ 0)
+NAMED_CHARACTER_REFERENCE(2045, /* t o */ 'e' _ 'a' _ ';', 3, 0, 0x2928 _ 0)
+NAMED_CHARACTER_REFERENCE(2046, /* t o */ 'p' _ ';', 2, 0, 0x22a4 _ 0)
+NAMED_CHARACTER_REFERENCE(2047, /* t o */ 'p' _ 'b' _ 'o' _ 't' _ ';', 5, 0, 0x2336 _ 0)
+NAMED_CHARACTER_REFERENCE(2048, /* t o */ 'p' _ 'c' _ 'i' _ 'r' _ ';', 5, 0, 0x2af1 _ 0)
+NAMED_CHARACTER_REFERENCE(2049, /* t o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd65)
+NAMED_CHARACTER_REFERENCE(2050, /* t o */ 'p' _ 'f' _ 'o' _ 'r' _ 'k' _ ';', 6, 0, 0x2ada _ 0)
+NAMED_CHARACTER_REFERENCE(2051, /* t o */ 's' _ 'a' _ ';', 3, 0, 0x2929 _ 0)
+NAMED_CHARACTER_REFERENCE(2052, /* t p */ 'r' _ 'i' _ 'm' _ 'e' _ ';', 5, 0, 0x2034 _ 0)
+NAMED_CHARACTER_REFERENCE(2053, /* t r */ 'a' _ 'd' _ 'e' _ ';', 4, 0, 0x2122 _ 0)
+NAMED_CHARACTER_REFERENCE(2054, /* t r */ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 7, 0, 0x25b5 _ 0)
+NAMED_CHARACTER_REFERENCE(2055, /* t r */ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'd' _ 'o' _ 'w' _ 'n' _ ';', 11, 0, 0x25bf _ 0)
+NAMED_CHARACTER_REFERENCE(2056, /* t r */ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 11, 0, 0x25c3 _ 0)
+NAMED_CHARACTER_REFERENCE(2057, /* t r */ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ 'e' _ 'q' _ ';', 13, 0, 0x22b4 _ 0)
+NAMED_CHARACTER_REFERENCE(2058, /* t r */ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'q' _ ';', 8, 0, 0x225c _ 0)
+NAMED_CHARACTER_REFERENCE(2059, /* t r */ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 12, 0, 0x25b9 _ 0)
+NAMED_CHARACTER_REFERENCE(2060, /* t r */ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'e' _ 'q' _ ';', 14, 0, 0x22b5 _ 0)
+NAMED_CHARACTER_REFERENCE(2061, /* t r */ 'i' _ 'd' _ 'o' _ 't' _ ';', 5, 0, 0x25ec _ 0)
+NAMED_CHARACTER_REFERENCE(2062, /* t r */ 'i' _ 'e' _ ';', 3, 0, 0x225c _ 0)
+NAMED_CHARACTER_REFERENCE(2063, /* t r */ 'i' _ 'm' _ 'i' _ 'n' _ 'u' _ 's' _ ';', 7, 0, 0x2a3a _ 0)
+NAMED_CHARACTER_REFERENCE(2064, /* t r */ 'i' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 6, 0, 0x2a39 _ 0)
+NAMED_CHARACTER_REFERENCE(2065, /* t r */ 'i' _ 's' _ 'b' _ ';', 4, 0, 0x29cd _ 0)
+NAMED_CHARACTER_REFERENCE(2066, /* t r */ 'i' _ 't' _ 'i' _ 'm' _ 'e' _ ';', 6, 0, 0x2a3b _ 0)
+NAMED_CHARACTER_REFERENCE(2067, /* t r */ 'p' _ 'e' _ 'z' _ 'i' _ 'u' _ 'm' _ ';', 7, 0, 0x23e2 _ 0)
+NAMED_CHARACTER_REFERENCE(2068, /* t s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcc9)
+NAMED_CHARACTER_REFERENCE(2069, /* t s */ 'c' _ 'y' _ ';', 3, 0, 0x0446 _ 0)
+NAMED_CHARACTER_REFERENCE(2070, /* t s */ 'h' _ 'c' _ 'y' _ ';', 4, 0, 0x045b _ 0)
+NAMED_CHARACTER_REFERENCE(2071, /* t s */ 't' _ 'r' _ 'o' _ 'k' _ ';', 5, 0, 0x0167 _ 0)
+NAMED_CHARACTER_REFERENCE(2072, /* t w */ 'i' _ 'x' _ 't' _ ';', 4, 0, 0x226c _ 0)
+NAMED_CHARACTER_REFERENCE(2073, /* t w */ 'o' _ 'h' _ 'e' _ 'a' _ 'd' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 15, 0, 0x219e _ 0)
+NAMED_CHARACTER_REFERENCE(2074, /* t w */ 'o' _ 'h' _ 'e' _ 'a' _ 'd' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 16, 0, 0x21a0 _ 0)
+NAMED_CHARACTER_REFERENCE(2075, /* u A */ 'r' _ 'r' _ ';', 3, 0, 0x21d1 _ 0)
+NAMED_CHARACTER_REFERENCE(2076, /* u H */ 'a' _ 'r' _ ';', 3, 0, 0x2963 _ 0)
+NAMED_CHARACTER_REFERENCE(2077, /* u a */ 'c' _ 'u' _ 't' _ 'e', 4, 0, 0x00fa _ 0)
+NAMED_CHARACTER_REFERENCE(2078, /* u a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x00fa _ 0)
+NAMED_CHARACTER_REFERENCE(2079, /* u a */ 'r' _ 'r' _ ';', 3, 0, 0x2191 _ 0)
+NAMED_CHARACTER_REFERENCE(2080, /* u b */ 'r' _ 'c' _ 'y' _ ';', 4, 0, 0x045e _ 0)
+NAMED_CHARACTER_REFERENCE(2081, /* u b */ 'r' _ 'e' _ 'v' _ 'e' _ ';', 5, 0, 0x016d _ 0)
+NAMED_CHARACTER_REFERENCE(2082, /* u c */ 'i' _ 'r' _ 'c', 3, 0, 0x00fb _ 0)
+NAMED_CHARACTER_REFERENCE(2083, /* u c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x00fb _ 0)
+NAMED_CHARACTER_REFERENCE(2084, /* u c */ 'y' _ ';', 2, 0, 0x0443 _ 0)
+NAMED_CHARACTER_REFERENCE(2085, /* u d */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21c5 _ 0)
+NAMED_CHARACTER_REFERENCE(2086, /* u d */ 'b' _ 'l' _ 'a' _ 'c' _ ';', 5, 0, 0x0171 _ 0)
+NAMED_CHARACTER_REFERENCE(2087, /* u d */ 'h' _ 'a' _ 'r' _ ';', 4, 0, 0x296e _ 0)
+NAMED_CHARACTER_REFERENCE(2088, /* u f */ 'i' _ 's' _ 'h' _ 't' _ ';', 5, 0, 0x297e _ 0)
+NAMED_CHARACTER_REFERENCE(2089, /* u f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd32)
+NAMED_CHARACTER_REFERENCE(2090, /* u g */ 'r' _ 'a' _ 'v' _ 'e', 4, 0, 0x00f9 _ 0)
+NAMED_CHARACTER_REFERENCE(2091, /* u g */ 'r' _ 'a' _ 'v' _ 'e' _ ';', 5, 0, 0x00f9 _ 0)
+NAMED_CHARACTER_REFERENCE(2092, /* u h */ 'a' _ 'r' _ 'l' _ ';', 4, 0, 0x21bf _ 0)
+NAMED_CHARACTER_REFERENCE(2093, /* u h */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21be _ 0)
+NAMED_CHARACTER_REFERENCE(2094, /* u h */ 'b' _ 'l' _ 'k' _ ';', 4, 0, 0x2580 _ 0)
+NAMED_CHARACTER_REFERENCE(2095, /* u l */ 'c' _ 'o' _ 'r' _ 'n' _ ';', 5, 0, 0x231c _ 0)
+NAMED_CHARACTER_REFERENCE(2096, /* u l */ 'c' _ 'o' _ 'r' _ 'n' _ 'e' _ 'r' _ ';', 7, 0, 0x231c _ 0)
+NAMED_CHARACTER_REFERENCE(2097, /* u l */ 'c' _ 'r' _ 'o' _ 'p' _ ';', 5, 0, 0x230f _ 0)
+NAMED_CHARACTER_REFERENCE(2098, /* u l */ 't' _ 'r' _ 'i' _ ';', 4, 0, 0x25f8 _ 0)
+NAMED_CHARACTER_REFERENCE(2099, /* u m */ 'a' _ 'c' _ 'r' _ ';', 4, 0, 0x016b _ 0)
+NAMED_CHARACTER_REFERENCE(2100, /* u m */ 'l', 1, 0, 0x00a8 _ 0)
+NAMED_CHARACTER_REFERENCE(2101, /* u m */ 'l' _ ';', 2, 0, 0x00a8 _ 0)
+NAMED_CHARACTER_REFERENCE(2102, /* u o */ 'g' _ 'o' _ 'n' _ ';', 4, 0, 0x0173 _ 0)
+NAMED_CHARACTER_REFERENCE(2103, /* u o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd66)
+NAMED_CHARACTER_REFERENCE(2104, /* u p */ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 6, 0, 0x2191 _ 0)
+NAMED_CHARACTER_REFERENCE(2105, /* u p */ 'd' _ 'o' _ 'w' _ 'n' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 10, 0, 0x2195 _ 0)
+NAMED_CHARACTER_REFERENCE(2106, /* u p */ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 12, 0, 0x21bf _ 0)
+NAMED_CHARACTER_REFERENCE(2107, /* u p */ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 13, 0, 0x21be _ 0)
+NAMED_CHARACTER_REFERENCE(2108, /* u p */ 'l' _ 'u' _ 's' _ ';', 4, 0, 0x228e _ 0)
+NAMED_CHARACTER_REFERENCE(2109, /* u p */ 's' _ 'i' _ ';', 3, 0, 0x03c5 _ 0)
+NAMED_CHARACTER_REFERENCE(2110, /* u p */ 's' _ 'i' _ 'h' _ ';', 4, 0, 0x03d2 _ 0)
+NAMED_CHARACTER_REFERENCE(2111, /* u p */ 's' _ 'i' _ 'l' _ 'o' _ 'n' _ ';', 6, 0, 0x03c5 _ 0)
+NAMED_CHARACTER_REFERENCE(2112, /* u p */ 'u' _ 'p' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 's' _ ';', 9, 0, 0x21c8 _ 0)
+NAMED_CHARACTER_REFERENCE(2113, /* u r */ 'c' _ 'o' _ 'r' _ 'n' _ ';', 5, 0, 0x231d _ 0)
+NAMED_CHARACTER_REFERENCE(2114, /* u r */ 'c' _ 'o' _ 'r' _ 'n' _ 'e' _ 'r' _ ';', 7, 0, 0x231d _ 0)
+NAMED_CHARACTER_REFERENCE(2115, /* u r */ 'c' _ 'r' _ 'o' _ 'p' _ ';', 5, 0, 0x230e _ 0)
+NAMED_CHARACTER_REFERENCE(2116, /* u r */ 'i' _ 'n' _ 'g' _ ';', 4, 0, 0x016f _ 0)
+NAMED_CHARACTER_REFERENCE(2117, /* u r */ 't' _ 'r' _ 'i' _ ';', 4, 0, 0x25f9 _ 0)
+NAMED_CHARACTER_REFERENCE(2118, /* u s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcca)
+NAMED_CHARACTER_REFERENCE(2119, /* u t */ 'd' _ 'o' _ 't' _ ';', 4, 0, 0x22f0 _ 0)
+NAMED_CHARACTER_REFERENCE(2120, /* u t */ 'i' _ 'l' _ 'd' _ 'e' _ ';', 5, 0, 0x0169 _ 0)
+NAMED_CHARACTER_REFERENCE(2121, /* u t */ 'r' _ 'i' _ ';', 3, 0, 0x25b5 _ 0)
+NAMED_CHARACTER_REFERENCE(2122, /* u t */ 'r' _ 'i' _ 'f' _ ';', 4, 0, 0x25b4 _ 0)
+NAMED_CHARACTER_REFERENCE(2123, /* u u */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x21c8 _ 0)
+NAMED_CHARACTER_REFERENCE(2124, /* u u */ 'm' _ 'l', 2, 0, 0x00fc _ 0)
+NAMED_CHARACTER_REFERENCE(2125, /* u u */ 'm' _ 'l' _ ';', 3, 0, 0x00fc _ 0)
+NAMED_CHARACTER_REFERENCE(2126, /* u w */ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 6, 0, 0x29a7 _ 0)
+NAMED_CHARACTER_REFERENCE(2127, /* v A */ 'r' _ 'r' _ ';', 3, 0, 0x21d5 _ 0)
+NAMED_CHARACTER_REFERENCE(2128, /* v B */ 'a' _ 'r' _ ';', 3, 0, 0x2ae8 _ 0)
+NAMED_CHARACTER_REFERENCE(2129, /* v B */ 'a' _ 'r' _ 'v' _ ';', 4, 0, 0x2ae9 _ 0)
+NAMED_CHARACTER_REFERENCE(2130, /* v D */ 'a' _ 's' _ 'h' _ ';', 4, 0, 0x22a8 _ 0)
+NAMED_CHARACTER_REFERENCE(2131, /* v a */ 'n' _ 'g' _ 'r' _ 't' _ ';', 5, 0, 0x299c _ 0)
+NAMED_CHARACTER_REFERENCE(2132, /* v a */ 'r' _ 'e' _ 'p' _ 's' _ 'i' _ 'l' _ 'o' _ 'n' _ ';', 9, 0, 0x03f5 _ 0)
+NAMED_CHARACTER_REFERENCE(2133, /* v a */ 'r' _ 'k' _ 'a' _ 'p' _ 'p' _ 'a' _ ';', 7, 0, 0x03f0 _ 0)
+NAMED_CHARACTER_REFERENCE(2134, /* v a */ 'r' _ 'n' _ 'o' _ 't' _ 'h' _ 'i' _ 'n' _ 'g' _ ';', 9, 0, 0x2205 _ 0)
+NAMED_CHARACTER_REFERENCE(2135, /* v a */ 'r' _ 'p' _ 'h' _ 'i' _ ';', 5, 0, 0x03d5 _ 0)
+NAMED_CHARACTER_REFERENCE(2136, /* v a */ 'r' _ 'p' _ 'i' _ ';', 4, 0, 0x03d6 _ 0)
+NAMED_CHARACTER_REFERENCE(2137, /* v a */ 'r' _ 'p' _ 'r' _ 'o' _ 'p' _ 't' _ 'o' _ ';', 8, 0, 0x221d _ 0)
+NAMED_CHARACTER_REFERENCE(2138, /* v a */ 'r' _ 'r' _ ';', 3, 0, 0x2195 _ 0)
+NAMED_CHARACTER_REFERENCE(2139, /* v a */ 'r' _ 'r' _ 'h' _ 'o' _ ';', 5, 0, 0x03f1 _ 0)
+NAMED_CHARACTER_REFERENCE(2140, /* v a */ 'r' _ 's' _ 'i' _ 'g' _ 'm' _ 'a' _ ';', 7, 0, 0x03c2 _ 0)
+NAMED_CHARACTER_REFERENCE(2141, /* v a */ 'r' _ 's' _ 'u' _ 'b' _ 's' _ 'e' _ 't' _ 'n' _ 'e' _ 'q' _ ';', 11, 0, 0x228a _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(2142, /* v a */ 'r' _ 's' _ 'u' _ 'b' _ 's' _ 'e' _ 't' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 12, 0, 0x2acb _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(2143, /* v a */ 'r' _ 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ 'n' _ 'e' _ 'q' _ ';', 11, 0, 0x228b _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(2144, /* v a */ 'r' _ 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 12, 0, 0x2acc _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(2145, /* v a */ 'r' _ 't' _ 'h' _ 'e' _ 't' _ 'a' _ ';', 7, 0, 0x03d1 _ 0)
+NAMED_CHARACTER_REFERENCE(2146, /* v a */ 'r' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 14, 0, 0x22b2 _ 0)
+NAMED_CHARACTER_REFERENCE(2147, /* v a */ 'r' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 15, 0, 0x22b3 _ 0)
+NAMED_CHARACTER_REFERENCE(2148, /* v c */ 'y' _ ';', 2, 0, 0x0432 _ 0)
+NAMED_CHARACTER_REFERENCE(2149, /* v d */ 'a' _ 's' _ 'h' _ ';', 4, 0, 0x22a2 _ 0)
+NAMED_CHARACTER_REFERENCE(2150, /* v e */ 'e' _ ';', 2, 0, 0x2228 _ 0)
+NAMED_CHARACTER_REFERENCE(2151, /* v e */ 'e' _ 'b' _ 'a' _ 'r' _ ';', 5, 0, 0x22bb _ 0)
+NAMED_CHARACTER_REFERENCE(2152, /* v e */ 'e' _ 'e' _ 'q' _ ';', 4, 0, 0x225a _ 0)
+NAMED_CHARACTER_REFERENCE(2153, /* v e */ 'l' _ 'l' _ 'i' _ 'p' _ ';', 5, 0, 0x22ee _ 0)
+NAMED_CHARACTER_REFERENCE(2154, /* v e */ 'r' _ 'b' _ 'a' _ 'r' _ ';', 5, 0, 0x007c _ 0)
+NAMED_CHARACTER_REFERENCE(2155, /* v e */ 'r' _ 't' _ ';', 3, 0, 0x007c _ 0)
+NAMED_CHARACTER_REFERENCE(2156, /* v f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd33)
+NAMED_CHARACTER_REFERENCE(2157, /* v l */ 't' _ 'r' _ 'i' _ ';', 4, 0, 0x22b2 _ 0)
+NAMED_CHARACTER_REFERENCE(2158, /* v n */ 's' _ 'u' _ 'b' _ ';', 4, 0, 0x2282 _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(2159, /* v n */ 's' _ 'u' _ 'p' _ ';', 4, 0, 0x2283 _ 0x20d2)
+NAMED_CHARACTER_REFERENCE(2160, /* v o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd67)
+NAMED_CHARACTER_REFERENCE(2161, /* v p */ 'r' _ 'o' _ 'p' _ ';', 4, 0, 0x221d _ 0)
+NAMED_CHARACTER_REFERENCE(2162, /* v r */ 't' _ 'r' _ 'i' _ ';', 4, 0, 0x22b3 _ 0)
+NAMED_CHARACTER_REFERENCE(2163, /* v s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdccb)
+NAMED_CHARACTER_REFERENCE(2164, /* v s */ 'u' _ 'b' _ 'n' _ 'E' _ ';', 5, 0, 0x2acb _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(2165, /* v s */ 'u' _ 'b' _ 'n' _ 'e' _ ';', 5, 0, 0x228a _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(2166, /* v s */ 'u' _ 'p' _ 'n' _ 'E' _ ';', 5, 0, 0x2acc _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(2167, /* v s */ 'u' _ 'p' _ 'n' _ 'e' _ ';', 5, 0, 0x228b _ 0xfe00)
+NAMED_CHARACTER_REFERENCE(2168, /* v z */ 'i' _ 'g' _ 'z' _ 'a' _ 'g' _ ';', 6, 0, 0x299a _ 0)
+NAMED_CHARACTER_REFERENCE(2169, /* w c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x0175 _ 0)
+NAMED_CHARACTER_REFERENCE(2170, /* w e */ 'd' _ 'b' _ 'a' _ 'r' _ ';', 5, 0, 0x2a5f _ 0)
+NAMED_CHARACTER_REFERENCE(2171, /* w e */ 'd' _ 'g' _ 'e' _ ';', 4, 0, 0x2227 _ 0)
+NAMED_CHARACTER_REFERENCE(2172, /* w e */ 'd' _ 'g' _ 'e' _ 'q' _ ';', 5, 0, 0x2259 _ 0)
+NAMED_CHARACTER_REFERENCE(2173, /* w e */ 'i' _ 'e' _ 'r' _ 'p' _ ';', 5, 0, 0x2118 _ 0)
+NAMED_CHARACTER_REFERENCE(2174, /* w f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd34)
+NAMED_CHARACTER_REFERENCE(2175, /* w o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd68)
+NAMED_CHARACTER_REFERENCE(2176, /* w p */ ';', 1, 0, 0x2118 _ 0)
+NAMED_CHARACTER_REFERENCE(2177, /* w r */ ';', 1, 0, 0x2240 _ 0)
+NAMED_CHARACTER_REFERENCE(2178, /* w r */ 'e' _ 'a' _ 't' _ 'h' _ ';', 5, 0, 0x2240 _ 0)
+NAMED_CHARACTER_REFERENCE(2179, /* w s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdccc)
+NAMED_CHARACTER_REFERENCE(2180, /* x c */ 'a' _ 'p' _ ';', 3, 0, 0x22c2 _ 0)
+NAMED_CHARACTER_REFERENCE(2181, /* x c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x25ef _ 0)
+NAMED_CHARACTER_REFERENCE(2182, /* x c */ 'u' _ 'p' _ ';', 3, 0, 0x22c3 _ 0)
+NAMED_CHARACTER_REFERENCE(2183, /* x d */ 't' _ 'r' _ 'i' _ ';', 4, 0, 0x25bd _ 0)
+NAMED_CHARACTER_REFERENCE(2184, /* x f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd35)
+NAMED_CHARACTER_REFERENCE(2185, /* x h */ 'A' _ 'r' _ 'r' _ ';', 4, 0, 0x27fa _ 0)
+NAMED_CHARACTER_REFERENCE(2186, /* x h */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x27f7 _ 0)
+NAMED_CHARACTER_REFERENCE(2187, /* x i */ ';', 1, 0, 0x03be _ 0)
+NAMED_CHARACTER_REFERENCE(2188, /* x l */ 'A' _ 'r' _ 'r' _ ';', 4, 0, 0x27f8 _ 0)
+NAMED_CHARACTER_REFERENCE(2189, /* x l */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x27f5 _ 0)
+NAMED_CHARACTER_REFERENCE(2190, /* x m */ 'a' _ 'p' _ ';', 3, 0, 0x27fc _ 0)
+NAMED_CHARACTER_REFERENCE(2191, /* x n */ 'i' _ 's' _ ';', 3, 0, 0x22fb _ 0)
+NAMED_CHARACTER_REFERENCE(2192, /* x o */ 'd' _ 'o' _ 't' _ ';', 4, 0, 0x2a00 _ 0)
+NAMED_CHARACTER_REFERENCE(2193, /* x o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd69)
+NAMED_CHARACTER_REFERENCE(2194, /* x o */ 'p' _ 'l' _ 'u' _ 's' _ ';', 5, 0, 0x2a01 _ 0)
+NAMED_CHARACTER_REFERENCE(2195, /* x o */ 't' _ 'i' _ 'm' _ 'e' _ ';', 5, 0, 0x2a02 _ 0)
+NAMED_CHARACTER_REFERENCE(2196, /* x r */ 'A' _ 'r' _ 'r' _ ';', 4, 0, 0x27f9 _ 0)
+NAMED_CHARACTER_REFERENCE(2197, /* x r */ 'a' _ 'r' _ 'r' _ ';', 4, 0, 0x27f6 _ 0)
+NAMED_CHARACTER_REFERENCE(2198, /* x s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdccd)
+NAMED_CHARACTER_REFERENCE(2199, /* x s */ 'q' _ 'c' _ 'u' _ 'p' _ ';', 5, 0, 0x2a06 _ 0)
+NAMED_CHARACTER_REFERENCE(2200, /* x u */ 'p' _ 'l' _ 'u' _ 's' _ ';', 5, 0, 0x2a04 _ 0)
+NAMED_CHARACTER_REFERENCE(2201, /* x u */ 't' _ 'r' _ 'i' _ ';', 4, 0, 0x25b3 _ 0)
+NAMED_CHARACTER_REFERENCE(2202, /* x v */ 'e' _ 'e' _ ';', 3, 0, 0x22c1 _ 0)
+NAMED_CHARACTER_REFERENCE(2203, /* x w */ 'e' _ 'd' _ 'g' _ 'e' _ ';', 5, 0, 0x22c0 _ 0)
+NAMED_CHARACTER_REFERENCE(2204, /* y a */ 'c' _ 'u' _ 't' _ 'e', 4, 0, 0x00fd _ 0)
+NAMED_CHARACTER_REFERENCE(2205, /* y a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x00fd _ 0)
+NAMED_CHARACTER_REFERENCE(2206, /* y a */ 'c' _ 'y' _ ';', 3, 0, 0x044f _ 0)
+NAMED_CHARACTER_REFERENCE(2207, /* y c */ 'i' _ 'r' _ 'c' _ ';', 4, 0, 0x0177 _ 0)
+NAMED_CHARACTER_REFERENCE(2208, /* y c */ 'y' _ ';', 2, 0, 0x044b _ 0)
+NAMED_CHARACTER_REFERENCE(2209, /* y e */ 'n', 1, 0, 0x00a5 _ 0)
+NAMED_CHARACTER_REFERENCE(2210, /* y e */ 'n' _ ';', 2, 0, 0x00a5 _ 0)
+NAMED_CHARACTER_REFERENCE(2211, /* y f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd36)
+NAMED_CHARACTER_REFERENCE(2212, /* y i */ 'c' _ 'y' _ ';', 3, 0, 0x0457 _ 0)
+NAMED_CHARACTER_REFERENCE(2213, /* y o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd6a)
+NAMED_CHARACTER_REFERENCE(2214, /* y s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdcce)
+NAMED_CHARACTER_REFERENCE(2215, /* y u */ 'c' _ 'y' _ ';', 3, 0, 0x044e _ 0)
+NAMED_CHARACTER_REFERENCE(2216, /* y u */ 'm' _ 'l', 2, 0, 0x00ff _ 0)
+NAMED_CHARACTER_REFERENCE(2217, /* y u */ 'm' _ 'l' _ ';', 3, 0, 0x00ff _ 0)
+NAMED_CHARACTER_REFERENCE(2218, /* z a */ 'c' _ 'u' _ 't' _ 'e' _ ';', 5, 0, 0x017a _ 0)
+NAMED_CHARACTER_REFERENCE(2219, /* z c */ 'a' _ 'r' _ 'o' _ 'n' _ ';', 5, 0, 0x017e _ 0)
+NAMED_CHARACTER_REFERENCE(2220, /* z c */ 'y' _ ';', 2, 0, 0x0437 _ 0)
+NAMED_CHARACTER_REFERENCE(2221, /* z d */ 'o' _ 't' _ ';', 3, 0, 0x017c _ 0)
+NAMED_CHARACTER_REFERENCE(2222, /* z e */ 'e' _ 't' _ 'r' _ 'f' _ ';', 5, 0, 0x2128 _ 0)
+NAMED_CHARACTER_REFERENCE(2223, /* z e */ 't' _ 'a' _ ';', 3, 0, 0x03b6 _ 0)
+NAMED_CHARACTER_REFERENCE(2224, /* z f */ 'r' _ ';', 2, 0, 0xd835 _ 0xdd37)
+NAMED_CHARACTER_REFERENCE(2225, /* z h */ 'c' _ 'y' _ ';', 3, 0, 0x0436 _ 0)
+NAMED_CHARACTER_REFERENCE(2226, /* z i */ 'g' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 6, 0, 0x21dd _ 0)
+NAMED_CHARACTER_REFERENCE(2227, /* z o */ 'p' _ 'f' _ ';', 3, 0, 0xd835 _ 0xdd6b)
+NAMED_CHARACTER_REFERENCE(2228, /* z s */ 'c' _ 'r' _ ';', 3, 0, 0xd835 _ 0xdccf)
+NAMED_CHARACTER_REFERENCE(2229, /* z w */ 'j' _ ';', 2, 0, 0x200d _ 0)
+NAMED_CHARACTER_REFERENCE(2230, /* z w */ 'n' _ 'j' _ ';', 3, 0, 0x200c _ 0)
+
+#undef _
diff --git a/parser/html/nsHtml5OplessBuilder.cpp b/parser/html/nsHtml5OplessBuilder.cpp
new file mode 100644
index 000000000..ac1c03f10
--- /dev/null
+++ b/parser/html/nsHtml5OplessBuilder.cpp
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 et tw=78: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5OplessBuilder.h"
+
+#include "nsScriptLoader.h"
+#include "mozilla/css/Loader.h"
+#include "nsIDocShell.h"
+#include "nsIHTMLDocument.h"
+
+nsHtml5OplessBuilder::nsHtml5OplessBuilder()
+ : nsHtml5DocumentBuilder(true)
+{
+}
+
+nsHtml5OplessBuilder::~nsHtml5OplessBuilder()
+{
+}
+
+void
+nsHtml5OplessBuilder::Start()
+{
+ mFlushState = eInFlush;
+ BeginDocUpdate();
+}
+
+void
+nsHtml5OplessBuilder::Finish()
+{
+ EndDocUpdate();
+ DropParserAndPerfHint();
+ mScriptLoader = nullptr;
+ mDocument = nullptr;
+ mNodeInfoManager = nullptr;
+ mCSSLoader = nullptr;
+ mDocumentURI = nullptr;
+ mDocShell = nullptr;
+ mOwnedElements.Clear();
+ mFlushState = eNotFlushing;
+}
+
+void
+nsHtml5OplessBuilder::SetParser(nsParserBase* aParser)
+{
+ mParser = aParser;
+}
diff --git a/parser/html/nsHtml5OplessBuilder.h b/parser/html/nsHtml5OplessBuilder.h
new file mode 100644
index 000000000..12d362c68
--- /dev/null
+++ b/parser/html/nsHtml5OplessBuilder.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 et tw=78: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5OplessBuilder_h
+#define nsHtml5OplessBuilder_h
+
+#include "nsHtml5DocumentBuilder.h"
+
+class nsParserBase;
+
+/**
+ * This class implements a minimal subclass of nsHtml5DocumentBuilder that
+ * works when tree operation queues that are part of the off-the-main-thread
+ * parsing machinery are not used and, therefore, nsHtml5TreeOpExecutor is
+ * not used.
+ *
+ * This class is mostly responsible for wrapping tree building in an update
+ * batch and resetting various fields in nsContentSink upon finishing.
+ */
+class nsHtml5OplessBuilder : public nsHtml5DocumentBuilder
+{
+public:
+ NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
+
+ nsHtml5OplessBuilder();
+ ~nsHtml5OplessBuilder();
+ void Start();
+ void Finish();
+ void SetParser(nsParserBase* aParser);
+};
+
+#endif // nsHtml5OplessBuilder_h
diff --git a/parser/html/nsHtml5OwningUTF16Buffer.cpp b/parser/html/nsHtml5OwningUTF16Buffer.cpp
new file mode 100644
index 000000000..213e40209
--- /dev/null
+++ b/parser/html/nsHtml5OwningUTF16Buffer.cpp
@@ -0,0 +1,86 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5OwningUTF16Buffer.h"
+
+nsHtml5OwningUTF16Buffer::nsHtml5OwningUTF16Buffer(char16_t* aBuffer)
+ : nsHtml5UTF16Buffer(aBuffer, 0),
+ next(nullptr),
+ key(nullptr)
+{
+ MOZ_COUNT_CTOR(nsHtml5OwningUTF16Buffer);
+}
+
+nsHtml5OwningUTF16Buffer::nsHtml5OwningUTF16Buffer(void* aKey)
+ : nsHtml5UTF16Buffer(nullptr, 0),
+ next(nullptr),
+ key(aKey)
+{
+ MOZ_COUNT_CTOR(nsHtml5OwningUTF16Buffer);
+}
+
+nsHtml5OwningUTF16Buffer::~nsHtml5OwningUTF16Buffer()
+{
+ MOZ_COUNT_DTOR(nsHtml5OwningUTF16Buffer);
+ DeleteBuffer();
+
+ // This is to avoid dtor recursion on 'next', bug 706932.
+ RefPtr<nsHtml5OwningUTF16Buffer> tail;
+ tail.swap(next);
+ while (tail && tail->mRefCnt == 1) {
+ RefPtr<nsHtml5OwningUTF16Buffer> tmp;
+ tmp.swap(tail->next);
+ tail.swap(tmp);
+ }
+}
+
+// static
+already_AddRefed<nsHtml5OwningUTF16Buffer>
+nsHtml5OwningUTF16Buffer::FalliblyCreate(int32_t aLength)
+{
+ char16_t* newBuf = new (mozilla::fallible) char16_t[aLength];
+ if (!newBuf) {
+ return nullptr;
+ }
+ RefPtr<nsHtml5OwningUTF16Buffer> newObj =
+ new (mozilla::fallible) nsHtml5OwningUTF16Buffer(newBuf);
+ if (!newObj) {
+ delete[] newBuf;
+ return nullptr;
+ }
+ return newObj.forget();
+}
+
+void
+nsHtml5OwningUTF16Buffer::Swap(nsHtml5OwningUTF16Buffer* aOther)
+{
+ nsHtml5UTF16Buffer::Swap(aOther);
+}
+
+
+// Not using macros for AddRef and Release in order to be able to refcount on
+// and create on different threads.
+
+nsrefcnt
+nsHtml5OwningUTF16Buffer::AddRef()
+{
+ NS_PRECONDITION(int32_t(mRefCnt) >= 0, "Illegal refcount.");
+ ++mRefCnt;
+ NS_LOG_ADDREF(this, mRefCnt, "nsHtml5OwningUTF16Buffer", sizeof(*this));
+ return mRefCnt;
+}
+
+nsrefcnt
+nsHtml5OwningUTF16Buffer::Release()
+{
+ NS_PRECONDITION(0 != mRefCnt, "Release without AddRef.");
+ --mRefCnt;
+ NS_LOG_RELEASE(this, mRefCnt, "nsHtml5OwningUTF16Buffer");
+ if (mRefCnt == 0) {
+ mRefCnt = 1; /* stabilize */
+ delete this;
+ return 0;
+ }
+ return mRefCnt;
+}
diff --git a/parser/html/nsHtml5OwningUTF16Buffer.h b/parser/html/nsHtml5OwningUTF16Buffer.h
new file mode 100644
index 000000000..d7e3200ea
--- /dev/null
+++ b/parser/html/nsHtml5OwningUTF16Buffer.h
@@ -0,0 +1,58 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5OwningUTF16Buffer_h
+#define nsHtml5OwningUTF16Buffer_h
+
+#include "nsHtml5UTF16Buffer.h"
+
+class nsHtml5OwningUTF16Buffer : public nsHtml5UTF16Buffer
+{
+ private:
+
+ /**
+ * Passes a buffer and its length to the superclass constructor.
+ */
+ explicit nsHtml5OwningUTF16Buffer(char16_t* aBuffer);
+
+ public:
+
+ /**
+ * Constructor for a parser key placeholder. (No actual buffer.)
+ * @param aKey a parser key
+ */
+ explicit nsHtml5OwningUTF16Buffer(void* aKey);
+
+protected:
+ /**
+ * Takes care of releasing the owned buffer.
+ */
+ ~nsHtml5OwningUTF16Buffer();
+
+public:
+ /**
+ * The next buffer in a queue.
+ */
+ RefPtr<nsHtml5OwningUTF16Buffer> next;
+
+ /**
+ * A parser key.
+ */
+ void* key;
+
+ static already_AddRefed<nsHtml5OwningUTF16Buffer>
+ FalliblyCreate(int32_t aLength);
+
+ /**
+ * Swap start, end and buffer fields with another object.
+ */
+ void Swap(nsHtml5OwningUTF16Buffer* aOther);
+
+ nsrefcnt AddRef();
+ nsrefcnt Release();
+ private:
+ nsAutoRefCnt mRefCnt;
+};
+
+#endif // nsHtml5OwningUTF16Buffer_h
diff --git a/parser/html/nsHtml5Parser.cpp b/parser/html/nsHtml5Parser.cpp
new file mode 100644
index 000000000..e8ca12f89
--- /dev/null
+++ b/parser/html/nsHtml5Parser.cpp
@@ -0,0 +1,754 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=2 et tw=79: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5Parser.h"
+
+#include "mozilla/AutoRestore.h"
+#include "nsContentUtils.h" // for kLoadAsData
+#include "nsHtml5Tokenizer.h"
+#include "nsHtml5TreeBuilder.h"
+#include "nsHtml5AtomTable.h"
+#include "nsHtml5DependentUTF16Buffer.h"
+#include "nsNetUtil.h"
+
+NS_INTERFACE_TABLE_HEAD(nsHtml5Parser)
+ NS_INTERFACE_TABLE(nsHtml5Parser, nsIParser, nsISupportsWeakReference)
+ NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsHtml5Parser)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHtml5Parser)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHtml5Parser)
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsHtml5Parser)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsHtml5Parser)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExecutor)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(GetStreamParser())
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsHtml5Parser)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mExecutor)
+ tmp->DropStreamParser();
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+nsHtml5Parser::nsHtml5Parser()
+ : mFirstBuffer(new nsHtml5OwningUTF16Buffer((void*)nullptr))
+ , mLastBuffer(mFirstBuffer)
+ , mExecutor(new nsHtml5TreeOpExecutor())
+ , mTreeBuilder(new nsHtml5TreeBuilder(mExecutor, nullptr))
+ , mTokenizer(new nsHtml5Tokenizer(mTreeBuilder, false))
+ , mRootContextLineNumber(1)
+{
+ mTokenizer->setInterner(&mAtomTable);
+ // There's a zeroing operator new for everything else
+}
+
+nsHtml5Parser::~nsHtml5Parser()
+{
+ mTokenizer->end();
+ if (mDocWriteSpeculativeTokenizer) {
+ mDocWriteSpeculativeTokenizer->end();
+ }
+}
+
+NS_IMETHODIMP_(void)
+nsHtml5Parser::SetContentSink(nsIContentSink* aSink)
+{
+ NS_ASSERTION(aSink == static_cast<nsIContentSink*> (mExecutor),
+ "Attempt to set a foreign sink.");
+}
+
+NS_IMETHODIMP_(nsIContentSink*)
+nsHtml5Parser::GetContentSink()
+{
+ return static_cast<nsIContentSink*> (mExecutor);
+}
+
+NS_IMETHODIMP_(void)
+nsHtml5Parser::GetCommand(nsCString& aCommand)
+{
+ aCommand.AssignLiteral("view");
+}
+
+NS_IMETHODIMP_(void)
+nsHtml5Parser::SetCommand(const char* aCommand)
+{
+ NS_ASSERTION(!strcmp(aCommand, "view") ||
+ !strcmp(aCommand, "view-source") ||
+ !strcmp(aCommand, "external-resource") ||
+ !strcmp(aCommand, "import") ||
+ !strcmp(aCommand, kLoadAsData),
+ "Unsupported parser command");
+}
+
+NS_IMETHODIMP_(void)
+nsHtml5Parser::SetCommand(eParserCommands aParserCommand)
+{
+ NS_ASSERTION(aParserCommand == eViewNormal,
+ "Parser command was not eViewNormal.");
+}
+
+NS_IMETHODIMP_(void)
+nsHtml5Parser::SetDocumentCharset(const nsACString& aCharset,
+ int32_t aCharsetSource)
+{
+ NS_PRECONDITION(!mExecutor->HasStarted(),
+ "Document charset set too late.");
+ NS_PRECONDITION(GetStreamParser(), "Setting charset on a script-only parser.");
+ nsAutoCString trimmed;
+ trimmed.Assign(aCharset);
+ trimmed.Trim(" \t\r\n\f");
+ GetStreamParser()->SetDocumentCharset(trimmed, aCharsetSource);
+ mExecutor->SetDocumentCharsetAndSource(trimmed,
+ aCharsetSource);
+}
+
+NS_IMETHODIMP
+nsHtml5Parser::GetChannel(nsIChannel** aChannel)
+{
+ if (GetStreamParser()) {
+ return GetStreamParser()->GetChannel(aChannel);
+ } else {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+}
+
+NS_IMETHODIMP
+nsHtml5Parser::GetDTD(nsIDTD** aDTD)
+{
+ *aDTD = nullptr;
+ return NS_OK;
+}
+
+nsIStreamListener*
+nsHtml5Parser::GetStreamListener()
+{
+ return mStreamListener;
+}
+
+NS_IMETHODIMP
+nsHtml5Parser::ContinueInterruptedParsing()
+{
+ NS_NOTREACHED("Don't call. For interface compat only.");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP_(void)
+nsHtml5Parser::BlockParser()
+{
+ mBlocked = true;
+}
+
+NS_IMETHODIMP_(void)
+nsHtml5Parser::UnblockParser()
+{
+ mBlocked = false;
+ mExecutor->ContinueInterruptedParsingAsync();
+}
+
+NS_IMETHODIMP_(void)
+nsHtml5Parser::ContinueInterruptedParsingAsync()
+{
+ mExecutor->ContinueInterruptedParsingAsync();
+}
+
+NS_IMETHODIMP_(bool)
+nsHtml5Parser::IsParserEnabled()
+{
+ return !mBlocked;
+}
+
+NS_IMETHODIMP_(bool)
+nsHtml5Parser::IsComplete()
+{
+ return mExecutor->IsComplete();
+}
+
+NS_IMETHODIMP
+nsHtml5Parser::Parse(nsIURI* aURL,
+ nsIRequestObserver* aObserver,
+ void* aKey, // legacy; ignored
+ nsDTDMode aMode) // legacy; ignored
+{
+ /*
+ * Do NOT cause WillBuildModel to be called synchronously from here!
+ * The document won't be ready for it until OnStartRequest!
+ */
+ NS_PRECONDITION(!mExecutor->HasStarted(),
+ "Tried to start parse without initializing the parser.");
+ NS_PRECONDITION(GetStreamParser(),
+ "Can't call this Parse() variant on script-created parser");
+ GetStreamParser()->SetObserver(aObserver);
+ GetStreamParser()->SetViewSourceTitle(aURL); // In case we're viewing source
+ mExecutor->SetStreamParser(GetStreamParser());
+ mExecutor->SetParser(this);
+ return NS_OK;
+}
+
+nsresult
+nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
+ void* aKey,
+ const nsACString& aContentType,
+ bool aLastCall,
+ nsDTDMode aMode) // ignored
+{
+ nsresult rv;
+ if (NS_FAILED(rv = mExecutor->IsBroken())) {
+ return rv;
+ }
+ if (aSourceBuffer.Length() > INT32_MAX) {
+ return mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
+ }
+
+ // Maintain a reference to ourselves so we don't go away
+ // till we're completely done. The old parser grips itself in this method.
+ nsCOMPtr<nsIParser> kungFuDeathGrip(this);
+
+ // Gripping the other objects just in case, since the other old grip
+ // required grips to these, too.
+ RefPtr<nsHtml5StreamParser> streamKungFuDeathGrip(GetStreamParser());
+ mozilla::Unused << streamKungFuDeathGrip; // Not used within function
+ RefPtr<nsHtml5TreeOpExecutor> executor(mExecutor);
+
+ if (!executor->HasStarted()) {
+ NS_ASSERTION(!GetStreamParser(),
+ "Had stream parser but document.write started life cycle.");
+ // This is the first document.write() on a document.open()ed document
+ executor->SetParser(this);
+ mTreeBuilder->setScriptingEnabled(executor->IsScriptEnabled());
+
+ bool isSrcdoc = false;
+ nsCOMPtr<nsIChannel> channel;
+ rv = GetChannel(getter_AddRefs(channel));
+ if (NS_SUCCEEDED(rv)) {
+ isSrcdoc = NS_IsSrcdocChannel(channel);
+ }
+ mTreeBuilder->setIsSrcdocDocument(isSrcdoc);
+
+ mTokenizer->start();
+ executor->Start();
+ if (!aContentType.EqualsLiteral("text/html")) {
+ mTreeBuilder->StartPlainText();
+ mTokenizer->StartPlainText();
+ }
+ /*
+ * If you move the following line, be very careful not to cause
+ * WillBuildModel to be called before the document has had its
+ * script global object set.
+ */
+ rv = executor->WillBuildModel(eDTDMode_unknown);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // Return early if the parser has processed EOF
+ if (executor->IsComplete()) {
+ return NS_OK;
+ }
+
+ if (aLastCall && aSourceBuffer.IsEmpty() && !aKey) {
+ // document.close()
+ NS_ASSERTION(!GetStreamParser(),
+ "Had stream parser but got document.close().");
+ if (mDocumentClosed) {
+ // already closed
+ return NS_OK;
+ }
+ mDocumentClosed = true;
+ if (!mBlocked && !mInDocumentWrite) {
+ return ParseUntilBlocked();
+ }
+ return NS_OK;
+ }
+
+ // If we got this far, we are dealing with a document.write or
+ // document.writeln call--not document.close().
+
+ NS_ASSERTION(IsInsertionPointDefined(),
+ "Doc.write reached parser with undefined insertion point.");
+
+ NS_ASSERTION(!(GetStreamParser() && !aKey),
+ "Got a null key in a non-script-created parser");
+
+ // XXX is this optimization bogus?
+ if (aSourceBuffer.IsEmpty()) {
+ return NS_OK;
+ }
+
+ // This guard is here to prevent document.close from tokenizing synchronously
+ // while a document.write (that wrote the script that called document.close!)
+ // is still on the call stack.
+ mozilla::AutoRestore<bool> guard(mInDocumentWrite);
+ mInDocumentWrite = true;
+
+ // The script is identified by aKey. If there's nothing in the buffer
+ // chain for that key, we'll insert at the head of the queue.
+ // When the script leaves something in the queue, a zero-length
+ // key-holder "buffer" is inserted in the queue. If the same script
+ // leaves something in the chain again, it will be inserted immediately
+ // before the old key holder belonging to the same script.
+ //
+ // We don't do the actual data insertion yet in the hope that the data gets
+ // tokenized and there no data or less data to copy to the heap after
+ // tokenization. Also, this way, we avoid inserting one empty data buffer
+ // per document.write, which matters for performance when the parser isn't
+ // blocked and a badly-authored script calls document.write() once per
+ // input character. (As seen in a benchmark!)
+ //
+ // The insertion into the input stream happens conceptually before anything
+ // gets tokenized. To make sure multi-level document.write works right,
+ // it's necessary to establish the location of our parser key up front
+ // in case this is the first write with this key.
+ //
+ // In a document.open() case, the first write level has a null key, so that
+ // case is handled separately, because normal buffers containing data
+ // have null keys.
+
+ // These don't need to be owning references, because they always point to
+ // the buffer queue and buffers can't be removed from the buffer queue
+ // before document.write() returns. The buffer queue clean-up happens the
+ // next time ParseUntilBlocked() is called.
+ // However, they are made owning just in case the reasoning above is flawed
+ // and a flaw would lead to worse problems with plain pointers. If this
+ // turns out to be a perf problem, it's worthwhile to consider making
+ // prevSearchbuf a plain pointer again.
+ RefPtr<nsHtml5OwningUTF16Buffer> prevSearchBuf;
+ RefPtr<nsHtml5OwningUTF16Buffer> firstLevelMarker;
+
+ if (aKey) {
+ if (mFirstBuffer == mLastBuffer) {
+ nsHtml5OwningUTF16Buffer* keyHolder = new nsHtml5OwningUTF16Buffer(aKey);
+ keyHolder->next = mLastBuffer;
+ mFirstBuffer = keyHolder;
+ } else if (mFirstBuffer->key != aKey) {
+ prevSearchBuf = mFirstBuffer;
+ for (;;) {
+ if (prevSearchBuf->next == mLastBuffer) {
+ // key was not found
+ nsHtml5OwningUTF16Buffer* keyHolder =
+ new nsHtml5OwningUTF16Buffer(aKey);
+ keyHolder->next = mFirstBuffer;
+ mFirstBuffer = keyHolder;
+ prevSearchBuf = nullptr;
+ break;
+ }
+ if (prevSearchBuf->next->key == aKey) {
+ // found a key holder
+ break;
+ }
+ prevSearchBuf = prevSearchBuf->next;
+ }
+ } // else mFirstBuffer is the keyholder
+
+ // prevSearchBuf is the previous buffer before the keyholder or null if
+ // there isn't one.
+ } else {
+ // We have a first-level write in the document.open() case. We insert before
+ // mLastBuffer, effectively, by making mLastBuffer be a new sentinel object
+ // and redesignating the previous mLastBuffer as our firstLevelMarker. We
+ // need to put a marker there, because otherwise additional document.writes
+ // from nested event loops would insert in the wrong place. Sigh.
+ mLastBuffer->next = new nsHtml5OwningUTF16Buffer((void*)nullptr);
+ firstLevelMarker = mLastBuffer;
+ mLastBuffer = mLastBuffer->next;
+ }
+
+ nsHtml5DependentUTF16Buffer stackBuffer(aSourceBuffer);
+
+ while (!mBlocked && stackBuffer.hasMore()) {
+ stackBuffer.adjust(mLastWasCR);
+ mLastWasCR = false;
+ if (stackBuffer.hasMore()) {
+ int32_t lineNumberSave;
+ bool inRootContext = (!GetStreamParser() && !aKey);
+ if (inRootContext) {
+ mTokenizer->setLineNumber(mRootContextLineNumber);
+ } else {
+ // we aren't the root context, so save the line number on the
+ // *stack* so that we can restore it.
+ lineNumberSave = mTokenizer->getLineNumber();
+ }
+
+ if (!mTokenizer->EnsureBufferSpace(stackBuffer.getLength())) {
+ return executor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
+ }
+ mLastWasCR = mTokenizer->tokenizeBuffer(&stackBuffer);
+ if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
+ return executor->MarkAsBroken(rv);
+ }
+
+ if (inRootContext) {
+ mRootContextLineNumber = mTokenizer->getLineNumber();
+ } else {
+ mTokenizer->setLineNumber(lineNumberSave);
+ }
+
+ if (mTreeBuilder->HasScript()) {
+ mTreeBuilder->Flush(); // Move ops to the executor
+ rv = executor->FlushDocumentWrite(); // run the ops
+ NS_ENSURE_SUCCESS(rv, rv);
+ // Flushing tree ops can cause all sorts of things.
+ // Return early if the parser got terminated.
+ if (executor->IsComplete()) {
+ return NS_OK;
+ }
+ }
+ // Ignore suspension requests
+ }
+ }
+
+ RefPtr<nsHtml5OwningUTF16Buffer> heapBuffer;
+ if (stackBuffer.hasMore()) {
+ // The buffer wasn't tokenized to completion. Create a copy of the tail
+ // on the heap.
+ heapBuffer = stackBuffer.FalliblyCopyAsOwningBuffer();
+ if (!heapBuffer) {
+ // Allocation failed. The parser is now broken.
+ return executor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
+ }
+ }
+
+ if (heapBuffer) {
+ // We have something to insert before the keyholder holding in the non-null
+ // aKey case and we have something to swap into firstLevelMarker in the
+ // null aKey case.
+ if (aKey) {
+ NS_ASSERTION(mFirstBuffer != mLastBuffer,
+ "Where's the keyholder?");
+ // the key holder is still somewhere further down the list from
+ // prevSearchBuf (which may be null)
+ if (mFirstBuffer->key == aKey) {
+ NS_ASSERTION(!prevSearchBuf,
+ "Non-null prevSearchBuf when mFirstBuffer is the key holder?");
+ heapBuffer->next = mFirstBuffer;
+ mFirstBuffer = heapBuffer;
+ } else {
+ if (!prevSearchBuf) {
+ prevSearchBuf = mFirstBuffer;
+ }
+ // We created a key holder earlier, so we will find it without walking
+ // past the end of the list.
+ while (prevSearchBuf->next->key != aKey) {
+ prevSearchBuf = prevSearchBuf->next;
+ }
+ heapBuffer->next = prevSearchBuf->next;
+ prevSearchBuf->next = heapBuffer;
+ }
+ } else {
+ NS_ASSERTION(firstLevelMarker, "How come we don't have a marker.");
+ firstLevelMarker->Swap(heapBuffer);
+ }
+ }
+
+ if (!mBlocked) { // buffer was tokenized to completion
+ NS_ASSERTION(!stackBuffer.hasMore(),
+ "Buffer wasn't tokenized to completion?");
+ // Scripting semantics require a forced tree builder flush here
+ mTreeBuilder->Flush(); // Move ops to the executor
+ rv = executor->FlushDocumentWrite(); // run the ops
+ NS_ENSURE_SUCCESS(rv, rv);
+ } else if (stackBuffer.hasMore()) {
+ // The buffer wasn't tokenized to completion. Tokenize the untokenized
+ // content in order to preload stuff. This content will be retokenized
+ // later for normal parsing.
+ if (!mDocWriteSpeculatorActive) {
+ mDocWriteSpeculatorActive = true;
+ if (!mDocWriteSpeculativeTreeBuilder) {
+ // Lazily initialize if uninitialized
+ mDocWriteSpeculativeTreeBuilder =
+ new nsHtml5TreeBuilder(nullptr, executor->GetStage());
+ mDocWriteSpeculativeTreeBuilder->setScriptingEnabled(
+ mTreeBuilder->isScriptingEnabled());
+ mDocWriteSpeculativeTokenizer =
+ new nsHtml5Tokenizer(mDocWriteSpeculativeTreeBuilder, false);
+ mDocWriteSpeculativeTokenizer->setInterner(&mAtomTable);
+ mDocWriteSpeculativeTokenizer->start();
+ }
+ mDocWriteSpeculativeTokenizer->resetToDataState();
+ mDocWriteSpeculativeTreeBuilder->loadState(mTreeBuilder, &mAtomTable);
+ mDocWriteSpeculativeLastWasCR = false;
+ }
+
+ // Note that with multilevel document.write if we didn't just activate the
+ // speculator, it's possible that the speculator is now in the wrong state.
+ // That's OK for the sake of simplicity. The worst that can happen is
+ // that the speculative loads aren't exactly right. The content will be
+ // reparsed anyway for non-preload purposes.
+
+ // The buffer position for subsequent non-speculative parsing now lives
+ // in heapBuffer, so it's ok to let the buffer position of stackBuffer
+ // to be overwritten and not restored below.
+ while (stackBuffer.hasMore()) {
+ stackBuffer.adjust(mDocWriteSpeculativeLastWasCR);
+ if (stackBuffer.hasMore()) {
+ if (!mDocWriteSpeculativeTokenizer->EnsureBufferSpace(
+ stackBuffer.getLength())) {
+ return executor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
+ }
+ mDocWriteSpeculativeLastWasCR =
+ mDocWriteSpeculativeTokenizer->tokenizeBuffer(&stackBuffer);
+ nsresult rv;
+ if (NS_FAILED((rv = mDocWriteSpeculativeTreeBuilder->IsBroken()))) {
+ return executor->MarkAsBroken(rv);
+ }
+ }
+ }
+
+ mDocWriteSpeculativeTreeBuilder->Flush();
+ mDocWriteSpeculativeTreeBuilder->DropHandles();
+ executor->FlushSpeculativeLoads();
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHtml5Parser::Terminate()
+{
+ // We should only call DidBuildModel once, so don't do anything if this is
+ // the second time that Terminate has been called.
+ if (mExecutor->IsComplete()) {
+ return NS_OK;
+ }
+ // XXX - [ until we figure out a way to break parser-sink circularity ]
+ // Hack - Hold a reference until we are completely done...
+ nsCOMPtr<nsIParser> kungFuDeathGrip(this);
+ RefPtr<nsHtml5StreamParser> streamParser(GetStreamParser());
+ RefPtr<nsHtml5TreeOpExecutor> executor(mExecutor);
+ if (streamParser) {
+ streamParser->Terminate();
+ }
+ return executor->DidBuildModel(true);
+}
+
+NS_IMETHODIMP
+nsHtml5Parser::ParseFragment(const nsAString& aSourceBuffer,
+ nsTArray<nsString>& aTagStack)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsHtml5Parser::BuildModel()
+{
+ NS_NOTREACHED("Don't call this!");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsHtml5Parser::CancelParsingEvents()
+{
+ NS_NOTREACHED("Don't call this!");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+void
+nsHtml5Parser::Reset()
+{
+ NS_NOTREACHED("Don't call this!");
+}
+
+bool
+nsHtml5Parser::IsInsertionPointDefined()
+{
+ return !mExecutor->IsFlushing() &&
+ (!GetStreamParser() || mInsertionPointPushLevel);
+}
+
+void
+nsHtml5Parser::PushDefinedInsertionPoint()
+{
+ ++mInsertionPointPushLevel;
+}
+
+void
+nsHtml5Parser::PopDefinedInsertionPoint()
+{
+ --mInsertionPointPushLevel;
+}
+
+void
+nsHtml5Parser::MarkAsNotScriptCreated(const char* aCommand)
+{
+ NS_PRECONDITION(!mStreamListener, "Must not call this twice.");
+ eParserMode mode = NORMAL;
+ if (!nsCRT::strcmp(aCommand, "view-source")) {
+ mode = VIEW_SOURCE_HTML;
+ } else if (!nsCRT::strcmp(aCommand, "view-source-xml")) {
+ mode = VIEW_SOURCE_XML;
+ } else if (!nsCRT::strcmp(aCommand, "view-source-plain")) {
+ mode = VIEW_SOURCE_PLAIN;
+ } else if (!nsCRT::strcmp(aCommand, "plain-text")) {
+ mode = PLAIN_TEXT;
+ } else if (!nsCRT::strcmp(aCommand, kLoadAsData)) {
+ mode = LOAD_AS_DATA;
+ }
+#ifdef DEBUG
+ else {
+ NS_ASSERTION(!nsCRT::strcmp(aCommand, "view") ||
+ !nsCRT::strcmp(aCommand, "external-resource") ||
+ !nsCRT::strcmp(aCommand, "import"),
+ "Unsupported parser command!");
+ }
+#endif
+ mStreamListener =
+ new nsHtml5StreamListener(new nsHtml5StreamParser(mExecutor, this, mode));
+}
+
+bool
+nsHtml5Parser::IsScriptCreated()
+{
+ return !GetStreamParser();
+}
+
+/* End nsIParser */
+
+// not from interface
+nsresult
+nsHtml5Parser::ParseUntilBlocked()
+{
+ nsresult rv = mExecutor->IsBroken();
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (mBlocked || mExecutor->IsComplete()) {
+ return NS_OK;
+ }
+ NS_ASSERTION(mExecutor->HasStarted(), "Bad life cycle.");
+ NS_ASSERTION(!mInDocumentWrite,
+ "ParseUntilBlocked entered while in doc.write!");
+
+ mDocWriteSpeculatorActive = false;
+
+ for (;;) {
+ if (!mFirstBuffer->hasMore()) {
+ if (mFirstBuffer == mLastBuffer) {
+ if (mExecutor->IsComplete()) {
+ // something like cache manisfests stopped the parse in mid-flight
+ return NS_OK;
+ }
+ if (mDocumentClosed) {
+ nsresult rv;
+ NS_ASSERTION(!GetStreamParser(),
+ "This should only happen with script-created parser.");
+ if (NS_SUCCEEDED((rv = mExecutor->IsBroken()))) {
+ mTokenizer->eof();
+ if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
+ mExecutor->MarkAsBroken(rv);
+ } else {
+ mTreeBuilder->StreamEnded();
+ }
+ }
+ mTreeBuilder->Flush();
+ mExecutor->FlushDocumentWrite();
+ // The below call does memory cleanup, so call it even if the
+ // parser has been marked as broken.
+ mTokenizer->end();
+ return rv;
+ }
+ // never release the last buffer.
+ NS_ASSERTION(!mLastBuffer->getStart() && !mLastBuffer->getEnd(),
+ "Sentinel buffer had its indeces changed.");
+ if (GetStreamParser()) {
+ if (mReturnToStreamParserPermitted &&
+ !mExecutor->IsScriptExecuting()) {
+ mTreeBuilder->Flush();
+ mReturnToStreamParserPermitted = false;
+ GetStreamParser()->ContinueAfterScripts(mTokenizer,
+ mTreeBuilder,
+ mLastWasCR);
+ }
+ } else {
+ // Script-created parser
+ mTreeBuilder->Flush();
+ // No need to flush the executor, because the executor is already
+ // in a flush
+ NS_ASSERTION(mExecutor->IsInFlushLoop(),
+ "How did we come here without being in the flush loop?");
+ }
+ return NS_OK; // no more data for now but expecting more
+ }
+ mFirstBuffer = mFirstBuffer->next;
+ continue;
+ }
+
+ if (mBlocked || mExecutor->IsComplete()) {
+ return NS_OK;
+ }
+
+ // now we have a non-empty buffer
+ mFirstBuffer->adjust(mLastWasCR);
+ mLastWasCR = false;
+ if (mFirstBuffer->hasMore()) {
+ bool inRootContext = (!GetStreamParser() && !mFirstBuffer->key);
+ if (inRootContext) {
+ mTokenizer->setLineNumber(mRootContextLineNumber);
+ }
+ if (!mTokenizer->EnsureBufferSpace(mFirstBuffer->getLength())) {
+ return mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
+ }
+ mLastWasCR = mTokenizer->tokenizeBuffer(mFirstBuffer);
+ nsresult rv;
+ if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
+ return mExecutor->MarkAsBroken(rv);
+ }
+ if (inRootContext) {
+ mRootContextLineNumber = mTokenizer->getLineNumber();
+ }
+ if (mTreeBuilder->HasScript()) {
+ mTreeBuilder->Flush();
+ rv = mExecutor->FlushDocumentWrite();
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ if (mBlocked) {
+ return NS_OK;
+ }
+ }
+ continue;
+ }
+}
+
+nsresult
+nsHtml5Parser::Initialize(nsIDocument* aDoc,
+ nsIURI* aURI,
+ nsISupports* aContainer,
+ nsIChannel* aChannel)
+{
+ return mExecutor->Init(aDoc, aURI, aContainer, aChannel);
+}
+
+void
+nsHtml5Parser::StartTokenizer(bool aScriptingEnabled) {
+
+ bool isSrcdoc = false;
+ nsCOMPtr<nsIChannel> channel;
+ nsresult rv = GetChannel(getter_AddRefs(channel));
+ if (NS_SUCCEEDED(rv)) {
+ isSrcdoc = NS_IsSrcdocChannel(channel);
+ }
+ mTreeBuilder->setIsSrcdocDocument(isSrcdoc);
+
+ mTreeBuilder->SetPreventScriptExecution(!aScriptingEnabled);
+ mTreeBuilder->setScriptingEnabled(aScriptingEnabled);
+ mTokenizer->start();
+}
+
+void
+nsHtml5Parser::InitializeDocWriteParserState(nsAHtml5TreeBuilderState* aState,
+ int32_t aLine)
+{
+ mTokenizer->resetToDataState();
+ mTokenizer->setLineNumber(aLine);
+ mTreeBuilder->loadState(aState, &mAtomTable);
+ mLastWasCR = false;
+ mReturnToStreamParserPermitted = true;
+}
+
+void
+nsHtml5Parser::ContinueAfterFailedCharsetSwitch()
+{
+ NS_PRECONDITION(GetStreamParser(),
+ "Tried to continue after failed charset switch without a stream parser");
+ GetStreamParser()->ContinueAfterFailedCharsetSwitch();
+}
+
diff --git a/parser/html/nsHtml5Parser.h b/parser/html/nsHtml5Parser.h
new file mode 100644
index 000000000..9d88adb29
--- /dev/null
+++ b/parser/html/nsHtml5Parser.h
@@ -0,0 +1,362 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef NS_HTML5_PARSER
+#define NS_HTML5_PARSER
+
+#include "nsAutoPtr.h"
+#include "nsIParser.h"
+#include "nsDeque.h"
+#include "nsIURL.h"
+#include "nsParserCIID.h"
+#include "nsITokenizer.h"
+#include "nsIContentSink.h"
+#include "nsIRequest.h"
+#include "nsIChannel.h"
+#include "nsCOMArray.h"
+#include "nsContentSink.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsIInputStream.h"
+#include "nsDetectionConfident.h"
+#include "nsHtml5OwningUTF16Buffer.h"
+#include "nsHtml5TreeOpExecutor.h"
+#include "nsHtml5StreamParser.h"
+#include "nsHtml5AtomTable.h"
+#include "nsWeakReference.h"
+#include "nsHtml5StreamListener.h"
+
+class nsHtml5Parser final : public nsIParser,
+ public nsSupportsWeakReference
+{
+ public:
+ NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsHtml5Parser, nsIParser)
+
+ nsHtml5Parser();
+
+ /* Start nsIParser */
+ /**
+ * No-op for backwards compat.
+ */
+ NS_IMETHOD_(void) SetContentSink(nsIContentSink* aSink) override;
+
+ /**
+ * Returns the tree op executor for backwards compat.
+ */
+ NS_IMETHOD_(nsIContentSink*) GetContentSink() override;
+
+ /**
+ * Always returns "view" for backwards compat.
+ */
+ NS_IMETHOD_(void) GetCommand(nsCString& aCommand) override;
+
+ /**
+ * No-op for backwards compat.
+ */
+ NS_IMETHOD_(void) SetCommand(const char* aCommand) override;
+
+ /**
+ * No-op for backwards compat.
+ */
+ NS_IMETHOD_(void) SetCommand(eParserCommands aParserCommand) override;
+
+ /**
+ * Call this method once you've created a parser, and want to instruct it
+ * about what charset to load
+ *
+ * @param aCharset the charset of a document
+ * @param aCharsetSource the source of the charset
+ */
+ NS_IMETHOD_(void) SetDocumentCharset(const nsACString& aCharset, int32_t aSource) override;
+
+ /**
+ * Don't call. For interface compat only.
+ */
+ NS_IMETHOD_(void) GetDocumentCharset(nsACString& aCharset, int32_t& aSource) override
+ {
+ NS_NOTREACHED("No one should call this.");
+ }
+
+ /**
+ * Get the channel associated with this parser
+ * @param aChannel out param that will contain the result
+ * @return NS_OK if successful or NS_NOT_AVAILABLE if not
+ */
+ NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
+
+ /**
+ * Return |this| for backwards compat.
+ */
+ NS_IMETHOD GetDTD(nsIDTD** aDTD) override;
+
+ /**
+ * Get the stream parser for this parser
+ */
+ virtual nsIStreamListener* GetStreamListener() override;
+
+ /**
+ * Don't call. For interface compat only.
+ */
+ NS_IMETHOD ContinueInterruptedParsing() override;
+
+ /**
+ * Blocks the parser.
+ */
+ NS_IMETHOD_(void) BlockParser() override;
+
+ /**
+ * Unblocks the parser.
+ */
+ NS_IMETHOD_(void) UnblockParser() override;
+
+ /**
+ * Asynchronously continues parsing.
+ */
+ NS_IMETHOD_(void) ContinueInterruptedParsingAsync() override;
+
+ /**
+ * Query whether the parser is enabled (i.e. not blocked) or not.
+ */
+ NS_IMETHOD_(bool) IsParserEnabled() override;
+
+ /**
+ * Query whether the parser thinks it's done with parsing.
+ */
+ NS_IMETHOD_(bool) IsComplete() override;
+
+ /**
+ * Set up request observer.
+ *
+ * @param aURL used for View Source title
+ * @param aListener a listener to forward notifications to
+ * @param aKey the root context key (used for document.write)
+ * @param aMode ignored (for interface compat only)
+ */
+ NS_IMETHOD Parse(nsIURI* aURL,
+ nsIRequestObserver* aListener = nullptr,
+ void* aKey = 0,
+ nsDTDMode aMode = eDTDMode_autodetect) override;
+
+ /**
+ * document.write and document.close
+ *
+ * @param aSourceBuffer the argument of document.write (empty for .close())
+ * @param aKey a key unique to the script element that caused this call
+ * @param aContentType "text/html" for HTML mode, else text/plain mode
+ * @param aLastCall true if .close() false if .write()
+ * @param aMode ignored (for interface compat only)
+ */
+ nsresult Parse(const nsAString& aSourceBuffer,
+ void* aKey,
+ const nsACString& aContentType,
+ bool aLastCall,
+ nsDTDMode aMode = eDTDMode_autodetect);
+
+ /**
+ * Stops the parser prematurely
+ */
+ NS_IMETHOD Terminate() override;
+
+ /**
+ * Don't call. For interface backwards compat only.
+ */
+ NS_IMETHOD ParseFragment(const nsAString& aSourceBuffer,
+ nsTArray<nsString>& aTagStack) override;
+
+ /**
+ * Don't call. For interface compat only.
+ */
+ NS_IMETHOD BuildModel() override;
+
+ /**
+ * Don't call. For interface compat only.
+ */
+ NS_IMETHOD CancelParsingEvents() override;
+
+ /**
+ * Don't call. For interface compat only.
+ */
+ virtual void Reset() override;
+
+ /**
+ * True if the insertion point (per HTML5) is defined.
+ */
+ virtual bool IsInsertionPointDefined() override;
+
+ /**
+ * Call immediately before starting to evaluate a parser-inserted script or
+ * in general when the spec says to define an insertion point.
+ */
+ virtual void PushDefinedInsertionPoint() override;
+
+ /**
+ * Call immediately after having evaluated a parser-inserted script or
+ * generally want to restore to the state before the last
+ * PushDefinedInsertionPoint call.
+ */
+ virtual void PopDefinedInsertionPoint() override;
+
+ /**
+ * Marks the HTML5 parser as not a script-created parser: Prepares the
+ * parser to be able to read a stream.
+ *
+ * @param aCommand the parser command (Yeah, this is bad API design. Let's
+ * make this better when retiring nsIParser)
+ */
+ virtual void MarkAsNotScriptCreated(const char* aCommand) override;
+
+ /**
+ * True if this is a script-created HTML5 parser.
+ */
+ virtual bool IsScriptCreated() override;
+
+ /* End nsIParser */
+
+ // Not from an external interface
+ // Non-inherited methods
+
+ public:
+
+ /**
+ * Initializes the parser to load from a channel.
+ */
+ virtual nsresult Initialize(nsIDocument* aDoc,
+ nsIURI* aURI,
+ nsISupports* aContainer,
+ nsIChannel* aChannel);
+
+ inline nsHtml5Tokenizer* GetTokenizer() {
+ return mTokenizer;
+ }
+
+ void InitializeDocWriteParserState(nsAHtml5TreeBuilderState* aState, int32_t aLine);
+
+ void DropStreamParser()
+ {
+ if (GetStreamParser()) {
+ GetStreamParser()->DropTimer();
+ mStreamListener->DropDelegate();
+ mStreamListener = nullptr;
+ }
+ }
+
+ void StartTokenizer(bool aScriptingEnabled);
+
+ void ContinueAfterFailedCharsetSwitch();
+
+ nsHtml5StreamParser* GetStreamParser()
+ {
+ if (!mStreamListener) {
+ return nullptr;
+ }
+ return mStreamListener->GetDelegate();
+ }
+
+ /**
+ * Parse until pending data is exhausted or a script blocks the parser
+ */
+ nsresult ParseUntilBlocked();
+
+ private:
+
+ virtual ~nsHtml5Parser();
+
+ // State variables
+
+ /**
+ * Whether the last character tokenized was a carriage return (for CRLF)
+ */
+ bool mLastWasCR;
+
+ /**
+ * Whether the last character tokenized was a carriage return (for CRLF)
+ * when preparsing document.write.
+ */
+ bool mDocWriteSpeculativeLastWasCR;
+
+ /**
+ * The parser is blocking on a script
+ */
+ bool mBlocked;
+
+ /**
+ * Whether the document.write() speculator is already active.
+ */
+ bool mDocWriteSpeculatorActive;
+
+ /**
+ * The number of PushDefinedInsertionPoint calls we've seen without a
+ * matching PopDefinedInsertionPoint.
+ */
+ int32_t mInsertionPointPushLevel;
+
+ /**
+ * True if document.close() has been called.
+ */
+ bool mDocumentClosed;
+
+ bool mInDocumentWrite;
+
+ // Portable parser objects
+ /**
+ * The first buffer in the pending UTF-16 buffer queue
+ */
+ RefPtr<nsHtml5OwningUTF16Buffer> mFirstBuffer;
+
+ /**
+ * The last buffer in the pending UTF-16 buffer queue. Always points
+ * to a sentinel object with nullptr as its parser key.
+ */
+ nsHtml5OwningUTF16Buffer* mLastBuffer; // weak ref;
+
+ /**
+ * The tree operation executor
+ */
+ RefPtr<nsHtml5TreeOpExecutor> mExecutor;
+
+ /**
+ * The HTML5 tree builder
+ */
+ const nsAutoPtr<nsHtml5TreeBuilder> mTreeBuilder;
+
+ /**
+ * The HTML5 tokenizer
+ */
+ const nsAutoPtr<nsHtml5Tokenizer> mTokenizer;
+
+ /**
+ * Another HTML5 tree builder for preloading document.written content.
+ */
+ nsAutoPtr<nsHtml5TreeBuilder> mDocWriteSpeculativeTreeBuilder;
+
+ /**
+ * Another HTML5 tokenizer for preloading document.written content.
+ */
+ nsAutoPtr<nsHtml5Tokenizer> mDocWriteSpeculativeTokenizer;
+
+ /**
+ * The stream listener holding the stream parser.
+ */
+ RefPtr<nsHtml5StreamListener> mStreamListener;
+
+ /**
+ *
+ */
+ int32_t mRootContextLineNumber;
+
+ /**
+ * Whether it's OK to transfer parsing back to the stream parser
+ */
+ bool mReturnToStreamParserPermitted;
+
+ /**
+ * The scoped atom table
+ */
+ nsHtml5AtomTable mAtomTable;
+
+};
+#endif
diff --git a/parser/html/nsHtml5PlainTextUtils.cpp b/parser/html/nsHtml5PlainTextUtils.cpp
new file mode 100644
index 000000000..4f0eab81b
--- /dev/null
+++ b/parser/html/nsHtml5PlainTextUtils.cpp
@@ -0,0 +1,40 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+#include "nsHtml5PlainTextUtils.h"
+#include "nsHtml5AttributeName.h"
+#include "nsIServiceManager.h"
+#include "nsIStringBundle.h"
+#include "mozilla/Preferences.h"
+
+// static
+nsHtml5HtmlAttributes*
+nsHtml5PlainTextUtils::NewLinkAttributes()
+{
+ nsHtml5HtmlAttributes* linkAttrs = new nsHtml5HtmlAttributes(0);
+ nsString* rel = new nsString(NS_LITERAL_STRING("alternate stylesheet"));
+ linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_REL, rel, -1);
+ nsString* type = new nsString(NS_LITERAL_STRING("text/css"));
+ linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TYPE, type, -1);
+ nsString* href = new nsString(
+ NS_LITERAL_STRING("resource://gre-resources/plaintext.css"));
+ linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_HREF, href, -1);
+
+ nsresult rv;
+ nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
+ NS_ASSERTION(NS_SUCCEEDED(rv) && bundleService, "The bundle service could not be loaded");
+ nsCOMPtr<nsIStringBundle> bundle;
+ rv = bundleService->CreateBundle("chrome://global/locale/browser.properties",
+ getter_AddRefs(bundle));
+ NS_ASSERTION(NS_SUCCEEDED(rv) && bundle, "chrome://global/locale/browser.properties could not be loaded");
+ nsXPIDLString title;
+ if (bundle) {
+ bundle->GetStringFromName(u"plainText.wordWrap", getter_Copies(title));
+ }
+
+ nsString* titleCopy = new nsString(title);
+ linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TITLE, titleCopy, -1);
+ return linkAttrs;
+}
diff --git a/parser/html/nsHtml5PlainTextUtils.h b/parser/html/nsHtml5PlainTextUtils.h
new file mode 100644
index 000000000..997702cff
--- /dev/null
+++ b/parser/html/nsHtml5PlainTextUtils.h
@@ -0,0 +1,16 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5PlainTextUtils_h
+#define nsHtml5PlainTextUtils_h
+
+#include "nsHtml5HtmlAttributes.h"
+
+class nsHtml5PlainTextUtils
+{
+ public:
+ static nsHtml5HtmlAttributes* NewLinkAttributes();
+};
+
+#endif // nsHtml5PlainTextUtils_h
diff --git a/parser/html/nsHtml5Portability.cpp b/parser/html/nsHtml5Portability.cpp
new file mode 100644
index 000000000..36c7e758a
--- /dev/null
+++ b/parser/html/nsHtml5Portability.cpp
@@ -0,0 +1,157 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIAtom.h"
+#include "nsString.h"
+#include "jArray.h"
+#include "nsHtml5Portability.h"
+#include "nsHtml5TreeBuilder.h"
+
+nsIAtom*
+nsHtml5Portability::newLocalNameFromBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5AtomTable* interner)
+{
+ NS_ASSERTION(!offset, "The offset should always be zero here.");
+ NS_ASSERTION(interner, "Didn't get an atom service.");
+ return interner->GetAtom(nsDependentSubstring(buf, buf + length));
+}
+
+nsString*
+nsHtml5Portability::newStringFromBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5TreeBuilder* treeBuilder)
+{
+ nsString* str = new nsString();
+ bool succeeded = str->Append(buf + offset, length, mozilla::fallible);
+ if (!succeeded) {
+ str->Assign(char16_t(0xFFFD));
+ treeBuilder->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
+ }
+ return str;
+}
+
+nsString*
+nsHtml5Portability::newEmptyString()
+{
+ return new nsString();
+}
+
+nsString*
+nsHtml5Portability::newStringFromLiteral(const char* literal)
+{
+ nsString* str = new nsString();
+ str->AssignASCII(literal);
+ return str;
+}
+
+nsString*
+nsHtml5Portability::newStringFromString(nsString* string) {
+ nsString* newStr = new nsString();
+ newStr->Assign(*string);
+ return newStr;
+}
+
+jArray<char16_t,int32_t>
+nsHtml5Portability::newCharArrayFromLocal(nsIAtom* local)
+{
+ nsAutoString temp;
+ local->ToString(temp);
+ int32_t len = temp.Length();
+ jArray<char16_t,int32_t> arr = jArray<char16_t,int32_t>::newJArray(len);
+ memcpy(arr, temp.BeginReading(), len * sizeof(char16_t));
+ return arr;
+}
+
+jArray<char16_t,int32_t>
+nsHtml5Portability::newCharArrayFromString(nsString* string)
+{
+ int32_t len = string->Length();
+ jArray<char16_t,int32_t> arr = jArray<char16_t,int32_t>::newJArray(len);
+ memcpy(arr, string->BeginReading(), len * sizeof(char16_t));
+ return arr;
+}
+
+nsIAtom*
+nsHtml5Portability::newLocalFromLocal(nsIAtom* local, nsHtml5AtomTable* interner)
+{
+ NS_PRECONDITION(local, "Atom was null.");
+ NS_PRECONDITION(interner, "Atom table was null");
+ if (!local->IsStaticAtom()) {
+ nsAutoString str;
+ local->ToString(str);
+ local = interner->GetAtom(str);
+ }
+ return local;
+}
+
+void
+nsHtml5Portability::releaseString(nsString* str)
+{
+ delete str;
+}
+
+bool
+nsHtml5Portability::localEqualsBuffer(nsIAtom* local, char16_t* buf, int32_t offset, int32_t length)
+{
+ return local->Equals(nsDependentSubstring(buf + offset, buf + offset + length));
+}
+
+bool
+nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string)
+{
+ if (!string) {
+ return false;
+ }
+ const char* litPtr = lowerCaseLiteral;
+ const char16_t* strPtr = string->BeginReading();
+ const char16_t* end = string->EndReading();
+ char16_t litChar;
+ while ((litChar = *litPtr)) {
+ NS_ASSERTION(!(litChar >= 'A' && litChar <= 'Z'), "Literal isn't in lower case.");
+ if (strPtr == end) {
+ return false;
+ }
+ char16_t strChar = *strPtr;
+ if (strChar >= 'A' && strChar <= 'Z') {
+ strChar += 0x20;
+ }
+ if (litChar != strChar) {
+ return false;
+ }
+ ++litPtr;
+ ++strPtr;
+ }
+ return true;
+}
+
+bool
+nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string)
+{
+ if (!string) {
+ return false;
+ }
+ return string->LowerCaseEqualsASCII(lowerCaseLiteral);
+}
+
+bool
+nsHtml5Portability::literalEqualsString(const char* literal, nsString* string)
+{
+ if (!string) {
+ return false;
+ }
+ return string->EqualsASCII(literal);
+}
+
+bool
+nsHtml5Portability::stringEqualsString(nsString* one, nsString* other)
+{
+ return one->Equals(*other);
+}
+
+void
+nsHtml5Portability::initializeStatics()
+{
+}
+
+void
+nsHtml5Portability::releaseStatics()
+{
+}
diff --git a/parser/html/nsHtml5Portability.h b/parser/html/nsHtml5Portability.h
new file mode 100644
index 000000000..bd85ccbdb
--- /dev/null
+++ b/parser/html/nsHtml5Portability.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2008-2015 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit Portability.java instead and regenerate.
+ */
+
+#ifndef nsHtml5Portability_h
+#define nsHtml5Portability_h
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5ByteReadable.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
+
+class nsHtml5StreamParser;
+
+class nsHtml5Tokenizer;
+class nsHtml5TreeBuilder;
+class nsHtml5MetaScanner;
+class nsHtml5AttributeName;
+class nsHtml5ElementName;
+class nsHtml5HtmlAttributes;
+class nsHtml5UTF16Buffer;
+class nsHtml5StateSnapshot;
+
+
+class nsHtml5Portability
+{
+ public:
+ static nsIAtom* newLocalNameFromBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5AtomTable* interner);
+ static nsString* newStringFromBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5TreeBuilder* treeBuilder);
+ static nsString* newEmptyString();
+ static nsString* newStringFromLiteral(const char* literal);
+ static nsString* newStringFromString(nsString* string);
+ static jArray<char16_t,int32_t> newCharArrayFromLocal(nsIAtom* local);
+ static jArray<char16_t,int32_t> newCharArrayFromString(nsString* string);
+ static nsIAtom* newLocalFromLocal(nsIAtom* local, nsHtml5AtomTable* interner);
+ static void releaseString(nsString* str);
+ static bool localEqualsBuffer(nsIAtom* local, char16_t* buf, int32_t offset, int32_t length);
+ static bool lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string);
+ static bool lowerCaseLiteralEqualsIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string);
+ static bool literalEqualsString(const char* literal, nsString* string);
+ static bool stringEqualsString(nsString* one, nsString* other);
+ static void initializeStatics();
+ static void releaseStatics();
+};
+
+
+
+#endif
+
diff --git a/parser/html/nsHtml5RefPtr.h b/parser/html/nsHtml5RefPtr.h
new file mode 100644
index 000000000..bc0477ba6
--- /dev/null
+++ b/parser/html/nsHtml5RefPtr.h
@@ -0,0 +1,449 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5RefPtr_h
+#define nsHtml5RefPtr_h
+
+#include "nsThreadUtils.h"
+
+template <class T>
+class nsHtml5RefPtrReleaser : public mozilla::Runnable
+ {
+ private:
+ T* mPtr;
+ public:
+ explicit nsHtml5RefPtrReleaser(T* aPtr)
+ : mPtr(aPtr)
+ {}
+ NS_IMETHOD Run() override
+ {
+ mPtr->Release();
+ return NS_OK;
+ }
+ };
+
+// template <class T> class nsHtml5RefPtrGetterAddRefs;
+
+/**
+ * Like nsRefPtr except release is proxied to the main thread. Mostly copied
+ * from nsRefPtr.
+ */
+template <class T>
+class nsHtml5RefPtr
+ {
+ private:
+
+ void
+ assign_with_AddRef( T* rawPtr )
+ {
+ if ( rawPtr )
+ rawPtr->AddRef();
+ assign_assuming_AddRef(rawPtr);
+ }
+
+ void**
+ begin_assignment()
+ {
+ assign_assuming_AddRef(0);
+ return reinterpret_cast<void**>(&mRawPtr);
+ }
+
+ void
+ assign_assuming_AddRef( T* newPtr )
+ {
+ T* oldPtr = mRawPtr;
+ mRawPtr = newPtr;
+ if ( oldPtr )
+ release(oldPtr);
+ }
+
+ void
+ release( T* aPtr )
+ {
+ nsCOMPtr<nsIRunnable> releaser = new nsHtml5RefPtrReleaser<T>(aPtr);
+ if (NS_FAILED(NS_DispatchToMainThread(releaser)))
+ {
+ NS_WARNING("Failed to dispatch releaser event.");
+ }
+ }
+
+ private:
+ T* mRawPtr;
+
+ public:
+ typedef T element_type;
+
+ ~nsHtml5RefPtr()
+ {
+ if ( mRawPtr )
+ release(mRawPtr);
+ }
+
+ // Constructors
+
+ nsHtml5RefPtr()
+ : mRawPtr(0)
+ // default constructor
+ {
+ }
+
+ nsHtml5RefPtr( const nsHtml5RefPtr<T>& aSmartPtr )
+ : mRawPtr(aSmartPtr.mRawPtr)
+ // copy-constructor
+ {
+ if ( mRawPtr )
+ mRawPtr->AddRef();
+ }
+
+ explicit nsHtml5RefPtr( T* aRawPtr )
+ : mRawPtr(aRawPtr)
+ // construct from a raw pointer (of the right type)
+ {
+ if ( mRawPtr )
+ mRawPtr->AddRef();
+ }
+
+ explicit nsHtml5RefPtr( const already_AddRefed<T>& aSmartPtr )
+ : mRawPtr(aSmartPtr.mRawPtr)
+ // construct from |dont_AddRef(expr)|
+ {
+ }
+
+ // Assignment operators
+
+ nsHtml5RefPtr<T>&
+ operator=( const nsHtml5RefPtr<T>& rhs )
+ // copy assignment operator
+ {
+ assign_with_AddRef(rhs.mRawPtr);
+ return *this;
+ }
+
+ nsHtml5RefPtr<T>&
+ operator=( T* rhs )
+ // assign from a raw pointer (of the right type)
+ {
+ assign_with_AddRef(rhs);
+ return *this;
+ }
+
+ nsHtml5RefPtr<T>&
+ operator=( const already_AddRefed<T>& rhs )
+ // assign from |dont_AddRef(expr)|
+ {
+ assign_assuming_AddRef(rhs.mRawPtr);
+ return *this;
+ }
+
+ // Other pointer operators
+
+ void
+ swap( nsHtml5RefPtr<T>& rhs )
+ // ...exchange ownership with |rhs|; can save a pair of refcount operations
+ {
+ T* temp = rhs.mRawPtr;
+ rhs.mRawPtr = mRawPtr;
+ mRawPtr = temp;
+ }
+
+ void
+ swap( T*& rhs )
+ // ...exchange ownership with |rhs|; can save a pair of refcount operations
+ {
+ T* temp = rhs;
+ rhs = mRawPtr;
+ mRawPtr = temp;
+ }
+
+ already_AddRefed<T>
+ forget()
+ // return the value of mRawPtr and null out mRawPtr. Useful for
+ // already_AddRefed return values.
+ {
+ T* temp = 0;
+ swap(temp);
+ return temp;
+ }
+
+ template <typename I>
+ void
+ forget( I** rhs)
+ // Set the target of rhs to the value of mRawPtr and null out mRawPtr.
+ // Useful to avoid unnecessary AddRef/Release pairs with "out"
+ // parameters where rhs bay be a T** or an I** where I is a base class
+ // of T.
+ {
+ NS_ASSERTION(rhs, "Null pointer passed to forget!");
+ *rhs = mRawPtr;
+ mRawPtr = 0;
+ }
+
+ T*
+ get() const
+ /*
+ Prefer the implicit conversion provided automatically by |operator T*() const|.
+ Use |get()| to resolve ambiguity or to get a castable pointer.
+ */
+ {
+ return const_cast<T*>(mRawPtr);
+ }
+
+ operator T*() const
+ /*
+ ...makes an |nsHtml5RefPtr| act like its underlying raw pointer type whenever it
+ is used in a context where a raw pointer is expected. It is this operator
+ that makes an |nsHtml5RefPtr| substitutable for a raw pointer.
+
+ Prefer the implicit use of this operator to calling |get()|, except where
+ necessary to resolve ambiguity.
+ */
+ {
+ return get();
+ }
+
+ T*
+ operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN
+ {
+ NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsHtml5RefPtr with operator->().");
+ return get();
+ }
+
+ nsHtml5RefPtr<T>*
+ get_address()
+ // This is not intended to be used by clients. See |address_of|
+ // below.
+ {
+ return this;
+ }
+
+ const nsHtml5RefPtr<T>*
+ get_address() const
+ // This is not intended to be used by clients. See |address_of|
+ // below.
+ {
+ return this;
+ }
+
+ public:
+ T&
+ operator*() const
+ {
+ NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsHtml5RefPtr with operator*().");
+ return *get();
+ }
+
+ T**
+ StartAssignment()
+ {
+#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
+ return reinterpret_cast<T**>(begin_assignment());
+#else
+ assign_assuming_AddRef(0);
+ return reinterpret_cast<T**>(&mRawPtr);
+#endif
+ }
+ };
+
+template <class T>
+inline
+nsHtml5RefPtr<T>*
+address_of( nsHtml5RefPtr<T>& aPtr )
+ {
+ return aPtr.get_address();
+ }
+
+template <class T>
+inline
+const nsHtml5RefPtr<T>*
+address_of( const nsHtml5RefPtr<T>& aPtr )
+ {
+ return aPtr.get_address();
+ }
+
+template <class T>
+class nsHtml5RefPtrGetterAddRefs
+ /*
+ ...
+
+ This class is designed to be used for anonymous temporary objects in the
+ argument list of calls that return COM interface pointers, e.g.,
+
+ nsHtml5RefPtr<IFoo> fooP;
+ ...->GetAddRefedPointer(getter_AddRefs(fooP))
+
+ DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_AddRefs()| instead.
+
+ When initialized with a |nsHtml5RefPtr|, as in the example above, it returns
+ a |void**|, a |T**|, or an |nsISupports**| as needed, that the
+ outer call (|GetAddRefedPointer| in this case) can fill in.
+
+ This type should be a nested class inside |nsHtml5RefPtr<T>|.
+ */
+ {
+ public:
+ explicit
+ nsHtml5RefPtrGetterAddRefs( nsHtml5RefPtr<T>& aSmartPtr )
+ : mTargetSmartPtr(aSmartPtr)
+ {
+ // nothing else to do
+ }
+
+ operator void**()
+ {
+ return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
+ }
+
+ operator T**()
+ {
+ return mTargetSmartPtr.StartAssignment();
+ }
+
+ T*&
+ operator*()
+ {
+ return *(mTargetSmartPtr.StartAssignment());
+ }
+
+ private:
+ nsHtml5RefPtr<T>& mTargetSmartPtr;
+ };
+
+template <class T>
+inline
+nsHtml5RefPtrGetterAddRefs<T>
+getter_AddRefs( nsHtml5RefPtr<T>& aSmartPtr )
+ /*
+ Used around a |nsHtml5RefPtr| when
+ ...makes the class |nsHtml5RefPtrGetterAddRefs<T>| invisible.
+ */
+ {
+ return nsHtml5RefPtrGetterAddRefs<T>(aSmartPtr);
+ }
+
+
+
+ // Comparing two |nsHtml5RefPtr|s
+
+template <class T, class U>
+inline
+bool
+operator==( const nsHtml5RefPtr<T>& lhs, const nsHtml5RefPtr<U>& rhs )
+ {
+ return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs.get());
+ }
+
+
+template <class T, class U>
+inline
+bool
+operator!=( const nsHtml5RefPtr<T>& lhs, const nsHtml5RefPtr<U>& rhs )
+ {
+ return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs.get());
+ }
+
+
+ // Comparing an |nsHtml5RefPtr| to a raw pointer
+
+template <class T, class U>
+inline
+bool
+operator==( const nsHtml5RefPtr<T>& lhs, const U* rhs )
+ {
+ return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs);
+ }
+
+template <class T, class U>
+inline
+bool
+operator==( const U* lhs, const nsHtml5RefPtr<T>& rhs )
+ {
+ return static_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
+ }
+
+template <class T, class U>
+inline
+bool
+operator!=( const nsHtml5RefPtr<T>& lhs, const U* rhs )
+ {
+ return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs);
+ }
+
+template <class T, class U>
+inline
+bool
+operator!=( const U* lhs, const nsHtml5RefPtr<T>& rhs )
+ {
+ return static_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
+ }
+
+template <class T, class U>
+inline
+bool
+operator==( const nsHtml5RefPtr<T>& lhs, U* rhs )
+ {
+ return static_cast<const T*>(lhs.get()) == const_cast<const U*>(rhs);
+ }
+
+template <class T, class U>
+inline
+bool
+operator==( U* lhs, const nsHtml5RefPtr<T>& rhs )
+ {
+ return const_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
+ }
+
+template <class T, class U>
+inline
+bool
+operator!=( const nsHtml5RefPtr<T>& lhs, U* rhs )
+ {
+ return static_cast<const T*>(lhs.get()) != const_cast<const U*>(rhs);
+ }
+
+template <class T, class U>
+inline
+bool
+operator!=( U* lhs, const nsHtml5RefPtr<T>& rhs )
+ {
+ return const_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
+ }
+
+
+
+ // Comparing an |nsHtml5RefPtr| to |0|
+
+template <class T>
+inline
+bool
+operator==( const nsHtml5RefPtr<T>& lhs, decltype(nullptr) )
+ {
+ return lhs.get() == nullptr;
+ }
+
+template <class T>
+inline
+bool
+operator==( decltype(nullptr), const nsHtml5RefPtr<T>& rhs )
+ {
+ return nullptr == rhs.get();
+ }
+
+template <class T>
+inline
+bool
+operator!=( const nsHtml5RefPtr<T>& lhs, decltype(nullptr) )
+ {
+ return lhs.get() != nullptr;
+ }
+
+template <class T>
+inline
+bool
+operator!=( decltype(nullptr), const nsHtml5RefPtr<T>& rhs )
+ {
+ return nullptr != rhs.get();
+ }
+
+#endif // !defined(nsHtml5RefPtr_h)
diff --git a/parser/html/nsHtml5ReleasableAttributeName.cpp b/parser/html/nsHtml5ReleasableAttributeName.cpp
new file mode 100644
index 000000000..4cef131e7
--- /dev/null
+++ b/parser/html/nsHtml5ReleasableAttributeName.cpp
@@ -0,0 +1,34 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5ReleasableAttributeName.h"
+#include "nsHtml5Portability.h"
+#include "nsHtml5AtomTable.h"
+
+nsHtml5ReleasableAttributeName::nsHtml5ReleasableAttributeName(int32_t* uri, nsIAtom** local, nsIAtom** prefix)
+ : nsHtml5AttributeName(uri, local, prefix)
+{
+}
+
+nsHtml5AttributeName*
+nsHtml5ReleasableAttributeName::cloneAttributeName(nsHtml5AtomTable* aInterner)
+{
+ nsIAtom* l = getLocal(0);
+ if (aInterner) {
+ if (!l->IsStaticAtom()) {
+ nsAutoString str;
+ l->ToString(str);
+ l = aInterner->GetAtom(str);
+ }
+ }
+ return new nsHtml5ReleasableAttributeName(nsHtml5AttributeName::ALL_NO_NS,
+ nsHtml5AttributeName::SAME_LOCAL(l),
+ nsHtml5AttributeName::ALL_NO_PREFIX);
+}
+
+void
+nsHtml5ReleasableAttributeName::release()
+{
+ delete this;
+}
diff --git a/parser/html/nsHtml5ReleasableAttributeName.h b/parser/html/nsHtml5ReleasableAttributeName.h
new file mode 100644
index 000000000..e9766173b
--- /dev/null
+++ b/parser/html/nsHtml5ReleasableAttributeName.h
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5ReleasableAttributeName_h
+#define nsHtml5ReleasableAttributeName_h
+
+#include "nsHtml5AttributeName.h"
+#include "mozilla/Attributes.h"
+
+class nsHtml5AtomTable;
+
+class nsHtml5ReleasableAttributeName final : public nsHtml5AttributeName
+{
+ public:
+ nsHtml5ReleasableAttributeName(int32_t* uri, nsIAtom** local, nsIAtom** prefix);
+ virtual nsHtml5AttributeName* cloneAttributeName(nsHtml5AtomTable* aInterner);
+ virtual void release();
+};
+
+#endif // nsHtml5ReleasableAttributeName_h
diff --git a/parser/html/nsHtml5ReleasableElementName.cpp b/parser/html/nsHtml5ReleasableElementName.cpp
new file mode 100644
index 000000000..244b22d97
--- /dev/null
+++ b/parser/html/nsHtml5ReleasableElementName.cpp
@@ -0,0 +1,30 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5ReleasableElementName.h"
+
+nsHtml5ReleasableElementName::nsHtml5ReleasableElementName(nsIAtom* name)
+ : nsHtml5ElementName(name)
+{
+}
+
+void
+nsHtml5ReleasableElementName::release()
+{
+ delete this;
+}
+
+nsHtml5ElementName*
+nsHtml5ReleasableElementName::cloneElementName(nsHtml5AtomTable* aInterner)
+{
+ nsIAtom* l = name;
+ if (aInterner) {
+ if (!l->IsStaticAtom()) {
+ nsAutoString str;
+ l->ToString(str);
+ l = aInterner->GetAtom(str);
+ }
+ }
+ return new nsHtml5ReleasableElementName(l);
+}
diff --git a/parser/html/nsHtml5ReleasableElementName.h b/parser/html/nsHtml5ReleasableElementName.h
new file mode 100644
index 000000000..f76792a48
--- /dev/null
+++ b/parser/html/nsHtml5ReleasableElementName.h
@@ -0,0 +1,19 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5ReleasableElementName_h
+#define nsHtml5ReleasableElementName_h
+
+#include "nsHtml5ElementName.h"
+#include "mozilla/Attributes.h"
+
+class nsHtml5ReleasableElementName final : public nsHtml5ElementName
+{
+ public:
+ explicit nsHtml5ReleasableElementName(nsIAtom* name);
+ virtual void release();
+ virtual nsHtml5ElementName* cloneElementName(nsHtml5AtomTable* interner);
+};
+
+#endif // nsHtml5ReleasableElementName_h
diff --git a/parser/html/nsHtml5SVGLoadDispatcher.cpp b/parser/html/nsHtml5SVGLoadDispatcher.cpp
new file mode 100644
index 000000000..b5c22d883
--- /dev/null
+++ b/parser/html/nsHtml5SVGLoadDispatcher.cpp
@@ -0,0 +1,40 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5SVGLoadDispatcher.h"
+#include "nsPresContext.h"
+#include "nsIPresShell.h"
+#include "mozilla/BasicEvents.h"
+#include "mozilla/EventDispatcher.h"
+#include "nsIDocument.h"
+
+using namespace mozilla;
+
+nsHtml5SVGLoadDispatcher::nsHtml5SVGLoadDispatcher(nsIContent* aElement)
+ : mElement(aElement)
+ , mDocument(mElement->OwnerDoc())
+{
+ mDocument->BlockOnload();
+}
+
+NS_IMETHODIMP
+nsHtml5SVGLoadDispatcher::Run()
+{
+ WidgetEvent event(true, eSVGLoad);
+ event.mFlags.mBubbles = false;
+ // Do we care about forcing presshell creation if it hasn't happened yet?
+ // That is, should this code flush or something? Does it really matter?
+ // For that matter, do we really want to try getting the prescontext?
+ // Does this event ever want one?
+ RefPtr<nsPresContext> ctx;
+ nsCOMPtr<nsIPresShell> shell = mElement->OwnerDoc()->GetShell();
+ if (shell) {
+ ctx = shell->GetPresContext();
+ }
+ EventDispatcher::Dispatch(mElement, ctx, &event);
+ // Unblocking onload on the same document that it was blocked even if
+ // the element has moved between docs since blocking.
+ mDocument->UnblockOnload(false);
+ return NS_OK;
+}
diff --git a/parser/html/nsHtml5SVGLoadDispatcher.h b/parser/html/nsHtml5SVGLoadDispatcher.h
new file mode 100644
index 000000000..3f1b1cd04
--- /dev/null
+++ b/parser/html/nsHtml5SVGLoadDispatcher.h
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5SVGLoadDispatcher_h
+#define nsHtml5SVGLoadDispatcher_h
+
+#include "nsThreadUtils.h"
+#include "nsIContent.h"
+
+class nsHtml5SVGLoadDispatcher : public mozilla::Runnable
+{
+ private:
+ nsCOMPtr<nsIContent> mElement;
+ nsCOMPtr<nsIDocument> mDocument;
+ public:
+ explicit nsHtml5SVGLoadDispatcher(nsIContent* aElement);
+ NS_IMETHOD Run();
+};
+
+#endif // nsHtml5SVGLoadDispatcher_h
diff --git a/parser/html/nsHtml5Speculation.cpp b/parser/html/nsHtml5Speculation.cpp
new file mode 100644
index 000000000..f9b5fa38f
--- /dev/null
+++ b/parser/html/nsHtml5Speculation.cpp
@@ -0,0 +1,36 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5Speculation.h"
+
+using namespace mozilla;
+
+nsHtml5Speculation::nsHtml5Speculation(nsHtml5OwningUTF16Buffer* aBuffer,
+ int32_t aStart,
+ int32_t aStartLineNumber,
+ nsAHtml5TreeBuilderState* aSnapshot)
+ : mBuffer(aBuffer)
+ , mStart(aStart)
+ , mStartLineNumber(aStartLineNumber)
+ , mSnapshot(aSnapshot)
+{
+ MOZ_COUNT_CTOR(nsHtml5Speculation);
+}
+
+nsHtml5Speculation::~nsHtml5Speculation()
+{
+ MOZ_COUNT_DTOR(nsHtml5Speculation);
+}
+
+void
+nsHtml5Speculation::MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue)
+{
+ mOpQueue.AppendElements(Move(aOpQueue));
+}
+
+void
+nsHtml5Speculation::FlushToSink(nsAHtml5TreeOpSink* aSink)
+{
+ aSink->MoveOpsFrom(mOpQueue);
+}
diff --git a/parser/html/nsHtml5Speculation.h b/parser/html/nsHtml5Speculation.h
new file mode 100644
index 000000000..3104bd7f4
--- /dev/null
+++ b/parser/html/nsHtml5Speculation.h
@@ -0,0 +1,75 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5Speculation_h
+#define nsHtml5Speculation_h
+
+#include "nsHtml5OwningUTF16Buffer.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5TreeOperation.h"
+#include "nsAHtml5TreeOpSink.h"
+#include "nsTArray.h"
+#include "nsAutoPtr.h"
+#include "mozilla/Attributes.h"
+
+class nsHtml5Speculation final : public nsAHtml5TreeOpSink
+{
+ public:
+ nsHtml5Speculation(nsHtml5OwningUTF16Buffer* aBuffer,
+ int32_t aStart,
+ int32_t aStartLineNumber,
+ nsAHtml5TreeBuilderState* aSnapshot);
+
+ ~nsHtml5Speculation();
+
+ nsHtml5OwningUTF16Buffer* GetBuffer()
+ {
+ return mBuffer;
+ }
+
+ int32_t GetStart()
+ {
+ return mStart;
+ }
+
+ int32_t GetStartLineNumber()
+ {
+ return mStartLineNumber;
+ }
+
+ nsAHtml5TreeBuilderState* GetSnapshot()
+ {
+ return mSnapshot;
+ }
+
+ /**
+ * Flush the operations from the tree operations from the argument
+ * queue unconditionally.
+ */
+ virtual void MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue);
+
+ void FlushToSink(nsAHtml5TreeOpSink* aSink);
+
+ private:
+ /**
+ * The first buffer in the pending UTF-16 buffer queue
+ */
+ RefPtr<nsHtml5OwningUTF16Buffer> mBuffer;
+
+ /**
+ * The start index of this speculation in the first buffer
+ */
+ int32_t mStart;
+
+ /**
+ * The current line number at the start of the speculation
+ */
+ int32_t mStartLineNumber;
+
+ nsAutoPtr<nsAHtml5TreeBuilderState> mSnapshot;
+
+ nsTArray<nsHtml5TreeOperation> mOpQueue;
+};
+
+#endif // nsHtml5Speculation_h
diff --git a/parser/html/nsHtml5SpeculativeLoad.cpp b/parser/html/nsHtml5SpeculativeLoad.cpp
new file mode 100644
index 000000000..8ffc4d063
--- /dev/null
+++ b/parser/html/nsHtml5SpeculativeLoad.cpp
@@ -0,0 +1,88 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5SpeculativeLoad.h"
+#include "nsHtml5TreeOpExecutor.h"
+
+nsHtml5SpeculativeLoad::nsHtml5SpeculativeLoad()
+#ifdef DEBUG
+ : mOpCode(eSpeculativeLoadUninitialized)
+#endif
+{
+ MOZ_COUNT_CTOR(nsHtml5SpeculativeLoad);
+}
+
+nsHtml5SpeculativeLoad::~nsHtml5SpeculativeLoad()
+{
+ MOZ_COUNT_DTOR(nsHtml5SpeculativeLoad);
+ NS_ASSERTION(mOpCode != eSpeculativeLoadUninitialized,
+ "Uninitialized speculative load.");
+}
+
+void
+nsHtml5SpeculativeLoad::Perform(nsHtml5TreeOpExecutor* aExecutor)
+{
+ switch (mOpCode) {
+ case eSpeculativeLoadBase:
+ aExecutor->SetSpeculationBase(mUrl);
+ break;
+ case eSpeculativeLoadCSP:
+ aExecutor->AddSpeculationCSP(mMetaCSP);
+ break;
+ case eSpeculativeLoadMetaReferrer:
+ aExecutor->SetSpeculationReferrerPolicy(mReferrerPolicy);
+ break;
+ case eSpeculativeLoadImage:
+ aExecutor->PreloadImage(mUrl, mCrossOrigin, mSrcset, mSizes, mReferrerPolicy);
+ break;
+ case eSpeculativeLoadOpenPicture:
+ aExecutor->PreloadOpenPicture();
+ break;
+ case eSpeculativeLoadEndPicture:
+ aExecutor->PreloadEndPicture();
+ break;
+ case eSpeculativeLoadPictureSource:
+ aExecutor->PreloadPictureSource(mSrcset, mSizes, mTypeOrCharsetSourceOrDocumentMode,
+ mMedia);
+ break;
+ case eSpeculativeLoadScript:
+ aExecutor->PreloadScript(mUrl, mCharset, mTypeOrCharsetSourceOrDocumentMode,
+ mCrossOrigin, mIntegrity, false);
+ break;
+ case eSpeculativeLoadScriptFromHead:
+ aExecutor->PreloadScript(mUrl, mCharset, mTypeOrCharsetSourceOrDocumentMode,
+ mCrossOrigin, mIntegrity, true);
+ break;
+ case eSpeculativeLoadStyle:
+ aExecutor->PreloadStyle(mUrl, mCharset, mCrossOrigin, mIntegrity);
+ break;
+ case eSpeculativeLoadManifest:
+ aExecutor->ProcessOfflineManifest(mUrl);
+ break;
+ case eSpeculativeLoadSetDocumentCharset: {
+ nsAutoCString narrowName;
+ CopyUTF16toUTF8(mCharset, narrowName);
+ NS_ASSERTION(mTypeOrCharsetSourceOrDocumentMode.Length() == 1,
+ "Unexpected charset source string");
+ int32_t intSource = (int32_t)mTypeOrCharsetSourceOrDocumentMode.First();
+ aExecutor->SetDocumentCharsetAndSource(narrowName,
+ intSource);
+ }
+ break;
+ case eSpeculativeLoadSetDocumentMode: {
+ NS_ASSERTION(mTypeOrCharsetSourceOrDocumentMode.Length() == 1,
+ "Unexpected document mode string");
+ nsHtml5DocumentMode mode =
+ (nsHtml5DocumentMode)mTypeOrCharsetSourceOrDocumentMode.First();
+ aExecutor->SetDocumentMode(mode);
+ }
+ break;
+ case eSpeculativeLoadPreconnect:
+ aExecutor->Preconnect(mUrl, mCrossOrigin);
+ break;
+ default:
+ NS_NOTREACHED("Bogus speculative load.");
+ break;
+ }
+}
diff --git a/parser/html/nsHtml5SpeculativeLoad.h b/parser/html/nsHtml5SpeculativeLoad.h
new file mode 100644
index 000000000..575f6186d
--- /dev/null
+++ b/parser/html/nsHtml5SpeculativeLoad.h
@@ -0,0 +1,263 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5SpeculativeLoad_h
+#define nsHtml5SpeculativeLoad_h
+
+#include "nsString.h"
+#include "nsContentUtils.h"
+
+class nsHtml5TreeOpExecutor;
+
+enum eHtml5SpeculativeLoad {
+#ifdef DEBUG
+ eSpeculativeLoadUninitialized,
+#endif
+ eSpeculativeLoadBase,
+ eSpeculativeLoadCSP,
+ eSpeculativeLoadMetaReferrer,
+ eSpeculativeLoadImage,
+ eSpeculativeLoadOpenPicture,
+ eSpeculativeLoadEndPicture,
+ eSpeculativeLoadPictureSource,
+ eSpeculativeLoadScript,
+ eSpeculativeLoadScriptFromHead,
+ eSpeculativeLoadStyle,
+ eSpeculativeLoadManifest,
+ eSpeculativeLoadSetDocumentCharset,
+ eSpeculativeLoadSetDocumentMode,
+ eSpeculativeLoadPreconnect
+};
+
+class nsHtml5SpeculativeLoad {
+ public:
+ nsHtml5SpeculativeLoad();
+ ~nsHtml5SpeculativeLoad();
+
+ inline void InitBase(const nsAString& aUrl)
+ {
+ NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
+ "Trying to reinitialize a speculative load!");
+ mOpCode = eSpeculativeLoadBase;
+ mUrl.Assign(aUrl);
+ }
+
+ inline void InitMetaCSP(const nsAString& aCSP) {
+ NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
+ "Trying to reinitialize a speculative load!");
+ mOpCode = eSpeculativeLoadCSP;
+ mMetaCSP.Assign(
+ nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aCSP));
+ }
+
+ inline void InitMetaReferrerPolicy(const nsAString& aReferrerPolicy) {
+ NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
+ "Trying to reinitialize a speculative load!");
+ mOpCode = eSpeculativeLoadMetaReferrer;
+ mReferrerPolicy.Assign(
+ nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aReferrerPolicy));
+ }
+
+ inline void InitImage(const nsAString& aUrl,
+ const nsAString& aCrossOrigin,
+ const nsAString& aReferrerPolicy,
+ const nsAString& aSrcset,
+ const nsAString& aSizes)
+ {
+ NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
+ "Trying to reinitialize a speculative load!");
+ mOpCode = eSpeculativeLoadImage;
+ mUrl.Assign(aUrl);
+ mCrossOrigin.Assign(aCrossOrigin);
+ mReferrerPolicy.Assign(
+ nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aReferrerPolicy));
+ mSrcset.Assign(aSrcset);
+ mSizes.Assign(aSizes);
+ }
+
+ // <picture> elements have multiple <source> nodes followed by an <img>,
+ // where we use the first valid source, which may be the img. Because we
+ // can't determine validity at this point without parsing CSS and getting
+ // main thread state, we push preload operations for picture pushed and
+ // popped, so that the target of the preload ops can determine what picture
+ // and nesting level each source/img from the main preloading code exists
+ // at.
+ inline void InitOpenPicture()
+ {
+ NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
+ "Trying to reinitialize a speculative load!");
+ mOpCode = eSpeculativeLoadOpenPicture;
+ }
+
+ inline void InitEndPicture()
+ {
+ NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
+ "Trying to reinitialize a speculative load!");
+ mOpCode = eSpeculativeLoadEndPicture;
+ }
+
+ inline void InitPictureSource(const nsAString& aSrcset,
+ const nsAString& aSizes,
+ const nsAString& aType,
+ const nsAString& aMedia)
+ {
+ NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
+ "Trying to reinitialize a speculative load!");
+ mOpCode = eSpeculativeLoadPictureSource;
+ mSrcset.Assign(aSrcset);
+ mSizes.Assign(aSizes);
+ mTypeOrCharsetSourceOrDocumentMode.Assign(aType);
+ mMedia.Assign(aMedia);
+ }
+
+ inline void InitScript(const nsAString& aUrl,
+ const nsAString& aCharset,
+ const nsAString& aType,
+ const nsAString& aCrossOrigin,
+ const nsAString& aIntegrity,
+ bool aParserInHead)
+ {
+ NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
+ "Trying to reinitialize a speculative load!");
+ mOpCode = aParserInHead ?
+ eSpeculativeLoadScriptFromHead : eSpeculativeLoadScript;
+ mUrl.Assign(aUrl);
+ mCharset.Assign(aCharset);
+ mTypeOrCharsetSourceOrDocumentMode.Assign(aType);
+ mCrossOrigin.Assign(aCrossOrigin);
+ mIntegrity.Assign(aIntegrity);
+ }
+
+ inline void InitStyle(const nsAString& aUrl, const nsAString& aCharset,
+ const nsAString& aCrossOrigin,
+ const nsAString& aIntegrity)
+ {
+ NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
+ "Trying to reinitialize a speculative load!");
+ mOpCode = eSpeculativeLoadStyle;
+ mUrl.Assign(aUrl);
+ mCharset.Assign(aCharset);
+ mCrossOrigin.Assign(aCrossOrigin);
+ mIntegrity.Assign(aIntegrity);
+ }
+
+ /**
+ * "Speculative" manifest loads aren't truly speculative--if a manifest
+ * gets loaded, we are committed to it. There can never be a <script>
+ * before the manifest, so the situation of having to undo a manifest due
+ * to document.write() never arises. The reason why a parser
+ * thread-discovered manifest gets loaded via the speculative load queue
+ * as opposed to tree operation queue is that the manifest must get
+ * processed before any actual speculative loads such as scripts. Thus,
+ * manifests seen by the parser thread have to maintain the queue order
+ * relative to true speculative loads. See bug 541079.
+ */
+ inline void InitManifest(const nsAString& aUrl)
+ {
+ NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
+ "Trying to reinitialize a speculative load!");
+ mOpCode = eSpeculativeLoadManifest;
+ mUrl.Assign(aUrl);
+ }
+
+ /**
+ * "Speculative" charset setting isn't truly speculative. If the charset
+ * is set via this operation, we are committed to it unless chardet or
+ * a late meta cause a reload. The reason why a parser
+ * thread-discovered charset gets communicated via the speculative load
+ * queue as opposed to tree operation queue is that the charset change
+ * must get processed before any actual speculative loads such as style
+ * sheets. Thus, encoding decisions by the parser thread have to maintain
+ * the queue order relative to true speculative loads. See bug 675499.
+ */
+ inline void InitSetDocumentCharset(nsACString& aCharset,
+ int32_t aCharsetSource)
+ {
+ NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
+ "Trying to reinitialize a speculative load!");
+ mOpCode = eSpeculativeLoadSetDocumentCharset;
+ CopyUTF8toUTF16(aCharset, mCharset);
+ mTypeOrCharsetSourceOrDocumentMode.Assign((char16_t)aCharsetSource);
+ }
+
+ /**
+ * Speculative document mode setting isn't really speculative. Once it
+ * happens, we are committed to it. However, this information needs to
+ * travel in the speculation queue in order to have this information
+ * available before parsing the speculatively loaded style sheets.
+ */
+ inline void InitSetDocumentMode(nsHtml5DocumentMode aMode)
+ {
+ NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
+ "Trying to reinitialize a speculative load!");
+ mOpCode = eSpeculativeLoadSetDocumentMode;
+ mTypeOrCharsetSourceOrDocumentMode.Assign((char16_t)aMode);
+ }
+
+ inline void InitPreconnect(const nsAString& aUrl,
+ const nsAString& aCrossOrigin)
+ {
+ NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
+ "Trying to reinitialize a speculative load!");
+ mOpCode = eSpeculativeLoadPreconnect;
+ mUrl.Assign(aUrl);
+ mCrossOrigin.Assign(aCrossOrigin);
+ }
+
+ void Perform(nsHtml5TreeOpExecutor* aExecutor);
+
+ private:
+ eHtml5SpeculativeLoad mOpCode;
+ nsString mUrl;
+ nsString mReferrerPolicy;
+ nsString mMetaCSP;
+
+ /**
+ * If mOpCode is eSpeculativeLoadStyle or eSpeculativeLoadScript[FromHead]
+ * then this is the value of the "charset" attribute. For
+ * eSpeculativeLoadSetDocumentCharset it is the charset that the
+ * document's charset is being set to. Otherwise it's empty.
+ */
+ nsString mCharset;
+ /**
+ * If mOpCode is eSpeculativeLoadSetDocumentCharset, this is a
+ * one-character string whose single character's code point is to be
+ * interpreted as a charset source integer. If mOpCode is
+ * eSpeculativeLoadSetDocumentMode, this is a one-character string whose
+ * single character's code point is to be interpreted as an
+ * nsHtml5DocumentMode. Otherwise, it is empty or the value of the type
+ * attribute.
+ */
+ nsString mTypeOrCharsetSourceOrDocumentMode;
+ /**
+ * If mOpCode is eSpeculativeLoadImage or eSpeculativeLoadScript[FromHead]
+ * or eSpeculativeLoadPreconnect this is the value of the "crossorigin"
+ * attribute. If the attribute is not set, this will be a void string.
+ */
+ nsString mCrossOrigin;
+ /**
+ * If mOpCode is eSpeculativeLoadImage or eSpeculativeLoadPictureSource,
+ * this is the value of "srcset" attribute. If the attribute is not set,
+ * this will be a void string.
+ */
+ nsString mSrcset;
+ /**
+ * If mOpCode is eSpeculativeLoadPictureSource, this is the value of "sizes"
+ * attribute. If the attribute is not set, this will be a void string.
+ */
+ nsString mSizes;
+ /**
+ * If mOpCode is eSpeculativeLoadPictureSource, this is the value of "media"
+ * attribute. If the attribute is not set, this will be a void string.
+ */
+ nsString mMedia;
+ /**
+ * If mOpCode is eSpeculativeLoadScript[FromHead], this is the value of the
+ * "integrity" attribute. If the attribute is not set, this will be a void
+ * string.
+ */
+ nsString mIntegrity;
+};
+
+#endif // nsHtml5SpeculativeLoad_h
diff --git a/parser/html/nsHtml5StackNode.cpp b/parser/html/nsHtml5StackNode.cpp
new file mode 100644
index 000000000..ac5f0b2a3
--- /dev/null
+++ b/parser/html/nsHtml5StackNode.cpp
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 2007-2011 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit StackNode.java instead and regenerate.
+ */
+
+#define nsHtml5StackNode_cpp__
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5ByteReadable.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
+
+#include "nsHtml5Tokenizer.h"
+#include "nsHtml5TreeBuilder.h"
+#include "nsHtml5MetaScanner.h"
+#include "nsHtml5AttributeName.h"
+#include "nsHtml5ElementName.h"
+#include "nsHtml5HtmlAttributes.h"
+#include "nsHtml5UTF16Buffer.h"
+#include "nsHtml5StateSnapshot.h"
+#include "nsHtml5Portability.h"
+
+#include "nsHtml5StackNode.h"
+
+int32_t
+nsHtml5StackNode::getGroup()
+{
+ return flags & NS_HTML5ELEMENT_NAME_GROUP_MASK;
+}
+
+bool
+nsHtml5StackNode::isScoping()
+{
+ return (flags & NS_HTML5ELEMENT_NAME_SCOPING);
+}
+
+bool
+nsHtml5StackNode::isSpecial()
+{
+ return (flags & NS_HTML5ELEMENT_NAME_SPECIAL);
+}
+
+bool
+nsHtml5StackNode::isFosterParenting()
+{
+ return (flags & NS_HTML5ELEMENT_NAME_FOSTER_PARENTING);
+}
+
+bool
+nsHtml5StackNode::isHtmlIntegrationPoint()
+{
+ return (flags & NS_HTML5ELEMENT_NAME_HTML_INTEGRATION_POINT);
+}
+
+
+nsHtml5StackNode::nsHtml5StackNode(int32_t flags, int32_t ns, nsIAtom* name, nsIContentHandle* node, nsIAtom* popName, nsHtml5HtmlAttributes* attributes)
+ : flags(flags),
+ name(name),
+ popName(popName),
+ ns(ns),
+ node(node),
+ attributes(attributes),
+ refcount(1)
+{
+ MOZ_COUNT_CTOR(nsHtml5StackNode);
+}
+
+
+nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node)
+ : flags(elementName->getFlags()),
+ name(elementName->name),
+ popName(elementName->name),
+ ns(kNameSpaceID_XHTML),
+ node(node),
+ attributes(nullptr),
+ refcount(1)
+{
+ MOZ_COUNT_CTOR(nsHtml5StackNode);
+ MOZ_ASSERT(!elementName->isCustom(), "Don't use this constructor for custom elements.");
+}
+
+
+nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsHtml5HtmlAttributes* attributes)
+ : flags(elementName->getFlags()),
+ name(elementName->name),
+ popName(elementName->name),
+ ns(kNameSpaceID_XHTML),
+ node(node),
+ attributes(attributes),
+ refcount(1)
+{
+ MOZ_COUNT_CTOR(nsHtml5StackNode);
+ MOZ_ASSERT(!elementName->isCustom(), "Don't use this constructor for custom elements.");
+}
+
+
+nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsIAtom* popName)
+ : flags(elementName->getFlags()),
+ name(elementName->name),
+ popName(popName),
+ ns(kNameSpaceID_XHTML),
+ node(node),
+ attributes(nullptr),
+ refcount(1)
+{
+ MOZ_COUNT_CTOR(nsHtml5StackNode);
+}
+
+
+nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIAtom* popName, nsIContentHandle* node)
+ : flags(prepareSvgFlags(elementName->getFlags())),
+ name(elementName->name),
+ popName(popName),
+ ns(kNameSpaceID_SVG),
+ node(node),
+ attributes(nullptr),
+ refcount(1)
+{
+ MOZ_COUNT_CTOR(nsHtml5StackNode);
+}
+
+
+nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsIAtom* popName, bool markAsIntegrationPoint)
+ : flags(prepareMathFlags(elementName->getFlags(), markAsIntegrationPoint)),
+ name(elementName->name),
+ popName(popName),
+ ns(kNameSpaceID_MathML),
+ node(node),
+ attributes(nullptr),
+ refcount(1)
+{
+ MOZ_COUNT_CTOR(nsHtml5StackNode);
+}
+
+int32_t
+nsHtml5StackNode::prepareSvgFlags(int32_t flags)
+{
+ flags &= ~(NS_HTML5ELEMENT_NAME_FOSTER_PARENTING | NS_HTML5ELEMENT_NAME_SCOPING | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ if ((flags & NS_HTML5ELEMENT_NAME_SCOPING_AS_SVG)) {
+ flags |= (NS_HTML5ELEMENT_NAME_SCOPING | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_HTML_INTEGRATION_POINT);
+ }
+ return flags;
+}
+
+int32_t
+nsHtml5StackNode::prepareMathFlags(int32_t flags, bool markAsIntegrationPoint)
+{
+ flags &= ~(NS_HTML5ELEMENT_NAME_FOSTER_PARENTING | NS_HTML5ELEMENT_NAME_SCOPING | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
+ if ((flags & NS_HTML5ELEMENT_NAME_SCOPING_AS_MATHML)) {
+ flags |= (NS_HTML5ELEMENT_NAME_SCOPING | NS_HTML5ELEMENT_NAME_SPECIAL);
+ }
+ if (markAsIntegrationPoint) {
+ flags |= NS_HTML5ELEMENT_NAME_HTML_INTEGRATION_POINT;
+ }
+ return flags;
+}
+
+
+nsHtml5StackNode::~nsHtml5StackNode()
+{
+ MOZ_COUNT_DTOR(nsHtml5StackNode);
+ delete attributes;
+}
+
+void
+nsHtml5StackNode::dropAttributes()
+{
+ attributes = nullptr;
+}
+
+void
+nsHtml5StackNode::retain()
+{
+ refcount++;
+}
+
+void
+nsHtml5StackNode::release()
+{
+ refcount--;
+ if (!refcount) {
+ delete this;
+ }
+}
+
+void
+nsHtml5StackNode::initializeStatics()
+{
+}
+
+void
+nsHtml5StackNode::releaseStatics()
+{
+}
+
+
diff --git a/parser/html/nsHtml5StackNode.h b/parser/html/nsHtml5StackNode.h
new file mode 100644
index 000000000..57909ca9c
--- /dev/null
+++ b/parser/html/nsHtml5StackNode.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 2007-2011 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit StackNode.java instead and regenerate.
+ */
+
+#ifndef nsHtml5StackNode_h
+#define nsHtml5StackNode_h
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5ByteReadable.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
+
+class nsHtml5StreamParser;
+
+class nsHtml5Tokenizer;
+class nsHtml5TreeBuilder;
+class nsHtml5MetaScanner;
+class nsHtml5AttributeName;
+class nsHtml5ElementName;
+class nsHtml5HtmlAttributes;
+class nsHtml5UTF16Buffer;
+class nsHtml5StateSnapshot;
+class nsHtml5Portability;
+
+
+class nsHtml5StackNode
+{
+ public:
+ int32_t flags;
+ nsIAtom* name;
+ nsIAtom* popName;
+ int32_t ns;
+ nsIContentHandle* node;
+ nsHtml5HtmlAttributes* attributes;
+ private:
+ int32_t refcount;
+ public:
+ inline int32_t getFlags()
+ {
+ return flags;
+ }
+
+ int32_t getGroup();
+ bool isScoping();
+ bool isSpecial();
+ bool isFosterParenting();
+ bool isHtmlIntegrationPoint();
+ nsHtml5StackNode(int32_t flags, int32_t ns, nsIAtom* name, nsIContentHandle* node, nsIAtom* popName, nsHtml5HtmlAttributes* attributes);
+ nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node);
+ nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsHtml5HtmlAttributes* attributes);
+ nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsIAtom* popName);
+ nsHtml5StackNode(nsHtml5ElementName* elementName, nsIAtom* popName, nsIContentHandle* node);
+ nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsIAtom* popName, bool markAsIntegrationPoint);
+ private:
+ static int32_t prepareSvgFlags(int32_t flags);
+ static int32_t prepareMathFlags(int32_t flags, bool markAsIntegrationPoint);
+ public:
+ ~nsHtml5StackNode();
+ void dropAttributes();
+ void retain();
+ void release();
+ static void initializeStatics();
+ static void releaseStatics();
+};
+
+
+
+#endif
+
diff --git a/parser/html/nsHtml5StateSnapshot.cpp b/parser/html/nsHtml5StateSnapshot.cpp
new file mode 100644
index 000000000..e8e3debf0
--- /dev/null
+++ b/parser/html/nsHtml5StateSnapshot.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2009-2010 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit StateSnapshot.java instead and regenerate.
+ */
+
+#define nsHtml5StateSnapshot_cpp__
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5ByteReadable.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
+
+#include "nsHtml5Tokenizer.h"
+#include "nsHtml5TreeBuilder.h"
+#include "nsHtml5MetaScanner.h"
+#include "nsHtml5AttributeName.h"
+#include "nsHtml5ElementName.h"
+#include "nsHtml5HtmlAttributes.h"
+#include "nsHtml5StackNode.h"
+#include "nsHtml5UTF16Buffer.h"
+#include "nsHtml5Portability.h"
+
+#include "nsHtml5StateSnapshot.h"
+
+
+nsHtml5StateSnapshot::nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,int32_t> stack, jArray<nsHtml5StackNode*,int32_t> listOfActiveFormattingElements, jArray<int32_t,int32_t> templateModeStack, nsIContentHandle* formPointer, nsIContentHandle* headPointer, nsIContentHandle* deepTreeSurrogateParent, int32_t mode, int32_t originalMode, bool framesetOk, bool needToDropLF, bool quirks)
+ : stack(stack),
+ listOfActiveFormattingElements(listOfActiveFormattingElements),
+ templateModeStack(templateModeStack),
+ formPointer(formPointer),
+ headPointer(headPointer),
+ deepTreeSurrogateParent(deepTreeSurrogateParent),
+ mode(mode),
+ originalMode(originalMode),
+ framesetOk(framesetOk),
+ needToDropLF(needToDropLF),
+ quirks(quirks)
+{
+ MOZ_COUNT_CTOR(nsHtml5StateSnapshot);
+}
+
+jArray<nsHtml5StackNode*,int32_t>
+nsHtml5StateSnapshot::getStack()
+{
+ return stack;
+}
+
+jArray<int32_t,int32_t>
+nsHtml5StateSnapshot::getTemplateModeStack()
+{
+ return templateModeStack;
+}
+
+jArray<nsHtml5StackNode*,int32_t>
+nsHtml5StateSnapshot::getListOfActiveFormattingElements()
+{
+ return listOfActiveFormattingElements;
+}
+
+nsIContentHandle*
+nsHtml5StateSnapshot::getFormPointer()
+{
+ return formPointer;
+}
+
+nsIContentHandle*
+nsHtml5StateSnapshot::getHeadPointer()
+{
+ return headPointer;
+}
+
+nsIContentHandle*
+nsHtml5StateSnapshot::getDeepTreeSurrogateParent()
+{
+ return deepTreeSurrogateParent;
+}
+
+int32_t
+nsHtml5StateSnapshot::getMode()
+{
+ return mode;
+}
+
+int32_t
+nsHtml5StateSnapshot::getOriginalMode()
+{
+ return originalMode;
+}
+
+bool
+nsHtml5StateSnapshot::isFramesetOk()
+{
+ return framesetOk;
+}
+
+bool
+nsHtml5StateSnapshot::isNeedToDropLF()
+{
+ return needToDropLF;
+}
+
+bool
+nsHtml5StateSnapshot::isQuirks()
+{
+ return quirks;
+}
+
+int32_t
+nsHtml5StateSnapshot::getListOfActiveFormattingElementsLength()
+{
+ return listOfActiveFormattingElements.length;
+}
+
+int32_t
+nsHtml5StateSnapshot::getStackLength()
+{
+ return stack.length;
+}
+
+int32_t
+nsHtml5StateSnapshot::getTemplateModeStackLength()
+{
+ return templateModeStack.length;
+}
+
+
+nsHtml5StateSnapshot::~nsHtml5StateSnapshot()
+{
+ MOZ_COUNT_DTOR(nsHtml5StateSnapshot);
+ for (int32_t i = 0; i < stack.length; i++) {
+ stack[i]->release();
+ }
+ for (int32_t i = 0; i < listOfActiveFormattingElements.length; i++) {
+ if (listOfActiveFormattingElements[i]) {
+ listOfActiveFormattingElements[i]->release();
+ }
+ }
+}
+
+void
+nsHtml5StateSnapshot::initializeStatics()
+{
+}
+
+void
+nsHtml5StateSnapshot::releaseStatics()
+{
+}
+
+
diff --git a/parser/html/nsHtml5StateSnapshot.h b/parser/html/nsHtml5StateSnapshot.h
new file mode 100644
index 000000000..141b34340
--- /dev/null
+++ b/parser/html/nsHtml5StateSnapshot.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2009-2010 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit StateSnapshot.java instead and regenerate.
+ */
+
+#ifndef nsHtml5StateSnapshot_h
+#define nsHtml5StateSnapshot_h
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5ByteReadable.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
+
+class nsHtml5StreamParser;
+
+class nsHtml5Tokenizer;
+class nsHtml5TreeBuilder;
+class nsHtml5MetaScanner;
+class nsHtml5AttributeName;
+class nsHtml5ElementName;
+class nsHtml5HtmlAttributes;
+class nsHtml5UTF16Buffer;
+class nsHtml5Portability;
+
+
+class nsHtml5StateSnapshot : public nsAHtml5TreeBuilderState
+{
+ private:
+ autoJArray<nsHtml5StackNode*,int32_t> stack;
+ autoJArray<nsHtml5StackNode*,int32_t> listOfActiveFormattingElements;
+ autoJArray<int32_t,int32_t> templateModeStack;
+ nsIContentHandle* formPointer;
+ nsIContentHandle* headPointer;
+ nsIContentHandle* deepTreeSurrogateParent;
+ int32_t mode;
+ int32_t originalMode;
+ bool framesetOk;
+ bool needToDropLF;
+ bool quirks;
+ public:
+ nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,int32_t> stack, jArray<nsHtml5StackNode*,int32_t> listOfActiveFormattingElements, jArray<int32_t,int32_t> templateModeStack, nsIContentHandle* formPointer, nsIContentHandle* headPointer, nsIContentHandle* deepTreeSurrogateParent, int32_t mode, int32_t originalMode, bool framesetOk, bool needToDropLF, bool quirks);
+ jArray<nsHtml5StackNode*,int32_t> getStack();
+ jArray<int32_t,int32_t> getTemplateModeStack();
+ jArray<nsHtml5StackNode*,int32_t> getListOfActiveFormattingElements();
+ nsIContentHandle* getFormPointer();
+ nsIContentHandle* getHeadPointer();
+ nsIContentHandle* getDeepTreeSurrogateParent();
+ int32_t getMode();
+ int32_t getOriginalMode();
+ bool isFramesetOk();
+ bool isNeedToDropLF();
+ bool isQuirks();
+ int32_t getListOfActiveFormattingElementsLength();
+ int32_t getStackLength();
+ int32_t getTemplateModeStackLength();
+ ~nsHtml5StateSnapshot();
+ static void initializeStatics();
+ static void releaseStatics();
+};
+
+
+
+#endif
+
diff --git a/parser/html/nsHtml5StreamListener.cpp b/parser/html/nsHtml5StreamListener.cpp
new file mode 100644
index 000000000..a585ce8de
--- /dev/null
+++ b/parser/html/nsHtml5StreamListener.cpp
@@ -0,0 +1,82 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5StreamListener.h"
+
+NS_IMPL_ADDREF(nsHtml5StreamListener)
+NS_IMPL_RELEASE(nsHtml5StreamListener)
+
+NS_INTERFACE_MAP_BEGIN(nsHtml5StreamListener)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRequestObserver)
+ NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
+ NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
+ NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener)
+NS_INTERFACE_MAP_END_THREADSAFE
+
+nsHtml5StreamListener::nsHtml5StreamListener(nsHtml5StreamParser* aDelegate)
+ : mDelegate(aDelegate)
+{
+}
+
+nsHtml5StreamListener::~nsHtml5StreamListener()
+{
+}
+
+void
+nsHtml5StreamListener::DropDelegate()
+{
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Must not call DropDelegate from non-main threads.");
+ mDelegate = nullptr;
+}
+
+NS_IMETHODIMP
+nsHtml5StreamListener::CheckListenerChain()
+{
+ if (MOZ_UNLIKELY(!mDelegate)) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ return mDelegate->CheckListenerChain();
+}
+
+NS_IMETHODIMP
+nsHtml5StreamListener::OnStartRequest(nsIRequest* aRequest,
+ nsISupports* aContext)
+{
+ if (MOZ_UNLIKELY(!mDelegate)) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ return mDelegate->OnStartRequest(aRequest, aContext);
+}
+
+NS_IMETHODIMP
+nsHtml5StreamListener::OnStopRequest(nsIRequest* aRequest,
+ nsISupports* aContext,
+ nsresult aStatus)
+{
+ if (MOZ_UNLIKELY(!mDelegate)) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ return mDelegate->OnStopRequest(aRequest,
+ aContext,
+ aStatus);
+}
+
+NS_IMETHODIMP
+nsHtml5StreamListener::OnDataAvailable(nsIRequest* aRequest,
+ nsISupports* aContext,
+ nsIInputStream* aInStream,
+ uint64_t aSourceOffset,
+ uint32_t aLength)
+{
+ if (MOZ_UNLIKELY(!mDelegate)) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ return mDelegate->OnDataAvailable(aRequest,
+ aContext,
+ aInStream,
+ aSourceOffset,
+ aLength);
+}
+
diff --git a/parser/html/nsHtml5StreamListener.h b/parser/html/nsHtml5StreamListener.h
new file mode 100644
index 000000000..966765fb5
--- /dev/null
+++ b/parser/html/nsHtml5StreamListener.h
@@ -0,0 +1,55 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5StreamListener_h
+#define nsHtml5StreamListener_h
+
+#include "nsIStreamListener.h"
+#include "nsIThreadRetargetableStreamListener.h"
+#include "nsHtml5RefPtr.h"
+#include "nsHtml5StreamParser.h"
+
+/**
+ * The purpose of this class is to reconcile the problem that
+ * nsHtml5StreamParser is a cycle collection participant, which means that it
+ * can only be refcounted on the main thread, but
+ * nsIThreadRetargetableStreamListener can be refcounted from another thread,
+ * so nsHtml5StreamParser being an nsIThreadRetargetableStreamListener was
+ * a memory corruption problem.
+ *
+ * mDelegate is an nsHtml5RefPtr, which releases the object that it points
+ * to from a runnable on the main thread. DropDelegate() is only called on
+ * the main thread. This call will finish before the main-thread derefs the
+ * nsHtml5StreamListener itself, so there is no risk of another thread making
+ * the refcount of nsHtml5StreamListener go to zero and running the destructor
+ * concurrently. Other than that, the thread-safe nsISupports implementation
+ * takes care of the destructor not running concurrently from different
+ * threads, so there is no need to have a mutex around nsHtml5RefPtr to
+ * prevent it from double-releasing nsHtml5StreamParser.
+ */
+class nsHtml5StreamListener : public nsIStreamListener,
+ public nsIThreadRetargetableStreamListener
+{
+public:
+ explicit nsHtml5StreamListener(nsHtml5StreamParser* aDelegate);
+
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIREQUESTOBSERVER
+ NS_DECL_NSISTREAMLISTENER
+ NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
+
+ inline nsHtml5StreamParser* GetDelegate()
+ {
+ return mDelegate;
+ }
+
+ void DropDelegate();
+
+private:
+ virtual ~nsHtml5StreamListener();
+
+ nsHtml5RefPtr<nsHtml5StreamParser> mDelegate;
+};
+
+#endif // nsHtml5StreamListener_h
diff --git a/parser/html/nsHtml5StreamParser.cpp b/parser/html/nsHtml5StreamParser.cpp
new file mode 100644
index 000000000..83bf4d8b6
--- /dev/null
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -0,0 +1,1722 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=2 et tw=79: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/DebugOnly.h"
+
+#include "nsHtml5StreamParser.h"
+#include "nsContentUtils.h"
+#include "nsHtml5Tokenizer.h"
+#include "nsIHttpChannel.h"
+#include "nsHtml5Parser.h"
+#include "nsHtml5TreeBuilder.h"
+#include "nsHtml5AtomTable.h"
+#include "nsHtml5Module.h"
+#include "nsHtml5RefPtr.h"
+#include "nsIScriptError.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/UniquePtrExtensions.h"
+#include "nsHtml5Highlighter.h"
+#include "expat_config.h"
+#include "expat.h"
+#include "nsINestedURI.h"
+#include "nsCharsetSource.h"
+#include "nsIWyciwygChannel.h"
+#include "nsIThreadRetargetableRequest.h"
+#include "nsPrintfCString.h"
+#include "nsNetUtil.h"
+#include "nsXULAppAPI.h"
+
+#include "mozilla/dom/EncodingUtils.h"
+
+using namespace mozilla;
+using mozilla::dom::EncodingUtils;
+
+int32_t nsHtml5StreamParser::sTimerInitialDelay = 120;
+int32_t nsHtml5StreamParser::sTimerSubsequentDelay = 120;
+
+// static
+void
+nsHtml5StreamParser::InitializeStatics()
+{
+ Preferences::AddIntVarCache(&sTimerInitialDelay,
+ "html5.flushtimer.initialdelay");
+ Preferences::AddIntVarCache(&sTimerSubsequentDelay,
+ "html5.flushtimer.subsequentdelay");
+}
+
+/*
+ * Note that nsHtml5StreamParser implements cycle collecting AddRef and
+ * Release. Therefore, nsHtml5StreamParser must never be refcounted from
+ * the parser thread!
+ *
+ * To work around this limitation, runnables posted by the main thread to the
+ * parser thread hold their reference to the stream parser in an
+ * nsHtml5RefPtr. Upon creation, nsHtml5RefPtr addrefs the object it holds
+ * just like a regular nsRefPtr. This is OK, since the creation of the
+ * runnable and the nsHtml5RefPtr happens on the main thread.
+ *
+ * When the runnable is done on the parser thread, the destructor of
+ * nsHtml5RefPtr runs there. It doesn't call Release on the held object
+ * directly. Instead, it posts another runnable back to the main thread where
+ * that runnable calls Release on the wrapped object.
+ *
+ * When posting runnables in the other direction, the runnables have to be
+ * created on the main thread when nsHtml5StreamParser is instantiated and
+ * held for the lifetime of the nsHtml5StreamParser. This works, because the
+ * same runnabled can be dispatched multiple times and currently runnables
+ * posted from the parser thread to main thread don't need to wrap any
+ * runnable-specific data. (In the other direction, the runnables most notably
+ * wrap the byte data of the stream.)
+ */
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHtml5StreamParser)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHtml5StreamParser)
+
+NS_INTERFACE_TABLE_HEAD(nsHtml5StreamParser)
+ NS_INTERFACE_TABLE(nsHtml5StreamParser,
+ nsICharsetDetectionObserver)
+ NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsHtml5StreamParser)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsHtml5StreamParser)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsHtml5StreamParser)
+ tmp->DropTimer();
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mObserver)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mRequest)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
+ tmp->mExecutorFlusher = nullptr;
+ tmp->mLoadFlusher = nullptr;
+ tmp->mExecutor = nullptr;
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mChardet)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsHtml5StreamParser)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObserver)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRequest)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
+ // hack: count the strongly owned edge wrapped in the runnable
+ if (tmp->mExecutorFlusher) {
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExecutorFlusher->mExecutor");
+ cb.NoteXPCOMChild(static_cast<nsIContentSink*> (tmp->mExecutor));
+ }
+ // hack: count the strongly owned edge wrapped in the runnable
+ if (tmp->mLoadFlusher) {
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mLoadFlusher->mExecutor");
+ cb.NoteXPCOMChild(static_cast<nsIContentSink*> (tmp->mExecutor));
+ }
+ // hack: count self if held by mChardet
+ if (tmp->mChardet) {
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mChardet->mObserver");
+ cb.NoteXPCOMChild(static_cast<nsICharsetDetectionObserver*>(tmp));
+ }
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+class nsHtml5ExecutorFlusher : public Runnable
+{
+ private:
+ RefPtr<nsHtml5TreeOpExecutor> mExecutor;
+ public:
+ explicit nsHtml5ExecutorFlusher(nsHtml5TreeOpExecutor* aExecutor)
+ : mExecutor(aExecutor)
+ {}
+ NS_IMETHOD Run() override
+ {
+ if (!mExecutor->isInList()) {
+ mExecutor->RunFlushLoop();
+ }
+ return NS_OK;
+ }
+};
+
+class nsHtml5LoadFlusher : public Runnable
+{
+ private:
+ RefPtr<nsHtml5TreeOpExecutor> mExecutor;
+ public:
+ explicit nsHtml5LoadFlusher(nsHtml5TreeOpExecutor* aExecutor)
+ : mExecutor(aExecutor)
+ {}
+ NS_IMETHOD Run() override
+ {
+ mExecutor->FlushSpeculativeLoads();
+ return NS_OK;
+ }
+};
+
+nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
+ nsHtml5Parser* aOwner,
+ eParserMode aMode)
+ : mFirstBuffer(nullptr) // Will be filled when starting
+ , mLastBuffer(nullptr) // Will be filled when starting
+ , mExecutor(aExecutor)
+ , mTreeBuilder(new nsHtml5TreeBuilder((aMode == VIEW_SOURCE_HTML ||
+ aMode == VIEW_SOURCE_XML) ?
+ nullptr : mExecutor->GetStage(),
+ aMode == NORMAL ?
+ mExecutor->GetStage() : nullptr))
+ , mTokenizer(new nsHtml5Tokenizer(mTreeBuilder, aMode == VIEW_SOURCE_XML))
+ , mTokenizerMutex("nsHtml5StreamParser mTokenizerMutex")
+ , mOwner(aOwner)
+ , mSpeculationMutex("nsHtml5StreamParser mSpeculationMutex")
+ , mTerminatedMutex("nsHtml5StreamParser mTerminatedMutex")
+ , mThread(nsHtml5Module::GetStreamParserThread())
+ , mExecutorFlusher(new nsHtml5ExecutorFlusher(aExecutor))
+ , mLoadFlusher(new nsHtml5LoadFlusher(aExecutor))
+ , mFlushTimer(do_CreateInstance("@mozilla.org/timer;1"))
+ , mMode(aMode)
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ mFlushTimer->SetTarget(mThread);
+#ifdef DEBUG
+ mAtomTable.SetPermittedLookupThread(mThread);
+#endif
+ mTokenizer->setInterner(&mAtomTable);
+ mTokenizer->setEncodingDeclarationHandler(this);
+
+ if (aMode == VIEW_SOURCE_HTML || aMode == VIEW_SOURCE_XML) {
+ nsHtml5Highlighter* highlighter =
+ new nsHtml5Highlighter(mExecutor->GetStage());
+ mTokenizer->EnableViewSource(highlighter); // takes ownership
+ mTreeBuilder->EnableViewSource(highlighter); // doesn't own
+ }
+
+ // Chardet instantiation adapted from File.
+ // Chardet is initialized here even if it turns out to be useless
+ // to make the chardet refcount its observer (nsHtml5StreamParser)
+ // on the main thread.
+ const nsAdoptingCString& detectorName =
+ Preferences::GetLocalizedCString("intl.charset.detector");
+ if (!detectorName.IsEmpty()) {
+ nsAutoCString detectorContractID;
+ detectorContractID.AssignLiteral(NS_CHARSET_DETECTOR_CONTRACTID_BASE);
+ detectorContractID += detectorName;
+ if ((mChardet = do_CreateInstance(detectorContractID.get()))) {
+ (void) mChardet->Init(this);
+ mFeedChardet = true;
+ }
+ }
+
+ // There's a zeroing operator new for everything else
+}
+
+nsHtml5StreamParser::~nsHtml5StreamParser()
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ mTokenizer->end();
+ NS_ASSERTION(!mFlushTimer, "Flush timer was not dropped before dtor!");
+#ifdef DEBUG
+ mRequest = nullptr;
+ mObserver = nullptr;
+ mUnicodeDecoder = nullptr;
+ mSniffingBuffer = nullptr;
+ mMetaScanner = nullptr;
+ mFirstBuffer = nullptr;
+ mExecutor = nullptr;
+ mTreeBuilder = nullptr;
+ mTokenizer = nullptr;
+ mOwner = nullptr;
+#endif
+}
+
+nsresult
+nsHtml5StreamParser::GetChannel(nsIChannel** aChannel)
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ return mRequest ? CallQueryInterface(mRequest, aChannel) :
+ NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsHtml5StreamParser::Notify(const char* aCharset, nsDetectionConfident aConf)
+{
+ NS_ASSERTION(IsParserThread(), "Wrong thread!");
+ if (aConf == eBestAnswer || aConf == eSureAnswer) {
+ mFeedChardet = false; // just in case
+ nsAutoCString encoding;
+ if (!EncodingUtils::FindEncodingForLabelNoReplacement(
+ nsDependentCString(aCharset), encoding)) {
+ return NS_OK;
+ }
+ if (HasDecoder()) {
+ if (mCharset.Equals(encoding)) {
+ NS_ASSERTION(mCharsetSource < kCharsetFromAutoDetection,
+ "Why are we running chardet at all?");
+ mCharsetSource = kCharsetFromAutoDetection;
+ mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
+ } else {
+ // We've already committed to a decoder. Request a reload from the
+ // docshell.
+ mTreeBuilder->NeedsCharsetSwitchTo(encoding,
+ kCharsetFromAutoDetection,
+ 0);
+ FlushTreeOpsAndDisarmTimer();
+ Interrupt();
+ }
+ } else {
+ // Got a confident answer from the sniffing buffer. That code will
+ // take care of setting up the decoder.
+ mCharset.Assign(encoding);
+ mCharsetSource = kCharsetFromAutoDetection;
+ mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
+ }
+ }
+ return NS_OK;
+}
+
+void
+nsHtml5StreamParser::SetViewSourceTitle(nsIURI* aURL)
+{
+ if (aURL) {
+ nsCOMPtr<nsIURI> temp;
+ bool isViewSource;
+ aURL->SchemeIs("view-source", &isViewSource);
+ if (isViewSource) {
+ nsCOMPtr<nsINestedURI> nested = do_QueryInterface(aURL);
+ nested->GetInnerURI(getter_AddRefs(temp));
+ } else {
+ temp = aURL;
+ }
+ bool isData;
+ temp->SchemeIs("data", &isData);
+ if (isData) {
+ // Avoid showing potentially huge data: URLs. The three last bytes are
+ // UTF-8 for an ellipsis.
+ mViewSourceTitle.AssignLiteral("data:\xE2\x80\xA6");
+ } else {
+ nsresult rv = temp->GetSpec(mViewSourceTitle);
+ if (NS_FAILED(rv)) {
+ mViewSourceTitle.AssignLiteral("\xE2\x80\xA6");
+ }
+ }
+ }
+}
+
+nsresult
+nsHtml5StreamParser::SetupDecodingAndWriteSniffingBufferAndCurrentSegment(const uint8_t* aFromSegment, // can be null
+ uint32_t aCount,
+ uint32_t* aWriteCount)
+{
+ NS_ASSERTION(IsParserThread(), "Wrong thread!");
+ nsresult rv = NS_OK;
+ mUnicodeDecoder = EncodingUtils::DecoderForEncoding(mCharset);
+ if (mSniffingBuffer) {
+ uint32_t writeCount;
+ rv = WriteStreamBytes(mSniffingBuffer.get(), mSniffingLength, &writeCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+ mSniffingBuffer = nullptr;
+ }
+ mMetaScanner = nullptr;
+ if (aFromSegment) {
+ rv = WriteStreamBytes(aFromSegment, aCount, aWriteCount);
+ }
+ return rv;
+}
+
+nsresult
+nsHtml5StreamParser::SetupDecodingFromBom(const char* aDecoderCharsetName)
+{
+ NS_ASSERTION(IsParserThread(), "Wrong thread!");
+ mCharset.Assign(aDecoderCharsetName);
+ mUnicodeDecoder = EncodingUtils::DecoderForEncoding(mCharset);
+ mCharsetSource = kCharsetFromByteOrderMark;
+ mFeedChardet = false;
+ mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
+ mSniffingBuffer = nullptr;
+ mMetaScanner = nullptr;
+ mBomState = BOM_SNIFFING_OVER;
+ return NS_OK;
+}
+
+void
+nsHtml5StreamParser::SniffBOMlessUTF16BasicLatin(const uint8_t* aFromSegment,
+ uint32_t aCountToSniffingLimit)
+{
+ // Avoid underspecified heuristic craziness for XHR
+ if (mMode == LOAD_AS_DATA) {
+ return;
+ }
+ // Make sure there's enough data. Require room for "<title></title>"
+ if (mSniffingLength + aCountToSniffingLimit < 30) {
+ return;
+ }
+ // even-numbered bytes tracked at 0, odd-numbered bytes tracked at 1
+ bool byteZero[2] = { false, false };
+ bool byteNonZero[2] = { false, false };
+ uint32_t i = 0;
+ if (mSniffingBuffer) {
+ for (; i < mSniffingLength; ++i) {
+ if (mSniffingBuffer[i]) {
+ if (byteNonZero[1 - (i % 2)]) {
+ return;
+ }
+ byteNonZero[i % 2] = true;
+ } else {
+ if (byteZero[1 - (i % 2)]) {
+ return;
+ }
+ byteZero[i % 2] = true;
+ }
+ }
+ }
+ if (aFromSegment) {
+ for (uint32_t j = 0; j < aCountToSniffingLimit; ++j) {
+ if (aFromSegment[j]) {
+ if (byteNonZero[1 - ((i + j) % 2)]) {
+ return;
+ }
+ byteNonZero[(i + j) % 2] = true;
+ } else {
+ if (byteZero[1 - ((i + j) % 2)]) {
+ return;
+ }
+ byteZero[(i + j) % 2] = true;
+ }
+ }
+ }
+
+ if (byteNonZero[0]) {
+ mCharset.AssignLiteral("UTF-16LE");
+ } else {
+ mCharset.AssignLiteral("UTF-16BE");
+ }
+ mCharsetSource = kCharsetFromIrreversibleAutoDetection;
+ mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
+ mFeedChardet = false;
+ mTreeBuilder->MaybeComplainAboutCharset("EncBomlessUtf16",
+ true,
+ 0);
+
+}
+
+void
+nsHtml5StreamParser::SetEncodingFromExpat(const char16_t* aEncoding)
+{
+ if (aEncoding) {
+ nsDependentString utf16(aEncoding);
+ nsAutoCString utf8;
+ CopyUTF16toUTF8(utf16, utf8);
+ if (PreferredForInternalEncodingDecl(utf8)) {
+ mCharset.Assign(utf8);
+ mCharsetSource = kCharsetFromMetaTag; // closest for XML
+ return;
+ }
+ // else the page declared an encoding Gecko doesn't support and we'd
+ // end up defaulting to UTF-8 anyway. Might as well fall through here
+ // right away and let the encoding be set to UTF-8 which we'd default to
+ // anyway.
+ }
+ mCharset.AssignLiteral("UTF-8"); // XML defaults to UTF-8 without a BOM
+ mCharsetSource = kCharsetFromMetaTag; // means confident
+}
+
+// A separate user data struct is used instead of passing the
+// nsHtml5StreamParser instance as user data in order to avoid including
+// expat.h in nsHtml5StreamParser.h. Doing that would cause naming conflicts.
+// Using a separate user data struct also avoids bloating nsHtml5StreamParser
+// by one pointer.
+struct UserData {
+ XML_Parser mExpat;
+ nsHtml5StreamParser* mStreamParser;
+};
+
+// Using no-namespace handler callbacks to avoid including expat.h in
+// nsHtml5StreamParser.h, since doing so would cause naming conclicts.
+static void
+HandleXMLDeclaration(void* aUserData,
+ const XML_Char* aVersion,
+ const XML_Char* aEncoding,
+ int aStandalone)
+{
+ UserData* ud = static_cast<UserData*>(aUserData);
+ ud->mStreamParser->SetEncodingFromExpat(
+ reinterpret_cast<const char16_t*>(aEncoding));
+ XML_StopParser(ud->mExpat, false);
+}
+
+static void
+HandleStartElement(void* aUserData,
+ const XML_Char* aName,
+ const XML_Char **aAtts)
+{
+ UserData* ud = static_cast<UserData*>(aUserData);
+ XML_StopParser(ud->mExpat, false);
+}
+
+static void
+HandleEndElement(void* aUserData,
+ const XML_Char* aName)
+{
+ UserData* ud = static_cast<UserData*>(aUserData);
+ XML_StopParser(ud->mExpat, false);
+}
+
+static void
+HandleComment(void* aUserData,
+ const XML_Char* aName)
+{
+ UserData* ud = static_cast<UserData*>(aUserData);
+ XML_StopParser(ud->mExpat, false);
+}
+
+static void
+HandleProcessingInstruction(void* aUserData,
+ const XML_Char* aTarget,
+ const XML_Char* aData)
+{
+ UserData* ud = static_cast<UserData*>(aUserData);
+ XML_StopParser(ud->mExpat, false);
+}
+
+nsresult
+nsHtml5StreamParser::FinalizeSniffing(const uint8_t* aFromSegment, // can be null
+ uint32_t aCount,
+ uint32_t* aWriteCount,
+ uint32_t aCountToSniffingLimit)
+{
+ NS_ASSERTION(IsParserThread(), "Wrong thread!");
+ NS_ASSERTION(mCharsetSource < kCharsetFromParentForced,
+ "Should not finalize sniffing when using forced charset.");
+ if (mMode == VIEW_SOURCE_XML) {
+ static const XML_Memory_Handling_Suite memsuite =
+ {
+ (void *(*)(size_t))moz_xmalloc,
+ (void *(*)(void *, size_t))moz_xrealloc,
+ free
+ };
+
+ static const char16_t kExpatSeparator[] = { 0xFFFF, '\0' };
+
+ static const char16_t kISO88591[] =
+ { 'I', 'S', 'O', '-', '8', '8', '5', '9', '-', '1', '\0' };
+
+ UserData ud;
+ ud.mStreamParser = this;
+
+ // If we got this far, the stream didn't have a BOM. UTF-16-encoded XML
+ // documents MUST begin with a BOM. We don't support EBCDIC and such.
+ // Thus, at this point, what we have is garbage or something encoded using
+ // a rough ASCII superset. ISO-8859-1 allows us to decode ASCII bytes
+ // without throwing errors when bytes have the most significant bit set
+ // and without triggering expat's unknown encoding code paths. This is
+ // enough to be able to use expat to parse the XML declaration in order
+ // to extract the encoding name from it.
+ ud.mExpat = XML_ParserCreate_MM(kISO88591, &memsuite, kExpatSeparator);
+ XML_SetXmlDeclHandler(ud.mExpat, HandleXMLDeclaration);
+ XML_SetElementHandler(ud.mExpat, HandleStartElement, HandleEndElement);
+ XML_SetCommentHandler(ud.mExpat, HandleComment);
+ XML_SetProcessingInstructionHandler(ud.mExpat, HandleProcessingInstruction);
+ XML_SetUserData(ud.mExpat, static_cast<void*>(&ud));
+
+ XML_Status status = XML_STATUS_OK;
+
+ // aFromSegment points to the data obtained from the current network
+ // event. mSniffingBuffer (if it exists) contains the data obtained before
+ // the current event. Thus, mSniffingLenth bytes of mSniffingBuffer
+ // followed by aCountToSniffingLimit bytes from aFromSegment are the
+ // first 1024 bytes of the file (or the file as a whole if the file is
+ // 1024 bytes long or shorter). Thus, we parse both buffers, but if the
+ // first call succeeds already, we skip parsing the second buffer.
+ if (mSniffingBuffer) {
+ status = XML_Parse(ud.mExpat,
+ reinterpret_cast<const char*>(mSniffingBuffer.get()),
+ mSniffingLength,
+ false);
+ }
+ if (status == XML_STATUS_OK &&
+ mCharsetSource < kCharsetFromMetaTag &&
+ aFromSegment) {
+ status = XML_Parse(ud.mExpat,
+ reinterpret_cast<const char*>(aFromSegment),
+ aCountToSniffingLimit,
+ false);
+ }
+ XML_ParserFree(ud.mExpat);
+
+ if (mCharsetSource < kCharsetFromMetaTag) {
+ // Failed to get an encoding from the XML declaration. XML defaults
+ // confidently to UTF-8 in this case.
+ // It is also possible that the document has an XML declaration that is
+ // longer than 1024 bytes, but that case is not worth worrying about.
+ mCharset.AssignLiteral("UTF-8");
+ mCharsetSource = kCharsetFromMetaTag; // means confident
+ }
+
+ return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment,
+ aCount,
+ aWriteCount);
+ }
+
+ // meta scan failed.
+ if (mCharsetSource >= kCharsetFromHintPrevDoc) {
+ mFeedChardet = false;
+ return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment, aCount, aWriteCount);
+ }
+ // Check for BOMless UTF-16 with Basic
+ // Latin content for compat with IE. See bug 631751.
+ SniffBOMlessUTF16BasicLatin(aFromSegment, aCountToSniffingLimit);
+ // the charset may have been set now
+ // maybe try chardet now;
+ if (mFeedChardet) {
+ bool dontFeed;
+ nsresult rv;
+ if (mSniffingBuffer) {
+ rv = mChardet->DoIt((const char*)mSniffingBuffer.get(), mSniffingLength, &dontFeed);
+ mFeedChardet = !dontFeed;
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ if (mFeedChardet && aFromSegment) {
+ rv = mChardet->DoIt((const char*)aFromSegment,
+ // Avoid buffer boundary-dependent behavior when
+ // reparsing is forbidden. If reparse is forbidden,
+ // act as if we only saw the first 1024 bytes.
+ // When reparsing isn't forbidden, buffer boundaries
+ // can have an effect on whether the page is loaded
+ // once or twice. :-(
+ mReparseForbidden ? aCountToSniffingLimit : aCount,
+ &dontFeed);
+ mFeedChardet = !dontFeed;
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ if (mFeedChardet && (!aFromSegment || mReparseForbidden)) {
+ // mReparseForbidden is checked so that we get to use the sniffing
+ // buffer with the best guess so far if we aren't allowed to guess
+ // better later.
+ mFeedChardet = false;
+ rv = mChardet->Done();
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ // fall thru; callback may have changed charset
+ }
+ if (mCharsetSource == kCharsetUninitialized) {
+ // Hopefully this case is never needed, but dealing with it anyway
+ mCharset.AssignLiteral("windows-1252");
+ mCharsetSource = kCharsetFromFallback;
+ mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
+ } else if (mMode == LOAD_AS_DATA &&
+ mCharsetSource == kCharsetFromFallback) {
+ NS_ASSERTION(mReparseForbidden, "Reparse should be forbidden for XHR");
+ NS_ASSERTION(!mFeedChardet, "Should not feed chardet for XHR");
+ NS_ASSERTION(mCharset.EqualsLiteral("UTF-8"),
+ "XHR should default to UTF-8");
+ // Now mark charset source as non-weak to signal that we have a decision
+ mCharsetSource = kCharsetFromDocTypeDefault;
+ mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
+ }
+ return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment, aCount, aWriteCount);
+}
+
+nsresult
+nsHtml5StreamParser::SniffStreamBytes(const uint8_t* aFromSegment,
+ uint32_t aCount,
+ uint32_t* aWriteCount)
+{
+ NS_ASSERTION(IsParserThread(), "Wrong thread!");
+ nsresult rv = NS_OK;
+ uint32_t writeCount;
+
+ // mCharset and mCharsetSource potentially have come from channel or higher
+ // by now. If we find a BOM, SetupDecodingFromBom() will overwrite them.
+ // If we don't find a BOM, the previously set values of mCharset and
+ // mCharsetSource are not modified by the BOM sniffing here.
+ for (uint32_t i = 0; i < aCount && mBomState != BOM_SNIFFING_OVER; i++) {
+ switch (mBomState) {
+ case BOM_SNIFFING_NOT_STARTED:
+ NS_ASSERTION(i == 0, "Bad BOM sniffing state.");
+ switch (*aFromSegment) {
+ case 0xEF:
+ mBomState = SEEN_UTF_8_FIRST_BYTE;
+ break;
+ case 0xFF:
+ mBomState = SEEN_UTF_16_LE_FIRST_BYTE;
+ break;
+ case 0xFE:
+ mBomState = SEEN_UTF_16_BE_FIRST_BYTE;
+ break;
+ default:
+ mBomState = BOM_SNIFFING_OVER;
+ break;
+ }
+ break;
+ case SEEN_UTF_16_LE_FIRST_BYTE:
+ if (aFromSegment[i] == 0xFE) {
+ rv = SetupDecodingFromBom("UTF-16LE"); // upper case is the raw form
+ NS_ENSURE_SUCCESS(rv, rv);
+ uint32_t count = aCount - (i + 1);
+ rv = WriteStreamBytes(aFromSegment + (i + 1), count, &writeCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+ *aWriteCount = writeCount + (i + 1);
+ return rv;
+ }
+ mBomState = BOM_SNIFFING_OVER;
+ break;
+ case SEEN_UTF_16_BE_FIRST_BYTE:
+ if (aFromSegment[i] == 0xFF) {
+ rv = SetupDecodingFromBom("UTF-16BE"); // upper case is the raw form
+ NS_ENSURE_SUCCESS(rv, rv);
+ uint32_t count = aCount - (i + 1);
+ rv = WriteStreamBytes(aFromSegment + (i + 1), count, &writeCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+ *aWriteCount = writeCount + (i + 1);
+ return rv;
+ }
+ mBomState = BOM_SNIFFING_OVER;
+ break;
+ case SEEN_UTF_8_FIRST_BYTE:
+ if (aFromSegment[i] == 0xBB) {
+ mBomState = SEEN_UTF_8_SECOND_BYTE;
+ } else {
+ mBomState = BOM_SNIFFING_OVER;
+ }
+ break;
+ case SEEN_UTF_8_SECOND_BYTE:
+ if (aFromSegment[i] == 0xBF) {
+ rv = SetupDecodingFromBom("UTF-8"); // upper case is the raw form
+ NS_ENSURE_SUCCESS(rv, rv);
+ uint32_t count = aCount - (i + 1);
+ rv = WriteStreamBytes(aFromSegment + (i + 1), count, &writeCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+ *aWriteCount = writeCount + (i + 1);
+ return rv;
+ }
+ mBomState = BOM_SNIFFING_OVER;
+ break;
+ default:
+ mBomState = BOM_SNIFFING_OVER;
+ break;
+ }
+ }
+ // if we get here, there either was no BOM or the BOM sniffing isn't complete
+ // yet
+
+ MOZ_ASSERT(mCharsetSource != kCharsetFromByteOrderMark,
+ "Should not come here if BOM was found.");
+ MOZ_ASSERT(mCharsetSource != kCharsetFromOtherComponent,
+ "kCharsetFromOtherComponent is for XSLT.");
+
+ if (mBomState == BOM_SNIFFING_OVER &&
+ mCharsetSource == kCharsetFromChannel) {
+ // There was no BOM and the charset came from channel. mCharset
+ // still contains the charset from the channel as set by an
+ // earlier call to SetDocumentCharset(), since we didn't find a BOM and
+ // overwrite mCharset. (Note that if the user has overridden the charset,
+ // we don't come here but check <meta> for XSS-dangerous charsets first.)
+ mFeedChardet = false;
+ mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
+ return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment,
+ aCount, aWriteCount);
+ }
+
+ if (!mMetaScanner && (mMode == NORMAL ||
+ mMode == VIEW_SOURCE_HTML ||
+ mMode == LOAD_AS_DATA)) {
+ mMetaScanner = new nsHtml5MetaScanner(mTreeBuilder);
+ }
+
+ if (mSniffingLength + aCount >= NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE) {
+ // this is the last buffer
+ uint32_t countToSniffingLimit =
+ NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE - mSniffingLength;
+ if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML || mMode == LOAD_AS_DATA) {
+ nsHtml5ByteReadable readable(aFromSegment, aFromSegment +
+ countToSniffingLimit);
+ nsAutoCString encoding;
+ mMetaScanner->sniff(&readable, encoding);
+ // Due to the way nsHtml5Portability reports OOM, ask the tree buider
+ nsresult rv;
+ if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
+ MarkAsBroken(rv);
+ return rv;
+ }
+ if (!encoding.IsEmpty()) {
+ // meta scan successful; honor overrides unless meta is XSS-dangerous
+ if ((mCharsetSource == kCharsetFromParentForced ||
+ mCharsetSource == kCharsetFromUserForced) &&
+ EncodingUtils::IsAsciiCompatible(encoding)) {
+ // Honor override
+ return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(
+ aFromSegment, aCount, aWriteCount);
+ }
+ mCharset.Assign(encoding);
+ mCharsetSource = kCharsetFromMetaPrescan;
+ mFeedChardet = false;
+ mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
+ return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(
+ aFromSegment, aCount, aWriteCount);
+ }
+ }
+ if (mCharsetSource == kCharsetFromParentForced ||
+ mCharsetSource == kCharsetFromUserForced) {
+ // meta not found, honor override
+ return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(
+ aFromSegment, aCount, aWriteCount);
+ }
+ return FinalizeSniffing(aFromSegment, aCount, aWriteCount,
+ countToSniffingLimit);
+ }
+
+ // not the last buffer
+ if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML || mMode == LOAD_AS_DATA) {
+ nsHtml5ByteReadable readable(aFromSegment, aFromSegment + aCount);
+ nsAutoCString encoding;
+ mMetaScanner->sniff(&readable, encoding);
+ // Due to the way nsHtml5Portability reports OOM, ask the tree buider
+ nsresult rv;
+ if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
+ MarkAsBroken(rv);
+ return rv;
+ }
+ if (!encoding.IsEmpty()) {
+ // meta scan successful; honor overrides unless meta is XSS-dangerous
+ if ((mCharsetSource == kCharsetFromParentForced ||
+ mCharsetSource == kCharsetFromUserForced) &&
+ EncodingUtils::IsAsciiCompatible(encoding)) {
+ // Honor override
+ return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment,
+ aCount, aWriteCount);
+ }
+ mCharset.Assign(encoding);
+ mCharsetSource = kCharsetFromMetaPrescan;
+ mFeedChardet = false;
+ mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
+ return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment,
+ aCount, aWriteCount);
+ }
+ }
+
+ if (!mSniffingBuffer) {
+ mSniffingBuffer =
+ MakeUniqueFallible<uint8_t[]>(NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE);
+ if (!mSniffingBuffer) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ memcpy(&mSniffingBuffer[mSniffingLength], aFromSegment, aCount);
+ mSniffingLength += aCount;
+ *aWriteCount = aCount;
+ return NS_OK;
+}
+
+nsresult
+nsHtml5StreamParser::WriteStreamBytes(const uint8_t* aFromSegment,
+ uint32_t aCount,
+ uint32_t* aWriteCount)
+{
+ NS_ASSERTION(IsParserThread(), "Wrong thread!");
+ // mLastBuffer should always point to a buffer of the size
+ // NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE.
+ if (!mLastBuffer) {
+ NS_WARNING("mLastBuffer should not be null!");
+ MarkAsBroken(NS_ERROR_NULL_POINTER);
+ return NS_ERROR_NULL_POINTER;
+ }
+ if (mLastBuffer->getEnd() == NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE) {
+ RefPtr<nsHtml5OwningUTF16Buffer> newBuf =
+ nsHtml5OwningUTF16Buffer::FalliblyCreate(
+ NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE);
+ if (!newBuf) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ mLastBuffer = (mLastBuffer->next = newBuf.forget());
+ }
+ int32_t totalByteCount = 0;
+ for (;;) {
+ int32_t end = mLastBuffer->getEnd();
+ int32_t byteCount = aCount - totalByteCount;
+ int32_t utf16Count = NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE - end;
+
+ NS_ASSERTION(utf16Count, "Trying to convert into a buffer with no free space!");
+ // byteCount may be zero to force the decoder to output a pending surrogate
+ // pair.
+
+ nsresult convResult = mUnicodeDecoder->Convert((const char*)aFromSegment, &byteCount, mLastBuffer->getBuffer() + end, &utf16Count);
+ MOZ_ASSERT(NS_SUCCEEDED(convResult));
+
+ end += utf16Count;
+ mLastBuffer->setEnd(end);
+ totalByteCount += byteCount;
+ aFromSegment += byteCount;
+
+ NS_ASSERTION(end <= NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE,
+ "The Unicode decoder wrote too much data.");
+ NS_ASSERTION(byteCount >= -1, "The decoder consumed fewer than -1 bytes.");
+
+ if (convResult == NS_PARTIAL_MORE_OUTPUT) {
+ RefPtr<nsHtml5OwningUTF16Buffer> newBuf =
+ nsHtml5OwningUTF16Buffer::FalliblyCreate(
+ NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE);
+ if (!newBuf) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ mLastBuffer = (mLastBuffer->next = newBuf.forget());
+ // All input may have been consumed if there is a pending surrogate pair
+ // that doesn't fit in the output buffer. Loop back to push a zero-length
+ // input to the decoder in that case.
+ } else {
+ NS_ASSERTION(totalByteCount == (int32_t)aCount,
+ "The Unicode decoder consumed the wrong number of bytes.");
+ *aWriteCount = (uint32_t)totalByteCount;
+ return NS_OK;
+ }
+ }
+}
+
+nsresult
+nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
+{
+ NS_PRECONDITION(STREAM_NOT_STARTED == mStreamState,
+ "Got OnStartRequest when the stream had already started.");
+ NS_PRECONDITION(!mExecutor->HasStarted(),
+ "Got OnStartRequest at the wrong stage in the executor life cycle.");
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ if (mObserver) {
+ mObserver->OnStartRequest(aRequest, aContext);
+ }
+ mRequest = aRequest;
+
+ mStreamState = STREAM_BEING_READ;
+
+ if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
+ mTokenizer->StartViewSource(NS_ConvertUTF8toUTF16(mViewSourceTitle));
+ }
+
+ // For View Source, the parser should run with scripts "enabled" if a normal
+ // load would have scripts enabled.
+ bool scriptingEnabled = mMode == LOAD_AS_DATA ?
+ false : mExecutor->IsScriptEnabled();
+ mOwner->StartTokenizer(scriptingEnabled);
+
+ bool isSrcdoc = false;
+ nsCOMPtr<nsIChannel> channel;
+ nsresult rv = GetChannel(getter_AddRefs(channel));
+ if (NS_SUCCEEDED(rv)) {
+ isSrcdoc = NS_IsSrcdocChannel(channel);
+ }
+ mTreeBuilder->setIsSrcdocDocument(isSrcdoc);
+ mTreeBuilder->setScriptingEnabled(scriptingEnabled);
+ mTreeBuilder->SetPreventScriptExecution(!((mMode == NORMAL) &&
+ scriptingEnabled));
+ mTokenizer->start();
+ mExecutor->Start();
+ mExecutor->StartReadingFromStage();
+
+ if (mMode == PLAIN_TEXT) {
+ mTreeBuilder->StartPlainText();
+ mTokenizer->StartPlainText();
+ } else if (mMode == VIEW_SOURCE_PLAIN) {
+ nsAutoString viewSourceTitle;
+ CopyUTF8toUTF16(mViewSourceTitle, viewSourceTitle);
+ mTreeBuilder->EnsureBufferSpace(viewSourceTitle.Length());
+ mTreeBuilder->StartPlainTextViewSource(viewSourceTitle);
+ mTokenizer->StartPlainText();
+ }
+
+ /*
+ * If you move the following line, be very careful not to cause
+ * WillBuildModel to be called before the document has had its
+ * script global object set.
+ */
+ rv = mExecutor->WillBuildModel(eDTDMode_unknown);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ RefPtr<nsHtml5OwningUTF16Buffer> newBuf =
+ nsHtml5OwningUTF16Buffer::FalliblyCreate(
+ NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE);
+ if (!newBuf) {
+ // marks this stream parser as terminated,
+ // which prevents entry to code paths that
+ // would use mFirstBuffer or mLastBuffer.
+ return mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
+ }
+ NS_ASSERTION(!mFirstBuffer, "How come we have the first buffer set?");
+ NS_ASSERTION(!mLastBuffer, "How come we have the last buffer set?");
+ mFirstBuffer = mLastBuffer = newBuf;
+
+ rv = NS_OK;
+
+ // The line below means that the encoding can end up being wrong if
+ // a view-source URL is loaded without having the encoding hint from a
+ // previous normal load in the history.
+ mReparseForbidden = !(mMode == NORMAL || mMode == PLAIN_TEXT);
+
+ nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mRequest, &rv));
+ if (NS_SUCCEEDED(rv)) {
+ nsAutoCString method;
+ httpChannel->GetRequestMethod(method);
+ // XXX does Necko have a way to renavigate POST, etc. without hitting
+ // the network?
+ if (!method.EqualsLiteral("GET")) {
+ // This is the old Gecko behavior but the HTML5 spec disagrees.
+ // Don't reparse on POST.
+ mReparseForbidden = true;
+ mFeedChardet = false; // can't restart anyway
+ }
+ }
+
+ // Attempt to retarget delivery of data (via OnDataAvailable) to the parser
+ // thread, rather than through the main thread.
+ nsCOMPtr<nsIThreadRetargetableRequest> threadRetargetableRequest =
+ do_QueryInterface(mRequest, &rv);
+ if (threadRetargetableRequest) {
+ rv = threadRetargetableRequest->RetargetDeliveryTo(mThread);
+ }
+
+ if (NS_FAILED(rv)) {
+ // for now skip warning if we're on child process, since we don't support
+ // off-main thread delivery there yet. This will change with bug 1015466
+ if (!XRE_IsContentProcess()) {
+ NS_WARNING("Failed to retarget HTML data delivery to the parser thread.");
+ }
+ }
+
+ if (mCharsetSource == kCharsetFromParentFrame) {
+ // Remember this in case chardet overwrites mCharsetSource
+ mInitialEncodingWasFromParentFrame = true;
+ }
+
+ if (mCharsetSource >= kCharsetFromAutoDetection) {
+ mFeedChardet = false;
+ }
+
+ nsCOMPtr<nsIWyciwygChannel> wyciwygChannel(do_QueryInterface(mRequest));
+ if (!wyciwygChannel) {
+ // we aren't ready to commit to an encoding yet
+ // leave converter uninstantiated for now
+ return NS_OK;
+ }
+
+ // We are reloading a document.open()ed doc.
+ mReparseForbidden = true;
+ mFeedChardet = false;
+
+ // Instantiate the converter here to avoid BOM sniffing.
+ mUnicodeDecoder = EncodingUtils::DecoderForEncoding(mCharset);
+ return NS_OK;
+}
+
+nsresult
+nsHtml5StreamParser::CheckListenerChain()
+{
+ NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread!");
+ if (!mObserver) {
+ return NS_OK;
+ }
+ nsresult rv;
+ nsCOMPtr<nsIThreadRetargetableStreamListener> retargetable =
+ do_QueryInterface(mObserver, &rv);
+ if (NS_SUCCEEDED(rv) && retargetable) {
+ rv = retargetable->CheckListenerChain();
+ }
+ return rv;
+}
+
+void
+nsHtml5StreamParser::DoStopRequest()
+{
+ NS_ASSERTION(IsParserThread(), "Wrong thread!");
+ NS_PRECONDITION(STREAM_BEING_READ == mStreamState,
+ "Stream ended without being open.");
+ mTokenizerMutex.AssertCurrentThreadOwns();
+
+ if (IsTerminated()) {
+ return;
+ }
+
+ mStreamState = STREAM_ENDED;
+
+ if (!mUnicodeDecoder) {
+ uint32_t writeCount;
+ nsresult rv;
+ if (NS_FAILED(rv = FinalizeSniffing(nullptr, 0, &writeCount, 0))) {
+ MarkAsBroken(rv);
+ return;
+ }
+ } else if (mFeedChardet) {
+ mChardet->Done();
+ }
+
+ if (IsTerminatedOrInterrupted()) {
+ return;
+ }
+
+ ParseAvailableData();
+}
+
+class nsHtml5RequestStopper : public Runnable
+{
+ private:
+ nsHtml5RefPtr<nsHtml5StreamParser> mStreamParser;
+ public:
+ explicit nsHtml5RequestStopper(nsHtml5StreamParser* aStreamParser)
+ : mStreamParser(aStreamParser)
+ {}
+ NS_IMETHOD Run() override
+ {
+ mozilla::MutexAutoLock autoLock(mStreamParser->mTokenizerMutex);
+ mStreamParser->DoStopRequest();
+ return NS_OK;
+ }
+};
+
+nsresult
+nsHtml5StreamParser::OnStopRequest(nsIRequest* aRequest,
+ nsISupports* aContext,
+ nsresult status)
+{
+ NS_ASSERTION(mRequest == aRequest, "Got Stop on wrong stream.");
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ if (mObserver) {
+ mObserver->OnStopRequest(aRequest, aContext, status);
+ }
+ nsCOMPtr<nsIRunnable> stopper = new nsHtml5RequestStopper(this);
+ if (NS_FAILED(mThread->Dispatch(stopper, nsIThread::DISPATCH_NORMAL))) {
+ NS_WARNING("Dispatching StopRequest event failed.");
+ }
+ return NS_OK;
+}
+
+void
+nsHtml5StreamParser::DoDataAvailable(const uint8_t* aBuffer, uint32_t aLength)
+{
+ NS_ASSERTION(IsParserThread(), "Wrong thread!");
+ NS_PRECONDITION(STREAM_BEING_READ == mStreamState,
+ "DoDataAvailable called when stream not open.");
+ mTokenizerMutex.AssertCurrentThreadOwns();
+
+ if (IsTerminated()) {
+ return;
+ }
+
+ uint32_t writeCount;
+ nsresult rv;
+ if (HasDecoder()) {
+ if (mFeedChardet) {
+ bool dontFeed;
+ mChardet->DoIt((const char*)aBuffer, aLength, &dontFeed);
+ mFeedChardet = !dontFeed;
+ }
+ rv = WriteStreamBytes(aBuffer, aLength, &writeCount);
+ } else {
+ rv = SniffStreamBytes(aBuffer, aLength, &writeCount);
+ }
+ if (NS_FAILED(rv)) {
+ MarkAsBroken(rv);
+ return;
+ }
+ NS_ASSERTION(writeCount == aLength, "Wrong number of stream bytes written/sniffed.");
+
+ if (IsTerminatedOrInterrupted()) {
+ return;
+ }
+
+ ParseAvailableData();
+
+ if (mFlushTimerArmed || mSpeculating) {
+ return;
+ }
+
+ mFlushTimer->InitWithFuncCallback(nsHtml5StreamParser::TimerCallback,
+ static_cast<void*> (this),
+ mFlushTimerEverFired ?
+ sTimerInitialDelay :
+ sTimerSubsequentDelay,
+ nsITimer::TYPE_ONE_SHOT);
+ mFlushTimerArmed = true;
+}
+
+class nsHtml5DataAvailable : public Runnable
+{
+ private:
+ nsHtml5RefPtr<nsHtml5StreamParser> mStreamParser;
+ UniquePtr<uint8_t[]> mData;
+ uint32_t mLength;
+ public:
+ nsHtml5DataAvailable(nsHtml5StreamParser* aStreamParser,
+ UniquePtr<uint8_t[]> aData,
+ uint32_t aLength)
+ : mStreamParser(aStreamParser)
+ , mData(Move(aData))
+ , mLength(aLength)
+ {}
+ NS_IMETHOD Run() override
+ {
+ mozilla::MutexAutoLock autoLock(mStreamParser->mTokenizerMutex);
+ mStreamParser->DoDataAvailable(mData.get(), mLength);
+ return NS_OK;
+ }
+};
+
+nsresult
+nsHtml5StreamParser::OnDataAvailable(nsIRequest* aRequest,
+ nsISupports* aContext,
+ nsIInputStream* aInStream,
+ uint64_t aSourceOffset,
+ uint32_t aLength)
+{
+ nsresult rv;
+ if (NS_FAILED(rv = mExecutor->IsBroken())) {
+ return rv;
+ }
+
+ NS_ASSERTION(mRequest == aRequest, "Got data on wrong stream.");
+ uint32_t totalRead;
+ // Main thread to parser thread dispatch requires copying to buffer first.
+ if (NS_IsMainThread()) {
+ auto data = MakeUniqueFallible<uint8_t[]>(aLength);
+ if (!data) {
+ return mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
+ }
+ rv = aInStream->Read(reinterpret_cast<char*>(data.get()),
+ aLength, &totalRead);
+ NS_ENSURE_SUCCESS(rv, rv);
+ NS_ASSERTION(totalRead <= aLength, "Read more bytes than were available?");
+
+ nsCOMPtr<nsIRunnable> dataAvailable = new nsHtml5DataAvailable(this,
+ Move(data),
+ totalRead);
+ if (NS_FAILED(mThread->Dispatch(dataAvailable, nsIThread::DISPATCH_NORMAL))) {
+ NS_WARNING("Dispatching DataAvailable event failed.");
+ }
+ return rv;
+ } else {
+ NS_ASSERTION(IsParserThread(), "Wrong thread!");
+ mozilla::MutexAutoLock autoLock(mTokenizerMutex);
+
+ // Read directly from response buffer.
+ rv = aInStream->ReadSegments(CopySegmentsToParser, this, aLength,
+ &totalRead);
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Failed reading response data to parser");
+ return rv;
+ }
+ return NS_OK;
+ }
+}
+
+/* static */ nsresult
+nsHtml5StreamParser::CopySegmentsToParser(nsIInputStream *aInStream,
+ void *aClosure,
+ const char *aFromSegment,
+ uint32_t aToOffset,
+ uint32_t aCount,
+ uint32_t *aWriteCount)
+{
+ nsHtml5StreamParser* parser = static_cast<nsHtml5StreamParser*>(aClosure);
+
+ parser->DoDataAvailable((const uint8_t*)aFromSegment, aCount);
+ // Assume DoDataAvailable consumed all available bytes.
+ *aWriteCount = aCount;
+ return NS_OK;
+}
+
+bool
+nsHtml5StreamParser::PreferredForInternalEncodingDecl(nsACString& aEncoding)
+{
+ nsAutoCString newEncoding;
+ if (!EncodingUtils::FindEncodingForLabel(aEncoding, newEncoding)) {
+ // the encoding name is bogus
+ mTreeBuilder->MaybeComplainAboutCharset("EncMetaUnsupported",
+ true,
+ mTokenizer->getLineNumber());
+ return false;
+ }
+
+ if (newEncoding.EqualsLiteral("UTF-16BE") ||
+ newEncoding.EqualsLiteral("UTF-16LE")) {
+ mTreeBuilder->MaybeComplainAboutCharset("EncMetaUtf16",
+ true,
+ mTokenizer->getLineNumber());
+ newEncoding.AssignLiteral("UTF-8");
+ }
+
+ if (newEncoding.EqualsLiteral("x-user-defined")) {
+ // WebKit/Blink hack for Indian and Armenian legacy sites
+ mTreeBuilder->MaybeComplainAboutCharset("EncMetaUserDefined",
+ true,
+ mTokenizer->getLineNumber());
+ newEncoding.AssignLiteral("windows-1252");
+ }
+
+ if (newEncoding.Equals(mCharset)) {
+ if (mCharsetSource < kCharsetFromMetaPrescan) {
+ if (mInitialEncodingWasFromParentFrame) {
+ mTreeBuilder->MaybeComplainAboutCharset("EncLateMetaFrame",
+ false,
+ mTokenizer->getLineNumber());
+ } else {
+ mTreeBuilder->MaybeComplainAboutCharset("EncLateMeta",
+ false,
+ mTokenizer->getLineNumber());
+ }
+ }
+ mCharsetSource = kCharsetFromMetaTag; // become confident
+ mFeedChardet = false; // don't feed chardet when confident
+ return false;
+ }
+
+ aEncoding.Assign(newEncoding);
+ return true;
+}
+
+bool
+nsHtml5StreamParser::internalEncodingDeclaration(nsString* aEncoding)
+{
+ // This code needs to stay in sync with
+ // nsHtml5MetaScanner::tryCharset. Unfortunately, the
+ // trickery with member fields there leads to some copy-paste reuse. :-(
+ NS_ASSERTION(IsParserThread(), "Wrong thread!");
+ if (mCharsetSource >= kCharsetFromMetaTag) { // this threshold corresponds to "confident" in the HTML5 spec
+ return false;
+ }
+
+ nsAutoCString newEncoding;
+ CopyUTF16toUTF8(*aEncoding, newEncoding);
+
+ if (!PreferredForInternalEncodingDecl(newEncoding)) {
+ return false;
+ }
+
+ if (mReparseForbidden) {
+ // This mReparseForbidden check happens after the call to
+ // PreferredForInternalEncodingDecl so that if that method calls
+ // MaybeComplainAboutCharset, its charset complaint wins over the one
+ // below.
+ mTreeBuilder->MaybeComplainAboutCharset("EncLateMetaTooLate",
+ true,
+ mTokenizer->getLineNumber());
+ return false; // not reparsing even if we wanted to
+ }
+
+ // Avoid having the chardet ask for another restart after this restart
+ // request.
+ mFeedChardet = false;
+ mTreeBuilder->NeedsCharsetSwitchTo(newEncoding,
+ kCharsetFromMetaTag,
+ mTokenizer->getLineNumber());
+ FlushTreeOpsAndDisarmTimer();
+ Interrupt();
+ // the tree op executor will cause the stream parser to terminate
+ // if the charset switch request is accepted or it'll uninterrupt
+ // if the request failed. Note that if the restart request fails,
+ // we don't bother trying to make chardet resume. Might as well
+ // assume that chardet-requested restarts would fail, too.
+ return true;
+}
+
+void
+nsHtml5StreamParser::FlushTreeOpsAndDisarmTimer()
+{
+ NS_ASSERTION(IsParserThread(), "Wrong thread!");
+ if (mFlushTimerArmed) {
+ // avoid calling Cancel if the flush timer isn't armed to avoid acquiring
+ // a mutex
+ mFlushTimer->Cancel();
+ mFlushTimerArmed = false;
+ }
+ if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
+ mTokenizer->FlushViewSource();
+ }
+ mTreeBuilder->Flush();
+ if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
+ NS_WARNING("failed to dispatch executor flush event");
+ }
+}
+
+void
+nsHtml5StreamParser::ParseAvailableData()
+{
+ NS_ASSERTION(IsParserThread(), "Wrong thread!");
+ mTokenizerMutex.AssertCurrentThreadOwns();
+
+ if (IsTerminatedOrInterrupted()) {
+ return;
+ }
+
+ if (mSpeculating && !IsSpeculationEnabled()) {
+ return;
+ }
+
+ for (;;) {
+ if (!mFirstBuffer->hasMore()) {
+ if (mFirstBuffer == mLastBuffer) {
+ switch (mStreamState) {
+ case STREAM_BEING_READ:
+ // never release the last buffer.
+ if (!mSpeculating) {
+ // reuse buffer space if not speculating
+ mFirstBuffer->setStart(0);
+ mFirstBuffer->setEnd(0);
+ }
+ mTreeBuilder->FlushLoads();
+ // Dispatch this runnable unconditionally, because the loads
+ // that need flushing may have been flushed earlier even if the
+ // flush right above here did nothing.
+ if (NS_FAILED(NS_DispatchToMainThread(mLoadFlusher))) {
+ NS_WARNING("failed to dispatch load flush event");
+ }
+ return; // no more data for now but expecting more
+ case STREAM_ENDED:
+ if (mAtEOF) {
+ return;
+ }
+ mAtEOF = true;
+ if (mCharsetSource < kCharsetFromMetaTag) {
+ if (mInitialEncodingWasFromParentFrame) {
+ // Unfortunately, this check doesn't take effect for
+ // cross-origin frames, so cross-origin ad frames that have
+ // no text and only an image or a Flash embed get the more
+ // severe message from the next if block. The message is
+ // technically accurate, though.
+ mTreeBuilder->MaybeComplainAboutCharset("EncNoDeclarationFrame",
+ false,
+ 0);
+ } else if (mMode == NORMAL) {
+ mTreeBuilder->MaybeComplainAboutCharset("EncNoDeclaration",
+ true,
+ 0);
+ } else if (mMode == PLAIN_TEXT) {
+ mTreeBuilder->MaybeComplainAboutCharset("EncNoDeclarationPlain",
+ true,
+ 0);
+ }
+ }
+ if (NS_SUCCEEDED(mTreeBuilder->IsBroken())) {
+ mTokenizer->eof();
+ nsresult rv;
+ if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
+ MarkAsBroken(rv);
+ } else {
+ mTreeBuilder->StreamEnded();
+ if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
+ mTokenizer->EndViewSource();
+ }
+ }
+ }
+ FlushTreeOpsAndDisarmTimer();
+ return; // no more data and not expecting more
+ default:
+ NS_NOTREACHED("It should be impossible to reach this.");
+ return;
+ }
+ }
+ mFirstBuffer = mFirstBuffer->next;
+ continue;
+ }
+
+ // now we have a non-empty buffer
+ mFirstBuffer->adjust(mLastWasCR);
+ mLastWasCR = false;
+ if (mFirstBuffer->hasMore()) {
+ if (!mTokenizer->EnsureBufferSpace(mFirstBuffer->getLength())) {
+ MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+ mLastWasCR = mTokenizer->tokenizeBuffer(mFirstBuffer);
+ nsresult rv;
+ if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
+ MarkAsBroken(rv);
+ return;
+ }
+ // At this point, internalEncodingDeclaration() may have called
+ // Terminate, but that never happens together with script.
+ // Can't assert that here, though, because it's possible that the main
+ // thread has called Terminate() while this thread was parsing.
+ if (mTreeBuilder->HasScript()) {
+ // HasScript() cannot return true if the tree builder is preventing
+ // script execution.
+ MOZ_ASSERT(mMode == NORMAL);
+ mozilla::MutexAutoLock speculationAutoLock(mSpeculationMutex);
+ nsHtml5Speculation* speculation =
+ new nsHtml5Speculation(mFirstBuffer,
+ mFirstBuffer->getStart(),
+ mTokenizer->getLineNumber(),
+ mTreeBuilder->newSnapshot());
+ mTreeBuilder->AddSnapshotToScript(speculation->GetSnapshot(),
+ speculation->GetStartLineNumber());
+ FlushTreeOpsAndDisarmTimer();
+ mTreeBuilder->SetOpSink(speculation);
+ mSpeculations.AppendElement(speculation); // adopts the pointer
+ mSpeculating = true;
+ }
+ if (IsTerminatedOrInterrupted()) {
+ return;
+ }
+ }
+ continue;
+ }
+}
+
+class nsHtml5StreamParserContinuation : public Runnable
+{
+private:
+ nsHtml5RefPtr<nsHtml5StreamParser> mStreamParser;
+public:
+ explicit nsHtml5StreamParserContinuation(nsHtml5StreamParser* aStreamParser)
+ : mStreamParser(aStreamParser)
+ {}
+ NS_IMETHOD Run() override
+ {
+ mozilla::MutexAutoLock autoLock(mStreamParser->mTokenizerMutex);
+ mStreamParser->Uninterrupt();
+ mStreamParser->ParseAvailableData();
+ return NS_OK;
+ }
+};
+
+void
+nsHtml5StreamParser::ContinueAfterScripts(nsHtml5Tokenizer* aTokenizer,
+ nsHtml5TreeBuilder* aTreeBuilder,
+ bool aLastWasCR)
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ NS_ASSERTION(!(mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML),
+ "ContinueAfterScripts called in view source mode!");
+ if (NS_FAILED(mExecutor->IsBroken())) {
+ return;
+ }
+ #ifdef DEBUG
+ mExecutor->AssertStageEmpty();
+ #endif
+ bool speculationFailed = false;
+ {
+ mozilla::MutexAutoLock speculationAutoLock(mSpeculationMutex);
+ if (mSpeculations.IsEmpty()) {
+ NS_NOTREACHED("ContinueAfterScripts called without speculations.");
+ return;
+ }
+ nsHtml5Speculation* speculation = mSpeculations.ElementAt(0);
+ if (aLastWasCR ||
+ !aTokenizer->isInDataState() ||
+ !aTreeBuilder->snapshotMatches(speculation->GetSnapshot())) {
+ speculationFailed = true;
+ // We've got a failed speculation :-(
+ MaybeDisableFutureSpeculation();
+ Interrupt(); // Make the parser thread release the tokenizer mutex sooner
+ // now fall out of the speculationAutoLock into the tokenizerAutoLock block
+ } else {
+ // We've got a successful speculation!
+ if (mSpeculations.Length() > 1) {
+ // the first speculation isn't the current speculation, so there's
+ // no need to bother the parser thread.
+ speculation->FlushToSink(mExecutor);
+ NS_ASSERTION(!mExecutor->IsScriptExecuting(),
+ "ParseUntilBlocked() was supposed to ensure we don't come "
+ "here when scripts are executing.");
+ NS_ASSERTION(mExecutor->IsInFlushLoop(), "How are we here if "
+ "RunFlushLoop() didn't call ParseUntilBlocked() which is the "
+ "only caller of this method?");
+ mSpeculations.RemoveElementAt(0);
+ return;
+ }
+ // else
+ Interrupt(); // Make the parser thread release the tokenizer mutex sooner
+
+ // now fall through
+ // the first speculation is the current speculation. Need to
+ // release the the speculation mutex and acquire the tokenizer
+ // mutex. (Just acquiring the other mutex here would deadlock)
+ }
+ }
+ {
+ mozilla::MutexAutoLock tokenizerAutoLock(mTokenizerMutex);
+ #ifdef DEBUG
+ {
+ nsCOMPtr<nsIThread> mainThread;
+ NS_GetMainThread(getter_AddRefs(mainThread));
+ mAtomTable.SetPermittedLookupThread(mainThread);
+ }
+ #endif
+ // In principle, the speculation mutex should be acquired here,
+ // but there's no point, because the parser thread only acquires it
+ // when it has also acquired the tokenizer mutex and we are already
+ // holding the tokenizer mutex.
+ if (speculationFailed) {
+ // Rewind the stream
+ mAtEOF = false;
+ nsHtml5Speculation* speculation = mSpeculations.ElementAt(0);
+ mFirstBuffer = speculation->GetBuffer();
+ mFirstBuffer->setStart(speculation->GetStart());
+ mTokenizer->setLineNumber(speculation->GetStartLineNumber());
+
+ nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
+ NS_LITERAL_CSTRING("DOM Events"),
+ mExecutor->GetDocument(),
+ nsContentUtils::eDOM_PROPERTIES,
+ "SpeculationFailed",
+ nullptr, 0,
+ nullptr,
+ EmptyString(),
+ speculation->GetStartLineNumber());
+
+ nsHtml5OwningUTF16Buffer* buffer = mFirstBuffer->next;
+ while (buffer) {
+ buffer->setStart(0);
+ buffer = buffer->next;
+ }
+
+ mSpeculations.Clear(); // potentially a huge number of destructors
+ // run here synchronously on the main thread...
+
+ mTreeBuilder->flushCharacters(); // empty the pending buffer
+ mTreeBuilder->ClearOps(); // now get rid of the failed ops
+
+ mTreeBuilder->SetOpSink(mExecutor->GetStage());
+ mExecutor->StartReadingFromStage();
+ mSpeculating = false;
+
+ // Copy state over
+ mLastWasCR = aLastWasCR;
+ mTokenizer->loadState(aTokenizer);
+ mTreeBuilder->loadState(aTreeBuilder, &mAtomTable);
+ } else {
+ // We've got a successful speculation and at least a moment ago it was
+ // the current speculation
+ mSpeculations.ElementAt(0)->FlushToSink(mExecutor);
+ NS_ASSERTION(!mExecutor->IsScriptExecuting(),
+ "ParseUntilBlocked() was supposed to ensure we don't come "
+ "here when scripts are executing.");
+ NS_ASSERTION(mExecutor->IsInFlushLoop(), "How are we here if "
+ "RunFlushLoop() didn't call ParseUntilBlocked() which is the "
+ "only caller of this method?");
+ mSpeculations.RemoveElementAt(0);
+ if (mSpeculations.IsEmpty()) {
+ // yes, it was still the only speculation. Now stop speculating
+ // However, before telling the executor to read from stage, flush
+ // any pending ops straight to the executor, because otherwise
+ // they remain unflushed until we get more data from the network.
+ mTreeBuilder->SetOpSink(mExecutor);
+ mTreeBuilder->Flush(true);
+ mTreeBuilder->SetOpSink(mExecutor->GetStage());
+ mExecutor->StartReadingFromStage();
+ mSpeculating = false;
+ }
+ }
+ nsCOMPtr<nsIRunnable> event = new nsHtml5StreamParserContinuation(this);
+ if (NS_FAILED(mThread->Dispatch(event, nsIThread::DISPATCH_NORMAL))) {
+ NS_WARNING("Failed to dispatch nsHtml5StreamParserContinuation");
+ }
+ // A stream event might run before this event runs, but that's harmless.
+ #ifdef DEBUG
+ mAtomTable.SetPermittedLookupThread(mThread);
+ #endif
+ }
+}
+
+void
+nsHtml5StreamParser::ContinueAfterFailedCharsetSwitch()
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ nsCOMPtr<nsIRunnable> event = new nsHtml5StreamParserContinuation(this);
+ if (NS_FAILED(mThread->Dispatch(event, nsIThread::DISPATCH_NORMAL))) {
+ NS_WARNING("Failed to dispatch nsHtml5StreamParserContinuation");
+ }
+}
+
+class nsHtml5TimerKungFu : public Runnable
+{
+private:
+ nsHtml5RefPtr<nsHtml5StreamParser> mStreamParser;
+public:
+ explicit nsHtml5TimerKungFu(nsHtml5StreamParser* aStreamParser)
+ : mStreamParser(aStreamParser)
+ {}
+ NS_IMETHOD Run() override
+ {
+ if (mStreamParser->mFlushTimer) {
+ mStreamParser->mFlushTimer->Cancel();
+ mStreamParser->mFlushTimer = nullptr;
+ }
+ return NS_OK;
+ }
+};
+
+void
+nsHtml5StreamParser::DropTimer()
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ /*
+ * Simply nulling out the timer wouldn't work, because if the timer is
+ * armed, it needs to be canceled first. Simply canceling it first wouldn't
+ * work, because nsTimerImpl::Cancel is not safe for calling from outside
+ * the thread where nsTimerImpl::Fire would run. It's not safe to
+ * dispatch a runnable to cancel the timer from the destructor of this
+ * class, because the timer has a weak (void*) pointer back to this instance
+ * of the stream parser and having the timer fire before the runnable
+ * cancels it would make the timer access a deleted object.
+ *
+ * This DropTimer method addresses these issues. This method must be called
+ * on the main thread before the destructor of this class is reached.
+ * The nsHtml5TimerKungFu object has an nsHtml5RefPtr that addrefs this
+ * stream parser object to keep it alive until the runnable is done.
+ * The runnable cancels the timer on the parser thread, drops the timer
+ * and lets nsHtml5RefPtr send a runnable back to the main thread to
+ * release the stream parser.
+ */
+ if (mFlushTimer) {
+ nsCOMPtr<nsIRunnable> event = new nsHtml5TimerKungFu(this);
+ if (NS_FAILED(mThread->Dispatch(event, nsIThread::DISPATCH_NORMAL))) {
+ NS_WARNING("Failed to dispatch TimerKungFu event");
+ }
+ }
+}
+
+// Using a static, because the method name Notify is taken by the chardet
+// callback.
+void
+nsHtml5StreamParser::TimerCallback(nsITimer* aTimer, void* aClosure)
+{
+ (static_cast<nsHtml5StreamParser*> (aClosure))->TimerFlush();
+}
+
+void
+nsHtml5StreamParser::TimerFlush()
+{
+ NS_ASSERTION(IsParserThread(), "Wrong thread!");
+ mozilla::MutexAutoLock autoLock(mTokenizerMutex);
+
+ NS_ASSERTION(!mSpeculating, "Flush timer fired while speculating.");
+
+ // The timer fired if we got here. No need to cancel it. Mark it as
+ // not armed, though.
+ mFlushTimerArmed = false;
+
+ mFlushTimerEverFired = true;
+
+ if (IsTerminatedOrInterrupted()) {
+ return;
+ }
+
+ if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
+ mTreeBuilder->Flush(); // delete useless ops
+ if (mTokenizer->FlushViewSource()) {
+ if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
+ NS_WARNING("failed to dispatch executor flush event");
+ }
+ }
+ } else {
+ // we aren't speculating and we don't know when new data is
+ // going to arrive. Send data to the main thread.
+ if (mTreeBuilder->Flush(true)) {
+ if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
+ NS_WARNING("failed to dispatch executor flush event");
+ }
+ }
+ }
+}
+
+void
+nsHtml5StreamParser::MarkAsBroken(nsresult aRv)
+{
+ NS_ASSERTION(IsParserThread(), "Wrong thread!");
+ mTokenizerMutex.AssertCurrentThreadOwns();
+
+ Terminate();
+ mTreeBuilder->MarkAsBroken(aRv);
+ mozilla::DebugOnly<bool> hadOps = mTreeBuilder->Flush(false);
+ NS_ASSERTION(hadOps, "Should have had the markAsBroken op!");
+ if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
+ NS_WARNING("failed to dispatch executor flush event");
+ }
+}
diff --git a/parser/html/nsHtml5StreamParser.h b/parser/html/nsHtml5StreamParser.h
new file mode 100644
index 000000000..9a38ba067
--- /dev/null
+++ b/parser/html/nsHtml5StreamParser.h
@@ -0,0 +1,579 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5StreamParser_h
+#define nsHtml5StreamParser_h
+
+#include "nsAutoPtr.h"
+#include "nsCOMPtr.h"
+#include "nsICharsetDetectionObserver.h"
+#include "nsHtml5MetaScanner.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5TreeOpExecutor.h"
+#include "nsHtml5OwningUTF16Buffer.h"
+#include "nsIInputStream.h"
+#include "mozilla/Mutex.h"
+#include "mozilla/UniquePtr.h"
+#include "nsHtml5AtomTable.h"
+#include "nsHtml5Speculation.h"
+#include "nsITimer.h"
+#include "nsICharsetDetector.h"
+
+class nsHtml5Parser;
+
+#define NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE 1024
+#define NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE 1024
+
+enum eParserMode {
+ /**
+ * Parse a document normally as HTML.
+ */
+ NORMAL,
+
+ /**
+ * View document as HTML source.
+ */
+ VIEW_SOURCE_HTML,
+
+ /**
+ * View document as XML source
+ */
+ VIEW_SOURCE_XML,
+
+ /**
+ * View document as plain text source
+ */
+ VIEW_SOURCE_PLAIN,
+
+ /**
+ * View document as plain text
+ */
+ PLAIN_TEXT,
+
+ /**
+ * Load as data (XHR)
+ */
+ LOAD_AS_DATA
+};
+
+enum eBomState {
+ /**
+ * BOM sniffing hasn't started.
+ */
+ BOM_SNIFFING_NOT_STARTED = 0,
+
+ /**
+ * BOM sniffing is ongoing, and the first byte of an UTF-16LE BOM has been
+ * seen.
+ */
+ SEEN_UTF_16_LE_FIRST_BYTE = 1,
+
+ /**
+ * BOM sniffing is ongoing, and the first byte of an UTF-16BE BOM has been
+ * seen.
+ */
+ SEEN_UTF_16_BE_FIRST_BYTE = 2,
+
+ /**
+ * BOM sniffing is ongoing, and the first byte of an UTF-8 BOM has been
+ * seen.
+ */
+ SEEN_UTF_8_FIRST_BYTE = 3,
+
+ /**
+ * BOM sniffing is ongoing, and the first and second bytes of an UTF-8 BOM
+ * have been seen.
+ */
+ SEEN_UTF_8_SECOND_BYTE = 4,
+
+ /**
+ * BOM sniffing was started but is now over for whatever reason.
+ */
+ BOM_SNIFFING_OVER = 5
+};
+
+enum eHtml5StreamState {
+ STREAM_NOT_STARTED = 0,
+ STREAM_BEING_READ = 1,
+ STREAM_ENDED = 2
+};
+
+class nsHtml5StreamParser : public nsICharsetDetectionObserver {
+
+ friend class nsHtml5RequestStopper;
+ friend class nsHtml5DataAvailable;
+ friend class nsHtml5StreamParserContinuation;
+ friend class nsHtml5TimerKungFu;
+
+ public:
+ NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsHtml5StreamParser,
+ nsICharsetDetectionObserver)
+
+ static void InitializeStatics();
+
+ nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
+ nsHtml5Parser* aOwner,
+ eParserMode aMode);
+
+ // Methods that nsHtml5StreamListener calls
+ nsresult CheckListenerChain();
+
+ nsresult OnStartRequest(nsIRequest* aRequest, nsISupports* aContext);
+
+ nsresult OnDataAvailable(nsIRequest* aRequest,
+ nsISupports* aContext,
+ nsIInputStream* aInStream,
+ uint64_t aSourceOffset,
+ uint32_t aLength);
+
+ nsresult OnStopRequest(nsIRequest* aRequest,
+ nsISupports* aContext,
+ nsresult status);
+
+ // nsICharsetDetectionObserver
+ /**
+ * Chardet calls this to report the detection result
+ */
+ NS_IMETHOD Notify(const char* aCharset, nsDetectionConfident aConf) override;
+
+ // EncodingDeclarationHandler
+ // http://hg.mozilla.org/projects/htmlparser/file/tip/src/nu/validator/htmlparser/common/EncodingDeclarationHandler.java
+ /**
+ * Tree builder uses this to report a late <meta charset>
+ */
+ bool internalEncodingDeclaration(nsString* aEncoding);
+
+ // Not from an external interface
+
+ /**
+ * Call this method once you've created a parser, and want to instruct it
+ * about what charset to load
+ *
+ * @param aCharset the charset of a document
+ * @param aCharsetSource the source of the charset
+ */
+ inline void SetDocumentCharset(const nsACString& aCharset, int32_t aSource) {
+ NS_PRECONDITION(mStreamState == STREAM_NOT_STARTED,
+ "SetDocumentCharset called too late.");
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ mCharset = aCharset;
+ mCharsetSource = aSource;
+ }
+
+ inline void SetObserver(nsIRequestObserver* aObserver) {
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ mObserver = aObserver;
+ }
+
+ nsresult GetChannel(nsIChannel** aChannel);
+
+ /**
+ * The owner parser must call this after script execution
+ * when no scripts are executing and the document.written
+ * buffer has been exhausted.
+ */
+ void ContinueAfterScripts(nsHtml5Tokenizer* aTokenizer,
+ nsHtml5TreeBuilder* aTreeBuilder,
+ bool aLastWasCR);
+
+ /**
+ * Continues the stream parser if the charset switch failed.
+ */
+ void ContinueAfterFailedCharsetSwitch();
+
+ void Terminate()
+ {
+ mozilla::MutexAutoLock autoLock(mTerminatedMutex);
+ mTerminated = true;
+ }
+
+ void DropTimer();
+
+ /**
+ * Sets mCharset and mCharsetSource appropriately for the XML View Source
+ * case if aEncoding names a supported rough ASCII superset and sets
+ * the mCharset and mCharsetSource to the UTF-8 default otherwise.
+ */
+ void SetEncodingFromExpat(const char16_t* aEncoding);
+
+ /**
+ * Sets the URL for View Source title in case this parser ends up being
+ * used for View Source. If aURL is a view-source: URL, takes the inner
+ * URL. data: URLs are shown with an ellipsis instead of the actual data.
+ */
+ void SetViewSourceTitle(nsIURI* aURL);
+
+ private:
+ virtual ~nsHtml5StreamParser();
+
+#ifdef DEBUG
+ bool IsParserThread() {
+ bool ret;
+ mThread->IsOnCurrentThread(&ret);
+ return ret;
+ }
+#endif
+
+ void MarkAsBroken(nsresult aRv);
+
+ /**
+ * Marks the stream parser as interrupted. If you ever add calls to this
+ * method, be sure to review Uninterrupt usage very, very carefully to
+ * avoid having a previous in-flight runnable cancel your Interrupt()
+ * call on the other thread too soon.
+ */
+ void Interrupt()
+ {
+ mozilla::MutexAutoLock autoLock(mTerminatedMutex);
+ mInterrupted = true;
+ }
+
+ void Uninterrupt()
+ {
+ NS_ASSERTION(IsParserThread(), "Wrong thread!");
+ mTokenizerMutex.AssertCurrentThreadOwns();
+ // Not acquiring mTerminatedMutex because mTokenizerMutex is already
+ // held at this point and is already stronger.
+ mInterrupted = false;
+ }
+
+ /**
+ * Flushes the tree ops from the tree builder and disarms the flush
+ * timer.
+ */
+ void FlushTreeOpsAndDisarmTimer();
+
+ void ParseAvailableData();
+
+ void DoStopRequest();
+
+ void DoDataAvailable(const uint8_t* aBuffer, uint32_t aLength);
+
+ static nsresult CopySegmentsToParser(nsIInputStream *aInStream,
+ void *aClosure,
+ const char *aFromSegment,
+ uint32_t aToOffset,
+ uint32_t aCount,
+ uint32_t *aWriteCount);
+
+ bool IsTerminatedOrInterrupted()
+ {
+ mozilla::MutexAutoLock autoLock(mTerminatedMutex);
+ return mTerminated || mInterrupted;
+ }
+
+ bool IsTerminated()
+ {
+ mozilla::MutexAutoLock autoLock(mTerminatedMutex);
+ return mTerminated;
+ }
+
+ /**
+ * True when there is a Unicode decoder already
+ */
+ inline bool HasDecoder()
+ {
+ return !!mUnicodeDecoder;
+ }
+
+ /**
+ * Push bytes from network when there is no Unicode decoder yet
+ */
+ nsresult SniffStreamBytes(const uint8_t* aFromSegment,
+ uint32_t aCount,
+ uint32_t* aWriteCount);
+
+ /**
+ * Push bytes from network when there is a Unicode decoder already
+ */
+ nsresult WriteStreamBytes(const uint8_t* aFromSegment,
+ uint32_t aCount,
+ uint32_t* aWriteCount);
+
+ /**
+ * Check whether every other byte in the sniffing buffer is zero.
+ */
+ void SniffBOMlessUTF16BasicLatin(const uint8_t* aFromSegment,
+ uint32_t aCountToSniffingLimit);
+
+ /**
+ * <meta charset> scan failed. Try chardet if applicable. After this, the
+ * the parser will have some encoding even if a last resolt fallback.
+ *
+ * @param aFromSegment The current network buffer or null if the sniffing
+ * buffer is being flushed due to network stream ending.
+ * @param aCount The number of bytes in aFromSegment (ignored if
+ * aFromSegment is null)
+ * @param aWriteCount Return value for how many bytes got read from the
+ * buffer.
+ * @param aCountToSniffingLimit The number of unfilled slots in
+ * mSniffingBuffer
+ */
+ nsresult FinalizeSniffing(const uint8_t* aFromSegment,
+ uint32_t aCount,
+ uint32_t* aWriteCount,
+ uint32_t aCountToSniffingLimit);
+
+ /**
+ * Set up the Unicode decoder and write the sniffing buffer into it
+ * followed by the current network buffer.
+ *
+ * @param aFromSegment The current network buffer or null if the sniffing
+ * buffer is being flushed due to network stream ending.
+ * @param aCount The number of bytes in aFromSegment (ignored if
+ * aFromSegment is null)
+ * @param aWriteCount Return value for how many bytes got read from the
+ * buffer.
+ */
+ nsresult SetupDecodingAndWriteSniffingBufferAndCurrentSegment(const uint8_t* aFromSegment,
+ uint32_t aCount,
+ uint32_t* aWriteCount);
+
+ /**
+ * Initialize the Unicode decoder, mark the BOM as the source and
+ * drop the sniffer.
+ *
+ * @param aDecoderCharsetName The name for the decoder's charset
+ * (UTF-16BE, UTF-16LE or UTF-8; the BOM has
+ * been swallowed)
+ */
+ nsresult SetupDecodingFromBom(const char* aDecoderCharsetName);
+
+ /**
+ * Become confident or resolve and encoding name to its preferred form.
+ * @param aEncoding the value of an internal encoding decl. Acts as an
+ * out param, too, when the method returns true.
+ * @return true if the parser needs to start using the new value of
+ * aEncoding and false if the parser became confident or if
+ * the encoding name did not specify a usable encoding
+ */
+ bool PreferredForInternalEncodingDecl(nsACString& aEncoding);
+
+ /**
+ * Callback for mFlushTimer.
+ */
+ static void TimerCallback(nsITimer* aTimer, void* aClosure);
+
+ /**
+ * Parser thread entry point for (maybe) flushing the ops and posting
+ * a flush runnable back on the main thread.
+ */
+ void TimerFlush();
+
+ /**
+ * Called when speculation fails.
+ */
+ void MaybeDisableFutureSpeculation()
+ {
+ mSpeculationFailureCount++;
+ }
+
+ /**
+ * Used to check whether we're getting too many speculation failures and
+ * should just stop trying. The 100 is picked pretty randomly to be not too
+ * small (so most pages are not affected) but small enough that we don't end
+ * up with failed speculations over and over in pathological cases.
+ */
+ bool IsSpeculationEnabled()
+ {
+ return mSpeculationFailureCount < 100;
+ }
+
+ nsCOMPtr<nsIRequest> mRequest;
+ nsCOMPtr<nsIRequestObserver> mObserver;
+
+ /**
+ * The document title to use if this turns out to be a View Source parser.
+ */
+ nsCString mViewSourceTitle;
+
+ /**
+ * The Unicode decoder
+ */
+ nsCOMPtr<nsIUnicodeDecoder> mUnicodeDecoder;
+
+ /**
+ * The buffer for sniffing the character encoding
+ */
+ mozilla::UniquePtr<uint8_t[]> mSniffingBuffer;
+
+ /**
+ * The number of meaningful bytes in mSniffingBuffer
+ */
+ uint32_t mSniffingLength;
+
+ /**
+ * BOM sniffing state
+ */
+ eBomState mBomState;
+
+ /**
+ * <meta> prescan implementation
+ */
+ nsAutoPtr<nsHtml5MetaScanner> mMetaScanner;
+
+ // encoding-related stuff
+ /**
+ * The source (confidence) of the character encoding in use
+ */
+ int32_t mCharsetSource;
+
+ /**
+ * The character encoding in use
+ */
+ nsCString mCharset;
+
+ /**
+ * Whether reparse is forbidden
+ */
+ bool mReparseForbidden;
+
+ // Portable parser objects
+ /**
+ * The first buffer in the pending UTF-16 buffer queue
+ */
+ RefPtr<nsHtml5OwningUTF16Buffer> mFirstBuffer;
+
+ /**
+ * The last buffer in the pending UTF-16 buffer queue
+ */
+ nsHtml5OwningUTF16Buffer* mLastBuffer; // weak ref; always points to
+ // a buffer of the size NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE
+
+ /**
+ * The tree operation executor
+ */
+ nsHtml5TreeOpExecutor* mExecutor;
+
+ /**
+ * The HTML5 tree builder
+ */
+ nsAutoPtr<nsHtml5TreeBuilder> mTreeBuilder;
+
+ /**
+ * The HTML5 tokenizer
+ */
+ nsAutoPtr<nsHtml5Tokenizer> mTokenizer;
+
+ /**
+ * Makes sure the main thread can't mess the tokenizer state while it's
+ * tokenizing. This mutex also protects the current speculation.
+ */
+ mozilla::Mutex mTokenizerMutex;
+
+ /**
+ * The scoped atom table
+ */
+ nsHtml5AtomTable mAtomTable;
+
+ /**
+ * The owner parser.
+ */
+ RefPtr<nsHtml5Parser> mOwner;
+
+ /**
+ * Whether the last character tokenized was a carriage return (for CRLF)
+ */
+ bool mLastWasCR;
+
+ /**
+ * For tracking stream life cycle
+ */
+ eHtml5StreamState mStreamState;
+
+ /**
+ * Whether we are speculating.
+ */
+ bool mSpeculating;
+
+ /**
+ * Whether the tokenizer has reached EOF. (Reset when stream rewinded.)
+ */
+ bool mAtEOF;
+
+ /**
+ * The speculations. The mutex protects the nsTArray itself.
+ * To access the queue of current speculation, mTokenizerMutex must be
+ * obtained.
+ * The current speculation is the last element
+ */
+ nsTArray<nsAutoPtr<nsHtml5Speculation> > mSpeculations;
+ mozilla::Mutex mSpeculationMutex;
+
+ /**
+ * Number of times speculation has failed for this parser.
+ */
+ uint32_t mSpeculationFailureCount;
+
+ /**
+ * True to terminate early; protected by mTerminatedMutex
+ */
+ bool mTerminated;
+ bool mInterrupted;
+ mozilla::Mutex mTerminatedMutex;
+
+ /**
+ * The thread this stream parser runs on.
+ */
+ nsCOMPtr<nsIThread> mThread;
+
+ nsCOMPtr<nsIRunnable> mExecutorFlusher;
+
+ nsCOMPtr<nsIRunnable> mLoadFlusher;
+
+ /**
+ * The chardet instance if chardet is enabled.
+ */
+ nsCOMPtr<nsICharsetDetector> mChardet;
+
+ /**
+ * If false, don't push data to chardet.
+ */
+ bool mFeedChardet;
+
+ /**
+ * Whether the initial charset source was kCharsetFromParentFrame
+ */
+ bool mInitialEncodingWasFromParentFrame;
+
+ /**
+ * Timer for flushing tree ops once in a while when not speculating.
+ */
+ nsCOMPtr<nsITimer> mFlushTimer;
+
+ /**
+ * Keeps track whether mFlushTimer has been armed. Unfortunately,
+ * nsITimer doesn't enable querying this from the timer itself.
+ */
+ bool mFlushTimerArmed;
+
+ /**
+ * False initially and true after the timer has fired at least once.
+ */
+ bool mFlushTimerEverFired;
+
+ /**
+ * Whether the parser is doing a normal parse, view source or plain text.
+ */
+ eParserMode mMode;
+
+ /**
+ * The pref html5.flushtimer.initialdelay: Time in milliseconds between
+ * the time a network buffer is seen and the timer firing when the
+ * timer hasn't fired previously in this parse.
+ */
+ static int32_t sTimerInitialDelay;
+
+ /**
+ * The pref html5.flushtimer.subsequentdelay: Time in milliseconds between
+ * the time a network buffer is seen and the timer firing when the
+ * timer has already fired previously in this parse.
+ */
+ static int32_t sTimerSubsequentDelay;
+};
+
+#endif // nsHtml5StreamParser_h
diff --git a/parser/html/nsHtml5StringParser.cpp b/parser/html/nsHtml5StringParser.cpp
new file mode 100644
index 000000000..d1eeca6b8
--- /dev/null
+++ b/parser/html/nsHtml5StringParser.cpp
@@ -0,0 +1,130 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5StringParser.h"
+#include "nsHtml5TreeOpExecutor.h"
+#include "nsHtml5TreeBuilder.h"
+#include "nsHtml5Tokenizer.h"
+#include "nsIContent.h"
+#include "nsIDocument.h"
+#include "nsIDOMDocumentFragment.h"
+#include "nsHtml5DependentUTF16Buffer.h"
+
+NS_IMPL_ISUPPORTS0(nsHtml5StringParser)
+
+nsHtml5StringParser::nsHtml5StringParser()
+ : mBuilder(new nsHtml5OplessBuilder())
+ , mTreeBuilder(new nsHtml5TreeBuilder(mBuilder))
+ , mTokenizer(new nsHtml5Tokenizer(mTreeBuilder, false))
+{
+ MOZ_COUNT_CTOR(nsHtml5StringParser);
+ mTokenizer->setInterner(&mAtomTable);
+}
+
+nsHtml5StringParser::~nsHtml5StringParser()
+{
+ MOZ_COUNT_DTOR(nsHtml5StringParser);
+}
+
+nsresult
+nsHtml5StringParser::ParseFragment(const nsAString& aSourceBuffer,
+ nsIContent* aTargetNode,
+ nsIAtom* aContextLocalName,
+ int32_t aContextNamespace,
+ bool aQuirks,
+ bool aPreventScriptExecution)
+{
+ NS_ENSURE_TRUE(aSourceBuffer.Length() <= INT32_MAX,
+ NS_ERROR_OUT_OF_MEMORY);
+
+ nsIDocument* doc = aTargetNode->OwnerDoc();
+ nsIURI* uri = doc->GetDocumentURI();
+ NS_ENSURE_TRUE(uri, NS_ERROR_NOT_AVAILABLE);
+
+ mTreeBuilder->setFragmentContext(aContextLocalName,
+ aContextNamespace,
+ aTargetNode,
+ aQuirks);
+
+#ifdef DEBUG
+ if (!aPreventScriptExecution) {
+ NS_ASSERTION(!aTargetNode->IsInUncomposedDoc(),
+ "If script execution isn't prevented, "
+ "the target node must not be in doc.");
+ nsCOMPtr<nsIDOMDocumentFragment> domFrag = do_QueryInterface(aTargetNode);
+ NS_ASSERTION(domFrag,
+ "If script execution isn't prevented, must parse to DOM fragment.");
+ }
+#endif
+
+ mTreeBuilder->SetPreventScriptExecution(aPreventScriptExecution);
+
+ return Tokenize(aSourceBuffer, doc, true);
+}
+
+nsresult
+nsHtml5StringParser::ParseDocument(const nsAString& aSourceBuffer,
+ nsIDocument* aTargetDoc,
+ bool aScriptingEnabledForNoscriptParsing)
+{
+ MOZ_ASSERT(!aTargetDoc->GetFirstChild());
+
+ NS_ENSURE_TRUE(aSourceBuffer.Length() <= INT32_MAX,
+ NS_ERROR_OUT_OF_MEMORY);
+
+ mTreeBuilder->setFragmentContext(nullptr,
+ kNameSpaceID_None,
+ nullptr,
+ false);
+
+ mTreeBuilder->SetPreventScriptExecution(true);
+
+ return Tokenize(aSourceBuffer, aTargetDoc, aScriptingEnabledForNoscriptParsing);
+}
+
+nsresult
+nsHtml5StringParser::Tokenize(const nsAString& aSourceBuffer,
+ nsIDocument* aDocument,
+ bool aScriptingEnabledForNoscriptParsing) {
+
+ nsIURI* uri = aDocument->GetDocumentURI();
+
+ mBuilder->Init(aDocument, uri, nullptr, nullptr);
+
+ mBuilder->SetParser(this);
+ mBuilder->SetNodeInfoManager(aDocument->NodeInfoManager());
+
+ // Mark the parser as *not* broken by passing NS_OK
+ nsresult rv = mBuilder->MarkAsBroken(NS_OK);
+
+ mTreeBuilder->setScriptingEnabled(aScriptingEnabledForNoscriptParsing);
+ mTreeBuilder->setIsSrcdocDocument(aDocument->IsSrcdocDocument());
+ mBuilder->Start();
+ mTokenizer->start();
+ if (!aSourceBuffer.IsEmpty()) {
+ bool lastWasCR = false;
+ nsHtml5DependentUTF16Buffer buffer(aSourceBuffer);
+ while (buffer.hasMore()) {
+ buffer.adjust(lastWasCR);
+ lastWasCR = false;
+ if (buffer.hasMore()) {
+ if (!mTokenizer->EnsureBufferSpace(buffer.getLength())) {
+ rv = mBuilder->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
+ break;
+ }
+ lastWasCR = mTokenizer->tokenizeBuffer(&buffer);
+ if (NS_FAILED(rv = mBuilder->IsBroken())) {
+ break;
+ }
+ }
+ }
+ }
+ if (NS_SUCCEEDED(rv)) {
+ mTokenizer->eof();
+ }
+ mTokenizer->end();
+ mBuilder->Finish();
+ mAtomTable.Clear();
+ return rv;
+}
diff --git a/parser/html/nsHtml5StringParser.h b/parser/html/nsHtml5StringParser.h
new file mode 100644
index 000000000..3f7322436
--- /dev/null
+++ b/parser/html/nsHtml5StringParser.h
@@ -0,0 +1,88 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5StringParser_h
+#define nsHtml5StringParser_h
+
+#include "nsHtml5AtomTable.h"
+#include "nsParserBase.h"
+
+class nsHtml5OplessBuilder;
+class nsHtml5TreeBuilder;
+class nsHtml5Tokenizer;
+class nsIContent;
+class nsIDocument;
+
+class nsHtml5StringParser : public nsParserBase
+{
+ public:
+
+ NS_DECL_ISUPPORTS
+
+ /**
+ * Constructor for use ONLY by nsContentUtils. Others, please call the
+ * nsContentUtils statics that wrap this.
+ */
+ nsHtml5StringParser();
+
+ /**
+ * Invoke the fragment parsing algorithm (innerHTML).
+ * DO NOT CALL from outside nsContentUtils.cpp.
+ *
+ * @param aSourceBuffer the string being set as innerHTML
+ * @param aTargetNode the target container
+ * @param aContextLocalName local name of context node
+ * @param aContextNamespace namespace of context node
+ * @param aQuirks true to make <table> not close <p>
+ * @param aPreventScriptExecution true to prevent scripts from executing;
+ * don't set to false when parsing into a target node that has been bound
+ * to tree.
+ */
+ nsresult ParseFragment(const nsAString& aSourceBuffer,
+ nsIContent* aTargetNode,
+ nsIAtom* aContextLocalName,
+ int32_t aContextNamespace,
+ bool aQuirks,
+ bool aPreventScriptExecution);
+
+ /**
+ * Parse an entire HTML document from a source string.
+ * DO NOT CALL from outside nsContentUtils.cpp.
+ *
+ */
+ nsresult ParseDocument(const nsAString& aSourceBuffer,
+ nsIDocument* aTargetDoc,
+ bool aScriptingEnabledForNoscriptParsing);
+
+ private:
+
+ virtual ~nsHtml5StringParser();
+
+ nsresult Tokenize(const nsAString& aSourceBuffer,
+ nsIDocument* aDocument,
+ bool aScriptingEnabledForNoscriptParsing);
+
+ /**
+ * The tree operation executor
+ */
+ RefPtr<nsHtml5OplessBuilder> mBuilder;
+
+ /**
+ * The HTML5 tree builder
+ */
+ const nsAutoPtr<nsHtml5TreeBuilder> mTreeBuilder;
+
+ /**
+ * The HTML5 tokenizer
+ */
+ const nsAutoPtr<nsHtml5Tokenizer> mTokenizer;
+
+ /**
+ * The scoped atom table
+ */
+ nsHtml5AtomTable mAtomTable;
+
+};
+
+#endif // nsHtml5StringParser_h
diff --git a/parser/html/nsHtml5Tokenizer.cpp b/parser/html/nsHtml5Tokenizer.cpp
new file mode 100644
index 000000000..2838d74aa
--- /dev/null
+++ b/parser/html/nsHtml5Tokenizer.cpp
@@ -0,0 +1,4116 @@
+/*
+ * Copyright (c) 2005-2007 Henri Sivonen
+ * Copyright (c) 2007-2015 Mozilla Foundation
+ * Portions of comments Copyright 2004-2010 Apple Computer, Inc., Mozilla
+ * Foundation, and Opera Software ASA.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit Tokenizer.java instead and regenerate.
+ */
+
+#define nsHtml5Tokenizer_cpp__
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5DocumentMode.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsHtml5NamedCharacters.h"
+#include "nsHtml5NamedCharactersAccel.h"
+#include "nsHtml5Atoms.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
+#include "nsHtml5Highlighter.h"
+#include "nsHtml5TokenizerLoopPolicies.h"
+
+#include "nsHtml5TreeBuilder.h"
+#include "nsHtml5MetaScanner.h"
+#include "nsHtml5AttributeName.h"
+#include "nsHtml5ElementName.h"
+#include "nsHtml5HtmlAttributes.h"
+#include "nsHtml5StackNode.h"
+#include "nsHtml5UTF16Buffer.h"
+#include "nsHtml5StateSnapshot.h"
+#include "nsHtml5Portability.h"
+
+#include "nsHtml5Tokenizer.h"
+
+char16_t nsHtml5Tokenizer::LT_GT[] = { '<', '>' };
+char16_t nsHtml5Tokenizer::LT_SOLIDUS[] = { '<', '/' };
+char16_t nsHtml5Tokenizer::RSQB_RSQB[] = { ']', ']' };
+char16_t nsHtml5Tokenizer::REPLACEMENT_CHARACTER[] = { 0xfffd };
+char16_t nsHtml5Tokenizer::LF[] = { '\n' };
+char16_t nsHtml5Tokenizer::CDATA_LSQB[] = { 'C', 'D', 'A', 'T', 'A', '[' };
+char16_t nsHtml5Tokenizer::OCTYPE[] = { 'o', 'c', 't', 'y', 'p', 'e' };
+char16_t nsHtml5Tokenizer::UBLIC[] = { 'u', 'b', 'l', 'i', 'c' };
+char16_t nsHtml5Tokenizer::YSTEM[] = { 'y', 's', 't', 'e', 'm' };
+static char16_t const TITLE_ARR_DATA[] = { 't', 'i', 't', 'l', 'e' };
+staticJArray<char16_t,int32_t> nsHtml5Tokenizer::TITLE_ARR = { TITLE_ARR_DATA, MOZ_ARRAY_LENGTH(TITLE_ARR_DATA) };
+static char16_t const SCRIPT_ARR_DATA[] = { 's', 'c', 'r', 'i', 'p', 't' };
+staticJArray<char16_t,int32_t> nsHtml5Tokenizer::SCRIPT_ARR = { SCRIPT_ARR_DATA, MOZ_ARRAY_LENGTH(SCRIPT_ARR_DATA) };
+static char16_t const STYLE_ARR_DATA[] = { 's', 't', 'y', 'l', 'e' };
+staticJArray<char16_t,int32_t> nsHtml5Tokenizer::STYLE_ARR = { STYLE_ARR_DATA, MOZ_ARRAY_LENGTH(STYLE_ARR_DATA) };
+static char16_t const PLAINTEXT_ARR_DATA[] = { 'p', 'l', 'a', 'i', 'n', 't', 'e', 'x', 't' };
+staticJArray<char16_t,int32_t> nsHtml5Tokenizer::PLAINTEXT_ARR = { PLAINTEXT_ARR_DATA, MOZ_ARRAY_LENGTH(PLAINTEXT_ARR_DATA) };
+static char16_t const XMP_ARR_DATA[] = { 'x', 'm', 'p' };
+staticJArray<char16_t,int32_t> nsHtml5Tokenizer::XMP_ARR = { XMP_ARR_DATA, MOZ_ARRAY_LENGTH(XMP_ARR_DATA) };
+static char16_t const TEXTAREA_ARR_DATA[] = { 't', 'e', 'x', 't', 'a', 'r', 'e', 'a' };
+staticJArray<char16_t,int32_t> nsHtml5Tokenizer::TEXTAREA_ARR = { TEXTAREA_ARR_DATA, MOZ_ARRAY_LENGTH(TEXTAREA_ARR_DATA) };
+static char16_t const IFRAME_ARR_DATA[] = { 'i', 'f', 'r', 'a', 'm', 'e' };
+staticJArray<char16_t,int32_t> nsHtml5Tokenizer::IFRAME_ARR = { IFRAME_ARR_DATA, MOZ_ARRAY_LENGTH(IFRAME_ARR_DATA) };
+static char16_t const NOEMBED_ARR_DATA[] = { 'n', 'o', 'e', 'm', 'b', 'e', 'd' };
+staticJArray<char16_t,int32_t> nsHtml5Tokenizer::NOEMBED_ARR = { NOEMBED_ARR_DATA, MOZ_ARRAY_LENGTH(NOEMBED_ARR_DATA) };
+static char16_t const NOSCRIPT_ARR_DATA[] = { 'n', 'o', 's', 'c', 'r', 'i', 'p', 't' };
+staticJArray<char16_t,int32_t> nsHtml5Tokenizer::NOSCRIPT_ARR = { NOSCRIPT_ARR_DATA, MOZ_ARRAY_LENGTH(NOSCRIPT_ARR_DATA) };
+static char16_t const NOFRAMES_ARR_DATA[] = { 'n', 'o', 'f', 'r', 'a', 'm', 'e', 's' };
+staticJArray<char16_t,int32_t> nsHtml5Tokenizer::NOFRAMES_ARR = { NOFRAMES_ARR_DATA, MOZ_ARRAY_LENGTH(NOFRAMES_ARR_DATA) };
+
+nsHtml5Tokenizer::nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler, bool viewingXmlSource)
+ : tokenHandler(tokenHandler),
+ encodingDeclarationHandler(nullptr),
+ charRefBuf(jArray<char16_t,int32_t>::newJArray(32)),
+ bmpChar(jArray<char16_t,int32_t>::newJArray(1)),
+ astralChar(jArray<char16_t,int32_t>::newJArray(2)),
+ tagName(nullptr),
+ attributeName(nullptr),
+ doctypeName(nullptr),
+ publicIdentifier(nullptr),
+ systemIdentifier(nullptr),
+ attributes(tokenHandler->HasBuilder() ? new nsHtml5HtmlAttributes(0) : nullptr),
+ newAttributesEachTime(!tokenHandler->HasBuilder()),
+ viewingXmlSource(viewingXmlSource)
+{
+ MOZ_COUNT_CTOR(nsHtml5Tokenizer);
+}
+
+void
+nsHtml5Tokenizer::setInterner(nsHtml5AtomTable* interner)
+{
+ this->interner = interner;
+}
+
+void
+nsHtml5Tokenizer::initLocation(nsString* newPublicId, nsString* newSystemId)
+{
+ this->systemId = newSystemId;
+ this->publicId = newPublicId;
+}
+
+bool
+nsHtml5Tokenizer::isViewingXmlSource()
+{
+ return viewingXmlSource;
+}
+
+void
+nsHtml5Tokenizer::setStateAndEndTagExpectation(int32_t specialTokenizerState, nsIAtom* endTagExpectation)
+{
+ this->stateSave = specialTokenizerState;
+ if (specialTokenizerState == NS_HTML5TOKENIZER_DATA) {
+ return;
+ }
+ autoJArray<char16_t,int32_t> asArray = nsHtml5Portability::newCharArrayFromLocal(endTagExpectation);
+ this->endTagExpectation = nsHtml5ElementName::elementNameByBuffer(asArray, 0, asArray.length, interner);
+ endTagExpectationToArray();
+}
+
+void
+nsHtml5Tokenizer::setStateAndEndTagExpectation(int32_t specialTokenizerState, nsHtml5ElementName* endTagExpectation)
+{
+ this->stateSave = specialTokenizerState;
+ this->endTagExpectation = endTagExpectation;
+ endTagExpectationToArray();
+}
+
+void
+nsHtml5Tokenizer::endTagExpectationToArray()
+{
+ switch(endTagExpectation->getGroup()) {
+ case NS_HTML5TREE_BUILDER_TITLE: {
+ endTagExpectationAsArray = TITLE_ARR;
+ return;
+ }
+ case NS_HTML5TREE_BUILDER_SCRIPT: {
+ endTagExpectationAsArray = SCRIPT_ARR;
+ return;
+ }
+ case NS_HTML5TREE_BUILDER_STYLE: {
+ endTagExpectationAsArray = STYLE_ARR;
+ return;
+ }
+ case NS_HTML5TREE_BUILDER_PLAINTEXT: {
+ endTagExpectationAsArray = PLAINTEXT_ARR;
+ return;
+ }
+ case NS_HTML5TREE_BUILDER_XMP: {
+ endTagExpectationAsArray = XMP_ARR;
+ return;
+ }
+ case NS_HTML5TREE_BUILDER_TEXTAREA: {
+ endTagExpectationAsArray = TEXTAREA_ARR;
+ return;
+ }
+ case NS_HTML5TREE_BUILDER_IFRAME: {
+ endTagExpectationAsArray = IFRAME_ARR;
+ return;
+ }
+ case NS_HTML5TREE_BUILDER_NOEMBED: {
+ endTagExpectationAsArray = NOEMBED_ARR;
+ return;
+ }
+ case NS_HTML5TREE_BUILDER_NOSCRIPT: {
+ endTagExpectationAsArray = NOSCRIPT_ARR;
+ return;
+ }
+ case NS_HTML5TREE_BUILDER_NOFRAMES: {
+ endTagExpectationAsArray = NOFRAMES_ARR;
+ return;
+ }
+ default: {
+ MOZ_ASSERT(false, "Bad end tag expectation.");
+ return;
+ }
+ }
+}
+
+void
+nsHtml5Tokenizer::setLineNumber(int32_t line)
+{
+ this->attributeLine = line;
+ this->line = line;
+}
+
+nsHtml5HtmlAttributes*
+nsHtml5Tokenizer::emptyAttributes()
+{
+ return nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES;
+}
+
+void
+nsHtml5Tokenizer::emitOrAppendCharRefBuf(int32_t returnState)
+{
+ if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ appendCharRefBufToStrBuf();
+ } else {
+ if (charRefBufLen > 0) {
+ tokenHandler->characters(charRefBuf, 0, charRefBufLen);
+ charRefBufLen = 0;
+ }
+ }
+}
+
+nsString*
+nsHtml5Tokenizer::strBufToString()
+{
+ nsString* str = nsHtml5Portability::newStringFromBuffer(strBuf, 0, strBufLen, tokenHandler);
+ clearStrBufAfterUse();
+ return str;
+}
+
+void
+nsHtml5Tokenizer::strBufToDoctypeName()
+{
+ doctypeName = nsHtml5Portability::newLocalNameFromBuffer(strBuf, 0, strBufLen, interner);
+ clearStrBufAfterUse();
+}
+
+void
+nsHtml5Tokenizer::emitStrBuf()
+{
+ if (strBufLen > 0) {
+ tokenHandler->characters(strBuf, 0, strBufLen);
+ clearStrBufAfterUse();
+ }
+}
+
+void
+nsHtml5Tokenizer::appendStrBuf(char16_t* buffer, int32_t offset, int32_t length)
+{
+ int32_t newLen = strBufLen + length;
+ MOZ_ASSERT(newLen <= strBuf.length, "Previous buffer length insufficient.");
+ if (MOZ_UNLIKELY(strBuf.length < newLen)) {
+ if (MOZ_UNLIKELY(!EnsureBufferSpace(length))) {
+ MOZ_CRASH("Unable to recover from buffer reallocation failure");
+ }
+ }
+ nsHtml5ArrayCopy::arraycopy(buffer, offset, strBuf, strBufLen, length);
+ strBufLen = newLen;
+}
+
+void
+nsHtml5Tokenizer::emitComment(int32_t provisionalHyphens, int32_t pos)
+{
+ tokenHandler->comment(strBuf, 0, strBufLen - provisionalHyphens);
+ clearStrBufAfterUse();
+ cstart = pos + 1;
+}
+
+void
+nsHtml5Tokenizer::flushChars(char16_t* buf, int32_t pos)
+{
+ if (pos > cstart) {
+ tokenHandler->characters(buf, cstart, pos - cstart);
+ }
+ cstart = INT32_MAX;
+}
+
+void
+nsHtml5Tokenizer::strBufToElementNameString()
+{
+ tagName = nsHtml5ElementName::elementNameByBuffer(strBuf, 0, strBufLen, interner);
+ clearStrBufAfterUse();
+}
+
+int32_t
+nsHtml5Tokenizer::emitCurrentTagToken(bool selfClosing, int32_t pos)
+{
+ cstart = pos + 1;
+ maybeErrSlashInEndTag(selfClosing);
+ stateSave = NS_HTML5TOKENIZER_DATA;
+ nsHtml5HtmlAttributes* attrs = (!attributes ? nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES : attributes);
+ if (endTag) {
+ maybeErrAttributesOnEndTag(attrs);
+ if (!viewingXmlSource) {
+ tokenHandler->endTag(tagName);
+ }
+ if (newAttributesEachTime) {
+ delete attributes;
+ attributes = nullptr;
+ }
+ } else {
+ if (viewingXmlSource) {
+ MOZ_ASSERT(newAttributesEachTime);
+ delete attributes;
+ attributes = nullptr;
+ } else {
+ tokenHandler->startTag(tagName, attrs, selfClosing);
+ }
+ }
+ tagName->release();
+ tagName = nullptr;
+ if (newAttributesEachTime) {
+ attributes = nullptr;
+ } else {
+ attributes->clear(0);
+ }
+ return stateSave;
+}
+
+void
+nsHtml5Tokenizer::attributeNameComplete()
+{
+ attributeName = nsHtml5AttributeName::nameByBuffer(strBuf, 0, strBufLen, interner);
+ clearStrBufAfterUse();
+ if (!attributes) {
+ attributes = new nsHtml5HtmlAttributes(0);
+ }
+ if (attributes->contains(attributeName)) {
+ errDuplicateAttribute();
+ attributeName->release();
+ attributeName = nullptr;
+ }
+}
+
+void
+nsHtml5Tokenizer::addAttributeWithoutValue()
+{
+
+ if (attributeName) {
+ attributes->addAttribute(attributeName, nsHtml5Portability::newEmptyString(), attributeLine);
+ attributeName = nullptr;
+ } else {
+ clearStrBufAfterUse();
+ }
+}
+
+void
+nsHtml5Tokenizer::addAttributeWithValue()
+{
+ if (attributeName) {
+ nsString* val = strBufToString();
+ if (mViewSource) {
+ mViewSource->MaybeLinkifyAttributeValue(attributeName, val);
+ }
+ attributes->addAttribute(attributeName, val, attributeLine);
+ attributeName = nullptr;
+ } else {
+ clearStrBufAfterUse();
+ }
+}
+
+void
+nsHtml5Tokenizer::start()
+{
+ initializeWithoutStarting();
+ tokenHandler->startTokenization(this);
+}
+
+bool
+nsHtml5Tokenizer::tokenizeBuffer(nsHtml5UTF16Buffer* buffer)
+{
+ int32_t state = stateSave;
+ int32_t returnState = returnStateSave;
+ char16_t c = '\0';
+ shouldSuspend = false;
+ lastCR = false;
+ int32_t start = buffer->getStart();
+ int32_t end = buffer->getEnd();
+ int32_t pos = start - 1;
+ switch(state) {
+ case NS_HTML5TOKENIZER_DATA:
+ case NS_HTML5TOKENIZER_RCDATA:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA:
+ case NS_HTML5TOKENIZER_PLAINTEXT:
+ case NS_HTML5TOKENIZER_RAWTEXT:
+ case NS_HTML5TOKENIZER_CDATA_SECTION:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START_DASH:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_START:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_END: {
+ cstart = start;
+ break;
+ }
+ default: {
+ cstart = INT32_MAX;
+ break;
+ }
+ }
+ if (mViewSource) {
+ mViewSource->SetBuffer(buffer);
+ pos = stateLoop<nsHtml5ViewSourcePolicy>(state, c, pos, buffer->getBuffer(), false, returnState, buffer->getEnd());
+ mViewSource->DropBuffer((pos == buffer->getEnd()) ? pos : pos + 1);
+ } else {
+ pos = stateLoop<nsHtml5SilentPolicy>(state, c, pos, buffer->getBuffer(), false, returnState, buffer->getEnd());
+ }
+ if (pos == end) {
+ buffer->setStart(pos);
+ } else {
+ buffer->setStart(pos + 1);
+ }
+ return lastCR;
+}
+
+template<class P>
+int32_t
+nsHtml5Tokenizer::stateLoop(int32_t state, char16_t c, int32_t pos, char16_t* buf, bool reconsume, int32_t returnState, int32_t endPos)
+{
+ stateloop: for (; ; ) {
+ switch(state) {
+ case NS_HTML5TOKENIZER_DATA: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '&': {
+ flushChars(buf, pos);
+ MOZ_ASSERT(!charRefBufLen, "charRefBufLen not reset after previous use!");
+ appendCharRefBuf(c);
+ setAdditionalAndRememberAmpersandLocation('\0');
+ returnState = state;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '<': {
+ flushChars(buf, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_TAG_OPEN, reconsume, pos);
+ NS_HTML5_BREAK(dataloop);
+ }
+ case '\0': {
+ emitReplacementCharacter(buf, pos);
+ continue;
+ }
+ case '\r': {
+ emitCarriageReturn(buf, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+ dataloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_TAG_OPEN: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ if (c >= 'A' && c <= 'Z') {
+ endTag = false;
+ clearStrBufBeforeUse();
+ appendStrBuf((char16_t) (c + 0x20));
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_TAG_NAME, reconsume, pos);
+ NS_HTML5_BREAK(tagopenloop);
+ } else if (c >= 'a' && c <= 'z') {
+ endTag = false;
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_TAG_NAME, reconsume, pos);
+ NS_HTML5_BREAK(tagopenloop);
+ }
+ switch(c) {
+ case '!': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_MARKUP_DECLARATION_OPEN, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '/': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_CLOSE_TAG_OPEN, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\?': {
+ if (viewingXmlSource) {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ if (P::reportErrors) {
+ errProcessingInstruction();
+ }
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ if (P::reportErrors) {
+ errLtGt();
+ }
+ tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 2);
+ cstart = pos + 1;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ if (P::reportErrors) {
+ errBadCharAfterLt(c);
+ }
+ tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
+ cstart = pos;
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ tagopenloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_TAG_NAME: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ strBufToElementNameString();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ strBufToElementNameString();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ NS_HTML5_BREAK(tagnameloop);
+ }
+ case '/': {
+ strBufToElementNameString();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ strBufToElementNameString();
+ state = P::transition(mViewSource, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ if (c >= 'A' && c <= 'Z') {
+ c += 0x20;
+ }
+ appendStrBuf(c);
+ continue;
+ }
+ }
+ }
+ tagnameloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ continue;
+ }
+ case '/': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ state = P::transition(mViewSource, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ case '\"':
+ case '\'':
+ case '<':
+ case '=': {
+ if (P::reportErrors) {
+ errBadCharBeforeAttributeNameOrNull(c);
+ }
+ }
+ default: {
+ if (c >= 'A' && c <= 'Z') {
+ c += 0x20;
+ }
+ attributeLine = line;
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_ATTRIBUTE_NAME, reconsume, pos);
+ NS_HTML5_BREAK(beforeattributenameloop);
+ }
+ }
+ }
+ beforeattributenameloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_ATTRIBUTE_NAME: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ attributeNameComplete();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ attributeNameComplete();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '/': {
+ attributeNameComplete();
+ addAttributeWithoutValue();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '=': {
+ attributeNameComplete();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE, reconsume, pos);
+ NS_HTML5_BREAK(attributenameloop);
+ }
+ case '>': {
+ attributeNameComplete();
+ addAttributeWithoutValue();
+ state = P::transition(mViewSource, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ case '\"':
+ case '\'':
+ case '<': {
+ if (P::reportErrors) {
+ errQuoteOrLtInAttributeNameOrNull(c);
+ }
+ }
+ default: {
+ if (c >= 'A' && c <= 'Z') {
+ c += 0x20;
+ }
+ appendStrBuf(c);
+ continue;
+ }
+ }
+ }
+ attributenameloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ continue;
+ }
+ case '\"': {
+ attributeLine = line;
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED, reconsume, pos);
+ NS_HTML5_BREAK(beforeattributevalueloop);
+ }
+ case '&': {
+ attributeLine = line;
+ clearStrBufBeforeUse();
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED, reconsume, pos);
+
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\'': {
+ attributeLine = line;
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ if (P::reportErrors) {
+ errAttributeValueMissing();
+ }
+ addAttributeWithoutValue();
+ state = P::transition(mViewSource, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ case '<':
+ case '=':
+ case '`': {
+ if (P::reportErrors) {
+ errLtOrEqualsOrGraveInUnquotedAttributeOrNull(c);
+ }
+ }
+ default: {
+ attributeLine = line;
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED, reconsume, pos);
+
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ beforeattributevalueloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '\"': {
+ addAttributeWithValue();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED, reconsume, pos);
+ NS_HTML5_BREAK(attributevaluedoublequotedloop);
+ }
+ case '&': {
+ MOZ_ASSERT(!charRefBufLen, "charRefBufLen not reset after previous use!");
+ appendCharRefBuf(c);
+ setAdditionalAndRememberAmpersandLocation('\"');
+ returnState = state;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\r': {
+ appendStrBufCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ appendStrBufLineFeed();
+ continue;
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ appendStrBuf(c);
+ continue;
+ }
+ }
+ }
+ attributevaluedoublequotedloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '/': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG, reconsume, pos);
+ NS_HTML5_BREAK(afterattributevaluequotedloop);
+ }
+ case '>': {
+ state = P::transition(mViewSource, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ if (P::reportErrors) {
+ errNoSpaceBetweenAttributes();
+ }
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ afterattributevaluequotedloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG: {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '>': {
+ state = P::transition(mViewSource, emitCurrentTagToken(true, pos), reconsume, pos);
+ if (shouldSuspend) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ if (P::reportErrors) {
+ errSlashNotFollowedByGt();
+ }
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ addAttributeWithValue();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ addAttributeWithValue();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '&': {
+ MOZ_ASSERT(!charRefBufLen, "charRefBufLen not reset after previous use!");
+ appendCharRefBuf(c);
+ setAdditionalAndRememberAmpersandLocation('>');
+ returnState = state;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ addAttributeWithValue();
+ state = P::transition(mViewSource, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ case '<':
+ case '\"':
+ case '\'':
+ case '=':
+ case '`': {
+ if (P::reportErrors) {
+ errUnquotedAttributeValOrNull(c);
+ }
+ }
+ default: {
+
+ appendStrBuf(c);
+ continue;
+ }
+ }
+ }
+ }
+ case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ continue;
+ }
+ case '/': {
+ addAttributeWithoutValue();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '=': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ addAttributeWithoutValue();
+ state = P::transition(mViewSource, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ case '\"':
+ case '\'':
+ case '<': {
+ if (P::reportErrors) {
+ errQuoteOrLtInAttributeNameOrNull(c);
+ }
+ }
+ default: {
+ addAttributeWithoutValue();
+ if (c >= 'A' && c <= 'Z') {
+ c += 0x20;
+ }
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_ATTRIBUTE_NAME, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ }
+ case NS_HTML5TOKENIZER_MARKUP_DECLARATION_OPEN: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '-': {
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_MARKUP_DECLARATION_HYPHEN, reconsume, pos);
+ NS_HTML5_BREAK(markupdeclarationopenloop);
+ }
+ case 'd':
+ case 'D': {
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ index = 0;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_MARKUP_DECLARATION_OCTYPE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '[': {
+ if (tokenHandler->cdataSectionAllowed()) {
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ index = 0;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_CDATA_START, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ default: {
+ if (P::reportErrors) {
+ errBogusComment();
+ }
+ clearStrBufBeforeUse();
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ markupdeclarationopenloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_MARKUP_DECLARATION_HYPHEN: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\0': {
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '-': {
+ clearStrBufAfterOneHyphen();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT_START, reconsume, pos);
+ NS_HTML5_BREAK(markupdeclarationhyphenloop);
+ }
+ default: {
+ if (P::reportErrors) {
+ errBogusComment();
+ }
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ markupdeclarationhyphenloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_COMMENT_START: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '-': {
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT_START_DASH, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ if (P::reportErrors) {
+ errPrematureEndOfComment();
+ }
+ emitComment(0, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\r': {
+ appendStrBufCarriageReturn();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ appendStrBufLineFeed();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT, reconsume, pos);
+ NS_HTML5_BREAK(commentstartloop);
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT, reconsume, pos);
+ NS_HTML5_BREAK(commentstartloop);
+ }
+ }
+ }
+ commentstartloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_COMMENT: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '-': {
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT_END_DASH, reconsume, pos);
+ NS_HTML5_BREAK(commentloop);
+ }
+ case '\r': {
+ appendStrBufCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ appendStrBufLineFeed();
+ continue;
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ appendStrBuf(c);
+ continue;
+ }
+ }
+ }
+ commentloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_COMMENT_END_DASH: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '-': {
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT_END, reconsume, pos);
+ NS_HTML5_BREAK(commentenddashloop);
+ }
+ case '\r': {
+ appendStrBufCarriageReturn();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ appendStrBufLineFeed();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ commentenddashloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_COMMENT_END: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '>': {
+ emitComment(2, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '-': {
+ adjustDoubleHyphenAndAppendToStrBufAndErr(c);
+ continue;
+ }
+ case '\r': {
+ adjustDoubleHyphenAndAppendToStrBufCarriageReturn();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ adjustDoubleHyphenAndAppendToStrBufLineFeed();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '!': {
+ if (P::reportErrors) {
+ errHyphenHyphenBang();
+ }
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT_END_BANG, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ adjustDoubleHyphenAndAppendToStrBufAndErr(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+
+ }
+ case NS_HTML5TOKENIZER_COMMENT_END_BANG: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '>': {
+ emitComment(3, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '-': {
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT_END_DASH, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\r': {
+ appendStrBufCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ appendStrBufLineFeed();
+ continue;
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ }
+ case NS_HTML5TOKENIZER_COMMENT_START_DASH: {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '-': {
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT_END, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ if (P::reportErrors) {
+ errPrematureEndOfComment();
+ }
+ emitComment(1, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\r': {
+ appendStrBufCarriageReturn();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ appendStrBufLineFeed();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ case NS_HTML5TOKENIZER_CDATA_START: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ if (index < 6) {
+ if (c == nsHtml5Tokenizer::CDATA_LSQB[index]) {
+ appendStrBuf(c);
+ } else {
+ if (P::reportErrors) {
+ errBogusComment();
+ }
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ index++;
+ continue;
+ } else {
+ clearStrBufAfterUse();
+ cstart = pos;
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_CDATA_SECTION, reconsume, pos);
+ break;
+ }
+ }
+ }
+ case NS_HTML5TOKENIZER_CDATA_SECTION: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case ']': {
+ flushChars(buf, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_CDATA_RSQB, reconsume, pos);
+ NS_HTML5_BREAK(cdatasectionloop);
+ }
+ case '\0': {
+ emitReplacementCharacter(buf, pos);
+ continue;
+ }
+ case '\r': {
+ emitCarriageReturn(buf, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+ cdatasectionloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_CDATA_RSQB: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case ']': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_CDATA_RSQB_RSQB, reconsume, pos);
+ NS_HTML5_BREAK(cdatarsqb);
+ }
+ default: {
+ tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
+ cstart = pos;
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_CDATA_SECTION, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ cdatarsqb_end: ;
+ }
+ case NS_HTML5TOKENIZER_CDATA_RSQB_RSQB: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case ']': {
+ tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
+ continue;
+ }
+ case '>': {
+ cstart = pos + 1;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 2);
+ cstart = pos;
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_CDATA_SECTION, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+
+ }
+ case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '\'': {
+ addAttributeWithValue();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '&': {
+ MOZ_ASSERT(!charRefBufLen, "charRefBufLen not reset after previous use!");
+ appendCharRefBuf(c);
+ setAdditionalAndRememberAmpersandLocation('\'');
+ returnState = state;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE, reconsume, pos);
+ NS_HTML5_BREAK(attributevaluesinglequotedloop);
+ }
+ case '\r': {
+ appendStrBufCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ appendStrBufLineFeed();
+ continue;
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ appendStrBuf(c);
+ continue;
+ }
+ }
+ }
+ attributevaluesinglequotedloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE: {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ if (c == '\0') {
+ NS_HTML5_BREAK(stateloop);
+ }
+ switch(c) {
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ case '\f':
+ case '<':
+ case '&': {
+ emitOrAppendCharRefBuf(returnState);
+ if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = P::transition(mViewSource, returnState, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '#': {
+ appendCharRefBuf('#');
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_CONSUME_NCR, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ if (c == additional) {
+ emitOrAppendCharRefBuf(returnState);
+ reconsume = true;
+ state = P::transition(mViewSource, returnState, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ if (c >= 'a' && c <= 'z') {
+ firstCharKey = c - 'a' + 26;
+ } else if (c >= 'A' && c <= 'Z') {
+ firstCharKey = c - 'A';
+ } else {
+ if (P::reportErrors) {
+ errNoNamedCharacterMatch();
+ }
+ emitOrAppendCharRefBuf(returnState);
+ if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = P::transition(mViewSource, returnState, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ appendCharRefBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP, reconsume, pos);
+ }
+ }
+ }
+ case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP: {
+ {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ if (c == '\0') {
+ NS_HTML5_BREAK(stateloop);
+ }
+ int32_t hilo = 0;
+ if (c <= 'z') {
+ const int32_t* row = nsHtml5NamedCharactersAccel::HILO_ACCEL[c];
+ if (row) {
+ hilo = row[firstCharKey];
+ }
+ }
+ if (!hilo) {
+ if (P::reportErrors) {
+ errNoNamedCharacterMatch();
+ }
+ emitOrAppendCharRefBuf(returnState);
+ if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = P::transition(mViewSource, returnState, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ appendCharRefBuf(c);
+ lo = hilo & 0xFFFF;
+ hi = hilo >> 16;
+ entCol = -1;
+ candidate = -1;
+ charRefBufMark = 0;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL, reconsume, pos);
+ }
+ }
+ case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ if (c == '\0') {
+ NS_HTML5_BREAK(stateloop);
+ }
+ entCol++;
+ for (; ; ) {
+ if (hi < lo) {
+ NS_HTML5_BREAK(outer);
+ }
+ if (entCol == nsHtml5NamedCharacters::NAMES[lo].length()) {
+ candidate = lo;
+ charRefBufMark = charRefBufLen;
+ lo++;
+ } else if (entCol > nsHtml5NamedCharacters::NAMES[lo].length()) {
+ NS_HTML5_BREAK(outer);
+ } else if (c > nsHtml5NamedCharacters::NAMES[lo].charAt(entCol)) {
+ lo++;
+ } else {
+ NS_HTML5_BREAK(loloop);
+ }
+ }
+ loloop_end: ;
+ for (; ; ) {
+ if (hi < lo) {
+ NS_HTML5_BREAK(outer);
+ }
+ if (entCol == nsHtml5NamedCharacters::NAMES[hi].length()) {
+ NS_HTML5_BREAK(hiloop);
+ }
+ if (entCol > nsHtml5NamedCharacters::NAMES[hi].length()) {
+ NS_HTML5_BREAK(outer);
+ } else if (c < nsHtml5NamedCharacters::NAMES[hi].charAt(entCol)) {
+ hi--;
+ } else {
+ NS_HTML5_BREAK(hiloop);
+ }
+ }
+ hiloop_end: ;
+ if (c == ';') {
+ if (entCol + 1 == nsHtml5NamedCharacters::NAMES[lo].length()) {
+ candidate = lo;
+ charRefBufMark = charRefBufLen;
+ }
+ NS_HTML5_BREAK(outer);
+ }
+ if (hi < lo) {
+ NS_HTML5_BREAK(outer);
+ }
+ appendCharRefBuf(c);
+ continue;
+ }
+ outer_end: ;
+ if (candidate == -1) {
+ if (P::reportErrors) {
+ errNoNamedCharacterMatch();
+ }
+ emitOrAppendCharRefBuf(returnState);
+ if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = P::transition(mViewSource, returnState, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ } else {
+ const nsHtml5CharacterName& candidateName = nsHtml5NamedCharacters::NAMES[candidate];
+ if (!candidateName.length() || candidateName.charAt(candidateName.length() - 1) != ';') {
+ if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ char16_t ch;
+ if (charRefBufMark == charRefBufLen) {
+ ch = c;
+ } else {
+ ch = charRefBuf[charRefBufMark];
+ }
+ if (ch == '=' || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
+ if (P::reportErrors) {
+ errNoNamedCharacterMatch();
+ }
+ appendCharRefBufToStrBuf();
+ reconsume = true;
+ state = P::transition(mViewSource, returnState, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ if (P::reportErrors) {
+ errUnescapedAmpersandInterpretedAsCharacterReference();
+ }
+ } else {
+ if (P::reportErrors) {
+ errNotSemicolonTerminated();
+ }
+ }
+ }
+ P::completedNamedCharacterReference(mViewSource);
+ const char16_t* val = nsHtml5NamedCharacters::VALUES[candidate];
+ if (!val[1]) {
+ emitOrAppendOne(val, returnState);
+ } else {
+ emitOrAppendTwo(val, returnState);
+ }
+ if (charRefBufMark < charRefBufLen) {
+ if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ appendStrBuf(charRefBuf, charRefBufMark, charRefBufLen - charRefBufMark);
+ } else {
+ tokenHandler->characters(charRefBuf, charRefBufMark, charRefBufLen - charRefBufMark);
+ }
+ }
+ bool earlyBreak = (c == ';' && charRefBufMark == charRefBufLen);
+ charRefBufLen = 0;
+ if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ cstart = earlyBreak ? pos + 1 : pos;
+ }
+ reconsume = !earlyBreak;
+ state = P::transition(mViewSource, returnState, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ case NS_HTML5TOKENIZER_CONSUME_NCR: {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ value = 0;
+ seenDigits = false;
+ switch(c) {
+ case 'x':
+ case 'X': {
+ appendCharRefBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_HEX_NCR_LOOP, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP, reconsume, pos);
+ }
+ }
+ }
+ case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ MOZ_ASSERT(value >= 0, "value must not become negative.");
+ if (c >= '0' && c <= '9') {
+ seenDigits = true;
+ if (value <= 0x10FFFF) {
+ value *= 10;
+ value += c - '0';
+ }
+ continue;
+ } else if (c == ';') {
+ if (seenDigits) {
+ if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ cstart = pos + 1;
+ }
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_HANDLE_NCR_VALUE, reconsume, pos);
+ NS_HTML5_BREAK(decimalloop);
+ } else {
+ if (P::reportErrors) {
+ errNoDigitsInNCR();
+ }
+ appendCharRefBuf(';');
+ emitOrAppendCharRefBuf(returnState);
+ if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ cstart = pos + 1;
+ }
+ state = P::transition(mViewSource, returnState, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ } else {
+ if (!seenDigits) {
+ if (P::reportErrors) {
+ errNoDigitsInNCR();
+ }
+ emitOrAppendCharRefBuf(returnState);
+ if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = P::transition(mViewSource, returnState, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ } else {
+ if (P::reportErrors) {
+ errCharRefLacksSemicolon();
+ }
+ if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_HANDLE_NCR_VALUE, reconsume, pos);
+ NS_HTML5_BREAK(decimalloop);
+ }
+ }
+ }
+ decimalloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_HANDLE_NCR_VALUE: {
+ charRefBufLen = 0;
+ handleNcrValue(returnState);
+ state = P::transition(mViewSource, returnState, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case NS_HTML5TOKENIZER_HEX_NCR_LOOP: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ MOZ_ASSERT(value >= 0, "value must not become negative.");
+ if (c >= '0' && c <= '9') {
+ seenDigits = true;
+ if (value <= 0x10FFFF) {
+ value *= 16;
+ value += c - '0';
+ }
+ continue;
+ } else if (c >= 'A' && c <= 'F') {
+ seenDigits = true;
+ if (value <= 0x10FFFF) {
+ value *= 16;
+ value += c - 'A' + 10;
+ }
+ continue;
+ } else if (c >= 'a' && c <= 'f') {
+ seenDigits = true;
+ if (value <= 0x10FFFF) {
+ value *= 16;
+ value += c - 'a' + 10;
+ }
+ continue;
+ } else if (c == ';') {
+ if (seenDigits) {
+ if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ cstart = pos + 1;
+ }
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_HANDLE_NCR_VALUE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ } else {
+ if (P::reportErrors) {
+ errNoDigitsInNCR();
+ }
+ appendCharRefBuf(';');
+ emitOrAppendCharRefBuf(returnState);
+ if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ cstart = pos + 1;
+ }
+ state = P::transition(mViewSource, returnState, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ } else {
+ if (!seenDigits) {
+ if (P::reportErrors) {
+ errNoDigitsInNCR();
+ }
+ emitOrAppendCharRefBuf(returnState);
+ if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = P::transition(mViewSource, returnState, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ } else {
+ if (P::reportErrors) {
+ errCharRefLacksSemicolon();
+ }
+ if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ cstart = pos;
+ }
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_HANDLE_NCR_VALUE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ }
+ case NS_HTML5TOKENIZER_PLAINTEXT: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '\0': {
+ emitPlaintextReplacementCharacter(buf, pos);
+ continue;
+ }
+ case '\r': {
+ emitCarriageReturn(buf, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+
+ }
+ case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN: {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '>': {
+ if (P::reportErrors) {
+ errLtSlashGt();
+ }
+ cstart = pos + 1;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\r': {
+ silentCarriageReturn();
+ if (P::reportErrors) {
+ errGarbageAfterLtSlash();
+ }
+ clearStrBufBeforeUse();
+ appendStrBuf('\n');
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ if (P::reportErrors) {
+ errGarbageAfterLtSlash();
+ }
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ if (c >= 'A' && c <= 'Z') {
+ c += 0x20;
+ }
+ if (c >= 'a' && c <= 'z') {
+ endTag = true;
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_TAG_NAME, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ } else {
+ if (P::reportErrors) {
+ errGarbageAfterLtSlash();
+ }
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ }
+ case NS_HTML5TOKENIZER_RCDATA: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '&': {
+ flushChars(buf, pos);
+ MOZ_ASSERT(!charRefBufLen, "charRefBufLen not reset after previous use!");
+ appendCharRefBuf(c);
+ setAdditionalAndRememberAmpersandLocation('\0');
+ returnState = state;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '<': {
+ flushChars(buf, pos);
+ returnState = state;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ emitReplacementCharacter(buf, pos);
+ continue;
+ }
+ case '\r': {
+ emitCarriageReturn(buf, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+
+ }
+ case NS_HTML5TOKENIZER_RAWTEXT: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '<': {
+ flushChars(buf, pos);
+ returnState = state;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN, reconsume, pos);
+ NS_HTML5_BREAK(rawtextloop);
+ }
+ case '\0': {
+ emitReplacementCharacter(buf, pos);
+ continue;
+ }
+ case '\r': {
+ emitCarriageReturn(buf, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+ rawtextloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '/': {
+ index = 0;
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME, reconsume, pos);
+ NS_HTML5_BREAK(rawtextrcdatalessthansignloop);
+ }
+ default: {
+ tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
+ cstart = pos;
+ reconsume = true;
+ state = P::transition(mViewSource, returnState, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ rawtextrcdatalessthansignloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ if (index < endTagExpectationAsArray.length) {
+ char16_t e = endTagExpectationAsArray[index];
+ char16_t folded = c;
+ if (c >= 'A' && c <= 'Z') {
+ folded += 0x20;
+ }
+ if (folded != e) {
+ tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
+ emitStrBuf();
+ cstart = pos;
+ reconsume = true;
+ state = P::transition(mViewSource, returnState, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ appendStrBuf(c);
+ index++;
+ continue;
+ } else {
+ endTag = true;
+ tagName = endTagExpectation;
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ clearStrBufAfterUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ clearStrBufAfterUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '/': {
+ clearStrBufAfterUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ clearStrBufAfterUse();
+ state = P::transition(mViewSource, emitCurrentTagToken(false, pos), reconsume, pos);
+ if (shouldSuspend) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
+ emitStrBuf();
+ if (c == '\0') {
+ emitReplacementCharacter(buf, pos);
+ } else {
+ cstart = pos;
+ }
+ state = P::transition(mViewSource, returnState, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ }
+ }
+ case NS_HTML5TOKENIZER_BOGUS_COMMENT: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '>': {
+ emitComment(0, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '-': {
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN, reconsume, pos);
+ NS_HTML5_BREAK(boguscommentloop);
+ }
+ case '\r': {
+ appendStrBufCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ appendStrBufLineFeed();
+ continue;
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ appendStrBuf(c);
+ continue;
+ }
+ }
+ }
+ boguscommentloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN: {
+ boguscommenthyphenloop: for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '>': {
+ emitComment(0, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '-': {
+ appendSecondHyphenToBogusComment();
+ NS_HTML5_CONTINUE(boguscommenthyphenloop);
+ }
+ case '\r': {
+ appendStrBufCarriageReturn();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ appendStrBufLineFeed();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+
+ }
+ case NS_HTML5TOKENIZER_SCRIPT_DATA: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '<': {
+ flushChars(buf, pos);
+ returnState = state;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN, reconsume, pos);
+ NS_HTML5_BREAK(scriptdataloop);
+ }
+ case '\0': {
+ emitReplacementCharacter(buf, pos);
+ continue;
+ }
+ case '\r': {
+ emitCarriageReturn(buf, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+ scriptdataloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '/': {
+ index = 0;
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '!': {
+ tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
+ cstart = pos;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START, reconsume, pos);
+ NS_HTML5_BREAK(scriptdatalessthansignloop);
+ }
+ default: {
+ tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
+ cstart = pos;
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ scriptdatalessthansignloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '-': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START_DASH, reconsume, pos);
+ NS_HTML5_BREAK(scriptdataescapestartloop);
+ }
+ default: {
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ scriptdataescapestartloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START_DASH: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '-': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH, reconsume, pos);
+ NS_HTML5_BREAK(scriptdataescapestartdashloop);
+ }
+ default: {
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ scriptdataescapestartdashloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '-': {
+ continue;
+ }
+ case '<': {
+ flushChars(buf, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ emitReplacementCharacter(buf, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED, reconsume, pos);
+ NS_HTML5_BREAK(scriptdataescapeddashdashloop);
+ }
+ case '\r': {
+ emitCarriageReturn(buf, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ default: {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED, reconsume, pos);
+ NS_HTML5_BREAK(scriptdataescapeddashdashloop);
+ }
+ }
+ }
+ scriptdataescapeddashdashloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '-': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH, reconsume, pos);
+ NS_HTML5_BREAK(scriptdataescapedloop);
+ }
+ case '<': {
+ flushChars(buf, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ emitReplacementCharacter(buf, pos);
+ continue;
+ }
+ case '\r': {
+ emitCarriageReturn(buf, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+ scriptdataescapedloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '-': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '<': {
+ flushChars(buf, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN, reconsume, pos);
+ NS_HTML5_BREAK(scriptdataescapeddashloop);
+ }
+ case '\0': {
+ emitReplacementCharacter(buf, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\r': {
+ emitCarriageReturn(buf, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ default: {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ scriptdataescapeddashloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '/': {
+ index = 0;
+ clearStrBufBeforeUse();
+ returnState = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case 'S':
+ case 's': {
+ tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
+ cstart = pos;
+ index = 1;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_START, reconsume, pos);
+ NS_HTML5_BREAK(scriptdataescapedlessthanloop);
+ }
+ default: {
+ tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
+ cstart = pos;
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ scriptdataescapedlessthanloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_START: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ MOZ_ASSERT(index > 0);
+ if (index < 6) {
+ char16_t folded = c;
+ if (c >= 'A' && c <= 'Z') {
+ folded += 0x20;
+ }
+ if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ index++;
+ continue;
+ }
+ switch(c) {
+ case '\r': {
+ emitCarriageReturn(buf, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f':
+ case '/':
+ case '>': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ NS_HTML5_BREAK(scriptdatadoubleescapestartloop);
+ }
+ default: {
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ scriptdatadoubleescapestartloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '-': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH, reconsume, pos);
+ NS_HTML5_BREAK(scriptdatadoubleescapedloop);
+ }
+ case '<': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ emitReplacementCharacter(buf, pos);
+ continue;
+ }
+ case '\r': {
+ emitCarriageReturn(buf, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+ scriptdatadoubleescapedloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '-': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH, reconsume, pos);
+ NS_HTML5_BREAK(scriptdatadoubleescapeddashloop);
+ }
+ case '<': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ emitReplacementCharacter(buf, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\r': {
+ emitCarriageReturn(buf, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ default: {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ scriptdatadoubleescapeddashloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '-': {
+ continue;
+ }
+ case '<': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN, reconsume, pos);
+ NS_HTML5_BREAK(scriptdatadoubleescapeddashdashloop);
+ }
+ case '>': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ emitReplacementCharacter(buf, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\r': {
+ emitCarriageReturn(buf, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ default: {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ scriptdatadoubleescapeddashdashloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '/': {
+ index = 0;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_END, reconsume, pos);
+ NS_HTML5_BREAK(scriptdatadoubleescapedlessthanloop);
+ }
+ default: {
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ scriptdatadoubleescapedlessthanloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_END: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ if (index < 6) {
+ char16_t folded = c;
+ if (c >= 'A' && c <= 'Z') {
+ folded += 0x20;
+ }
+ if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ index++;
+ continue;
+ }
+ switch(c) {
+ case '\r': {
+ emitCarriageReturn(buf, pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f':
+ case '/':
+ case '>': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+
+ }
+ case NS_HTML5TOKENIZER_MARKUP_DECLARATION_OCTYPE: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ if (index < 6) {
+ char16_t folded = c;
+ if (c >= 'A' && c <= 'Z') {
+ folded += 0x20;
+ }
+ if (folded == nsHtml5Tokenizer::OCTYPE[index]) {
+ appendStrBuf(c);
+ } else {
+ if (P::reportErrors) {
+ errBogusComment();
+ }
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ index++;
+ continue;
+ } else {
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE, reconsume, pos);
+ NS_HTML5_BREAK(markupdeclarationdoctypeloop);
+ }
+ }
+ markupdeclarationdoctypeloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_DOCTYPE: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ initDoctypeFields();
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME, reconsume, pos);
+ NS_HTML5_BREAK(doctypeloop);
+ }
+ default: {
+ if (P::reportErrors) {
+ errMissingSpaceBeforeDoctypeName();
+ }
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME, reconsume, pos);
+ NS_HTML5_BREAK(doctypeloop);
+ }
+ }
+ }
+ doctypeloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ continue;
+ }
+ case '>': {
+ if (P::reportErrors) {
+ errNamelessDoctype();
+ }
+ forceQuirks = true;
+ emitDoctypeToken(pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ if (c >= 'A' && c <= 'Z') {
+ c += 0x20;
+ }
+ clearStrBufBeforeUse();
+ appendStrBuf(c);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_NAME, reconsume, pos);
+ NS_HTML5_BREAK(beforedoctypenameloop);
+ }
+ }
+ }
+ beforedoctypenameloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_DOCTYPE_NAME: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ strBufToDoctypeName();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ strBufToDoctypeName();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME, reconsume, pos);
+ NS_HTML5_BREAK(doctypenameloop);
+ }
+ case '>': {
+ strBufToDoctypeName();
+ emitDoctypeToken(pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ if (c >= 'A' && c <= 'Z') {
+ c += 0x0020;
+ }
+ appendStrBuf(c);
+ continue;
+ }
+ }
+ }
+ doctypenameloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ continue;
+ }
+ case '>': {
+ emitDoctypeToken(pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case 'p':
+ case 'P': {
+ index = 0;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_UBLIC, reconsume, pos);
+ NS_HTML5_BREAK(afterdoctypenameloop);
+ }
+ case 's':
+ case 'S': {
+ index = 0;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_YSTEM, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ bogusDoctype();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_DOCTYPE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ afterdoctypenameloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_DOCTYPE_UBLIC: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ if (index < 5) {
+ char16_t folded = c;
+ if (c >= 'A' && c <= 'Z') {
+ folded += 0x20;
+ }
+ if (folded != nsHtml5Tokenizer::UBLIC[index]) {
+ bogusDoctype();
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_DOCTYPE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ index++;
+ continue;
+ } else {
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD, reconsume, pos);
+ NS_HTML5_BREAK(doctypeublicloop);
+ }
+ }
+ doctypeublicloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos);
+ NS_HTML5_BREAK(afterdoctypepublickeywordloop);
+ }
+ case '\"': {
+ if (P::reportErrors) {
+ errNoSpaceBetweenDoctypePublicKeywordAndQuote();
+ }
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\'': {
+ if (P::reportErrors) {
+ errNoSpaceBetweenDoctypePublicKeywordAndQuote();
+ }
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ if (P::reportErrors) {
+ errExpectedPublicId();
+ }
+ forceQuirks = true;
+ emitDoctypeToken(pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ bogusDoctype();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_DOCTYPE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ afterdoctypepublickeywordloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ continue;
+ }
+ case '\"': {
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
+ NS_HTML5_BREAK(beforedoctypepublicidentifierloop);
+ }
+ case '\'': {
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ if (P::reportErrors) {
+ errExpectedPublicId();
+ }
+ forceQuirks = true;
+ emitDoctypeToken(pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ bogusDoctype();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_DOCTYPE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ beforedoctypepublicidentifierloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\"': {
+ publicIdentifier = strBufToString();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos);
+ NS_HTML5_BREAK(doctypepublicidentifierdoublequotedloop);
+ }
+ case '>': {
+ if (P::reportErrors) {
+ errGtInPublicId();
+ }
+ forceQuirks = true;
+ publicIdentifier = strBufToString();
+ emitDoctypeToken(pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\r': {
+ appendStrBufCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ appendStrBufLineFeed();
+ continue;
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ appendStrBuf(c);
+ continue;
+ }
+ }
+ }
+ doctypepublicidentifierdoublequotedloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS, reconsume, pos);
+ NS_HTML5_BREAK(afterdoctypepublicidentifierloop);
+ }
+ case '>': {
+ emitDoctypeToken(pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\"': {
+ if (P::reportErrors) {
+ errNoSpaceBetweenPublicAndSystemIds();
+ }
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\'': {
+ if (P::reportErrors) {
+ errNoSpaceBetweenPublicAndSystemIds();
+ }
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ bogusDoctype();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_DOCTYPE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ afterdoctypepublicidentifierloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ continue;
+ }
+ case '>': {
+ emitDoctypeToken(pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\"': {
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
+ NS_HTML5_BREAK(betweendoctypepublicandsystemidentifiersloop);
+ }
+ case '\'': {
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ bogusDoctype();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_DOCTYPE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ betweendoctypepublicandsystemidentifiersloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\"': {
+ systemIdentifier = strBufToString();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ if (P::reportErrors) {
+ errGtInSystemId();
+ }
+ forceQuirks = true;
+ systemIdentifier = strBufToString();
+ emitDoctypeToken(pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\r': {
+ appendStrBufCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ appendStrBufLineFeed();
+ continue;
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ appendStrBuf(c);
+ continue;
+ }
+ }
+ }
+
+ }
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ continue;
+ }
+ case '>': {
+ emitDoctypeToken(pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ bogusDoctypeWithoutQuirks();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_DOCTYPE, reconsume, pos);
+ NS_HTML5_BREAK(afterdoctypesystemidentifierloop);
+ }
+ }
+ }
+ afterdoctypesystemidentifierloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_BOGUS_DOCTYPE: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '>': {
+ emitDoctypeToken(pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\r': {
+ silentCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+ }
+ case NS_HTML5TOKENIZER_DOCTYPE_YSTEM: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ if (index < 5) {
+ char16_t folded = c;
+ if (c >= 'A' && c <= 'Z') {
+ folded += 0x20;
+ }
+ if (folded != nsHtml5Tokenizer::YSTEM[index]) {
+ bogusDoctype();
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_DOCTYPE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ index++;
+ NS_HTML5_CONTINUE(stateloop);
+ } else {
+ reconsume = true;
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD, reconsume, pos);
+ NS_HTML5_BREAK(doctypeystemloop);
+ }
+ }
+ doctypeystemloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD: {
+ for (; ; ) {
+ if (reconsume) {
+ reconsume = false;
+ } else {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ }
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos);
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos);
+ NS_HTML5_BREAK(afterdoctypesystemkeywordloop);
+ }
+ case '\"': {
+ if (P::reportErrors) {
+ errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
+ }
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\'': {
+ if (P::reportErrors) {
+ errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
+ }
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ if (P::reportErrors) {
+ errExpectedPublicId();
+ }
+ forceQuirks = true;
+ emitDoctypeToken(pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ bogusDoctype();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_DOCTYPE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ afterdoctypesystemkeywordloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\r': {
+ silentCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ silentLineFeed();
+ }
+ case ' ':
+ case '\t':
+ case '\f': {
+ continue;
+ }
+ case '\"': {
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\'': {
+ clearStrBufBeforeUse();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
+ NS_HTML5_BREAK(beforedoctypesystemidentifierloop);
+ }
+ case '>': {
+ if (P::reportErrors) {
+ errExpectedSystemId();
+ }
+ forceQuirks = true;
+ emitDoctypeToken(pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ bogusDoctype();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_DOCTYPE, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ beforedoctypesystemidentifierloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\'': {
+ systemIdentifier = strBufToString();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ if (P::reportErrors) {
+ errGtInSystemId();
+ }
+ forceQuirks = true;
+ systemIdentifier = strBufToString();
+ emitDoctypeToken(pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\r': {
+ appendStrBufCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ appendStrBufLineFeed();
+ continue;
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ appendStrBuf(c);
+ continue;
+ }
+ }
+ }
+ }
+ case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\'': {
+ publicIdentifier = strBufToString();
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '>': {
+ if (P::reportErrors) {
+ errGtInPublicId();
+ }
+ forceQuirks = true;
+ publicIdentifier = strBufToString();
+ emitDoctypeToken(pos);
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ case '\r': {
+ appendStrBufCarriageReturn();
+ NS_HTML5_BREAK(stateloop);
+ }
+ case '\n': {
+ appendStrBufLineFeed();
+ continue;
+ }
+ case '\0': {
+ c = 0xfffd;
+ }
+ default: {
+ appendStrBuf(c);
+ continue;
+ }
+ }
+ }
+ }
+ case NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION: {
+ for (; ; ) {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '\?': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION_QUESTION_MARK, reconsume, pos);
+ NS_HTML5_BREAK(processinginstructionloop);
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+ processinginstructionloop_end: ;
+ }
+ case NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION_QUESTION_MARK: {
+ if (++pos == endPos) {
+ NS_HTML5_BREAK(stateloop);
+ }
+ c = checkChar(buf, pos);
+ switch(c) {
+ case '>': {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ default: {
+ state = P::transition(mViewSource, NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION, reconsume, pos);
+ NS_HTML5_CONTINUE(stateloop);
+ }
+ }
+ }
+ }
+ }
+ stateloop_end: ;
+ flushChars(buf, pos);
+ stateSave = state;
+ returnStateSave = returnState;
+ return pos;
+}
+
+void
+nsHtml5Tokenizer::initDoctypeFields()
+{
+ clearStrBufAfterUse();
+ doctypeName = nsHtml5Atoms::emptystring;
+ if (systemIdentifier) {
+ nsHtml5Portability::releaseString(systemIdentifier);
+ systemIdentifier = nullptr;
+ }
+ if (publicIdentifier) {
+ nsHtml5Portability::releaseString(publicIdentifier);
+ publicIdentifier = nullptr;
+ }
+ forceQuirks = false;
+}
+
+void
+nsHtml5Tokenizer::emitCarriageReturn(char16_t* buf, int32_t pos)
+{
+ silentCarriageReturn();
+ flushChars(buf, pos);
+ tokenHandler->characters(nsHtml5Tokenizer::LF, 0, 1);
+ cstart = INT32_MAX;
+}
+
+void
+nsHtml5Tokenizer::emitReplacementCharacter(char16_t* buf, int32_t pos)
+{
+ flushChars(buf, pos);
+ tokenHandler->zeroOriginatingReplacementCharacter();
+ cstart = pos + 1;
+}
+
+void
+nsHtml5Tokenizer::emitPlaintextReplacementCharacter(char16_t* buf, int32_t pos)
+{
+ flushChars(buf, pos);
+ tokenHandler->characters(REPLACEMENT_CHARACTER, 0, 1);
+ cstart = pos + 1;
+}
+
+void
+nsHtml5Tokenizer::setAdditionalAndRememberAmpersandLocation(char16_t add)
+{
+ additional = add;
+}
+
+void
+nsHtml5Tokenizer::bogusDoctype()
+{
+ errBogusDoctype();
+ forceQuirks = true;
+}
+
+void
+nsHtml5Tokenizer::bogusDoctypeWithoutQuirks()
+{
+ errBogusDoctype();
+ forceQuirks = false;
+}
+
+void
+nsHtml5Tokenizer::handleNcrValue(int32_t returnState)
+{
+ if (value <= 0xFFFF) {
+ if (value >= 0x80 && value <= 0x9f) {
+ errNcrInC1Range();
+ char16_t* val = nsHtml5NamedCharacters::WINDOWS_1252[value - 0x80];
+ emitOrAppendOne(val, returnState);
+ } else if (value == 0x0) {
+ errNcrZero();
+ emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState);
+ } else if ((value & 0xF800) == 0xD800) {
+ errNcrSurrogate();
+ emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState);
+ } else {
+ char16_t ch = (char16_t) value;
+ bmpChar[0] = ch;
+ emitOrAppendOne(bmpChar, returnState);
+ }
+ } else if (value <= 0x10FFFF) {
+ astralChar[0] = (char16_t) (NS_HTML5TOKENIZER_LEAD_OFFSET + (value >> 10));
+ astralChar[1] = (char16_t) (0xDC00 + (value & 0x3FF));
+ emitOrAppendTwo(astralChar, returnState);
+ } else {
+ errNcrOutOfRange();
+ emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState);
+ }
+}
+
+void
+nsHtml5Tokenizer::eof()
+{
+ int32_t state = stateSave;
+ int32_t returnState = returnStateSave;
+ eofloop: for (; ; ) {
+ switch(state) {
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN:
+ case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
+ tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_TAG_OPEN: {
+ errEofAfterLt();
+ tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN: {
+ tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME: {
+ tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
+ emitStrBuf();
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN: {
+ errEofAfterLt();
+ tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_TAG_NAME: {
+ errEofInTagName();
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
+ case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED:
+ case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG: {
+ errEofWithoutGt();
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_ATTRIBUTE_NAME: {
+ errEofInAttributeName();
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME:
+ case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE: {
+ errEofWithoutGt();
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED:
+ case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED:
+ case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED: {
+ errEofInAttributeValue();
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_BOGUS_COMMENT: {
+ emitComment(0, 0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN: {
+ emitComment(0, 0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_MARKUP_DECLARATION_OPEN: {
+ errBogusComment();
+ emitComment(0, 0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_MARKUP_DECLARATION_HYPHEN: {
+ errBogusComment();
+ emitComment(0, 0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_MARKUP_DECLARATION_OCTYPE: {
+ if (index < 6) {
+ errBogusComment();
+ emitComment(0, 0);
+ } else {
+ errEofInDoctype();
+ doctypeName = nsHtml5Atoms::emptystring;
+ if (systemIdentifier) {
+ nsHtml5Portability::releaseString(systemIdentifier);
+ systemIdentifier = nullptr;
+ }
+ if (publicIdentifier) {
+ nsHtml5Portability::releaseString(publicIdentifier);
+ publicIdentifier = nullptr;
+ }
+ forceQuirks = true;
+ emitDoctypeToken(0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_COMMENT_START:
+ case NS_HTML5TOKENIZER_COMMENT: {
+ errEofInComment();
+ emitComment(0, 0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_COMMENT_END: {
+ errEofInComment();
+ emitComment(2, 0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_COMMENT_END_DASH:
+ case NS_HTML5TOKENIZER_COMMENT_START_DASH: {
+ errEofInComment();
+ emitComment(1, 0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_COMMENT_END_BANG: {
+ errEofInComment();
+ emitComment(3, 0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_DOCTYPE:
+ case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME: {
+ errEofInDoctype();
+ forceQuirks = true;
+ emitDoctypeToken(0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_DOCTYPE_NAME: {
+ errEofInDoctype();
+ strBufToDoctypeName();
+ forceQuirks = true;
+ emitDoctypeToken(0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_DOCTYPE_UBLIC:
+ case NS_HTML5TOKENIZER_DOCTYPE_YSTEM:
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME:
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD:
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD:
+ case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
+ errEofInDoctype();
+ forceQuirks = true;
+ emitDoctypeToken(0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
+ case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
+ errEofInPublicId();
+ forceQuirks = true;
+ publicIdentifier = strBufToString();
+ emitDoctypeToken(0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
+ case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
+ case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
+ errEofInDoctype();
+ forceQuirks = true;
+ emitDoctypeToken(0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
+ case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
+ errEofInSystemId();
+ forceQuirks = true;
+ systemIdentifier = strBufToString();
+ emitDoctypeToken(0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
+ errEofInDoctype();
+ forceQuirks = true;
+ emitDoctypeToken(0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_BOGUS_DOCTYPE: {
+ emitDoctypeToken(0);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE: {
+ emitOrAppendCharRefBuf(returnState);
+ state = returnState;
+ continue;
+ }
+ case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP: {
+ errNoNamedCharacterMatch();
+ emitOrAppendCharRefBuf(returnState);
+ state = returnState;
+ continue;
+ }
+ case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL: {
+ for (; ; ) {
+ char16_t c = '\0';
+ entCol++;
+ for (; ; ) {
+ if (hi == -1) {
+ NS_HTML5_BREAK(hiloop);
+ }
+ if (entCol == nsHtml5NamedCharacters::NAMES[hi].length()) {
+ NS_HTML5_BREAK(hiloop);
+ }
+ if (entCol > nsHtml5NamedCharacters::NAMES[hi].length()) {
+ NS_HTML5_BREAK(outer);
+ } else if (c < nsHtml5NamedCharacters::NAMES[hi].charAt(entCol)) {
+ hi--;
+ } else {
+ NS_HTML5_BREAK(hiloop);
+ }
+ }
+ hiloop_end: ;
+ for (; ; ) {
+ if (hi < lo) {
+ NS_HTML5_BREAK(outer);
+ }
+ if (entCol == nsHtml5NamedCharacters::NAMES[lo].length()) {
+ candidate = lo;
+ charRefBufMark = charRefBufLen;
+ lo++;
+ } else if (entCol > nsHtml5NamedCharacters::NAMES[lo].length()) {
+ NS_HTML5_BREAK(outer);
+ } else if (c > nsHtml5NamedCharacters::NAMES[lo].charAt(entCol)) {
+ lo++;
+ } else {
+ NS_HTML5_BREAK(loloop);
+ }
+ }
+ loloop_end: ;
+ if (hi < lo) {
+ NS_HTML5_BREAK(outer);
+ }
+ continue;
+ }
+ outer_end: ;
+ if (candidate == -1) {
+ errNoNamedCharacterMatch();
+ emitOrAppendCharRefBuf(returnState);
+ state = returnState;
+ NS_HTML5_CONTINUE(eofloop);
+ } else {
+ const nsHtml5CharacterName& candidateName = nsHtml5NamedCharacters::NAMES[candidate];
+ if (!candidateName.length() || candidateName.charAt(candidateName.length() - 1) != ';') {
+ if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ char16_t ch;
+ if (charRefBufMark == charRefBufLen) {
+ ch = '\0';
+ } else {
+ ch = charRefBuf[charRefBufMark];
+ }
+ if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
+ errNoNamedCharacterMatch();
+ appendCharRefBufToStrBuf();
+ state = returnState;
+ NS_HTML5_CONTINUE(eofloop);
+ }
+ }
+ if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ errUnescapedAmpersandInterpretedAsCharacterReference();
+ } else {
+ errNotSemicolonTerminated();
+ }
+ }
+ const char16_t* val = nsHtml5NamedCharacters::VALUES[candidate];
+ if (!val[1]) {
+ emitOrAppendOne(val, returnState);
+ } else {
+ emitOrAppendTwo(val, returnState);
+ }
+ if (charRefBufMark < charRefBufLen) {
+ if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ appendStrBuf(charRefBuf, charRefBufMark, charRefBufLen - charRefBufMark);
+ } else {
+ tokenHandler->characters(charRefBuf, charRefBufMark, charRefBufLen - charRefBufMark);
+ }
+ }
+ charRefBufLen = 0;
+ state = returnState;
+ NS_HTML5_CONTINUE(eofloop);
+ }
+ }
+ case NS_HTML5TOKENIZER_CONSUME_NCR:
+ case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP:
+ case NS_HTML5TOKENIZER_HEX_NCR_LOOP: {
+ if (!seenDigits) {
+ errNoDigitsInNCR();
+ emitOrAppendCharRefBuf(returnState);
+ state = returnState;
+ continue;
+ } else {
+ errCharRefLacksSemicolon();
+ }
+ handleNcrValue(returnState);
+ state = returnState;
+ continue;
+ }
+ case NS_HTML5TOKENIZER_CDATA_RSQB: {
+ tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_CDATA_RSQB_RSQB: {
+ tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 2);
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TOKENIZER_DATA:
+ default: {
+ NS_HTML5_BREAK(eofloop);
+ }
+ }
+ }
+ eofloop_end: ;
+ tokenHandler->eof();
+ return;
+}
+
+void
+nsHtml5Tokenizer::emitDoctypeToken(int32_t pos)
+{
+ cstart = pos + 1;
+ tokenHandler->doctype(doctypeName, publicIdentifier, systemIdentifier, forceQuirks);
+ doctypeName = nullptr;
+ nsHtml5Portability::releaseString(publicIdentifier);
+ publicIdentifier = nullptr;
+ nsHtml5Portability::releaseString(systemIdentifier);
+ systemIdentifier = nullptr;
+}
+
+bool
+nsHtml5Tokenizer::internalEncodingDeclaration(nsString* internalCharset)
+{
+ if (encodingDeclarationHandler) {
+ return encodingDeclarationHandler->internalEncodingDeclaration(internalCharset);
+ }
+ return false;
+}
+
+void
+nsHtml5Tokenizer::emitOrAppendTwo(const char16_t* val, int32_t returnState)
+{
+ if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ appendStrBuf(val[0]);
+ appendStrBuf(val[1]);
+ } else {
+ tokenHandler->characters(val, 0, 2);
+ }
+}
+
+void
+nsHtml5Tokenizer::emitOrAppendOne(const char16_t* val, int32_t returnState)
+{
+ if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
+ appendStrBuf(val[0]);
+ } else {
+ tokenHandler->characters(val, 0, 1);
+ }
+}
+
+void
+nsHtml5Tokenizer::end()
+{
+ strBuf = nullptr;
+ doctypeName = nullptr;
+ if (systemIdentifier) {
+ nsHtml5Portability::releaseString(systemIdentifier);
+ systemIdentifier = nullptr;
+ }
+ if (publicIdentifier) {
+ nsHtml5Portability::releaseString(publicIdentifier);
+ publicIdentifier = nullptr;
+ }
+ if (tagName) {
+ tagName->release();
+ tagName = nullptr;
+ }
+ if (attributeName) {
+ attributeName->release();
+ attributeName = nullptr;
+ }
+ tokenHandler->endTokenization();
+ if (attributes) {
+ attributes->clear(0);
+ }
+}
+
+void
+nsHtml5Tokenizer::requestSuspension()
+{
+ shouldSuspend = true;
+}
+
+bool
+nsHtml5Tokenizer::isInDataState()
+{
+ return (stateSave == NS_HTML5TOKENIZER_DATA);
+}
+
+void
+nsHtml5Tokenizer::resetToDataState()
+{
+ clearStrBufAfterUse();
+ charRefBufLen = 0;
+ stateSave = NS_HTML5TOKENIZER_DATA;
+ lastCR = false;
+ index = 0;
+ forceQuirks = false;
+ additional = '\0';
+ entCol = -1;
+ firstCharKey = -1;
+ lo = 0;
+ hi = 0;
+ candidate = -1;
+ charRefBufMark = 0;
+ value = 0;
+ seenDigits = false;
+ endTag = false;
+ shouldSuspend = false;
+ initDoctypeFields();
+ if (tagName) {
+ tagName->release();
+ tagName = nullptr;
+ }
+ if (attributeName) {
+ attributeName->release();
+ attributeName = nullptr;
+ }
+ if (newAttributesEachTime) {
+ if (attributes) {
+ delete attributes;
+ attributes = nullptr;
+ }
+ }
+}
+
+void
+nsHtml5Tokenizer::loadState(nsHtml5Tokenizer* other)
+{
+ strBufLen = other->strBufLen;
+ if (strBufLen > strBuf.length) {
+ strBuf = jArray<char16_t,int32_t>::newJArray(strBufLen);
+ }
+ nsHtml5ArrayCopy::arraycopy(other->strBuf, strBuf, strBufLen);
+ charRefBufLen = other->charRefBufLen;
+ nsHtml5ArrayCopy::arraycopy(other->charRefBuf, charRefBuf, charRefBufLen);
+ stateSave = other->stateSave;
+ returnStateSave = other->returnStateSave;
+ endTagExpectation = other->endTagExpectation;
+ endTagExpectationAsArray = other->endTagExpectationAsArray;
+ lastCR = other->lastCR;
+ index = other->index;
+ forceQuirks = other->forceQuirks;
+ additional = other->additional;
+ entCol = other->entCol;
+ firstCharKey = other->firstCharKey;
+ lo = other->lo;
+ hi = other->hi;
+ candidate = other->candidate;
+ charRefBufMark = other->charRefBufMark;
+ value = other->value;
+ seenDigits = other->seenDigits;
+ endTag = other->endTag;
+ shouldSuspend = false;
+ if (!other->doctypeName) {
+ doctypeName = nullptr;
+ } else {
+ doctypeName = nsHtml5Portability::newLocalFromLocal(other->doctypeName, interner);
+ }
+ nsHtml5Portability::releaseString(systemIdentifier);
+ if (!other->systemIdentifier) {
+ systemIdentifier = nullptr;
+ } else {
+ systemIdentifier = nsHtml5Portability::newStringFromString(other->systemIdentifier);
+ }
+ nsHtml5Portability::releaseString(publicIdentifier);
+ if (!other->publicIdentifier) {
+ publicIdentifier = nullptr;
+ } else {
+ publicIdentifier = nsHtml5Portability::newStringFromString(other->publicIdentifier);
+ }
+ if (tagName) {
+ tagName->release();
+ }
+ if (!other->tagName) {
+ tagName = nullptr;
+ } else {
+ tagName = other->tagName->cloneElementName(interner);
+ }
+ if (attributeName) {
+ attributeName->release();
+ }
+ if (!other->attributeName) {
+ attributeName = nullptr;
+ } else {
+ attributeName = other->attributeName->cloneAttributeName(interner);
+ }
+ delete attributes;
+ if (!other->attributes) {
+ attributes = nullptr;
+ } else {
+ attributes = other->attributes->cloneAttributes(interner);
+ }
+}
+
+void
+nsHtml5Tokenizer::initializeWithoutStarting()
+{
+ confident = false;
+ strBuf = nullptr;
+ line = 1;
+ attributeLine = 1;
+ resetToDataState();
+}
+
+void
+nsHtml5Tokenizer::setEncodingDeclarationHandler(nsHtml5StreamParser* encodingDeclarationHandler)
+{
+ this->encodingDeclarationHandler = encodingDeclarationHandler;
+}
+
+
+nsHtml5Tokenizer::~nsHtml5Tokenizer()
+{
+ MOZ_COUNT_DTOR(nsHtml5Tokenizer);
+ delete attributes;
+ attributes = nullptr;
+}
+
+void
+nsHtml5Tokenizer::initializeStatics()
+{
+}
+
+void
+nsHtml5Tokenizer::releaseStatics()
+{
+}
+
+
+#include "nsHtml5TokenizerCppSupplement.h"
+
diff --git a/parser/html/nsHtml5Tokenizer.h b/parser/html/nsHtml5Tokenizer.h
new file mode 100644
index 000000000..da509b69b
--- /dev/null
+++ b/parser/html/nsHtml5Tokenizer.h
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2005-2007 Henri Sivonen
+ * Copyright (c) 2007-2015 Mozilla Foundation
+ * Portions of comments Copyright 2004-2010 Apple Computer, Inc., Mozilla
+ * Foundation, and Opera Software ASA.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit Tokenizer.java instead and regenerate.
+ */
+
+#ifndef nsHtml5Tokenizer_h
+#define nsHtml5Tokenizer_h
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5DocumentMode.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsHtml5NamedCharacters.h"
+#include "nsHtml5NamedCharactersAccel.h"
+#include "nsHtml5Atoms.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
+#include "nsHtml5Highlighter.h"
+#include "nsHtml5TokenizerLoopPolicies.h"
+
+class nsHtml5StreamParser;
+
+class nsHtml5TreeBuilder;
+class nsHtml5MetaScanner;
+class nsHtml5AttributeName;
+class nsHtml5ElementName;
+class nsHtml5HtmlAttributes;
+class nsHtml5UTF16Buffer;
+class nsHtml5StateSnapshot;
+class nsHtml5Portability;
+
+
+class nsHtml5Tokenizer
+{
+ private:
+ static char16_t LT_GT[];
+ static char16_t LT_SOLIDUS[];
+ static char16_t RSQB_RSQB[];
+ static char16_t REPLACEMENT_CHARACTER[];
+ static char16_t LF[];
+ static char16_t CDATA_LSQB[];
+ static char16_t OCTYPE[];
+ static char16_t UBLIC[];
+ static char16_t YSTEM[];
+ static staticJArray<char16_t,int32_t> TITLE_ARR;
+ static staticJArray<char16_t,int32_t> SCRIPT_ARR;
+ static staticJArray<char16_t,int32_t> STYLE_ARR;
+ static staticJArray<char16_t,int32_t> PLAINTEXT_ARR;
+ static staticJArray<char16_t,int32_t> XMP_ARR;
+ static staticJArray<char16_t,int32_t> TEXTAREA_ARR;
+ static staticJArray<char16_t,int32_t> IFRAME_ARR;
+ static staticJArray<char16_t,int32_t> NOEMBED_ARR;
+ static staticJArray<char16_t,int32_t> NOSCRIPT_ARR;
+ static staticJArray<char16_t,int32_t> NOFRAMES_ARR;
+ protected:
+ nsHtml5TreeBuilder* tokenHandler;
+ nsHtml5StreamParser* encodingDeclarationHandler;
+ bool lastCR;
+ int32_t stateSave;
+ private:
+ int32_t returnStateSave;
+ protected:
+ int32_t index;
+ private:
+ bool forceQuirks;
+ char16_t additional;
+ int32_t entCol;
+ int32_t firstCharKey;
+ int32_t lo;
+ int32_t hi;
+ int32_t candidate;
+ int32_t charRefBufMark;
+ protected:
+ int32_t value;
+ private:
+ bool seenDigits;
+ protected:
+ int32_t cstart;
+ private:
+ nsString* publicId;
+ nsString* systemId;
+ autoJArray<char16_t,int32_t> strBuf;
+ int32_t strBufLen;
+ autoJArray<char16_t,int32_t> charRefBuf;
+ int32_t charRefBufLen;
+ autoJArray<char16_t,int32_t> bmpChar;
+ autoJArray<char16_t,int32_t> astralChar;
+ protected:
+ nsHtml5ElementName* endTagExpectation;
+ private:
+ jArray<char16_t,int32_t> endTagExpectationAsArray;
+ protected:
+ bool endTag;
+ private:
+ nsHtml5ElementName* tagName;
+ protected:
+ nsHtml5AttributeName* attributeName;
+ private:
+ nsIAtom* doctypeName;
+ nsString* publicIdentifier;
+ nsString* systemIdentifier;
+ nsHtml5HtmlAttributes* attributes;
+ bool newAttributesEachTime;
+ bool shouldSuspend;
+ protected:
+ bool confident;
+ private:
+ int32_t line;
+ int32_t attributeLine;
+ nsHtml5AtomTable* interner;
+ bool viewingXmlSource;
+ public:
+ nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler, bool viewingXmlSource);
+ void setInterner(nsHtml5AtomTable* interner);
+ void initLocation(nsString* newPublicId, nsString* newSystemId);
+ bool isViewingXmlSource();
+ void setStateAndEndTagExpectation(int32_t specialTokenizerState, nsIAtom* endTagExpectation);
+ void setStateAndEndTagExpectation(int32_t specialTokenizerState, nsHtml5ElementName* endTagExpectation);
+ private:
+ void endTagExpectationToArray();
+ public:
+ void setLineNumber(int32_t line);
+ inline int32_t getLineNumber()
+ {
+ return line;
+ }
+
+ nsHtml5HtmlAttributes* emptyAttributes();
+ private:
+ inline void appendCharRefBuf(char16_t c)
+ {
+ MOZ_RELEASE_ASSERT(charRefBufLen < charRefBuf.length, "Attempted to overrun charRefBuf!");
+ charRefBuf[charRefBufLen++] = c;
+ }
+
+ void emitOrAppendCharRefBuf(int32_t returnState);
+ inline void clearStrBufAfterUse()
+ {
+ strBufLen = 0;
+ }
+
+ inline void clearStrBufBeforeUse()
+ {
+ MOZ_ASSERT(!strBufLen, "strBufLen not reset after previous use!");
+ strBufLen = 0;
+ }
+
+ inline void clearStrBufAfterOneHyphen()
+ {
+ MOZ_ASSERT(strBufLen == 1, "strBufLen length not one!");
+ MOZ_ASSERT(strBuf[0] == '-', "strBuf does not start with a hyphen!");
+ strBufLen = 0;
+ }
+
+ inline void appendStrBuf(char16_t c)
+ {
+ MOZ_ASSERT(strBufLen < strBuf.length, "Previous buffer length insufficient.");
+ if (MOZ_UNLIKELY(strBufLen == strBuf.length)) {
+ if (MOZ_UNLIKELY(!EnsureBufferSpace(1))) {
+ MOZ_CRASH("Unable to recover from buffer reallocation failure");
+ }
+ }
+ strBuf[strBufLen++] = c;
+ }
+
+ protected:
+ nsString* strBufToString();
+ private:
+ void strBufToDoctypeName();
+ void emitStrBuf();
+ inline void appendSecondHyphenToBogusComment()
+ {
+ appendStrBuf('-');
+ }
+
+ inline void adjustDoubleHyphenAndAppendToStrBufAndErr(char16_t c)
+ {
+ errConsecutiveHyphens();
+ appendStrBuf(c);
+ }
+
+ void appendStrBuf(char16_t* buffer, int32_t offset, int32_t length);
+ inline void appendCharRefBufToStrBuf()
+ {
+ appendStrBuf(charRefBuf, 0, charRefBufLen);
+ charRefBufLen = 0;
+ }
+
+ void emitComment(int32_t provisionalHyphens, int32_t pos);
+ protected:
+ void flushChars(char16_t* buf, int32_t pos);
+ private:
+ void strBufToElementNameString();
+ int32_t emitCurrentTagToken(bool selfClosing, int32_t pos);
+ void attributeNameComplete();
+ void addAttributeWithoutValue();
+ void addAttributeWithValue();
+ public:
+ void start();
+ bool tokenizeBuffer(nsHtml5UTF16Buffer* buffer);
+ private:
+ template<class P> int32_t stateLoop(int32_t state, char16_t c, int32_t pos, char16_t* buf, bool reconsume, int32_t returnState, int32_t endPos);
+ void initDoctypeFields();
+ inline void adjustDoubleHyphenAndAppendToStrBufCarriageReturn()
+ {
+ silentCarriageReturn();
+ adjustDoubleHyphenAndAppendToStrBufAndErr('\n');
+ }
+
+ inline void adjustDoubleHyphenAndAppendToStrBufLineFeed()
+ {
+ silentLineFeed();
+ adjustDoubleHyphenAndAppendToStrBufAndErr('\n');
+ }
+
+ inline void appendStrBufLineFeed()
+ {
+ silentLineFeed();
+ appendStrBuf('\n');
+ }
+
+ inline void appendStrBufCarriageReturn()
+ {
+ silentCarriageReturn();
+ appendStrBuf('\n');
+ }
+
+ protected:
+ inline void silentCarriageReturn()
+ {
+ ++line;
+ lastCR = true;
+ }
+
+ inline void silentLineFeed()
+ {
+ ++line;
+ }
+
+ private:
+ void emitCarriageReturn(char16_t* buf, int32_t pos);
+ void emitReplacementCharacter(char16_t* buf, int32_t pos);
+ void emitPlaintextReplacementCharacter(char16_t* buf, int32_t pos);
+ void setAdditionalAndRememberAmpersandLocation(char16_t add);
+ void bogusDoctype();
+ void bogusDoctypeWithoutQuirks();
+ void handleNcrValue(int32_t returnState);
+ public:
+ void eof();
+ private:
+ void emitDoctypeToken(int32_t pos);
+ protected:
+ inline char16_t checkChar(char16_t* buf, int32_t pos)
+ {
+ return buf[pos];
+ }
+
+ public:
+ bool internalEncodingDeclaration(nsString* internalCharset);
+ private:
+ void emitOrAppendTwo(const char16_t* val, int32_t returnState);
+ void emitOrAppendOne(const char16_t* val, int32_t returnState);
+ public:
+ void end();
+ void requestSuspension();
+ bool isInDataState();
+ void resetToDataState();
+ void loadState(nsHtml5Tokenizer* other);
+ void initializeWithoutStarting();
+ void setEncodingDeclarationHandler(nsHtml5StreamParser* encodingDeclarationHandler);
+ ~nsHtml5Tokenizer();
+ static void initializeStatics();
+ static void releaseStatics();
+
+#include "nsHtml5TokenizerHSupplement.h"
+};
+
+#define NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK ~1
+#define NS_HTML5TOKENIZER_DATA 0
+#define NS_HTML5TOKENIZER_RCDATA 1
+#define NS_HTML5TOKENIZER_SCRIPT_DATA 2
+#define NS_HTML5TOKENIZER_RAWTEXT 3
+#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED 4
+#define NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED 5
+#define NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED 6
+#define NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED 7
+#define NS_HTML5TOKENIZER_PLAINTEXT 8
+#define NS_HTML5TOKENIZER_TAG_OPEN 9
+#define NS_HTML5TOKENIZER_CLOSE_TAG_OPEN 10
+#define NS_HTML5TOKENIZER_TAG_NAME 11
+#define NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME 12
+#define NS_HTML5TOKENIZER_ATTRIBUTE_NAME 13
+#define NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME 14
+#define NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE 15
+#define NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED 16
+#define NS_HTML5TOKENIZER_BOGUS_COMMENT 17
+#define NS_HTML5TOKENIZER_MARKUP_DECLARATION_OPEN 18
+#define NS_HTML5TOKENIZER_DOCTYPE 19
+#define NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME 20
+#define NS_HTML5TOKENIZER_DOCTYPE_NAME 21
+#define NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME 22
+#define NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER 23
+#define NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED 24
+#define NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED 25
+#define NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER 26
+#define NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER 27
+#define NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED 28
+#define NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED 29
+#define NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER 30
+#define NS_HTML5TOKENIZER_BOGUS_DOCTYPE 31
+#define NS_HTML5TOKENIZER_COMMENT_START 32
+#define NS_HTML5TOKENIZER_COMMENT_START_DASH 33
+#define NS_HTML5TOKENIZER_COMMENT 34
+#define NS_HTML5TOKENIZER_COMMENT_END_DASH 35
+#define NS_HTML5TOKENIZER_COMMENT_END 36
+#define NS_HTML5TOKENIZER_COMMENT_END_BANG 37
+#define NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME 38
+#define NS_HTML5TOKENIZER_MARKUP_DECLARATION_HYPHEN 39
+#define NS_HTML5TOKENIZER_MARKUP_DECLARATION_OCTYPE 40
+#define NS_HTML5TOKENIZER_DOCTYPE_UBLIC 41
+#define NS_HTML5TOKENIZER_DOCTYPE_YSTEM 42
+#define NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD 43
+#define NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS 44
+#define NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD 45
+#define NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE 46
+#define NS_HTML5TOKENIZER_CONSUME_NCR 47
+#define NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL 48
+#define NS_HTML5TOKENIZER_HEX_NCR_LOOP 49
+#define NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP 50
+#define NS_HTML5TOKENIZER_HANDLE_NCR_VALUE 51
+#define NS_HTML5TOKENIZER_HANDLE_NCR_VALUE_RECONSUME 52
+#define NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP 53
+#define NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG 54
+#define NS_HTML5TOKENIZER_CDATA_START 55
+#define NS_HTML5TOKENIZER_CDATA_SECTION 56
+#define NS_HTML5TOKENIZER_CDATA_RSQB 57
+#define NS_HTML5TOKENIZER_CDATA_RSQB_RSQB 58
+#define NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN 59
+#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START 60
+#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START_DASH 61
+#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH 62
+#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH 63
+#define NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN 64
+#define NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN 65
+#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN 66
+#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_START 67
+#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED 68
+#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN 69
+#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH 70
+#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH 71
+#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_END 72
+#define NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION 73
+#define NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION_QUESTION_MARK 74
+#define NS_HTML5TOKENIZER_LEAD_OFFSET (0xD800 - (0x10000 >> 10))
+
+
+#endif
+
diff --git a/parser/html/nsHtml5TokenizerCppSupplement.h b/parser/html/nsHtml5TokenizerCppSupplement.h
new file mode 100644
index 000000000..b8a9bce0e
--- /dev/null
+++ b/parser/html/nsHtml5TokenizerCppSupplement.h
@@ -0,0 +1,585 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/Likely.h"
+
+// INT32_MAX is (2^31)-1. Therefore, the highest power-of-two that fits
+// is 2^30. Note that this is counting char16_t units. The underlying
+// bytes will be twice that, but they fit even in 32-bit size_t even
+// if a contiguous chunk of memory of that size is pretty unlikely to
+// be available on a 32-bit system.
+#define MAX_POWER_OF_TWO_IN_INT32 0x40000000
+
+bool
+nsHtml5Tokenizer::EnsureBufferSpace(int32_t aLength)
+{
+ MOZ_RELEASE_ASSERT(aLength >= 0, "Negative length.");
+ if (aLength > MAX_POWER_OF_TWO_IN_INT32) {
+ // Can't happen when loading from network.
+ return false;
+ }
+ CheckedInt<int32_t> worstCase(strBufLen);
+ worstCase += aLength;
+ worstCase += charRefBufLen;
+ // Add 2 to account for emissions of LT_GT, LT_SOLIDUS and RSQB_RSQB.
+ // Adding to the general worst case instead of only the
+ // TreeBuilder-exposed worst case to avoid re-introducing a bug when
+ // unifying the tokenizer and tree builder buffers in the future.
+ worstCase += 2;
+ if (!worstCase.isValid()) {
+ return false;
+ }
+ if (worstCase.value() > MAX_POWER_OF_TWO_IN_INT32) {
+ return false;
+ }
+ // TODO: Unify nsHtml5Tokenizer::strBuf and nsHtml5TreeBuilder::charBuffer
+ // so that the call below becomes unnecessary.
+ if (!tokenHandler->EnsureBufferSpace(worstCase.value())) {
+ return false;
+ }
+ if (!strBuf) {
+ if (worstCase.value() < MAX_POWER_OF_TWO_IN_INT32) {
+ // Add one to round to the next power of two to avoid immediate
+ // reallocation once there are a few characters in the buffer.
+ worstCase += 1;
+ }
+ strBuf = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
+ if (!strBuf) {
+ return false;
+ }
+ } else if (worstCase.value() > strBuf.length) {
+ jArray<char16_t,int32_t> newBuf = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
+ if (!newBuf) {
+ return false;
+ }
+ memcpy(newBuf, strBuf, sizeof(char16_t) * size_t(strBufLen));
+ strBuf = newBuf;
+ }
+ return true;
+}
+
+void
+nsHtml5Tokenizer::StartPlainText()
+{
+ stateSave = NS_HTML5TOKENIZER_PLAINTEXT;
+}
+
+void
+nsHtml5Tokenizer::EnableViewSource(nsHtml5Highlighter* aHighlighter)
+{
+ mViewSource = aHighlighter;
+}
+
+bool
+nsHtml5Tokenizer::FlushViewSource()
+{
+ return mViewSource->FlushOps();
+}
+
+void
+nsHtml5Tokenizer::StartViewSource(const nsAutoString& aTitle)
+{
+ mViewSource->Start(aTitle);
+}
+
+void
+nsHtml5Tokenizer::EndViewSource()
+{
+ mViewSource->End();
+}
+
+void
+nsHtml5Tokenizer::errWarnLtSlashInRcdata()
+{
+}
+
+// The null checks below annotated MOZ_LIKELY are not actually necessary.
+
+void
+nsHtml5Tokenizer::errUnquotedAttributeValOrNull(char16_t c)
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ switch (c) {
+ case '<':
+ mViewSource->AddErrorToCurrentNode("errUnquotedAttributeLt");
+ return;
+ case '`':
+ mViewSource->AddErrorToCurrentNode("errUnquotedAttributeGrave");
+ return;
+ case '\'':
+ case '"':
+ mViewSource->AddErrorToCurrentNode("errUnquotedAttributeQuote");
+ return;
+ case '=':
+ mViewSource->AddErrorToCurrentNode("errUnquotedAttributeEquals");
+ return;
+ }
+ }
+}
+
+void
+nsHtml5Tokenizer::errLtOrEqualsOrGraveInUnquotedAttributeOrNull(char16_t c)
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ switch (c) {
+ case '=':
+ mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartEquals");
+ return;
+ case '<':
+ mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartLt");
+ return;
+ case '`':
+ mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartGrave");
+ return;
+ }
+ }
+}
+
+void
+nsHtml5Tokenizer::errBadCharBeforeAttributeNameOrNull(char16_t c)
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ if (c == '<') {
+ mViewSource->AddErrorToCurrentNode("errBadCharBeforeAttributeNameLt");
+ } else if (c == '=') {
+ errEqualsSignBeforeAttributeName();
+ } else if (c != 0xFFFD) {
+ errQuoteBeforeAttributeName(c);
+ }
+ }
+}
+
+void
+nsHtml5Tokenizer::errBadCharAfterLt(char16_t c)
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errBadCharAfterLt");
+ }
+}
+
+void
+nsHtml5Tokenizer::errQuoteOrLtInAttributeNameOrNull(char16_t c)
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ if (c == '<') {
+ mViewSource->AddErrorToCurrentNode("errLtInAttributeName");
+ } else if (c != 0xFFFD) {
+ mViewSource->AddErrorToCurrentNode("errQuoteInAttributeName");
+ }
+ }
+}
+
+void
+nsHtml5Tokenizer::maybeErrAttributesOnEndTag(nsHtml5HtmlAttributes* attrs)
+{
+ if (mViewSource && attrs->getLength() != 0) {
+ /*
+ * When an end tag token is emitted with attributes, that is a parse
+ * error.
+ */
+ mViewSource->AddErrorToCurrentRun("maybeErrAttributesOnEndTag");
+ }
+}
+
+void
+nsHtml5Tokenizer::maybeErrSlashInEndTag(bool selfClosing)
+{
+ if (mViewSource && selfClosing && endTag) {
+ mViewSource->AddErrorToCurrentSlash("maybeErrSlashInEndTag");
+ }
+}
+
+char16_t
+nsHtml5Tokenizer::errNcrNonCharacter(char16_t ch)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNcrNonCharacter");
+ }
+ return ch;
+}
+
+void
+nsHtml5Tokenizer::errAstralNonCharacter(int32_t ch)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNcrNonCharacter");
+ }
+}
+
+char16_t
+nsHtml5Tokenizer::errNcrControlChar(char16_t ch)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNcrControlChar");
+ }
+ return ch;
+}
+
+void
+nsHtml5Tokenizer::errGarbageAfterLtSlash()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errGarbageAfterLtSlash");
+ }
+}
+
+void
+nsHtml5Tokenizer::errLtSlashGt()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errLtSlashGt");
+ }
+}
+
+void
+nsHtml5Tokenizer::errCharRefLacksSemicolon()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errCharRefLacksSemicolon");
+ }
+}
+
+void
+nsHtml5Tokenizer::errNoDigitsInNCR()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNoDigitsInNCR");
+ }
+}
+
+void
+nsHtml5Tokenizer::errGtInSystemId()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errGtInSystemId");
+ }
+}
+
+void
+nsHtml5Tokenizer::errGtInPublicId()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errGtInPublicId");
+ }
+}
+
+void
+nsHtml5Tokenizer::errNamelessDoctype()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNamelessDoctype");
+ }
+}
+
+void
+nsHtml5Tokenizer::errConsecutiveHyphens()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errConsecutiveHyphens");
+ }
+}
+
+void
+nsHtml5Tokenizer::errPrematureEndOfComment()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errPrematureEndOfComment");
+ }
+}
+
+void
+nsHtml5Tokenizer::errBogusComment()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errBogusComment");
+ }
+}
+
+void
+nsHtml5Tokenizer::errSlashNotFollowedByGt()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentSlash("errSlashNotFollowedByGt");
+ }
+}
+
+void
+nsHtml5Tokenizer::errNoSpaceBetweenAttributes()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenAttributes");
+ }
+}
+
+void
+nsHtml5Tokenizer::errAttributeValueMissing()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errAttributeValueMissing");
+ }
+}
+
+void
+nsHtml5Tokenizer::errEqualsSignBeforeAttributeName()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errEqualsSignBeforeAttributeName");
+ }
+}
+
+void
+nsHtml5Tokenizer::errLtGt()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errLtGt");
+ }
+}
+
+void
+nsHtml5Tokenizer::errProcessingInstruction()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errProcessingInstruction");
+ }
+}
+
+void
+nsHtml5Tokenizer::errUnescapedAmpersandInterpretedAsCharacterReference()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentAmpersand("errUnescapedAmpersandInterpretedAsCharacterReference");
+ }
+}
+
+void
+nsHtml5Tokenizer::errNotSemicolonTerminated()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNotSemicolonTerminated");
+ }
+}
+
+void
+nsHtml5Tokenizer::errNoNamedCharacterMatch()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentAmpersand("errNoNamedCharacterMatch");
+ }
+}
+
+void
+nsHtml5Tokenizer::errQuoteBeforeAttributeName(char16_t c)
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errQuoteBeforeAttributeName");
+ }
+}
+
+void
+nsHtml5Tokenizer::errExpectedPublicId()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errExpectedPublicId");
+ }
+}
+
+void
+nsHtml5Tokenizer::errBogusDoctype()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errBogusDoctype");
+ }
+}
+
+void
+nsHtml5Tokenizer::errNcrSurrogate()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNcrSurrogate");
+ }
+}
+
+void
+nsHtml5Tokenizer::errNcrCr()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNcrCr");
+ }
+}
+
+void
+nsHtml5Tokenizer::errNcrInC1Range()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNcrInC1Range");
+ }
+}
+
+void
+nsHtml5Tokenizer::errEofInPublicId()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errEofInPublicId");
+ }
+}
+
+void
+nsHtml5Tokenizer::errEofInComment()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errEofInComment");
+ }
+}
+
+void
+nsHtml5Tokenizer::errEofInDoctype()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errEofInDoctype");
+ }
+}
+
+void
+nsHtml5Tokenizer::errEofInAttributeValue()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errEofInAttributeValue");
+ }
+}
+
+void
+nsHtml5Tokenizer::errEofInAttributeName()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errEofInAttributeName");
+ }
+}
+
+void
+nsHtml5Tokenizer::errEofWithoutGt()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errEofWithoutGt");
+ }
+}
+
+void
+nsHtml5Tokenizer::errEofInTagName()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errEofInTagName");
+ }
+}
+
+void
+nsHtml5Tokenizer::errEofInEndTag()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errEofInEndTag");
+ }
+}
+
+void
+nsHtml5Tokenizer::errEofAfterLt()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errEofAfterLt");
+ }
+}
+
+void
+nsHtml5Tokenizer::errNcrOutOfRange()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNcrOutOfRange");
+ }
+}
+
+void
+nsHtml5Tokenizer::errNcrUnassigned()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNcrUnassigned");
+ }
+}
+
+void
+nsHtml5Tokenizer::errDuplicateAttribute()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errDuplicateAttribute");
+ }
+}
+
+void
+nsHtml5Tokenizer::errEofInSystemId()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errEofInSystemId");
+ }
+}
+
+void
+nsHtml5Tokenizer::errExpectedSystemId()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errExpectedSystemId");
+ }
+}
+
+void
+nsHtml5Tokenizer::errMissingSpaceBeforeDoctypeName()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errMissingSpaceBeforeDoctypeName");
+ }
+}
+
+void
+nsHtml5Tokenizer::errHyphenHyphenBang()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errHyphenHyphenBang");
+ }
+}
+
+void
+nsHtml5Tokenizer::errNcrControlChar()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNcrControlChar");
+ }
+}
+
+void
+nsHtml5Tokenizer::errNcrZero()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNcrZero");
+ }
+}
+
+void
+nsHtml5Tokenizer::errNoSpaceBetweenDoctypeSystemKeywordAndQuote()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypeSystemKeywordAndQuote");
+ }
+}
+
+void
+nsHtml5Tokenizer::errNoSpaceBetweenPublicAndSystemIds()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenPublicAndSystemIds");
+ }
+}
+
+void
+nsHtml5Tokenizer::errNoSpaceBetweenDoctypePublicKeywordAndQuote()
+{
+ if (MOZ_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypePublicKeywordAndQuote");
+ }
+}
diff --git a/parser/html/nsHtml5TokenizerHSupplement.h b/parser/html/nsHtml5TokenizerHSupplement.h
new file mode 100644
index 000000000..a899feec9
--- /dev/null
+++ b/parser/html/nsHtml5TokenizerHSupplement.h
@@ -0,0 +1,148 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+inline nsHtml5HtmlAttributes* GetAttributes()
+{
+ return attributes;
+}
+
+/**
+ * Makes sure the buffers are large enough to be able to tokenize aLength
+ * UTF-16 code units before having to make the buffers larger.
+ *
+ * @param aLength the number of UTF-16 code units to be tokenized before the
+ * next call to this method.
+ * @return true if successful; false if out of memory
+ */
+bool EnsureBufferSpace(int32_t aLength);
+
+nsAutoPtr<nsHtml5Highlighter> mViewSource;
+
+/**
+ * Starts handling text/plain. This is a one-way initialization. There is
+ * no corresponding EndPlainText() call.
+ */
+void StartPlainText();
+
+void EnableViewSource(nsHtml5Highlighter* aHighlighter);
+
+bool FlushViewSource();
+
+void StartViewSource(const nsAutoString& aTitle);
+
+void EndViewSource();
+
+void errGarbageAfterLtSlash();
+
+void errLtSlashGt();
+
+void errWarnLtSlashInRcdata();
+
+void errCharRefLacksSemicolon();
+
+void errNoDigitsInNCR();
+
+void errGtInSystemId();
+
+void errGtInPublicId();
+
+void errNamelessDoctype();
+
+void errConsecutiveHyphens();
+
+void errPrematureEndOfComment();
+
+void errBogusComment();
+
+void errUnquotedAttributeValOrNull(char16_t c);
+
+void errSlashNotFollowedByGt();
+
+void errNoSpaceBetweenAttributes();
+
+void errLtOrEqualsOrGraveInUnquotedAttributeOrNull(char16_t c);
+
+void errAttributeValueMissing();
+
+void errBadCharBeforeAttributeNameOrNull(char16_t c);
+
+void errEqualsSignBeforeAttributeName();
+
+void errBadCharAfterLt(char16_t c);
+
+void errLtGt();
+
+void errProcessingInstruction();
+
+void errUnescapedAmpersandInterpretedAsCharacterReference();
+
+void errNotSemicolonTerminated();
+
+void errNoNamedCharacterMatch();
+
+void errQuoteBeforeAttributeName(char16_t c);
+
+void errQuoteOrLtInAttributeNameOrNull(char16_t c);
+
+void errExpectedPublicId();
+
+void errBogusDoctype();
+
+void maybeErrAttributesOnEndTag(nsHtml5HtmlAttributes* attrs);
+
+void maybeErrSlashInEndTag(bool selfClosing);
+
+char16_t errNcrNonCharacter(char16_t ch);
+
+void errAstralNonCharacter(int32_t ch);
+
+void errNcrSurrogate();
+
+char16_t errNcrControlChar(char16_t ch);
+
+void errNcrCr();
+
+void errNcrInC1Range();
+
+void errEofInPublicId();
+
+void errEofInComment();
+
+void errEofInDoctype();
+
+void errEofInAttributeValue();
+
+void errEofInAttributeName();
+
+void errEofWithoutGt();
+
+void errEofInTagName();
+
+void errEofInEndTag();
+
+void errEofAfterLt();
+
+void errNcrOutOfRange();
+
+void errNcrUnassigned();
+
+void errDuplicateAttribute();
+
+void errEofInSystemId();
+
+void errExpectedSystemId();
+
+void errMissingSpaceBeforeDoctypeName();
+
+void errHyphenHyphenBang();
+
+void errNcrControlChar();
+
+void errNcrZero();
+
+void errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
+
+void errNoSpaceBetweenPublicAndSystemIds();
+
+void errNoSpaceBetweenDoctypePublicKeywordAndQuote();
diff --git a/parser/html/nsHtml5TokenizerLoopPolicies.h b/parser/html/nsHtml5TokenizerLoopPolicies.h
new file mode 100644
index 000000000..8e5869a62
--- /dev/null
+++ b/parser/html/nsHtml5TokenizerLoopPolicies.h
@@ -0,0 +1,47 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5TokenizerLoopPolicies_h
+#define nsHtml5TokenizerLoopPolicies_h
+
+/**
+ * This policy does not report tokenizer transitions anywhere. To be used
+ * when _not_ viewing source.
+ */
+struct nsHtml5SilentPolicy
+{
+ static const bool reportErrors = false;
+ static int32_t transition(nsHtml5Highlighter* aHighlighter,
+ int32_t aState,
+ bool aReconsume,
+ int32_t aPos)
+ {
+ return aState;
+ }
+ static void completedNamedCharacterReference(nsHtml5Highlighter* aHighlighter)
+ {
+ }
+};
+
+/**
+ * This policy reports the tokenizer transitions to a highlighter. To be used
+ * when viewing source.
+ */
+struct nsHtml5ViewSourcePolicy
+{
+ static const bool reportErrors = true;
+ static int32_t transition(nsHtml5Highlighter* aHighlighter,
+ int32_t aState,
+ bool aReconsume,
+ int32_t aPos)
+ {
+ return aHighlighter->Transition(aState, aReconsume, aPos);
+ }
+ static void completedNamedCharacterReference(nsHtml5Highlighter* aHighlighter)
+ {
+ aHighlighter->CompletedNamedCharacterReference();
+ }
+};
+
+#endif // nsHtml5TokenizerLoopPolicies_h
diff --git a/parser/html/nsHtml5TreeBuilder.cpp b/parser/html/nsHtml5TreeBuilder.cpp
new file mode 100644
index 000000000..f694116ba
--- /dev/null
+++ b/parser/html/nsHtml5TreeBuilder.cpp
@@ -0,0 +1,4520 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 2007-2015 Mozilla Foundation
+ * Portions of comments Copyright 2004-2008 Apple Computer, Inc., Mozilla
+ * Foundation, and Opera Software ASA.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit TreeBuilder.java instead and regenerate.
+ */
+
+#define nsHtml5TreeBuilder_cpp__
+
+#include "nsContentUtils.h"
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsITimer.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5DocumentMode.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsHtml5Parser.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5TreeOperation.h"
+#include "nsHtml5StateSnapshot.h"
+#include "nsHtml5StackNode.h"
+#include "nsHtml5TreeOpExecutor.h"
+#include "nsHtml5StreamParser.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Highlighter.h"
+#include "nsHtml5PlainTextUtils.h"
+#include "nsHtml5ViewSourceUtils.h"
+#include "mozilla/Likely.h"
+#include "nsIContentHandle.h"
+#include "nsHtml5OplessBuilder.h"
+
+#include "nsHtml5Tokenizer.h"
+#include "nsHtml5MetaScanner.h"
+#include "nsHtml5AttributeName.h"
+#include "nsHtml5ElementName.h"
+#include "nsHtml5HtmlAttributes.h"
+#include "nsHtml5StackNode.h"
+#include "nsHtml5UTF16Buffer.h"
+#include "nsHtml5StateSnapshot.h"
+#include "nsHtml5Portability.h"
+
+#include "nsHtml5TreeBuilder.h"
+
+char16_t nsHtml5TreeBuilder::REPLACEMENT_CHARACTER[] = { 0xfffd };
+static const char* const QUIRKY_PUBLIC_IDS_DATA[] = { "+//silmaril//dtd html pro v0r11 19970101//", "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", "-//as//dtd html 3.0 aswedit + extensions//", "-//ietf//dtd html 2.0 level 1//", "-//ietf//dtd html 2.0 level 2//", "-//ietf//dtd html 2.0 strict level 1//", "-//ietf//dtd html 2.0 strict level 2//", "-//ietf//dtd html 2.0 strict//", "-//ietf//dtd html 2.0//", "-//ietf//dtd html 2.1e//", "-//ietf//dtd html 3.0//", "-//ietf//dtd html 3.2 final//", "-//ietf//dtd html 3.2//", "-//ietf//dtd html 3//", "-//ietf//dtd html level 0//", "-//ietf//dtd html level 1//", "-//ietf//dtd html level 2//", "-//ietf//dtd html level 3//", "-//ietf//dtd html strict level 0//", "-//ietf//dtd html strict level 1//", "-//ietf//dtd html strict level 2//", "-//ietf//dtd html strict level 3//", "-//ietf//dtd html strict//", "-//ietf//dtd html//", "-//metrius//dtd metrius presentational//", "-//microsoft//dtd internet explorer 2.0 html strict//", "-//microsoft//dtd internet explorer 2.0 html//", "-//microsoft//dtd internet explorer 2.0 tables//", "-//microsoft//dtd internet explorer 3.0 html strict//", "-//microsoft//dtd internet explorer 3.0 html//", "-//microsoft//dtd internet explorer 3.0 tables//", "-//netscape comm. corp.//dtd html//", "-//netscape comm. corp.//dtd strict html//", "-//o'reilly and associates//dtd html 2.0//", "-//o'reilly and associates//dtd html extended 1.0//", "-//o'reilly and associates//dtd html extended relaxed 1.0//", "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", "-//spyglass//dtd html 2.0 extended//", "-//sq//dtd html 2.0 hotmetal + extensions//", "-//sun microsystems corp.//dtd hotjava html//", "-//sun microsystems corp.//dtd hotjava strict html//", "-//w3c//dtd html 3 1995-03-24//", "-//w3c//dtd html 3.2 draft//", "-//w3c//dtd html 3.2 final//", "-//w3c//dtd html 3.2//", "-//w3c//dtd html 3.2s draft//", "-//w3c//dtd html 4.0 frameset//", "-//w3c//dtd html 4.0 transitional//", "-//w3c//dtd html experimental 19960712//", "-//w3c//dtd html experimental 970421//", "-//w3c//dtd w3 html//", "-//w3o//dtd w3 html 3.0//", "-//webtechs//dtd mozilla html 2.0//", "-//webtechs//dtd mozilla html//" };
+staticJArray<const char*,int32_t> nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS = { QUIRKY_PUBLIC_IDS_DATA, MOZ_ARRAY_LENGTH(QUIRKY_PUBLIC_IDS_DATA) };
+void
+nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer* self)
+{
+ tokenizer = self;
+ stack = jArray<nsHtml5StackNode*,int32_t>::newJArray(64);
+ templateModeStack = jArray<int32_t,int32_t>::newJArray(64);
+ listOfActiveFormattingElements = jArray<nsHtml5StackNode*,int32_t>::newJArray(64);
+ needToDropLF = false;
+ originalMode = NS_HTML5TREE_BUILDER_INITIAL;
+ templateModePtr = -1;
+ currentPtr = -1;
+ listPtr = -1;
+ formPointer = nullptr;
+ headPointer = nullptr;
+ deepTreeSurrogateParent = nullptr;
+ start(fragment);
+ charBufferLen = 0;
+ charBuffer = nullptr;
+ framesetOk = true;
+ if (fragment) {
+ nsIContentHandle* elt;
+ if (contextNode) {
+ elt = contextNode;
+ } else {
+ elt = createHtmlElementSetAsRoot(tokenizer->emptyAttributes());
+ }
+ if (contextNamespace == kNameSpaceID_SVG) {
+ nsHtml5ElementName* elementName = nsHtml5ElementName::ELT_SVG;
+ if (nsHtml5Atoms::title == contextName || nsHtml5Atoms::desc == contextName || nsHtml5Atoms::foreignObject == contextName) {
+ elementName = nsHtml5ElementName::ELT_FOREIGNOBJECT;
+ }
+ nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elementName->camelCaseName, elt);
+ currentPtr++;
+ stack[currentPtr] = node;
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_DATA, contextName);
+ mode = NS_HTML5TREE_BUILDER_FRAMESET_OK;
+ } else if (contextNamespace == kNameSpaceID_MathML) {
+ nsHtml5ElementName* elementName = nsHtml5ElementName::ELT_MATH;
+ if (nsHtml5Atoms::mi == contextName || nsHtml5Atoms::mo == contextName || nsHtml5Atoms::mn == contextName || nsHtml5Atoms::ms == contextName || nsHtml5Atoms::mtext == contextName) {
+ elementName = nsHtml5ElementName::ELT_MTEXT;
+ } else if (nsHtml5Atoms::annotation_xml == contextName) {
+ elementName = nsHtml5ElementName::ELT_ANNOTATION_XML;
+ }
+ nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, elementName->name, false);
+ currentPtr++;
+ stack[currentPtr] = node;
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_DATA, contextName);
+ mode = NS_HTML5TREE_BUILDER_FRAMESET_OK;
+ } else {
+ nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_HTML, elt);
+ currentPtr++;
+ stack[currentPtr] = node;
+ if (nsHtml5Atoms::template_ == contextName) {
+ pushTemplateMode(NS_HTML5TREE_BUILDER_IN_TEMPLATE);
+ }
+ resetTheInsertionMode();
+ formPointer = getFormPointerForContext(contextNode);
+ if (nsHtml5Atoms::title == contextName || nsHtml5Atoms::textarea == contextName) {
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RCDATA, contextName);
+ } else if (nsHtml5Atoms::style == contextName || nsHtml5Atoms::xmp == contextName || nsHtml5Atoms::iframe == contextName || nsHtml5Atoms::noembed == contextName || nsHtml5Atoms::noframes == contextName || (scriptingEnabled && nsHtml5Atoms::noscript == contextName)) {
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, contextName);
+ } else if (nsHtml5Atoms::plaintext == contextName) {
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_PLAINTEXT, contextName);
+ } else if (nsHtml5Atoms::script == contextName) {
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_SCRIPT_DATA, contextName);
+ } else {
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_DATA, contextName);
+ }
+ }
+ contextName = nullptr;
+ contextNode = nullptr;
+ } else {
+ mode = NS_HTML5TREE_BUILDER_INITIAL;
+ if (tokenizer->isViewingXmlSource()) {
+ nsIContentHandle* elt = createElement(kNameSpaceID_SVG, nsHtml5Atoms::svg, tokenizer->emptyAttributes(), nullptr);
+ nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_SVG, nsHtml5Atoms::svg, elt);
+ currentPtr++;
+ stack[currentPtr] = node;
+ }
+ }
+}
+
+void
+nsHtml5TreeBuilder::doctype(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks)
+{
+ needToDropLF = false;
+ if (!isInForeign() && mode == NS_HTML5TREE_BUILDER_INITIAL) {
+ nsString* emptyString = nsHtml5Portability::newEmptyString();
+ appendDoctypeToDocument(!name ? nsHtml5Atoms::emptystring : name, !publicIdentifier ? emptyString : publicIdentifier, !systemIdentifier ? emptyString : systemIdentifier);
+ nsHtml5Portability::releaseString(emptyString);
+ if (isQuirky(name, publicIdentifier, systemIdentifier, forceQuirks)) {
+ errQuirkyDoctype();
+ documentModeInternal(QUIRKS_MODE, publicIdentifier, systemIdentifier, false);
+ } else if (isAlmostStandards(publicIdentifier, systemIdentifier)) {
+ errAlmostStandardsDoctype();
+ documentModeInternal(ALMOST_STANDARDS_MODE, publicIdentifier, systemIdentifier, false);
+ } else {
+ documentModeInternal(STANDARDS_MODE, publicIdentifier, systemIdentifier, false);
+ }
+ mode = NS_HTML5TREE_BUILDER_BEFORE_HTML;
+ return;
+ }
+ errStrayDoctype();
+ return;
+}
+
+void
+nsHtml5TreeBuilder::comment(char16_t* buf, int32_t start, int32_t length)
+{
+ needToDropLF = false;
+ if (!isInForeign()) {
+ switch(mode) {
+ case NS_HTML5TREE_BUILDER_INITIAL:
+ case NS_HTML5TREE_BUILDER_BEFORE_HTML:
+ case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY:
+ case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: {
+ appendCommentToDocument(buf, start, length);
+ return;
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_BODY: {
+ flushCharacters();
+ appendComment(stack[0]->node, buf, start, length);
+ return;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ flushCharacters();
+ appendComment(stack[currentPtr]->node, buf, start, length);
+ return;
+}
+
+void
+nsHtml5TreeBuilder::characters(const char16_t* buf, int32_t start, int32_t length)
+{
+ if (tokenizer->isViewingXmlSource()) {
+ return;
+ }
+ if (needToDropLF) {
+ needToDropLF = false;
+ if (buf[start] == '\n') {
+ start++;
+ length--;
+ if (!length) {
+ return;
+ }
+ }
+ }
+ switch(mode) {
+ case NS_HTML5TREE_BUILDER_IN_BODY:
+ case NS_HTML5TREE_BUILDER_IN_CELL:
+ case NS_HTML5TREE_BUILDER_IN_CAPTION: {
+ if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
+ reconstructTheActiveFormattingElements();
+ }
+ }
+ case NS_HTML5TREE_BUILDER_TEXT: {
+ accumulateCharacters(buf, start, length);
+ return;
+ }
+ case NS_HTML5TREE_BUILDER_IN_TABLE:
+ case NS_HTML5TREE_BUILDER_IN_TABLE_BODY:
+ case NS_HTML5TREE_BUILDER_IN_ROW: {
+ accumulateCharactersForced(buf, start, length);
+ return;
+ }
+ default: {
+ int32_t end = start + length;
+ for (int32_t i = start; i < end; i++) {
+ switch(buf[i]) {
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ case '\f': {
+ switch(mode) {
+ case NS_HTML5TREE_BUILDER_INITIAL:
+ case NS_HTML5TREE_BUILDER_BEFORE_HTML:
+ case NS_HTML5TREE_BUILDER_BEFORE_HEAD: {
+ start = i + 1;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_IN_HEAD:
+ case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT:
+ case NS_HTML5TREE_BUILDER_AFTER_HEAD:
+ case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP:
+ case NS_HTML5TREE_BUILDER_IN_FRAMESET:
+ case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: {
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_FRAMESET_OK:
+ case NS_HTML5TREE_BUILDER_IN_TEMPLATE:
+ case NS_HTML5TREE_BUILDER_IN_BODY:
+ case NS_HTML5TREE_BUILDER_IN_CELL:
+ case NS_HTML5TREE_BUILDER_IN_CAPTION: {
+ if (start < i) {
+ accumulateCharacters(buf, start, i - start);
+ start = i;
+ }
+ if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
+ flushCharacters();
+ reconstructTheActiveFormattingElements();
+ }
+ NS_HTML5_BREAK(charactersloop);
+ }
+ case NS_HTML5TREE_BUILDER_IN_SELECT:
+ case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: {
+ NS_HTML5_BREAK(charactersloop);
+ }
+ case NS_HTML5TREE_BUILDER_IN_TABLE:
+ case NS_HTML5TREE_BUILDER_IN_TABLE_BODY:
+ case NS_HTML5TREE_BUILDER_IN_ROW: {
+ accumulateCharactersForced(buf, i, 1);
+ start = i + 1;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_BODY:
+ case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY:
+ case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: {
+ if (start < i) {
+ accumulateCharacters(buf, start, i - start);
+ start = i;
+ }
+ flushCharacters();
+ reconstructTheActiveFormattingElements();
+ continue;
+ }
+ }
+ }
+ default: {
+ switch(mode) {
+ case NS_HTML5TREE_BUILDER_INITIAL: {
+ documentModeInternal(QUIRKS_MODE, nullptr, nullptr, false);
+ mode = NS_HTML5TREE_BUILDER_BEFORE_HTML;
+ i--;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_BEFORE_HTML: {
+ appendHtmlElementToDocumentAndPush();
+ mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD;
+ i--;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_BEFORE_HEAD: {
+ if (start < i) {
+ accumulateCharacters(buf, start, i - start);
+ start = i;
+ }
+ flushCharacters();
+ appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+ mode = NS_HTML5TREE_BUILDER_IN_HEAD;
+ i--;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_IN_HEAD: {
+ if (start < i) {
+ accumulateCharacters(buf, start, i - start);
+ start = i;
+ }
+ flushCharacters();
+ pop();
+ mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
+ i--;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: {
+ if (start < i) {
+ accumulateCharacters(buf, start, i - start);
+ start = i;
+ }
+ errNonSpaceInNoscriptInHead();
+ flushCharacters();
+ pop();
+ mode = NS_HTML5TREE_BUILDER_IN_HEAD;
+ i--;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_HEAD: {
+ if (start < i) {
+ accumulateCharacters(buf, start, i - start);
+ start = i;
+ }
+ flushCharacters();
+ appendToCurrentNodeAndPushBodyElement();
+ mode = NS_HTML5TREE_BUILDER_FRAMESET_OK;
+ i--;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_FRAMESET_OK: {
+ framesetOk = false;
+ mode = NS_HTML5TREE_BUILDER_IN_BODY;
+ i--;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_IN_TEMPLATE:
+ case NS_HTML5TREE_BUILDER_IN_BODY:
+ case NS_HTML5TREE_BUILDER_IN_CELL:
+ case NS_HTML5TREE_BUILDER_IN_CAPTION: {
+ if (start < i) {
+ accumulateCharacters(buf, start, i - start);
+ start = i;
+ }
+ if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
+ flushCharacters();
+ reconstructTheActiveFormattingElements();
+ }
+ NS_HTML5_BREAK(charactersloop);
+ }
+ case NS_HTML5TREE_BUILDER_IN_TABLE:
+ case NS_HTML5TREE_BUILDER_IN_TABLE_BODY:
+ case NS_HTML5TREE_BUILDER_IN_ROW: {
+ accumulateCharactersForced(buf, i, 1);
+ start = i + 1;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: {
+ if (start < i) {
+ accumulateCharacters(buf, start, i - start);
+ start = i;
+ }
+ if (!currentPtr || stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) {
+ errNonSpaceInColgroupInFragment();
+ start = i + 1;
+ continue;
+ }
+ flushCharacters();
+ pop();
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+ i--;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_IN_SELECT:
+ case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: {
+ NS_HTML5_BREAK(charactersloop);
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_BODY: {
+ errNonSpaceAfterBody();
+
+ mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
+ i--;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_IN_FRAMESET: {
+ if (start < i) {
+ accumulateCharacters(buf, start, i - start);
+ }
+ errNonSpaceInFrameset();
+ start = i + 1;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: {
+ if (start < i) {
+ accumulateCharacters(buf, start, i - start);
+ }
+ errNonSpaceAfterFrameset();
+ start = i + 1;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY: {
+ errNonSpaceInTrailer();
+ mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
+ i--;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: {
+ if (start < i) {
+ accumulateCharacters(buf, start, i - start);
+ }
+ errNonSpaceInTrailer();
+ start = i + 1;
+ continue;
+ }
+ }
+ }
+ }
+ }
+ charactersloop_end: ;
+ if (start < end) {
+ accumulateCharacters(buf, start, end - start);
+ }
+ }
+ }
+}
+
+void
+nsHtml5TreeBuilder::zeroOriginatingReplacementCharacter()
+{
+ if (mode == NS_HTML5TREE_BUILDER_TEXT) {
+ accumulateCharacters(REPLACEMENT_CHARACTER, 0, 1);
+ return;
+ }
+ if (currentPtr >= 0) {
+ if (isSpecialParentInForeign(stack[currentPtr])) {
+ return;
+ }
+ accumulateCharacters(REPLACEMENT_CHARACTER, 0, 1);
+ }
+}
+
+void
+nsHtml5TreeBuilder::eof()
+{
+ flushCharacters();
+ for (; ; ) {
+ switch(mode) {
+ case NS_HTML5TREE_BUILDER_INITIAL: {
+ documentModeInternal(QUIRKS_MODE, nullptr, nullptr, false);
+ mode = NS_HTML5TREE_BUILDER_BEFORE_HTML;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_BEFORE_HTML: {
+ appendHtmlElementToDocumentAndPush();
+ mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_BEFORE_HEAD: {
+ appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+ mode = NS_HTML5TREE_BUILDER_IN_HEAD;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_IN_HEAD: {
+ while (currentPtr > 0) {
+ popOnEof();
+ }
+ mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: {
+ while (currentPtr > 1) {
+ popOnEof();
+ }
+ mode = NS_HTML5TREE_BUILDER_IN_HEAD;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_HEAD: {
+ appendToCurrentNodeAndPushBodyElement();
+ mode = NS_HTML5TREE_BUILDER_IN_BODY;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_IN_TABLE_BODY:
+ case NS_HTML5TREE_BUILDER_IN_ROW:
+ case NS_HTML5TREE_BUILDER_IN_TABLE:
+ case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE:
+ case NS_HTML5TREE_BUILDER_IN_SELECT:
+ case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP:
+ case NS_HTML5TREE_BUILDER_FRAMESET_OK:
+ case NS_HTML5TREE_BUILDER_IN_CAPTION:
+ case NS_HTML5TREE_BUILDER_IN_CELL:
+ case NS_HTML5TREE_BUILDER_IN_BODY: {
+ if (isTemplateModeStackEmpty()) {
+ NS_HTML5_BREAK(eofloop);
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_TEMPLATE: {
+ int32_t eltPos = findLast(nsHtml5Atoms::template_);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ MOZ_ASSERT(fragment);
+ NS_HTML5_BREAK(eofloop);
+ }
+ if (MOZ_UNLIKELY(mViewSource)) {
+ errUnclosedElements(eltPos, nsHtml5Atoms::template_);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ popTemplateMode();
+ resetTheInsertionMode();
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_TEXT: {
+ if (originalMode == NS_HTML5TREE_BUILDER_AFTER_HEAD) {
+ popOnEof();
+ }
+ popOnEof();
+ mode = originalMode;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_IN_FRAMESET: {
+ NS_HTML5_BREAK(eofloop);
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_BODY:
+ case NS_HTML5TREE_BUILDER_AFTER_FRAMESET:
+ case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY:
+ case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET:
+ default: {
+ NS_HTML5_BREAK(eofloop);
+ }
+ }
+ }
+ eofloop_end: ;
+ while (currentPtr > 0) {
+ popOnEof();
+ }
+ if (!fragment) {
+ popOnEof();
+ }
+}
+
+void
+nsHtml5TreeBuilder::endTokenization()
+{
+ formPointer = nullptr;
+ headPointer = nullptr;
+ deepTreeSurrogateParent = nullptr;
+ templateModeStack = nullptr;
+ if (stack) {
+ while (currentPtr > -1) {
+ stack[currentPtr]->release();
+ currentPtr--;
+ }
+ stack = nullptr;
+ }
+ if (listOfActiveFormattingElements) {
+ while (listPtr > -1) {
+ if (listOfActiveFormattingElements[listPtr]) {
+ listOfActiveFormattingElements[listPtr]->release();
+ }
+ listPtr--;
+ }
+ listOfActiveFormattingElements = nullptr;
+ }
+ charBuffer = nullptr;
+ end();
+}
+
+void
+nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, bool selfClosing)
+{
+ flushCharacters();
+ int32_t eltPos;
+ needToDropLF = false;
+ starttagloop: for (; ; ) {
+ int32_t group = elementName->getGroup();
+ nsIAtom* name = elementName->name;
+ if (isInForeign()) {
+ nsHtml5StackNode* currentNode = stack[currentPtr];
+ int32_t currNs = currentNode->ns;
+ if (!(currentNode->isHtmlIntegrationPoint() || (currNs == kNameSpaceID_MathML && ((currentNode->getGroup() == NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT && group != NS_HTML5TREE_BUILDER_MGLYPH_OR_MALIGNMARK) || (currentNode->getGroup() == NS_HTML5TREE_BUILDER_ANNOTATION_XML && group == NS_HTML5TREE_BUILDER_SVG))))) {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
+ case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
+ case NS_HTML5TREE_BUILDER_BODY:
+ case NS_HTML5TREE_BUILDER_BR:
+ case NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR:
+ case NS_HTML5TREE_BUILDER_DD_OR_DT:
+ case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL:
+ case NS_HTML5TREE_BUILDER_EMBED:
+ case NS_HTML5TREE_BUILDER_IMG:
+ case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
+ case NS_HTML5TREE_BUILDER_HEAD:
+ case NS_HTML5TREE_BUILDER_HR:
+ case NS_HTML5TREE_BUILDER_LI:
+ case NS_HTML5TREE_BUILDER_META:
+ case NS_HTML5TREE_BUILDER_NOBR:
+ case NS_HTML5TREE_BUILDER_P:
+ case NS_HTML5TREE_BUILDER_PRE_OR_LISTING:
+ case NS_HTML5TREE_BUILDER_TABLE:
+ case NS_HTML5TREE_BUILDER_FONT: {
+ if (!(group == NS_HTML5TREE_BUILDER_FONT && !(attributes->contains(nsHtml5AttributeName::ATTR_COLOR) || attributes->contains(nsHtml5AttributeName::ATTR_FACE) || attributes->contains(nsHtml5AttributeName::ATTR_SIZE)))) {
+ errHtmlStartTagInForeignContext(name);
+ if (!fragment) {
+ while (!isSpecialParentInForeign(stack[currentPtr])) {
+ pop();
+ }
+ NS_HTML5_CONTINUE(starttagloop);
+ }
+ }
+ }
+ default: {
+ if (kNameSpaceID_SVG == currNs) {
+ attributes->adjustForSvg();
+ if (selfClosing) {
+ appendVoidElementToCurrentMayFosterSVG(elementName, attributes);
+ selfClosing = false;
+ } else {
+ appendToCurrentNodeAndPushElementMayFosterSVG(elementName, attributes);
+ }
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ } else {
+ attributes->adjustForMath();
+ if (selfClosing) {
+ appendVoidElementToCurrentMayFosterMathML(elementName, attributes);
+ selfClosing = false;
+ } else {
+ appendToCurrentNodeAndPushElementMayFosterMathML(elementName, attributes);
+ }
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ }
+ }
+ }
+ }
+ switch(mode) {
+ case NS_HTML5TREE_BUILDER_IN_TEMPLATE: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_COL: {
+ popTemplateMode();
+ pushTemplateMode(NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP);
+ mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_CAPTION:
+ case NS_HTML5TREE_BUILDER_COLGROUP:
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
+ popTemplateMode();
+ pushTemplateMode(NS_HTML5TREE_BUILDER_IN_TABLE);
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_TR: {
+ popTemplateMode();
+ pushTemplateMode(NS_HTML5TREE_BUILDER_IN_TABLE_BODY);
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+ popTemplateMode();
+ pushTemplateMode(NS_HTML5TREE_BUILDER_IN_ROW);
+ mode = NS_HTML5TREE_BUILDER_IN_ROW;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_META: {
+ checkMetaCharset(attributes);
+ appendVoidElementToCurrentMayFoster(elementName, attributes);
+ selfClosing = false;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TITLE: {
+ startTagTitleInHead(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_BASE:
+ case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: {
+ appendVoidElementToCurrentMayFoster(elementName, attributes);
+ selfClosing = false;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_SCRIPT: {
+ startTagScriptInHead(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_NOFRAMES:
+ case NS_HTML5TREE_BUILDER_STYLE: {
+ startTagGenericRawText(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TEMPLATE: {
+ startTagTemplateInHead(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ default: {
+ popTemplateMode();
+ pushTemplateMode(NS_HTML5TREE_BUILDER_IN_BODY);
+ mode = NS_HTML5TREE_BUILDER_IN_BODY;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_ROW: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+ clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TR));
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ mode = NS_HTML5TREE_BUILDER_IN_CELL;
+ insertMarker();
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_CAPTION:
+ case NS_HTML5TREE_BUILDER_COL:
+ case NS_HTML5TREE_BUILDER_COLGROUP:
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+ case NS_HTML5TREE_BUILDER_TR: {
+ eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
+ if (!eltPos) {
+ MOZ_ASSERT(fragment || isTemplateContents());
+ errNoTableRowToClose();
+ NS_HTML5_BREAK(starttagloop);
+ }
+ clearStackBackTo(eltPos);
+ pop();
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
+ continue;
+ }
+ default:
+ ; // fall through
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_TR: {
+ clearStackBackTo(findLastInTableScopeOrRootTemplateTbodyTheadTfoot());
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ mode = NS_HTML5TREE_BUILDER_IN_ROW;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+ errStartTagInTableBody(name);
+ clearStackBackTo(findLastInTableScopeOrRootTemplateTbodyTheadTfoot());
+ appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_TR, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+ mode = NS_HTML5TREE_BUILDER_IN_ROW;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_CAPTION:
+ case NS_HTML5TREE_BUILDER_COL:
+ case NS_HTML5TREE_BUILDER_COLGROUP:
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
+ eltPos = findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
+ if (!eltPos || stack[eltPos]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) {
+ MOZ_ASSERT(fragment || isTemplateContents());
+ errStrayStartTag(name);
+ NS_HTML5_BREAK(starttagloop);
+ } else {
+ clearStackBackTo(eltPos);
+ pop();
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+ continue;
+ }
+ }
+ default:
+ ; // fall through
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_TABLE: {
+ for (; ; ) {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_CAPTION: {
+ clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
+ insertMarker();
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ mode = NS_HTML5TREE_BUILDER_IN_CAPTION;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_COLGROUP: {
+ clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_COL: {
+ clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
+ appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_COLGROUP, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+ mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP;
+ NS_HTML5_CONTINUE(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
+ clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TR:
+ case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+ clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
+ appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_TBODY, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
+ NS_HTML5_CONTINUE(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TEMPLATE: {
+ NS_HTML5_BREAK(intableloop);
+ }
+ case NS_HTML5TREE_BUILDER_TABLE: {
+ errTableSeenWhileTableOpen();
+ eltPos = findLastInTableScope(name);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ MOZ_ASSERT(fragment || isTemplateContents());
+ NS_HTML5_BREAK(starttagloop);
+ }
+ generateImpliedEndTags();
+ if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(nsHtml5Atoms::table)) {
+ errNoCheckUnclosedElementsOnStack();
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ resetTheInsertionMode();
+ NS_HTML5_CONTINUE(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_SCRIPT: {
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ originalMode = mode;
+ mode = NS_HTML5TREE_BUILDER_TEXT;
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_SCRIPT_DATA, elementName);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_STYLE: {
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ originalMode = mode;
+ mode = NS_HTML5TREE_BUILDER_TEXT;
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_INPUT: {
+ errStartTagInTable(name);
+ if (!nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("hidden", attributes->getValue(nsHtml5AttributeName::ATTR_TYPE))) {
+ NS_HTML5_BREAK(intableloop);
+ }
+ appendVoidElementToCurrent(name, attributes, formPointer);
+ selfClosing = false;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_FORM: {
+ if (!!formPointer || isTemplateContents()) {
+ errFormWhenFormOpen();
+ NS_HTML5_BREAK(starttagloop);
+ } else {
+ errStartTagInTable(name);
+ appendVoidFormToCurrent(attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ }
+ default: {
+ errStartTagInTable(name);
+ NS_HTML5_BREAK(intableloop);
+ }
+ }
+ }
+ intableloop_end: ;
+ }
+ case NS_HTML5TREE_BUILDER_IN_CAPTION: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_CAPTION:
+ case NS_HTML5TREE_BUILDER_COL:
+ case NS_HTML5TREE_BUILDER_COLGROUP:
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+ case NS_HTML5TREE_BUILDER_TR:
+ case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+ errStrayStartTag(name);
+ eltPos = findLastInTableScope(nsHtml5Atoms::caption);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ NS_HTML5_BREAK(starttagloop);
+ }
+ generateImpliedEndTags();
+ if (!!MOZ_UNLIKELY(mViewSource) && currentPtr != eltPos) {
+ errNoCheckUnclosedElementsOnStack();
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+ continue;
+ }
+ default:
+ ; // fall through
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_CELL: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_CAPTION:
+ case NS_HTML5TREE_BUILDER_COL:
+ case NS_HTML5TREE_BUILDER_COLGROUP:
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+ case NS_HTML5TREE_BUILDER_TR:
+ case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+ eltPos = findLastInTableScopeTdTh();
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ errNoCellToClose();
+ NS_HTML5_BREAK(starttagloop);
+ } else {
+ closeTheCell(eltPos);
+ continue;
+ }
+ }
+ default:
+ ; // fall through
+ }
+ }
+ case NS_HTML5TREE_BUILDER_FRAMESET_OK: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_FRAMESET: {
+ if (mode == NS_HTML5TREE_BUILDER_FRAMESET_OK) {
+ if (!currentPtr || stack[1]->getGroup() != NS_HTML5TREE_BUILDER_BODY) {
+ MOZ_ASSERT(fragment || isTemplateContents());
+ errStrayStartTag(name);
+ NS_HTML5_BREAK(starttagloop);
+ } else {
+ errFramesetStart();
+ detachFromParent(stack[1]->node);
+ while (currentPtr > 0) {
+ pop();
+ }
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ mode = NS_HTML5TREE_BUILDER_IN_FRAMESET;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ } else {
+ errStrayStartTag(name);
+ NS_HTML5_BREAK(starttagloop);
+ }
+ }
+ case NS_HTML5TREE_BUILDER_PRE_OR_LISTING:
+ case NS_HTML5TREE_BUILDER_LI:
+ case NS_HTML5TREE_BUILDER_DD_OR_DT:
+ case NS_HTML5TREE_BUILDER_BUTTON:
+ case NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET:
+ case NS_HTML5TREE_BUILDER_OBJECT:
+ case NS_HTML5TREE_BUILDER_TABLE:
+ case NS_HTML5TREE_BUILDER_AREA_OR_WBR:
+ case NS_HTML5TREE_BUILDER_BR:
+ case NS_HTML5TREE_BUILDER_EMBED:
+ case NS_HTML5TREE_BUILDER_IMG:
+ case NS_HTML5TREE_BUILDER_INPUT:
+ case NS_HTML5TREE_BUILDER_KEYGEN:
+ case NS_HTML5TREE_BUILDER_HR:
+ case NS_HTML5TREE_BUILDER_TEXTAREA:
+ case NS_HTML5TREE_BUILDER_XMP:
+ case NS_HTML5TREE_BUILDER_IFRAME:
+ case NS_HTML5TREE_BUILDER_SELECT: {
+ if (mode == NS_HTML5TREE_BUILDER_FRAMESET_OK && !(group == NS_HTML5TREE_BUILDER_INPUT && nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("hidden", attributes->getValue(nsHtml5AttributeName::ATTR_TYPE)))) {
+ framesetOk = false;
+ mode = NS_HTML5TREE_BUILDER_IN_BODY;
+ }
+ }
+ default:
+ ; // fall through
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_BODY: {
+ for (; ; ) {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HTML: {
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = nullptr;
+ }
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_BASE:
+ case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND:
+ case NS_HTML5TREE_BUILDER_META:
+ case NS_HTML5TREE_BUILDER_STYLE:
+ case NS_HTML5TREE_BUILDER_SCRIPT:
+ case NS_HTML5TREE_BUILDER_TITLE:
+ case NS_HTML5TREE_BUILDER_TEMPLATE: {
+ NS_HTML5_BREAK(inbodyloop);
+ }
+ case NS_HTML5TREE_BUILDER_BODY: {
+ if (!currentPtr || stack[1]->getGroup() != NS_HTML5TREE_BUILDER_BODY || isTemplateContents()) {
+ MOZ_ASSERT(fragment || isTemplateContents());
+ errStrayStartTag(name);
+ NS_HTML5_BREAK(starttagloop);
+ }
+ errFooSeenWhenFooOpen(name);
+ framesetOk = false;
+ if (mode == NS_HTML5TREE_BUILDER_FRAMESET_OK) {
+ mode = NS_HTML5TREE_BUILDER_IN_BODY;
+ }
+ if (addAttributesToBody(attributes)) {
+ attributes = nullptr;
+ }
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_P:
+ case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
+ case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL:
+ case NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY: {
+ implicitlyCloseP();
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6: {
+ implicitlyCloseP();
+ if (stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6) {
+ errHeadingWhenHeadingOpen();
+ pop();
+ }
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_FIELDSET: {
+ implicitlyCloseP();
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_PRE_OR_LISTING: {
+ implicitlyCloseP();
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ needToDropLF = true;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_FORM: {
+ if (!!formPointer && !isTemplateContents()) {
+ errFormWhenFormOpen();
+ NS_HTML5_BREAK(starttagloop);
+ } else {
+ implicitlyCloseP();
+ appendToCurrentNodeAndPushFormElementMayFoster(attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ }
+ case NS_HTML5TREE_BUILDER_LI:
+ case NS_HTML5TREE_BUILDER_DD_OR_DT: {
+ eltPos = currentPtr;
+ for (; ; ) {
+ nsHtml5StackNode* node = stack[eltPos];
+ if (node->getGroup() == group) {
+ generateImpliedEndTagsExceptFor(node->name);
+ if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) {
+ errUnclosedElementsImplied(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ break;
+ } else if (!eltPos || (node->isSpecial() && (node->ns != kNameSpaceID_XHTML || (node->name != nsHtml5Atoms::p && node->name != nsHtml5Atoms::address && node->name != nsHtml5Atoms::div)))) {
+ break;
+ }
+ eltPos--;
+ }
+ implicitlyCloseP();
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_PLAINTEXT: {
+ implicitlyCloseP();
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_PLAINTEXT, elementName);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_A: {
+ int32_t activeAPos = findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(nsHtml5Atoms::a);
+ if (activeAPos != -1) {
+ errFooSeenWhenFooOpen(name);
+ nsHtml5StackNode* activeA = listOfActiveFormattingElements[activeAPos];
+ activeA->retain();
+ adoptionAgencyEndTag(nsHtml5Atoms::a);
+ removeFromStack(activeA);
+ activeAPos = findInListOfActiveFormattingElements(activeA);
+ if (activeAPos != -1) {
+ removeFromListOfActiveFormattingElements(activeAPos);
+ }
+ activeA->release();
+ }
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushFormattingElementMayFoster(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
+ case NS_HTML5TREE_BUILDER_FONT: {
+ reconstructTheActiveFormattingElements();
+ maybeForgetEarlierDuplicateFormattingElement(elementName->name, attributes);
+ appendToCurrentNodeAndPushFormattingElementMayFoster(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_NOBR: {
+ reconstructTheActiveFormattingElements();
+ if (NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK != findLastInScope(nsHtml5Atoms::nobr)) {
+ errFooSeenWhenFooOpen(name);
+ adoptionAgencyEndTag(nsHtml5Atoms::nobr);
+ reconstructTheActiveFormattingElements();
+ }
+ appendToCurrentNodeAndPushFormattingElementMayFoster(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_BUTTON: {
+ eltPos = findLastInScope(name);
+ if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ errFooSeenWhenFooOpen(name);
+ generateImpliedEndTags();
+ if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
+ errUnclosedElementsImplied(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ NS_HTML5_CONTINUE(starttagloop);
+ } else {
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ }
+ case NS_HTML5TREE_BUILDER_OBJECT: {
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer);
+ insertMarker();
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET: {
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ insertMarker();
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TABLE: {
+ if (!quirks) {
+ implicitlyCloseP();
+ }
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_BR:
+ case NS_HTML5TREE_BUILDER_EMBED:
+ case NS_HTML5TREE_BUILDER_AREA_OR_WBR: {
+ reconstructTheActiveFormattingElements();
+ }
+#ifdef ENABLE_VOID_MENUITEM
+ case NS_HTML5TREE_BUILDER_MENUITEM:
+#endif
+ case NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE_OR_TRACK: {
+ appendVoidElementToCurrentMayFoster(elementName, attributes);
+ selfClosing = false;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_HR: {
+ implicitlyCloseP();
+ appendVoidElementToCurrentMayFoster(elementName, attributes);
+ selfClosing = false;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_IMAGE: {
+ errImage();
+ elementName = nsHtml5ElementName::ELT_IMG;
+ NS_HTML5_CONTINUE(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_IMG:
+ case NS_HTML5TREE_BUILDER_KEYGEN:
+ case NS_HTML5TREE_BUILDER_INPUT: {
+ reconstructTheActiveFormattingElements();
+ appendVoidElementToCurrentMayFoster(name, attributes, formPointer);
+ selfClosing = false;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_ISINDEX: {
+ errIsindex();
+ if (!!formPointer && !isTemplateContents()) {
+ NS_HTML5_BREAK(starttagloop);
+ }
+ implicitlyCloseP();
+ nsHtml5HtmlAttributes* formAttrs = new nsHtml5HtmlAttributes(0);
+ int32_t actionIndex = attributes->getIndex(nsHtml5AttributeName::ATTR_ACTION);
+ if (actionIndex > -1) {
+ formAttrs->addAttribute(nsHtml5AttributeName::ATTR_ACTION, attributes->getValueNoBoundsCheck(actionIndex), attributes->getLineNoBoundsCheck(actionIndex));
+ }
+ appendToCurrentNodeAndPushFormElementMayFoster(formAttrs);
+ appendVoidElementToCurrentMayFoster(nsHtml5ElementName::ELT_HR, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+ appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName::ELT_LABEL, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+ int32_t promptIndex = attributes->getIndex(nsHtml5AttributeName::ATTR_PROMPT);
+ if (promptIndex > -1) {
+ autoJArray<char16_t,int32_t> prompt = nsHtml5Portability::newCharArrayFromString(attributes->getValueNoBoundsCheck(promptIndex));
+ appendCharacters(stack[currentPtr]->node, prompt, 0, prompt.length);
+ } else {
+ appendIsindexPrompt(stack[currentPtr]->node);
+ }
+ nsHtml5HtmlAttributes* inputAttributes = new nsHtml5HtmlAttributes(0);
+ inputAttributes->addAttribute(nsHtml5AttributeName::ATTR_NAME, nsHtml5Portability::newStringFromLiteral("isindex"), tokenizer->getLineNumber());
+ for (int32_t i = 0; i < attributes->getLength(); i++) {
+ nsHtml5AttributeName* attributeQName = attributes->getAttributeNameNoBoundsCheck(i);
+ if (nsHtml5AttributeName::ATTR_NAME == attributeQName || nsHtml5AttributeName::ATTR_PROMPT == attributeQName) {
+ attributes->releaseValue(i);
+ } else if (nsHtml5AttributeName::ATTR_ACTION != attributeQName) {
+ inputAttributes->addAttribute(attributeQName, attributes->getValueNoBoundsCheck(i), attributes->getLineNoBoundsCheck(i));
+ }
+ }
+ attributes->clearWithoutReleasingContents();
+ appendVoidElementToCurrentMayFoster(nsHtml5Atoms::input, inputAttributes, formPointer);
+ pop();
+ appendVoidElementToCurrentMayFoster(nsHtml5ElementName::ELT_HR, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+ pop();
+ if (!isTemplateContents()) {
+ formPointer = nullptr;
+ }
+ selfClosing = false;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TEXTAREA: {
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer);
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RCDATA, elementName);
+ originalMode = mode;
+ mode = NS_HTML5TREE_BUILDER_TEXT;
+ needToDropLF = true;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_XMP: {
+ implicitlyCloseP();
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ originalMode = mode;
+ mode = NS_HTML5TREE_BUILDER_TEXT;
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_NOSCRIPT: {
+ if (!scriptingEnabled) {
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ } else {
+ }
+ }
+ case NS_HTML5TREE_BUILDER_NOFRAMES:
+ case NS_HTML5TREE_BUILDER_IFRAME:
+ case NS_HTML5TREE_BUILDER_NOEMBED: {
+ startTagGenericRawText(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_SELECT: {
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer);
+ switch(mode) {
+ case NS_HTML5TREE_BUILDER_IN_TABLE:
+ case NS_HTML5TREE_BUILDER_IN_CAPTION:
+ case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP:
+ case NS_HTML5TREE_BUILDER_IN_TABLE_BODY:
+ case NS_HTML5TREE_BUILDER_IN_ROW:
+ case NS_HTML5TREE_BUILDER_IN_CELL: {
+ mode = NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE;
+ break;
+ }
+ default: {
+ mode = NS_HTML5TREE_BUILDER_IN_SELECT;
+ break;
+ }
+ }
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_OPTGROUP:
+ case NS_HTML5TREE_BUILDER_OPTION: {
+ if (isCurrent(nsHtml5Atoms::option)) {
+ pop();
+ }
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_RB_OR_RTC: {
+ eltPos = findLastInScope(nsHtml5Atoms::ruby);
+ if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ generateImpliedEndTags();
+ }
+ if (eltPos != currentPtr) {
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ errStartTagSeenWithoutRuby(name);
+ } else {
+ errUnclosedChildrenInRuby();
+ }
+ }
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_RT_OR_RP: {
+ eltPos = findLastInScope(nsHtml5Atoms::ruby);
+ if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ generateImpliedEndTagsExceptFor(nsHtml5Atoms::rtc);
+ }
+ if (eltPos != currentPtr) {
+ if (!isCurrent(nsHtml5Atoms::rtc)) {
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ errStartTagSeenWithoutRuby(name);
+ } else {
+ errUnclosedChildrenInRuby();
+ }
+ }
+ }
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_MATH: {
+ reconstructTheActiveFormattingElements();
+ attributes->adjustForMath();
+ if (selfClosing) {
+ appendVoidElementToCurrentMayFosterMathML(elementName, attributes);
+ selfClosing = false;
+ } else {
+ appendToCurrentNodeAndPushElementMayFosterMathML(elementName, attributes);
+ }
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_SVG: {
+ reconstructTheActiveFormattingElements();
+ attributes->adjustForSvg();
+ if (selfClosing) {
+ appendVoidElementToCurrentMayFosterSVG(elementName, attributes);
+ selfClosing = false;
+ } else {
+ appendToCurrentNodeAndPushElementMayFosterSVG(elementName, attributes);
+ }
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_CAPTION:
+ case NS_HTML5TREE_BUILDER_COL:
+ case NS_HTML5TREE_BUILDER_COLGROUP:
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+ case NS_HTML5TREE_BUILDER_TR:
+ case NS_HTML5TREE_BUILDER_TD_OR_TH:
+ case NS_HTML5TREE_BUILDER_FRAME:
+ case NS_HTML5TREE_BUILDER_FRAMESET:
+ case NS_HTML5TREE_BUILDER_HEAD: {
+ errStrayStartTag(name);
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_OUTPUT: {
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ default: {
+ reconstructTheActiveFormattingElements();
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ }
+ }
+ inbodyloop_end: ;
+ }
+ case NS_HTML5TREE_BUILDER_IN_HEAD: {
+ for (; ; ) {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HTML: {
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = nullptr;
+ }
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_BASE:
+ case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: {
+ appendVoidElementToCurrentMayFoster(elementName, attributes);
+ selfClosing = false;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_META: {
+ NS_HTML5_BREAK(inheadloop);
+ }
+ case NS_HTML5TREE_BUILDER_TITLE: {
+ startTagTitleInHead(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_NOSCRIPT: {
+ if (scriptingEnabled) {
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ originalMode = mode;
+ mode = NS_HTML5TREE_BUILDER_TEXT;
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName);
+ } else {
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ mode = NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT;
+ }
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_SCRIPT: {
+ startTagScriptInHead(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_STYLE:
+ case NS_HTML5TREE_BUILDER_NOFRAMES: {
+ startTagGenericRawText(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_HEAD: {
+ errFooSeenWhenFooOpen(name);
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TEMPLATE: {
+ startTagTemplateInHead(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ default: {
+ pop();
+ mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
+ NS_HTML5_CONTINUE(starttagloop);
+ }
+ }
+ }
+ inheadloop_end: ;
+ }
+ case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HTML: {
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = nullptr;
+ }
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: {
+ appendVoidElementToCurrentMayFoster(elementName, attributes);
+ selfClosing = false;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_META: {
+ checkMetaCharset(attributes);
+ appendVoidElementToCurrentMayFoster(elementName, attributes);
+ selfClosing = false;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_STYLE:
+ case NS_HTML5TREE_BUILDER_NOFRAMES: {
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ originalMode = mode;
+ mode = NS_HTML5TREE_BUILDER_TEXT;
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_HEAD: {
+ errFooSeenWhenFooOpen(name);
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_NOSCRIPT: {
+ errFooSeenWhenFooOpen(name);
+ NS_HTML5_BREAK(starttagloop);
+ }
+ default: {
+ errBadStartTagInHead(name);
+ pop();
+ mode = NS_HTML5TREE_BUILDER_IN_HEAD;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HTML: {
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = nullptr;
+ }
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_COL: {
+ appendVoidElementToCurrentMayFoster(elementName, attributes);
+ selfClosing = false;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TEMPLATE: {
+ startTagTemplateInHead(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ default: {
+ if (!currentPtr || stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) {
+ MOZ_ASSERT(fragment || isTemplateContents());
+ errGarbageInColgroup();
+ NS_HTML5_BREAK(starttagloop);
+ }
+ pop();
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_CAPTION:
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+ case NS_HTML5TREE_BUILDER_TR:
+ case NS_HTML5TREE_BUILDER_TD_OR_TH:
+ case NS_HTML5TREE_BUILDER_TABLE: {
+ errStartTagWithSelectOpen(name);
+ eltPos = findLastInTableScope(nsHtml5Atoms::select);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ MOZ_ASSERT(fragment);
+ NS_HTML5_BREAK(starttagloop);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ resetTheInsertionMode();
+ continue;
+ }
+ default:
+ ; // fall through
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_SELECT: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HTML: {
+ errStrayStartTag(name);
+ if (!fragment) {
+ addAttributesToHtml(attributes);
+ attributes = nullptr;
+ }
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_OPTION: {
+ if (isCurrent(nsHtml5Atoms::option)) {
+ pop();
+ }
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_OPTGROUP: {
+ if (isCurrent(nsHtml5Atoms::option)) {
+ pop();
+ }
+ if (isCurrent(nsHtml5Atoms::optgroup)) {
+ pop();
+ }
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_SELECT: {
+ errStartSelectWhereEndSelectExpected();
+ eltPos = findLastInTableScope(name);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ MOZ_ASSERT(fragment);
+ errNoSelectInTableScope();
+ NS_HTML5_BREAK(starttagloop);
+ } else {
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ resetTheInsertionMode();
+ NS_HTML5_BREAK(starttagloop);
+ }
+ }
+ case NS_HTML5TREE_BUILDER_INPUT:
+ case NS_HTML5TREE_BUILDER_TEXTAREA:
+ case NS_HTML5TREE_BUILDER_KEYGEN: {
+ errStartTagWithSelectOpen(name);
+ eltPos = findLastInTableScope(nsHtml5Atoms::select);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ MOZ_ASSERT(fragment);
+ NS_HTML5_BREAK(starttagloop);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ resetTheInsertionMode();
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_SCRIPT: {
+ startTagScriptInHead(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TEMPLATE: {
+ startTagTemplateInHead(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ default: {
+ errStrayStartTag(name);
+ NS_HTML5_BREAK(starttagloop);
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_BODY: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HTML: {
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = nullptr;
+ }
+ NS_HTML5_BREAK(starttagloop);
+ }
+ default: {
+ errStrayStartTag(name);
+ mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_FRAMESET: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_FRAMESET: {
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_FRAME: {
+ appendVoidElementToCurrentMayFoster(elementName, attributes);
+ selfClosing = false;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ default:
+ ; // fall through
+ }
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HTML: {
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = nullptr;
+ }
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_NOFRAMES: {
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ originalMode = mode;
+ mode = NS_HTML5TREE_BUILDER_TEXT;
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ default: {
+ errStrayStartTag(name);
+ NS_HTML5_BREAK(starttagloop);
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_INITIAL: {
+ errStartTagWithoutDoctype();
+ documentModeInternal(QUIRKS_MODE, nullptr, nullptr, false);
+ mode = NS_HTML5TREE_BUILDER_BEFORE_HTML;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_BEFORE_HTML: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HTML: {
+ if (attributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
+ appendHtmlElementToDocumentAndPush();
+ } else {
+ appendHtmlElementToDocumentAndPush(attributes);
+ }
+ mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ default: {
+ appendHtmlElementToDocumentAndPush();
+ mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_BEFORE_HEAD: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HTML: {
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = nullptr;
+ }
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_HEAD: {
+ appendToCurrentNodeAndPushHeadElement(attributes);
+ mode = NS_HTML5TREE_BUILDER_IN_HEAD;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ default: {
+ appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+ mode = NS_HTML5TREE_BUILDER_IN_HEAD;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_HEAD: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HTML: {
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = nullptr;
+ }
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_BODY: {
+ if (!attributes->getLength()) {
+ appendToCurrentNodeAndPushBodyElement();
+ } else {
+ appendToCurrentNodeAndPushBodyElement(attributes);
+ }
+ framesetOk = false;
+ mode = NS_HTML5TREE_BUILDER_IN_BODY;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_FRAMESET: {
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ mode = NS_HTML5TREE_BUILDER_IN_FRAMESET;
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TEMPLATE: {
+ errFooBetweenHeadAndBody(name);
+ pushHeadPointerOntoStack();
+ nsHtml5StackNode* headOnStack = stack[currentPtr];
+ startTagTemplateInHead(elementName, attributes);
+ removeFromStack(headOnStack);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_BASE:
+ case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: {
+ errFooBetweenHeadAndBody(name);
+ pushHeadPointerOntoStack();
+ appendVoidElementToCurrentMayFoster(elementName, attributes);
+ selfClosing = false;
+ pop();
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_META: {
+ errFooBetweenHeadAndBody(name);
+ checkMetaCharset(attributes);
+ pushHeadPointerOntoStack();
+ appendVoidElementToCurrentMayFoster(elementName, attributes);
+ selfClosing = false;
+ pop();
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_SCRIPT: {
+ errFooBetweenHeadAndBody(name);
+ pushHeadPointerOntoStack();
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ originalMode = mode;
+ mode = NS_HTML5TREE_BUILDER_TEXT;
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_SCRIPT_DATA, elementName);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_STYLE:
+ case NS_HTML5TREE_BUILDER_NOFRAMES: {
+ errFooBetweenHeadAndBody(name);
+ pushHeadPointerOntoStack();
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ originalMode = mode;
+ mode = NS_HTML5TREE_BUILDER_TEXT;
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TITLE: {
+ errFooBetweenHeadAndBody(name);
+ pushHeadPointerOntoStack();
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ originalMode = mode;
+ mode = NS_HTML5TREE_BUILDER_TEXT;
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RCDATA, elementName);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_HEAD: {
+ errStrayStartTag(name);
+ NS_HTML5_BREAK(starttagloop);
+ }
+ default: {
+ appendToCurrentNodeAndPushBodyElement();
+ mode = NS_HTML5TREE_BUILDER_FRAMESET_OK;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HTML: {
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = nullptr;
+ }
+ NS_HTML5_BREAK(starttagloop);
+ }
+ default: {
+ errStrayStartTag(name);
+
+ mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HTML: {
+ errStrayStartTag(name);
+ if (!fragment && !isTemplateContents()) {
+ addAttributesToHtml(attributes);
+ attributes = nullptr;
+ }
+ NS_HTML5_BREAK(starttagloop);
+ }
+ case NS_HTML5TREE_BUILDER_NOFRAMES: {
+ startTagGenericRawText(elementName, attributes);
+ attributes = nullptr;
+ NS_HTML5_BREAK(starttagloop);
+ }
+ default: {
+ errStrayStartTag(name);
+ NS_HTML5_BREAK(starttagloop);
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_TEXT: {
+ MOZ_ASSERT(false);
+ NS_HTML5_BREAK(starttagloop);
+ }
+ }
+ }
+ starttagloop_end: ;
+ if (selfClosing) {
+ errSelfClosing();
+ }
+ if (!mBuilder && attributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
+ delete attributes;
+ }
+}
+
+void
+nsHtml5TreeBuilder::startTagTitleInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
+{
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ originalMode = mode;
+ mode = NS_HTML5TREE_BUILDER_TEXT;
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RCDATA, elementName);
+}
+
+void
+nsHtml5TreeBuilder::startTagGenericRawText(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
+{
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ originalMode = mode;
+ mode = NS_HTML5TREE_BUILDER_TEXT;
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName);
+}
+
+void
+nsHtml5TreeBuilder::startTagScriptInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
+{
+ appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+ originalMode = mode;
+ mode = NS_HTML5TREE_BUILDER_TEXT;
+ tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_SCRIPT_DATA, elementName);
+}
+
+void
+nsHtml5TreeBuilder::startTagTemplateInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
+{
+ appendToCurrentNodeAndPushElement(elementName, attributes);
+ insertMarker();
+ framesetOk = false;
+ originalMode = mode;
+ mode = NS_HTML5TREE_BUILDER_IN_TEMPLATE;
+ pushTemplateMode(NS_HTML5TREE_BUILDER_IN_TEMPLATE);
+}
+
+bool
+nsHtml5TreeBuilder::isTemplateContents()
+{
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK != findLast(nsHtml5Atoms::template_);
+}
+
+bool
+nsHtml5TreeBuilder::isTemplateModeStackEmpty()
+{
+ return templateModePtr == -1;
+}
+
+bool
+nsHtml5TreeBuilder::isSpecialParentInForeign(nsHtml5StackNode* stackNode)
+{
+ int32_t ns = stackNode->ns;
+ return (kNameSpaceID_XHTML == ns) || (stackNode->isHtmlIntegrationPoint()) || ((kNameSpaceID_MathML == ns) && (stackNode->getGroup() == NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT));
+}
+
+nsString*
+nsHtml5TreeBuilder::extractCharsetFromContent(nsString* attributeValue, nsHtml5TreeBuilder* tb)
+{
+ int32_t charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
+ int32_t start = -1;
+ int32_t end = -1;
+ autoJArray<char16_t,int32_t> buffer = nsHtml5Portability::newCharArrayFromString(attributeValue);
+ for (int32_t i = 0; i < buffer.length; i++) {
+ char16_t c = buffer[i];
+ switch(charsetState) {
+ case NS_HTML5TREE_BUILDER_CHARSET_INITIAL: {
+ switch(c) {
+ case 'c':
+ case 'C': {
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_C;
+ continue;
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_CHARSET_C: {
+ switch(c) {
+ case 'h':
+ case 'H': {
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_H;
+ continue;
+ }
+ default: {
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_CHARSET_H: {
+ switch(c) {
+ case 'a':
+ case 'A': {
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_A;
+ continue;
+ }
+ default: {
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_CHARSET_A: {
+ switch(c) {
+ case 'r':
+ case 'R': {
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_R;
+ continue;
+ }
+ default: {
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_CHARSET_R: {
+ switch(c) {
+ case 's':
+ case 'S': {
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_S;
+ continue;
+ }
+ default: {
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_CHARSET_S: {
+ switch(c) {
+ case 'e':
+ case 'E': {
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_E;
+ continue;
+ }
+ default: {
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_CHARSET_E: {
+ switch(c) {
+ case 't':
+ case 'T': {
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_T;
+ continue;
+ }
+ default: {
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_CHARSET_T: {
+ switch(c) {
+ case '\t':
+ case '\n':
+ case '\f':
+ case '\r':
+ case ' ': {
+ continue;
+ }
+ case '=': {
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_EQUALS;
+ continue;
+ }
+ default: {
+ return nullptr;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_CHARSET_EQUALS: {
+ switch(c) {
+ case '\t':
+ case '\n':
+ case '\f':
+ case '\r':
+ case ' ': {
+ continue;
+ }
+ case '\'': {
+ start = i + 1;
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_SINGLE_QUOTED;
+ continue;
+ }
+ case '\"': {
+ start = i + 1;
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_DOUBLE_QUOTED;
+ continue;
+ }
+ default: {
+ start = i;
+ charsetState = NS_HTML5TREE_BUILDER_CHARSET_UNQUOTED;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_CHARSET_SINGLE_QUOTED: {
+ switch(c) {
+ case '\'': {
+ end = i;
+ NS_HTML5_BREAK(charsetloop);
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_CHARSET_DOUBLE_QUOTED: {
+ switch(c) {
+ case '\"': {
+ end = i;
+ NS_HTML5_BREAK(charsetloop);
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_CHARSET_UNQUOTED: {
+ switch(c) {
+ case '\t':
+ case '\n':
+ case '\f':
+ case '\r':
+ case ' ':
+ case ';': {
+ end = i;
+ NS_HTML5_BREAK(charsetloop);
+ }
+ default: {
+ continue;
+ }
+ }
+ }
+ }
+ }
+ charsetloop_end: ;
+ nsString* charset = nullptr;
+ if (start != -1) {
+ if (end == -1) {
+ end = buffer.length;
+ }
+ charset = nsHtml5Portability::newStringFromBuffer(buffer, start, end - start, tb);
+ }
+ return charset;
+}
+
+void
+nsHtml5TreeBuilder::checkMetaCharset(nsHtml5HtmlAttributes* attributes)
+{
+ nsString* charset = attributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
+ if (charset) {
+ if (tokenizer->internalEncodingDeclaration(charset)) {
+ requestSuspension();
+ return;
+ }
+ return;
+ }
+ if (!nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("content-type", attributes->getValue(nsHtml5AttributeName::ATTR_HTTP_EQUIV))) {
+ return;
+ }
+ nsString* content = attributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
+ if (content) {
+ nsString* extract = nsHtml5TreeBuilder::extractCharsetFromContent(content, this);
+ if (extract) {
+ if (tokenizer->internalEncodingDeclaration(extract)) {
+ requestSuspension();
+ }
+ }
+ nsHtml5Portability::releaseString(extract);
+ }
+}
+
+void
+nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName)
+{
+ flushCharacters();
+ needToDropLF = false;
+ int32_t eltPos;
+ int32_t group = elementName->getGroup();
+ nsIAtom* name = elementName->name;
+ for (; ; ) {
+ if (isInForeign()) {
+ if (stack[currentPtr]->name != name) {
+ if (!currentPtr) {
+ errStrayEndTag(name);
+ } else {
+ errEndTagDidNotMatchCurrentOpenElement(name, stack[currentPtr]->popName);
+ }
+ }
+ eltPos = currentPtr;
+ for (; ; ) {
+ if (!eltPos) {
+ MOZ_ASSERT(fragment, "We can get this close to the root of the stack in foreign content only in the fragment case.");
+ NS_HTML5_BREAK(endtagloop);
+ }
+ if (stack[eltPos]->name == name) {
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ NS_HTML5_BREAK(endtagloop);
+ }
+ if (stack[--eltPos]->ns == kNameSpaceID_XHTML) {
+ break;
+ }
+ }
+ }
+ switch(mode) {
+ case NS_HTML5TREE_BUILDER_IN_TEMPLATE: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_TEMPLATE: {
+ break;
+ }
+ default: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_ROW: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_TR: {
+ eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
+ if (!eltPos) {
+ MOZ_ASSERT(fragment || isTemplateContents());
+ errNoTableRowToClose();
+ NS_HTML5_BREAK(endtagloop);
+ }
+ clearStackBackTo(eltPos);
+ pop();
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TABLE: {
+ eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
+ if (!eltPos) {
+ MOZ_ASSERT(fragment || isTemplateContents());
+ errNoTableRowToClose();
+ NS_HTML5_BREAK(endtagloop);
+ }
+ clearStackBackTo(eltPos);
+ pop();
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
+ if (findLastInTableScope(name) == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
+ if (!eltPos) {
+ MOZ_ASSERT(fragment || isTemplateContents());
+ errNoTableRowToClose();
+ NS_HTML5_BREAK(endtagloop);
+ }
+ clearStackBackTo(eltPos);
+ pop();
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_BODY:
+ case NS_HTML5TREE_BUILDER_CAPTION:
+ case NS_HTML5TREE_BUILDER_COL:
+ case NS_HTML5TREE_BUILDER_COLGROUP:
+ case NS_HTML5TREE_BUILDER_HTML:
+ case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ default:
+ ; // fall through
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
+ eltPos = findLastOrRoot(name);
+ if (!eltPos) {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ clearStackBackTo(eltPos);
+ pop();
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TABLE: {
+ eltPos = findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
+ if (!eltPos || stack[eltPos]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) {
+ MOZ_ASSERT(fragment || isTemplateContents());
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ clearStackBackTo(eltPos);
+ pop();
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_BODY:
+ case NS_HTML5TREE_BUILDER_CAPTION:
+ case NS_HTML5TREE_BUILDER_COL:
+ case NS_HTML5TREE_BUILDER_COLGROUP:
+ case NS_HTML5TREE_BUILDER_HTML:
+ case NS_HTML5TREE_BUILDER_TD_OR_TH:
+ case NS_HTML5TREE_BUILDER_TR: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ default:
+ ; // fall through
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_TABLE: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_TABLE: {
+ eltPos = findLast(nsHtml5Atoms::table);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ MOZ_ASSERT(fragment || isTemplateContents());
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ resetTheInsertionMode();
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_BODY:
+ case NS_HTML5TREE_BUILDER_CAPTION:
+ case NS_HTML5TREE_BUILDER_COL:
+ case NS_HTML5TREE_BUILDER_COLGROUP:
+ case NS_HTML5TREE_BUILDER_HTML:
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+ case NS_HTML5TREE_BUILDER_TD_OR_TH:
+ case NS_HTML5TREE_BUILDER_TR: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TEMPLATE: {
+ break;
+ }
+ default: {
+ errStrayEndTag(name);
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_CAPTION: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_CAPTION: {
+ eltPos = findLastInTableScope(nsHtml5Atoms::caption);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ NS_HTML5_BREAK(endtagloop);
+ }
+ generateImpliedEndTags();
+ if (!!MOZ_UNLIKELY(mViewSource) && currentPtr != eltPos) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TABLE: {
+ errTableClosedWhileCaptionOpen();
+ eltPos = findLastInTableScope(nsHtml5Atoms::caption);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ NS_HTML5_BREAK(endtagloop);
+ }
+ generateImpliedEndTags();
+ if (!!MOZ_UNLIKELY(mViewSource) && currentPtr != eltPos) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_BODY:
+ case NS_HTML5TREE_BUILDER_COL:
+ case NS_HTML5TREE_BUILDER_COLGROUP:
+ case NS_HTML5TREE_BUILDER_HTML:
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+ case NS_HTML5TREE_BUILDER_TD_OR_TH:
+ case NS_HTML5TREE_BUILDER_TR: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ default:
+ ; // fall through
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_CELL: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+ eltPos = findLastInTableScope(name);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ generateImpliedEndTags();
+ if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ mode = NS_HTML5TREE_BUILDER_IN_ROW;
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TABLE:
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+ case NS_HTML5TREE_BUILDER_TR: {
+ if (findLastInTableScope(name) == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ MOZ_ASSERT(name == nsHtml5Atoms::tbody || name == nsHtml5Atoms::tfoot || name == nsHtml5Atoms::thead || fragment || isTemplateContents());
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ closeTheCell(findLastInTableScopeTdTh());
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_BODY:
+ case NS_HTML5TREE_BUILDER_CAPTION:
+ case NS_HTML5TREE_BUILDER_COL:
+ case NS_HTML5TREE_BUILDER_COLGROUP:
+ case NS_HTML5TREE_BUILDER_HTML: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ default:
+ ; // fall through
+ }
+ }
+ case NS_HTML5TREE_BUILDER_FRAMESET_OK:
+ case NS_HTML5TREE_BUILDER_IN_BODY: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_BODY: {
+ if (!isSecondOnStackBody()) {
+ MOZ_ASSERT(fragment || isTemplateContents());
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ MOZ_ASSERT(currentPtr >= 1);
+ if (MOZ_UNLIKELY(mViewSource)) {
+ for (int32_t i = 2; i <= currentPtr; i++) {
+ switch(stack[i]->getGroup()) {
+ case NS_HTML5TREE_BUILDER_DD_OR_DT:
+ case NS_HTML5TREE_BUILDER_LI:
+ case NS_HTML5TREE_BUILDER_OPTGROUP:
+ case NS_HTML5TREE_BUILDER_OPTION:
+ case NS_HTML5TREE_BUILDER_P:
+ case NS_HTML5TREE_BUILDER_RB_OR_RTC:
+ case NS_HTML5TREE_BUILDER_RT_OR_RP:
+ case NS_HTML5TREE_BUILDER_TD_OR_TH:
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
+ break;
+ }
+ default: {
+ errEndWithUnclosedElements(name);
+ NS_HTML5_BREAK(uncloseloop1);
+ }
+ }
+ }
+ uncloseloop1_end: ;
+ }
+ mode = NS_HTML5TREE_BUILDER_AFTER_BODY;
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_HTML: {
+ if (!isSecondOnStackBody()) {
+ MOZ_ASSERT(fragment || isTemplateContents());
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ if (MOZ_UNLIKELY(mViewSource)) {
+ for (int32_t i = 0; i <= currentPtr; i++) {
+ switch(stack[i]->getGroup()) {
+ case NS_HTML5TREE_BUILDER_DD_OR_DT:
+ case NS_HTML5TREE_BUILDER_LI:
+ case NS_HTML5TREE_BUILDER_P:
+ case NS_HTML5TREE_BUILDER_RB_OR_RTC:
+ case NS_HTML5TREE_BUILDER_RT_OR_RP:
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+ case NS_HTML5TREE_BUILDER_TD_OR_TH:
+ case NS_HTML5TREE_BUILDER_BODY:
+ case NS_HTML5TREE_BUILDER_HTML: {
+ break;
+ }
+ default: {
+ errEndWithUnclosedElements(name);
+ NS_HTML5_BREAK(uncloseloop2);
+ }
+ }
+ }
+ uncloseloop2_end: ;
+ }
+ mode = NS_HTML5TREE_BUILDER_AFTER_BODY;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
+ case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL:
+ case NS_HTML5TREE_BUILDER_PRE_OR_LISTING:
+ case NS_HTML5TREE_BUILDER_FIELDSET:
+ case NS_HTML5TREE_BUILDER_BUTTON:
+ case NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY: {
+ eltPos = findLastInScope(name);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ errStrayEndTag(name);
+ } else {
+ generateImpliedEndTags();
+ if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ }
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_FORM: {
+ if (!isTemplateContents()) {
+ if (!formPointer) {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ formPointer = nullptr;
+ eltPos = findLastInScope(name);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ generateImpliedEndTags();
+ if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
+ errUnclosedElements(eltPos, name);
+ }
+ removeFromStack(eltPos);
+ NS_HTML5_BREAK(endtagloop);
+ } else {
+ eltPos = findLastInScope(name);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ generateImpliedEndTags();
+ if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ NS_HTML5_BREAK(endtagloop);
+ }
+ }
+ case NS_HTML5TREE_BUILDER_P: {
+ eltPos = findLastInButtonScope(nsHtml5Atoms::p);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ errNoElementToCloseButEndTagSeen(nsHtml5Atoms::p);
+ if (isInForeign()) {
+ errHtmlStartTagInForeignContext(name);
+ while (currentPtr >= 0 && stack[currentPtr]->ns != kNameSpaceID_XHTML) {
+ pop();
+ }
+ }
+ appendVoidElementToCurrentMayFoster(elementName, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ generateImpliedEndTagsExceptFor(nsHtml5Atoms::p);
+ MOZ_ASSERT(eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK);
+ if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_LI: {
+ eltPos = findLastInListScope(name);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ errNoElementToCloseButEndTagSeen(name);
+ } else {
+ generateImpliedEndTagsExceptFor(name);
+ if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ }
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_DD_OR_DT: {
+ eltPos = findLastInScope(name);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ errNoElementToCloseButEndTagSeen(name);
+ } else {
+ generateImpliedEndTagsExceptFor(name);
+ if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ }
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6: {
+ eltPos = findLastInScopeHn();
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ errStrayEndTag(name);
+ } else {
+ generateImpliedEndTags();
+ if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ }
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_OBJECT:
+ case NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET: {
+ eltPos = findLastInScope(name);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ errStrayEndTag(name);
+ } else {
+ generateImpliedEndTags();
+ if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ }
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_BR: {
+ errEndTagBr();
+ if (isInForeign()) {
+ errHtmlStartTagInForeignContext(name);
+ while (currentPtr >= 0 && stack[currentPtr]->ns != kNameSpaceID_XHTML) {
+ pop();
+ }
+ }
+ reconstructTheActiveFormattingElements();
+ appendVoidElementToCurrentMayFoster(elementName, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TEMPLATE: {
+ break;
+ }
+ case NS_HTML5TREE_BUILDER_AREA_OR_WBR:
+#ifdef ENABLE_VOID_MENUITEM
+ case NS_HTML5TREE_BUILDER_MENUITEM:
+#endif
+ case NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE_OR_TRACK:
+ case NS_HTML5TREE_BUILDER_EMBED:
+ case NS_HTML5TREE_BUILDER_IMG:
+ case NS_HTML5TREE_BUILDER_IMAGE:
+ case NS_HTML5TREE_BUILDER_INPUT:
+ case NS_HTML5TREE_BUILDER_KEYGEN:
+ case NS_HTML5TREE_BUILDER_HR:
+ case NS_HTML5TREE_BUILDER_ISINDEX:
+ case NS_HTML5TREE_BUILDER_IFRAME:
+ case NS_HTML5TREE_BUILDER_NOEMBED:
+ case NS_HTML5TREE_BUILDER_NOFRAMES:
+ case NS_HTML5TREE_BUILDER_SELECT:
+ case NS_HTML5TREE_BUILDER_TABLE:
+ case NS_HTML5TREE_BUILDER_TEXTAREA: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_NOSCRIPT: {
+ if (scriptingEnabled) {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ } else {
+ }
+ }
+ case NS_HTML5TREE_BUILDER_A:
+ case NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
+ case NS_HTML5TREE_BUILDER_FONT:
+ case NS_HTML5TREE_BUILDER_NOBR: {
+ if (adoptionAgencyEndTag(name)) {
+ NS_HTML5_BREAK(endtagloop);
+ }
+ }
+ default: {
+ if (isCurrent(name)) {
+ pop();
+ NS_HTML5_BREAK(endtagloop);
+ }
+ eltPos = currentPtr;
+ for (; ; ) {
+ nsHtml5StackNode* node = stack[eltPos];
+ if (node->ns == kNameSpaceID_XHTML && node->name == name) {
+ generateImpliedEndTags();
+ if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
+ errUnclosedElements(eltPos, name);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ NS_HTML5_BREAK(endtagloop);
+ } else if (!eltPos || node->isSpecial()) {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ eltPos--;
+ }
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_HEAD: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HEAD: {
+ pop();
+ mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_BR:
+ case NS_HTML5TREE_BUILDER_HTML:
+ case NS_HTML5TREE_BUILDER_BODY: {
+ pop();
+ mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_TEMPLATE: {
+ endTagTemplateInHead();
+ NS_HTML5_BREAK(endtagloop);
+ }
+ default: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_NOSCRIPT: {
+ pop();
+ mode = NS_HTML5TREE_BUILDER_IN_HEAD;
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_BR: {
+ errStrayEndTag(name);
+ pop();
+ mode = NS_HTML5TREE_BUILDER_IN_HEAD;
+ continue;
+ }
+ default: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_COLGROUP: {
+ if (!currentPtr || stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) {
+ MOZ_ASSERT(fragment || isTemplateContents());
+ errGarbageInColgroup();
+ NS_HTML5_BREAK(endtagloop);
+ }
+ pop();
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_COL: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TEMPLATE: {
+ endTagTemplateInHead();
+ NS_HTML5_BREAK(endtagloop);
+ }
+ default: {
+ if (!currentPtr || stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) {
+ MOZ_ASSERT(fragment || isTemplateContents());
+ errGarbageInColgroup();
+ NS_HTML5_BREAK(endtagloop);
+ }
+ pop();
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_CAPTION:
+ case NS_HTML5TREE_BUILDER_TABLE:
+ case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+ case NS_HTML5TREE_BUILDER_TR:
+ case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+ errEndTagSeenWithSelectOpen(name);
+ if (findLastInTableScope(name) != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ eltPos = findLastInTableScope(nsHtml5Atoms::select);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ MOZ_ASSERT(fragment);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ resetTheInsertionMode();
+ continue;
+ } else {
+ NS_HTML5_BREAK(endtagloop);
+ }
+ }
+ default:
+ ; // fall through
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_SELECT: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_OPTION: {
+ if (isCurrent(nsHtml5Atoms::option)) {
+ pop();
+ NS_HTML5_BREAK(endtagloop);
+ } else {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ }
+ case NS_HTML5TREE_BUILDER_OPTGROUP: {
+ if (isCurrent(nsHtml5Atoms::option) && nsHtml5Atoms::optgroup == stack[currentPtr - 1]->name) {
+ pop();
+ }
+ if (isCurrent(nsHtml5Atoms::optgroup)) {
+ pop();
+ } else {
+ errStrayEndTag(name);
+ }
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_SELECT: {
+ eltPos = findLastInTableScope(nsHtml5Atoms::select);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ MOZ_ASSERT(fragment);
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ resetTheInsertionMode();
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TEMPLATE: {
+ endTagTemplateInHead();
+ NS_HTML5_BREAK(endtagloop);
+ }
+ default: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_BODY: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HTML: {
+ if (fragment) {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ } else {
+ mode = NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY;
+ NS_HTML5_BREAK(endtagloop);
+ }
+ }
+ default: {
+ errEndTagAfterBody();
+ mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
+ continue;
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_IN_FRAMESET: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_FRAMESET: {
+ if (!currentPtr) {
+ MOZ_ASSERT(fragment);
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ pop();
+ if ((!fragment) && !isCurrent(nsHtml5Atoms::frameset)) {
+ mode = NS_HTML5TREE_BUILDER_AFTER_FRAMESET;
+ }
+ NS_HTML5_BREAK(endtagloop);
+ }
+ default: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HTML: {
+ mode = NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET;
+ NS_HTML5_BREAK(endtagloop);
+ }
+ default: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_INITIAL: {
+ errEndTagSeenWithoutDoctype();
+ documentModeInternal(QUIRKS_MODE, nullptr, nullptr, false);
+ mode = NS_HTML5TREE_BUILDER_BEFORE_HTML;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_BEFORE_HTML: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HEAD:
+ case NS_HTML5TREE_BUILDER_BR:
+ case NS_HTML5TREE_BUILDER_HTML:
+ case NS_HTML5TREE_BUILDER_BODY: {
+ appendHtmlElementToDocumentAndPush();
+ mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD;
+ continue;
+ }
+ default: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_BEFORE_HEAD: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_HEAD:
+ case NS_HTML5TREE_BUILDER_BR:
+ case NS_HTML5TREE_BUILDER_HTML:
+ case NS_HTML5TREE_BUILDER_BODY: {
+ appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+ mode = NS_HTML5TREE_BUILDER_IN_HEAD;
+ continue;
+ }
+ default: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_HEAD: {
+ switch(group) {
+ case NS_HTML5TREE_BUILDER_TEMPLATE: {
+ endTagTemplateInHead();
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_HTML:
+ case NS_HTML5TREE_BUILDER_BODY:
+ case NS_HTML5TREE_BUILDER_BR: {
+ appendToCurrentNodeAndPushBodyElement();
+ mode = NS_HTML5TREE_BUILDER_FRAMESET_OK;
+ continue;
+ }
+ default: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ }
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY: {
+ errStrayEndTag(name);
+ mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
+ continue;
+ }
+ case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+ case NS_HTML5TREE_BUILDER_TEXT: {
+ pop();
+ if (originalMode == NS_HTML5TREE_BUILDER_AFTER_HEAD) {
+ silentPop();
+ }
+ mode = originalMode;
+ NS_HTML5_BREAK(endtagloop);
+ }
+ }
+ }
+ endtagloop_end: ;
+}
+
+void
+nsHtml5TreeBuilder::endTagTemplateInHead()
+{
+ int32_t eltPos = findLast(nsHtml5Atoms::template_);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ errStrayEndTag(nsHtml5Atoms::template_);
+ return;
+ }
+ generateImpliedEndTags();
+ if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(nsHtml5Atoms::template_)) {
+ errUnclosedElements(eltPos, nsHtml5Atoms::template_);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ popTemplateMode();
+ resetTheInsertionMode();
+}
+
+int32_t
+nsHtml5TreeBuilder::findLastInTableScopeOrRootTemplateTbodyTheadTfoot()
+{
+ for (int32_t i = currentPtr; i > 0; i--) {
+ if (stack[i]->getGroup() == NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT || stack[i]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) {
+ return i;
+ }
+ }
+ return 0;
+}
+
+int32_t
+nsHtml5TreeBuilder::findLast(nsIAtom* name)
+{
+ for (int32_t i = currentPtr; i > 0; i--) {
+ if (stack[i]->ns == kNameSpaceID_XHTML && stack[i]->name == name) {
+ return i;
+ }
+ }
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+}
+
+int32_t
+nsHtml5TreeBuilder::findLastInTableScope(nsIAtom* name)
+{
+ for (int32_t i = currentPtr; i > 0; i--) {
+ if (stack[i]->ns == kNameSpaceID_XHTML) {
+ if (stack[i]->name == name) {
+ return i;
+ } else if (stack[i]->name == nsHtml5Atoms::table || stack[i]->name == nsHtml5Atoms::template_) {
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+ }
+ }
+ }
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+}
+
+int32_t
+nsHtml5TreeBuilder::findLastInButtonScope(nsIAtom* name)
+{
+ for (int32_t i = currentPtr; i > 0; i--) {
+ if (stack[i]->ns == kNameSpaceID_XHTML) {
+ if (stack[i]->name == name) {
+ return i;
+ } else if (stack[i]->name == nsHtml5Atoms::button) {
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+ }
+ }
+ if (stack[i]->isScoping()) {
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+ }
+ }
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+}
+
+int32_t
+nsHtml5TreeBuilder::findLastInScope(nsIAtom* name)
+{
+ for (int32_t i = currentPtr; i > 0; i--) {
+ if (stack[i]->ns == kNameSpaceID_XHTML && stack[i]->name == name) {
+ return i;
+ } else if (stack[i]->isScoping()) {
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+ }
+ }
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+}
+
+int32_t
+nsHtml5TreeBuilder::findLastInListScope(nsIAtom* name)
+{
+ for (int32_t i = currentPtr; i > 0; i--) {
+ if (stack[i]->ns == kNameSpaceID_XHTML) {
+ if (stack[i]->name == name) {
+ return i;
+ } else if (stack[i]->name == nsHtml5Atoms::ul || stack[i]->name == nsHtml5Atoms::ol) {
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+ }
+ }
+ if (stack[i]->isScoping()) {
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+ }
+ }
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+}
+
+int32_t
+nsHtml5TreeBuilder::findLastInScopeHn()
+{
+ for (int32_t i = currentPtr; i > 0; i--) {
+ if (stack[i]->getGroup() == NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6) {
+ return i;
+ } else if (stack[i]->isScoping()) {
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+ }
+ }
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+}
+
+void
+nsHtml5TreeBuilder::generateImpliedEndTagsExceptFor(nsIAtom* name)
+{
+ for (; ; ) {
+ nsHtml5StackNode* node = stack[currentPtr];
+ switch(node->getGroup()) {
+ case NS_HTML5TREE_BUILDER_P:
+ case NS_HTML5TREE_BUILDER_LI:
+ case NS_HTML5TREE_BUILDER_DD_OR_DT:
+ case NS_HTML5TREE_BUILDER_OPTION:
+ case NS_HTML5TREE_BUILDER_OPTGROUP:
+ case NS_HTML5TREE_BUILDER_RB_OR_RTC:
+ case NS_HTML5TREE_BUILDER_RT_OR_RP: {
+ if (node->ns == kNameSpaceID_XHTML && node->name == name) {
+ return;
+ }
+ pop();
+ continue;
+ }
+ default: {
+ return;
+ }
+ }
+ }
+}
+
+void
+nsHtml5TreeBuilder::generateImpliedEndTags()
+{
+ for (; ; ) {
+ switch(stack[currentPtr]->getGroup()) {
+ case NS_HTML5TREE_BUILDER_P:
+ case NS_HTML5TREE_BUILDER_LI:
+ case NS_HTML5TREE_BUILDER_DD_OR_DT:
+ case NS_HTML5TREE_BUILDER_OPTION:
+ case NS_HTML5TREE_BUILDER_OPTGROUP:
+ case NS_HTML5TREE_BUILDER_RB_OR_RTC:
+ case NS_HTML5TREE_BUILDER_RT_OR_RP: {
+ pop();
+ continue;
+ }
+ default: {
+ return;
+ }
+ }
+ }
+}
+
+bool
+nsHtml5TreeBuilder::isSecondOnStackBody()
+{
+ return currentPtr >= 1 && stack[1]->getGroup() == NS_HTML5TREE_BUILDER_BODY;
+}
+
+void
+nsHtml5TreeBuilder::documentModeInternal(nsHtml5DocumentMode m, nsString* publicIdentifier, nsString* systemIdentifier, bool html4SpecificAdditionalErrorChecks)
+{
+ if (isSrcdocDocument) {
+ quirks = false;
+ this->documentMode(STANDARDS_MODE);
+ return;
+ }
+ quirks = (m == QUIRKS_MODE);
+ this->documentMode(m);
+}
+
+bool
+nsHtml5TreeBuilder::isAlmostStandards(nsString* publicIdentifier, nsString* systemIdentifier)
+{
+ if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd xhtml 1.0 transitional//en", publicIdentifier)) {
+ return true;
+ }
+ if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd xhtml 1.0 frameset//en", publicIdentifier)) {
+ return true;
+ }
+ if (systemIdentifier) {
+ if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd html 4.01 transitional//en", publicIdentifier)) {
+ return true;
+ }
+ if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd html 4.01 frameset//en", publicIdentifier)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
+nsHtml5TreeBuilder::isQuirky(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks)
+{
+ if (forceQuirks) {
+ return true;
+ }
+ if (name != nsHtml5Atoms::html) {
+ return true;
+ }
+ if (publicIdentifier) {
+ for (int32_t i = 0; i < nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS.length; i++) {
+ if (nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS[i], publicIdentifier)) {
+ return true;
+ }
+ }
+ if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3o//dtd w3 html strict 3.0//en//", publicIdentifier) || nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-/w3c/dtd html 4.0 transitional/en", publicIdentifier) || nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("html", publicIdentifier)) {
+ return true;
+ }
+ }
+ if (!systemIdentifier) {
+ if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd html 4.01 transitional//en", publicIdentifier)) {
+ return true;
+ } else if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd html 4.01 frameset//en", publicIdentifier)) {
+ return true;
+ }
+ } else if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd", systemIdentifier)) {
+ return true;
+ }
+ return false;
+}
+
+void
+nsHtml5TreeBuilder::closeTheCell(int32_t eltPos)
+{
+ generateImpliedEndTags();
+ if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) {
+ errUnclosedElementsCell(eltPos);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+ clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ mode = NS_HTML5TREE_BUILDER_IN_ROW;
+ return;
+}
+
+int32_t
+nsHtml5TreeBuilder::findLastInTableScopeTdTh()
+{
+ for (int32_t i = currentPtr; i > 0; i--) {
+ nsIAtom* name = stack[i]->name;
+ if (stack[i]->ns == kNameSpaceID_XHTML) {
+ if (nsHtml5Atoms::td == name || nsHtml5Atoms::th == name) {
+ return i;
+ } else if (name == nsHtml5Atoms::table || name == nsHtml5Atoms::template_) {
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+ }
+ }
+ }
+ return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+}
+
+void
+nsHtml5TreeBuilder::clearStackBackTo(int32_t eltPos)
+{
+ int32_t eltGroup = stack[eltPos]->getGroup();
+ while (currentPtr > eltPos) {
+ if (stack[currentPtr]->ns == kNameSpaceID_XHTML && stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE && (eltGroup == NS_HTML5TREE_BUILDER_TABLE || eltGroup == NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT || eltGroup == NS_HTML5TREE_BUILDER_TR || !eltPos)) {
+ return;
+ }
+ pop();
+ }
+}
+
+void
+nsHtml5TreeBuilder::resetTheInsertionMode()
+{
+ nsHtml5StackNode* node;
+ nsIAtom* name;
+ int32_t ns;
+ for (int32_t i = currentPtr; i >= 0; i--) {
+ node = stack[i];
+ name = node->name;
+ ns = node->ns;
+ if (!i) {
+ if (!(contextNamespace == kNameSpaceID_XHTML && (contextName == nsHtml5Atoms::td || contextName == nsHtml5Atoms::th))) {
+ if (fragment) {
+ name = contextName;
+ ns = contextNamespace;
+ }
+ } else {
+ mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
+ return;
+ }
+ }
+ if (nsHtml5Atoms::select == name) {
+ int32_t ancestorIndex = i;
+ while (ancestorIndex > 0) {
+ nsHtml5StackNode* ancestor = stack[ancestorIndex--];
+ if (kNameSpaceID_XHTML == ancestor->ns) {
+ if (nsHtml5Atoms::template_ == ancestor->name) {
+ break;
+ }
+ if (nsHtml5Atoms::table == ancestor->name) {
+ mode = NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE;
+ return;
+ }
+ }
+ }
+ mode = NS_HTML5TREE_BUILDER_IN_SELECT;
+ return;
+ } else if (nsHtml5Atoms::td == name || nsHtml5Atoms::th == name) {
+ mode = NS_HTML5TREE_BUILDER_IN_CELL;
+ return;
+ } else if (nsHtml5Atoms::tr == name) {
+ mode = NS_HTML5TREE_BUILDER_IN_ROW;
+ return;
+ } else if (nsHtml5Atoms::tbody == name || nsHtml5Atoms::thead == name || nsHtml5Atoms::tfoot == name) {
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
+ return;
+ } else if (nsHtml5Atoms::caption == name) {
+ mode = NS_HTML5TREE_BUILDER_IN_CAPTION;
+ return;
+ } else if (nsHtml5Atoms::colgroup == name) {
+ mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP;
+ return;
+ } else if (nsHtml5Atoms::table == name) {
+ mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+ return;
+ } else if (kNameSpaceID_XHTML != ns) {
+ mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
+ return;
+ } else if (nsHtml5Atoms::template_ == name) {
+ MOZ_ASSERT(templateModePtr >= 0);
+ mode = templateModeStack[templateModePtr];
+ return;
+ } else if (nsHtml5Atoms::head == name) {
+ if (name == contextName) {
+ mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
+ } else {
+ mode = NS_HTML5TREE_BUILDER_IN_HEAD;
+ }
+ return;
+ } else if (nsHtml5Atoms::body == name) {
+ mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
+ return;
+ } else if (nsHtml5Atoms::frameset == name) {
+ mode = NS_HTML5TREE_BUILDER_IN_FRAMESET;
+ return;
+ } else if (nsHtml5Atoms::html == name) {
+ if (!headPointer) {
+ mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD;
+ } else {
+ mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
+ }
+ return;
+ } else if (!i) {
+ mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
+ return;
+ }
+ }
+}
+
+void
+nsHtml5TreeBuilder::implicitlyCloseP()
+{
+ int32_t eltPos = findLastInButtonScope(nsHtml5Atoms::p);
+ if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+ return;
+ }
+ generateImpliedEndTagsExceptFor(nsHtml5Atoms::p);
+ if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) {
+ errUnclosedElementsImplied(eltPos, nsHtml5Atoms::p);
+ }
+ while (currentPtr >= eltPos) {
+ pop();
+ }
+}
+
+bool
+nsHtml5TreeBuilder::debugOnlyClearLastStackSlot()
+{
+ stack[currentPtr] = nullptr;
+ return true;
+}
+
+bool
+nsHtml5TreeBuilder::debugOnlyClearLastListSlot()
+{
+ listOfActiveFormattingElements[listPtr] = nullptr;
+ return true;
+}
+
+void
+nsHtml5TreeBuilder::pushTemplateMode(int32_t mode)
+{
+ templateModePtr++;
+ if (templateModePtr == templateModeStack.length) {
+ jArray<int32_t,int32_t> newStack = jArray<int32_t,int32_t>::newJArray(templateModeStack.length + 64);
+ nsHtml5ArrayCopy::arraycopy(templateModeStack, newStack, templateModeStack.length);
+ templateModeStack = newStack;
+ }
+ templateModeStack[templateModePtr] = mode;
+}
+
+void
+nsHtml5TreeBuilder::push(nsHtml5StackNode* node)
+{
+ currentPtr++;
+ if (currentPtr == stack.length) {
+ jArray<nsHtml5StackNode*,int32_t> newStack = jArray<nsHtml5StackNode*,int32_t>::newJArray(stack.length + 64);
+ nsHtml5ArrayCopy::arraycopy(stack, newStack, stack.length);
+ stack = newStack;
+ }
+ stack[currentPtr] = node;
+ elementPushed(node->ns, node->popName, node->node);
+}
+
+void
+nsHtml5TreeBuilder::silentPush(nsHtml5StackNode* node)
+{
+ currentPtr++;
+ if (currentPtr == stack.length) {
+ jArray<nsHtml5StackNode*,int32_t> newStack = jArray<nsHtml5StackNode*,int32_t>::newJArray(stack.length + 64);
+ nsHtml5ArrayCopy::arraycopy(stack, newStack, stack.length);
+ stack = newStack;
+ }
+ stack[currentPtr] = node;
+}
+
+void
+nsHtml5TreeBuilder::append(nsHtml5StackNode* node)
+{
+ listPtr++;
+ if (listPtr == listOfActiveFormattingElements.length) {
+ jArray<nsHtml5StackNode*,int32_t> newList = jArray<nsHtml5StackNode*,int32_t>::newJArray(listOfActiveFormattingElements.length + 64);
+ nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements, newList, listOfActiveFormattingElements.length);
+ listOfActiveFormattingElements = newList;
+ }
+ listOfActiveFormattingElements[listPtr] = node;
+}
+
+void
+nsHtml5TreeBuilder::clearTheListOfActiveFormattingElementsUpToTheLastMarker()
+{
+ while (listPtr > -1) {
+ if (!listOfActiveFormattingElements[listPtr]) {
+ --listPtr;
+ return;
+ }
+ listOfActiveFormattingElements[listPtr]->release();
+ --listPtr;
+ }
+}
+
+void
+nsHtml5TreeBuilder::removeFromStack(int32_t pos)
+{
+ if (currentPtr == pos) {
+ pop();
+ } else {
+
+ stack[pos]->release();
+ nsHtml5ArrayCopy::arraycopy(stack, pos + 1, pos, currentPtr - pos);
+ MOZ_ASSERT(debugOnlyClearLastStackSlot());
+ currentPtr--;
+ }
+}
+
+void
+nsHtml5TreeBuilder::removeFromStack(nsHtml5StackNode* node)
+{
+ if (stack[currentPtr] == node) {
+ pop();
+ } else {
+ int32_t pos = currentPtr - 1;
+ while (pos >= 0 && stack[pos] != node) {
+ pos--;
+ }
+ if (pos == -1) {
+ return;
+ }
+
+ node->release();
+ nsHtml5ArrayCopy::arraycopy(stack, pos + 1, pos, currentPtr - pos);
+ currentPtr--;
+ }
+}
+
+void
+nsHtml5TreeBuilder::removeFromListOfActiveFormattingElements(int32_t pos)
+{
+ MOZ_ASSERT(!!listOfActiveFormattingElements[pos]);
+ listOfActiveFormattingElements[pos]->release();
+ if (pos == listPtr) {
+ MOZ_ASSERT(debugOnlyClearLastListSlot());
+ listPtr--;
+ return;
+ }
+ MOZ_ASSERT(pos < listPtr);
+ nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements, pos + 1, pos, listPtr - pos);
+ MOZ_ASSERT(debugOnlyClearLastListSlot());
+ listPtr--;
+}
+
+bool
+nsHtml5TreeBuilder::adoptionAgencyEndTag(nsIAtom* name)
+{
+ if (stack[currentPtr]->ns == kNameSpaceID_XHTML && stack[currentPtr]->name == name && findInListOfActiveFormattingElements(stack[currentPtr]) == -1) {
+ pop();
+ return true;
+ }
+ for (int32_t i = 0; i < 8; ++i) {
+ int32_t formattingEltListPos = listPtr;
+ while (formattingEltListPos > -1) {
+ nsHtml5StackNode* listNode = listOfActiveFormattingElements[formattingEltListPos];
+ if (!listNode) {
+ formattingEltListPos = -1;
+ break;
+ } else if (listNode->name == name) {
+ break;
+ }
+ formattingEltListPos--;
+ }
+ if (formattingEltListPos == -1) {
+ return false;
+ }
+ nsHtml5StackNode* formattingElt = listOfActiveFormattingElements[formattingEltListPos];
+ int32_t formattingEltStackPos = currentPtr;
+ bool inScope = true;
+ while (formattingEltStackPos > -1) {
+ nsHtml5StackNode* node = stack[formattingEltStackPos];
+ if (node == formattingElt) {
+ break;
+ } else if (node->isScoping()) {
+ inScope = false;
+ }
+ formattingEltStackPos--;
+ }
+ if (formattingEltStackPos == -1) {
+ errNoElementToCloseButEndTagSeen(name);
+ removeFromListOfActiveFormattingElements(formattingEltListPos);
+ return true;
+ }
+ if (!inScope) {
+ errNoElementToCloseButEndTagSeen(name);
+ return true;
+ }
+ if (formattingEltStackPos != currentPtr) {
+ errEndTagViolatesNestingRules(name);
+ }
+ int32_t furthestBlockPos = formattingEltStackPos + 1;
+ while (furthestBlockPos <= currentPtr) {
+ nsHtml5StackNode* node = stack[furthestBlockPos];
+ MOZ_ASSERT(furthestBlockPos > 0, "How is formattingEltStackPos + 1 not > 0?");
+ if (node->isSpecial()) {
+ break;
+ }
+ furthestBlockPos++;
+ }
+ if (furthestBlockPos > currentPtr) {
+ while (currentPtr >= formattingEltStackPos) {
+ pop();
+ }
+ removeFromListOfActiveFormattingElements(formattingEltListPos);
+ return true;
+ }
+ nsHtml5StackNode* commonAncestor = stack[formattingEltStackPos - 1];
+ nsHtml5StackNode* furthestBlock = stack[furthestBlockPos];
+ int32_t bookmark = formattingEltListPos;
+ int32_t nodePos = furthestBlockPos;
+ nsHtml5StackNode* lastNode = furthestBlock;
+ int32_t j = 0;
+ for (; ; ) {
+ ++j;
+ nodePos--;
+ if (nodePos == formattingEltStackPos) {
+ break;
+ }
+ nsHtml5StackNode* node = stack[nodePos];
+ int32_t nodeListPos = findInListOfActiveFormattingElements(node);
+ if (j > 3 && nodeListPos != -1) {
+ removeFromListOfActiveFormattingElements(nodeListPos);
+ if (nodeListPos <= formattingEltListPos) {
+ formattingEltListPos--;
+ }
+ if (nodeListPos <= bookmark) {
+ bookmark--;
+ }
+ nodeListPos = -1;
+ }
+ if (nodeListPos == -1) {
+ MOZ_ASSERT(formattingEltStackPos < nodePos);
+ MOZ_ASSERT(bookmark < nodePos);
+ MOZ_ASSERT(furthestBlockPos > nodePos);
+ removeFromStack(nodePos);
+ furthestBlockPos--;
+ continue;
+ }
+ if (nodePos == furthestBlockPos) {
+ bookmark = nodeListPos + 1;
+ }
+ MOZ_ASSERT(node == listOfActiveFormattingElements[nodeListPos]);
+ MOZ_ASSERT(node == stack[nodePos]);
+ nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, node->name, node->attributes->cloneAttributes(nullptr), commonAncestor->node);
+ nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, node->name, clone, node->popName, node->attributes);
+ node->dropAttributes();
+ stack[nodePos] = newNode;
+ newNode->retain();
+ listOfActiveFormattingElements[nodeListPos] = newNode;
+ node->release();
+ node->release();
+ node = newNode;
+ detachFromParent(lastNode->node);
+ appendElement(lastNode->node, node->node);
+ lastNode = node;
+ }
+ if (commonAncestor->isFosterParenting()) {
+
+ detachFromParent(lastNode->node);
+ insertIntoFosterParent(lastNode->node);
+ } else {
+ detachFromParent(lastNode->node);
+ appendElement(lastNode->node, commonAncestor->node);
+ }
+ nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, formattingElt->name, formattingElt->attributes->cloneAttributes(nullptr), furthestBlock->node);
+ nsHtml5StackNode* formattingClone = new nsHtml5StackNode(formattingElt->getFlags(), formattingElt->ns, formattingElt->name, clone, formattingElt->popName, formattingElt->attributes);
+ formattingElt->dropAttributes();
+ appendChildrenToNewParent(furthestBlock->node, clone);
+ appendElement(clone, furthestBlock->node);
+ removeFromListOfActiveFormattingElements(formattingEltListPos);
+ insertIntoListOfActiveFormattingElements(formattingClone, bookmark);
+ MOZ_ASSERT(formattingEltStackPos < furthestBlockPos);
+ removeFromStack(formattingEltStackPos);
+ insertIntoStack(formattingClone, furthestBlockPos);
+ }
+ return true;
+}
+
+void
+nsHtml5TreeBuilder::insertIntoStack(nsHtml5StackNode* node, int32_t position)
+{
+ MOZ_ASSERT(currentPtr + 1 < stack.length);
+ MOZ_ASSERT(position <= currentPtr + 1);
+ if (position == currentPtr + 1) {
+ push(node);
+ } else {
+ nsHtml5ArrayCopy::arraycopy(stack, position, position + 1, (currentPtr - position) + 1);
+ currentPtr++;
+ stack[position] = node;
+ }
+}
+
+void
+nsHtml5TreeBuilder::insertIntoListOfActiveFormattingElements(nsHtml5StackNode* formattingClone, int32_t bookmark)
+{
+ formattingClone->retain();
+ MOZ_ASSERT(listPtr + 1 < listOfActiveFormattingElements.length);
+ if (bookmark <= listPtr) {
+ nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements, bookmark, bookmark + 1, (listPtr - bookmark) + 1);
+ }
+ listPtr++;
+ listOfActiveFormattingElements[bookmark] = formattingClone;
+}
+
+int32_t
+nsHtml5TreeBuilder::findInListOfActiveFormattingElements(nsHtml5StackNode* node)
+{
+ for (int32_t i = listPtr; i >= 0; i--) {
+ if (node == listOfActiveFormattingElements[i]) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+int32_t
+nsHtml5TreeBuilder::findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(nsIAtom* name)
+{
+ for (int32_t i = listPtr; i >= 0; i--) {
+ nsHtml5StackNode* node = listOfActiveFormattingElements[i];
+ if (!node) {
+ return -1;
+ } else if (node->name == name) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+void
+nsHtml5TreeBuilder::maybeForgetEarlierDuplicateFormattingElement(nsIAtom* name, nsHtml5HtmlAttributes* attributes)
+{
+ int32_t candidate = -1;
+ int32_t count = 0;
+ for (int32_t i = listPtr; i >= 0; i--) {
+ nsHtml5StackNode* node = listOfActiveFormattingElements[i];
+ if (!node) {
+ break;
+ }
+ if (node->name == name && node->attributes->equalsAnother(attributes)) {
+ candidate = i;
+ ++count;
+ }
+ }
+ if (count >= 3) {
+ removeFromListOfActiveFormattingElements(candidate);
+ }
+}
+
+int32_t
+nsHtml5TreeBuilder::findLastOrRoot(nsIAtom* name)
+{
+ for (int32_t i = currentPtr; i > 0; i--) {
+ if (stack[i]->ns == kNameSpaceID_XHTML && stack[i]->name == name) {
+ return i;
+ }
+ }
+ return 0;
+}
+
+int32_t
+nsHtml5TreeBuilder::findLastOrRoot(int32_t group)
+{
+ for (int32_t i = currentPtr; i > 0; i--) {
+ if (stack[i]->getGroup() == group) {
+ return i;
+ }
+ }
+ return 0;
+}
+
+bool
+nsHtml5TreeBuilder::addAttributesToBody(nsHtml5HtmlAttributes* attributes)
+{
+ if (currentPtr >= 1) {
+ nsHtml5StackNode* body = stack[1];
+ if (body->getGroup() == NS_HTML5TREE_BUILDER_BODY) {
+ addAttributesToElement(body->node, attributes);
+ return true;
+ }
+ }
+ return false;
+}
+
+void
+nsHtml5TreeBuilder::addAttributesToHtml(nsHtml5HtmlAttributes* attributes)
+{
+ addAttributesToElement(stack[0]->node, attributes);
+}
+
+void
+nsHtml5TreeBuilder::pushHeadPointerOntoStack()
+{
+ MOZ_ASSERT(!!headPointer);
+ MOZ_ASSERT(mode == NS_HTML5TREE_BUILDER_AFTER_HEAD);
+
+ silentPush(new nsHtml5StackNode(nsHtml5ElementName::ELT_HEAD, headPointer));
+}
+
+void
+nsHtml5TreeBuilder::reconstructTheActiveFormattingElements()
+{
+ if (listPtr == -1) {
+ return;
+ }
+ nsHtml5StackNode* mostRecent = listOfActiveFormattingElements[listPtr];
+ if (!mostRecent || isInStack(mostRecent)) {
+ return;
+ }
+ int32_t entryPos = listPtr;
+ for (; ; ) {
+ entryPos--;
+ if (entryPos == -1) {
+ break;
+ }
+ if (!listOfActiveFormattingElements[entryPos]) {
+ break;
+ }
+ if (isInStack(listOfActiveFormattingElements[entryPos])) {
+ break;
+ }
+ }
+ while (entryPos < listPtr) {
+ entryPos++;
+ nsHtml5StackNode* entry = listOfActiveFormattingElements[entryPos];
+ nsHtml5StackNode* currentNode = stack[currentPtr];
+ nsIContentHandle* clone;
+ if (currentNode->isFosterParenting()) {
+ clone = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, entry->name, entry->attributes->cloneAttributes(nullptr));
+ } else {
+ clone = createElement(kNameSpaceID_XHTML, entry->name, entry->attributes->cloneAttributes(nullptr), currentNode->node);
+ appendElement(clone, currentNode->node);
+ }
+ nsHtml5StackNode* entryClone = new nsHtml5StackNode(entry->getFlags(), entry->ns, entry->name, clone, entry->popName, entry->attributes);
+ entry->dropAttributes();
+ push(entryClone);
+ listOfActiveFormattingElements[entryPos] = entryClone;
+ entry->release();
+ entryClone->retain();
+ }
+}
+
+void
+nsHtml5TreeBuilder::insertIntoFosterParent(nsIContentHandle* child)
+{
+ int32_t tablePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE);
+ int32_t templatePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TEMPLATE);
+ if (templatePos >= tablePos) {
+ appendElement(child, stack[templatePos]->node);
+ return;
+ }
+ nsHtml5StackNode* node = stack[tablePos];
+ insertFosterParentedChild(child, node->node, stack[tablePos - 1]->node);
+}
+
+nsIContentHandle*
+nsHtml5TreeBuilder::createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes)
+{
+ return createAndInsertFosterParentedElement(ns, name, attributes, nullptr);
+}
+
+nsIContentHandle*
+nsHtml5TreeBuilder::createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
+{
+ int32_t tablePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE);
+ int32_t templatePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TEMPLATE);
+ if (templatePos >= tablePos) {
+ nsIContentHandle* child = createElement(ns, name, attributes, form, stack[templatePos]->node);
+ appendElement(child, stack[templatePos]->node);
+ return child;
+ }
+ nsHtml5StackNode* node = stack[tablePos];
+ return createAndInsertFosterParentedElement(ns, name, attributes, form, node->node, stack[tablePos - 1]->node);
+}
+
+bool
+nsHtml5TreeBuilder::isInStack(nsHtml5StackNode* node)
+{
+ for (int32_t i = currentPtr; i >= 0; i--) {
+ if (stack[i] == node) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void
+nsHtml5TreeBuilder::popTemplateMode()
+{
+ templateModePtr--;
+}
+
+void
+nsHtml5TreeBuilder::pop()
+{
+ nsHtml5StackNode* node = stack[currentPtr];
+ MOZ_ASSERT(debugOnlyClearLastStackSlot());
+ currentPtr--;
+ elementPopped(node->ns, node->popName, node->node);
+ node->release();
+}
+
+void
+nsHtml5TreeBuilder::silentPop()
+{
+ nsHtml5StackNode* node = stack[currentPtr];
+ MOZ_ASSERT(debugOnlyClearLastStackSlot());
+ currentPtr--;
+ node->release();
+}
+
+void
+nsHtml5TreeBuilder::popOnEof()
+{
+ nsHtml5StackNode* node = stack[currentPtr];
+ MOZ_ASSERT(debugOnlyClearLastStackSlot());
+ currentPtr--;
+ markMalformedIfScript(node->node);
+ elementPopped(node->ns, node->popName, node->node);
+ node->release();
+}
+
+void
+nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush(nsHtml5HtmlAttributes* attributes)
+{
+ nsIContentHandle* elt = createHtmlElementSetAsRoot(attributes);
+ nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_HTML, elt);
+ push(node);
+}
+
+void
+nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush()
+{
+ appendHtmlElementToDocumentAndPush(tokenizer->emptyAttributes());
+}
+
+void
+nsHtml5TreeBuilder::appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes* attributes)
+{
+ nsIContentHandle* currentNode = stack[currentPtr]->node;
+ nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::head, attributes, currentNode);
+ appendElement(elt, currentNode);
+ headPointer = elt;
+ nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_HEAD, elt);
+ push(node);
+}
+
+void
+nsHtml5TreeBuilder::appendToCurrentNodeAndPushBodyElement(nsHtml5HtmlAttributes* attributes)
+{
+ appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_BODY, attributes);
+}
+
+void
+nsHtml5TreeBuilder::appendToCurrentNodeAndPushBodyElement()
+{
+ appendToCurrentNodeAndPushBodyElement(tokenizer->emptyAttributes());
+}
+
+void
+nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormElementMayFoster(nsHtml5HtmlAttributes* attributes)
+{
+ nsIContentHandle* elt;
+ nsHtml5StackNode* current = stack[currentPtr];
+ if (current->isFosterParenting()) {
+
+ elt = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes);
+ } else {
+ elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes, current->node);
+ appendElement(elt, current->node);
+ }
+ if (!isTemplateContents()) {
+ formPointer = elt;
+ }
+ nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_FORM, elt);
+ push(node);
+}
+
+void
+nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormattingElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
+{
+ nsHtml5HtmlAttributes* clone = attributes->cloneAttributes(nullptr);
+ nsIContentHandle* elt;
+ nsHtml5StackNode* current = stack[currentPtr];
+ if (current->isFosterParenting()) {
+
+ elt = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, elementName->name, attributes);
+ } else {
+ elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes, current->node);
+ appendElement(elt, current->node);
+ }
+ nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, clone);
+ push(node);
+ append(node);
+ node->retain();
+}
+
+void
+nsHtml5TreeBuilder::appendToCurrentNodeAndPushElement(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
+{
+ nsIContentHandle* currentNode = stack[currentPtr]->node;
+ nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes, currentNode);
+ appendElement(elt, currentNode);
+ if (nsHtml5ElementName::ELT_TEMPLATE == elementName) {
+ elt = getDocumentFragmentForTemplate(elt);
+ }
+ nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt);
+ push(node);
+}
+
+void
+nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
+{
+ nsIAtom* popName = elementName->name;
+ nsIContentHandle* elt;
+ nsHtml5StackNode* current = stack[currentPtr];
+ if (current->isFosterParenting()) {
+
+ elt = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, popName, attributes);
+ } else {
+ elt = createElement(kNameSpaceID_XHTML, popName, attributes, current->node);
+ appendElement(elt, current->node);
+ }
+ nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, popName);
+ push(node);
+}
+
+void
+nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterMathML(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
+{
+ nsIAtom* popName = elementName->name;
+ bool markAsHtmlIntegrationPoint = false;
+ if (nsHtml5ElementName::ELT_ANNOTATION_XML == elementName && annotationXmlEncodingPermitsHtml(attributes)) {
+ markAsHtmlIntegrationPoint = true;
+ }
+ nsIContentHandle* elt;
+ nsHtml5StackNode* current = stack[currentPtr];
+ if (current->isFosterParenting()) {
+
+ elt = createAndInsertFosterParentedElement(kNameSpaceID_MathML, popName, attributes);
+ } else {
+ elt = createElement(kNameSpaceID_MathML, popName, attributes, current->node);
+ appendElement(elt, current->node);
+ }
+ nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, popName, markAsHtmlIntegrationPoint);
+ push(node);
+}
+
+bool
+nsHtml5TreeBuilder::annotationXmlEncodingPermitsHtml(nsHtml5HtmlAttributes* attributes)
+{
+ nsString* encoding = attributes->getValue(nsHtml5AttributeName::ATTR_ENCODING);
+ if (!encoding) {
+ return false;
+ }
+ return nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("application/xhtml+xml", encoding) || nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("text/html", encoding);
+}
+
+void
+nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
+{
+ nsIAtom* popName = elementName->camelCaseName;
+ nsIContentHandle* elt;
+ nsHtml5StackNode* current = stack[currentPtr];
+ if (current->isFosterParenting()) {
+
+ elt = createAndInsertFosterParentedElement(kNameSpaceID_SVG, popName, attributes);
+ } else {
+ elt = createElement(kNameSpaceID_SVG, popName, attributes, current->node);
+ appendElement(elt, current->node);
+ }
+ nsHtml5StackNode* node = new nsHtml5StackNode(elementName, popName, elt);
+ push(node);
+}
+
+void
+nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
+{
+ nsIContentHandle* elt;
+ nsIContentHandle* formOwner = !form || fragment || isTemplateContents() ? nullptr : form;
+ nsHtml5StackNode* current = stack[currentPtr];
+ if (current->isFosterParenting()) {
+
+ elt = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, elementName->name, attributes, formOwner);
+ } else {
+ elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes, formOwner, current->node);
+ appendElement(elt, current->node);
+ }
+ nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt);
+ push(node);
+}
+
+void
+nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
+{
+ nsIContentHandle* elt;
+ nsIContentHandle* formOwner = !form || fragment || isTemplateContents() ? nullptr : form;
+ nsHtml5StackNode* current = stack[currentPtr];
+ if (current->isFosterParenting()) {
+
+ elt = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, name, attributes, formOwner);
+ } else {
+ elt = createElement(kNameSpaceID_XHTML, name, attributes, formOwner, current->node);
+ appendElement(elt, current->node);
+ }
+ elementPushed(kNameSpaceID_XHTML, name, elt);
+ elementPopped(kNameSpaceID_XHTML, name, elt);
+}
+
+void
+nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
+{
+ nsIAtom* popName = elementName->name;
+ nsIContentHandle* elt;
+ nsHtml5StackNode* current = stack[currentPtr];
+ if (current->isFosterParenting()) {
+
+ elt = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, popName, attributes);
+ } else {
+ elt = createElement(kNameSpaceID_XHTML, popName, attributes, current->node);
+ appendElement(elt, current->node);
+ }
+ elementPushed(kNameSpaceID_XHTML, popName, elt);
+ elementPopped(kNameSpaceID_XHTML, popName, elt);
+}
+
+void
+nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
+{
+ nsIAtom* popName = elementName->camelCaseName;
+ nsIContentHandle* elt;
+ nsHtml5StackNode* current = stack[currentPtr];
+ if (current->isFosterParenting()) {
+
+ elt = createAndInsertFosterParentedElement(kNameSpaceID_SVG, popName, attributes);
+ } else {
+ elt = createElement(kNameSpaceID_SVG, popName, attributes, current->node);
+ appendElement(elt, current->node);
+ }
+ elementPushed(kNameSpaceID_SVG, popName, elt);
+ elementPopped(kNameSpaceID_SVG, popName, elt);
+}
+
+void
+nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterMathML(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
+{
+ nsIAtom* popName = elementName->name;
+ nsIContentHandle* elt;
+ nsHtml5StackNode* current = stack[currentPtr];
+ if (current->isFosterParenting()) {
+
+ elt = createAndInsertFosterParentedElement(kNameSpaceID_MathML, popName, attributes);
+ } else {
+ elt = createElement(kNameSpaceID_MathML, popName, attributes, current->node);
+ appendElement(elt, current->node);
+ }
+ elementPushed(kNameSpaceID_MathML, popName, elt);
+ elementPopped(kNameSpaceID_MathML, popName, elt);
+}
+
+void
+nsHtml5TreeBuilder::appendVoidElementToCurrent(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
+{
+ nsIContentHandle* currentNode = stack[currentPtr]->node;
+ nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, name, attributes, !form || fragment || isTemplateContents() ? nullptr : form, currentNode);
+ appendElement(elt, currentNode);
+ elementPushed(kNameSpaceID_XHTML, name, elt);
+ elementPopped(kNameSpaceID_XHTML, name, elt);
+}
+
+void
+nsHtml5TreeBuilder::appendVoidFormToCurrent(nsHtml5HtmlAttributes* attributes)
+{
+ nsIContentHandle* currentNode = stack[currentPtr]->node;
+ nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes, currentNode);
+ formPointer = elt;
+ appendElement(elt, currentNode);
+ elementPushed(kNameSpaceID_XHTML, nsHtml5Atoms::form, elt);
+ elementPopped(kNameSpaceID_XHTML, nsHtml5Atoms::form, elt);
+}
+
+void
+nsHtml5TreeBuilder::requestSuspension()
+{
+ tokenizer->requestSuspension();
+}
+
+;bool
+nsHtml5TreeBuilder::isInForeign()
+{
+ return currentPtr >= 0 && stack[currentPtr]->ns != kNameSpaceID_XHTML;
+}
+
+bool
+nsHtml5TreeBuilder::isInForeignButNotHtmlOrMathTextIntegrationPoint()
+{
+ if (currentPtr < 0) {
+ return false;
+ }
+ return !isSpecialParentInForeign(stack[currentPtr]);
+}
+
+void
+nsHtml5TreeBuilder::setFragmentContext(nsIAtom* context, int32_t ns, nsIContentHandle* node, bool quirks)
+{
+ this->contextName = context;
+ this->contextNamespace = ns;
+ this->contextNode = node;
+ this->fragment = (!!contextName);
+ this->quirks = quirks;
+}
+
+nsIContentHandle*
+nsHtml5TreeBuilder::currentNode()
+{
+ return stack[currentPtr]->node;
+}
+
+bool
+nsHtml5TreeBuilder::isScriptingEnabled()
+{
+ return scriptingEnabled;
+}
+
+void
+nsHtml5TreeBuilder::setScriptingEnabled(bool scriptingEnabled)
+{
+ this->scriptingEnabled = scriptingEnabled;
+}
+
+void
+nsHtml5TreeBuilder::setIsSrcdocDocument(bool isSrcdocDocument)
+{
+ this->isSrcdocDocument = isSrcdocDocument;
+}
+
+void
+nsHtml5TreeBuilder::flushCharacters()
+{
+ if (charBufferLen > 0) {
+ if ((mode == NS_HTML5TREE_BUILDER_IN_TABLE || mode == NS_HTML5TREE_BUILDER_IN_TABLE_BODY || mode == NS_HTML5TREE_BUILDER_IN_ROW) && charBufferContainsNonWhitespace()) {
+ errNonSpaceInTable();
+ reconstructTheActiveFormattingElements();
+ if (!stack[currentPtr]->isFosterParenting()) {
+ appendCharacters(currentNode(), charBuffer, 0, charBufferLen);
+ charBufferLen = 0;
+ return;
+ }
+ int32_t tablePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE);
+ int32_t templatePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TEMPLATE);
+ if (templatePos >= tablePos) {
+ appendCharacters(stack[templatePos]->node, charBuffer, 0, charBufferLen);
+ charBufferLen = 0;
+ return;
+ }
+ nsHtml5StackNode* tableElt = stack[tablePos];
+ insertFosterParentedCharacters(charBuffer, 0, charBufferLen, tableElt->node, stack[tablePos - 1]->node);
+ charBufferLen = 0;
+ return;
+ }
+ appendCharacters(currentNode(), charBuffer, 0, charBufferLen);
+ charBufferLen = 0;
+ }
+}
+
+bool
+nsHtml5TreeBuilder::charBufferContainsNonWhitespace()
+{
+ for (int32_t i = 0; i < charBufferLen; i++) {
+ switch(charBuffer[i]) {
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ case '\f': {
+ continue;
+ }
+ default: {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+nsAHtml5TreeBuilderState*
+nsHtml5TreeBuilder::newSnapshot()
+{
+ jArray<nsHtml5StackNode*,int32_t> listCopy = jArray<nsHtml5StackNode*,int32_t>::newJArray(listPtr + 1);
+ for (int32_t i = 0; i < listCopy.length; i++) {
+ nsHtml5StackNode* node = listOfActiveFormattingElements[i];
+ if (node) {
+ nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, node->name, node->node, node->popName, node->attributes->cloneAttributes(nullptr));
+ listCopy[i] = newNode;
+ } else {
+ listCopy[i] = nullptr;
+ }
+ }
+ jArray<nsHtml5StackNode*,int32_t> stackCopy = jArray<nsHtml5StackNode*,int32_t>::newJArray(currentPtr + 1);
+ for (int32_t i = 0; i < stackCopy.length; i++) {
+ nsHtml5StackNode* node = stack[i];
+ int32_t listIndex = findInListOfActiveFormattingElements(node);
+ if (listIndex == -1) {
+ nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, node->name, node->node, node->popName, nullptr);
+ stackCopy[i] = newNode;
+ } else {
+ stackCopy[i] = listCopy[listIndex];
+ stackCopy[i]->retain();
+ }
+ }
+ jArray<int32_t,int32_t> templateModeStackCopy = jArray<int32_t,int32_t>::newJArray(templateModePtr + 1);
+ nsHtml5ArrayCopy::arraycopy(templateModeStack, templateModeStackCopy, templateModeStackCopy.length);
+ return new nsHtml5StateSnapshot(stackCopy, listCopy, templateModeStackCopy, formPointer, headPointer, deepTreeSurrogateParent, mode, originalMode, framesetOk, needToDropLF, quirks);
+}
+
+bool
+nsHtml5TreeBuilder::snapshotMatches(nsAHtml5TreeBuilderState* snapshot)
+{
+ jArray<nsHtml5StackNode*,int32_t> stackCopy = snapshot->getStack();
+ int32_t stackLen = snapshot->getStackLength();
+ jArray<nsHtml5StackNode*,int32_t> listCopy = snapshot->getListOfActiveFormattingElements();
+ int32_t listLen = snapshot->getListOfActiveFormattingElementsLength();
+ jArray<int32_t,int32_t> templateModeStackCopy = snapshot->getTemplateModeStack();
+ int32_t templateModeStackLen = snapshot->getTemplateModeStackLength();
+ if (stackLen != currentPtr + 1 || listLen != listPtr + 1 || templateModeStackLen != templateModePtr + 1 || formPointer != snapshot->getFormPointer() || headPointer != snapshot->getHeadPointer() || deepTreeSurrogateParent != snapshot->getDeepTreeSurrogateParent() || mode != snapshot->getMode() || originalMode != snapshot->getOriginalMode() || framesetOk != snapshot->isFramesetOk() || needToDropLF != snapshot->isNeedToDropLF() || quirks != snapshot->isQuirks()) {
+ return false;
+ }
+ for (int32_t i = listLen - 1; i >= 0; i--) {
+ if (!listCopy[i] && !listOfActiveFormattingElements[i]) {
+ continue;
+ } else if (!listCopy[i] || !listOfActiveFormattingElements[i]) {
+ return false;
+ }
+ if (listCopy[i]->node != listOfActiveFormattingElements[i]->node) {
+ return false;
+ }
+ }
+ for (int32_t i = stackLen - 1; i >= 0; i--) {
+ if (stackCopy[i]->node != stack[i]->node) {
+ return false;
+ }
+ }
+ for (int32_t i = templateModeStackLen - 1; i >= 0; i--) {
+ if (templateModeStackCopy[i] != templateModeStack[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void
+nsHtml5TreeBuilder::loadState(nsAHtml5TreeBuilderState* snapshot, nsHtml5AtomTable* interner)
+{
+ jArray<nsHtml5StackNode*,int32_t> stackCopy = snapshot->getStack();
+ int32_t stackLen = snapshot->getStackLength();
+ jArray<nsHtml5StackNode*,int32_t> listCopy = snapshot->getListOfActiveFormattingElements();
+ int32_t listLen = snapshot->getListOfActiveFormattingElementsLength();
+ jArray<int32_t,int32_t> templateModeStackCopy = snapshot->getTemplateModeStack();
+ int32_t templateModeStackLen = snapshot->getTemplateModeStackLength();
+ for (int32_t i = 0; i <= listPtr; i++) {
+ if (listOfActiveFormattingElements[i]) {
+ listOfActiveFormattingElements[i]->release();
+ }
+ }
+ if (listOfActiveFormattingElements.length < listLen) {
+ listOfActiveFormattingElements = jArray<nsHtml5StackNode*,int32_t>::newJArray(listLen);
+ }
+ listPtr = listLen - 1;
+ for (int32_t i = 0; i <= currentPtr; i++) {
+ stack[i]->release();
+ }
+ if (stack.length < stackLen) {
+ stack = jArray<nsHtml5StackNode*,int32_t>::newJArray(stackLen);
+ }
+ currentPtr = stackLen - 1;
+ if (templateModeStack.length < templateModeStackLen) {
+ templateModeStack = jArray<int32_t,int32_t>::newJArray(templateModeStackLen);
+ }
+ templateModePtr = templateModeStackLen - 1;
+ for (int32_t i = 0; i < listLen; i++) {
+ nsHtml5StackNode* node = listCopy[i];
+ if (node) {
+ nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, nsHtml5Portability::newLocalFromLocal(node->name, interner), node->node, nsHtml5Portability::newLocalFromLocal(node->popName, interner), node->attributes->cloneAttributes(nullptr));
+ listOfActiveFormattingElements[i] = newNode;
+ } else {
+ listOfActiveFormattingElements[i] = nullptr;
+ }
+ }
+ for (int32_t i = 0; i < stackLen; i++) {
+ nsHtml5StackNode* node = stackCopy[i];
+ int32_t listIndex = findInArray(node, listCopy);
+ if (listIndex == -1) {
+ nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, nsHtml5Portability::newLocalFromLocal(node->name, interner), node->node, nsHtml5Portability::newLocalFromLocal(node->popName, interner), nullptr);
+ stack[i] = newNode;
+ } else {
+ stack[i] = listOfActiveFormattingElements[listIndex];
+ stack[i]->retain();
+ }
+ }
+ nsHtml5ArrayCopy::arraycopy(templateModeStackCopy, templateModeStack, templateModeStackLen);
+ formPointer = snapshot->getFormPointer();
+ headPointer = snapshot->getHeadPointer();
+ deepTreeSurrogateParent = snapshot->getDeepTreeSurrogateParent();
+ mode = snapshot->getMode();
+ originalMode = snapshot->getOriginalMode();
+ framesetOk = snapshot->isFramesetOk();
+ needToDropLF = snapshot->isNeedToDropLF();
+ quirks = snapshot->isQuirks();
+}
+
+int32_t
+nsHtml5TreeBuilder::findInArray(nsHtml5StackNode* node, jArray<nsHtml5StackNode*,int32_t> arr)
+{
+ for (int32_t i = listPtr; i >= 0; i--) {
+ if (node == arr[i]) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+nsIContentHandle*
+nsHtml5TreeBuilder::getFormPointer()
+{
+ return formPointer;
+}
+
+nsIContentHandle*
+nsHtml5TreeBuilder::getHeadPointer()
+{
+ return headPointer;
+}
+
+nsIContentHandle*
+nsHtml5TreeBuilder::getDeepTreeSurrogateParent()
+{
+ return deepTreeSurrogateParent;
+}
+
+jArray<nsHtml5StackNode*,int32_t>
+nsHtml5TreeBuilder::getListOfActiveFormattingElements()
+{
+ return listOfActiveFormattingElements;
+}
+
+jArray<nsHtml5StackNode*,int32_t>
+nsHtml5TreeBuilder::getStack()
+{
+ return stack;
+}
+
+jArray<int32_t,int32_t>
+nsHtml5TreeBuilder::getTemplateModeStack()
+{
+ return templateModeStack;
+}
+
+int32_t
+nsHtml5TreeBuilder::getMode()
+{
+ return mode;
+}
+
+int32_t
+nsHtml5TreeBuilder::getOriginalMode()
+{
+ return originalMode;
+}
+
+bool
+nsHtml5TreeBuilder::isFramesetOk()
+{
+ return framesetOk;
+}
+
+bool
+nsHtml5TreeBuilder::isNeedToDropLF()
+{
+ return needToDropLF;
+}
+
+bool
+nsHtml5TreeBuilder::isQuirks()
+{
+ return quirks;
+}
+
+int32_t
+nsHtml5TreeBuilder::getListOfActiveFormattingElementsLength()
+{
+ return listPtr + 1;
+}
+
+int32_t
+nsHtml5TreeBuilder::getStackLength()
+{
+ return currentPtr + 1;
+}
+
+int32_t
+nsHtml5TreeBuilder::getTemplateModeStackLength()
+{
+ return templateModePtr + 1;
+}
+
+void
+nsHtml5TreeBuilder::initializeStatics()
+{
+}
+
+void
+nsHtml5TreeBuilder::releaseStatics()
+{
+}
+
+
+#include "nsHtml5TreeBuilderCppSupplement.h"
+
diff --git a/parser/html/nsHtml5TreeBuilder.h b/parser/html/nsHtml5TreeBuilder.h
new file mode 100644
index 000000000..a66b168be
--- /dev/null
+++ b/parser/html/nsHtml5TreeBuilder.h
@@ -0,0 +1,384 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 2007-2015 Mozilla Foundation
+ * Portions of comments Copyright 2004-2008 Apple Computer, Inc., Mozilla
+ * Foundation, and Opera Software ASA.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit TreeBuilder.java instead and regenerate.
+ */
+
+#ifndef nsHtml5TreeBuilder_h
+#define nsHtml5TreeBuilder_h
+
+#include "nsContentUtils.h"
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsITimer.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5DocumentMode.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsHtml5Parser.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5TreeOperation.h"
+#include "nsHtml5StateSnapshot.h"
+#include "nsHtml5StackNode.h"
+#include "nsHtml5TreeOpExecutor.h"
+#include "nsHtml5StreamParser.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Highlighter.h"
+#include "nsHtml5PlainTextUtils.h"
+#include "nsHtml5ViewSourceUtils.h"
+#include "mozilla/Likely.h"
+#include "nsIContentHandle.h"
+#include "nsHtml5OplessBuilder.h"
+
+class nsHtml5StreamParser;
+
+class nsHtml5Tokenizer;
+class nsHtml5MetaScanner;
+class nsHtml5AttributeName;
+class nsHtml5ElementName;
+class nsHtml5HtmlAttributes;
+class nsHtml5UTF16Buffer;
+class nsHtml5StateSnapshot;
+class nsHtml5Portability;
+
+
+class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
+{
+ private:
+ static char16_t REPLACEMENT_CHARACTER[];
+ static staticJArray<const char*,int32_t> QUIRKY_PUBLIC_IDS;
+ int32_t mode;
+ int32_t originalMode;
+ bool framesetOk;
+ protected:
+ nsHtml5Tokenizer* tokenizer;
+ private:
+ bool scriptingEnabled;
+ bool needToDropLF;
+ bool fragment;
+ nsIAtom* contextName;
+ int32_t contextNamespace;
+ nsIContentHandle* contextNode;
+ autoJArray<int32_t,int32_t> templateModeStack;
+ int32_t templateModePtr;
+ autoJArray<nsHtml5StackNode*,int32_t> stack;
+ int32_t currentPtr;
+ autoJArray<nsHtml5StackNode*,int32_t> listOfActiveFormattingElements;
+ int32_t listPtr;
+ nsIContentHandle* formPointer;
+ nsIContentHandle* headPointer;
+ nsIContentHandle* deepTreeSurrogateParent;
+ protected:
+ autoJArray<char16_t,int32_t> charBuffer;
+ int32_t charBufferLen;
+ private:
+ bool quirks;
+ bool isSrcdocDocument;
+ public:
+ void startTokenization(nsHtml5Tokenizer* self);
+ void doctype(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks);
+ void comment(char16_t* buf, int32_t start, int32_t length);
+ void characters(const char16_t* buf, int32_t start, int32_t length);
+ void zeroOriginatingReplacementCharacter();
+ void eof();
+ void endTokenization();
+ void startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, bool selfClosing);
+ private:
+ void startTagTitleInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
+ void startTagGenericRawText(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
+ void startTagScriptInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
+ void startTagTemplateInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
+ bool isTemplateContents();
+ bool isTemplateModeStackEmpty();
+ bool isSpecialParentInForeign(nsHtml5StackNode* stackNode);
+ public:
+ static nsString* extractCharsetFromContent(nsString* attributeValue, nsHtml5TreeBuilder* tb);
+ private:
+ void checkMetaCharset(nsHtml5HtmlAttributes* attributes);
+ public:
+ void endTag(nsHtml5ElementName* elementName);
+ private:
+ void endTagTemplateInHead();
+ int32_t findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
+ int32_t findLast(nsIAtom* name);
+ int32_t findLastInTableScope(nsIAtom* name);
+ int32_t findLastInButtonScope(nsIAtom* name);
+ int32_t findLastInScope(nsIAtom* name);
+ int32_t findLastInListScope(nsIAtom* name);
+ int32_t findLastInScopeHn();
+ void generateImpliedEndTagsExceptFor(nsIAtom* name);
+ void generateImpliedEndTags();
+ bool isSecondOnStackBody();
+ void documentModeInternal(nsHtml5DocumentMode m, nsString* publicIdentifier, nsString* systemIdentifier, bool html4SpecificAdditionalErrorChecks);
+ bool isAlmostStandards(nsString* publicIdentifier, nsString* systemIdentifier);
+ bool isQuirky(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks);
+ void closeTheCell(int32_t eltPos);
+ int32_t findLastInTableScopeTdTh();
+ void clearStackBackTo(int32_t eltPos);
+ void resetTheInsertionMode();
+ void implicitlyCloseP();
+ bool debugOnlyClearLastStackSlot();
+ bool debugOnlyClearLastListSlot();
+ void pushTemplateMode(int32_t mode);
+ void push(nsHtml5StackNode* node);
+ void silentPush(nsHtml5StackNode* node);
+ void append(nsHtml5StackNode* node);
+ inline void insertMarker()
+ {
+ append(nullptr);
+ }
+
+ void clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+ inline bool isCurrent(nsIAtom* name)
+ {
+ return stack[currentPtr]->ns == kNameSpaceID_XHTML && name == stack[currentPtr]->name;
+ }
+
+ void removeFromStack(int32_t pos);
+ void removeFromStack(nsHtml5StackNode* node);
+ void removeFromListOfActiveFormattingElements(int32_t pos);
+ bool adoptionAgencyEndTag(nsIAtom* name);
+ void insertIntoStack(nsHtml5StackNode* node, int32_t position);
+ void insertIntoListOfActiveFormattingElements(nsHtml5StackNode* formattingClone, int32_t bookmark);
+ int32_t findInListOfActiveFormattingElements(nsHtml5StackNode* node);
+ int32_t findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(nsIAtom* name);
+ void maybeForgetEarlierDuplicateFormattingElement(nsIAtom* name, nsHtml5HtmlAttributes* attributes);
+ int32_t findLastOrRoot(nsIAtom* name);
+ int32_t findLastOrRoot(int32_t group);
+ bool addAttributesToBody(nsHtml5HtmlAttributes* attributes);
+ void addAttributesToHtml(nsHtml5HtmlAttributes* attributes);
+ void pushHeadPointerOntoStack();
+ void reconstructTheActiveFormattingElements();
+ void insertIntoFosterParent(nsIContentHandle* child);
+ nsIContentHandle* createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes);
+ nsIContentHandle* createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form);
+ bool isInStack(nsHtml5StackNode* node);
+ void popTemplateMode();
+ void pop();
+ void silentPop();
+ void popOnEof();
+ void appendHtmlElementToDocumentAndPush(nsHtml5HtmlAttributes* attributes);
+ void appendHtmlElementToDocumentAndPush();
+ void appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes* attributes);
+ void appendToCurrentNodeAndPushBodyElement(nsHtml5HtmlAttributes* attributes);
+ void appendToCurrentNodeAndPushBodyElement();
+ void appendToCurrentNodeAndPushFormElementMayFoster(nsHtml5HtmlAttributes* attributes);
+ void appendToCurrentNodeAndPushFormattingElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
+ void appendToCurrentNodeAndPushElement(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
+ void appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
+ void appendToCurrentNodeAndPushElementMayFosterMathML(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
+ bool annotationXmlEncodingPermitsHtml(nsHtml5HtmlAttributes* attributes);
+ void appendToCurrentNodeAndPushElementMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
+ void appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form);
+ void appendVoidElementToCurrentMayFoster(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form);
+ void appendVoidElementToCurrentMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
+ void appendVoidElementToCurrentMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
+ void appendVoidElementToCurrentMayFosterMathML(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
+ void appendVoidElementToCurrent(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form);
+ void appendVoidFormToCurrent(nsHtml5HtmlAttributes* attributes);
+ protected:
+ void accumulateCharacters(const char16_t* buf, int32_t start, int32_t length);
+ void requestSuspension();
+ nsIContentHandle* createElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* intendedParent);
+ nsIContentHandle* createElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form, nsIContentHandle* intendedParent);
+ nsIContentHandle* createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* attributes);
+ void detachFromParent(nsIContentHandle* element);
+ bool hasChildren(nsIContentHandle* element);
+ void appendElement(nsIContentHandle* child, nsIContentHandle* newParent);
+ void appendChildrenToNewParent(nsIContentHandle* oldParent, nsIContentHandle* newParent);
+ void insertFosterParentedChild(nsIContentHandle* child, nsIContentHandle* table, nsIContentHandle* stackParent);
+ nsIContentHandle* createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form, nsIContentHandle* table, nsIContentHandle* stackParent);
+ ;void insertFosterParentedCharacters(char16_t* buf, int32_t start, int32_t length, nsIContentHandle* table, nsIContentHandle* stackParent);
+ void appendCharacters(nsIContentHandle* parent, char16_t* buf, int32_t start, int32_t length);
+ void appendIsindexPrompt(nsIContentHandle* parent);
+ void appendComment(nsIContentHandle* parent, char16_t* buf, int32_t start, int32_t length);
+ void appendCommentToDocument(char16_t* buf, int32_t start, int32_t length);
+ void addAttributesToElement(nsIContentHandle* element, nsHtml5HtmlAttributes* attributes);
+ void markMalformedIfScript(nsIContentHandle* elt);
+ void start(bool fragmentMode);
+ void end();
+ void appendDoctypeToDocument(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier);
+ void elementPushed(int32_t ns, nsIAtom* name, nsIContentHandle* node);
+ void elementPopped(int32_t ns, nsIAtom* name, nsIContentHandle* node);
+ public:
+ inline bool cdataSectionAllowed()
+ {
+ return isInForeign();
+ }
+
+ private:
+ bool isInForeign();
+ bool isInForeignButNotHtmlOrMathTextIntegrationPoint();
+ public:
+ void setFragmentContext(nsIAtom* context, int32_t ns, nsIContentHandle* node, bool quirks);
+ protected:
+ nsIContentHandle* currentNode();
+ public:
+ bool isScriptingEnabled();
+ void setScriptingEnabled(bool scriptingEnabled);
+ void setIsSrcdocDocument(bool isSrcdocDocument);
+ void flushCharacters();
+ private:
+ bool charBufferContainsNonWhitespace();
+ public:
+ nsAHtml5TreeBuilderState* newSnapshot();
+ bool snapshotMatches(nsAHtml5TreeBuilderState* snapshot);
+ void loadState(nsAHtml5TreeBuilderState* snapshot, nsHtml5AtomTable* interner);
+ private:
+ int32_t findInArray(nsHtml5StackNode* node, jArray<nsHtml5StackNode*,int32_t> arr);
+ public:
+ nsIContentHandle* getFormPointer();
+ nsIContentHandle* getHeadPointer();
+ nsIContentHandle* getDeepTreeSurrogateParent();
+ jArray<nsHtml5StackNode*,int32_t> getListOfActiveFormattingElements();
+ jArray<nsHtml5StackNode*,int32_t> getStack();
+ jArray<int32_t,int32_t> getTemplateModeStack();
+ int32_t getMode();
+ int32_t getOriginalMode();
+ bool isFramesetOk();
+ bool isNeedToDropLF();
+ bool isQuirks();
+ int32_t getListOfActiveFormattingElementsLength();
+ int32_t getStackLength();
+ int32_t getTemplateModeStackLength();
+ static void initializeStatics();
+ static void releaseStatics();
+
+#include "nsHtml5TreeBuilderHSupplement.h"
+};
+
+#define NS_HTML5TREE_BUILDER_OTHER 0
+#define NS_HTML5TREE_BUILDER_A 1
+#define NS_HTML5TREE_BUILDER_BASE 2
+#define NS_HTML5TREE_BUILDER_BODY 3
+#define NS_HTML5TREE_BUILDER_BR 4
+#define NS_HTML5TREE_BUILDER_BUTTON 5
+#define NS_HTML5TREE_BUILDER_CAPTION 6
+#define NS_HTML5TREE_BUILDER_COL 7
+#define NS_HTML5TREE_BUILDER_COLGROUP 8
+#define NS_HTML5TREE_BUILDER_FORM 9
+#define NS_HTML5TREE_BUILDER_FRAME 10
+#define NS_HTML5TREE_BUILDER_FRAMESET 11
+#define NS_HTML5TREE_BUILDER_IMAGE 12
+#define NS_HTML5TREE_BUILDER_INPUT 13
+#define NS_HTML5TREE_BUILDER_ISINDEX 14
+#define NS_HTML5TREE_BUILDER_LI 15
+#define NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND 16
+#define NS_HTML5TREE_BUILDER_MATH 17
+#define NS_HTML5TREE_BUILDER_META 18
+#define NS_HTML5TREE_BUILDER_SVG 19
+#define NS_HTML5TREE_BUILDER_HEAD 20
+#define NS_HTML5TREE_BUILDER_HR 22
+#define NS_HTML5TREE_BUILDER_HTML 23
+#define NS_HTML5TREE_BUILDER_NOBR 24
+#define NS_HTML5TREE_BUILDER_NOFRAMES 25
+#define NS_HTML5TREE_BUILDER_NOSCRIPT 26
+#define NS_HTML5TREE_BUILDER_OPTGROUP 27
+#define NS_HTML5TREE_BUILDER_OPTION 28
+#define NS_HTML5TREE_BUILDER_P 29
+#define NS_HTML5TREE_BUILDER_PLAINTEXT 30
+#define NS_HTML5TREE_BUILDER_SCRIPT 31
+#define NS_HTML5TREE_BUILDER_SELECT 32
+#define NS_HTML5TREE_BUILDER_STYLE 33
+#define NS_HTML5TREE_BUILDER_TABLE 34
+#define NS_HTML5TREE_BUILDER_TEXTAREA 35
+#define NS_HTML5TREE_BUILDER_TITLE 36
+#define NS_HTML5TREE_BUILDER_TR 37
+#define NS_HTML5TREE_BUILDER_XMP 38
+#define NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT 39
+#define NS_HTML5TREE_BUILDER_TD_OR_TH 40
+#define NS_HTML5TREE_BUILDER_DD_OR_DT 41
+#define NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 42
+#define NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET 43
+#define NS_HTML5TREE_BUILDER_PRE_OR_LISTING 44
+#define NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U 45
+#define NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL 46
+#define NS_HTML5TREE_BUILDER_IFRAME 47
+#define NS_HTML5TREE_BUILDER_EMBED 48
+#define NS_HTML5TREE_BUILDER_AREA_OR_WBR 49
+#define NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU 50
+#define NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY 51
+#define NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR 52
+#define NS_HTML5TREE_BUILDER_RB_OR_RTC 53
+#define NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE_OR_TRACK 55
+#define NS_HTML5TREE_BUILDER_MGLYPH_OR_MALIGNMARK 56
+#define NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT 57
+#define NS_HTML5TREE_BUILDER_ANNOTATION_XML 58
+#define NS_HTML5TREE_BUILDER_FOREIGNOBJECT_OR_DESC 59
+#define NS_HTML5TREE_BUILDER_NOEMBED 60
+#define NS_HTML5TREE_BUILDER_FIELDSET 61
+#define NS_HTML5TREE_BUILDER_OUTPUT 62
+#define NS_HTML5TREE_BUILDER_OBJECT 63
+#define NS_HTML5TREE_BUILDER_FONT 64
+#define NS_HTML5TREE_BUILDER_KEYGEN 65
+#define NS_HTML5TREE_BUILDER_MENUITEM 66
+#define NS_HTML5TREE_BUILDER_TEMPLATE 67
+#define NS_HTML5TREE_BUILDER_IMG 68
+#define NS_HTML5TREE_BUILDER_RT_OR_RP 69
+#define NS_HTML5TREE_BUILDER_IN_ROW 0
+#define NS_HTML5TREE_BUILDER_IN_TABLE_BODY 1
+#define NS_HTML5TREE_BUILDER_IN_TABLE 2
+#define NS_HTML5TREE_BUILDER_IN_CAPTION 3
+#define NS_HTML5TREE_BUILDER_IN_CELL 4
+#define NS_HTML5TREE_BUILDER_FRAMESET_OK 5
+#define NS_HTML5TREE_BUILDER_IN_BODY 6
+#define NS_HTML5TREE_BUILDER_IN_HEAD 7
+#define NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT 8
+#define NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP 9
+#define NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE 10
+#define NS_HTML5TREE_BUILDER_IN_SELECT 11
+#define NS_HTML5TREE_BUILDER_AFTER_BODY 12
+#define NS_HTML5TREE_BUILDER_IN_FRAMESET 13
+#define NS_HTML5TREE_BUILDER_AFTER_FRAMESET 14
+#define NS_HTML5TREE_BUILDER_INITIAL 15
+#define NS_HTML5TREE_BUILDER_BEFORE_HTML 16
+#define NS_HTML5TREE_BUILDER_BEFORE_HEAD 17
+#define NS_HTML5TREE_BUILDER_AFTER_HEAD 18
+#define NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY 19
+#define NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET 20
+#define NS_HTML5TREE_BUILDER_TEXT 21
+#define NS_HTML5TREE_BUILDER_IN_TEMPLATE 22
+#define NS_HTML5TREE_BUILDER_CHARSET_INITIAL 0
+#define NS_HTML5TREE_BUILDER_CHARSET_C 1
+#define NS_HTML5TREE_BUILDER_CHARSET_H 2
+#define NS_HTML5TREE_BUILDER_CHARSET_A 3
+#define NS_HTML5TREE_BUILDER_CHARSET_R 4
+#define NS_HTML5TREE_BUILDER_CHARSET_S 5
+#define NS_HTML5TREE_BUILDER_CHARSET_E 6
+#define NS_HTML5TREE_BUILDER_CHARSET_T 7
+#define NS_HTML5TREE_BUILDER_CHARSET_EQUALS 8
+#define NS_HTML5TREE_BUILDER_CHARSET_SINGLE_QUOTED 9
+#define NS_HTML5TREE_BUILDER_CHARSET_DOUBLE_QUOTED 10
+#define NS_HTML5TREE_BUILDER_CHARSET_UNQUOTED 11
+#define NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK INT32_MAX
+
+
+#endif
+
diff --git a/parser/html/nsHtml5TreeBuilderCppSupplement.h b/parser/html/nsHtml5TreeBuilderCppSupplement.h
new file mode 100644
index 000000000..ff17c326e
--- /dev/null
+++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h
@@ -0,0 +1,1685 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 et tw=78: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsError.h"
+#include "nsIPresShell.h"
+#include "nsNodeUtils.h"
+#include "nsIFrame.h"
+#include "mozilla/Likely.h"
+#include "mozilla/UniquePtr.h"
+
+nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsHtml5OplessBuilder* aBuilder)
+ : scriptingEnabled(false)
+ , fragment(false)
+ , contextName(nullptr)
+ , contextNamespace(kNameSpaceID_None)
+ , contextNode(nullptr)
+ , formPointer(nullptr)
+ , headPointer(nullptr)
+ , mBuilder(aBuilder)
+ , mViewSource(nullptr)
+ , mOpSink(nullptr)
+ , mHandles(nullptr)
+ , mHandlesUsed(0)
+ , mSpeculativeLoadStage(nullptr)
+ , mBroken(NS_OK)
+ , mCurrentHtmlScriptIsAsyncOrDefer(false)
+ , mPreventScriptExecution(false)
+#ifdef DEBUG
+ , mActive(false)
+#endif
+{
+ MOZ_COUNT_CTOR(nsHtml5TreeBuilder);
+}
+
+nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,
+ nsHtml5TreeOpStage* aStage)
+ : scriptingEnabled(false)
+ , fragment(false)
+ , contextName(nullptr)
+ , contextNamespace(kNameSpaceID_None)
+ , contextNode(nullptr)
+ , formPointer(nullptr)
+ , headPointer(nullptr)
+ , mBuilder(nullptr)
+ , mViewSource(nullptr)
+ , mOpSink(aOpSink)
+ , mHandles(new nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH])
+ , mHandlesUsed(0)
+ , mSpeculativeLoadStage(aStage)
+ , mBroken(NS_OK)
+ , mCurrentHtmlScriptIsAsyncOrDefer(false)
+ , mPreventScriptExecution(false)
+#ifdef DEBUG
+ , mActive(false)
+#endif
+{
+ MOZ_COUNT_CTOR(nsHtml5TreeBuilder);
+}
+
+nsHtml5TreeBuilder::~nsHtml5TreeBuilder()
+{
+ MOZ_COUNT_DTOR(nsHtml5TreeBuilder);
+ NS_ASSERTION(!mActive, "nsHtml5TreeBuilder deleted without ever calling end() on it!");
+ mOpQueue.Clear();
+}
+
+nsIContentHandle*
+nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
+ nsHtml5HtmlAttributes* aAttributes,
+ nsIContentHandle* aIntendedParent)
+{
+ NS_PRECONDITION(aAttributes, "Got null attributes.");
+ NS_PRECONDITION(aName, "Got null name.");
+ NS_PRECONDITION(aNamespace == kNameSpaceID_XHTML ||
+ aNamespace == kNameSpaceID_SVG ||
+ aNamespace == kNameSpaceID_MathML,
+ "Bogus namespace.");
+
+ if (mBuilder) {
+ nsCOMPtr<nsIAtom> name = nsHtml5TreeOperation::Reget(aName);
+
+ nsIContent* intendedParent = aIntendedParent ?
+ static_cast<nsIContent*>(aIntendedParent) : nullptr;
+
+ // intendedParent == nullptr is a special case where the
+ // intended parent is the document.
+ nsNodeInfoManager* nodeInfoManager = intendedParent ?
+ intendedParent->OwnerDoc()->NodeInfoManager() :
+ mBuilder->GetNodeInfoManager();
+
+ nsIContent* elem =
+ nsHtml5TreeOperation::CreateElement(aNamespace,
+ name,
+ aAttributes,
+ mozilla::dom::FROM_PARSER_FRAGMENT,
+ nodeInfoManager,
+ mBuilder);
+ if (MOZ_UNLIKELY(aAttributes != tokenizer->GetAttributes() &&
+ aAttributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES)) {
+ delete aAttributes;
+ }
+ return elem;
+ }
+
+ nsIContentHandle* content = AllocateContentHandle();
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(aNamespace,
+ aName,
+ aAttributes,
+ content,
+ aIntendedParent,
+ !!mSpeculativeLoadStage);
+ // mSpeculativeLoadStage is non-null only in the off-the-main-thread
+ // tree builder, which handles the network stream
+
+ // Start wall of code for speculative loading and line numbers
+
+ if (mSpeculativeLoadStage) {
+ switch (aNamespace) {
+ case kNameSpaceID_XHTML:
+ if (nsHtml5Atoms::img == aName) {
+ nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
+ nsString* srcset =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_SRCSET);
+ nsString* crossOrigin =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
+ nsString* referrerPolicy =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_REFERRERPOLICY);
+ nsString* sizes =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_SIZES);
+ mSpeculativeLoadQueue.AppendElement()->
+ InitImage(url ? *url : NullString(),
+ crossOrigin ? *crossOrigin : NullString(),
+ referrerPolicy ? *referrerPolicy : NullString(),
+ srcset ? *srcset : NullString(),
+ sizes ? *sizes : NullString());
+ } else if (nsHtml5Atoms::source == aName) {
+ nsString* srcset =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_SRCSET);
+ // Sources without srcset cannot be selected. The source could also be
+ // for a media element, but in that context doesn't use srcset. See
+ // comments in nsHtml5SpeculativeLoad.h about <picture> preloading
+ if (srcset) {
+ nsString* sizes =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_SIZES);
+ nsString* type =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
+ nsString* media =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_MEDIA);
+ mSpeculativeLoadQueue.AppendElement()->
+ InitPictureSource(*srcset,
+ sizes ? *sizes : NullString(),
+ type ? *type : NullString(),
+ media ? *media : NullString());
+ }
+ } else if (nsHtml5Atoms::script == aName) {
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
+
+ nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
+ if (url) {
+ nsString* charset = aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
+ nsString* type = aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
+ nsString* crossOrigin =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
+ nsString* integrity =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
+ mSpeculativeLoadQueue.AppendElement()->
+ InitScript(*url,
+ (charset) ? *charset : EmptyString(),
+ (type) ? *type : EmptyString(),
+ (crossOrigin) ? *crossOrigin : NullString(),
+ (integrity) ? *integrity : NullString(),
+ mode == NS_HTML5TREE_BUILDER_IN_HEAD);
+ mCurrentHtmlScriptIsAsyncOrDefer =
+ aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) ||
+ aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER);
+ }
+ } else if (nsHtml5Atoms::link == aName) {
+ nsString* rel = aAttributes->getValue(nsHtml5AttributeName::ATTR_REL);
+ // Not splitting on space here is bogus but the old parser didn't even
+ // do a case-insensitive check.
+ if (rel) {
+ if (rel->LowerCaseEqualsASCII("stylesheet")) {
+ nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
+ if (url) {
+ nsString* charset = aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
+ nsString* crossOrigin =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
+ nsString* integrity =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
+ mSpeculativeLoadQueue.AppendElement()->
+ InitStyle(*url,
+ (charset) ? *charset : EmptyString(),
+ (crossOrigin) ? *crossOrigin : NullString(),
+ (integrity) ? *integrity : NullString());
+ }
+ } else if (rel->LowerCaseEqualsASCII("preconnect")) {
+ nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
+ if (url) {
+ nsString* crossOrigin =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
+ mSpeculativeLoadQueue.AppendElement()->
+ InitPreconnect(*url, (crossOrigin) ? *crossOrigin : NullString());
+ }
+ }
+ }
+ } else if (nsHtml5Atoms::video == aName) {
+ nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_POSTER);
+ if (url) {
+ mSpeculativeLoadQueue.AppendElement()->InitImage(*url, NullString(),
+ NullString(),
+ NullString(),
+ NullString());
+ }
+ } else if (nsHtml5Atoms::style == aName) {
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
+ } else if (nsHtml5Atoms::html == aName) {
+ nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
+ if (url) {
+ mSpeculativeLoadQueue.AppendElement()->InitManifest(*url);
+ } else {
+ mSpeculativeLoadQueue.AppendElement()->InitManifest(EmptyString());
+ }
+ } else if (nsHtml5Atoms::base == aName) {
+ nsString* url =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
+ if (url) {
+ mSpeculativeLoadQueue.AppendElement()->InitBase(*url);
+ }
+ } else if (nsHtml5Atoms::meta == aName) {
+ if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "content-security-policy",
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_HTTP_EQUIV))) {
+ nsString* csp = aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
+ if (csp) {
+ mSpeculativeLoadQueue.AppendElement()->InitMetaCSP(*csp);
+ }
+ }
+ else if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ "referrer",
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_NAME))) {
+ nsString* referrerPolicy = aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
+ if (referrerPolicy) {
+ mSpeculativeLoadQueue.AppendElement()->InitMetaReferrerPolicy(*referrerPolicy);
+ }
+ }
+ }
+ break;
+ case kNameSpaceID_SVG:
+ if (nsHtml5Atoms::image == aName) {
+ nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
+ if (url) {
+ mSpeculativeLoadQueue.AppendElement()->InitImage(*url, NullString(),
+ NullString(),
+ NullString(),
+ NullString());
+ }
+ } else if (nsHtml5Atoms::script == aName) {
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
+
+ nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
+ if (url) {
+ nsString* type = aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
+ nsString* crossOrigin =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
+ nsString* integrity =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
+ mSpeculativeLoadQueue.AppendElement()->
+ InitScript(*url,
+ EmptyString(),
+ (type) ? *type : EmptyString(),
+ (crossOrigin) ? *crossOrigin : NullString(),
+ (integrity) ? *integrity : NullString(),
+ mode == NS_HTML5TREE_BUILDER_IN_HEAD);
+ }
+ } else if (nsHtml5Atoms::style == aName) {
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
+
+ nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
+ if (url) {
+ nsString* crossOrigin =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
+ nsString* integrity =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
+ mSpeculativeLoadQueue.AppendElement()->
+ InitStyle(*url, EmptyString(),
+ (crossOrigin) ? *crossOrigin : NullString(),
+ (integrity) ? *integrity : NullString());
+ }
+ }
+ break;
+ }
+ } else if (aNamespace != kNameSpaceID_MathML) {
+ // No speculative loader--just line numbers and defer/async check
+ if (nsHtml5Atoms::style == aName) {
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
+ } else if (nsHtml5Atoms::script == aName) {
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
+ if (aNamespace == kNameSpaceID_XHTML) {
+ mCurrentHtmlScriptIsAsyncOrDefer =
+ aAttributes->contains(nsHtml5AttributeName::ATTR_SRC) &&
+ (aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) ||
+ aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER));
+ }
+ } else if (aNamespace == kNameSpaceID_XHTML) {
+ if (nsHtml5Atoms::html == aName) {
+ nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ if (url) {
+ treeOp->Init(eTreeOpProcessOfflineManifest, *url);
+ } else {
+ treeOp->Init(eTreeOpProcessOfflineManifest, EmptyString());
+ }
+ } else if (nsHtml5Atoms::base == aName && mViewSource) {
+ nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
+ if (url) {
+ mViewSource->AddBase(*url);
+ }
+ }
+ }
+ }
+
+ // End wall of code for speculative loading
+
+ return content;
+}
+
+nsIContentHandle*
+nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
+ nsHtml5HtmlAttributes* aAttributes,
+ nsIContentHandle* aFormElement,
+ nsIContentHandle* aIntendedParent)
+{
+ nsIContentHandle* content = createElement(aNamespace, aName, aAttributes,
+ aIntendedParent);
+ if (aFormElement) {
+ if (mBuilder) {
+ nsHtml5TreeOperation::SetFormElement(static_cast<nsIContent*>(content),
+ static_cast<nsIContent*>(aFormElement));
+ } else {
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpSetFormElement, content, aFormElement);
+ }
+ }
+ return content;
+}
+
+nsIContentHandle*
+nsHtml5TreeBuilder::createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* aAttributes)
+{
+ nsIContentHandle* content = createElement(kNameSpaceID_XHTML,
+ nsHtml5Atoms::html,
+ aAttributes,
+ nullptr);
+ if (mBuilder) {
+ nsresult rv = nsHtml5TreeOperation::AppendToDocument(static_cast<nsIContent*>(content),
+ mBuilder);
+ if (NS_FAILED(rv)) {
+ MarkAsBrokenAndRequestSuspension(rv);
+ }
+ } else {
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpAppendToDocument, content);
+ }
+ return content;
+}
+
+nsIContentHandle*
+nsHtml5TreeBuilder::createAndInsertFosterParentedElement(int32_t aNamespace, nsIAtom* aName,
+ nsHtml5HtmlAttributes* aAttributes,
+ nsIContentHandle* aFormElement,
+ nsIContentHandle* aTable,
+ nsIContentHandle* aStackParent)
+{
+ NS_PRECONDITION(aTable, "Null table");
+ NS_PRECONDITION(aStackParent, "Null stack parent");
+
+ if (mBuilder) {
+ // Get the foster parent to use as the intended parent when creating
+ // the child element.
+ nsIContent* fosterParent = nsHtml5TreeOperation::GetFosterParent(
+ static_cast<nsIContent*>(aTable),
+ static_cast<nsIContent*>(aStackParent));
+
+ nsIContentHandle* child = createElement(aNamespace, aName, aAttributes,
+ aFormElement, fosterParent);
+
+ insertFosterParentedChild(child, aTable, aStackParent);
+
+ return child;
+ }
+
+ // Tree op to get the foster parent that we use as the intended parent
+ // when creating the child element.
+ nsHtml5TreeOperation* fosterParentTreeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(fosterParentTreeOp, "Tree op allocation failed.");
+ nsIContentHandle* fosterParentHandle = AllocateContentHandle();
+ fosterParentTreeOp->Init(eTreeOpGetFosterParent, aTable,
+ aStackParent, fosterParentHandle);
+
+ // Create the element with the correct intended parent.
+ nsIContentHandle* child = createElement(aNamespace, aName, aAttributes,
+ aFormElement, fosterParentHandle);
+
+ // Insert the child into the foster parent.
+ insertFosterParentedChild(child, aTable, aStackParent);
+
+ return child;
+}
+
+void
+nsHtml5TreeBuilder::detachFromParent(nsIContentHandle* aElement)
+{
+ NS_PRECONDITION(aElement, "Null element");
+
+ if (mBuilder) {
+ nsHtml5TreeOperation::Detach(static_cast<nsIContent*>(aElement),
+ mBuilder);
+ return;
+ }
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpDetach, aElement);
+}
+
+void
+nsHtml5TreeBuilder::appendElement(nsIContentHandle* aChild, nsIContentHandle* aParent)
+{
+ NS_PRECONDITION(aChild, "Null child");
+ NS_PRECONDITION(aParent, "Null parent");
+ if (deepTreeSurrogateParent) {
+ return;
+ }
+
+ if (mBuilder) {
+ nsresult rv = nsHtml5TreeOperation::Append(static_cast<nsIContent*>(aChild),
+ static_cast<nsIContent*>(aParent),
+ mBuilder);
+ if (NS_FAILED(rv)) {
+ MarkAsBrokenAndRequestSuspension(rv);
+ }
+ return;
+ }
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpAppend, aChild, aParent);
+}
+
+void
+nsHtml5TreeBuilder::appendChildrenToNewParent(nsIContentHandle* aOldParent, nsIContentHandle* aNewParent)
+{
+ NS_PRECONDITION(aOldParent, "Null old parent");
+ NS_PRECONDITION(aNewParent, "Null new parent");
+
+ if (mBuilder) {
+ nsresult rv = nsHtml5TreeOperation::AppendChildrenToNewParent(
+ static_cast<nsIContent*>(aOldParent),
+ static_cast<nsIContent*>(aNewParent),
+ mBuilder);
+ if (NS_FAILED(rv)) {
+ MarkAsBrokenAndRequestSuspension(rv);
+ }
+ return;
+ }
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpAppendChildrenToNewParent, aOldParent, aNewParent);
+}
+
+void
+nsHtml5TreeBuilder::insertFosterParentedCharacters(char16_t* aBuffer, int32_t aStart, int32_t aLength, nsIContentHandle* aTable, nsIContentHandle* aStackParent)
+{
+ NS_PRECONDITION(aBuffer, "Null buffer");
+ NS_PRECONDITION(aTable, "Null table");
+ NS_PRECONDITION(aStackParent, "Null stack parent");
+ MOZ_ASSERT(!aStart, "aStart must always be zero.");
+
+ if (mBuilder) {
+ nsresult rv = nsHtml5TreeOperation::FosterParentText(
+ static_cast<nsIContent*>(aStackParent),
+ aBuffer, // XXX aStart always ignored???
+ aLength,
+ static_cast<nsIContent*>(aTable),
+ mBuilder);
+ if (NS_FAILED(rv)) {
+ MarkAsBrokenAndRequestSuspension(rv);
+ }
+ return;
+ }
+
+ char16_t* bufferCopy = new (mozilla::fallible) char16_t[aLength];
+ if (!bufferCopy) {
+ // Just assigning mBroken instead of generating tree op. The caller
+ // of tokenizeBuffer() will call MarkAsBroken() as appropriate.
+ mBroken = NS_ERROR_OUT_OF_MEMORY;
+ requestSuspension();
+ return;
+ }
+
+ memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpFosterParentText, bufferCopy, aLength, aStackParent, aTable);
+}
+
+void
+nsHtml5TreeBuilder::insertFosterParentedChild(nsIContentHandle* aChild, nsIContentHandle* aTable, nsIContentHandle* aStackParent)
+{
+ NS_PRECONDITION(aChild, "Null child");
+ NS_PRECONDITION(aTable, "Null table");
+ NS_PRECONDITION(aStackParent, "Null stack parent");
+
+ if (mBuilder) {
+ nsresult rv = nsHtml5TreeOperation::FosterParent(
+ static_cast<nsIContent*>(aChild),
+ static_cast<nsIContent*>(aStackParent),
+ static_cast<nsIContent*>(aTable),
+ mBuilder);
+ if (NS_FAILED(rv)) {
+ MarkAsBrokenAndRequestSuspension(rv);
+ }
+ return;
+ }
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpFosterParent, aChild, aStackParent, aTable);
+}
+
+void
+nsHtml5TreeBuilder::appendCharacters(nsIContentHandle* aParent, char16_t* aBuffer, int32_t aStart, int32_t aLength)
+{
+ NS_PRECONDITION(aBuffer, "Null buffer");
+ NS_PRECONDITION(aParent, "Null parent");
+ MOZ_ASSERT(!aStart, "aStart must always be zero.");
+
+ if (mBuilder) {
+ nsresult rv = nsHtml5TreeOperation::AppendText(
+ aBuffer, // XXX aStart always ignored???
+ aLength,
+ static_cast<nsIContent*>(deepTreeSurrogateParent ?
+ deepTreeSurrogateParent : aParent),
+ mBuilder);
+ if (NS_FAILED(rv)) {
+ MarkAsBrokenAndRequestSuspension(rv);
+ }
+ return;
+ }
+
+ char16_t* bufferCopy = new (mozilla::fallible) char16_t[aLength];
+ if (!bufferCopy) {
+ // Just assigning mBroken instead of generating tree op. The caller
+ // of tokenizeBuffer() will call MarkAsBroken() as appropriate.
+ mBroken = NS_ERROR_OUT_OF_MEMORY;
+ requestSuspension();
+ return;
+ }
+
+ memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpAppendText, bufferCopy, aLength,
+ deepTreeSurrogateParent ? deepTreeSurrogateParent : aParent);
+}
+
+void
+nsHtml5TreeBuilder::appendIsindexPrompt(nsIContentHandle* aParent)
+{
+ NS_PRECONDITION(aParent, "Null parent");
+
+ if (mBuilder) {
+ nsresult rv = nsHtml5TreeOperation::AppendIsindexPrompt(
+ static_cast<nsIContent*>(aParent),
+ mBuilder);
+ if (NS_FAILED(rv)) {
+ MarkAsBrokenAndRequestSuspension(rv);
+ }
+ return;
+ }
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpAppendIsindexPrompt, aParent);
+}
+
+void
+nsHtml5TreeBuilder::appendComment(nsIContentHandle* aParent, char16_t* aBuffer, int32_t aStart, int32_t aLength)
+{
+ NS_PRECONDITION(aBuffer, "Null buffer");
+ NS_PRECONDITION(aParent, "Null parent");
+ MOZ_ASSERT(!aStart, "aStart must always be zero.");
+
+ if (deepTreeSurrogateParent) {
+ return;
+ }
+
+ if (mBuilder) {
+ nsresult rv = nsHtml5TreeOperation::AppendComment(
+ static_cast<nsIContent*>(aParent),
+ aBuffer, // XXX aStart always ignored???
+ aLength,
+ mBuilder);
+ if (NS_FAILED(rv)) {
+ MarkAsBrokenAndRequestSuspension(rv);
+ }
+ return;
+ }
+
+ char16_t* bufferCopy = new (mozilla::fallible) char16_t[aLength];
+ if (!bufferCopy) {
+ // Just assigning mBroken instead of generating tree op. The caller
+ // of tokenizeBuffer() will call MarkAsBroken() as appropriate.
+ mBroken = NS_ERROR_OUT_OF_MEMORY;
+ requestSuspension();
+ return;
+ }
+
+ memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpAppendComment, bufferCopy, aLength, aParent);
+}
+
+void
+nsHtml5TreeBuilder::appendCommentToDocument(char16_t* aBuffer, int32_t aStart, int32_t aLength)
+{
+ NS_PRECONDITION(aBuffer, "Null buffer");
+ MOZ_ASSERT(!aStart, "aStart must always be zero.");
+
+ if (mBuilder) {
+ nsresult rv = nsHtml5TreeOperation::AppendCommentToDocument(
+ aBuffer, // XXX aStart always ignored???
+ aLength,
+ mBuilder);
+ if (NS_FAILED(rv)) {
+ MarkAsBrokenAndRequestSuspension(rv);
+ }
+ return;
+ }
+
+ char16_t* bufferCopy = new (mozilla::fallible) char16_t[aLength];
+ if (!bufferCopy) {
+ // Just assigning mBroken instead of generating tree op. The caller
+ // of tokenizeBuffer() will call MarkAsBroken() as appropriate.
+ mBroken = NS_ERROR_OUT_OF_MEMORY;
+ requestSuspension();
+ return;
+ }
+
+ memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpAppendCommentToDocument, bufferCopy, aLength);
+}
+
+void
+nsHtml5TreeBuilder::addAttributesToElement(nsIContentHandle* aElement, nsHtml5HtmlAttributes* aAttributes)
+{
+ NS_PRECONDITION(aElement, "Null element");
+ NS_PRECONDITION(aAttributes, "Null attributes");
+
+ if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
+ return;
+ }
+
+ if (mBuilder) {
+ MOZ_ASSERT(aAttributes == tokenizer->GetAttributes(),
+ "Using attribute other than the tokenizer's to add to body or html.");
+ nsresult rv = nsHtml5TreeOperation::AddAttributes(
+ static_cast<nsIContent*>(aElement),
+ aAttributes,
+ mBuilder);
+ if (NS_FAILED(rv)) {
+ MarkAsBrokenAndRequestSuspension(rv);
+ }
+ return;
+ }
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(aElement, aAttributes);
+}
+
+void
+nsHtml5TreeBuilder::markMalformedIfScript(nsIContentHandle* aElement)
+{
+ NS_PRECONDITION(aElement, "Null element");
+
+ if (mBuilder) {
+ nsHtml5TreeOperation::MarkMalformedIfScript(
+ static_cast<nsIContent*>(aElement));
+ return;
+ }
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpMarkMalformedIfScript, aElement);
+}
+
+void
+nsHtml5TreeBuilder::start(bool fragment)
+{
+ mCurrentHtmlScriptIsAsyncOrDefer = false;
+ deepTreeSurrogateParent = nullptr;
+#ifdef DEBUG
+ mActive = true;
+#endif
+}
+
+void
+nsHtml5TreeBuilder::end()
+{
+ mOpQueue.Clear();
+#ifdef DEBUG
+ mActive = false;
+#endif
+}
+
+void
+nsHtml5TreeBuilder::appendDoctypeToDocument(nsIAtom* aName, nsString* aPublicId, nsString* aSystemId)
+{
+ NS_PRECONDITION(aName, "Null name");
+
+ if (mBuilder) {
+ nsCOMPtr<nsIAtom> name = nsHtml5TreeOperation::Reget(aName);
+ nsresult rv =
+ nsHtml5TreeOperation::AppendDoctypeToDocument(name,
+ *aPublicId,
+ *aSystemId,
+ mBuilder);
+ if (NS_FAILED(rv)) {
+ MarkAsBrokenAndRequestSuspension(rv);
+ }
+ return;
+ }
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(aName, *aPublicId, *aSystemId);
+ // nsXMLContentSink can flush here, but what's the point?
+ // It can also interrupt here, but we can't.
+}
+
+void
+nsHtml5TreeBuilder::elementPushed(int32_t aNamespace, nsIAtom* aName, nsIContentHandle* aElement)
+{
+ NS_ASSERTION(aNamespace == kNameSpaceID_XHTML || aNamespace == kNameSpaceID_SVG || aNamespace == kNameSpaceID_MathML, "Element isn't HTML, SVG or MathML!");
+ NS_ASSERTION(aName, "Element doesn't have local name!");
+ NS_ASSERTION(aElement, "No element!");
+ /*
+ * The frame constructor uses recursive algorithms, so it can't deal with
+ * arbitrarily deep trees. This is especially a problem on Windows where
+ * the permitted depth of the runtime stack is rather small.
+ *
+ * The following is a protection against author incompetence--not against
+ * malice. There are other ways to make the DOM deep anyway.
+ *
+ * The basic idea is that when the tree builder stack gets too deep,
+ * append operations no longer append to the node that the HTML parsing
+ * algorithm says they should but instead text nodes are append to the last
+ * element that was seen before a magic tree builder stack threshold was
+ * reached and element and comment nodes aren't appended to the DOM at all.
+ *
+ * However, for security reasons, non-child descendant text nodes inside an
+ * SVG script or style element should not become children. Also, non-cell
+ * table elements shouldn't be used as surrogate parents for user experience
+ * reasons.
+ */
+ if (!deepTreeSurrogateParent && currentPtr >= MAX_REFLOW_DEPTH &&
+ !(aName == nsHtml5Atoms::script ||
+ aName == nsHtml5Atoms::table ||
+ aName == nsHtml5Atoms::thead ||
+ aName == nsHtml5Atoms::tfoot ||
+ aName == nsHtml5Atoms::tbody ||
+ aName == nsHtml5Atoms::tr ||
+ aName == nsHtml5Atoms::colgroup ||
+ aName == nsHtml5Atoms::style)) {
+ deepTreeSurrogateParent = aElement;
+ }
+ if (aNamespace != kNameSpaceID_XHTML) {
+ return;
+ }
+ if (aName == nsHtml5Atoms::body || aName == nsHtml5Atoms::frameset) {
+ if (mBuilder) {
+ // InnerHTML and DOMParser shouldn't start layout anyway
+ return;
+ }
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpStartLayout);
+ return;
+ }
+ if (aName == nsHtml5Atoms::input ||
+ aName == nsHtml5Atoms::button) {
+ if (mBuilder) {
+ nsHtml5TreeOperation::DoneCreatingElement(static_cast<nsIContent*>(aElement));
+ } else {
+ mOpQueue.AppendElement()->Init(eTreeOpDoneCreatingElement, aElement);
+ }
+ return;
+ }
+ if (aName == nsHtml5Atoms::audio ||
+ aName == nsHtml5Atoms::video ||
+ aName == nsHtml5Atoms::menuitem) {
+ if (mBuilder) {
+ nsHtml5TreeOperation::DoneCreatingElement(static_cast<nsIContent*>(aElement));
+ } else {
+ mOpQueue.AppendElement()->Init(eTreeOpDoneCreatingElement, aElement);
+ }
+ return;
+ }
+ if (mSpeculativeLoadStage && aName == nsHtml5Atoms::picture) {
+ // mSpeculativeLoadStage is non-null only in the off-the-main-thread
+ // tree builder, which handles the network stream
+ //
+ // See comments in nsHtml5SpeculativeLoad.h about <picture> preloading
+ mSpeculativeLoadQueue.AppendElement()->InitOpenPicture();
+ }
+}
+
+void
+nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsIAtom* aName, nsIContentHandle* aElement)
+{
+ NS_ASSERTION(aNamespace == kNameSpaceID_XHTML || aNamespace == kNameSpaceID_SVG || aNamespace == kNameSpaceID_MathML, "Element isn't HTML, SVG or MathML!");
+ NS_ASSERTION(aName, "Element doesn't have local name!");
+ NS_ASSERTION(aElement, "No element!");
+ if (deepTreeSurrogateParent && currentPtr <= MAX_REFLOW_DEPTH) {
+ deepTreeSurrogateParent = nullptr;
+ }
+ if (aNamespace == kNameSpaceID_MathML) {
+ return;
+ }
+ // we now have only SVG and HTML
+ if (aName == nsHtml5Atoms::script) {
+ if (mPreventScriptExecution) {
+ if (mBuilder) {
+ nsHtml5TreeOperation::PreventScriptExecution(static_cast<nsIContent*>(aElement));
+ return;
+ }
+ mOpQueue.AppendElement()->Init(eTreeOpPreventScriptExecution, aElement);
+ return;
+ }
+ if (mBuilder) {
+ return;
+ }
+ if (mCurrentHtmlScriptIsAsyncOrDefer) {
+ NS_ASSERTION(aNamespace == kNameSpaceID_XHTML,
+ "Only HTML scripts may be async/defer.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpRunScriptAsyncDefer, aElement);
+ mCurrentHtmlScriptIsAsyncOrDefer = false;
+ return;
+ }
+ requestSuspension();
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->InitScript(aElement);
+ return;
+ }
+ if (aName == nsHtml5Atoms::title) {
+ if (mBuilder) {
+ nsHtml5TreeOperation::DoneAddingChildren(static_cast<nsIContent*>(aElement));
+ return;
+ }
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpDoneAddingChildren, aElement);
+ return;
+ }
+ if (aName == nsHtml5Atoms::style || (aNamespace == kNameSpaceID_XHTML && aName == nsHtml5Atoms::link)) {
+ if (mBuilder) {
+ MOZ_ASSERT(!nsContentUtils::IsSafeToRunScript(),
+ "Scripts must be blocked.");
+ mBuilder->UpdateStyleSheet(static_cast<nsIContent*>(aElement));
+ return;
+ }
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpUpdateStyleSheet, aElement);
+ return;
+ }
+ if (aNamespace == kNameSpaceID_SVG) {
+ if (aName == nsHtml5Atoms::svg) {
+ if (mBuilder) {
+ nsHtml5TreeOperation::SvgLoad(static_cast<nsIContent*>(aElement));
+ return;
+ }
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpSvgLoad, aElement);
+ }
+ return;
+ }
+ // we now have only HTML
+ // Some HTML nodes need DoneAddingChildren() called to initialize
+ // properly (e.g. form state restoration).
+ // XXX expose ElementName group here and do switch
+ if (aName == nsHtml5Atoms::object ||
+ aName == nsHtml5Atoms::applet ||
+ aName == nsHtml5Atoms::select ||
+ aName == nsHtml5Atoms::textarea ||
+ aName == nsHtml5Atoms::output) {
+ if (mBuilder) {
+ nsHtml5TreeOperation::DoneAddingChildren(static_cast<nsIContent*>(aElement));
+ return;
+ }
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpDoneAddingChildren, aElement);
+ return;
+ }
+ if (aName == nsHtml5Atoms::meta && !fragment && !mBuilder) {
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpProcessMeta, aElement);
+ return;
+ }
+ if (mSpeculativeLoadStage && aName == nsHtml5Atoms::picture) {
+ // mSpeculativeLoadStage is non-null only in the off-the-main-thread
+ // tree builder, which handles the network stream
+ //
+ // See comments in nsHtml5SpeculativeLoad.h about <picture> preloading
+ mSpeculativeLoadQueue.AppendElement()->InitEndPicture();
+ }
+ return;
+}
+
+void
+nsHtml5TreeBuilder::accumulateCharacters(const char16_t* aBuf, int32_t aStart, int32_t aLength)
+{
+ MOZ_RELEASE_ASSERT(charBufferLen + aLength <= charBuffer.length,
+ "About to memcpy past the end of the buffer!");
+ memcpy(charBuffer + charBufferLen, aBuf + aStart, sizeof(char16_t) * aLength);
+ charBufferLen += aLength;
+}
+
+// INT32_MAX is (2^31)-1. Therefore, the highest power-of-two that fits
+// is 2^30. Note that this is counting char16_t units. The underlying
+// bytes will be twice that, but they fit even in 32-bit size_t even
+// if a contiguous chunk of memory of that size is pretty unlikely to
+// be available on a 32-bit system.
+#define MAX_POWER_OF_TWO_IN_INT32 0x40000000
+
+bool
+nsHtml5TreeBuilder::EnsureBufferSpace(int32_t aLength)
+{
+ // TODO: Unify nsHtml5Tokenizer::strBuf and nsHtml5TreeBuilder::charBuffer
+ // so that this method becomes unnecessary.
+ CheckedInt<int32_t> worstCase(charBufferLen);
+ worstCase += aLength;
+ if (!worstCase.isValid()) {
+ return false;
+ }
+ if (worstCase.value() > MAX_POWER_OF_TWO_IN_INT32) {
+ return false;
+ }
+ if (!charBuffer) {
+ if (worstCase.value() < MAX_POWER_OF_TWO_IN_INT32) {
+ // Add one to round to the next power of two to avoid immediate
+ // reallocation once there are a few characters in the buffer.
+ worstCase += 1;
+ }
+ charBuffer = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
+ if (!charBuffer) {
+ return false;
+ }
+ } else if (worstCase.value() > charBuffer.length) {
+ jArray<char16_t,int32_t> newBuf = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
+ if (!newBuf) {
+ return false;
+ }
+ memcpy(newBuf, charBuffer, sizeof(char16_t) * size_t(charBufferLen));
+ charBuffer = newBuf;
+ }
+ return true;
+}
+
+nsIContentHandle*
+nsHtml5TreeBuilder::AllocateContentHandle()
+{
+ if (MOZ_UNLIKELY(mBuilder)) {
+ MOZ_ASSERT_UNREACHABLE("Must never allocate a handle with builder.");
+ return nullptr;
+ }
+ if (mHandlesUsed == NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH) {
+ mOldHandles.AppendElement(Move(mHandles));
+ mHandles = MakeUnique<nsIContent*[]>(NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH);
+ mHandlesUsed = 0;
+ }
+#ifdef DEBUG
+ mHandles[mHandlesUsed] = reinterpret_cast<nsIContent*>(uintptr_t(0xC0DEDBAD));
+#endif
+ return &mHandles[mHandlesUsed++];
+}
+
+bool
+nsHtml5TreeBuilder::HasScript()
+{
+ uint32_t len = mOpQueue.Length();
+ if (!len) {
+ return false;
+ }
+ return mOpQueue.ElementAt(len - 1).IsRunScript();
+}
+
+bool
+nsHtml5TreeBuilder::Flush(bool aDiscretionary)
+{
+ if (MOZ_UNLIKELY(mBuilder)) {
+ MOZ_ASSERT_UNREACHABLE("Must never flush with builder.");
+ return false;
+ }
+ if (NS_SUCCEEDED(mBroken)) {
+ if (!aDiscretionary ||
+ !(charBufferLen &&
+ currentPtr >= 0 &&
+ stack[currentPtr]->isFosterParenting())) {
+ // Don't flush text on discretionary flushes if the current element on
+ // the stack is a foster-parenting element and there's pending text,
+ // because flushing in that case would make the tree shape dependent on
+ // where the flush points fall.
+ flushCharacters();
+ }
+ FlushLoads();
+ }
+ if (mOpSink) {
+ bool hasOps = !mOpQueue.IsEmpty();
+ if (hasOps) {
+ // If the builder is broken and mOpQueue is not empty, there must be
+ // one op and it must be eTreeOpMarkAsBroken.
+ if (NS_FAILED(mBroken)) {
+ MOZ_ASSERT(mOpQueue.Length() == 1,
+ "Tree builder is broken with a non-empty op queue whose length isn't 1.");
+ MOZ_ASSERT(mOpQueue[0].IsMarkAsBroken(),
+ "Tree builder is broken but the op in queue is not marked as broken.");
+ }
+ mOpSink->MoveOpsFrom(mOpQueue);
+ }
+ return hasOps;
+ }
+ // no op sink: throw away ops
+ mOpQueue.Clear();
+ return false;
+}
+
+void
+nsHtml5TreeBuilder::FlushLoads()
+{
+ if (MOZ_UNLIKELY(mBuilder)) {
+ MOZ_ASSERT_UNREACHABLE("Must never flush loads with builder.");
+ return;
+ }
+ if (!mSpeculativeLoadQueue.IsEmpty()) {
+ mSpeculativeLoadStage->MoveSpeculativeLoadsFrom(mSpeculativeLoadQueue);
+ }
+}
+
+void
+nsHtml5TreeBuilder::SetDocumentCharset(nsACString& aCharset,
+ int32_t aCharsetSource)
+{
+ if (mBuilder) {
+ mBuilder->SetDocumentCharsetAndSource(aCharset, aCharsetSource);
+ } else if (mSpeculativeLoadStage) {
+ mSpeculativeLoadQueue.AppendElement()->InitSetDocumentCharset(
+ aCharset, aCharsetSource);
+ } else {
+ mOpQueue.AppendElement()->Init(
+ eTreeOpSetDocumentCharset, aCharset, aCharsetSource);
+ }
+}
+
+void
+nsHtml5TreeBuilder::StreamEnded()
+{
+ MOZ_ASSERT(!mBuilder, "Must not call StreamEnded with builder.");
+ MOZ_ASSERT(!fragment, "Must not parse fragments off the main thread.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpStreamEnded);
+}
+
+void
+nsHtml5TreeBuilder::NeedsCharsetSwitchTo(const nsACString& aCharset,
+ int32_t aCharsetSource,
+ int32_t aLineNumber)
+{
+ if (MOZ_UNLIKELY(mBuilder)) {
+ MOZ_ASSERT_UNREACHABLE("Must never switch charset with builder.");
+ return;
+ }
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(eTreeOpNeedsCharsetSwitchTo,
+ aCharset,
+ aCharsetSource,
+ aLineNumber);
+}
+
+void
+nsHtml5TreeBuilder::MaybeComplainAboutCharset(const char* aMsgId,
+ bool aError,
+ int32_t aLineNumber)
+{
+ if (MOZ_UNLIKELY(mBuilder)) {
+ MOZ_ASSERT_UNREACHABLE("Must never complain about charset with builder.");
+ return;
+ }
+ mOpQueue.AppendElement()->Init(aMsgId, aError, aLineNumber);
+}
+
+void
+nsHtml5TreeBuilder::AddSnapshotToScript(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine)
+{
+ if (MOZ_UNLIKELY(mBuilder)) {
+ MOZ_ASSERT_UNREACHABLE("Must never use snapshots with builder.");
+ return;
+ }
+ NS_PRECONDITION(HasScript(), "No script to add a snapshot to!");
+ NS_PRECONDITION(aSnapshot, "Got null snapshot.");
+ mOpQueue.ElementAt(mOpQueue.Length() - 1).SetSnapshot(aSnapshot, aLine);
+}
+
+void
+nsHtml5TreeBuilder::DropHandles()
+{
+ MOZ_ASSERT(!mBuilder, "Must not drop handles with builder.");
+ mOldHandles.Clear();
+ mHandlesUsed = 0;
+}
+
+void
+nsHtml5TreeBuilder::MarkAsBroken(nsresult aRv)
+{
+ if (MOZ_UNLIKELY(mBuilder)) {
+ MOZ_ASSERT_UNREACHABLE("Must not call this with builder.");
+ return;
+ }
+ mBroken = aRv;
+ mOpQueue.Clear(); // Previous ops don't matter anymore
+ mOpQueue.AppendElement()->Init(aRv);
+}
+
+void
+nsHtml5TreeBuilder::MarkAsBrokenFromPortability(nsresult aRv)
+{
+ if (mBuilder) {
+ MarkAsBrokenAndRequestSuspension(aRv);
+ return;
+ }
+ mBroken = aRv;
+ requestSuspension();
+}
+
+void
+nsHtml5TreeBuilder::StartPlainTextViewSource(const nsAutoString& aTitle)
+{
+ MOZ_ASSERT(!mBuilder, "Must not view source with builder.");
+ startTag(nsHtml5ElementName::ELT_TITLE,
+ nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES,
+ false);
+
+ // XUL will add the "Source of: " prefix.
+ uint32_t length = aTitle.Length();
+ if (length > INT32_MAX) {
+ length = INT32_MAX;
+ }
+ characters(aTitle.get(), 0, (int32_t)length);
+ endTag(nsHtml5ElementName::ELT_TITLE);
+
+ startTag(nsHtml5ElementName::ELT_LINK,
+ nsHtml5ViewSourceUtils::NewLinkAttributes(),
+ false);
+
+ startTag(nsHtml5ElementName::ELT_BODY,
+ nsHtml5ViewSourceUtils::NewBodyAttributes(),
+ false);
+
+ StartPlainTextBody();
+}
+
+void
+nsHtml5TreeBuilder::StartPlainText()
+{
+ MOZ_ASSERT(!mBuilder, "Must not view source with builder.");
+ startTag(nsHtml5ElementName::ELT_LINK,
+ nsHtml5PlainTextUtils::NewLinkAttributes(),
+ false);
+
+ StartPlainTextBody();
+}
+
+void
+nsHtml5TreeBuilder::StartPlainTextBody()
+{
+ MOZ_ASSERT(!mBuilder, "Must not view source with builder.");
+ startTag(nsHtml5ElementName::ELT_PRE,
+ nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES,
+ false);
+ needToDropLF = false;
+}
+
+// DocumentModeHandler
+void
+nsHtml5TreeBuilder::documentMode(nsHtml5DocumentMode m)
+{
+ if (mBuilder) {
+ mBuilder->SetDocumentMode(m);
+ return;
+ }
+ if (mSpeculativeLoadStage) {
+ mSpeculativeLoadQueue.AppendElement()->InitSetDocumentMode(m);
+ return;
+ }
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ treeOp->Init(m);
+}
+
+nsIContentHandle*
+nsHtml5TreeBuilder::getDocumentFragmentForTemplate(nsIContentHandle* aTemplate)
+{
+ if (mBuilder) {
+ return nsHtml5TreeOperation::GetDocumentFragmentForTemplate(static_cast<nsIContent*>(aTemplate));
+ }
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+ NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsIContentHandle* fragHandle = AllocateContentHandle();
+ treeOp->Init(eTreeOpGetDocumentFragmentForTemplate, aTemplate, fragHandle);
+ return fragHandle;
+}
+
+nsIContentHandle*
+nsHtml5TreeBuilder::getFormPointerForContext(nsIContentHandle* aContext)
+{
+ MOZ_ASSERT(mBuilder, "Must have builder.");
+ if (!aContext) {
+ return nullptr;
+ }
+
+ MOZ_ASSERT(NS_IsMainThread());
+
+ // aContext must always be an element that already exists
+ // in the document.
+ nsIContent* contextNode = static_cast<nsIContent*>(aContext);
+ nsIContent* currentAncestor = contextNode;
+
+ // We traverse the ancestors of the context node to find the nearest
+ // form pointer. This traversal is why aContext must not be an emtpy handle.
+ nsIContent* nearestForm = nullptr;
+ while (currentAncestor) {
+ if (currentAncestor->IsHTMLElement(nsGkAtoms::form)) {
+ nearestForm = currentAncestor;
+ break;
+ }
+ currentAncestor = currentAncestor->GetParent();
+ }
+
+ if (!nearestForm) {
+ return nullptr;
+ }
+
+ return nearestForm;
+}
+
+// Error reporting
+
+void
+nsHtml5TreeBuilder::EnableViewSource(nsHtml5Highlighter* aHighlighter)
+{
+ MOZ_ASSERT(!mBuilder, "Must not view source with builder.");
+ mViewSource = aHighlighter;
+}
+
+void
+nsHtml5TreeBuilder::errStrayStartTag(nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errStrayStartTag2", aName);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errStrayEndTag(nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errStrayEndTag", aName);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errUnclosedElements(int32_t aIndex, nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errUnclosedElements", aName);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errUnclosedElementsImplied(int32_t aIndex, nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errUnclosedElementsImplied",
+ aName);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errUnclosedElementsCell(int32_t aIndex)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errUnclosedElementsCell");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errStrayDoctype()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errStrayDoctype");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errAlmostStandardsDoctype()
+{
+ if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
+ mViewSource->AddErrorToCurrentRun("errAlmostStandardsDoctype");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errQuirkyDoctype()
+{
+ if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
+ mViewSource->AddErrorToCurrentRun("errQuirkyDoctype");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errNonSpaceInTrailer()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errNonSpaceInTrailer");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errNonSpaceAfterFrameset()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errNonSpaceAfterFrameset");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errNonSpaceInFrameset()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errNonSpaceInFrameset");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errNonSpaceAfterBody()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errNonSpaceAfterBody");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errNonSpaceInColgroupInFragment()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errNonSpaceInColgroupInFragment");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errNonSpaceInNoscriptInHead()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errNonSpaceInNoscriptInHead");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errFooBetweenHeadAndBody(nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errFooBetweenHeadAndBody", aName);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errStartTagWithoutDoctype()
+{
+ if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
+ mViewSource->AddErrorToCurrentRun("errStartTagWithoutDoctype");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errNoSelectInTableScope()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errNoSelectInTableScope");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errStartSelectWhereEndSelectExpected()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun(
+ "errStartSelectWhereEndSelectExpected");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errStartTagWithSelectOpen(nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errStartTagWithSelectOpen", aName);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errBadStartTagInHead(nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errBadStartTagInHead2", aName);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errImage()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errImage");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errIsindex()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errIsindex");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errFooSeenWhenFooOpen(nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errFooSeenWhenFooOpen", aName);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errHeadingWhenHeadingOpen()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errHeadingWhenHeadingOpen");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errFramesetStart()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errFramesetStart");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errNoCellToClose()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errNoCellToClose");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errStartTagInTable(nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errStartTagInTable", aName);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errFormWhenFormOpen()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errFormWhenFormOpen");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errTableSeenWhileTableOpen()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errTableSeenWhileTableOpen");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errStartTagInTableBody(nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errStartTagInTableBody", aName);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errEndTagSeenWithoutDoctype()
+{
+ if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
+ mViewSource->AddErrorToCurrentRun("errEndTagSeenWithoutDoctype");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errEndTagAfterBody()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errEndTagAfterBody");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errEndTagSeenWithSelectOpen(nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errEndTagSeenWithSelectOpen",
+ aName);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errGarbageInColgroup()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errGarbageInColgroup");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errEndTagBr()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errEndTagBr");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errNoElementToCloseButEndTagSeen(nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun(
+ "errNoElementToCloseButEndTagSeen", aName);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errHtmlStartTagInForeignContext(nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errHtmlStartTagInForeignContext",
+ aName);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errTableClosedWhileCaptionOpen()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errTableClosedWhileCaptionOpen");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errNoTableRowToClose()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errNoTableRowToClose");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errNonSpaceInTable()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errNonSpaceInTable");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errUnclosedChildrenInRuby()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errUnclosedChildrenInRuby");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errStartTagSeenWithoutRuby(nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errStartTagSeenWithoutRuby",
+ aName);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errSelfClosing()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentSlash("errSelfClosing");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errNoCheckUnclosedElementsOnStack()
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun(
+ "errNoCheckUnclosedElementsOnStack");
+ }
+}
+
+void
+nsHtml5TreeBuilder::errEndTagDidNotMatchCurrentOpenElement(nsIAtom* aName,
+ nsIAtom* aOther)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun(
+ "errEndTagDidNotMatchCurrentOpenElement", aName, aOther);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errEndTagViolatesNestingRules(nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errEndTagViolatesNestingRules", aName);
+ }
+}
+
+void
+nsHtml5TreeBuilder::errEndWithUnclosedElements(nsIAtom* aName)
+{
+ if (MOZ_UNLIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentRun("errEndWithUnclosedElements", aName);
+ }
+}
diff --git a/parser/html/nsHtml5TreeBuilderHSupplement.h b/parser/html/nsHtml5TreeBuilderHSupplement.h
new file mode 100644
index 000000000..afaa0b4a2
--- /dev/null
+++ b/parser/html/nsHtml5TreeBuilderHSupplement.h
@@ -0,0 +1,248 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#define NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH 512
+
+ private:
+ nsHtml5OplessBuilder* mBuilder;
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // If mBuilder is not null, the tree op machinery is not in use and
+ // the fields below aren't in use, either.
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ nsHtml5Highlighter* mViewSource;
+ nsTArray<nsHtml5TreeOperation> mOpQueue;
+ nsTArray<nsHtml5SpeculativeLoad> mSpeculativeLoadQueue;
+ nsAHtml5TreeOpSink* mOpSink;
+ mozilla::UniquePtr<nsIContent*[]> mHandles;
+ int32_t mHandlesUsed;
+ nsTArray<mozilla::UniquePtr<nsIContent*[]>> mOldHandles;
+ nsHtml5TreeOpStage* mSpeculativeLoadStage;
+ nsresult mBroken;
+ bool mCurrentHtmlScriptIsAsyncOrDefer;
+ bool mPreventScriptExecution;
+#ifdef DEBUG
+ bool mActive;
+#endif
+
+ // DocumentModeHandler
+ /**
+ * Tree builder uses this to report quirkiness of the document
+ */
+ void documentMode(nsHtml5DocumentMode m);
+
+ nsIContentHandle* getDocumentFragmentForTemplate(nsIContentHandle* aTemplate);
+
+ nsIContentHandle* getFormPointerForContext(nsIContentHandle* aContext);
+
+ /**
+ * Using nsIContent** instead of nsIContent* is the parser deals with DOM
+ * nodes in a way that works off the main thread. Non-main-thread code
+ * can't refcount or otherwise touch nsIContent objects in any way.
+ * Yet, the off-the-main-thread code needs to have a way to hold onto a
+ * particular node and repeatedly operate on the same node.
+ *
+ * The way this works is that the off-the-main-thread code has an
+ * nsIContent** for each DOM node and a given nsIContent** is only ever
+ * actually dereferenced into an actual nsIContent* on the main thread.
+ * When the off-the-main-thread code requests a new node, it gets an
+ * nsIContent** immediately and a tree op is enqueued for later allocating
+ * an actual nsIContent object and writing a pointer to it into the memory
+ * location pointed to by the nsIContent**.
+ *
+ * Since tree ops are in a queue, the node creating tree op will always
+ * run before tree ops that try to further operate on the node that the
+ * nsIContent** is a handle to.
+ *
+ * On-the-main-thread parts of the parser use nsIContent* instead of
+ * nsIContent**. Since both cases share the same parser core, the parser
+ * core casts both to nsIContentHandle*.
+ */
+ nsIContentHandle* AllocateContentHandle();
+
+ void accumulateCharactersForced(const char16_t* aBuf, int32_t aStart, int32_t aLength)
+ {
+ accumulateCharacters(aBuf, aStart, aLength);
+ }
+
+ void MarkAsBrokenAndRequestSuspension(nsresult aRv)
+ {
+ mBuilder->MarkAsBroken(aRv);
+ requestSuspension();
+ }
+
+ void MarkAsBrokenFromPortability(nsresult aRv);
+
+ public:
+
+ explicit nsHtml5TreeBuilder(nsHtml5OplessBuilder* aBuilder);
+
+ nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,
+ nsHtml5TreeOpStage* aStage);
+
+ ~nsHtml5TreeBuilder();
+
+ void StartPlainTextViewSource(const nsAutoString& aTitle);
+
+ void StartPlainText();
+
+ void StartPlainTextBody();
+
+ bool HasScript();
+
+ void SetOpSink(nsAHtml5TreeOpSink* aOpSink)
+ {
+ mOpSink = aOpSink;
+ }
+
+ void ClearOps()
+ {
+ mOpQueue.Clear();
+ }
+
+ bool Flush(bool aDiscretionary = false);
+
+ void FlushLoads();
+
+ void SetDocumentCharset(nsACString& aCharset, int32_t aCharsetSource);
+
+ void StreamEnded();
+
+ void NeedsCharsetSwitchTo(const nsACString& aEncoding,
+ int32_t aSource,
+ int32_t aLineNumber);
+
+ void MaybeComplainAboutCharset(const char* aMsgId,
+ bool aError,
+ int32_t aLineNumber);
+
+ void AddSnapshotToScript(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine);
+
+ void DropHandles();
+
+ void SetPreventScriptExecution(bool aPrevent)
+ {
+ mPreventScriptExecution = aPrevent;
+ }
+
+ bool HasBuilder()
+ {
+ return mBuilder;
+ }
+
+ /**
+ * Makes sure the buffers are large enough to be able to tokenize aLength
+ * UTF-16 code units before having to make the buffers larger.
+ *
+ * @param aLength the number of UTF-16 code units to be tokenized before the
+ * next call to this method.
+ * @return true if successful; false if out of memory
+ */
+ bool EnsureBufferSpace(int32_t aLength);
+
+ void EnableViewSource(nsHtml5Highlighter* aHighlighter);
+
+ void errStrayStartTag(nsIAtom* aName);
+
+ void errStrayEndTag(nsIAtom* aName);
+
+ void errUnclosedElements(int32_t aIndex, nsIAtom* aName);
+
+ void errUnclosedElementsImplied(int32_t aIndex, nsIAtom* aName);
+
+ void errUnclosedElementsCell(int32_t aIndex);
+
+ void errStrayDoctype();
+
+ void errAlmostStandardsDoctype();
+
+ void errQuirkyDoctype();
+
+ void errNonSpaceInTrailer();
+
+ void errNonSpaceAfterFrameset();
+
+ void errNonSpaceInFrameset();
+
+ void errNonSpaceAfterBody();
+
+ void errNonSpaceInColgroupInFragment();
+
+ void errNonSpaceInNoscriptInHead();
+
+ void errFooBetweenHeadAndBody(nsIAtom* aName);
+
+ void errStartTagWithoutDoctype();
+
+ void errNoSelectInTableScope();
+
+ void errStartSelectWhereEndSelectExpected();
+
+ void errStartTagWithSelectOpen(nsIAtom* aName);
+
+ void errBadStartTagInHead(nsIAtom* aName);
+
+ void errImage();
+
+ void errIsindex();
+
+ void errFooSeenWhenFooOpen(nsIAtom* aName);
+
+ void errHeadingWhenHeadingOpen();
+
+ void errFramesetStart();
+
+ void errNoCellToClose();
+
+ void errStartTagInTable(nsIAtom* aName);
+
+ void errFormWhenFormOpen();
+
+ void errTableSeenWhileTableOpen();
+
+ void errStartTagInTableBody(nsIAtom* aName);
+
+ void errEndTagSeenWithoutDoctype();
+
+ void errEndTagAfterBody();
+
+ void errEndTagSeenWithSelectOpen(nsIAtom* aName);
+
+ void errGarbageInColgroup();
+
+ void errEndTagBr();
+
+ void errNoElementToCloseButEndTagSeen(nsIAtom* aName);
+
+ void errHtmlStartTagInForeignContext(nsIAtom* aName);
+
+ void errTableClosedWhileCaptionOpen();
+
+ void errNoTableRowToClose();
+
+ void errNonSpaceInTable();
+
+ void errUnclosedChildrenInRuby();
+
+ void errStartTagSeenWithoutRuby(nsIAtom* aName);
+
+ void errSelfClosing();
+
+ void errNoCheckUnclosedElementsOnStack();
+
+ void errEndTagDidNotMatchCurrentOpenElement(nsIAtom* aName, nsIAtom* aOther);
+
+ void errEndTagViolatesNestingRules(nsIAtom* aName);
+
+ void errEndWithUnclosedElements(nsIAtom* aName);
+
+ void MarkAsBroken(nsresult aRv);
+
+ /**
+ * Checks if this parser is broken. Returns a non-NS_OK (i.e. non-0)
+ * value if broken.
+ */
+ nsresult IsBroken()
+ {
+ return mBroken;
+ }
diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp
new file mode 100644
index 000000000..b0eabb13d
--- /dev/null
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -0,0 +1,1085 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=2 et tw=79: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/DebugOnly.h"
+#include "mozilla/Likely.h"
+#include "mozilla/dom/nsCSPService.h"
+
+#include "nsError.h"
+#include "nsHtml5TreeOpExecutor.h"
+#include "nsScriptLoader.h"
+#include "nsIContentViewer.h"
+#include "nsIContentSecurityPolicy.h"
+#include "nsIDocShellTreeItem.h"
+#include "nsIDocShell.h"
+#include "nsIDOMDocument.h"
+#include "nsIScriptGlobalObject.h"
+#include "nsIWebShellServices.h"
+#include "nsContentUtils.h"
+#include "mozAutoDocUpdate.h"
+#include "nsNetUtil.h"
+#include "nsHtml5Parser.h"
+#include "nsHtml5Tokenizer.h"
+#include "nsHtml5TreeBuilder.h"
+#include "nsHtml5StreamParser.h"
+#include "mozilla/css/Loader.h"
+#include "GeckoProfiler.h"
+#include "nsIScriptError.h"
+#include "nsIScriptContext.h"
+#include "mozilla/Preferences.h"
+#include "nsIHTMLDocument.h"
+#include "nsIViewSourceChannel.h"
+#include "xpcpublic.h"
+
+using namespace mozilla;
+
+NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHtml5TreeOpExecutor)
+ NS_INTERFACE_TABLE_INHERITED(nsHtml5TreeOpExecutor,
+ nsIContentSink)
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsHtml5DocumentBuilder)
+
+NS_IMPL_ADDREF_INHERITED(nsHtml5TreeOpExecutor, nsContentSink)
+
+NS_IMPL_RELEASE_INHERITED(nsHtml5TreeOpExecutor, nsContentSink)
+
+class nsHtml5ExecutorReflusher : public Runnable
+{
+ private:
+ RefPtr<nsHtml5TreeOpExecutor> mExecutor;
+ public:
+ explicit nsHtml5ExecutorReflusher(nsHtml5TreeOpExecutor* aExecutor)
+ : mExecutor(aExecutor)
+ {}
+ NS_IMETHOD Run() override
+ {
+ mExecutor->RunFlushLoop();
+ return NS_OK;
+ }
+};
+
+static mozilla::LinkedList<nsHtml5TreeOpExecutor>* gBackgroundFlushList = nullptr;
+static nsITimer* gFlushTimer = nullptr;
+
+nsHtml5TreeOpExecutor::nsHtml5TreeOpExecutor()
+ : nsHtml5DocumentBuilder(false)
+ , mPreloadedURLs(23) // Mean # of preloadable resources per page on dmoz
+ , mSpeculationReferrerPolicy(mozilla::net::RP_Default)
+{
+ // zeroing operator new for everything else
+}
+
+nsHtml5TreeOpExecutor::~nsHtml5TreeOpExecutor()
+{
+ if (gBackgroundFlushList && isInList()) {
+ mOpQueue.Clear();
+ removeFrom(*gBackgroundFlushList);
+ if (gBackgroundFlushList->isEmpty()) {
+ delete gBackgroundFlushList;
+ gBackgroundFlushList = nullptr;
+ if (gFlushTimer) {
+ gFlushTimer->Cancel();
+ NS_RELEASE(gFlushTimer);
+ }
+ }
+ }
+ NS_ASSERTION(mOpQueue.IsEmpty(), "Somehow there's stuff in the op queue.");
+}
+
+// nsIContentSink
+NS_IMETHODIMP
+nsHtml5TreeOpExecutor::WillParse()
+{
+ NS_NOTREACHED("No one should call this");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsHtml5TreeOpExecutor::WillBuildModel(nsDTDMode aDTDMode)
+{
+ mDocument->AddObserver(this);
+ WillBuildModelImpl();
+ GetDocument()->BeginLoad();
+ if (mDocShell && !GetDocument()->GetWindow() &&
+ !IsExternalViewSource()) {
+ // Not loading as data but script global object not ready
+ return MarkAsBroken(NS_ERROR_DOM_INVALID_STATE_ERR);
+ }
+ return NS_OK;
+}
+
+
+// This is called when the tree construction has ended
+NS_IMETHODIMP
+nsHtml5TreeOpExecutor::DidBuildModel(bool aTerminated)
+{
+ if (!aTerminated) {
+ // This is needed to avoid unblocking loads too many times on one hand
+ // and on the other hand to avoid destroying the frame constructor from
+ // within an update batch. See bug 537683.
+ EndDocUpdate();
+
+ // If the above caused a call to nsIParser::Terminate(), let that call
+ // win.
+ if (!mParser) {
+ return NS_OK;
+ }
+ }
+
+ if (mRunsToCompletion) {
+ return NS_OK;
+ }
+
+ GetParser()->DropStreamParser();
+
+ // This comes from nsXMLContentSink and nsHTMLContentSink
+ // If this parser has been marked as broken, treat the end of parse as
+ // forced termination.
+ DidBuildModelImpl(aTerminated || NS_FAILED(IsBroken()));
+
+ if (!mLayoutStarted) {
+ // We never saw the body, and layout never got started. Force
+ // layout *now*, to get an initial reflow.
+
+ // NOTE: only force the layout if we are NOT destroying the
+ // docshell. If we are destroying it, then starting layout will
+ // likely cause us to crash, or at best waste a lot of time as we
+ // are just going to tear it down anyway.
+ bool destroying = true;
+ if (mDocShell) {
+ mDocShell->IsBeingDestroyed(&destroying);
+ }
+
+ if (!destroying) {
+ nsContentSink::StartLayout(false);
+ }
+ }
+
+ ScrollToRef();
+ mDocument->RemoveObserver(this);
+ if (!mParser) {
+ // DidBuildModelImpl may cause mParser to be nulled out
+ // Return early to avoid unblocking the onload event too many times.
+ return NS_OK;
+ }
+
+ // We may not have called BeginLoad() if loading is terminated before
+ // OnStartRequest call.
+ if (mStarted) {
+ mDocument->EndLoad();
+ }
+ DropParserAndPerfHint();
+#ifdef GATHER_DOCWRITE_STATISTICS
+ printf("UNSAFE SCRIPTS: %d\n", sUnsafeDocWrites);
+ printf("TOKENIZER-SAFE SCRIPTS: %d\n", sTokenSafeDocWrites);
+ printf("TREEBUILDER-SAFE SCRIPTS: %d\n", sTreeSafeDocWrites);
+#endif
+#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
+ printf("MAX NOTIFICATION BATCH LEN: %d\n", sAppendBatchMaxSize);
+ if (sAppendBatchExaminations != 0) {
+ printf("AVERAGE SLOTS EXAMINED: %d\n", sAppendBatchSlotsExamined / sAppendBatchExaminations);
+ }
+#endif
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHtml5TreeOpExecutor::WillInterrupt()
+{
+ NS_NOTREACHED("Don't call. For interface compat only.");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsHtml5TreeOpExecutor::WillResume()
+{
+ NS_NOTREACHED("Don't call. For interface compat only.");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsHtml5TreeOpExecutor::SetParser(nsParserBase* aParser)
+{
+ mParser = aParser;
+ return NS_OK;
+}
+
+void
+nsHtml5TreeOpExecutor::FlushPendingNotifications(mozFlushType aType)
+{
+ if (aType >= Flush_InterruptibleLayout) {
+ // Bug 577508 / 253951
+ nsContentSink::StartLayout(true);
+ }
+}
+
+nsISupports*
+nsHtml5TreeOpExecutor::GetTarget()
+{
+ return mDocument;
+}
+
+nsresult
+nsHtml5TreeOpExecutor::MarkAsBroken(nsresult aReason)
+{
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ mBroken = aReason;
+ if (mStreamParser) {
+ mStreamParser->Terminate();
+ }
+ // We are under memory pressure, but let's hope the following allocation
+ // works out so that we get to terminate and clean up the parser from
+ // a safer point.
+ if (mParser) { // can mParser ever be null here?
+ MOZ_ALWAYS_SUCCEEDS(
+ NS_DispatchToMainThread(NewRunnableMethod(GetParser(), &nsHtml5Parser::Terminate)));
+ }
+ return aReason;
+}
+
+void
+FlushTimerCallback(nsITimer* aTimer, void* aClosure)
+{
+ RefPtr<nsHtml5TreeOpExecutor> ex = gBackgroundFlushList->popFirst();
+ if (ex) {
+ ex->RunFlushLoop();
+ }
+ if (gBackgroundFlushList && gBackgroundFlushList->isEmpty()) {
+ delete gBackgroundFlushList;
+ gBackgroundFlushList = nullptr;
+ gFlushTimer->Cancel();
+ NS_RELEASE(gFlushTimer);
+ }
+}
+
+void
+nsHtml5TreeOpExecutor::ContinueInterruptedParsingAsync()
+{
+ if (!mDocument || !mDocument->IsInBackgroundWindow()) {
+ nsCOMPtr<nsIRunnable> flusher = new nsHtml5ExecutorReflusher(this);
+ if (NS_FAILED(NS_DispatchToMainThread(flusher))) {
+ NS_WARNING("failed to dispatch executor flush event");
+ }
+ } else {
+ if (!gBackgroundFlushList) {
+ gBackgroundFlushList = new mozilla::LinkedList<nsHtml5TreeOpExecutor>();
+ }
+ if (!isInList()) {
+ gBackgroundFlushList->insertBack(this);
+ }
+ if (!gFlushTimer) {
+ nsCOMPtr<nsITimer> t = do_CreateInstance("@mozilla.org/timer;1");
+ t.swap(gFlushTimer);
+ // The timer value 50 should not hopefully slow down background pages too
+ // much, yet lets event loop to process enough between ticks.
+ // See bug 734015.
+ gFlushTimer->InitWithNamedFuncCallback(FlushTimerCallback, nullptr,
+ 50, nsITimer::TYPE_REPEATING_SLACK,
+ "FlushTimerCallback");
+ }
+ }
+}
+
+void
+nsHtml5TreeOpExecutor::FlushSpeculativeLoads()
+{
+ nsTArray<nsHtml5SpeculativeLoad> speculativeLoadQueue;
+ mStage.MoveSpeculativeLoadsTo(speculativeLoadQueue);
+ const nsHtml5SpeculativeLoad* start = speculativeLoadQueue.Elements();
+ const nsHtml5SpeculativeLoad* end = start + speculativeLoadQueue.Length();
+ for (nsHtml5SpeculativeLoad* iter = const_cast<nsHtml5SpeculativeLoad*>(start);
+ iter < end;
+ ++iter) {
+ if (MOZ_UNLIKELY(!mParser)) {
+ // An extension terminated the parser from a HTTP observer.
+ return;
+ }
+ iter->Perform(this);
+ }
+}
+
+class nsHtml5FlushLoopGuard
+{
+ private:
+ RefPtr<nsHtml5TreeOpExecutor> mExecutor;
+ #ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
+ uint32_t mStartTime;
+ #endif
+ public:
+ explicit nsHtml5FlushLoopGuard(nsHtml5TreeOpExecutor* aExecutor)
+ : mExecutor(aExecutor)
+ #ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
+ , mStartTime(PR_IntervalToMilliseconds(PR_IntervalNow()))
+ #endif
+ {
+ mExecutor->mRunFlushLoopOnStack = true;
+ }
+ ~nsHtml5FlushLoopGuard()
+ {
+ #ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
+ uint32_t timeOffTheEventLoop =
+ PR_IntervalToMilliseconds(PR_IntervalNow()) - mStartTime;
+ if (timeOffTheEventLoop >
+ nsHtml5TreeOpExecutor::sLongestTimeOffTheEventLoop) {
+ nsHtml5TreeOpExecutor::sLongestTimeOffTheEventLoop =
+ timeOffTheEventLoop;
+ }
+ printf("Longest time off the event loop: %d\n",
+ nsHtml5TreeOpExecutor::sLongestTimeOffTheEventLoop);
+ #endif
+
+ mExecutor->mRunFlushLoopOnStack = false;
+ }
+};
+
+/**
+ * The purpose of the loop here is to avoid returning to the main event loop
+ */
+void
+nsHtml5TreeOpExecutor::RunFlushLoop()
+{
+ PROFILER_LABEL("nsHtml5TreeOpExecutor", "RunFlushLoop",
+ js::ProfileEntry::Category::OTHER);
+
+ if (mRunFlushLoopOnStack) {
+ // There's already a RunFlushLoop() on the call stack.
+ return;
+ }
+
+ nsHtml5FlushLoopGuard guard(this); // this is also the self-kungfu!
+
+ RefPtr<nsParserBase> parserKungFuDeathGrip(mParser);
+
+ // Remember the entry time
+ (void) nsContentSink::WillParseImpl();
+
+ for (;;) {
+ if (!mParser) {
+ // Parse has terminated.
+ mOpQueue.Clear(); // clear in order to be able to assert in destructor
+ return;
+ }
+
+ if (NS_FAILED(IsBroken())) {
+ return;
+ }
+
+ if (!parserKungFuDeathGrip->IsParserEnabled()) {
+ // The parser is blocked.
+ return;
+ }
+
+ if (mFlushState != eNotFlushing) {
+ // XXX Can this happen? In case it can, let's avoid crashing.
+ return;
+ }
+
+ // If there are scripts executing, then the content sink is jumping the gun
+ // (probably due to a synchronous XMLHttpRequest) and will re-enable us
+ // later, see bug 460706.
+ if (IsScriptExecuting()) {
+ return;
+ }
+
+ if (mReadingFromStage) {
+ nsTArray<nsHtml5SpeculativeLoad> speculativeLoadQueue;
+ mStage.MoveOpsAndSpeculativeLoadsTo(mOpQueue, speculativeLoadQueue);
+ // Make sure speculative loads never start after the corresponding
+ // normal loads for the same URLs.
+ const nsHtml5SpeculativeLoad* start = speculativeLoadQueue.Elements();
+ const nsHtml5SpeculativeLoad* end = start + speculativeLoadQueue.Length();
+ for (nsHtml5SpeculativeLoad* iter = (nsHtml5SpeculativeLoad*)start;
+ iter < end;
+ ++iter) {
+ iter->Perform(this);
+ if (MOZ_UNLIKELY(!mParser)) {
+ // An extension terminated the parser from a HTTP observer.
+ mOpQueue.Clear(); // clear in order to be able to assert in destructor
+ return;
+ }
+ }
+ } else {
+ FlushSpeculativeLoads(); // Make sure speculative loads never start after
+ // the corresponding normal loads for the same
+ // URLs.
+ if (MOZ_UNLIKELY(!mParser)) {
+ // An extension terminated the parser from a HTTP observer.
+ mOpQueue.Clear(); // clear in order to be able to assert in destructor
+ return;
+ }
+ // Not sure if this grip is still needed, but previously, the code
+ // gripped before calling ParseUntilBlocked();
+ RefPtr<nsHtml5StreamParser> streamKungFuDeathGrip =
+ GetParser()->GetStreamParser();
+ mozilla::Unused << streamKungFuDeathGrip; // Not used within function
+ // Now parse content left in the document.write() buffer queue if any.
+ // This may generate tree ops on its own or dequeue a speculation.
+ nsresult rv = GetParser()->ParseUntilBlocked();
+ if (NS_FAILED(rv)) {
+ MarkAsBroken(rv);
+ return;
+ }
+ }
+
+ if (mOpQueue.IsEmpty()) {
+ // Avoid bothering the rest of the engine with a doc update if there's
+ // nothing to do.
+ return;
+ }
+
+ mFlushState = eInFlush;
+
+ nsIContent* scriptElement = nullptr;
+
+ BeginDocUpdate();
+
+ uint32_t numberOfOpsToFlush = mOpQueue.Length();
+
+ const nsHtml5TreeOperation* first = mOpQueue.Elements();
+ const nsHtml5TreeOperation* last = first + numberOfOpsToFlush - 1;
+ for (nsHtml5TreeOperation* iter = const_cast<nsHtml5TreeOperation*>(first);;) {
+ if (MOZ_UNLIKELY(!mParser)) {
+ // The previous tree op caused a call to nsIParser::Terminate().
+ break;
+ }
+ NS_ASSERTION(mFlushState == eInDocUpdate,
+ "Tried to perform tree op outside update batch.");
+ nsresult rv = iter->Perform(this, &scriptElement);
+ if (NS_FAILED(rv)) {
+ MarkAsBroken(rv);
+ break;
+ }
+
+ // Be sure not to check the deadline if the last op was just performed.
+ if (MOZ_UNLIKELY(iter == last)) {
+ break;
+ } else if (MOZ_UNLIKELY(nsContentSink::DidProcessATokenImpl() ==
+ NS_ERROR_HTMLPARSER_INTERRUPTED)) {
+ mOpQueue.RemoveElementsAt(0, (iter - first) + 1);
+
+ EndDocUpdate();
+
+ mFlushState = eNotFlushing;
+
+ #ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
+ printf("REFLUSH SCHEDULED (executing ops): %d\n",
+ ++sTimesFlushLoopInterrupted);
+ #endif
+ nsHtml5TreeOpExecutor::ContinueInterruptedParsingAsync();
+ return;
+ }
+ ++iter;
+ }
+
+ mOpQueue.Clear();
+
+ EndDocUpdate();
+
+ mFlushState = eNotFlushing;
+
+ if (MOZ_UNLIKELY(!mParser)) {
+ // The parse ended already.
+ return;
+ }
+
+ if (scriptElement) {
+ // must be tail call when mFlushState is eNotFlushing
+ RunScript(scriptElement);
+
+ // Always check the clock in nsContentSink right after a script
+ StopDeflecting();
+ if (nsContentSink::DidProcessATokenImpl() ==
+ NS_ERROR_HTMLPARSER_INTERRUPTED) {
+ #ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
+ printf("REFLUSH SCHEDULED (after script): %d\n",
+ ++sTimesFlushLoopInterrupted);
+ #endif
+ nsHtml5TreeOpExecutor::ContinueInterruptedParsingAsync();
+ return;
+ }
+ }
+ }
+}
+
+nsresult
+nsHtml5TreeOpExecutor::FlushDocumentWrite()
+{
+ nsresult rv = IsBroken();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ FlushSpeculativeLoads(); // Make sure speculative loads never start after the
+ // corresponding normal loads for the same URLs.
+
+ if (MOZ_UNLIKELY(!mParser)) {
+ // The parse has ended.
+ mOpQueue.Clear(); // clear in order to be able to assert in destructor
+ return rv;
+ }
+
+ if (mFlushState != eNotFlushing) {
+ // XXX Can this happen? In case it can, let's avoid crashing.
+ return rv;
+ }
+
+ mFlushState = eInFlush;
+
+ // avoid crashing near EOF
+ RefPtr<nsHtml5TreeOpExecutor> kungFuDeathGrip(this);
+ RefPtr<nsParserBase> parserKungFuDeathGrip(mParser);
+ mozilla::Unused << parserKungFuDeathGrip; // Intentionally not used within function
+
+ NS_ASSERTION(!mReadingFromStage,
+ "Got doc write flush when reading from stage");
+
+#ifdef DEBUG
+ mStage.AssertEmpty();
+#endif
+
+ nsIContent* scriptElement = nullptr;
+
+ BeginDocUpdate();
+
+ uint32_t numberOfOpsToFlush = mOpQueue.Length();
+
+ const nsHtml5TreeOperation* start = mOpQueue.Elements();
+ const nsHtml5TreeOperation* end = start + numberOfOpsToFlush;
+ for (nsHtml5TreeOperation* iter = const_cast<nsHtml5TreeOperation*>(start);
+ iter < end;
+ ++iter) {
+ if (MOZ_UNLIKELY(!mParser)) {
+ // The previous tree op caused a call to nsIParser::Terminate().
+ break;
+ }
+ NS_ASSERTION(mFlushState == eInDocUpdate,
+ "Tried to perform tree op outside update batch.");
+ rv = iter->Perform(this, &scriptElement);
+ if (NS_FAILED(rv)) {
+ MarkAsBroken(rv);
+ break;
+ }
+ }
+
+ mOpQueue.Clear();
+
+ EndDocUpdate();
+
+ mFlushState = eNotFlushing;
+
+ if (MOZ_UNLIKELY(!mParser)) {
+ // Ending the doc update caused a call to nsIParser::Terminate().
+ return rv;
+ }
+
+ if (scriptElement) {
+ // must be tail call when mFlushState is eNotFlushing
+ RunScript(scriptElement);
+ }
+ return rv;
+}
+
+// copied from HTML content sink
+bool
+nsHtml5TreeOpExecutor::IsScriptEnabled()
+{
+ // Note that if we have no document or no docshell or no global or whatnot we
+ // want to claim script _is_ enabled, so we don't parse the contents of
+ // <noscript> tags!
+ if (!mDocument || !mDocShell)
+ return true;
+ nsCOMPtr<nsIScriptGlobalObject> globalObject = do_QueryInterface(mDocument->GetInnerWindow());
+ // Getting context is tricky if the document hasn't had its
+ // GlobalObject set yet
+ if (!globalObject) {
+ globalObject = mDocShell->GetScriptGlobalObject();
+ }
+ NS_ENSURE_TRUE(globalObject && globalObject->GetGlobalJSObject(), true);
+ return xpc::Scriptability::Get(globalObject->GetGlobalJSObject()).Allowed();
+}
+
+void
+nsHtml5TreeOpExecutor::StartLayout() {
+ if (mLayoutStarted || !mDocument) {
+ return;
+ }
+
+ EndDocUpdate();
+
+ if (MOZ_UNLIKELY(!mParser)) {
+ // got terminate
+ return;
+ }
+
+ nsContentSink::StartLayout(false);
+
+ BeginDocUpdate();
+}
+
+/**
+ * The reason why this code is here and not in the tree builder even in the
+ * main-thread case is to allow the control to return from the tokenizer
+ * before scripts run. This way, the tokenizer is not invoked re-entrantly
+ * although the parser is.
+ *
+ * The reason why this is called as a tail call when mFlushState is set to
+ * eNotFlushing is to allow re-entry to Flush() but only after the current
+ * Flush() has cleared the op queue and is otherwise done cleaning up after
+ * itself.
+ */
+void
+nsHtml5TreeOpExecutor::RunScript(nsIContent* aScriptElement)
+{
+ if (mRunsToCompletion) {
+ // We are in createContextualFragment() or in the upcoming document.parse().
+ // Do nothing. Let's not even mark scripts malformed here, because that
+ // could cause serialization weirdness later.
+ return;
+ }
+
+ NS_ASSERTION(aScriptElement, "No script to run");
+ nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(aScriptElement);
+
+ if (!mParser) {
+ NS_ASSERTION(sele->IsMalformed(), "Script wasn't marked as malformed.");
+ // We got here not because of an end tag but because the tree builder
+ // popped an incomplete script element on EOF. Returning here to avoid
+ // calling back into mParser anymore.
+ return;
+ }
+
+ if (sele->GetScriptDeferred() || sele->GetScriptAsync()) {
+ DebugOnly<bool> block = sele->AttemptToExecute();
+ NS_ASSERTION(!block, "Defer or async script tried to block.");
+ return;
+ }
+
+ NS_ASSERTION(mFlushState == eNotFlushing, "Tried to run script when flushing.");
+
+ mReadingFromStage = false;
+
+ sele->SetCreatorParser(GetParser());
+
+ // Copied from nsXMLContentSink
+ // Now tell the script that it's ready to go. This may execute the script
+ // or return true, or neither if the script doesn't need executing.
+ bool block = sele->AttemptToExecute();
+
+ // If the act of insertion evaluated the script, we're fine.
+ // Else, block the parser till the script has loaded.
+ if (block) {
+ if (mParser) {
+ GetParser()->BlockParser();
+ }
+ } else {
+ // mParser may have been nulled out by now, but the flusher deals
+
+ // If this event isn't needed, it doesn't do anything. It is sometimes
+ // necessary for the parse to continue after complex situations.
+ nsHtml5TreeOpExecutor::ContinueInterruptedParsingAsync();
+ }
+}
+
+void
+nsHtml5TreeOpExecutor::Start()
+{
+ NS_PRECONDITION(!mStarted, "Tried to start when already started.");
+ mStarted = true;
+}
+
+void
+nsHtml5TreeOpExecutor::NeedsCharsetSwitchTo(const char* aEncoding,
+ int32_t aSource,
+ uint32_t aLineNumber)
+{
+ EndDocUpdate();
+
+ if (MOZ_UNLIKELY(!mParser)) {
+ // got terminate
+ return;
+ }
+
+ nsCOMPtr<nsIWebShellServices> wss = do_QueryInterface(mDocShell);
+ if (!wss) {
+ return;
+ }
+
+ // ask the webshellservice to load the URL
+ if (NS_SUCCEEDED(wss->StopDocumentLoad())) {
+ wss->ReloadDocument(aEncoding, aSource);
+ }
+ // if the charset switch was accepted, wss has called Terminate() on the
+ // parser by now
+
+ if (!mParser) {
+ // success
+ if (aSource == kCharsetFromMetaTag) {
+ MaybeComplainAboutCharset("EncLateMetaReload", false, aLineNumber);
+ }
+ return;
+ }
+
+ if (aSource == kCharsetFromMetaTag) {
+ MaybeComplainAboutCharset("EncLateMetaTooLate", true, aLineNumber);
+ }
+
+ GetParser()->ContinueAfterFailedCharsetSwitch();
+
+ BeginDocUpdate();
+}
+
+void
+nsHtml5TreeOpExecutor::MaybeComplainAboutCharset(const char* aMsgId,
+ bool aError,
+ uint32_t aLineNumber)
+{
+ if (mAlreadyComplainedAboutCharset) {
+ return;
+ }
+ // The EncNoDeclaration case for advertising iframes is so common that it
+ // would result is way too many errors. The iframe case doesn't matter
+ // when the ad is an image or a Flash animation anyway. When the ad is
+ // textual, a misrendered ad probably isn't a huge loss for users.
+ // Let's suppress the message in this case.
+ // This means that errors about other different-origin iframes in mashups
+ // are lost as well, but generally, the site author isn't in control of
+ // the embedded different-origin pages anyway and can't fix problems even
+ // if alerted about them.
+ if (!strcmp(aMsgId, "EncNoDeclaration") && mDocShell) {
+ nsCOMPtr<nsIDocShellTreeItem> parent;
+ mDocShell->GetSameTypeParent(getter_AddRefs(parent));
+ if (parent) {
+ return;
+ }
+ }
+ mAlreadyComplainedAboutCharset = true;
+ nsContentUtils::ReportToConsole(aError ? nsIScriptError::errorFlag
+ : nsIScriptError::warningFlag,
+ NS_LITERAL_CSTRING("HTML parser"),
+ mDocument,
+ nsContentUtils::eHTMLPARSER_PROPERTIES,
+ aMsgId,
+ nullptr,
+ 0,
+ nullptr,
+ EmptyString(),
+ aLineNumber);
+}
+
+void
+nsHtml5TreeOpExecutor::ComplainAboutBogusProtocolCharset(nsIDocument* aDoc)
+{
+ NS_ASSERTION(!mAlreadyComplainedAboutCharset,
+ "How come we already managed to complain?");
+ mAlreadyComplainedAboutCharset = true;
+ nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
+ NS_LITERAL_CSTRING("HTML parser"),
+ aDoc,
+ nsContentUtils::eHTMLPARSER_PROPERTIES,
+ "EncProtocolUnsupported");
+}
+
+nsHtml5Parser*
+nsHtml5TreeOpExecutor::GetParser()
+{
+ MOZ_ASSERT(!mRunsToCompletion);
+ return static_cast<nsHtml5Parser*>(mParser.get());
+}
+
+void
+nsHtml5TreeOpExecutor::MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue)
+{
+ NS_PRECONDITION(mFlushState == eNotFlushing, "mOpQueue modified during tree op execution.");
+ mOpQueue.AppendElements(Move(aOpQueue));
+}
+
+void
+nsHtml5TreeOpExecutor::InitializeDocWriteParserState(nsAHtml5TreeBuilderState* aState, int32_t aLine)
+{
+ GetParser()->InitializeDocWriteParserState(aState, aLine);
+}
+
+nsIURI*
+nsHtml5TreeOpExecutor::GetViewSourceBaseURI()
+{
+ if (!mViewSourceBaseURI) {
+
+ // We query the channel for the baseURI because in certain situations it
+ // cannot otherwise be determined. If this process fails, fall back to the
+ // standard method.
+ nsCOMPtr<nsIViewSourceChannel> vsc =
+ do_QueryInterface(mDocument->GetChannel());
+ if (vsc) {
+ nsresult rv = vsc->GetBaseURI(getter_AddRefs(mViewSourceBaseURI));
+ if (NS_SUCCEEDED(rv) && mViewSourceBaseURI) {
+ return mViewSourceBaseURI;
+ }
+ }
+
+ nsCOMPtr<nsIURI> orig = mDocument->GetOriginalURI();
+ bool isViewSource;
+ orig->SchemeIs("view-source", &isViewSource);
+ if (isViewSource) {
+ nsCOMPtr<nsINestedURI> nested = do_QueryInterface(orig);
+ NS_ASSERTION(nested, "URI with scheme view-source didn't QI to nested!");
+ nested->GetInnerURI(getter_AddRefs(mViewSourceBaseURI));
+ } else {
+ // Fail gracefully if the base URL isn't a view-source: URL.
+ // Not sure if this can ever happen.
+ mViewSourceBaseURI = orig;
+ }
+ }
+ return mViewSourceBaseURI;
+}
+
+//static
+void
+nsHtml5TreeOpExecutor::InitializeStatics()
+{
+ mozilla::Preferences::AddBoolVarCache(&sExternalViewSource,
+ "view_source.editor.external");
+}
+
+bool
+nsHtml5TreeOpExecutor::IsExternalViewSource()
+{
+ if (!sExternalViewSource) {
+ return false;
+ }
+ bool isViewSource = false;
+ if (mDocumentURI) {
+ mDocumentURI->SchemeIs("view-source", &isViewSource);
+ }
+ return isViewSource;
+}
+
+// Speculative loading
+
+nsIURI*
+nsHtml5TreeOpExecutor::BaseURIForPreload()
+{
+ // The URL of the document without <base>
+ nsIURI* documentURI = mDocument->GetDocumentURI();
+ // The URL of the document with non-speculative <base>
+ nsIURI* documentBaseURI = mDocument->GetDocBaseURI();
+
+ // If the two above are different, use documentBaseURI. If they are the same,
+ // the document object isn't aware of a <base>, so attempt to use the
+ // mSpeculationBaseURI or, failing, that, documentURI.
+ return (documentURI == documentBaseURI) ?
+ (mSpeculationBaseURI ?
+ mSpeculationBaseURI.get() : documentURI)
+ : documentBaseURI;
+}
+
+already_AddRefed<nsIURI>
+nsHtml5TreeOpExecutor::ConvertIfNotPreloadedYet(const nsAString& aURL)
+{
+ if (aURL.IsEmpty()) {
+ return nullptr;
+ }
+
+ nsIURI* base = BaseURIForPreload();
+ const nsCString& charset = mDocument->GetDocumentCharacterSet();
+ nsCOMPtr<nsIURI> uri;
+ nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, charset.get(), base);
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Failed to create a URI");
+ return nullptr;
+ }
+
+ if (ShouldPreloadURI(uri)) {
+ return uri.forget();
+ }
+
+ return nullptr;
+}
+
+bool
+nsHtml5TreeOpExecutor::ShouldPreloadURI(nsIURI *aURI)
+{
+ nsAutoCString spec;
+ nsresult rv = aURI->GetSpec(spec);
+ NS_ENSURE_SUCCESS(rv, false);
+ if (mPreloadedURLs.Contains(spec)) {
+ return false;
+ }
+ mPreloadedURLs.PutEntry(spec);
+ return true;
+}
+
+void
+nsHtml5TreeOpExecutor::PreloadScript(const nsAString& aURL,
+ const nsAString& aCharset,
+ const nsAString& aType,
+ const nsAString& aCrossOrigin,
+ const nsAString& aIntegrity,
+ bool aScriptFromHead)
+{
+ nsCOMPtr<nsIURI> uri = ConvertIfNotPreloadedYet(aURL);
+ if (!uri) {
+ return;
+ }
+ mDocument->ScriptLoader()->PreloadURI(uri, aCharset, aType, aCrossOrigin,
+ aIntegrity, aScriptFromHead,
+ mSpeculationReferrerPolicy);
+}
+
+void
+nsHtml5TreeOpExecutor::PreloadStyle(const nsAString& aURL,
+ const nsAString& aCharset,
+ const nsAString& aCrossOrigin,
+ const nsAString& aIntegrity)
+{
+ nsCOMPtr<nsIURI> uri = ConvertIfNotPreloadedYet(aURL);
+ if (!uri) {
+ return;
+ }
+ mDocument->PreloadStyle(uri, aCharset, aCrossOrigin,
+ mSpeculationReferrerPolicy, aIntegrity);
+}
+
+void
+nsHtml5TreeOpExecutor::PreloadImage(const nsAString& aURL,
+ const nsAString& aCrossOrigin,
+ const nsAString& aSrcset,
+ const nsAString& aSizes,
+ const nsAString& aImageReferrerPolicy)
+{
+ nsCOMPtr<nsIURI> baseURI = BaseURIForPreload();
+ nsCOMPtr<nsIURI> uri = mDocument->ResolvePreloadImage(baseURI, aURL, aSrcset,
+ aSizes);
+ if (uri && ShouldPreloadURI(uri)) {
+ // use document wide referrer policy
+ mozilla::net::ReferrerPolicy referrerPolicy = mSpeculationReferrerPolicy;
+ // if enabled in preferences, use the referrer attribute from the image, if provided
+ bool referrerAttributeEnabled = Preferences::GetBool("network.http.enablePerElementReferrer", true);
+ if (referrerAttributeEnabled) {
+ mozilla::net::ReferrerPolicy imageReferrerPolicy =
+ mozilla::net::AttributeReferrerPolicyFromString(aImageReferrerPolicy);
+ if (imageReferrerPolicy != mozilla::net::RP_Unset) {
+ referrerPolicy = imageReferrerPolicy;
+ }
+ }
+
+ mDocument->MaybePreLoadImage(uri, aCrossOrigin, referrerPolicy);
+ }
+}
+
+// These calls inform the document of picture state and seen sources, such that
+// it can use them to inform ResolvePreLoadImage as necessary
+void
+nsHtml5TreeOpExecutor::PreloadPictureSource(const nsAString& aSrcset,
+ const nsAString& aSizes,
+ const nsAString& aType,
+ const nsAString& aMedia)
+{
+ mDocument->PreloadPictureImageSource(aSrcset, aSizes, aType, aMedia);
+}
+
+void
+nsHtml5TreeOpExecutor::PreloadOpenPicture()
+{
+ mDocument->PreloadPictureOpened();
+}
+
+void
+nsHtml5TreeOpExecutor::PreloadEndPicture()
+{
+ mDocument->PreloadPictureClosed();
+}
+
+void
+nsHtml5TreeOpExecutor::AddBase(const nsAString& aURL)
+{
+ const nsCString& charset = mDocument->GetDocumentCharacterSet();
+ nsresult rv = NS_NewURI(getter_AddRefs(mViewSourceBaseURI), aURL,
+ charset.get(), GetViewSourceBaseURI());
+ if (NS_FAILED(rv)) {
+ mViewSourceBaseURI = nullptr;
+ }
+}
+void
+nsHtml5TreeOpExecutor::SetSpeculationBase(const nsAString& aURL)
+{
+ if (mSpeculationBaseURI) {
+ // the first one wins
+ return;
+ }
+ const nsCString& charset = mDocument->GetDocumentCharacterSet();
+ DebugOnly<nsresult> rv = NS_NewURI(getter_AddRefs(mSpeculationBaseURI), aURL,
+ charset.get(), mDocument->GetDocumentURI());
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to create a URI");
+}
+
+void
+nsHtml5TreeOpExecutor::SetSpeculationReferrerPolicy(const nsAString& aReferrerPolicy)
+{
+ // Specs says:
+ // - Let value be the result of stripping leading and trailing whitespace from
+ // the value of element's content attribute.
+ // - If value is not the empty string, then:
+ if (aReferrerPolicy.IsEmpty()) {
+ return;
+ }
+
+ ReferrerPolicy policy = mozilla::net::ReferrerPolicyFromString(aReferrerPolicy);
+ // Specs says:
+ // - If policy is not the empty string, then set element's node document's
+ // referrer policy to policy
+ if (policy != mozilla::net::RP_Unset) {
+ SetSpeculationReferrerPolicy(policy);
+ }
+}
+
+void
+nsHtml5TreeOpExecutor::AddSpeculationCSP(const nsAString& aCSP)
+{
+ if (!CSPService::sCSPEnabled) {
+ return;
+ }
+
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+ nsIPrincipal* principal = mDocument->NodePrincipal();
+ nsCOMPtr<nsIContentSecurityPolicy> preloadCsp;
+ nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mDocument);
+ nsresult rv = principal->EnsurePreloadCSP(domDoc, getter_AddRefs(preloadCsp));
+ NS_ENSURE_SUCCESS_VOID(rv);
+
+ // please note that meta CSPs and CSPs delivered through a header need
+ // to be joined together.
+ rv = preloadCsp->AppendPolicy(aCSP,
+ false, // csp via meta tag can not be report only
+ true); // delivered through the meta tag
+ NS_ENSURE_SUCCESS_VOID(rv);
+
+ // Record "speculated" referrer policy for preloads
+ bool hasReferrerPolicy = false;
+ uint32_t referrerPolicy = mozilla::net::RP_Default;
+ rv = preloadCsp->GetReferrerPolicy(&referrerPolicy, &hasReferrerPolicy);
+ NS_ENSURE_SUCCESS_VOID(rv);
+ if (hasReferrerPolicy) {
+ SetSpeculationReferrerPolicy(static_cast<ReferrerPolicy>(referrerPolicy));
+ }
+
+ mDocument->ApplySettingsFromCSP(true);
+}
+
+void
+nsHtml5TreeOpExecutor::SetSpeculationReferrerPolicy(ReferrerPolicy aReferrerPolicy)
+{
+ // Record "speculated" referrer policy locally and thread through the
+ // speculation phase. The actual referrer policy will be set by
+ // HTMLMetaElement::BindToTree().
+ mSpeculationReferrerPolicy = aReferrerPolicy;
+}
+
+#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
+uint32_t nsHtml5TreeOpExecutor::sAppendBatchMaxSize = 0;
+uint32_t nsHtml5TreeOpExecutor::sAppendBatchSlotsExamined = 0;
+uint32_t nsHtml5TreeOpExecutor::sAppendBatchExaminations = 0;
+uint32_t nsHtml5TreeOpExecutor::sLongestTimeOffTheEventLoop = 0;
+uint32_t nsHtml5TreeOpExecutor::sTimesFlushLoopInterrupted = 0;
+#endif
+bool nsHtml5TreeOpExecutor::sExternalViewSource = false;
diff --git a/parser/html/nsHtml5TreeOpExecutor.h b/parser/html/nsHtml5TreeOpExecutor.h
new file mode 100644
index 000000000..c4b6a4594
--- /dev/null
+++ b/parser/html/nsHtml5TreeOpExecutor.h
@@ -0,0 +1,306 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5TreeOpExecutor_h
+#define nsHtml5TreeOpExecutor_h
+
+#include "nsIAtom.h"
+#include "nsTraceRefcnt.h"
+#include "nsHtml5TreeOperation.h"
+#include "nsHtml5SpeculativeLoad.h"
+#include "nsTArray.h"
+#include "nsContentSink.h"
+#include "nsNodeInfoManager.h"
+#include "nsHtml5DocumentMode.h"
+#include "nsIScriptElement.h"
+#include "nsIParser.h"
+#include "nsAHtml5TreeOpSink.h"
+#include "nsHtml5TreeOpStage.h"
+#include "nsIURI.h"
+#include "nsTHashtable.h"
+#include "nsHashKeys.h"
+#include "mozilla/LinkedList.h"
+#include "nsHtml5DocumentBuilder.h"
+#include "mozilla/net/ReferrerPolicy.h"
+
+class nsHtml5Parser;
+class nsHtml5StreamParser;
+class nsIContent;
+class nsIDocument;
+
+class nsHtml5TreeOpExecutor final : public nsHtml5DocumentBuilder,
+ public nsIContentSink,
+ public nsAHtml5TreeOpSink,
+ public mozilla::LinkedListElement<nsHtml5TreeOpExecutor>
+{
+ friend class nsHtml5FlushLoopGuard;
+ typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
+
+ public:
+ NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
+ NS_DECL_ISUPPORTS_INHERITED
+
+ private:
+ static bool sExternalViewSource;
+#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
+ static uint32_t sAppendBatchMaxSize;
+ static uint32_t sAppendBatchSlotsExamined;
+ static uint32_t sAppendBatchExaminations;
+ static uint32_t sLongestTimeOffTheEventLoop;
+ static uint32_t sTimesFlushLoopInterrupted;
+#endif
+
+ /**
+ * Whether EOF needs to be suppressed
+ */
+ bool mSuppressEOF;
+
+ bool mReadingFromStage;
+ nsTArray<nsHtml5TreeOperation> mOpQueue;
+ nsHtml5StreamParser* mStreamParser;
+
+ /**
+ * URLs already preloaded/preloading.
+ */
+ nsTHashtable<nsCStringHashKey> mPreloadedURLs;
+
+ nsCOMPtr<nsIURI> mSpeculationBaseURI;
+
+ /**
+ * Speculative referrer policy
+ */
+ ReferrerPolicy mSpeculationReferrerPolicy;
+
+ nsCOMPtr<nsIURI> mViewSourceBaseURI;
+
+ /**
+ * Whether the parser has started
+ */
+ bool mStarted;
+
+ nsHtml5TreeOpStage mStage;
+
+ bool mRunFlushLoopOnStack;
+
+ bool mCallContinueInterruptedParsingIfEnabled;
+
+ /**
+ * Whether this executor has already complained about matters related
+ * to character encoding declarations.
+ */
+ bool mAlreadyComplainedAboutCharset;
+
+ public:
+
+ nsHtml5TreeOpExecutor();
+
+ protected:
+
+ virtual ~nsHtml5TreeOpExecutor();
+
+ public:
+
+ // nsIContentSink
+
+ /**
+ * Unimplemented. For interface compat only.
+ */
+ NS_IMETHOD WillParse() override;
+
+ /**
+ *
+ */
+ NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override;
+
+ /**
+ * Emits EOF.
+ */
+ NS_IMETHOD DidBuildModel(bool aTerminated) override;
+
+ /**
+ * Forwards to nsContentSink
+ */
+ NS_IMETHOD WillInterrupt() override;
+
+ /**
+ * Unimplemented. For interface compat only.
+ */
+ NS_IMETHOD WillResume() override;
+
+ /**
+ * Sets the parser.
+ */
+ NS_IMETHOD SetParser(nsParserBase* aParser) override;
+
+ /**
+ * No-op for backwards compat.
+ */
+ virtual void FlushPendingNotifications(mozFlushType aType) override;
+
+ /**
+ * Don't call. For interface compat only.
+ */
+ NS_IMETHOD SetDocumentCharset(nsACString& aCharset) override {
+ NS_NOTREACHED("No one should call this.");
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+
+ /**
+ * Returns the document.
+ */
+ virtual nsISupports *GetTarget() override;
+
+ virtual void ContinueInterruptedParsingAsync() override;
+
+ bool IsScriptExecuting() override
+ {
+ return IsScriptExecutingImpl();
+ }
+
+ // Not from interface
+
+ void SetStreamParser(nsHtml5StreamParser* aStreamParser)
+ {
+ mStreamParser = aStreamParser;
+ }
+
+ void InitializeDocWriteParserState(nsAHtml5TreeBuilderState* aState, int32_t aLine);
+
+ bool IsScriptEnabled();
+
+ virtual nsresult MarkAsBroken(nsresult aReason) override;
+
+ void StartLayout();
+
+ void FlushSpeculativeLoads();
+
+ void RunFlushLoop();
+
+ nsresult FlushDocumentWrite();
+
+ void MaybeSuspend();
+
+ void Start();
+
+ void NeedsCharsetSwitchTo(const char* aEncoding,
+ int32_t aSource,
+ uint32_t aLineNumber);
+
+ void MaybeComplainAboutCharset(const char* aMsgId,
+ bool aError,
+ uint32_t aLineNumber);
+
+ void ComplainAboutBogusProtocolCharset(nsIDocument* aDoc);
+
+ bool IsComplete()
+ {
+ return !mParser;
+ }
+
+ bool HasStarted()
+ {
+ return mStarted;
+ }
+
+ bool IsFlushing()
+ {
+ return mFlushState >= eInFlush;
+ }
+
+#ifdef DEBUG
+ bool IsInFlushLoop()
+ {
+ return mRunFlushLoopOnStack;
+ }
+#endif
+
+ void RunScript(nsIContent* aScriptElement);
+
+ /**
+ * Flush the operations from the tree operations from the argument
+ * queue unconditionally. (This is for the main thread case.)
+ */
+ virtual void MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue) override;
+
+ nsHtml5TreeOpStage* GetStage()
+ {
+ return &mStage;
+ }
+
+ void StartReadingFromStage()
+ {
+ mReadingFromStage = true;
+ }
+
+ void StreamEnded();
+
+#ifdef DEBUG
+ void AssertStageEmpty()
+ {
+ mStage.AssertEmpty();
+ }
+#endif
+
+ nsIURI* GetViewSourceBaseURI();
+
+ void PreloadScript(const nsAString& aURL,
+ const nsAString& aCharset,
+ const nsAString& aType,
+ const nsAString& aCrossOrigin,
+ const nsAString& aIntegrity,
+ bool aScriptFromHead);
+
+ void PreloadStyle(const nsAString& aURL, const nsAString& aCharset,
+ const nsAString& aCrossOrigin,
+ const nsAString& aIntegrity);
+
+ void PreloadImage(const nsAString& aURL,
+ const nsAString& aCrossOrigin,
+ const nsAString& aSrcset,
+ const nsAString& aSizes,
+ const nsAString& aImageReferrerPolicy);
+
+ void PreloadOpenPicture();
+
+ void PreloadEndPicture();
+
+ void PreloadPictureSource(const nsAString& aSrcset,
+ const nsAString& aSizes,
+ const nsAString& aType,
+ const nsAString& aMedia);
+
+ void SetSpeculationBase(const nsAString& aURL);
+
+ void SetSpeculationReferrerPolicy(ReferrerPolicy aReferrerPolicy);
+ void SetSpeculationReferrerPolicy(const nsAString& aReferrerPolicy);
+
+ void AddSpeculationCSP(const nsAString& aCSP);
+
+ void AddBase(const nsAString& aURL);
+
+ static void InitializeStatics();
+
+ private:
+ nsHtml5Parser* GetParser();
+
+ bool IsExternalViewSource();
+
+ /**
+ * Get a nsIURI for an nsString if the URL hasn't been preloaded yet.
+ */
+ already_AddRefed<nsIURI> ConvertIfNotPreloadedYet(const nsAString& aURL);
+
+ /**
+ * The base URI we would use for current preload operations
+ */
+ nsIURI* BaseURIForPreload();
+
+ /**
+ * Returns true if we haven't preloaded this URI yet, and adds it to the
+ * list of preloaded URIs
+ */
+ bool ShouldPreloadURI(nsIURI *aURI);
+};
+
+#endif // nsHtml5TreeOpExecutor_h
diff --git a/parser/html/nsHtml5TreeOpStage.cpp b/parser/html/nsHtml5TreeOpStage.cpp
new file mode 100644
index 000000000..5f7fe7496
--- /dev/null
+++ b/parser/html/nsHtml5TreeOpStage.cpp
@@ -0,0 +1,56 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5TreeOpStage.h"
+
+using namespace mozilla;
+
+nsHtml5TreeOpStage::nsHtml5TreeOpStage()
+ : mMutex("nsHtml5TreeOpStage mutex")
+{
+}
+
+nsHtml5TreeOpStage::~nsHtml5TreeOpStage()
+{
+}
+
+void
+nsHtml5TreeOpStage::MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue)
+{
+ mozilla::MutexAutoLock autoLock(mMutex);
+ mOpQueue.AppendElements(Move(aOpQueue));
+}
+
+void
+nsHtml5TreeOpStage::MoveOpsAndSpeculativeLoadsTo(nsTArray<nsHtml5TreeOperation>& aOpQueue,
+ nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue)
+{
+ mozilla::MutexAutoLock autoLock(mMutex);
+ aOpQueue.AppendElements(Move(mOpQueue));
+ aSpeculativeLoadQueue.AppendElements(Move(mSpeculativeLoadQueue));
+}
+
+void
+nsHtml5TreeOpStage::MoveSpeculativeLoadsFrom(nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue)
+{
+ mozilla::MutexAutoLock autoLock(mMutex);
+ mSpeculativeLoadQueue.AppendElements(Move(aSpeculativeLoadQueue));
+}
+
+void
+nsHtml5TreeOpStage::MoveSpeculativeLoadsTo(nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue)
+{
+ mozilla::MutexAutoLock autoLock(mMutex);
+ aSpeculativeLoadQueue.AppendElements(Move(mSpeculativeLoadQueue));
+}
+
+#ifdef DEBUG
+void
+nsHtml5TreeOpStage::AssertEmpty()
+{
+ mozilla::MutexAutoLock autoLock(mMutex);
+ // This shouldn't really need the mutex
+ NS_ASSERTION(mOpQueue.IsEmpty(), "The stage was supposed to be empty.");
+}
+#endif
diff --git a/parser/html/nsHtml5TreeOpStage.h b/parser/html/nsHtml5TreeOpStage.h
new file mode 100644
index 000000000..10e0054ee
--- /dev/null
+++ b/parser/html/nsHtml5TreeOpStage.h
@@ -0,0 +1,54 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5TreeOpStage_h
+#define nsHtml5TreeOpStage_h
+
+#include "mozilla/Mutex.h"
+#include "nsHtml5TreeOperation.h"
+#include "nsTArray.h"
+#include "nsAHtml5TreeOpSink.h"
+#include "nsHtml5SpeculativeLoad.h"
+
+class nsHtml5TreeOpStage : public nsAHtml5TreeOpSink {
+ public:
+
+ nsHtml5TreeOpStage();
+
+ virtual ~nsHtml5TreeOpStage();
+
+ /**
+ * Flush the operations from the tree operations from the argument
+ * queue unconditionally.
+ */
+ virtual void MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue);
+
+ /**
+ * Retrieve the staged operations and speculative loads into the arguments.
+ */
+ void MoveOpsAndSpeculativeLoadsTo(nsTArray<nsHtml5TreeOperation>& aOpQueue,
+ nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue);
+
+ /**
+ * Move the speculative loads from the argument into the staging queue.
+ */
+ void MoveSpeculativeLoadsFrom(nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue);
+
+ /**
+ * Retrieve the staged speculative loads into the argument.
+ */
+ void MoveSpeculativeLoadsTo(nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue);
+
+#ifdef DEBUG
+ void AssertEmpty();
+#endif
+
+ private:
+ nsTArray<nsHtml5TreeOperation> mOpQueue;
+ nsTArray<nsHtml5SpeculativeLoad> mSpeculativeLoadQueue;
+ mozilla::Mutex mMutex;
+
+};
+
+#endif /* nsHtml5TreeOpStage_h */
diff --git a/parser/html/nsHtml5TreeOperation.cpp b/parser/html/nsHtml5TreeOperation.cpp
new file mode 100644
index 000000000..af246a253
--- /dev/null
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -0,0 +1,995 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 et tw=78: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5TreeOperation.h"
+#include "nsContentUtils.h"
+#include "nsDocElementCreatedNotificationRunner.h"
+#include "nsNodeUtils.h"
+#include "nsAttrName.h"
+#include "nsHtml5TreeBuilder.h"
+#include "nsIDOMMutationEvent.h"
+#include "mozAutoDocUpdate.h"
+#include "nsBindingManager.h"
+#include "nsXBLBinding.h"
+#include "nsHtml5DocumentMode.h"
+#include "nsHtml5HtmlAttributes.h"
+#include "nsContentCreatorFunctions.h"
+#include "nsIScriptElement.h"
+#include "nsIDTD.h"
+#include "nsISupportsImpl.h"
+#include "nsIDOMHTMLFormElement.h"
+#include "nsIFormControl.h"
+#include "nsIStyleSheetLinkingElement.h"
+#include "nsIDOMDocumentType.h"
+#include "nsIObserverService.h"
+#include "mozilla/Services.h"
+#include "nsIMutationObserver.h"
+#include "nsIFormProcessor.h"
+#include "nsIServiceManager.h"
+#include "nsEscape.h"
+#include "mozilla/dom/Comment.h"
+#include "mozilla/dom/Element.h"
+#include "mozilla/dom/HTMLImageElement.h"
+#include "mozilla/dom/HTMLTemplateElement.h"
+#include "nsHtml5SVGLoadDispatcher.h"
+#include "nsIURI.h"
+#include "nsIProtocolHandler.h"
+#include "nsNetUtil.h"
+#include "nsIHTMLDocument.h"
+#include "mozilla/Likely.h"
+#include "nsTextNode.h"
+
+using namespace mozilla;
+
+static NS_DEFINE_CID(kFormProcessorCID, NS_FORMPROCESSOR_CID);
+
+/**
+ * Helper class that opens a notification batch if the current doc
+ * is different from the executor doc.
+ */
+class MOZ_STACK_CLASS nsHtml5OtherDocUpdate {
+ public:
+ nsHtml5OtherDocUpdate(nsIDocument* aCurrentDoc, nsIDocument* aExecutorDoc)
+ {
+ NS_PRECONDITION(aCurrentDoc, "Node has no doc?");
+ NS_PRECONDITION(aExecutorDoc, "Executor has no doc?");
+ if (MOZ_LIKELY(aCurrentDoc == aExecutorDoc)) {
+ mDocument = nullptr;
+ } else {
+ mDocument = aCurrentDoc;
+ aCurrentDoc->BeginUpdate(UPDATE_CONTENT_MODEL);
+ }
+ }
+
+ ~nsHtml5OtherDocUpdate()
+ {
+ if (MOZ_UNLIKELY(mDocument)) {
+ mDocument->EndUpdate(UPDATE_CONTENT_MODEL);
+ }
+ }
+ private:
+ nsCOMPtr<nsIDocument> mDocument;
+};
+
+nsHtml5TreeOperation::nsHtml5TreeOperation()
+ : mOpCode(eTreeOpUninitialized)
+{
+ MOZ_COUNT_CTOR(nsHtml5TreeOperation);
+}
+
+nsHtml5TreeOperation::~nsHtml5TreeOperation()
+{
+ MOZ_COUNT_DTOR(nsHtml5TreeOperation);
+ NS_ASSERTION(mOpCode != eTreeOpUninitialized, "Uninitialized tree op.");
+ switch(mOpCode) {
+ case eTreeOpAddAttributes:
+ delete mTwo.attributes;
+ break;
+ case eTreeOpCreateElementNetwork:
+ case eTreeOpCreateElementNotNetwork:
+ delete mThree.attributes;
+ break;
+ case eTreeOpAppendDoctypeToDocument:
+ delete mTwo.stringPair;
+ break;
+ case eTreeOpFosterParentText:
+ case eTreeOpAppendText:
+ case eTreeOpAppendComment:
+ case eTreeOpAppendCommentToDocument:
+ case eTreeOpAddViewSourceHref:
+ case eTreeOpAddViewSourceBase:
+ delete[] mTwo.unicharPtr;
+ break;
+ case eTreeOpSetDocumentCharset:
+ case eTreeOpNeedsCharsetSwitchTo:
+ delete[] mOne.charPtr;
+ break;
+ case eTreeOpProcessOfflineManifest:
+ free(mOne.unicharPtr);
+ break;
+ default: // keep the compiler happy
+ break;
+ }
+}
+
+nsresult
+nsHtml5TreeOperation::AppendTextToTextNode(const char16_t* aBuffer,
+ uint32_t aLength,
+ nsIContent* aTextNode,
+ nsHtml5DocumentBuilder* aBuilder)
+{
+ NS_PRECONDITION(aTextNode, "Got null text node.");
+ MOZ_ASSERT(aBuilder);
+ MOZ_ASSERT(aBuilder->IsInDocUpdate());
+ uint32_t oldLength = aTextNode->TextLength();
+ CharacterDataChangeInfo info = {
+ true,
+ oldLength,
+ oldLength,
+ aLength
+ };
+ nsNodeUtils::CharacterDataWillChange(aTextNode, &info);
+
+ nsresult rv = aTextNode->AppendText(aBuffer, aLength, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsNodeUtils::CharacterDataChanged(aTextNode, &info);
+ return rv;
+}
+
+
+nsresult
+nsHtml5TreeOperation::AppendText(const char16_t* aBuffer,
+ uint32_t aLength,
+ nsIContent* aParent,
+ nsHtml5DocumentBuilder* aBuilder)
+{
+ nsresult rv = NS_OK;
+ nsIContent* lastChild = aParent->GetLastChild();
+ if (lastChild && lastChild->IsNodeOfType(nsINode::eTEXT)) {
+ nsHtml5OtherDocUpdate update(aParent->OwnerDoc(),
+ aBuilder->GetDocument());
+ return AppendTextToTextNode(aBuffer,
+ aLength,
+ lastChild,
+ aBuilder);
+ }
+
+ nsNodeInfoManager* nodeInfoManager = aParent->OwnerDoc()->NodeInfoManager();
+ RefPtr<nsTextNode> text = new nsTextNode(nodeInfoManager);
+ NS_ASSERTION(text, "Infallible malloc failed?");
+ rv = text->SetText(aBuffer, aLength, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return Append(text, aParent, aBuilder);
+}
+
+nsresult
+nsHtml5TreeOperation::Append(nsIContent* aNode,
+ nsIContent* aParent,
+ nsHtml5DocumentBuilder* aBuilder)
+{
+ MOZ_ASSERT(aBuilder);
+ MOZ_ASSERT(aBuilder->IsInDocUpdate());
+ nsresult rv = NS_OK;
+ nsHtml5OtherDocUpdate update(aParent->OwnerDoc(),
+ aBuilder->GetDocument());
+ uint32_t childCount = aParent->GetChildCount();
+ rv = aParent->AppendChildTo(aNode, false);
+ if (NS_SUCCEEDED(rv)) {
+ aNode->SetParserHasNotified();
+ nsNodeUtils::ContentAppended(aParent, aNode, childCount);
+ }
+ return rv;
+}
+
+nsresult
+nsHtml5TreeOperation::AppendToDocument(nsIContent* aNode,
+ nsHtml5DocumentBuilder* aBuilder)
+{
+ MOZ_ASSERT(aBuilder);
+ MOZ_ASSERT(aBuilder->GetDocument() == aNode->OwnerDoc());
+ MOZ_ASSERT(aBuilder->IsInDocUpdate());
+ nsresult rv = NS_OK;
+
+ nsIDocument* doc = aBuilder->GetDocument();
+ uint32_t childCount = doc->GetChildCount();
+ rv = doc->AppendChildTo(aNode, false);
+ if (rv == NS_ERROR_DOM_HIERARCHY_REQUEST_ERR) {
+ aNode->SetParserHasNotified();
+ return NS_OK;
+ }
+ NS_ENSURE_SUCCESS(rv, rv);
+ aNode->SetParserHasNotified();
+ nsNodeUtils::ContentInserted(doc, aNode, childCount);
+
+ NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
+ "Someone forgot to block scripts");
+ if (aNode->IsElement()) {
+ nsContentUtils::AddScriptRunner(
+ new nsDocElementCreatedNotificationRunner(doc));
+ }
+ return rv;
+}
+
+static bool
+IsElementOrTemplateContent(nsINode* aNode) {
+ if (aNode) {
+ if (aNode->IsElement()) {
+ return true;
+ } else if (aNode->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
+ // Check if the node is a template content.
+ mozilla::dom::DocumentFragment* frag =
+ static_cast<mozilla::dom::DocumentFragment*>(aNode);
+ nsIContent* fragHost = frag->GetHost();
+ if (fragHost && nsNodeUtils::IsTemplateElement(fragHost)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void
+nsHtml5TreeOperation::Detach(nsIContent* aNode, nsHtml5DocumentBuilder* aBuilder)
+{
+ MOZ_ASSERT(aBuilder);
+ MOZ_ASSERT(aBuilder->IsInDocUpdate());
+ nsCOMPtr<nsINode> parent = aNode->GetParentNode();
+ if (parent) {
+ nsHtml5OtherDocUpdate update(parent->OwnerDoc(),
+ aBuilder->GetDocument());
+ int32_t pos = parent->IndexOf(aNode);
+ NS_ASSERTION((pos >= 0), "Element not found as child of its parent");
+ parent->RemoveChildAt(pos, true);
+ }
+}
+
+nsresult
+nsHtml5TreeOperation::AppendChildrenToNewParent(nsIContent* aNode,
+ nsIContent* aParent,
+ nsHtml5DocumentBuilder* aBuilder)
+{
+ MOZ_ASSERT(aBuilder);
+ MOZ_ASSERT(aBuilder->IsInDocUpdate());
+ nsHtml5OtherDocUpdate update(aParent->OwnerDoc(),
+ aBuilder->GetDocument());
+
+ uint32_t childCount = aParent->GetChildCount();
+ bool didAppend = false;
+ while (aNode->HasChildren()) {
+ nsCOMPtr<nsIContent> child = aNode->GetFirstChild();
+ aNode->RemoveChildAt(0, true);
+ nsresult rv = aParent->AppendChildTo(child, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+ didAppend = true;
+ }
+ if (didAppend) {
+ nsNodeUtils::ContentAppended(aParent, aParent->GetChildAt(childCount),
+ childCount);
+ }
+ return NS_OK;
+}
+
+nsresult
+nsHtml5TreeOperation::FosterParent(nsIContent* aNode,
+ nsIContent* aParent,
+ nsIContent* aTable,
+ nsHtml5DocumentBuilder* aBuilder)
+{
+ MOZ_ASSERT(aBuilder);
+ MOZ_ASSERT(aBuilder->IsInDocUpdate());
+ nsIContent* foster = aTable->GetParent();
+
+ if (IsElementOrTemplateContent(foster)) {
+
+ nsHtml5OtherDocUpdate update(foster->OwnerDoc(),
+ aBuilder->GetDocument());
+
+ uint32_t pos = foster->IndexOf(aTable);
+ nsresult rv = foster->InsertChildAt(aNode, pos, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsNodeUtils::ContentInserted(foster, aNode, pos);
+ return rv;
+ }
+
+ return Append(aNode, aParent, aBuilder);
+}
+
+nsresult
+nsHtml5TreeOperation::AddAttributes(nsIContent* aNode,
+ nsHtml5HtmlAttributes* aAttributes,
+ nsHtml5DocumentBuilder* aBuilder)
+{
+ dom::Element* node = aNode->AsElement();
+ nsHtml5OtherDocUpdate update(node->OwnerDoc(),
+ aBuilder->GetDocument());
+
+ int32_t len = aAttributes->getLength();
+ for (int32_t i = len; i > 0;) {
+ --i;
+ // prefix doesn't need regetting. it is always null or a static atom
+ // local name is never null
+ nsCOMPtr<nsIAtom> localName =
+ Reget(aAttributes->getLocalNameNoBoundsCheck(i));
+ int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
+ if (!node->HasAttr(nsuri, localName)) {
+ // prefix doesn't need regetting. it is always null or a static atom
+ // local name is never null
+ node->SetAttr(nsuri,
+ localName,
+ aAttributes->getPrefixNoBoundsCheck(i),
+ *(aAttributes->getValueNoBoundsCheck(i)),
+ true);
+ // XXX what to do with nsresult?
+ }
+ }
+ return NS_OK;
+}
+
+
+nsIContent*
+nsHtml5TreeOperation::CreateElement(int32_t aNs,
+ nsIAtom* aName,
+ nsHtml5HtmlAttributes* aAttributes,
+ mozilla::dom::FromParser aFromParser,
+ nsNodeInfoManager* aNodeInfoManager,
+ nsHtml5DocumentBuilder* aBuilder)
+{
+ bool isKeygen = (aName == nsHtml5Atoms::keygen && aNs == kNameSpaceID_XHTML);
+ if (MOZ_UNLIKELY(isKeygen)) {
+ aName = nsHtml5Atoms::select;
+ }
+
+ nsCOMPtr<dom::Element> newElement;
+ RefPtr<dom::NodeInfo> nodeInfo = aNodeInfoManager->
+ GetNodeInfo(aName, nullptr, aNs, nsIDOMNode::ELEMENT_NODE);
+ NS_ASSERTION(nodeInfo, "Got null nodeinfo.");
+ NS_NewElement(getter_AddRefs(newElement),
+ nodeInfo.forget(),
+ aFromParser);
+ NS_ASSERTION(newElement, "Element creation created null pointer.");
+
+ dom::Element* newContent = newElement;
+ aBuilder->HoldElement(newElement.forget());
+
+ if (MOZ_UNLIKELY(aName == nsHtml5Atoms::style || aName == nsHtml5Atoms::link)) {
+ nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(newContent));
+ if (ssle) {
+ ssle->InitStyleLinkElement(false);
+ ssle->SetEnableUpdates(false);
+ }
+ } else if (MOZ_UNLIKELY(isKeygen)) {
+ // Adapted from CNavDTD
+ nsresult rv;
+ nsCOMPtr<nsIFormProcessor> theFormProcessor =
+ do_GetService(kFormProcessorCID, &rv);
+ if (NS_FAILED(rv)) {
+ return newContent;
+ }
+
+ nsTArray<nsString> theContent;
+ nsAutoString theAttribute;
+
+ (void) theFormProcessor->ProvideContent(NS_LITERAL_STRING("select"),
+ theContent,
+ theAttribute);
+
+ newContent->SetAttr(kNameSpaceID_None,
+ nsGkAtoms::moztype,
+ nullptr,
+ theAttribute,
+ false);
+
+ RefPtr<dom::NodeInfo> optionNodeInfo =
+ aNodeInfoManager->GetNodeInfo(nsHtml5Atoms::option,
+ nullptr,
+ kNameSpaceID_XHTML,
+ nsIDOMNode::ELEMENT_NODE);
+
+ for (uint32_t i = 0; i < theContent.Length(); ++i) {
+ nsCOMPtr<dom::Element> optionElt;
+ RefPtr<dom::NodeInfo> ni = optionNodeInfo;
+ NS_NewElement(getter_AddRefs(optionElt),
+ ni.forget(),
+ aFromParser);
+ RefPtr<nsTextNode> optionText = new nsTextNode(aNodeInfoManager);
+ (void) optionText->SetText(theContent[i], false);
+ optionElt->AppendChildTo(optionText, false);
+ newContent->AppendChildTo(optionElt, false);
+ // XXXsmaug Shouldn't we call this after adding all the child nodes.
+ newContent->DoneAddingChildren(false);
+ }
+ }
+
+ if (!aAttributes) {
+ return newContent;
+ }
+
+ int32_t len = aAttributes->getLength();
+ for (int32_t i = 0; i < len; i++) {
+ // prefix doesn't need regetting. it is always null or a static atom
+ // local name is never null
+ nsCOMPtr<nsIAtom> localName =
+ Reget(aAttributes->getLocalNameNoBoundsCheck(i));
+ nsCOMPtr<nsIAtom> prefix = aAttributes->getPrefixNoBoundsCheck(i);
+ int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
+
+ if (aNs == kNameSpaceID_XHTML &&
+ nsHtml5Atoms::a == aName &&
+ nsHtml5Atoms::name == localName) {
+ // This is an HTML5-incompliant Geckoism.
+ // Remove when fixing bug 582361
+ NS_ConvertUTF16toUTF8 cname(*(aAttributes->getValueNoBoundsCheck(i)));
+ NS_ConvertUTF8toUTF16 uv(nsUnescape(cname.BeginWriting()));
+ newContent->SetAttr(nsuri,
+ localName,
+ prefix,
+ uv,
+ false);
+ } else {
+ nsString& value = *(aAttributes->getValueNoBoundsCheck(i));
+ newContent->SetAttr(nsuri,
+ localName,
+ prefix,
+ value,
+ false);
+
+ // Custom element setup may be needed if there is an "is" attribute.
+ if (kNameSpaceID_None == nsuri && !prefix && nsGkAtoms::is == localName) {
+ nsContentUtils::SetupCustomElement(newContent, &value);
+ }
+ }
+ }
+ return newContent;
+}
+
+void
+nsHtml5TreeOperation::SetFormElement(nsIContent* aNode, nsIContent* aParent)
+{
+ nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(aNode));
+ nsCOMPtr<nsIDOMHTMLImageElement> domImageElement = do_QueryInterface(aNode);
+ // NS_ASSERTION(formControl, "Form-associated element did not implement nsIFormControl.");
+ // TODO: uncomment the above line when <keygen> (bug 101019) is supported by Gecko
+ nsCOMPtr<nsIDOMHTMLFormElement> formElement(do_QueryInterface(aParent));
+ NS_ASSERTION(formElement, "The form element doesn't implement nsIDOMHTMLFormElement.");
+ // avoid crashing on <keygen>
+ if (formControl &&
+ !aNode->HasAttr(kNameSpaceID_None, nsGkAtoms::form)) {
+ formControl->SetForm(formElement);
+ } else if (domImageElement) {
+ RefPtr<dom::HTMLImageElement> imageElement =
+ static_cast<dom::HTMLImageElement*>(domImageElement.get());
+ MOZ_ASSERT(imageElement);
+ imageElement->SetForm(formElement);
+ }
+}
+
+nsresult
+nsHtml5TreeOperation::AppendIsindexPrompt(nsIContent* parent, nsHtml5DocumentBuilder* aBuilder)
+{
+ nsXPIDLString prompt;
+ nsresult rv =
+ nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
+ "IsIndexPromptWithSpace", prompt);
+ uint32_t len = prompt.Length();
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ if (!len) {
+ // Don't bother appending a zero-length text node.
+ return NS_OK;
+ }
+ return AppendText(prompt.BeginReading(), len, parent, aBuilder);
+}
+
+nsresult
+nsHtml5TreeOperation::FosterParentText(nsIContent* aStackParent,
+ char16_t* aBuffer,
+ uint32_t aLength,
+ nsIContent* aTable,
+ nsHtml5DocumentBuilder* aBuilder)
+{
+ MOZ_ASSERT(aBuilder);
+ MOZ_ASSERT(aBuilder->IsInDocUpdate());
+ nsresult rv = NS_OK;
+ nsIContent* foster = aTable->GetParent();
+
+ if (IsElementOrTemplateContent(foster)) {
+ nsHtml5OtherDocUpdate update(foster->OwnerDoc(),
+ aBuilder->GetDocument());
+
+ uint32_t pos = foster->IndexOf(aTable);
+
+ nsIContent* previousSibling = aTable->GetPreviousSibling();
+ if (previousSibling && previousSibling->IsNodeOfType(nsINode::eTEXT)) {
+ return AppendTextToTextNode(aBuffer,
+ aLength,
+ previousSibling,
+ aBuilder);
+ }
+
+ nsNodeInfoManager* nodeInfoManager = aStackParent->OwnerDoc()->NodeInfoManager();
+ RefPtr<nsTextNode> text = new nsTextNode(nodeInfoManager);
+ NS_ASSERTION(text, "Infallible malloc failed?");
+ rv = text->SetText(aBuffer, aLength, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = foster->InsertChildAt(text, pos, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsNodeUtils::ContentInserted(foster, text, pos);
+ return rv;
+ }
+
+ return AppendText(aBuffer, aLength, aStackParent, aBuilder);
+}
+
+nsresult
+nsHtml5TreeOperation::AppendComment(nsIContent* aParent,
+ char16_t* aBuffer,
+ int32_t aLength,
+ nsHtml5DocumentBuilder* aBuilder)
+{
+ nsNodeInfoManager* nodeInfoManager = aParent->OwnerDoc()->NodeInfoManager();
+ RefPtr<dom::Comment> comment = new dom::Comment(nodeInfoManager);
+ NS_ASSERTION(comment, "Infallible malloc failed?");
+ nsresult rv = comment->SetText(aBuffer, aLength, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return Append(comment, aParent, aBuilder);
+}
+
+nsresult
+nsHtml5TreeOperation::AppendCommentToDocument(char16_t* aBuffer,
+ int32_t aLength,
+ nsHtml5DocumentBuilder* aBuilder)
+{
+ RefPtr<dom::Comment> comment =
+ new dom::Comment(aBuilder->GetNodeInfoManager());
+ NS_ASSERTION(comment, "Infallible malloc failed?");
+ nsresult rv = comment->SetText(aBuffer, aLength, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return AppendToDocument(comment, aBuilder);
+}
+
+nsresult
+nsHtml5TreeOperation::AppendDoctypeToDocument(nsIAtom* aName,
+ const nsAString& aPublicId,
+ const nsAString& aSystemId,
+ nsHtml5DocumentBuilder* aBuilder)
+{
+ // Adapted from nsXMLContentSink
+ // Create a new doctype node
+ nsCOMPtr<nsIDOMDocumentType> docType;
+ NS_NewDOMDocumentType(getter_AddRefs(docType),
+ aBuilder->GetNodeInfoManager(),
+ aName,
+ aPublicId,
+ aSystemId,
+ NullString());
+ NS_ASSERTION(docType, "Doctype creation failed.");
+ nsCOMPtr<nsIContent> asContent = do_QueryInterface(docType);
+ return AppendToDocument(asContent, aBuilder);
+}
+
+nsIContent*
+nsHtml5TreeOperation::GetDocumentFragmentForTemplate(nsIContent* aNode)
+{
+ dom::HTMLTemplateElement* tempElem =
+ static_cast<dom::HTMLTemplateElement*>(aNode);
+ RefPtr<dom::DocumentFragment> frag = tempElem->Content();
+ return frag;
+}
+
+nsIContent*
+nsHtml5TreeOperation::GetFosterParent(nsIContent* aTable, nsIContent* aStackParent)
+{
+ nsIContent* tableParent = aTable->GetParent();
+ return IsElementOrTemplateContent(tableParent) ? tableParent : aStackParent;
+}
+
+void
+nsHtml5TreeOperation::PreventScriptExecution(nsIContent* aNode)
+{
+ nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(aNode);
+ MOZ_ASSERT(sele);
+ sele->PreventExecution();
+}
+
+void
+nsHtml5TreeOperation::DoneAddingChildren(nsIContent* aNode)
+{
+ aNode->DoneAddingChildren(aNode->HasParserNotified());
+}
+
+void
+nsHtml5TreeOperation::DoneCreatingElement(nsIContent* aNode)
+{
+ aNode->DoneCreatingElement();
+}
+
+void
+nsHtml5TreeOperation::SvgLoad(nsIContent* aNode)
+{
+ nsCOMPtr<nsIRunnable> event = new nsHtml5SVGLoadDispatcher(aNode);
+ if (NS_FAILED(NS_DispatchToMainThread(event))) {
+ NS_WARNING("failed to dispatch svg load dispatcher");
+ }
+}
+
+void
+nsHtml5TreeOperation::MarkMalformedIfScript(nsIContent* aNode)
+{
+ nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(aNode);
+ if (sele) {
+ // Make sure to serialize this script correctly, for nice round tripping.
+ sele->SetIsMalformed();
+ }
+}
+
+nsresult
+nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
+ nsIContent** aScriptElement)
+{
+ switch(mOpCode) {
+ case eTreeOpUninitialized: {
+ MOZ_CRASH("eTreeOpUninitialized");
+ }
+ case eTreeOpAppend: {
+ nsIContent* node = *(mOne.node);
+ nsIContent* parent = *(mTwo.node);
+ return Append(node, parent, aBuilder);
+ }
+ case eTreeOpDetach: {
+ nsIContent* node = *(mOne.node);
+ Detach(node, aBuilder);
+ return NS_OK;
+ }
+ case eTreeOpAppendChildrenToNewParent: {
+ nsCOMPtr<nsIContent> node = *(mOne.node);
+ nsIContent* parent = *(mTwo.node);
+ return AppendChildrenToNewParent(node, parent, aBuilder);
+ }
+ case eTreeOpFosterParent: {
+ nsIContent* node = *(mOne.node);
+ nsIContent* parent = *(mTwo.node);
+ nsIContent* table = *(mThree.node);
+ return FosterParent(node, parent, table, aBuilder);
+ }
+ case eTreeOpAppendToDocument: {
+ nsIContent* node = *(mOne.node);
+ return AppendToDocument(node, aBuilder);
+ }
+ case eTreeOpAddAttributes: {
+ nsIContent* node = *(mOne.node);
+ nsHtml5HtmlAttributes* attributes = mTwo.attributes;
+ return AddAttributes(node, attributes, aBuilder);
+ }
+ case eTreeOpDocumentMode: {
+ aBuilder->SetDocumentMode(mOne.mode);
+ return NS_OK;
+ }
+ case eTreeOpCreateElementNetwork:
+ case eTreeOpCreateElementNotNetwork: {
+ nsIContent** target = mOne.node;
+ int32_t ns = mFour.integer;
+ nsCOMPtr<nsIAtom> name = Reget(mTwo.atom);
+ nsHtml5HtmlAttributes* attributes = mThree.attributes;
+ nsIContent* intendedParent = mFive.node ? *(mFive.node) : nullptr;
+
+ // intendedParent == nullptr is a special case where the
+ // intended parent is the document.
+ nsNodeInfoManager* nodeInfoManager = intendedParent ?
+ intendedParent->OwnerDoc()->NodeInfoManager() :
+ aBuilder->GetNodeInfoManager();
+
+ *target = CreateElement(ns,
+ name,
+ attributes,
+ mOpCode == eTreeOpCreateElementNetwork ?
+ dom::FROM_PARSER_NETWORK :
+ dom::FROM_PARSER_DOCUMENT_WRITE,
+ nodeInfoManager,
+ aBuilder);
+ return NS_OK;
+ }
+ case eTreeOpSetFormElement: {
+ nsIContent* node = *(mOne.node);
+ nsIContent* parent = *(mTwo.node);
+ SetFormElement(node, parent);
+ return NS_OK;
+ }
+ case eTreeOpAppendText: {
+ nsIContent* parent = *mOne.node;
+ char16_t* buffer = mTwo.unicharPtr;
+ uint32_t length = mFour.integer;
+ return AppendText(buffer, length, parent, aBuilder);
+ }
+ case eTreeOpAppendIsindexPrompt: {
+ nsIContent* parent = *mOne.node;
+ return AppendIsindexPrompt(parent, aBuilder);
+ }
+ case eTreeOpFosterParentText: {
+ nsIContent* stackParent = *mOne.node;
+ char16_t* buffer = mTwo.unicharPtr;
+ uint32_t length = mFour.integer;
+ nsIContent* table = *mThree.node;
+ return FosterParentText(stackParent, buffer, length, table, aBuilder);
+ }
+ case eTreeOpAppendComment: {
+ nsIContent* parent = *mOne.node;
+ char16_t* buffer = mTwo.unicharPtr;
+ int32_t length = mFour.integer;
+ return AppendComment(parent, buffer, length, aBuilder);
+ }
+ case eTreeOpAppendCommentToDocument: {
+ char16_t* buffer = mTwo.unicharPtr;
+ int32_t length = mFour.integer;
+ return AppendCommentToDocument(buffer, length, aBuilder);
+ }
+ case eTreeOpAppendDoctypeToDocument: {
+ nsCOMPtr<nsIAtom> name = Reget(mOne.atom);
+ nsHtml5TreeOperationStringPair* pair = mTwo.stringPair;
+ nsString publicId;
+ nsString systemId;
+ pair->Get(publicId, systemId);
+ return AppendDoctypeToDocument(name, publicId, systemId, aBuilder);
+ }
+ case eTreeOpGetDocumentFragmentForTemplate: {
+ nsIContent* node = *(mOne.node);
+ *mTwo.node = GetDocumentFragmentForTemplate(node);
+ return NS_OK;
+ }
+ case eTreeOpGetFosterParent: {
+ nsIContent* table = *(mOne.node);
+ nsIContent* stackParent = *(mTwo.node);
+ nsIContent* fosterParent = GetFosterParent(table, stackParent);
+ *mThree.node = fosterParent;
+ return NS_OK;
+ }
+ case eTreeOpMarkAsBroken: {
+ return mOne.result;
+ }
+ case eTreeOpRunScript: {
+ nsIContent* node = *(mOne.node);
+ nsAHtml5TreeBuilderState* snapshot = mTwo.state;
+ if (snapshot) {
+ aBuilder->InitializeDocWriteParserState(snapshot, mFour.integer);
+ }
+ *aScriptElement = node;
+ return NS_OK;
+ }
+ case eTreeOpRunScriptAsyncDefer: {
+ nsIContent* node = *(mOne.node);
+ aBuilder->RunScript(node);
+ return NS_OK;
+ }
+ case eTreeOpPreventScriptExecution: {
+ nsIContent* node = *(mOne.node);
+ PreventScriptExecution(node);
+ return NS_OK;
+ }
+ case eTreeOpDoneAddingChildren: {
+ nsIContent* node = *(mOne.node);
+ node->DoneAddingChildren(node->HasParserNotified());
+ return NS_OK;
+ }
+ case eTreeOpDoneCreatingElement: {
+ nsIContent* node = *(mOne.node);
+ DoneCreatingElement(node);
+ return NS_OK;
+ }
+ case eTreeOpSetDocumentCharset: {
+ char* str = mOne.charPtr;
+ int32_t charsetSource = mFour.integer;
+ nsDependentCString dependentString(str);
+ aBuilder->SetDocumentCharsetAndSource(dependentString, charsetSource);
+ return NS_OK;
+ }
+ case eTreeOpNeedsCharsetSwitchTo: {
+ char* str = mOne.charPtr;
+ int32_t charsetSource = mFour.integer;
+ int32_t lineNumber = mTwo.integer;
+ aBuilder->NeedsCharsetSwitchTo(str, charsetSource, (uint32_t)lineNumber);
+ return NS_OK;
+ }
+ case eTreeOpUpdateStyleSheet: {
+ nsIContent* node = *(mOne.node);
+ aBuilder->UpdateStyleSheet(node);
+ return NS_OK;
+ }
+ case eTreeOpProcessMeta: {
+ nsIContent* node = *(mOne.node);
+ return aBuilder->ProcessMETATag(node);
+ }
+ case eTreeOpProcessOfflineManifest: {
+ char16_t* str = mOne.unicharPtr;
+ nsDependentString dependentString(str);
+ aBuilder->ProcessOfflineManifest(dependentString);
+ return NS_OK;
+ }
+ case eTreeOpMarkMalformedIfScript: {
+ nsIContent* node = *(mOne.node);
+ MarkMalformedIfScript(node);
+ return NS_OK;
+ }
+ case eTreeOpStreamEnded: {
+ aBuilder->DidBuildModel(false); // this causes a notifications flush anyway
+ return NS_OK;
+ }
+ case eTreeOpSetStyleLineNumber: {
+ nsIContent* node = *(mOne.node);
+ nsCOMPtr<nsIStyleSheetLinkingElement> ssle = do_QueryInterface(node);
+ NS_ASSERTION(ssle, "Node didn't QI to style.");
+ ssle->SetLineNumber(mFour.integer);
+ return NS_OK;
+ }
+ case eTreeOpSetScriptLineNumberAndFreeze: {
+ nsIContent* node = *(mOne.node);
+ nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(node);
+ NS_ASSERTION(sele, "Node didn't QI to script.");
+ sele->SetScriptLineNumber(mFour.integer);
+ sele->FreezeUriAsyncDefer();
+ return NS_OK;
+ }
+ case eTreeOpSvgLoad: {
+ nsIContent* node = *(mOne.node);
+ SvgLoad(node);
+ return NS_OK;
+ }
+ case eTreeOpMaybeComplainAboutCharset: {
+ char* msgId = mOne.charPtr;
+ bool error = mTwo.integer;
+ int32_t lineNumber = mThree.integer;
+ aBuilder->MaybeComplainAboutCharset(msgId, error, (uint32_t)lineNumber);
+ return NS_OK;
+ }
+ case eTreeOpAddClass: {
+ nsIContent* node = *(mOne.node);
+ char16_t* str = mTwo.unicharPtr;
+ nsDependentString depStr(str);
+ // See viewsource.css for the possible classes
+ nsAutoString klass;
+ node->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);
+ if (!klass.IsEmpty()) {
+ klass.Append(' ');
+ klass.Append(depStr);
+ node->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass, true);
+ } else {
+ node->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, depStr, true);
+ }
+ return NS_OK;
+ }
+ case eTreeOpAddViewSourceHref: {
+ nsIContent* node = *mOne.node;
+ char16_t* buffer = mTwo.unicharPtr;
+ int32_t length = mFour.integer;
+
+ nsDependentString relative(buffer, length);
+
+ nsIDocument* doc = aBuilder->GetDocument();
+
+ const nsCString& charset = doc->GetDocumentCharacterSet();
+ nsCOMPtr<nsIURI> uri;
+ nsresult rv = NS_NewURI(getter_AddRefs(uri),
+ relative,
+ charset.get(),
+ aBuilder->GetViewSourceBaseURI());
+ NS_ENSURE_SUCCESS(rv, NS_OK);
+
+ // Reuse the fix for bug 467852
+ // URLs that execute script (e.g. "javascript:" URLs) should just be
+ // ignored. There's nothing reasonable we can do with them, and allowing
+ // them to execute in the context of the view-source window presents a
+ // security risk. Just return the empty string in this case.
+ bool openingExecutesScript = false;
+ rv = NS_URIChainHasFlags(uri,
+ nsIProtocolHandler::URI_OPENING_EXECUTES_SCRIPT,
+ &openingExecutesScript);
+ if (NS_FAILED(rv) || openingExecutesScript) {
+ return NS_OK;
+ }
+
+ nsAutoCString viewSourceUrl;
+
+ // URLs that return data (e.g. "http:" URLs) should be prefixed with
+ // "view-source:". URLs that don't return data should just be returned
+ // undecorated.
+ bool doesNotReturnData = false;
+ rv = NS_URIChainHasFlags(uri,
+ nsIProtocolHandler::URI_DOES_NOT_RETURN_DATA,
+ &doesNotReturnData);
+ NS_ENSURE_SUCCESS(rv, NS_OK);
+ if (!doesNotReturnData) {
+ viewSourceUrl.AssignLiteral("view-source:");
+ }
+
+ nsAutoCString spec;
+ rv = uri->GetSpec(spec);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ viewSourceUrl.Append(spec);
+
+ nsAutoString utf16;
+ CopyUTF8toUTF16(viewSourceUrl, utf16);
+
+ node->SetAttr(kNameSpaceID_None, nsGkAtoms::href, utf16, true);
+ return NS_OK;
+ }
+ case eTreeOpAddViewSourceBase: {
+ char16_t* buffer = mTwo.unicharPtr;
+ int32_t length = mFour.integer;
+ nsDependentString baseUrl(buffer, length);
+ aBuilder->AddBase(baseUrl);
+ return NS_OK;
+ }
+ case eTreeOpAddError: {
+ nsIContent* node = *(mOne.node);
+ char* msgId = mTwo.charPtr;
+ nsCOMPtr<nsIAtom> atom = Reget(mThree.atom);
+ nsCOMPtr<nsIAtom> otherAtom = Reget(mFour.atom);
+ // See viewsource.css for the possible classes in addition to "error".
+ nsAutoString klass;
+ node->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);
+ if (!klass.IsEmpty()) {
+ klass.AppendLiteral(" error");
+ node->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass, true);
+ } else {
+ node->SetAttr(kNameSpaceID_None,
+ nsGkAtoms::_class,
+ NS_LITERAL_STRING("error"),
+ true);
+ }
+
+ nsresult rv;
+ nsXPIDLString message;
+ if (otherAtom) {
+ const char16_t* params[] = { atom->GetUTF16String(),
+ otherAtom->GetUTF16String() };
+ rv = nsContentUtils::FormatLocalizedString(
+ nsContentUtils::eHTMLPARSER_PROPERTIES, msgId, params, message);
+ NS_ENSURE_SUCCESS(rv, NS_OK);
+ } else if (atom) {
+ const char16_t* params[] = { atom->GetUTF16String() };
+ rv = nsContentUtils::FormatLocalizedString(
+ nsContentUtils::eHTMLPARSER_PROPERTIES, msgId, params, message);
+ NS_ENSURE_SUCCESS(rv, NS_OK);
+ } else {
+ rv = nsContentUtils::GetLocalizedString(
+ nsContentUtils::eHTMLPARSER_PROPERTIES, msgId, message);
+ NS_ENSURE_SUCCESS(rv, NS_OK);
+ }
+
+ nsAutoString title;
+ node->GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
+ if (!title.IsEmpty()) {
+ title.Append('\n');
+ title.Append(message);
+ node->SetAttr(kNameSpaceID_None, nsGkAtoms::title, title, true);
+ } else {
+ node->SetAttr(kNameSpaceID_None, nsGkAtoms::title, message, true);
+ }
+ return rv;
+ }
+ case eTreeOpAddLineNumberId: {
+ nsIContent* node = *(mOne.node);
+ int32_t lineNumber = mFour.integer;
+ nsAutoString val(NS_LITERAL_STRING("line"));
+ val.AppendInt(lineNumber);
+ node->SetAttr(kNameSpaceID_None, nsGkAtoms::id, val, true);
+ return NS_OK;
+ }
+ case eTreeOpStartLayout: {
+ aBuilder->StartLayout(); // this causes a notification flush anyway
+ return NS_OK;
+ }
+ default: {
+ MOZ_CRASH("Bogus tree op");
+ }
+ }
+ return NS_OK; // keep compiler happy
+}
diff --git a/parser/html/nsHtml5TreeOperation.h b/parser/html/nsHtml5TreeOperation.h
new file mode 100644
index 000000000..0b2970738
--- /dev/null
+++ b/parser/html/nsHtml5TreeOperation.h
@@ -0,0 +1,513 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5TreeOperation_h
+#define nsHtml5TreeOperation_h
+
+#include "nsHtml5DocumentMode.h"
+#include "nsHtml5HtmlAttributes.h"
+#include "nsXPCOMStrings.h"
+#include "mozilla/dom/FromParser.h"
+
+class nsIContent;
+class nsHtml5TreeOpExecutor;
+class nsHtml5DocumentBuilder;
+
+enum eHtml5TreeOperation {
+ eTreeOpUninitialized,
+ // main HTML5 ops
+ eTreeOpAppend,
+ eTreeOpDetach,
+ eTreeOpAppendChildrenToNewParent,
+ eTreeOpFosterParent,
+ eTreeOpAppendToDocument,
+ eTreeOpAddAttributes,
+ eTreeOpDocumentMode,
+ eTreeOpCreateElementNetwork,
+ eTreeOpCreateElementNotNetwork,
+ eTreeOpSetFormElement,
+ eTreeOpAppendText,
+ eTreeOpAppendIsindexPrompt,
+ eTreeOpFosterParentText,
+ eTreeOpAppendComment,
+ eTreeOpAppendCommentToDocument,
+ eTreeOpAppendDoctypeToDocument,
+ eTreeOpGetDocumentFragmentForTemplate,
+ eTreeOpGetFosterParent,
+ // Gecko-specific on-pop ops
+ eTreeOpMarkAsBroken,
+ eTreeOpRunScript,
+ eTreeOpRunScriptAsyncDefer,
+ eTreeOpPreventScriptExecution,
+ eTreeOpDoneAddingChildren,
+ eTreeOpDoneCreatingElement,
+ eTreeOpSetDocumentCharset,
+ eTreeOpNeedsCharsetSwitchTo,
+ eTreeOpUpdateStyleSheet,
+ eTreeOpProcessMeta,
+ eTreeOpProcessOfflineManifest,
+ eTreeOpMarkMalformedIfScript,
+ eTreeOpStreamEnded,
+ eTreeOpSetStyleLineNumber,
+ eTreeOpSetScriptLineNumberAndFreeze,
+ eTreeOpSvgLoad,
+ eTreeOpMaybeComplainAboutCharset,
+ eTreeOpAddClass,
+ eTreeOpAddViewSourceHref,
+ eTreeOpAddViewSourceBase,
+ eTreeOpAddError,
+ eTreeOpAddLineNumberId,
+ eTreeOpStartLayout
+};
+
+class nsHtml5TreeOperationStringPair {
+ private:
+ nsString mPublicId;
+ nsString mSystemId;
+ public:
+ nsHtml5TreeOperationStringPair(const nsAString& aPublicId,
+ const nsAString& aSystemId)
+ : mPublicId(aPublicId)
+ , mSystemId(aSystemId)
+ {
+ MOZ_COUNT_CTOR(nsHtml5TreeOperationStringPair);
+ }
+
+ ~nsHtml5TreeOperationStringPair()
+ {
+ MOZ_COUNT_DTOR(nsHtml5TreeOperationStringPair);
+ }
+
+ inline void Get(nsAString& aPublicId, nsAString& aSystemId)
+ {
+ aPublicId.Assign(mPublicId);
+ aSystemId.Assign(mSystemId);
+ }
+};
+
+class nsHtml5TreeOperation {
+
+ public:
+ /**
+ * Atom is used inside the parser core are either static atoms that are
+ * the same as Gecko-wide static atoms or they are dynamic atoms scoped by
+ * both thread and parser to a particular nsHtml5AtomTable. In order to
+ * such scoped atoms coming into contact with the rest of Gecko, atoms
+ * that are about to exit the parser must go through this method which
+ * reobtains dynamic atoms from the Gecko-global atom table.
+ *
+ * @param aAtom a potentially parser-scoped atom
+ * @return an nsIAtom that's pointer comparable on the main thread with
+ * other not-parser atoms.
+ */
+ static inline already_AddRefed<nsIAtom> Reget(nsIAtom* aAtom)
+ {
+ if (!aAtom || aAtom->IsStaticAtom()) {
+ return dont_AddRef(aAtom);
+ }
+ nsAutoString str;
+ aAtom->ToString(str);
+ return NS_Atomize(str);
+ }
+
+ static nsresult AppendTextToTextNode(const char16_t* aBuffer,
+ uint32_t aLength,
+ nsIContent* aTextNode,
+ nsHtml5DocumentBuilder* aBuilder);
+
+ static nsresult AppendText(const char16_t* aBuffer,
+ uint32_t aLength,
+ nsIContent* aParent,
+ nsHtml5DocumentBuilder* aBuilder);
+
+ static nsresult Append(nsIContent* aNode,
+ nsIContent* aParent,
+ nsHtml5DocumentBuilder* aBuilder);
+
+ static nsresult AppendToDocument(nsIContent* aNode,
+ nsHtml5DocumentBuilder* aBuilder);
+
+ static void Detach(nsIContent* aNode, nsHtml5DocumentBuilder* aBuilder);
+
+ static nsresult AppendChildrenToNewParent(nsIContent* aNode,
+ nsIContent* aParent,
+ nsHtml5DocumentBuilder* aBuilder);
+
+ static nsresult FosterParent(nsIContent* aNode,
+ nsIContent* aParent,
+ nsIContent* aTable,
+ nsHtml5DocumentBuilder* aBuilder);
+
+ static nsresult AddAttributes(nsIContent* aNode,
+ nsHtml5HtmlAttributes* aAttributes,
+ nsHtml5DocumentBuilder* aBuilder);
+
+ static nsIContent* CreateElement(int32_t aNs,
+ nsIAtom* aName,
+ nsHtml5HtmlAttributes* aAttributes,
+ mozilla::dom::FromParser aFromParser,
+ nsNodeInfoManager* aNodeInfoManager,
+ nsHtml5DocumentBuilder* aBuilder);
+
+ static void SetFormElement(nsIContent* aNode, nsIContent* aParent);
+
+ static nsresult AppendIsindexPrompt(nsIContent* parent,
+ nsHtml5DocumentBuilder* aBuilder);
+
+ static nsresult FosterParentText(nsIContent* aStackParent,
+ char16_t* aBuffer,
+ uint32_t aLength,
+ nsIContent* aTable,
+ nsHtml5DocumentBuilder* aBuilder);
+
+ static nsresult AppendComment(nsIContent* aParent,
+ char16_t* aBuffer,
+ int32_t aLength,
+ nsHtml5DocumentBuilder* aBuilder);
+
+ static nsresult AppendCommentToDocument(char16_t* aBuffer,
+ int32_t aLength,
+ nsHtml5DocumentBuilder* aBuilder);
+
+ static nsresult AppendDoctypeToDocument(nsIAtom* aName,
+ const nsAString& aPublicId,
+ const nsAString& aSystemId,
+ nsHtml5DocumentBuilder* aBuilder);
+
+ static nsIContent* GetDocumentFragmentForTemplate(nsIContent* aNode);
+
+ static nsIContent* GetFosterParent(nsIContent* aTable, nsIContent* aStackParent);
+
+ static void PreventScriptExecution(nsIContent* aNode);
+
+ static void DoneAddingChildren(nsIContent* aNode);
+
+ static void DoneCreatingElement(nsIContent* aNode);
+
+ static void SvgLoad(nsIContent* aNode);
+
+ static void MarkMalformedIfScript(nsIContent* aNode);
+
+ nsHtml5TreeOperation();
+
+ ~nsHtml5TreeOperation();
+
+ inline void Init(eHtml5TreeOperation aOpCode)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ mOpCode = aOpCode;
+ }
+
+ inline void Init(eHtml5TreeOperation aOpCode, nsIContentHandle* aNode)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ NS_PRECONDITION(aNode, "Initialized tree op with null node.");
+ mOpCode = aOpCode;
+ mOne.node = static_cast<nsIContent**>(aNode);
+ }
+
+ inline void Init(eHtml5TreeOperation aOpCode,
+ nsIContentHandle* aNode,
+ nsIContentHandle* aParent)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ NS_PRECONDITION(aNode, "Initialized tree op with null node.");
+ NS_PRECONDITION(aParent, "Initialized tree op with null parent.");
+ mOpCode = aOpCode;
+ mOne.node = static_cast<nsIContent**>(aNode);
+ mTwo.node = static_cast<nsIContent**>(aParent);
+ }
+
+ inline void Init(eHtml5TreeOperation aOpCode,
+ const nsACString& aString,
+ int32_t aInt32)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+
+ int32_t len = aString.Length();
+ char* str = new char[len + 1];
+ const char* start = aString.BeginReading();
+ for (int32_t i = 0; i < len; ++i) {
+ str[i] = start[i];
+ }
+ str[len] = '\0';
+
+ mOpCode = aOpCode;
+ mOne.charPtr = str;
+ mFour.integer = aInt32;
+ }
+
+ inline void Init(eHtml5TreeOperation aOpCode,
+ const nsACString& aString,
+ int32_t aInt32,
+ int32_t aLineNumber)
+ {
+ Init(aOpCode, aString, aInt32);
+ mTwo.integer = aLineNumber;
+ }
+
+ inline void Init(eHtml5TreeOperation aOpCode,
+ nsIContentHandle* aNode,
+ nsIContentHandle* aParent,
+ nsIContentHandle* aTable)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ NS_PRECONDITION(aNode, "Initialized tree op with null node.");
+ NS_PRECONDITION(aParent, "Initialized tree op with null parent.");
+ NS_PRECONDITION(aTable, "Initialized tree op with null table.");
+ mOpCode = aOpCode;
+ mOne.node = static_cast<nsIContent**>(aNode);
+ mTwo.node = static_cast<nsIContent**>(aParent);
+ mThree.node = static_cast<nsIContent**>(aTable);
+ }
+
+ inline void Init(nsHtml5DocumentMode aMode)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ mOpCode = eTreeOpDocumentMode;
+ mOne.mode = aMode;
+ }
+
+ inline void InitScript(nsIContentHandle* aNode)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ NS_PRECONDITION(aNode, "Initialized tree op with null node.");
+ mOpCode = eTreeOpRunScript;
+ mOne.node = static_cast<nsIContent**>(aNode);
+ mTwo.state = nullptr;
+ }
+
+ inline void Init(int32_t aNamespace,
+ nsIAtom* aName,
+ nsHtml5HtmlAttributes* aAttributes,
+ nsIContentHandle* aTarget,
+ nsIContentHandle* aIntendedParent,
+ bool aFromNetwork)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ NS_PRECONDITION(aName, "Initialized tree op with null name.");
+ NS_PRECONDITION(aTarget, "Initialized tree op with null target node.");
+ mOpCode = aFromNetwork ?
+ eTreeOpCreateElementNetwork :
+ eTreeOpCreateElementNotNetwork;
+ mFour.integer = aNamespace;
+ mFive.node = static_cast<nsIContent**>(aIntendedParent);
+ mOne.node = static_cast<nsIContent**>(aTarget);
+ mTwo.atom = aName;
+ if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
+ mThree.attributes = nullptr;
+ } else {
+ mThree.attributes = aAttributes;
+ }
+ }
+
+ inline void Init(eHtml5TreeOperation aOpCode,
+ char16_t* aBuffer,
+ int32_t aLength,
+ nsIContentHandle* aStackParent,
+ nsIContentHandle* aTable)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer.");
+ mOpCode = aOpCode;
+ mOne.node = static_cast<nsIContent**>(aStackParent);
+ mTwo.unicharPtr = aBuffer;
+ mThree.node = static_cast<nsIContent**>(aTable);
+ mFour.integer = aLength;
+ }
+
+ inline void Init(eHtml5TreeOperation aOpCode,
+ char16_t* aBuffer,
+ int32_t aLength,
+ nsIContentHandle* aParent)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer.");
+ mOpCode = aOpCode;
+ mOne.node = static_cast<nsIContent**>(aParent);
+ mTwo.unicharPtr = aBuffer;
+ mFour.integer = aLength;
+ }
+
+ inline void Init(eHtml5TreeOperation aOpCode,
+ char16_t* aBuffer,
+ int32_t aLength)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer.");
+ mOpCode = aOpCode;
+ mTwo.unicharPtr = aBuffer;
+ mFour.integer = aLength;
+ }
+
+ inline void Init(nsIContentHandle* aElement,
+ nsHtml5HtmlAttributes* aAttributes)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ NS_PRECONDITION(aElement, "Initialized tree op with null element.");
+ mOpCode = eTreeOpAddAttributes;
+ mOne.node = static_cast<nsIContent**>(aElement);
+ mTwo.attributes = aAttributes;
+ }
+
+ inline void Init(nsIAtom* aName,
+ const nsAString& aPublicId,
+ const nsAString& aSystemId)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ mOpCode = eTreeOpAppendDoctypeToDocument;
+ mOne.atom = aName;
+ mTwo.stringPair = new nsHtml5TreeOperationStringPair(aPublicId, aSystemId);
+ }
+
+ inline void Init(nsIContentHandle* aElement,
+ const char* aMsgId,
+ nsIAtom* aAtom,
+ nsIAtom* aOtherAtom)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ mOpCode = eTreeOpAddError;
+ mOne.node = static_cast<nsIContent**>(aElement);
+ mTwo.charPtr = (char*)aMsgId;
+ mThree.atom = aAtom;
+ mFour.atom = aOtherAtom;
+ }
+
+ inline void Init(nsIContentHandle* aElement,
+ const char* aMsgId,
+ nsIAtom* aAtom)
+ {
+ Init(aElement, aMsgId, aAtom, nullptr);
+ }
+
+ inline void Init(nsIContentHandle* aElement,
+ const char* aMsgId)
+ {
+ Init(aElement, aMsgId, nullptr, nullptr);
+ }
+
+ inline void Init(const char* aMsgId,
+ bool aError,
+ int32_t aLineNumber)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ mOpCode = eTreeOpMaybeComplainAboutCharset;
+ mOne.charPtr = const_cast<char*>(aMsgId);
+ mTwo.integer = aError;
+ mThree.integer = aLineNumber;
+ }
+
+ inline void Init(eHtml5TreeOperation aOpCode, const nsAString& aString)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+
+ char16_t* str = NS_StringCloneData(aString);
+ mOpCode = aOpCode;
+ mOne.unicharPtr = str;
+ }
+
+ inline void Init(eHtml5TreeOperation aOpCode,
+ nsIContentHandle* aNode,
+ int32_t aInt)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ NS_PRECONDITION(aNode, "Initialized tree op with null node.");
+ mOpCode = aOpCode;
+ mOne.node = static_cast<nsIContent**>(aNode);
+ mFour.integer = aInt;
+ }
+
+ inline void Init(nsresult aRv)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ NS_PRECONDITION(NS_FAILED(aRv), "Initialized tree op with non-failure.");
+ mOpCode = eTreeOpMarkAsBroken;
+ mOne.result = aRv;
+ }
+
+ inline void InitAddClass(nsIContentHandle* aNode, const char16_t* aClass)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ NS_PRECONDITION(aNode, "Initialized tree op with null node.");
+ NS_PRECONDITION(aClass, "Initialized tree op with null string.");
+ // aClass must be a literal string that does not need freeing
+ mOpCode = eTreeOpAddClass;
+ mOne.node = static_cast<nsIContent**>(aNode);
+ mTwo.unicharPtr = (char16_t*)aClass;
+ }
+
+ inline void InitAddLineNumberId(nsIContentHandle* aNode,
+ const int32_t aLineNumber)
+ {
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
+ "Op code must be uninitialized when initializing.");
+ NS_PRECONDITION(aNode, "Initialized tree op with null node.");
+ NS_PRECONDITION(aLineNumber > 0, "Initialized tree op with line number.");
+ // aClass must be a literal string that does not need freeing
+ mOpCode = eTreeOpAddLineNumberId;
+ mOne.node = static_cast<nsIContent**>(aNode);
+ mFour.integer = aLineNumber;
+ }
+
+ inline bool IsRunScript()
+ {
+ return mOpCode == eTreeOpRunScript;
+ }
+
+ inline bool IsMarkAsBroken()
+ {
+ return mOpCode == eTreeOpMarkAsBroken;
+ }
+
+ inline void SetSnapshot(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine)
+ {
+ NS_ASSERTION(IsRunScript(),
+ "Setting a snapshot for a tree operation other than eTreeOpRunScript!");
+ NS_PRECONDITION(aSnapshot, "Initialized tree op with null snapshot.");
+ mTwo.state = aSnapshot;
+ mFour.integer = aLine;
+ }
+
+ nsresult Perform(nsHtml5TreeOpExecutor* aBuilder,
+ nsIContent** aScriptElement);
+
+ private:
+ // possible optimization:
+ // Make the queue take items the size of pointer and make the op code
+ // decide how many operands it dequeues after it.
+ eHtml5TreeOperation mOpCode;
+ union {
+ nsIContent** node;
+ nsIAtom* atom;
+ nsHtml5HtmlAttributes* attributes;
+ nsHtml5DocumentMode mode;
+ char16_t* unicharPtr;
+ char* charPtr;
+ nsHtml5TreeOperationStringPair* stringPair;
+ nsAHtml5TreeBuilderState* state;
+ int32_t integer;
+ nsresult result;
+ } mOne, mTwo, mThree, mFour, mFive;
+};
+
+#endif // nsHtml5TreeOperation_h
diff --git a/parser/html/nsHtml5UTF16Buffer.cpp b/parser/html/nsHtml5UTF16Buffer.cpp
new file mode 100644
index 000000000..f70365ce4
--- /dev/null
+++ b/parser/html/nsHtml5UTF16Buffer.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2008-2010 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit UTF16Buffer.java instead and regenerate.
+ */
+
+#define nsHtml5UTF16Buffer_cpp__
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5ByteReadable.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
+
+#include "nsHtml5Tokenizer.h"
+#include "nsHtml5TreeBuilder.h"
+#include "nsHtml5MetaScanner.h"
+#include "nsHtml5AttributeName.h"
+#include "nsHtml5ElementName.h"
+#include "nsHtml5HtmlAttributes.h"
+#include "nsHtml5StackNode.h"
+#include "nsHtml5StateSnapshot.h"
+#include "nsHtml5Portability.h"
+
+#include "nsHtml5UTF16Buffer.h"
+
+int32_t
+nsHtml5UTF16Buffer::getStart()
+{
+ return start;
+}
+
+void
+nsHtml5UTF16Buffer::setStart(int32_t start)
+{
+ this->start = start;
+}
+
+char16_t*
+nsHtml5UTF16Buffer::getBuffer()
+{
+ return buffer;
+}
+
+int32_t
+nsHtml5UTF16Buffer::getEnd()
+{
+ return end;
+}
+
+bool
+nsHtml5UTF16Buffer::hasMore()
+{
+ return start < end;
+}
+
+int32_t
+nsHtml5UTF16Buffer::getLength()
+{
+ return end - start;
+}
+
+void
+nsHtml5UTF16Buffer::adjust(bool lastWasCR)
+{
+ if (lastWasCR && buffer[start] == '\n') {
+ start++;
+ }
+}
+
+void
+nsHtml5UTF16Buffer::setEnd(int32_t end)
+{
+ this->end = end;
+}
+
+void
+nsHtml5UTF16Buffer::initializeStatics()
+{
+}
+
+void
+nsHtml5UTF16Buffer::releaseStatics()
+{
+}
+
+
+#include "nsHtml5UTF16BufferCppSupplement.h"
+
diff --git a/parser/html/nsHtml5UTF16Buffer.h b/parser/html/nsHtml5UTF16Buffer.h
new file mode 100644
index 000000000..cf810e124
--- /dev/null
+++ b/parser/html/nsHtml5UTF16Buffer.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2008-2010 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
+ * Please edit UTF16Buffer.java instead and regenerate.
+ */
+
+#ifndef nsHtml5UTF16Buffer_h
+#define nsHtml5UTF16Buffer_h
+
+#include "nsIAtom.h"
+#include "nsHtml5AtomTable.h"
+#include "nsString.h"
+#include "nsNameSpaceManager.h"
+#include "nsIContent.h"
+#include "nsTraceRefcnt.h"
+#include "jArray.h"
+#include "nsHtml5ArrayCopy.h"
+#include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Atoms.h"
+#include "nsHtml5ByteReadable.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
+
+class nsHtml5StreamParser;
+
+class nsHtml5Tokenizer;
+class nsHtml5TreeBuilder;
+class nsHtml5MetaScanner;
+class nsHtml5AttributeName;
+class nsHtml5ElementName;
+class nsHtml5HtmlAttributes;
+class nsHtml5StateSnapshot;
+class nsHtml5Portability;
+
+
+class nsHtml5UTF16Buffer
+{
+ private:
+ char16_t* buffer;
+ int32_t start;
+ int32_t end;
+ public:
+ int32_t getStart();
+ void setStart(int32_t start);
+ char16_t* getBuffer();
+ int32_t getEnd();
+ bool hasMore();
+ int32_t getLength();
+ void adjust(bool lastWasCR);
+ void setEnd(int32_t end);
+ static void initializeStatics();
+ static void releaseStatics();
+
+#include "nsHtml5UTF16BufferHSupplement.h"
+};
+
+
+
+#endif
+
diff --git a/parser/html/nsHtml5UTF16BufferCppSupplement.h b/parser/html/nsHtml5UTF16BufferCppSupplement.h
new file mode 100644
index 000000000..4c374fecc
--- /dev/null
+++ b/parser/html/nsHtml5UTF16BufferCppSupplement.h
@@ -0,0 +1,36 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+nsHtml5UTF16Buffer::nsHtml5UTF16Buffer(char16_t* aBuffer, int32_t aEnd)
+ : buffer(aBuffer)
+ , start(0)
+ , end(aEnd)
+{
+ MOZ_COUNT_CTOR(nsHtml5UTF16Buffer);
+}
+
+nsHtml5UTF16Buffer::~nsHtml5UTF16Buffer()
+{
+ MOZ_COUNT_DTOR(nsHtml5UTF16Buffer);
+}
+
+void
+nsHtml5UTF16Buffer::DeleteBuffer()
+{
+ delete[] buffer;
+}
+
+void
+nsHtml5UTF16Buffer::Swap(nsHtml5UTF16Buffer* aOther)
+{
+ char16_t* tempBuffer = buffer;
+ int32_t tempStart = start;
+ int32_t tempEnd = end;
+ buffer = aOther->buffer;
+ start = aOther->start;
+ end = aOther->end;
+ aOther->buffer = tempBuffer;
+ aOther->start = tempStart;
+ aOther->end = tempEnd;
+}
diff --git a/parser/html/nsHtml5UTF16BufferHSupplement.h b/parser/html/nsHtml5UTF16BufferHSupplement.h
new file mode 100644
index 000000000..938d164e8
--- /dev/null
+++ b/parser/html/nsHtml5UTF16BufferHSupplement.h
@@ -0,0 +1,17 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+protected:
+ nsHtml5UTF16Buffer(char16_t* aBuffer, int32_t aEnd);
+ ~nsHtml5UTF16Buffer();
+
+ /**
+ * For working around the privacy of |buffer| in the generated code.
+ */
+ void DeleteBuffer();
+
+ /**
+ * For working around the privacy of |buffer| in the generated code.
+ */
+ void Swap(nsHtml5UTF16Buffer* aOther);
diff --git a/parser/html/nsHtml5ViewSourceUtils.cpp b/parser/html/nsHtml5ViewSourceUtils.cpp
new file mode 100644
index 000000000..4dd33fc05
--- /dev/null
+++ b/parser/html/nsHtml5ViewSourceUtils.cpp
@@ -0,0 +1,53 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+#include "nsHtml5ViewSourceUtils.h"
+#include "nsHtml5AttributeName.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/UniquePtr.h"
+
+// static
+nsHtml5HtmlAttributes*
+nsHtml5ViewSourceUtils::NewBodyAttributes()
+{
+ nsHtml5HtmlAttributes* bodyAttrs = new nsHtml5HtmlAttributes(0);
+ auto id = MakeUnique<nsString>(NS_LITERAL_STRING("viewsource"));
+ bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, id.release(), -1);
+
+ auto klass = MakeUnique<nsString>();
+ if (mozilla::Preferences::GetBool("view_source.wrap_long_lines", true)) {
+ klass->Append(NS_LITERAL_STRING("wrap "));
+ }
+ if (mozilla::Preferences::GetBool("view_source.syntax_highlight", true)) {
+ klass->Append(NS_LITERAL_STRING("highlight"));
+ }
+ if (!klass->IsEmpty()) {
+ bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_CLASS, klass.release(), -1);
+ }
+
+ int32_t tabSize = mozilla::Preferences::GetInt("view_source.tab_size", 4);
+ if (tabSize > 0) {
+ auto style = MakeUnique<nsString>(NS_LITERAL_STRING("-moz-tab-size: "));
+ style->AppendInt(tabSize);
+ bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_STYLE, style.release(), -1);
+ }
+
+ return bodyAttrs;
+}
+
+// static
+nsHtml5HtmlAttributes*
+nsHtml5ViewSourceUtils::NewLinkAttributes()
+{
+ nsHtml5HtmlAttributes* linkAttrs = new nsHtml5HtmlAttributes(0);
+ nsString* rel = new nsString(NS_LITERAL_STRING("stylesheet"));
+ linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_REL, rel, -1);
+ nsString* type = new nsString(NS_LITERAL_STRING("text/css"));
+ linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TYPE, type, -1);
+ nsString* href = new nsString(
+ NS_LITERAL_STRING("resource://gre-resources/viewsource.css"));
+ linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_HREF, href, -1);
+ return linkAttrs;
+}
diff --git a/parser/html/nsHtml5ViewSourceUtils.h b/parser/html/nsHtml5ViewSourceUtils.h
new file mode 100644
index 000000000..1644801b6
--- /dev/null
+++ b/parser/html/nsHtml5ViewSourceUtils.h
@@ -0,0 +1,17 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5ViewSourceUtils_h
+#define nsHtml5ViewSourceUtils_h
+
+#include "nsHtml5HtmlAttributes.h"
+
+class nsHtml5ViewSourceUtils
+{
+ public:
+ static nsHtml5HtmlAttributes* NewBodyAttributes();
+ static nsHtml5HtmlAttributes* NewLinkAttributes();
+};
+
+#endif // nsHtml5ViewSourceUtils_h
diff --git a/parser/html/nsIContentHandle.h b/parser/html/nsIContentHandle.h
new file mode 100644
index 000000000..b1cd6475f
--- /dev/null
+++ b/parser/html/nsIContentHandle.h
@@ -0,0 +1,5 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+typedef void nsIContentHandle;
diff --git a/parser/html/nsIParserUtils.idl b/parser/html/nsIParserUtils.idl
new file mode 100644
index 000000000..a982cb2de
--- /dev/null
+++ b/parser/html/nsIParserUtils.idl
@@ -0,0 +1,130 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsIDOMElement;
+interface nsIDOMDocumentFragment;
+interface nsIURI;
+
+/**
+ * Non-Web HTML parser functionality to Firefox extensions and XULRunner apps.
+ * Don't use this from within Gecko--use nsContentUtils, nsTreeSanitizer, etc.
+ * directly instead.
+ */
+[scriptable, uuid(a1101145-0025-411e-8873-fdf57bf28128)]
+interface nsIParserUtils : nsISupports
+{
+
+ /**
+ * Flag for sanitizer: Allow comment nodes.
+ */
+ const unsigned long SanitizerAllowComments = (1 << 0);
+
+ /**
+ * Flag for sanitizer: Allow <style> and style="" (with contents sanitized
+ * in case of -moz-binding). Note! If -moz-binding is absent, properties
+ * that might be XSS risks in other Web engines are preserved!
+ */
+ const unsigned long SanitizerAllowStyle = (1 << 1);
+
+ /**
+ * Flag for sanitizer: Only allow cid: URLs for embedded content.
+ *
+ * At present, sanitizing CSS backgrounds, etc., is not supported, so setting
+ * this together with SanitizerAllowStyle doesn't make sense.
+ *
+ * At present, sanitizing CSS syntax in SVG presentational attributes is not
+ * supported, so this option flattens out SVG.
+ */
+ const unsigned long SanitizerCidEmbedsOnly = (1 << 2);
+
+ /**
+ * Flag for sanitizer: Drop non-CSS presentational HTML elements and
+ * attributes, such as <font>, <center> and bgcolor="".
+ */
+ const unsigned long SanitizerDropNonCSSPresentation = (1 << 3);
+
+ /**
+ * Flag for sanitizer: Drop forms and form controls (excluding
+ * fieldset/legend).
+ */
+ const unsigned long SanitizerDropForms = (1 << 4);
+
+ /**
+ * Flag for sanitizer: Drop <img>, <video>, <audio> and <source> and flatten
+ * out SVG.
+ */
+ const unsigned long SanitizerDropMedia = (1 << 5);
+
+ /**
+ * Parses a string into an HTML document, sanitizes the document and
+ * returns the result serialized to a string.
+ *
+ * The sanitizer is designed to protect against XSS when sanitized content
+ * is inserted into a different-origin context without an iframe-equivalent
+ * sandboxing mechanism.
+ *
+ * By default, the sanitizer doesn't try to avoid leaking information that
+ * the content was viewed to third parties. That is, by default, e.g.
+ * <img src> pointing to an HTTP server potentially controlled by a third
+ * party is not removed. To avoid ambient information leakage upon loading
+ * the sanitized content, use the SanitizerInternalEmbedsOnly flag. In that
+ * case, <a href> links (and similar) to other content are preserved, so an
+ * explicit user action (following a link) after the content has been loaded
+ * can still leak information.
+ *
+ * By default, non-dangerous non-CSS presentational HTML elements and
+ * attributes or forms are not removed. To remove these, use
+ * SanitizerDropNonCSSPresentation and/or SanitizerDropForms.
+ *
+ * By default, comments and CSS is removed. To preserve comments, use
+ * SanitizerAllowComments. To preserve <style> and style="", use
+ * SanitizerAllowStyle. -moz-binding is removed from <style> and style="" if
+ * present. In this case, properties that Gecko doesn't recognize can get
+ * removed as a side effect. Note! If -moz-binding is not present, <style>
+ * and style="" and SanitizerAllowStyle is specified, the sanitized content
+ * may still be XSS dangerous if loaded into a non-Gecko Web engine!
+ *
+ * @param src the HTML source to parse (C++ callers are allowed but not
+ * required to use the same string for the return value.)
+ * @param flags sanitization option flags defined above
+ */
+ AString sanitize(in AString src, in unsigned long flags);
+
+ /**
+ * Convert HTML to plain text.
+ *
+ * @param src the HTML source to parse (C++ callers are allowed but not
+ * required to use the same string for the return value.)
+ * @param flags conversion option flags defined in nsIDocumentEncoder
+ * @param wrapCol number of characters per line; 0 for no auto-wrapping
+ */
+ AString convertToPlainText(in AString src,
+ in unsigned long flags,
+ in unsigned long wrapCol);
+
+ /**
+ * Parses markup into a sanitized document fragment.
+ *
+ * @param fragment the input markup
+ * @param flags sanitization option flags defined above
+ * @param isXML true if |fragment| is XML and false if HTML
+ * @param baseURI the base URL for this fragment
+ * @param element the context node for the fragment parsing algorithm
+ */
+ nsIDOMDocumentFragment parseFragment(in AString fragment,
+ in unsigned long flags,
+ in boolean isXML,
+ in nsIURI baseURI,
+ in nsIDOMElement element);
+
+};
+
+%{ C++
+#define NS_PARSERUTILS_CONTRACTID \
+ "@mozilla.org/parserutils;1"
+#define NS_PARSERUTILS_CID \
+{ 0xaf7b24cb, 0x893f, 0x41bb, { 0x96, 0x1f, 0x5a, 0x69, 0x38, 0x8e, 0x27, 0xc3 } }
+%}
diff --git a/parser/html/nsIScriptableUnescapeHTML.idl b/parser/html/nsIScriptableUnescapeHTML.idl
new file mode 100644
index 000000000..238adf0dc
--- /dev/null
+++ b/parser/html/nsIScriptableUnescapeHTML.idl
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsIDOMElement;
+interface nsIDOMDocumentFragment;
+interface nsIURI;
+
+/**
+ * This interface is OBSOLETE and exists solely for legacy extensions.
+ */
+[scriptable, uuid(3ab244a9-f09d-44da-9e3f-ee4d67367f2d)]
+interface nsIScriptableUnescapeHTML : nsISupports
+{
+ /**
+ * Converts HTML to plain text. This is equivalent to calling
+ * nsIParserUtils::convertToPlainText(src,
+ * nsIDocumentEncoder::OutputSelectionOnly |
+ * nsIDocumentEncoder::OutputAbsoluteLinks, 0).
+ *
+ * You should call nsIParserUtils::convertToPlainText() instead of calling
+ * this method.
+ *
+ * @param src The HTML string to convert to plain text.
+ */
+ AString unescape(in AString src);
+
+ /**
+ * Parses markup into a sanitized document fragment. This is equivalent to
+ * calling nsIParserUtils::parseFragment(fragment, 0, isXML, baseURI,
+ * element).
+ *
+ * You should call nsIParserUtils::parseFragment() instead of calling this
+ * method.
+ * @param fragment the input markup
+ * @param isXML true if |fragment| is XML and false if HTML
+ * @param baseURI the base URL for this fragment
+ * @param element the context node for the fragment parsing algorithm
+ */
+ nsIDOMDocumentFragment parseFragment(in AString fragment,
+ in boolean isXML,
+ in nsIURI baseURI,
+ in nsIDOMElement element);
+};
+
+%{ C++
+#define NS_SCRIPTABLEUNESCAPEHTML_CONTRACTID \
+ "@mozilla.org/feed-unescapehtml;1"
+#define NS_SCRIPTABLEUNESCAPEHTML_CID \
+{ 0x10f2f5f0, 0xf103, 0x4901, { 0x98, 0x0f, 0xba, 0x11, 0xbd, 0x70, 0xd6, 0x0d} }
+%}
diff --git a/parser/html/nsParserUtils.cpp b/parser/html/nsParserUtils.cpp
new file mode 100644
index 000000000..9e0bb8c9e
--- /dev/null
+++ b/parser/html/nsParserUtils.cpp
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsString.h"
+#include "nsIComponentManager.h"
+#include "nsCOMPtr.h"
+#include "nsXPCOM.h"
+#include "nsISupportsPrimitives.h"
+#include "nsXPIDLString.h"
+#include "nsScriptLoader.h"
+#include "nsEscape.h"
+#include "nsIParser.h"
+#include "nsIDTD.h"
+#include "nsNetCID.h"
+#include "nsNetUtil.h"
+#include "nsParserCIID.h"
+#include "nsContentUtils.h"
+#include "nsIContentSink.h"
+#include "nsIDocumentEncoder.h"
+#include "nsIDOMDocumentFragment.h"
+#include "nsIFragmentContentSink.h"
+#include "nsIDOMDocument.h"
+#include "nsIDOMNodeList.h"
+#include "nsIDOMNode.h"
+#include "nsIDOMElement.h"
+#include "nsIDocument.h"
+#include "nsIContent.h"
+#include "nsAttrName.h"
+#include "nsHTMLParts.h"
+#include "nsContentCID.h"
+#include "nsIScriptableUnescapeHTML.h"
+#include "nsParserUtils.h"
+#include "nsAutoPtr.h"
+#include "nsTreeSanitizer.h"
+#include "nsHtml5Module.h"
+#include "mozilla/dom/DocumentFragment.h"
+#include "nsNullPrincipal.h"
+
+#define XHTML_DIV_TAG "div xmlns=\"http://www.w3.org/1999/xhtml\""
+
+using namespace mozilla::dom;
+
+NS_IMPL_ISUPPORTS(nsParserUtils,
+ nsIScriptableUnescapeHTML,
+ nsIParserUtils)
+
+NS_IMETHODIMP
+nsParserUtils::ConvertToPlainText(const nsAString& aFromStr,
+ uint32_t aFlags,
+ uint32_t aWrapCol,
+ nsAString& aToStr)
+{
+ return nsContentUtils::ConvertToPlainText(aFromStr,
+ aToStr,
+ aFlags,
+ aWrapCol);
+}
+
+NS_IMETHODIMP
+nsParserUtils::Unescape(const nsAString& aFromStr,
+ nsAString& aToStr)
+{
+ return nsContentUtils::ConvertToPlainText(aFromStr,
+ aToStr,
+ nsIDocumentEncoder::OutputSelectionOnly |
+ nsIDocumentEncoder::OutputAbsoluteLinks,
+ 0);
+}
+
+NS_IMETHODIMP
+nsParserUtils::Sanitize(const nsAString& aFromStr,
+ uint32_t aFlags,
+ nsAString& aToStr)
+{
+ nsCOMPtr<nsIURI> uri;
+ NS_NewURI(getter_AddRefs(uri), "about:blank");
+ nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::Create();
+ nsCOMPtr<nsIDOMDocument> domDocument;
+ nsresult rv = NS_NewDOMDocument(getter_AddRefs(domDocument),
+ EmptyString(),
+ EmptyString(),
+ nullptr,
+ uri,
+ uri,
+ principal,
+ true,
+ nullptr,
+ DocumentFlavorHTML);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
+ rv = nsContentUtils::ParseDocumentHTML(aFromStr, document, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsTreeSanitizer sanitizer(aFlags);
+ sanitizer.Sanitize(document);
+
+ nsCOMPtr<nsIDocumentEncoder> encoder =
+ do_CreateInstance(NS_DOC_ENCODER_CONTRACTID_BASE "text/html");
+
+ encoder->NativeInit(document,
+ NS_LITERAL_STRING("text/html"),
+ nsIDocumentEncoder::OutputDontRewriteEncodingDeclaration |
+ nsIDocumentEncoder::OutputNoScriptContent |
+ nsIDocumentEncoder::OutputEncodeBasicEntities |
+ nsIDocumentEncoder::OutputLFLineBreak |
+ nsIDocumentEncoder::OutputRaw);
+
+ return encoder->EncodeToString(aToStr);
+}
+
+NS_IMETHODIMP
+nsParserUtils::ParseFragment(const nsAString& aFragment,
+ bool aIsXML,
+ nsIURI* aBaseURI,
+ nsIDOMElement* aContextElement,
+ nsIDOMDocumentFragment** aReturn)
+{
+ return nsParserUtils::ParseFragment(aFragment,
+ 0,
+ aIsXML,
+ aBaseURI,
+ aContextElement,
+ aReturn);
+}
+
+NS_IMETHODIMP
+nsParserUtils::ParseFragment(const nsAString& aFragment,
+ uint32_t aFlags,
+ bool aIsXML,
+ nsIURI* aBaseURI,
+ nsIDOMElement* aContextElement,
+ nsIDOMDocumentFragment** aReturn)
+{
+ NS_ENSURE_ARG(aContextElement);
+ *aReturn = nullptr;
+
+ nsCOMPtr<nsIDocument> document;
+ nsCOMPtr<nsIDOMDocument> domDocument;
+ nsCOMPtr<nsIDOMNode> contextNode;
+ contextNode = do_QueryInterface(aContextElement);
+ contextNode->GetOwnerDocument(getter_AddRefs(domDocument));
+ document = do_QueryInterface(domDocument);
+ NS_ENSURE_TRUE(document, NS_ERROR_NOT_AVAILABLE);
+
+ nsAutoScriptBlockerSuppressNodeRemoved autoBlocker;
+
+ // stop scripts
+ RefPtr<nsScriptLoader> loader;
+ bool scripts_enabled = false;
+ if (document) {
+ loader = document->ScriptLoader();
+ scripts_enabled = loader->GetEnabled();
+ }
+ if (scripts_enabled) {
+ loader->SetEnabled(false);
+ }
+
+ // Wrap things in a div or body for parsing, but it won't show up in
+ // the fragment.
+ nsresult rv = NS_OK;
+ AutoTArray<nsString, 2> tagStack;
+ nsAutoCString base, spec;
+ if (aIsXML) {
+ // XHTML
+ if (aBaseURI) {
+ base.AppendLiteral(XHTML_DIV_TAG);
+ base.AppendLiteral(" xml:base=\"");
+ rv = aBaseURI->GetSpec(spec);
+ NS_ENSURE_SUCCESS(rv, rv);
+ // nsEscapeHTML is good enough, because we only need to get
+ // quotes, ampersands, and angle brackets
+ char* escapedSpec = nsEscapeHTML(spec.get());
+ if (escapedSpec)
+ base += escapedSpec;
+ free(escapedSpec);
+ base.Append('"');
+ tagStack.AppendElement(NS_ConvertUTF8toUTF16(base));
+ } else {
+ tagStack.AppendElement(NS_LITERAL_STRING(XHTML_DIV_TAG));
+ }
+ }
+
+ nsCOMPtr<nsIContent> fragment;
+ if (aIsXML) {
+ rv = nsContentUtils::ParseFragmentXML(aFragment,
+ document,
+ tagStack,
+ true,
+ aReturn);
+ fragment = do_QueryInterface(*aReturn);
+ } else {
+ NS_ADDREF(*aReturn = new DocumentFragment(document->NodeInfoManager()));
+ fragment = do_QueryInterface(*aReturn);
+ rv = nsContentUtils::ParseFragmentHTML(aFragment,
+ fragment,
+ nsGkAtoms::body,
+ kNameSpaceID_XHTML,
+ false,
+ true);
+ // Now, set the base URI on all subtree roots.
+ if (aBaseURI) {
+ nsresult rv2 = aBaseURI->GetSpec(spec);
+ NS_ENSURE_SUCCESS(rv2, rv2);
+ nsAutoString spec16;
+ CopyUTF8toUTF16(spec, spec16);
+ nsIContent* node = fragment->GetFirstChild();
+ while (node) {
+ if (node->IsElement()) {
+ node->SetAttr(kNameSpaceID_XML,
+ nsGkAtoms::base,
+ nsGkAtoms::xml,
+ spec16,
+ false);
+ }
+ node = node->GetNextSibling();
+ }
+ }
+ }
+ if (fragment) {
+ nsTreeSanitizer sanitizer(aFlags);
+ sanitizer.Sanitize(fragment);
+ }
+
+ if (scripts_enabled) {
+ loader->SetEnabled(true);
+ }
+
+ return rv;
+}
diff --git a/parser/html/nsParserUtils.h b/parser/html/nsParserUtils.h
new file mode 100644
index 000000000..4645f11b9
--- /dev/null
+++ b/parser/html/nsParserUtils.h
@@ -0,0 +1,23 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsParserUtils_h
+#define nsParserUtils_h
+
+#include "nsIScriptableUnescapeHTML.h"
+#include "nsIParserUtils.h"
+#include "mozilla/Attributes.h"
+
+class nsParserUtils final : public nsIScriptableUnescapeHTML,
+ public nsIParserUtils
+{
+ ~nsParserUtils() {}
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSISCRIPTABLEUNESCAPEHTML
+ NS_DECL_NSIPARSERUTILS
+};
+
+#endif // nsParserUtils_h
diff --git a/parser/htmlparser/CNavDTD.cpp b/parser/htmlparser/CNavDTD.cpp
new file mode 100644
index 000000000..ce4ac796d
--- /dev/null
+++ b/parser/htmlparser/CNavDTD.cpp
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=2 et tw=78: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.h"
+#include "nsISupportsImpl.h"
+#include "nsIParser.h"
+#include "CNavDTD.h"
+#include "nsIHTMLContentSink.h"
+
+NS_IMPL_ISUPPORTS(CNavDTD, nsIDTD);
+
+CNavDTD::CNavDTD()
+{
+}
+
+CNavDTD::~CNavDTD()
+{
+}
+
+NS_IMETHODIMP
+CNavDTD::WillBuildModel(const CParserContext& aParserContext,
+ nsITokenizer* aTokenizer,
+ nsIContentSink* aSink)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+CNavDTD::BuildModel(nsITokenizer* aTokenizer,
+ nsIContentSink* aSink)
+{
+ // NB: It is important to throw STOPPARSING if the sink is the wrong type in
+ // order to make sure nsParser cleans up properly after itself.
+ nsCOMPtr<nsIHTMLContentSink> sink = do_QueryInterface(aSink);
+ if (!sink) {
+ return NS_ERROR_HTMLPARSER_STOPPARSING;
+ }
+
+ nsresult rv = sink->OpenContainer(nsIHTMLContentSink::eHTML);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = sink->OpenContainer(nsIHTMLContentSink::eBody);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = sink->CloseContainer(nsIHTMLContentSink::eBody);
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+ rv = sink->CloseContainer(nsIHTMLContentSink::eHTML);
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+CNavDTD::DidBuildModel(nsresult anErrorCode)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP_(void)
+CNavDTD::Terminate()
+{
+}
+
+
+NS_IMETHODIMP_(int32_t)
+CNavDTD::GetType()
+{
+ return NS_IPARSER_FLAG_HTML;
+}
+
+NS_IMETHODIMP_(nsDTDMode)
+CNavDTD::GetMode() const
+{
+ return eDTDMode_quirks;
+}
+
+NS_IMETHODIMP_(bool)
+CNavDTD::CanContain(int32_t aParent,int32_t aChild) const
+{
+ MOZ_CRASH("nobody calls this");
+ return false;
+}
+
+NS_IMETHODIMP_(bool)
+CNavDTD::IsContainer(int32_t aTag) const
+{
+ MOZ_CRASH("nobody calls this");
+ return false;
+}
diff --git a/parser/htmlparser/CNavDTD.h b/parser/htmlparser/CNavDTD.h
new file mode 100644
index 000000000..ae08c337c
--- /dev/null
+++ b/parser/htmlparser/CNavDTD.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=2 ts=2 et tw=78: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef NS_NAVHTMLDTD__
+#define NS_NAVHTMLDTD__
+
+#include "nsIDTD.h"
+#include "nsISupports.h"
+#include "nsCOMPtr.h"
+
+#ifdef _MSC_VER
+#pragma warning( disable : 4275 )
+#endif
+
+class CNavDTD : public nsIDTD
+{
+#ifdef _MSC_VER
+#pragma warning( default : 4275 )
+#endif
+
+ virtual ~CNavDTD();
+
+public:
+ CNavDTD();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIDTD
+};
+
+#endif
+
+
+
diff --git a/parser/htmlparser/CParserContext.cpp b/parser/htmlparser/CParserContext.cpp
new file mode 100644
index 000000000..f78878a87
--- /dev/null
+++ b/parser/htmlparser/CParserContext.cpp
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 et tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+#include "nsIAtom.h"
+#include "CParserContext.h"
+#include "nsToken.h"
+#include "prenv.h"
+#include "nsIHTMLContentSink.h"
+#include "nsHTMLTokenizer.h"
+#include "nsMimeTypes.h"
+#include "nsHTMLTokenizer.h"
+
+CParserContext::CParserContext(CParserContext* aPrevContext,
+ nsScanner* aScanner,
+ void *aKey,
+ eParserCommands aCommand,
+ nsIRequestObserver* aListener,
+ eAutoDetectResult aStatus,
+ bool aCopyUnused)
+ : mListener(aListener),
+ mKey(aKey),
+ mPrevContext(aPrevContext),
+ mScanner(aScanner),
+ mDTDMode(eDTDMode_unknown),
+ mStreamListenerState(eNone),
+ mContextType(eCTNone),
+ mAutoDetectStatus(aStatus),
+ mParserCommand(aCommand),
+ mMultipart(true),
+ mCopyUnused(aCopyUnused)
+{
+ MOZ_COUNT_CTOR(CParserContext);
+}
+
+CParserContext::~CParserContext()
+{
+ // It's ok to simply ingore the PrevContext.
+ MOZ_COUNT_DTOR(CParserContext);
+}
+
+void
+CParserContext::SetMimeType(const nsACString& aMimeType)
+{
+ mMimeType.Assign(aMimeType);
+
+ mDocType = ePlainText;
+
+ if (mMimeType.EqualsLiteral(TEXT_HTML))
+ mDocType = eHTML_Strict;
+ else if (mMimeType.EqualsLiteral(TEXT_XML) ||
+ mMimeType.EqualsLiteral(APPLICATION_XML) ||
+ mMimeType.EqualsLiteral(APPLICATION_XHTML_XML) ||
+ mMimeType.EqualsLiteral(TEXT_XUL) ||
+ mMimeType.EqualsLiteral(IMAGE_SVG_XML) ||
+ mMimeType.EqualsLiteral(APPLICATION_MATHML_XML) ||
+ mMimeType.EqualsLiteral(APPLICATION_RDF_XML) ||
+ mMimeType.EqualsLiteral(APPLICATION_WAPXHTML_XML) ||
+ mMimeType.EqualsLiteral(TEXT_RDF))
+ mDocType = eXML;
+}
+
+nsresult
+CParserContext::GetTokenizer(nsIDTD* aDTD,
+ nsIContentSink* aSink,
+ nsITokenizer*& aTokenizer)
+{
+ nsresult result = NS_OK;
+ int32_t type = aDTD ? aDTD->GetType() : NS_IPARSER_FLAG_HTML;
+
+ if (!mTokenizer) {
+ if (type == NS_IPARSER_FLAG_HTML || mParserCommand == eViewSource) {
+ mTokenizer = new nsHTMLTokenizer;
+ }
+ else if (type == NS_IPARSER_FLAG_XML) {
+ mTokenizer = do_QueryInterface(aDTD, &result);
+ }
+ }
+
+ aTokenizer = mTokenizer;
+
+ return result;
+}
diff --git a/parser/htmlparser/CParserContext.h b/parser/htmlparser/CParserContext.h
new file mode 100644
index 000000000..8850b83d5
--- /dev/null
+++ b/parser/htmlparser/CParserContext.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * MODULE NOTES:
+ * @update gess 4/1/98
+ *
+ */
+
+#ifndef __CParserContext
+#define __CParserContext
+
+#include "nsIParser.h"
+#include "nsIURL.h"
+#include "nsIDTD.h"
+#include "nsIStreamListener.h"
+#include "nsIRequest.h"
+#include "nsScanner.h"
+#include "nsString.h"
+#include "nsCOMPtr.h"
+#include "nsAutoPtr.h"
+
+/**
+ * Note that the parser is given FULL access to all
+ * data in a parsercontext. Hey, that what it's for!
+ */
+
+class CParserContext {
+public:
+ enum eContextType {eCTNone,eCTURL,eCTString,eCTStream};
+
+ CParserContext(CParserContext* aPrevContext,
+ nsScanner* aScanner,
+ void* aKey = 0,
+ eParserCommands aCommand = eViewNormal,
+ nsIRequestObserver* aListener = 0,
+ eAutoDetectResult aStatus = eUnknownDetect,
+ bool aCopyUnused = false);
+
+ ~CParserContext();
+
+ nsresult GetTokenizer(nsIDTD* aDTD,
+ nsIContentSink* aSink,
+ nsITokenizer*& aTokenizer);
+ void SetMimeType(const nsACString& aMimeType);
+
+ nsCOMPtr<nsIRequest> mRequest; // provided by necko to differnciate different input streams
+ // why is mRequest strongly referenced? see bug 102376.
+ nsCOMPtr<nsIRequestObserver> mListener;
+ void* const mKey;
+ nsCOMPtr<nsITokenizer> mTokenizer;
+ CParserContext* const mPrevContext;
+ nsAutoPtr<nsScanner> mScanner;
+
+ nsCString mMimeType;
+ nsDTDMode mDTDMode;
+
+ eParserDocType mDocType;
+ eStreamState mStreamListenerState;
+ eContextType mContextType;
+ eAutoDetectResult mAutoDetectStatus;
+ eParserCommands mParserCommand;
+
+ bool mMultipart;
+ bool mCopyUnused;
+};
+
+#endif
diff --git a/parser/htmlparser/moz.build b/parser/htmlparser/moz.build
new file mode 100644
index 000000000..7e5da29a5
--- /dev/null
+++ b/parser/htmlparser/moz.build
@@ -0,0 +1,53 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini']
+BROWSER_CHROME_MANIFESTS += ['tests/mochitest/browser.ini']
+
+XPIDL_SOURCES += [
+ 'nsIExpatSink.idl',
+ 'nsIExtendedExpatSink.idl',
+]
+
+XPIDL_MODULE = 'htmlparser'
+
+EXPORTS += [
+ 'nsHTMLTagList.h',
+ 'nsHTMLTags.h',
+ 'nsIContentSink.h',
+ 'nsIDTD.h',
+ 'nsIFragmentContentSink.h',
+ 'nsIHTMLContentSink.h',
+ 'nsIParser.h',
+ 'nsIParserService.h',
+ 'nsITokenizer.h',
+ 'nsParserBase.h',
+ 'nsParserCIID.h',
+ 'nsParserConstants.h',
+ 'nsScannerString.h',
+ 'nsToken.h',
+]
+
+UNIFIED_SOURCES += [
+ 'CNavDTD.cpp',
+ 'CParserContext.cpp',
+ 'nsElementTable.cpp',
+ 'nsExpatDriver.cpp',
+ 'nsHTMLEntities.cpp',
+ 'nsHTMLTags.cpp',
+ 'nsHTMLTokenizer.cpp',
+ 'nsParser.cpp',
+ 'nsParserModule.cpp',
+ 'nsParserMsgUtils.cpp',
+ 'nsParserService.cpp',
+ 'nsScanner.cpp',
+ 'nsScannerString.cpp',
+]
+
+FINAL_LIBRARY = 'xul'
+
+if CONFIG['GNU_CXX']:
+ CXXFLAGS += ['-Wno-error=shadow']
diff --git a/parser/htmlparser/nsElementTable.cpp b/parser/htmlparser/nsElementTable.cpp
new file mode 100644
index 000000000..80f581a16
--- /dev/null
+++ b/parser/htmlparser/nsElementTable.cpp
@@ -0,0 +1,623 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 et tw=78: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+#include "nsIAtom.h"
+#include "nsElementTable.h"
+
+/*****************************************************************************
+ Now it's time to list all the html elements all with their capabilities...
+******************************************************************************/
+
+// The Element Table (sung to the tune of Modern Major General)
+
+const nsHTMLElement gHTMLElements[] = {
+ {
+ /*tag*/ eHTMLTag_unknown,
+ /*parent,leaf*/ kNone, true
+ },
+ {
+ /*tag*/ eHTMLTag_a,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_abbr,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_acronym,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_address,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_applet,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_area,
+ /*parent,leaf*/ kNone, true
+ },
+ {
+ /*tag*/ eHTMLTag_article,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_aside,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_audio,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_b,
+ /*parent,leaf*/ kFontStyle, false
+ },
+ {
+ /*tag*/ eHTMLTag_base,
+ /*parent,leaf*/ kHeadContent, true
+ },
+ {
+ /*tag*/ eHTMLTag_basefont,
+ /*parent,leaf*/ kSpecial, true
+ },
+ {
+ /*tag*/ eHTMLTag_bdo,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_bgsound,
+ /*parent,leaf*/ (kFlowEntity|kHeadMisc), true
+ },
+ {
+ /*tag*/ eHTMLTag_big,
+ /*parent,leaf*/ kFontStyle, false
+ },
+ {
+ /*tag*/ eHTMLTag_blockquote,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_body,
+ /*parent,leaf*/ kHTMLContent, false
+ },
+ {
+ /*tag*/ eHTMLTag_br,
+ /*parent,leaf*/ kSpecial, true
+ },
+ {
+ /*tag*/ eHTMLTag_button,
+ /*parent,leaf*/ kFormControl, false
+ },
+ {
+ /*tag*/ eHTMLTag_canvas,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_caption,
+ /*parent,leaf*/ kNone, false
+ },
+ {
+ /*tag*/ eHTMLTag_center,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_cite,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_code,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_col,
+ /*parent,leaf*/ kNone, true
+ },
+ {
+ /*tag*/ eHTMLTag_colgroup,
+ /*parent,leaf*/ kNone, false
+ },
+ {
+ /*tag*/ eHTMLTag_content,
+ /*parent,leaf*/ kNone, false
+ },
+ {
+ /*tag*/ eHTMLTag_data,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_datalist,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_dd,
+ /*parent,leaf*/ kInlineEntity, false
+ },
+ {
+ /*tag*/ eHTMLTag_del,
+ /*parent,leaf*/ kFlowEntity, false
+ },
+ {
+ /*tag*/ eHTMLTag_details,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_dfn,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_dir,
+ /*parent,leaf*/ kList, false
+ },
+ {
+ /*tag*/ eHTMLTag_div,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_dl,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_dt,
+ /*parent,leaf*/ kInlineEntity, false
+ },
+ {
+ /*tag*/ eHTMLTag_em,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_embed,
+ /*parent,leaf*/ kSpecial, true
+ },
+ {
+ /*tag*/ eHTMLTag_fieldset,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_figcaption,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_figure,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_font,
+ /*parent,leaf*/ kFontStyle, false
+ },
+ {
+ /*tag*/ eHTMLTag_footer,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_form,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_frame,
+ /*parent,leaf*/ kNone, true
+ },
+ {
+ /*tag*/ eHTMLTag_frameset,
+ /*parent,leaf*/ kHTMLContent, false
+ },
+ {
+ /*tag*/ eHTMLTag_h1,
+ /*parent,leaf*/ kHeading, false
+ },
+ {
+ /*tag*/ eHTMLTag_h2,
+ /*parent,leaf*/ kHeading, false
+ },
+ {
+ /*tag*/ eHTMLTag_h3,
+ /*parent,leaf*/ kHeading, false
+ },
+ {
+ /*tag*/ eHTMLTag_h4,
+ /*parent,leaf*/ kHeading, false
+ },
+ {
+ /*tag*/ eHTMLTag_h5,
+ /*parent,leaf*/ kHeading, false
+ },
+ {
+ /*tag*/ eHTMLTag_h6,
+ /*parent,leaf*/ kHeading, false
+ },
+ {
+ /*tag*/ eHTMLTag_head,
+ /*parent,leaf*/ kHTMLContent, false
+ },
+ {
+ /*tag*/ eHTMLTag_header,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_hgroup,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_hr,
+ /*parent,leaf*/ kBlock, true
+ },
+ {
+ /*tag*/ eHTMLTag_html,
+ /*parent,leaf*/ kNone, false
+ },
+ {
+ /*tag*/ eHTMLTag_i,
+ /*parent,leaf*/ kFontStyle, false
+ },
+ {
+ /*tag*/ eHTMLTag_iframe,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_image,
+ /*parent,leaf*/ kSpecial, true
+ },
+ {
+ /*tag*/ eHTMLTag_img,
+ /*parent,leaf*/ kSpecial, true
+ },
+ {
+ /*tag*/ eHTMLTag_input,
+ /*parent,leaf*/ kFormControl, true
+ },
+ {
+ /*tag*/ eHTMLTag_ins,
+ /*parent,leaf*/ kFlowEntity, false
+ },
+ {
+ /*tag*/ eHTMLTag_kbd,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_keygen,
+ /*parent,leaf*/ kFlowEntity, true
+ },
+ {
+ /*tag*/ eHTMLTag_label,
+ /*parent,leaf*/ kFormControl, false
+ },
+ {
+ /*tag*/ eHTMLTag_legend,
+ /*parent,leaf*/ kNone, false
+ },
+ {
+ /*tag*/ eHTMLTag_li,
+ /*parent,leaf*/ kBlockEntity, false
+ },
+ {
+ /*tag*/ eHTMLTag_link,
+ /*parent,leaf*/ kAllTags - kHeadContent, true
+ },
+ {
+ /*tag*/ eHTMLTag_listing,
+ /*parent,leaf*/ kPreformatted, false
+ },
+ {
+ /*tag*/ eHTMLTag_main,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_map,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_mark,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_marquee,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_menu,
+ /*parent,leaf*/ kList, false
+ },
+ {
+ /*tag*/ eHTMLTag_menuitem,
+ /*parent,leaf*/ kFlowEntity, false
+ },
+ {
+ /*tag*/ eHTMLTag_meta,
+ /*parent,leaf*/ kHeadContent, true
+ },
+ {
+ /*tag*/ eHTMLTag_meter,
+ /*parent,leaf*/ kFormControl, false
+ },
+ {
+ /*tag*/ eHTMLTag_multicol,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_nav,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_nobr,
+ /*parent,leaf*/ kExtensions, false
+ },
+ {
+ /*tag*/ eHTMLTag_noembed,
+ /*parent,leaf*/ kFlowEntity, false
+ },
+ {
+ /*tag*/ eHTMLTag_noframes,
+ /*parent,leaf*/ kFlowEntity, false
+ },
+ {
+ /*tag*/ eHTMLTag_noscript,
+ /*parent,leaf*/ kFlowEntity|kHeadMisc, false
+ },
+ {
+ /*tag*/ eHTMLTag_object,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_ol,
+ /*parent,leaf*/ kList, false
+ },
+ {
+ /*tag*/ eHTMLTag_optgroup,
+ /*parent,leaf*/ kNone, false
+ },
+ {
+ /*tag*/ eHTMLTag_option,
+ /*parent,leaf*/ kNone, false
+ },
+ {
+ /*tag*/ eHTMLTag_output,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_p,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_param,
+ /*parent,leaf*/ kSpecial, true
+ },
+ {
+ /*tag*/ eHTMLTag_picture,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_plaintext,
+ /*parent,leaf*/ kExtensions, false
+ },
+ {
+ /*tag*/ eHTMLTag_pre,
+ /*parent,leaf*/ kBlock|kPreformatted, false
+ },
+ {
+ /*tag*/ eHTMLTag_progress,
+ /*parent,leaf*/ kFormControl, false
+ },
+ {
+ /*tag*/ eHTMLTag_q,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_rb,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_rp,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_rt,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_rtc,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_ruby,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_s,
+ /*parent,leaf*/ kFontStyle, false
+ },
+ {
+ /*tag*/ eHTMLTag_samp,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_script,
+ /*parent,leaf*/ (kSpecial|kHeadContent), false
+ },
+ {
+ /*tag*/ eHTMLTag_section,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_select,
+ /*parent,leaf*/ kFormControl, false
+ },
+ {
+ /*tag*/ eHTMLTag_shadow,
+ /*parent,leaf*/ kFlowEntity, false
+ },
+ {
+ /*tag*/ eHTMLTag_small,
+ /*parent,leaf*/ kFontStyle, false
+ },
+ {
+ /*tag*/ eHTMLTag_source,
+ /*parent,leaf*/ kSpecial, true
+ },
+ {
+ /*tag*/ eHTMLTag_span,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_strike,
+ /*parent,leaf*/ kFontStyle, false
+ },
+ {
+ /*tag*/ eHTMLTag_strong,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_style,
+ /*parent,leaf*/ kAllTags - kHeadContent, false
+ },
+ {
+ /*tag*/ eHTMLTag_sub,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_summary,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_sup,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_table,
+ /*parent,leaf*/ kBlock, false
+ },
+ {
+ /*tag*/ eHTMLTag_tbody,
+ /*parent,leaf*/ kNone, false
+ },
+ {
+ /*tag*/ eHTMLTag_td,
+ /*parent,leaf*/ kNone, false
+ },
+ {
+ /*tag*/ eHTMLTag_textarea,
+ /*parent,leaf*/ kFormControl, false
+ },
+ {
+ /*tag*/ eHTMLTag_tfoot,
+ /*parent,leaf*/ kNone, false
+ },
+ {
+ /*tag*/ eHTMLTag_th,
+ /*parent,leaf*/ kNone, false
+ },
+ {
+ /*tag*/ eHTMLTag_thead,
+ /*parent,leaf*/ kNone, false
+ },
+ {
+ /*tag*/ eHTMLTag_template,
+ /*parent,leaf*/ kNone, false
+ },
+ {
+ /*tag*/ eHTMLTag_time,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_title,
+ /*parent,leaf*/ kHeadContent, false
+ },
+ {
+ /*tag*/ eHTMLTag_tr,
+ /*parent,leaf*/ kNone, false
+ },
+ {
+ /*tag*/ eHTMLTag_track,
+ /*parent,leaf*/ kSpecial, true
+ },
+ {
+ /*tag*/ eHTMLTag_tt,
+ /*parent,leaf*/ kFontStyle, false
+ },
+ {
+ /*tag*/ eHTMLTag_u,
+ /*parent,leaf*/ kFontStyle, false
+ },
+ {
+ /*tag*/ eHTMLTag_ul,
+ /*parent,leaf*/ kList, false
+ },
+ {
+ /*tag*/ eHTMLTag_var,
+ /*parent,leaf*/ kPhrase, false
+ },
+ {
+ /*tag*/ eHTMLTag_video,
+ /*parent,leaf*/ kSpecial, false
+ },
+ {
+ /*tag*/ eHTMLTag_wbr,
+ /*parent,leaf*/ kExtensions, true
+ },
+ {
+ /*tag*/ eHTMLTag_xmp,
+ /*parent,leaf*/ kInlineEntity|kPreformatted, false
+ },
+ {
+ /*tag*/ eHTMLTag_text,
+ /*parent,leaf*/ kFlowEntity, true
+ },
+ {
+ /*tag*/ eHTMLTag_whitespace,
+ /*parent,leaf*/ kFlowEntity|kHeadMisc, true
+ },
+ {
+ /*tag*/ eHTMLTag_newline,
+ /*parent,leaf*/ kFlowEntity|kHeadMisc, true
+ },
+ {
+ /*tag*/ eHTMLTag_comment,
+ /*parent,leaf*/ kFlowEntity|kHeadMisc, false
+ },
+ {
+ /*tag*/ eHTMLTag_entity,
+ /*parent,leaf*/ kFlowEntity, false
+ },
+ {
+ /*tag*/ eHTMLTag_doctypeDecl,
+ /*parent,leaf*/ kFlowEntity, false
+ },
+ {
+ /*tag*/ eHTMLTag_markupDecl,
+ /*parent,leaf*/ kFlowEntity, false
+ },
+ {
+ /*tag*/ eHTMLTag_instruction,
+ /*parent,leaf*/ kFlowEntity, false
+ },
+ {
+ /*tag*/ eHTMLTag_userdefined,
+ /*parent,leaf*/ (kFlowEntity|kHeadMisc), false
+ },
+};
+
+/*********************************************************************************************/
+
+bool nsHTMLElement::IsContainer(eHTMLTags aChild)
+{
+ return !gHTMLElements[aChild].mLeaf;
+}
+
+bool nsHTMLElement::IsMemberOf(int32_t aSet) const
+{
+ return TestBits(aSet,mParentBits);
+}
+
+#ifdef DEBUG
+void CheckElementTable()
+{
+ for (eHTMLTags t = eHTMLTag_unknown; t <= eHTMLTag_userdefined; t = eHTMLTags(t + 1)) {
+ NS_ASSERTION(gHTMLElements[t].mTagID == t, "gHTMLElements entries does match tag list.");
+ }
+}
+#endif
diff --git a/parser/htmlparser/nsElementTable.h b/parser/htmlparser/nsElementTable.h
new file mode 100644
index 000000000..a4b78c09e
--- /dev/null
+++ b/parser/htmlparser/nsElementTable.h
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+/**
+ * MODULE NOTES:
+ * @update gess 4/1/98
+ *
+ */
+
+
+
+#ifndef _NSELEMENTABLE
+#define _NSELEMENTABLE
+
+#include "nsHTMLTags.h"
+#include "nsIDTD.h"
+
+//*********************************************************************************************
+// The following ints define the standard groups of HTML elements...
+//*********************************************************************************************
+
+static const int kNone= 0x0;
+
+static const int kHTMLContent = 0x0001; // HEAD, (FRAMESET | BODY)
+static const int kHeadContent = 0x0002; // Elements that *must* be in the head.
+static const int kHeadMisc = 0x0004; // Elements that *can* be in the head.
+
+static const int kSpecial = 0x0008; // A, IMG, APPLET, OBJECT, FONT, BASEFONT, BR, SCRIPT,
+ // MAP, Q, SUB, SUP, SPAN, BDO, IFRAME
+
+static const int kFormControl = 0x0010; // INPUT SELECT TEXTAREA LABEL BUTTON
+static const int kPreformatted = 0x0020; // PRE
+static const int kPreExclusion = 0x0040; // IMG, OBJECT, APPLET, BIG, SMALL, SUB, SUP, FONT, BASEFONT
+static const int kFontStyle = 0x0080; // TT, I, B, U, S, STRIKE, BIG, SMALL
+static const int kPhrase = 0x0100; // EM, STRONG, DFN, CODE, SAMP, KBD, VAR, CITE, ABBR, ACRONYM
+static const int kHeading = 0x0200; // H1..H6
+static const int kBlockMisc = 0x0400; // OBJECT, SCRIPT
+static const int kBlock = 0x0800; // ADDRESS, BLOCKQUOTE, CENTER, DIV, DL, FIELDSET, FORM,
+ // ISINDEX, HR, NOSCRIPT, NOFRAMES, P, TABLE
+static const int kList = 0x1000; // UL, OL, DIR, MENU
+static const int kPCDATA = 0x2000; // plain text and entities...
+static const int kSelf = 0x4000; // whatever THIS tag is...
+static const int kExtensions = 0x8000; // BGSOUND, WBR, NOBR
+static const int kTable = 0x10000;// TR,TD,THEAD,TBODY,TFOOT,CAPTION,TH
+static const int kDLChild = 0x20000;// DL, DT
+static const int kCDATA = 0x40000;// just plain text...
+
+static const int kInlineEntity = (kPCDATA|kFontStyle|kPhrase|kSpecial|kFormControl|kExtensions); // #PCDATA, %fontstyle, %phrase, %special, %formctrl
+static const int kBlockEntity = (kHeading|kList|kPreformatted|kBlock); // %heading, %list, %preformatted, %block
+static const int kFlowEntity = (kBlockEntity|kInlineEntity); // %blockentity, %inlineentity
+static const int kAllTags = 0xffffff;
+
+
+//*********************************************************************************************
+// The following ints define the standard groups of HTML elements...
+//*********************************************************************************************
+
+#ifdef DEBUG
+extern void CheckElementTable();
+#endif
+
+
+/**
+ * We're asking the question: is aTest a member of bitset.
+ *
+ * @param
+ * @return TRUE or FALSE
+ */
+inline bool TestBits(int aBitset,int aTest) {
+ if(aTest) {
+ int32_t result=(aBitset & aTest);
+ return bool(result==aTest);
+ }
+ return false;
+}
+
+struct nsHTMLElement {
+ bool IsMemberOf(int32_t aType) const;
+
+ eHTMLTags mTagID;
+ int mParentBits; //defines groups that can contain this element
+ bool mLeaf;
+
+ static bool IsContainer(eHTMLTags aTag);
+};
+
+extern const nsHTMLElement gHTMLElements[];
+
+#endif
diff --git a/parser/htmlparser/nsExpatDriver.cpp b/parser/htmlparser/nsExpatDriver.cpp
new file mode 100644
index 000000000..8882ec593
--- /dev/null
+++ b/parser/htmlparser/nsExpatDriver.cpp
@@ -0,0 +1,1398 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsExpatDriver.h"
+#include "nsCOMPtr.h"
+#include "nsParserCIID.h"
+#include "CParserContext.h"
+#include "nsIExpatSink.h"
+#include "nsIExtendedExpatSink.h"
+#include "nsIContentSink.h"
+#include "nsParserMsgUtils.h"
+#include "nsIURL.h"
+#include "nsIUnicharInputStream.h"
+#include "nsIProtocolHandler.h"
+#include "nsNetUtil.h"
+#include "prprf.h"
+#include "prmem.h"
+#include "nsTextFormatter.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsCRT.h"
+#include "nsIConsoleService.h"
+#include "nsIScriptError.h"
+#include "nsIContentPolicy.h"
+#include "nsContentPolicyUtils.h"
+#include "nsError.h"
+#include "nsXPCOMCIDInternal.h"
+#include "nsUnicharInputStream.h"
+#include "nsContentUtils.h"
+#include "nsNullPrincipal.h"
+
+#include "mozilla/Logging.h"
+
+using mozilla::fallible;
+using mozilla::LogLevel;
+
+#define kExpatSeparatorChar 0xFFFF
+
+static const char16_t kUTF16[] = { 'U', 'T', 'F', '-', '1', '6', '\0' };
+
+static mozilla::LazyLogModule gExpatDriverLog("expatdriver");
+
+/***************************** EXPAT CALL BACKS ******************************/
+// The callback handlers that get called from the expat parser.
+
+static void
+Driver_HandleXMLDeclaration(void *aUserData,
+ const XML_Char *aVersion,
+ const XML_Char *aEncoding,
+ int aStandalone)
+{
+ NS_ASSERTION(aUserData, "expat driver should exist");
+ if (aUserData) {
+ nsExpatDriver* driver = static_cast<nsExpatDriver*>(aUserData);
+ driver->HandleXMLDeclaration(aVersion, aEncoding, aStandalone);
+ }
+}
+
+static void
+Driver_HandleStartElement(void *aUserData,
+ const XML_Char *aName,
+ const XML_Char **aAtts)
+{
+ NS_ASSERTION(aUserData, "expat driver should exist");
+ if (aUserData) {
+ static_cast<nsExpatDriver*>(aUserData)->HandleStartElement(aName,
+ aAtts);
+ }
+}
+
+static void
+Driver_HandleEndElement(void *aUserData,
+ const XML_Char *aName)
+{
+ NS_ASSERTION(aUserData, "expat driver should exist");
+ if (aUserData) {
+ static_cast<nsExpatDriver*>(aUserData)->HandleEndElement(aName);
+ }
+}
+
+static void
+Driver_HandleCharacterData(void *aUserData,
+ const XML_Char *aData,
+ int aLength)
+{
+ NS_ASSERTION(aUserData, "expat driver should exist");
+ if (aUserData) {
+ nsExpatDriver* driver = static_cast<nsExpatDriver*>(aUserData);
+ driver->HandleCharacterData(aData, uint32_t(aLength));
+ }
+}
+
+static void
+Driver_HandleComment(void *aUserData,
+ const XML_Char *aName)
+{
+ NS_ASSERTION(aUserData, "expat driver should exist");
+ if(aUserData) {
+ static_cast<nsExpatDriver*>(aUserData)->HandleComment(aName);
+ }
+}
+
+static void
+Driver_HandleProcessingInstruction(void *aUserData,
+ const XML_Char *aTarget,
+ const XML_Char *aData)
+{
+ NS_ASSERTION(aUserData, "expat driver should exist");
+ if (aUserData) {
+ nsExpatDriver* driver = static_cast<nsExpatDriver*>(aUserData);
+ driver->HandleProcessingInstruction(aTarget, aData);
+ }
+}
+
+static void
+Driver_HandleDefault(void *aUserData,
+ const XML_Char *aData,
+ int aLength)
+{
+ NS_ASSERTION(aUserData, "expat driver should exist");
+ if (aUserData) {
+ nsExpatDriver* driver = static_cast<nsExpatDriver*>(aUserData);
+ driver->HandleDefault(aData, uint32_t(aLength));
+ }
+}
+
+static void
+Driver_HandleStartCdataSection(void *aUserData)
+{
+ NS_ASSERTION(aUserData, "expat driver should exist");
+ if (aUserData) {
+ static_cast<nsExpatDriver*>(aUserData)->HandleStartCdataSection();
+ }
+}
+
+static void
+Driver_HandleEndCdataSection(void *aUserData)
+{
+ NS_ASSERTION(aUserData, "expat driver should exist");
+ if (aUserData) {
+ static_cast<nsExpatDriver*>(aUserData)->HandleEndCdataSection();
+ }
+}
+
+static void
+Driver_HandleStartDoctypeDecl(void *aUserData,
+ const XML_Char *aDoctypeName,
+ const XML_Char *aSysid,
+ const XML_Char *aPubid,
+ int aHasInternalSubset)
+{
+ NS_ASSERTION(aUserData, "expat driver should exist");
+ if (aUserData) {
+ static_cast<nsExpatDriver*>(aUserData)->
+ HandleStartDoctypeDecl(aDoctypeName, aSysid, aPubid, !!aHasInternalSubset);
+ }
+}
+
+static void
+Driver_HandleEndDoctypeDecl(void *aUserData)
+{
+ NS_ASSERTION(aUserData, "expat driver should exist");
+ if (aUserData) {
+ static_cast<nsExpatDriver*>(aUserData)->HandleEndDoctypeDecl();
+ }
+}
+
+static int
+Driver_HandleExternalEntityRef(void *aExternalEntityRefHandler,
+ const XML_Char *aOpenEntityNames,
+ const XML_Char *aBase,
+ const XML_Char *aSystemId,
+ const XML_Char *aPublicId)
+{
+ NS_ASSERTION(aExternalEntityRefHandler, "expat driver should exist");
+ if (!aExternalEntityRefHandler) {
+ return 1;
+ }
+
+ nsExpatDriver* driver = static_cast<nsExpatDriver*>
+ (aExternalEntityRefHandler);
+
+ return driver->HandleExternalEntityRef(aOpenEntityNames, aBase, aSystemId,
+ aPublicId);
+}
+
+static void
+Driver_HandleStartNamespaceDecl(void *aUserData,
+ const XML_Char *aPrefix,
+ const XML_Char *aUri)
+{
+ NS_ASSERTION(aUserData, "expat driver should exist");
+ if (aUserData) {
+ static_cast<nsExpatDriver*>(aUserData)->
+ HandleStartNamespaceDecl(aPrefix, aUri);
+ }
+}
+
+static void
+Driver_HandleEndNamespaceDecl(void *aUserData,
+ const XML_Char *aPrefix)
+{
+ NS_ASSERTION(aUserData, "expat driver should exist");
+ if (aUserData) {
+ static_cast<nsExpatDriver*>(aUserData)->
+ HandleEndNamespaceDecl(aPrefix);
+ }
+}
+
+static void
+Driver_HandleNotationDecl(void *aUserData,
+ const XML_Char *aNotationName,
+ const XML_Char *aBase,
+ const XML_Char *aSysid,
+ const XML_Char *aPubid)
+{
+ NS_ASSERTION(aUserData, "expat driver should exist");
+ if (aUserData) {
+ static_cast<nsExpatDriver*>(aUserData)->
+ HandleNotationDecl(aNotationName, aBase, aSysid, aPubid);
+ }
+}
+
+static void
+Driver_HandleUnparsedEntityDecl(void *aUserData,
+ const XML_Char *aEntityName,
+ const XML_Char *aBase,
+ const XML_Char *aSysid,
+ const XML_Char *aPubid,
+ const XML_Char *aNotationName)
+{
+ NS_ASSERTION(aUserData, "expat driver should exist");
+ if (aUserData) {
+ static_cast<nsExpatDriver*>(aUserData)->
+ HandleUnparsedEntityDecl(aEntityName, aBase, aSysid, aPubid,
+ aNotationName);
+ }
+}
+
+
+/***************************** END CALL BACKS ********************************/
+
+/***************************** CATALOG UTILS *********************************/
+
+// Initially added for bug 113400 to switch from the remote "XHTML 1.0 plus
+// MathML 2.0" DTD to the the lightweight customized version that Mozilla uses.
+// Since Mozilla is not validating, no need to fetch a *huge* file at each
+// click.
+// XXX The cleanest solution here would be to fix Bug 98413: Implement XML
+// Catalogs.
+struct nsCatalogData {
+ const char* mPublicID;
+ const char* mLocalDTD;
+ const char* mAgentSheet;
+};
+
+// The order of this table is guestimated to be in the optimum order
+static const nsCatalogData kCatalogTable[] = {
+ { "-//W3C//DTD XHTML 1.0 Transitional//EN", "htmlmathml-f.ent", nullptr },
+ { "-//W3C//DTD XHTML 1.1//EN", "htmlmathml-f.ent", nullptr },
+ { "-//W3C//DTD XHTML 1.0 Strict//EN", "htmlmathml-f.ent", nullptr },
+ { "-//W3C//DTD XHTML 1.0 Frameset//EN", "htmlmathml-f.ent", nullptr },
+ { "-//W3C//DTD XHTML Basic 1.0//EN", "htmlmathml-f.ent", nullptr },
+ { "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN", "htmlmathml-f.ent", nullptr },
+ { "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN", "htmlmathml-f.ent", nullptr },
+ { "-//W3C//DTD MathML 2.0//EN", "htmlmathml-f.ent", nullptr },
+ { "-//WAPFORUM//DTD XHTML Mobile 1.0//EN", "htmlmathml-f.ent", nullptr },
+ { nullptr, nullptr, nullptr }
+};
+
+static const nsCatalogData*
+LookupCatalogData(const char16_t* aPublicID)
+{
+ nsDependentString publicID(aPublicID);
+
+ // linear search for now since the number of entries is going to
+ // be negligible, and the fix for bug 98413 would get rid of this
+ // code anyway
+ const nsCatalogData* data = kCatalogTable;
+ while (data->mPublicID) {
+ if (publicID.EqualsASCII(data->mPublicID)) {
+ return data;
+ }
+ ++data;
+ }
+
+ return nullptr;
+}
+
+// This function provides a resource URI to a local DTD
+// in resource://gre/res/dtd/ which may or may not exist.
+// If aCatalogData is provided, it is used to remap the
+// DTD instead of taking the filename from the URI.
+static void
+GetLocalDTDURI(const nsCatalogData* aCatalogData, nsIURI* aDTD,
+ nsIURI** aResult)
+{
+ NS_ASSERTION(aDTD, "Null parameter.");
+
+ nsAutoCString fileName;
+ if (aCatalogData) {
+ // remap the DTD to a known local DTD
+ fileName.Assign(aCatalogData->mLocalDTD);
+ }
+
+ if (fileName.IsEmpty()) {
+ // Try to see if the user has installed the DTD file -- we extract the
+ // filename.ext of the DTD here. Hence, for any DTD for which we have
+ // no predefined mapping, users just have to copy the DTD file to our
+ // special DTD directory and it will be picked.
+ nsCOMPtr<nsIURL> dtdURL = do_QueryInterface(aDTD);
+ if (!dtdURL) {
+ return;
+ }
+
+ dtdURL->GetFileName(fileName);
+ if (fileName.IsEmpty()) {
+ return;
+ }
+ }
+
+ nsAutoCString respath("resource://gre/res/dtd/");
+ respath += fileName;
+ NS_NewURI(aResult, respath);
+}
+
+/***************************** END CATALOG UTILS *****************************/
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsExpatDriver)
+ NS_INTERFACE_MAP_ENTRY(nsITokenizer)
+ NS_INTERFACE_MAP_ENTRY(nsIDTD)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDTD)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsExpatDriver)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsExpatDriver)
+
+NS_IMPL_CYCLE_COLLECTION(nsExpatDriver, mSink, mExtendedSink)
+
+nsExpatDriver::nsExpatDriver()
+ : mExpatParser(nullptr),
+ mInCData(false),
+ mInInternalSubset(false),
+ mInExternalDTD(false),
+ mMadeFinalCallToExpat(false),
+ mIsFinalChunk(false),
+ mInternalState(NS_OK),
+ mExpatBuffered(0),
+ mCatalogData(nullptr),
+ mInnerWindowID(0)
+{
+}
+
+nsExpatDriver::~nsExpatDriver()
+{
+ if (mExpatParser) {
+ XML_ParserFree(mExpatParser);
+ }
+}
+
+nsresult
+nsExpatDriver::HandleStartElement(const char16_t *aValue,
+ const char16_t **aAtts)
+{
+ NS_ASSERTION(mSink, "content sink not found!");
+
+ // Calculate the total number of elements in aAtts.
+ // XML_GetSpecifiedAttributeCount will only give us the number of specified
+ // attrs (twice that number, actually), so we have to check for default attrs
+ // ourselves.
+ uint32_t attrArrayLength;
+ for (attrArrayLength = XML_GetSpecifiedAttributeCount(mExpatParser);
+ aAtts[attrArrayLength];
+ attrArrayLength += 2) {
+ // Just looping till we find out what the length is
+ }
+
+ if (mSink) {
+ nsresult rv = mSink->
+ HandleStartElement(aValue, aAtts, attrArrayLength,
+ XML_GetCurrentLineNumber(mExpatParser));
+ MaybeStopParser(rv);
+ }
+
+ return NS_OK;
+}
+
+nsresult
+nsExpatDriver::HandleEndElement(const char16_t *aValue)
+{
+ NS_ASSERTION(mSink, "content sink not found!");
+ NS_ASSERTION(mInternalState != NS_ERROR_HTMLPARSER_BLOCK,
+ "Shouldn't block from HandleStartElement.");
+
+ if (mSink && mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) {
+ nsresult rv = mSink->HandleEndElement(aValue);
+ MaybeStopParser(rv);
+ }
+
+ return NS_OK;
+}
+
+nsresult
+nsExpatDriver::HandleCharacterData(const char16_t *aValue,
+ const uint32_t aLength)
+{
+ NS_ASSERTION(mSink, "content sink not found!");
+
+ if (mInCData) {
+ if (!mCDataText.Append(aValue, aLength, fallible)) {
+ MaybeStopParser(NS_ERROR_OUT_OF_MEMORY);
+ }
+ }
+ else if (mSink) {
+ nsresult rv = mSink->HandleCharacterData(aValue, aLength);
+ MaybeStopParser(rv);
+ }
+
+ return NS_OK;
+}
+
+nsresult
+nsExpatDriver::HandleComment(const char16_t *aValue)
+{
+ NS_ASSERTION(mSink, "content sink not found!");
+
+ if (mInExternalDTD) {
+ // Ignore comments from external DTDs
+ return NS_OK;
+ }
+
+ if (mInInternalSubset) {
+ mInternalSubset.AppendLiteral("<!--");
+ mInternalSubset.Append(aValue);
+ mInternalSubset.AppendLiteral("-->");
+ }
+ else if (mSink) {
+ nsresult rv = mSink->HandleComment(aValue);
+ MaybeStopParser(rv);
+ }
+
+ return NS_OK;
+}
+
+nsresult
+nsExpatDriver::HandleProcessingInstruction(const char16_t *aTarget,
+ const char16_t *aData)
+{
+ NS_ASSERTION(mSink, "content sink not found!");
+
+ if (mInExternalDTD) {
+ // Ignore PIs in external DTDs for now. Eventually we want to
+ // pass them to the sink in a way that doesn't put them in the DOM
+ return NS_OK;
+ }
+
+ if (mInInternalSubset) {
+ mInternalSubset.AppendLiteral("<?");
+ mInternalSubset.Append(aTarget);
+ mInternalSubset.Append(' ');
+ mInternalSubset.Append(aData);
+ mInternalSubset.AppendLiteral("?>");
+ }
+ else if (mSink) {
+ nsresult rv = mSink->HandleProcessingInstruction(aTarget, aData);
+ MaybeStopParser(rv);
+ }
+
+ return NS_OK;
+}
+
+nsresult
+nsExpatDriver::HandleXMLDeclaration(const char16_t *aVersion,
+ const char16_t *aEncoding,
+ int32_t aStandalone)
+{
+ if (mSink) {
+ nsresult rv = mSink->HandleXMLDeclaration(aVersion, aEncoding, aStandalone);
+ MaybeStopParser(rv);
+ }
+
+ return NS_OK;
+}
+
+nsresult
+nsExpatDriver::HandleDefault(const char16_t *aValue,
+ const uint32_t aLength)
+{
+ NS_ASSERTION(mSink, "content sink not found!");
+
+ if (mInExternalDTD) {
+ // Ignore newlines in external DTDs
+ return NS_OK;
+ }
+
+ if (mInInternalSubset) {
+ mInternalSubset.Append(aValue, aLength);
+ }
+ else if (mSink) {
+ uint32_t i;
+ nsresult rv = mInternalState;
+ for (i = 0; i < aLength && NS_SUCCEEDED(rv); ++i) {
+ if (aValue[i] == '\n' || aValue[i] == '\r') {
+ rv = mSink->HandleCharacterData(&aValue[i], 1);
+ }
+ }
+ MaybeStopParser(rv);
+ }
+
+ return NS_OK;
+}
+
+nsresult
+nsExpatDriver::HandleStartCdataSection()
+{
+ mInCData = true;
+
+ return NS_OK;
+}
+
+nsresult
+nsExpatDriver::HandleEndCdataSection()
+{
+ NS_ASSERTION(mSink, "content sink not found!");
+
+ mInCData = false;
+ if (mSink) {
+ nsresult rv = mSink->HandleCDataSection(mCDataText.get(),
+ mCDataText.Length());
+ MaybeStopParser(rv);
+ }
+ mCDataText.Truncate();
+
+ return NS_OK;
+}
+
+nsresult
+nsExpatDriver::HandleStartNamespaceDecl(const char16_t* aPrefix,
+ const char16_t* aUri)
+{
+ if (mExtendedSink) {
+ nsresult rv = mExtendedSink->HandleStartNamespaceDecl(aPrefix, aUri);
+ MaybeStopParser(rv);
+ }
+ return NS_OK;
+}
+
+nsresult
+nsExpatDriver::HandleEndNamespaceDecl(const char16_t* aPrefix)
+{
+ if (mExtendedSink && mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) {
+ nsresult rv = mExtendedSink->HandleEndNamespaceDecl(aPrefix);
+ MaybeStopParser(rv);
+ }
+ return NS_OK;
+}
+
+nsresult
+nsExpatDriver::HandleNotationDecl(const char16_t* aNotationName,
+ const char16_t* aBase,
+ const char16_t* aSysid,
+ const char16_t* aPubid)
+{
+ if (mExtendedSink) {
+ nsresult rv = mExtendedSink->HandleNotationDecl(aNotationName, aSysid,
+ aPubid);
+ MaybeStopParser(rv);
+ }
+ return NS_OK;
+}
+
+nsresult
+nsExpatDriver::HandleUnparsedEntityDecl(const char16_t* aEntityName,
+ const char16_t* aBase,
+ const char16_t* aSysid,
+ const char16_t* aPubid,
+ const char16_t* aNotationName)
+{
+ if (mExtendedSink) {
+ nsresult rv = mExtendedSink->HandleUnparsedEntityDecl(aEntityName,
+ aSysid,
+ aPubid,
+ aNotationName);
+ MaybeStopParser(rv);
+ }
+ return NS_OK;
+}
+
+nsresult
+nsExpatDriver::HandleStartDoctypeDecl(const char16_t* aDoctypeName,
+ const char16_t* aSysid,
+ const char16_t* aPubid,
+ bool aHasInternalSubset)
+{
+ mDoctypeName = aDoctypeName;
+ mSystemID = aSysid;
+ mPublicID = aPubid;
+
+ if (mExtendedSink) {
+ nsresult rv = mExtendedSink->HandleStartDTD(aDoctypeName, aSysid, aPubid);
+ MaybeStopParser(rv);
+ }
+
+ if (aHasInternalSubset) {
+ // Consuming a huge internal subset translates to numerous
+ // allocations. In an effort to avoid too many allocations
+ // setting mInternalSubset's capacity to be 1K ( just a guesstimate! ).
+ mInInternalSubset = true;
+ mInternalSubset.SetCapacity(1024);
+ } else {
+ // Distinguish missing internal subset from an empty one
+ mInternalSubset.SetIsVoid(true);
+ }
+
+ return NS_OK;
+}
+
+nsresult
+nsExpatDriver::HandleEndDoctypeDecl()
+{
+ NS_ASSERTION(mSink, "content sink not found!");
+
+ mInInternalSubset = false;
+
+ if (mSink) {
+ // let the sink know any additional knowledge that we have about the
+ // document (currently, from bug 124570, we only expect to pass additional
+ // agent sheets needed to layout the XML vocabulary of the document)
+ nsCOMPtr<nsIURI> data;
+#if 0
+ if (mCatalogData && mCatalogData->mAgentSheet) {
+ NS_NewURI(getter_AddRefs(data), mCatalogData->mAgentSheet);
+ }
+#endif
+
+ // The unused support for "catalog style sheets" was removed. It doesn't
+ // look like we'll ever fix bug 98413 either.
+ MOZ_ASSERT(!mCatalogData || !mCatalogData->mAgentSheet,
+ "Need to add back support for catalog style sheets");
+
+ // Note: mInternalSubset already doesn't include the [] around it.
+ nsresult rv = mSink->HandleDoctypeDecl(mInternalSubset, mDoctypeName,
+ mSystemID, mPublicID, data);
+ MaybeStopParser(rv);
+ }
+
+ mInternalSubset.SetCapacity(0);
+
+ return NS_OK;
+}
+
+static nsresult
+ExternalDTDStreamReaderFunc(nsIUnicharInputStream* aIn,
+ void* aClosure,
+ const char16_t* aFromSegment,
+ uint32_t aToOffset,
+ uint32_t aCount,
+ uint32_t *aWriteCount)
+{
+ // Pass the buffer to expat for parsing.
+ if (XML_Parse((XML_Parser)aClosure, (const char *)aFromSegment,
+ aCount * sizeof(char16_t), 0) == XML_STATUS_OK) {
+ *aWriteCount = aCount;
+
+ return NS_OK;
+ }
+
+ *aWriteCount = 0;
+
+ return NS_ERROR_FAILURE;
+}
+
+int
+nsExpatDriver::HandleExternalEntityRef(const char16_t *openEntityNames,
+ const char16_t *base,
+ const char16_t *systemId,
+ const char16_t *publicId)
+{
+ if (mInInternalSubset && !mInExternalDTD && openEntityNames) {
+ mInternalSubset.Append(char16_t('%'));
+ mInternalSubset.Append(nsDependentString(openEntityNames));
+ mInternalSubset.Append(char16_t(';'));
+ }
+
+ // Load the external entity into a buffer.
+ nsCOMPtr<nsIInputStream> in;
+ nsAutoString absURL;
+ nsresult rv = OpenInputStreamFromExternalDTD(publicId, systemId, base,
+ getter_AddRefs(in), absURL);
+ if (NS_FAILED(rv)) {
+#ifdef DEBUG
+ nsCString message("Failed to open external DTD: publicId \"");
+ AppendUTF16toUTF8(publicId, message);
+ message += "\" systemId \"";
+ AppendUTF16toUTF8(systemId, message);
+ message += "\" base \"";
+ AppendUTF16toUTF8(base, message);
+ message += "\" URL \"";
+ AppendUTF16toUTF8(absURL, message);
+ message += "\"";
+ NS_WARNING(message.get());
+#endif
+ return 1;
+ }
+
+ nsCOMPtr<nsIUnicharInputStream> uniIn;
+ rv = NS_NewUnicharInputStream(in, getter_AddRefs(uniIn));
+ NS_ENSURE_SUCCESS(rv, 1);
+
+ int result = 1;
+ if (uniIn) {
+ XML_Parser entParser = XML_ExternalEntityParserCreate(mExpatParser, 0,
+ kUTF16);
+ if (entParser) {
+ XML_SetBase(entParser, absURL.get());
+
+ mInExternalDTD = true;
+
+ uint32_t totalRead;
+ do {
+ rv = uniIn->ReadSegments(ExternalDTDStreamReaderFunc, entParser,
+ uint32_t(-1), &totalRead);
+ } while (NS_SUCCEEDED(rv) && totalRead > 0);
+
+ result = XML_Parse(entParser, nullptr, 0, 1);
+
+ mInExternalDTD = false;
+
+ XML_ParserFree(entParser);
+ }
+ }
+
+ return result;
+}
+
+nsresult
+nsExpatDriver::OpenInputStreamFromExternalDTD(const char16_t* aFPIStr,
+ const char16_t* aURLStr,
+ const char16_t* aBaseURL,
+ nsIInputStream** aStream,
+ nsAString& aAbsURL)
+{
+ nsCOMPtr<nsIURI> baseURI;
+ nsresult rv = NS_NewURI(getter_AddRefs(baseURI),
+ NS_ConvertUTF16toUTF8(aBaseURL));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIURI> uri;
+ rv = NS_NewURI(getter_AddRefs(uri), NS_ConvertUTF16toUTF8(aURLStr), nullptr,
+ baseURI);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // make sure the URI is allowed to be loaded in sync
+ bool isUIResource = false;
+ rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_IS_UI_RESOURCE,
+ &isUIResource);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIURI> localURI;
+ if (!isUIResource) {
+ // Check to see if we can map the DTD to a known local DTD, or if a DTD
+ // file of the same name exists in the special DTD directory
+ if (aFPIStr) {
+ // see if the Formal Public Identifier (FPI) maps to a catalog entry
+ mCatalogData = LookupCatalogData(aFPIStr);
+ GetLocalDTDURI(mCatalogData, uri, getter_AddRefs(localURI));
+ }
+ if (!localURI) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+ }
+
+ nsCOMPtr<nsIChannel> channel;
+ if (localURI) {
+ localURI.swap(uri);
+ rv = NS_NewChannel(getter_AddRefs(channel),
+ uri,
+ nsContentUtils::GetSystemPrincipal(),
+ nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+ nsIContentPolicy::TYPE_DTD);
+ }
+ else {
+ NS_ASSERTION(mSink == nsCOMPtr<nsIExpatSink>(do_QueryInterface(mOriginalSink)),
+ "In nsExpatDriver::OpenInputStreamFromExternalDTD: "
+ "mOriginalSink not the same object as mSink?");
+ nsCOMPtr<nsIPrincipal> loadingPrincipal;
+ if (mOriginalSink) {
+ nsCOMPtr<nsIDocument> doc;
+ doc = do_QueryInterface(mOriginalSink->GetTarget());
+ if (doc) {
+ loadingPrincipal = doc->NodePrincipal();
+ }
+ }
+ if (!loadingPrincipal) {
+ loadingPrincipal = nsNullPrincipal::Create();
+ }
+ rv = NS_NewChannel(getter_AddRefs(channel),
+ uri,
+ loadingPrincipal,
+ nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS |
+ nsILoadInfo::SEC_ALLOW_CHROME,
+ nsIContentPolicy::TYPE_DTD);
+ }
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsAutoCString absURL;
+ rv = uri->GetSpec(absURL);
+ NS_ENSURE_SUCCESS(rv, rv);
+ CopyUTF8toUTF16(absURL, aAbsURL);
+
+ channel->SetContentType(NS_LITERAL_CSTRING("application/xml"));
+ return channel->Open2(aStream);
+}
+
+static nsresult
+CreateErrorText(const char16_t* aDescription,
+ const char16_t* aSourceURL,
+ const uint32_t aLineNumber,
+ const uint32_t aColNumber,
+ nsString& aErrorString)
+{
+ aErrorString.Truncate();
+
+ nsAutoString msg;
+ nsresult rv =
+ nsParserMsgUtils::GetLocalizedStringByName(XMLPARSER_PROPERTIES,
+ "XMLParsingError", msg);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // XML Parsing Error: %1$S\nLocation: %2$S\nLine Number %3$u, Column %4$u:
+ char16_t *message = nsTextFormatter::smprintf(msg.get(), aDescription,
+ aSourceURL, aLineNumber,
+ aColNumber);
+ if (!message) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ aErrorString.Assign(message);
+ nsTextFormatter::smprintf_free(message);
+
+ return NS_OK;
+}
+
+static nsresult
+AppendErrorPointer(const int32_t aColNumber,
+ const char16_t *aSourceLine,
+ nsString& aSourceString)
+{
+ aSourceString.Append(char16_t('\n'));
+
+ // Last character will be '^'.
+ int32_t last = aColNumber - 1;
+ int32_t i;
+ uint32_t minuses = 0;
+ for (i = 0; i < last; ++i) {
+ if (aSourceLine[i] == '\t') {
+ // Since this uses |white-space: pre;| a tab stop equals 8 spaces.
+ uint32_t add = 8 - (minuses % 8);
+ aSourceString.AppendASCII("--------", add);
+ minuses += add;
+ }
+ else {
+ aSourceString.Append(char16_t('-'));
+ ++minuses;
+ }
+ }
+ aSourceString.Append(char16_t('^'));
+
+ return NS_OK;
+}
+
+nsresult
+nsExpatDriver::HandleError()
+{
+ int32_t code = XML_GetErrorCode(mExpatParser);
+ NS_ASSERTION(code > XML_ERROR_NONE, "unexpected XML error code");
+
+ // Map Expat error code to an error string
+ // XXX Deal with error returns.
+ nsAutoString description;
+ nsParserMsgUtils::GetLocalizedStringByID(XMLPARSER_PROPERTIES, code,
+ description);
+
+ if (code == XML_ERROR_TAG_MISMATCH) {
+ /**
+ * Expat can send the following:
+ * localName
+ * namespaceURI<separator>localName
+ * namespaceURI<separator>localName<separator>prefix
+ *
+ * and we use 0xFFFF for the <separator>.
+ *
+ */
+ const char16_t *mismatch = MOZ_XML_GetMismatchedTag(mExpatParser);
+ const char16_t *uriEnd = nullptr;
+ const char16_t *nameEnd = nullptr;
+ const char16_t *pos;
+ for (pos = mismatch; *pos; ++pos) {
+ if (*pos == kExpatSeparatorChar) {
+ if (uriEnd) {
+ nameEnd = pos;
+ }
+ else {
+ uriEnd = pos;
+ }
+ }
+ }
+
+ nsAutoString tagName;
+ if (uriEnd && nameEnd) {
+ // We have a prefix.
+ tagName.Append(nameEnd + 1, pos - nameEnd - 1);
+ tagName.Append(char16_t(':'));
+ }
+ const char16_t *nameStart = uriEnd ? uriEnd + 1 : mismatch;
+ tagName.Append(nameStart, (nameEnd ? nameEnd : pos) - nameStart);
+
+ nsAutoString msg;
+ nsParserMsgUtils::GetLocalizedStringByName(XMLPARSER_PROPERTIES,
+ "Expected", msg);
+
+ // . Expected: </%S>.
+ char16_t *message = nsTextFormatter::smprintf(msg.get(), tagName.get());
+ if (!message) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ description.Append(message);
+
+ nsTextFormatter::smprintf_free(message);
+ }
+
+ // Adjust the column number so that it is one based rather than zero based.
+ uint32_t colNumber = XML_GetCurrentColumnNumber(mExpatParser) + 1;
+ uint32_t lineNumber = XML_GetCurrentLineNumber(mExpatParser);
+
+ nsAutoString errorText;
+ CreateErrorText(description.get(), XML_GetBase(mExpatParser), lineNumber,
+ colNumber, errorText);
+
+ NS_ASSERTION(mSink, "no sink?");
+
+ nsAutoString sourceText(mLastLine);
+ AppendErrorPointer(colNumber, mLastLine.get(), sourceText);
+
+ // Try to create and initialize the script error.
+ nsCOMPtr<nsIScriptError> serr(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
+ nsresult rv = NS_ERROR_FAILURE;
+ if (serr) {
+ rv = serr->InitWithWindowID(errorText,
+ mURISpec,
+ mLastLine,
+ lineNumber, colNumber,
+ nsIScriptError::errorFlag, "malformed-xml",
+ mInnerWindowID);
+ }
+
+ // If it didn't initialize, we can't do any logging.
+ bool shouldReportError = NS_SUCCEEDED(rv);
+
+ if (mSink && shouldReportError) {
+ rv = mSink->ReportError(errorText.get(),
+ sourceText.get(),
+ serr,
+ &shouldReportError);
+ if (NS_FAILED(rv)) {
+ shouldReportError = true;
+ }
+ }
+
+ if (mOriginalSink) {
+ nsCOMPtr<nsIDocument> doc = do_QueryInterface(mOriginalSink->GetTarget());
+ if (doc && doc->SuppressParserErrorConsoleMessages()) {
+ shouldReportError = false;
+ }
+ }
+
+ if (shouldReportError) {
+ nsCOMPtr<nsIConsoleService> cs
+ (do_GetService(NS_CONSOLESERVICE_CONTRACTID));
+ if (cs) {
+ cs->LogMessage(serr);
+ }
+ }
+
+ return NS_ERROR_HTMLPARSER_STOPPARSING;
+}
+
+void
+nsExpatDriver::ParseBuffer(const char16_t *aBuffer,
+ uint32_t aLength,
+ bool aIsFinal,
+ uint32_t *aConsumed)
+{
+ NS_ASSERTION((aBuffer && aLength != 0) || (!aBuffer && aLength == 0), "?");
+ NS_ASSERTION(mInternalState != NS_OK || aIsFinal || aBuffer,
+ "Useless call, we won't call Expat");
+ NS_PRECONDITION(!BlockedOrInterrupted() || !aBuffer,
+ "Non-null buffer when resuming");
+ NS_PRECONDITION(XML_GetCurrentByteIndex(mExpatParser) % sizeof(char16_t) == 0,
+ "Consumed part of a char16_t?");
+
+ if (mExpatParser && (mInternalState == NS_OK || BlockedOrInterrupted())) {
+ int32_t parserBytesBefore = XML_GetCurrentByteIndex(mExpatParser);
+ NS_ASSERTION(parserBytesBefore >= 0, "Unexpected value");
+
+ XML_Status status;
+ if (BlockedOrInterrupted()) {
+ mInternalState = NS_OK; // Resume in case we're blocked.
+ status = XML_ResumeParser(mExpatParser);
+ }
+ else {
+ status = XML_Parse(mExpatParser,
+ reinterpret_cast<const char*>(aBuffer),
+ aLength * sizeof(char16_t), aIsFinal);
+ }
+
+ int32_t parserBytesConsumed = XML_GetCurrentByteIndex(mExpatParser);
+
+ NS_ASSERTION(parserBytesConsumed >= 0, "Unexpected value");
+ NS_ASSERTION(parserBytesConsumed >= parserBytesBefore,
+ "How'd this happen?");
+ NS_ASSERTION(parserBytesConsumed % sizeof(char16_t) == 0,
+ "Consumed part of a char16_t?");
+
+ // Consumed something.
+ *aConsumed = (parserBytesConsumed - parserBytesBefore) / sizeof(char16_t);
+ NS_ASSERTION(*aConsumed <= aLength + mExpatBuffered,
+ "Too many bytes consumed?");
+
+ NS_ASSERTION(status != XML_STATUS_SUSPENDED || BlockedOrInterrupted(),
+ "Inconsistent expat suspension state.");
+
+ if (status == XML_STATUS_ERROR) {
+ mInternalState = NS_ERROR_HTMLPARSER_STOPPARSING;
+ }
+ }
+ else {
+ *aConsumed = 0;
+ }
+}
+
+NS_IMETHODIMP
+nsExpatDriver::ConsumeToken(nsScanner& aScanner, bool& aFlushTokens)
+{
+ // We keep the scanner pointing to the position where Expat will start
+ // parsing.
+ nsScannerIterator currentExpatPosition;
+ aScanner.CurrentPosition(currentExpatPosition);
+
+ // This is the start of the first buffer that we need to pass to Expat.
+ nsScannerIterator start = currentExpatPosition;
+ start.advance(mExpatBuffered);
+
+ // This is the end of the last buffer (at this point, more data could come in
+ // later).
+ nsScannerIterator end;
+ aScanner.EndReading(end);
+
+ MOZ_LOG(gExpatDriverLog, LogLevel::Debug,
+ ("Remaining in expat's buffer: %i, remaining in scanner: %i.",
+ mExpatBuffered, Distance(start, end)));
+
+ // We want to call Expat if we have more buffers, or if we know there won't
+ // be more buffers (and so we want to flush the remaining data), or if we're
+ // currently blocked and there's data in Expat's buffer.
+ while (start != end || (mIsFinalChunk && !mMadeFinalCallToExpat) ||
+ (BlockedOrInterrupted() && mExpatBuffered > 0)) {
+ bool noMoreBuffers = start == end && mIsFinalChunk;
+ bool blocked = BlockedOrInterrupted();
+
+ const char16_t *buffer;
+ uint32_t length;
+ if (blocked || noMoreBuffers) {
+ // If we're blocked we just resume Expat so we don't need a buffer, if
+ // there aren't any more buffers we pass a null buffer to Expat.
+ buffer = nullptr;
+ length = 0;
+
+ if (blocked) {
+ MOZ_LOG(gExpatDriverLog, LogLevel::Debug,
+ ("Resuming Expat, will parse data remaining in Expat's "
+ "buffer.\nContent of Expat's buffer:\n-----\n%s\n-----\n",
+ NS_ConvertUTF16toUTF8(currentExpatPosition.get(),
+ mExpatBuffered).get()));
+ }
+ else {
+ NS_ASSERTION(mExpatBuffered == Distance(currentExpatPosition, end),
+ "Didn't pass all the data to Expat?");
+ MOZ_LOG(gExpatDriverLog, LogLevel::Debug,
+ ("Last call to Expat, will parse data remaining in Expat's "
+ "buffer.\nContent of Expat's buffer:\n-----\n%s\n-----\n",
+ NS_ConvertUTF16toUTF8(currentExpatPosition.get(),
+ mExpatBuffered).get()));
+ }
+ }
+ else {
+ buffer = start.get();
+ length = uint32_t(start.size_forward());
+
+ MOZ_LOG(gExpatDriverLog, LogLevel::Debug,
+ ("Calling Expat, will parse data remaining in Expat's buffer and "
+ "new data.\nContent of Expat's buffer:\n-----\n%s\n-----\nNew "
+ "data:\n-----\n%s\n-----\n",
+ NS_ConvertUTF16toUTF8(currentExpatPosition.get(),
+ mExpatBuffered).get(),
+ NS_ConvertUTF16toUTF8(start.get(), length).get()));
+ }
+
+ uint32_t consumed;
+ ParseBuffer(buffer, length, noMoreBuffers, &consumed);
+ if (consumed > 0) {
+ nsScannerIterator oldExpatPosition = currentExpatPosition;
+ currentExpatPosition.advance(consumed);
+
+ // We consumed some data, we want to store the last line of data that
+ // was consumed in case we run into an error (to show the line in which
+ // the error occurred).
+
+ // The length of the last line that Expat has parsed.
+ XML_Size lastLineLength = XML_GetCurrentColumnNumber(mExpatParser);
+
+ if (lastLineLength <= consumed) {
+ // The length of the last line was less than what expat consumed, so
+ // there was at least one line break in the consumed data. Store the
+ // last line until the point where we stopped parsing.
+ nsScannerIterator startLastLine = currentExpatPosition;
+ startLastLine.advance(-((ptrdiff_t)lastLineLength));
+ if (!CopyUnicodeTo(startLastLine, currentExpatPosition, mLastLine)) {
+ return (mInternalState = NS_ERROR_OUT_OF_MEMORY);
+ }
+ }
+ else {
+ // There was no line break in the consumed data, append the consumed
+ // data.
+ if (!AppendUnicodeTo(oldExpatPosition,
+ currentExpatPosition,
+ mLastLine)) {
+ return (mInternalState = NS_ERROR_OUT_OF_MEMORY);
+ }
+ }
+ }
+
+ mExpatBuffered += length - consumed;
+
+ if (BlockedOrInterrupted()) {
+ MOZ_LOG(gExpatDriverLog, LogLevel::Debug,
+ ("Blocked or interrupted parser (probably for loading linked "
+ "stylesheets or scripts)."));
+
+ aScanner.SetPosition(currentExpatPosition, true);
+ aScanner.Mark();
+
+ return mInternalState;
+ }
+
+ if (noMoreBuffers && mExpatBuffered == 0) {
+ mMadeFinalCallToExpat = true;
+ }
+
+ if (NS_FAILED(mInternalState)) {
+ if (XML_GetErrorCode(mExpatParser) != XML_ERROR_NONE) {
+ NS_ASSERTION(mInternalState == NS_ERROR_HTMLPARSER_STOPPARSING,
+ "Unexpected error");
+
+ // Look for the next newline after the last one we consumed
+ nsScannerIterator lastLine = currentExpatPosition;
+ while (lastLine != end) {
+ length = uint32_t(lastLine.size_forward());
+ uint32_t endOffset = 0;
+ const char16_t *buffer = lastLine.get();
+ while (endOffset < length && buffer[endOffset] != '\n' &&
+ buffer[endOffset] != '\r') {
+ ++endOffset;
+ }
+ mLastLine.Append(Substring(buffer, buffer + endOffset));
+ if (endOffset < length) {
+ // We found a newline.
+ break;
+ }
+
+ lastLine.advance(length);
+ }
+
+ HandleError();
+ }
+
+ return mInternalState;
+ }
+
+ // Either we have more buffers, or we were blocked (and we'll flush in the
+ // next iteration), or we should have emptied Expat's buffer.
+ NS_ASSERTION(!noMoreBuffers || blocked ||
+ (mExpatBuffered == 0 && currentExpatPosition == end),
+ "Unreachable data left in Expat's buffer");
+
+ start.advance(length);
+
+ // It's possible for start to have passed end if we received more data
+ // (e.g. if we spun the event loop in an inline script). Reload end now
+ // to compensate.
+ aScanner.EndReading(end);
+ }
+
+ aScanner.SetPosition(currentExpatPosition, true);
+ aScanner.Mark();
+
+ MOZ_LOG(gExpatDriverLog, LogLevel::Debug,
+ ("Remaining in expat's buffer: %i, remaining in scanner: %i.",
+ mExpatBuffered, Distance(currentExpatPosition, end)));
+
+ return NS_SUCCEEDED(mInternalState) ? kEOF : NS_OK;
+}
+
+NS_IMETHODIMP
+nsExpatDriver::WillBuildModel(const CParserContext& aParserContext,
+ nsITokenizer* aTokenizer,
+ nsIContentSink* aSink)
+{
+ mSink = do_QueryInterface(aSink);
+ if (!mSink) {
+ NS_ERROR("nsExpatDriver didn't get an nsIExpatSink");
+ // Make sure future calls to us bail out as needed
+ mInternalState = NS_ERROR_UNEXPECTED;
+ return mInternalState;
+ }
+
+ mOriginalSink = aSink;
+
+ static const XML_Memory_Handling_Suite memsuite =
+ {
+ (void *(*)(size_t))PR_Malloc,
+ (void *(*)(void *, size_t))PR_Realloc,
+ PR_Free
+ };
+
+ static const char16_t kExpatSeparator[] = { kExpatSeparatorChar, '\0' };
+
+ mExpatParser = XML_ParserCreate_MM(kUTF16, &memsuite, kExpatSeparator);
+ NS_ENSURE_TRUE(mExpatParser, NS_ERROR_FAILURE);
+
+ XML_SetReturnNSTriplet(mExpatParser, XML_TRUE);
+
+#ifdef XML_DTD
+ XML_SetParamEntityParsing(mExpatParser, XML_PARAM_ENTITY_PARSING_ALWAYS);
+#endif
+
+ mURISpec = aParserContext.mScanner->GetFilename();
+
+ XML_SetBase(mExpatParser, mURISpec.get());
+
+ nsCOMPtr<nsIDocument> doc = do_QueryInterface(mOriginalSink->GetTarget());
+ if (doc) {
+ nsCOMPtr<nsPIDOMWindowOuter> win = doc->GetWindow();
+ nsCOMPtr<nsPIDOMWindowInner> inner;
+ if (win) {
+ inner = win->GetCurrentInnerWindow();
+ } else {
+ bool aHasHadScriptHandlingObject;
+ nsIScriptGlobalObject *global =
+ doc->GetScriptHandlingObject(aHasHadScriptHandlingObject);
+ if (global) {
+ inner = do_QueryInterface(global);
+ }
+ }
+ if (inner) {
+ mInnerWindowID = inner->WindowID();
+ }
+ }
+
+ // Set up the callbacks
+ XML_SetXmlDeclHandler(mExpatParser, Driver_HandleXMLDeclaration);
+ XML_SetElementHandler(mExpatParser, Driver_HandleStartElement,
+ Driver_HandleEndElement);
+ XML_SetCharacterDataHandler(mExpatParser, Driver_HandleCharacterData);
+ XML_SetProcessingInstructionHandler(mExpatParser,
+ Driver_HandleProcessingInstruction);
+ XML_SetDefaultHandlerExpand(mExpatParser, Driver_HandleDefault);
+ XML_SetExternalEntityRefHandler(mExpatParser,
+ (XML_ExternalEntityRefHandler)
+ Driver_HandleExternalEntityRef);
+ XML_SetExternalEntityRefHandlerArg(mExpatParser, this);
+ XML_SetCommentHandler(mExpatParser, Driver_HandleComment);
+ XML_SetCdataSectionHandler(mExpatParser, Driver_HandleStartCdataSection,
+ Driver_HandleEndCdataSection);
+
+ XML_SetParamEntityParsing(mExpatParser,
+ XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
+ XML_SetDoctypeDeclHandler(mExpatParser, Driver_HandleStartDoctypeDecl,
+ Driver_HandleEndDoctypeDecl);
+
+ // If the sink is an nsIExtendedExpatSink,
+ // register some addtional handlers.
+ mExtendedSink = do_QueryInterface(mSink);
+ if (mExtendedSink) {
+ XML_SetNamespaceDeclHandler(mExpatParser,
+ Driver_HandleStartNamespaceDecl,
+ Driver_HandleEndNamespaceDecl);
+ XML_SetUnparsedEntityDeclHandler(mExpatParser,
+ Driver_HandleUnparsedEntityDecl);
+ XML_SetNotationDeclHandler(mExpatParser,
+ Driver_HandleNotationDecl);
+ }
+
+ // Set up the user data.
+ XML_SetUserData(mExpatParser, this);
+
+ return mInternalState;
+}
+
+NS_IMETHODIMP
+nsExpatDriver::BuildModel(nsITokenizer* aTokenizer, nsIContentSink* aSink)
+{
+ return mInternalState;
+}
+
+NS_IMETHODIMP
+nsExpatDriver::DidBuildModel(nsresult anErrorCode)
+{
+ mOriginalSink = nullptr;
+ mSink = nullptr;
+ mExtendedSink = nullptr;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsExpatDriver::WillTokenize(bool aIsFinalChunk)
+{
+ mIsFinalChunk = aIsFinalChunk;
+ return NS_OK;
+}
+
+NS_IMETHODIMP_(void)
+nsExpatDriver::Terminate()
+{
+ // XXX - not sure what happens to the unparsed data.
+ if (mExpatParser) {
+ XML_StopParser(mExpatParser, XML_FALSE);
+ }
+ mInternalState = NS_ERROR_HTMLPARSER_STOPPARSING;
+}
+
+NS_IMETHODIMP_(int32_t)
+nsExpatDriver::GetType()
+{
+ return NS_IPARSER_FLAG_XML;
+}
+
+NS_IMETHODIMP_(nsDTDMode)
+nsExpatDriver::GetMode() const
+{
+ return eDTDMode_full_standards;
+}
+
+/*************************** Unused methods **********************************/
+
+NS_IMETHODIMP_(bool)
+nsExpatDriver::IsContainer(int32_t aTag) const
+{
+ return true;
+}
+
+NS_IMETHODIMP_(bool)
+nsExpatDriver::CanContain(int32_t aParent,int32_t aChild) const
+{
+ return true;
+}
+
+void
+nsExpatDriver::MaybeStopParser(nsresult aState)
+{
+ if (NS_FAILED(aState)) {
+ // If we had a failure we want to override NS_ERROR_HTMLPARSER_INTERRUPTED
+ // and we want to override NS_ERROR_HTMLPARSER_BLOCK but not with
+ // NS_ERROR_HTMLPARSER_INTERRUPTED.
+ if (NS_SUCCEEDED(mInternalState) ||
+ mInternalState == NS_ERROR_HTMLPARSER_INTERRUPTED ||
+ (mInternalState == NS_ERROR_HTMLPARSER_BLOCK &&
+ aState != NS_ERROR_HTMLPARSER_INTERRUPTED)) {
+ mInternalState = (aState == NS_ERROR_HTMLPARSER_INTERRUPTED ||
+ aState == NS_ERROR_HTMLPARSER_BLOCK) ?
+ aState :
+ NS_ERROR_HTMLPARSER_STOPPARSING;
+ }
+
+ // If we get an error then we need to stop Expat (by calling XML_StopParser
+ // with false as the last argument). If the parser should be blocked or
+ // interrupted we need to pause Expat (by calling XML_StopParser with
+ // true as the last argument).
+ XML_StopParser(mExpatParser, BlockedOrInterrupted());
+ }
+ else if (NS_SUCCEEDED(mInternalState)) {
+ // Only clobber mInternalState with the success code if we didn't block or
+ // interrupt before.
+ mInternalState = aState;
+ }
+}
diff --git a/parser/htmlparser/nsExpatDriver.h b/parser/htmlparser/nsExpatDriver.h
new file mode 100644
index 000000000..1bf022ade
--- /dev/null
+++ b/parser/htmlparser/nsExpatDriver.h
@@ -0,0 +1,142 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef NS_EXPAT_DRIVER__
+#define NS_EXPAT_DRIVER__
+
+#include "expat_config.h"
+#include "expat.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "nsIDTD.h"
+#include "nsITokenizer.h"
+#include "nsIInputStream.h"
+#include "nsIParser.h"
+#include "nsCycleCollectionParticipant.h"
+
+class nsIExpatSink;
+class nsIExtendedExpatSink;
+struct nsCatalogData;
+
+class nsExpatDriver : public nsIDTD,
+ public nsITokenizer
+{
+ virtual ~nsExpatDriver();
+
+public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_NSIDTD
+ NS_DECL_NSITOKENIZER
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsExpatDriver, nsIDTD)
+
+ nsExpatDriver();
+
+ int HandleExternalEntityRef(const char16_t *aOpenEntityNames,
+ const char16_t *aBase,
+ const char16_t *aSystemId,
+ const char16_t *aPublicId);
+ nsresult HandleStartElement(const char16_t *aName, const char16_t **aAtts);
+ nsresult HandleEndElement(const char16_t *aName);
+ nsresult HandleCharacterData(const char16_t *aCData, const uint32_t aLength);
+ nsresult HandleComment(const char16_t *aName);
+ nsresult HandleProcessingInstruction(const char16_t *aTarget,
+ const char16_t *aData);
+ nsresult HandleXMLDeclaration(const char16_t *aVersion,
+ const char16_t *aEncoding,
+ int32_t aStandalone);
+ nsresult HandleDefault(const char16_t *aData, const uint32_t aLength);
+ nsresult HandleStartCdataSection();
+ nsresult HandleEndCdataSection();
+ nsresult HandleStartDoctypeDecl(const char16_t* aDoctypeName,
+ const char16_t* aSysid,
+ const char16_t* aPubid,
+ bool aHasInternalSubset);
+ nsresult HandleEndDoctypeDecl();
+ nsresult HandleStartNamespaceDecl(const char16_t* aPrefix,
+ const char16_t* aUri);
+ nsresult HandleEndNamespaceDecl(const char16_t* aPrefix);
+ nsresult HandleNotationDecl(const char16_t* aNotationName,
+ const char16_t* aBase,
+ const char16_t* aSysid,
+ const char16_t* aPubid);
+ nsresult HandleUnparsedEntityDecl(const char16_t* aEntityName,
+ const char16_t* aBase,
+ const char16_t* aSysid,
+ const char16_t* aPubid,
+ const char16_t* aNotationName);
+
+private:
+ // Load up an external stream to get external entity information
+ nsresult OpenInputStreamFromExternalDTD(const char16_t* aFPIStr,
+ const char16_t* aURLStr,
+ const char16_t* aBaseURL,
+ nsIInputStream** aStream,
+ nsAString& aAbsURL);
+
+ /**
+ * Pass a buffer to Expat. If Expat is blocked aBuffer should be null and
+ * aLength should be 0. The result of the call will be stored in
+ * mInternalState. Expat will parse as much of the buffer as it can and store
+ * the rest in its internal buffer.
+ *
+ * @param aBuffer the buffer to pass to Expat. May be null.
+ * @param aLength the length of the buffer to pass to Expat (in number of
+ * char16_t's). Must be 0 if aBuffer is null and > 0 if
+ * aBuffer is not null.
+ * @param aIsFinal whether there will definitely not be any more new buffers
+ * passed in to ParseBuffer
+ * @param aConsumed [out] the number of PRUnichars that Expat consumed. This
+ * doesn't include the PRUnichars that Expat stored in
+ * its buffer but didn't parse yet.
+ */
+ void ParseBuffer(const char16_t *aBuffer, uint32_t aLength, bool aIsFinal,
+ uint32_t *aConsumed);
+ nsresult HandleError();
+
+ void MaybeStopParser(nsresult aState);
+
+ bool BlockedOrInterrupted()
+ {
+ return mInternalState == NS_ERROR_HTMLPARSER_BLOCK ||
+ mInternalState == NS_ERROR_HTMLPARSER_INTERRUPTED;
+ }
+
+ XML_Parser mExpatParser;
+ nsString mLastLine;
+ nsString mCDataText;
+ // Various parts of a doctype
+ nsString mDoctypeName;
+ nsString mSystemID;
+ nsString mPublicID;
+ nsString mInternalSubset;
+ bool mInCData;
+ bool mInInternalSubset;
+ bool mInExternalDTD;
+ bool mMadeFinalCallToExpat;
+
+ // Whether we're sure that we won't be getting more buffers to parse from
+ // Necko
+ bool mIsFinalChunk;
+
+ nsresult mInternalState;
+
+ // The length of the data in Expat's buffer (in number of PRUnichars).
+ uint32_t mExpatBuffered;
+
+ // These sinks all refer the same conceptual object. mOriginalSink is
+ // identical with the nsIContentSink* passed to WillBuildModel, and exists
+ // only to avoid QI-ing back to nsIContentSink*.
+ nsCOMPtr<nsIContentSink> mOriginalSink;
+ nsCOMPtr<nsIExpatSink> mSink;
+ nsCOMPtr<nsIExtendedExpatSink> mExtendedSink;
+
+ const nsCatalogData* mCatalogData; // weak
+ nsString mURISpec;
+
+ // Used for error reporting.
+ uint64_t mInnerWindowID;
+};
+
+#endif
diff --git a/parser/htmlparser/nsHTMLEntities.cpp b/parser/htmlparser/nsHTMLEntities.cpp
new file mode 100644
index 000000000..e8365c21f
--- /dev/null
+++ b/parser/htmlparser/nsHTMLEntities.cpp
@@ -0,0 +1,205 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/ArrayUtils.h"
+
+#include "nsHTMLEntities.h"
+
+#include "nsString.h"
+#include "nsCRT.h"
+#include "PLDHashTable.h"
+
+using namespace mozilla;
+
+struct EntityNode {
+ const char* mStr; // never owns buffer
+ int32_t mUnicode;
+};
+
+struct EntityNodeEntry : public PLDHashEntryHdr
+{
+ const EntityNode* node;
+};
+
+static bool matchNodeString(const PLDHashEntryHdr* aHdr, const void* key)
+{
+ const EntityNodeEntry* entry = static_cast<const EntityNodeEntry*>(aHdr);
+ const char* str = static_cast<const char*>(key);
+ return (nsCRT::strcmp(entry->node->mStr, str) == 0);
+}
+
+static bool matchNodeUnicode(const PLDHashEntryHdr* aHdr, const void* key)
+{
+ const EntityNodeEntry* entry = static_cast<const EntityNodeEntry*>(aHdr);
+ const int32_t ucode = NS_PTR_TO_INT32(key);
+ return (entry->node->mUnicode == ucode);
+}
+
+static PLDHashNumber hashUnicodeValue(const void* key)
+{
+ // key is actually the unicode value
+ return PLDHashNumber(NS_PTR_TO_INT32(key));
+}
+
+
+static const PLDHashTableOps EntityToUnicodeOps = {
+ PLDHashTable::HashStringKey,
+ matchNodeString,
+ PLDHashTable::MoveEntryStub,
+ PLDHashTable::ClearEntryStub,
+ nullptr,
+};
+
+static const PLDHashTableOps UnicodeToEntityOps = {
+ hashUnicodeValue,
+ matchNodeUnicode,
+ PLDHashTable::MoveEntryStub,
+ PLDHashTable::ClearEntryStub,
+ nullptr,
+};
+
+static PLDHashTable* gEntityToUnicode;
+static PLDHashTable* gUnicodeToEntity;
+static nsrefcnt gTableRefCnt = 0;
+
+#define HTML_ENTITY(_name, _value) { #_name, _value },
+static const EntityNode gEntityArray[] = {
+#include "nsHTMLEntityList.h"
+};
+#undef HTML_ENTITY
+
+#define NS_HTML_ENTITY_COUNT ((int32_t)ArrayLength(gEntityArray))
+
+nsresult
+nsHTMLEntities::AddRefTable(void)
+{
+ if (!gTableRefCnt) {
+ gEntityToUnicode = new PLDHashTable(&EntityToUnicodeOps,
+ sizeof(EntityNodeEntry),
+ NS_HTML_ENTITY_COUNT);
+ gUnicodeToEntity = new PLDHashTable(&UnicodeToEntityOps,
+ sizeof(EntityNodeEntry),
+ NS_HTML_ENTITY_COUNT);
+ for (const EntityNode *node = gEntityArray,
+ *node_end = ArrayEnd(gEntityArray);
+ node < node_end; ++node) {
+
+ // add to Entity->Unicode table
+ auto entry = static_cast<EntityNodeEntry*>
+ (gEntityToUnicode->Add(node->mStr, fallible));
+ NS_ASSERTION(entry, "Error adding an entry");
+ // Prefer earlier entries when we have duplication.
+ if (!entry->node)
+ entry->node = node;
+
+ // add to Unicode->Entity table
+ entry = static_cast<EntityNodeEntry*>
+ (gUnicodeToEntity->Add(NS_INT32_TO_PTR(node->mUnicode),
+ fallible));
+ NS_ASSERTION(entry, "Error adding an entry");
+ // Prefer earlier entries when we have duplication.
+ if (!entry->node)
+ entry->node = node;
+ }
+#ifdef DEBUG
+ gUnicodeToEntity->MarkImmutable();
+ gEntityToUnicode->MarkImmutable();
+#endif
+ }
+ ++gTableRefCnt;
+ return NS_OK;
+}
+
+void
+nsHTMLEntities::ReleaseTable(void)
+{
+ if (--gTableRefCnt != 0) {
+ return;
+ }
+
+ delete gEntityToUnicode;
+ delete gUnicodeToEntity;
+ gEntityToUnicode = nullptr;
+ gUnicodeToEntity = nullptr;
+}
+
+int32_t
+nsHTMLEntities::EntityToUnicode(const nsCString& aEntity)
+{
+ NS_ASSERTION(gEntityToUnicode, "no lookup table, needs addref");
+ if (!gEntityToUnicode) {
+ return -1;
+ }
+
+ //this little piece of code exists because entities may or may not have the terminating ';'.
+ //if we see it, strip if off for this test...
+
+ if(';'==aEntity.Last()) {
+ nsAutoCString temp(aEntity);
+ temp.Truncate(aEntity.Length()-1);
+ return EntityToUnicode(temp);
+ }
+
+ auto entry =
+ static_cast<EntityNodeEntry*>(gEntityToUnicode->Search(aEntity.get()));
+
+ return entry ? entry->node->mUnicode : -1;
+}
+
+
+int32_t
+nsHTMLEntities::EntityToUnicode(const nsAString& aEntity) {
+ nsAutoCString theEntity; theEntity.AssignWithConversion(aEntity);
+ if(';'==theEntity.Last()) {
+ theEntity.Truncate(theEntity.Length()-1);
+ }
+
+ return EntityToUnicode(theEntity);
+}
+
+
+const char*
+nsHTMLEntities::UnicodeToEntity(int32_t aUnicode)
+{
+ NS_ASSERTION(gUnicodeToEntity, "no lookup table, needs addref");
+ auto entry =
+ static_cast<EntityNodeEntry*>
+ (gUnicodeToEntity->Search(NS_INT32_TO_PTR(aUnicode)));
+
+ return entry ? entry->node->mStr : nullptr;
+}
+
+#ifdef DEBUG
+#include <stdio.h>
+
+class nsTestEntityTable {
+public:
+ nsTestEntityTable() {
+ int32_t value;
+ nsHTMLEntities::AddRefTable();
+
+ // Make sure we can find everything we are supposed to
+ for (int i = 0; i < NS_HTML_ENTITY_COUNT; ++i) {
+ nsAutoString entity; entity.AssignWithConversion(gEntityArray[i].mStr);
+
+ value = nsHTMLEntities::EntityToUnicode(entity);
+ NS_ASSERTION(value != -1, "can't find entity");
+ NS_ASSERTION(value == gEntityArray[i].mUnicode, "bad unicode value");
+
+ entity.AssignWithConversion(nsHTMLEntities::UnicodeToEntity(value));
+ NS_ASSERTION(entity.EqualsASCII(gEntityArray[i].mStr), "bad entity name");
+ }
+
+ // Make sure we don't find things that aren't there
+ value = nsHTMLEntities::EntityToUnicode(nsAutoCString("@"));
+ NS_ASSERTION(value == -1, "found @");
+ value = nsHTMLEntities::EntityToUnicode(nsAutoCString("zzzzz"));
+ NS_ASSERTION(value == -1, "found zzzzz");
+ nsHTMLEntities::ReleaseTable();
+ }
+};
+//nsTestEntityTable validateEntityTable;
+#endif
+
diff --git a/parser/htmlparser/nsHTMLEntities.h b/parser/htmlparser/nsHTMLEntities.h
new file mode 100644
index 000000000..f38856bfa
--- /dev/null
+++ b/parser/htmlparser/nsHTMLEntities.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef nsHTMLEntities_h___
+#define nsHTMLEntities_h___
+
+#include "nsString.h"
+
+class nsHTMLEntities {
+public:
+
+ static nsresult AddRefTable(void);
+ static void ReleaseTable(void);
+
+/**
+ * Translate an entity string into it's unicode value. This call
+ * returns -1 if the entity cannot be mapped. Note that the string
+ * passed in must NOT have the leading "&" nor the trailing ";"
+ * in it.
+ */
+ static int32_t EntityToUnicode(const nsAString& aEntity);
+ static int32_t EntityToUnicode(const nsCString& aEntity);
+
+/**
+ * Translate a unicode value into an entity string. This call
+ * returns null if the entity cannot be mapped.
+ * Note that the string returned DOES NOT have the leading "&" nor
+ * the trailing ";" in it.
+ */
+ static const char* UnicodeToEntity(int32_t aUnicode);
+};
+
+
+#endif /* nsHTMLEntities_h___ */
diff --git a/parser/htmlparser/nsHTMLEntityList.h b/parser/htmlparser/nsHTMLEntityList.h
new file mode 100644
index 000000000..fa05382bf
--- /dev/null
+++ b/parser/htmlparser/nsHTMLEntityList.h
@@ -0,0 +1,303 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/******
+
+ This file contains the list of all HTML entities
+ See nsHTMLEntities.h for access to the enum values for entities
+
+ It is designed to be used as inline input to nsHTMLEntities.cpp *only*
+ through the magic of C preprocessing.
+
+ All entries must be enclosed in the macro HTML_ENTITY which will have cruel
+ and unusual things done to it
+
+ It is recommended (but not strictly necessary) to keep all entries
+ in alphabetical order
+
+ The first argument to HTML_ENTITY is the string value of the entity
+ The second argument it HTML_ENTITY is the unicode value of the entity
+
+ ******/
+
+// ISO 8859-1 entities.
+// See the HTML4.0 spec for this list in it's DTD form
+HTML_ENTITY(nbsp, 160)
+HTML_ENTITY(iexcl, 161)
+HTML_ENTITY(cent, 162)
+HTML_ENTITY(pound, 163)
+HTML_ENTITY(curren, 164)
+HTML_ENTITY(yen, 165)
+HTML_ENTITY(brvbar, 166)
+HTML_ENTITY(sect, 167)
+HTML_ENTITY(uml, 168)
+HTML_ENTITY(copy, 169)
+HTML_ENTITY(ordf, 170)
+HTML_ENTITY(laquo, 171)
+HTML_ENTITY(not, 172)
+HTML_ENTITY(shy, 173)
+HTML_ENTITY(reg, 174)
+HTML_ENTITY(macr, 175)
+HTML_ENTITY(deg, 176)
+HTML_ENTITY(plusmn, 177)
+HTML_ENTITY(sup2, 178)
+HTML_ENTITY(sup3, 179)
+HTML_ENTITY(acute, 180)
+HTML_ENTITY(micro, 181)
+HTML_ENTITY(para, 182)
+HTML_ENTITY(middot, 183)
+HTML_ENTITY(cedil, 184)
+HTML_ENTITY(sup1, 185)
+HTML_ENTITY(ordm, 186)
+HTML_ENTITY(raquo, 187)
+HTML_ENTITY(frac14, 188)
+HTML_ENTITY(frac12, 189)
+HTML_ENTITY(frac34, 190)
+HTML_ENTITY(iquest, 191)
+HTML_ENTITY(Agrave, 192)
+HTML_ENTITY(Aacute, 193)
+HTML_ENTITY(Acirc, 194)
+HTML_ENTITY(Atilde, 195)
+HTML_ENTITY(Auml, 196)
+HTML_ENTITY(Aring, 197)
+HTML_ENTITY(AElig, 198)
+HTML_ENTITY(Ccedil, 199)
+HTML_ENTITY(Egrave, 200)
+HTML_ENTITY(Eacute, 201)
+HTML_ENTITY(Ecirc, 202)
+HTML_ENTITY(Euml, 203)
+HTML_ENTITY(Igrave, 204)
+HTML_ENTITY(Iacute, 205)
+HTML_ENTITY(Icirc, 206)
+HTML_ENTITY(Iuml, 207)
+HTML_ENTITY(ETH, 208)
+HTML_ENTITY(Ntilde, 209)
+HTML_ENTITY(Ograve, 210)
+HTML_ENTITY(Oacute, 211)
+HTML_ENTITY(Ocirc, 212)
+HTML_ENTITY(Otilde, 213)
+HTML_ENTITY(Ouml, 214)
+HTML_ENTITY(times, 215)
+HTML_ENTITY(Oslash, 216)
+HTML_ENTITY(Ugrave, 217)
+HTML_ENTITY(Uacute, 218)
+HTML_ENTITY(Ucirc, 219)
+HTML_ENTITY(Uuml, 220)
+HTML_ENTITY(Yacute, 221)
+HTML_ENTITY(THORN, 222)
+HTML_ENTITY(szlig, 223)
+HTML_ENTITY(agrave, 224)
+HTML_ENTITY(aacute, 225)
+HTML_ENTITY(acirc, 226)
+HTML_ENTITY(atilde, 227)
+HTML_ENTITY(auml, 228)
+HTML_ENTITY(aring, 229)
+HTML_ENTITY(aelig, 230)
+HTML_ENTITY(ccedil, 231)
+HTML_ENTITY(egrave, 232)
+HTML_ENTITY(eacute, 233)
+HTML_ENTITY(ecirc, 234)
+HTML_ENTITY(euml, 235)
+HTML_ENTITY(igrave, 236)
+HTML_ENTITY(iacute, 237)
+HTML_ENTITY(icirc, 238)
+HTML_ENTITY(iuml, 239)
+HTML_ENTITY(eth, 240)
+HTML_ENTITY(ntilde, 241)
+HTML_ENTITY(ograve, 242)
+HTML_ENTITY(oacute, 243)
+HTML_ENTITY(ocirc, 244)
+HTML_ENTITY(otilde, 245)
+HTML_ENTITY(ouml, 246)
+HTML_ENTITY(divide, 247)
+HTML_ENTITY(oslash, 248)
+HTML_ENTITY(ugrave, 249)
+HTML_ENTITY(uacute, 250)
+HTML_ENTITY(ucirc, 251)
+HTML_ENTITY(uuml, 252)
+HTML_ENTITY(yacute, 253)
+HTML_ENTITY(thorn, 254)
+HTML_ENTITY(yuml, 255)
+
+// Symbols, mathematical symbols and Greek letters
+// See the HTML4.0 spec for this list in it's DTD form
+HTML_ENTITY(fnof, 402)
+HTML_ENTITY(Alpha, 913)
+HTML_ENTITY(Beta, 914)
+HTML_ENTITY(Gamma, 915)
+HTML_ENTITY(Delta, 916)
+HTML_ENTITY(Epsilon, 917)
+HTML_ENTITY(Zeta, 918)
+HTML_ENTITY(Eta, 919)
+HTML_ENTITY(Theta, 920)
+HTML_ENTITY(Iota, 921)
+HTML_ENTITY(Kappa, 922)
+HTML_ENTITY(Lambda, 923)
+HTML_ENTITY(Mu, 924)
+HTML_ENTITY(Nu, 925)
+HTML_ENTITY(Xi, 926)
+HTML_ENTITY(Omicron, 927)
+HTML_ENTITY(Pi, 928)
+HTML_ENTITY(Rho, 929)
+HTML_ENTITY(Sigma, 931)
+HTML_ENTITY(Tau, 932)
+HTML_ENTITY(Upsilon, 933)
+HTML_ENTITY(Phi, 934)
+HTML_ENTITY(Chi, 935)
+HTML_ENTITY(Psi, 936)
+HTML_ENTITY(Omega, 937)
+HTML_ENTITY(alpha, 945)
+HTML_ENTITY(beta, 946)
+HTML_ENTITY(gamma, 947)
+HTML_ENTITY(delta, 948)
+HTML_ENTITY(epsilon, 949)
+HTML_ENTITY(zeta, 950)
+HTML_ENTITY(eta, 951)
+HTML_ENTITY(theta, 952)
+HTML_ENTITY(iota, 953)
+HTML_ENTITY(kappa, 954)
+HTML_ENTITY(lambda, 955)
+HTML_ENTITY(mu, 956)
+HTML_ENTITY(nu, 957)
+HTML_ENTITY(xi, 958)
+HTML_ENTITY(omicron, 959)
+HTML_ENTITY(pi, 960)
+HTML_ENTITY(rho, 961)
+HTML_ENTITY(sigmaf, 962)
+HTML_ENTITY(sigma, 963)
+HTML_ENTITY(tau, 964)
+HTML_ENTITY(upsilon, 965)
+HTML_ENTITY(phi, 966)
+HTML_ENTITY(chi, 967)
+HTML_ENTITY(psi, 968)
+HTML_ENTITY(omega, 969)
+HTML_ENTITY(thetasym, 977)
+HTML_ENTITY(upsih, 978)
+HTML_ENTITY(piv, 982)
+HTML_ENTITY(bull, 8226)
+HTML_ENTITY(hellip, 8230)
+HTML_ENTITY(prime, 8242)
+HTML_ENTITY(Prime, 8243)
+HTML_ENTITY(oline, 8254)
+HTML_ENTITY(frasl, 8260)
+HTML_ENTITY(weierp, 8472)
+HTML_ENTITY(image, 8465)
+HTML_ENTITY(real, 8476)
+HTML_ENTITY(trade, 8482)
+HTML_ENTITY(alefsym, 8501)
+HTML_ENTITY(larr, 8592)
+HTML_ENTITY(uarr, 8593)
+HTML_ENTITY(rarr, 8594)
+HTML_ENTITY(darr, 8595)
+HTML_ENTITY(harr, 8596)
+HTML_ENTITY(crarr, 8629)
+HTML_ENTITY(lArr, 8656)
+HTML_ENTITY(uArr, 8657)
+HTML_ENTITY(rArr, 8658)
+HTML_ENTITY(dArr, 8659)
+HTML_ENTITY(hArr, 8660)
+HTML_ENTITY(forall, 8704)
+HTML_ENTITY(part, 8706)
+HTML_ENTITY(exist, 8707)
+HTML_ENTITY(empty, 8709)
+HTML_ENTITY(nabla, 8711)
+HTML_ENTITY(isin, 8712)
+HTML_ENTITY(notin, 8713)
+HTML_ENTITY(ni, 8715)
+HTML_ENTITY(prod, 8719)
+HTML_ENTITY(sum, 8721)
+HTML_ENTITY(minus, 8722)
+HTML_ENTITY(lowast, 8727)
+HTML_ENTITY(radic, 8730)
+HTML_ENTITY(prop, 8733)
+HTML_ENTITY(infin, 8734)
+HTML_ENTITY(ang, 8736)
+HTML_ENTITY(and, 8743)
+HTML_ENTITY(or, 8744)
+HTML_ENTITY(cap, 8745)
+HTML_ENTITY(cup, 8746)
+HTML_ENTITY(int, 8747)
+HTML_ENTITY(there4, 8756)
+HTML_ENTITY(sim, 8764)
+HTML_ENTITY(cong, 8773)
+HTML_ENTITY(asymp, 8776)
+HTML_ENTITY(ne, 8800)
+HTML_ENTITY(equiv, 8801)
+HTML_ENTITY(le, 8804)
+HTML_ENTITY(ge, 8805)
+HTML_ENTITY(sub, 8834)
+HTML_ENTITY(sup, 8835)
+HTML_ENTITY(nsub, 8836)
+HTML_ENTITY(sube, 8838)
+HTML_ENTITY(supe, 8839)
+HTML_ENTITY(oplus, 8853)
+HTML_ENTITY(otimes, 8855)
+HTML_ENTITY(perp, 8869)
+HTML_ENTITY(sdot, 8901)
+HTML_ENTITY(lceil, 8968)
+HTML_ENTITY(rceil, 8969)
+HTML_ENTITY(lfloor, 8970)
+HTML_ENTITY(rfloor, 8971)
+// Bug 603716: expansions of &lang; and &rang; have been modified in HTML5.
+// See http://www.w3.org/2003/entities/2007/htmlmathml-f.ent
+HTML_ENTITY(lang, 0x27E8)
+HTML_ENTITY(rang, 0x27E9)
+HTML_ENTITY(loz, 9674)
+HTML_ENTITY(spades, 9824)
+HTML_ENTITY(clubs, 9827)
+HTML_ENTITY(hearts, 9829)
+HTML_ENTITY(diams, 9830)
+
+// Markup-significant and internationalization characters
+// See the HTML4.0 spec for this list in it's DTD form
+HTML_ENTITY(quot, 34)
+HTML_ENTITY(amp, 38)
+HTML_ENTITY(lt, 60)
+HTML_ENTITY(gt, 62)
+HTML_ENTITY(OElig, 338)
+HTML_ENTITY(oelig, 339)
+HTML_ENTITY(Scaron, 352)
+HTML_ENTITY(scaron, 353)
+HTML_ENTITY(Yuml, 376)
+HTML_ENTITY(circ, 710)
+HTML_ENTITY(tilde, 732)
+HTML_ENTITY(ensp, 8194)
+HTML_ENTITY(emsp, 8195)
+HTML_ENTITY(thinsp, 8201)
+HTML_ENTITY(zwnj, 8204)
+HTML_ENTITY(zwj, 8205)
+HTML_ENTITY(lrm, 8206)
+HTML_ENTITY(rlm, 8207)
+HTML_ENTITY(ndash, 8211)
+HTML_ENTITY(mdash, 8212)
+HTML_ENTITY(lsquo, 8216)
+HTML_ENTITY(rsquo, 8217)
+HTML_ENTITY(sbquo, 8218)
+HTML_ENTITY(ldquo, 8220)
+HTML_ENTITY(rdquo, 8221)
+HTML_ENTITY(bdquo, 8222)
+HTML_ENTITY(dagger, 8224)
+HTML_ENTITY(Dagger, 8225)
+HTML_ENTITY(permil, 8240)
+HTML_ENTITY(lsaquo, 8249)
+HTML_ENTITY(rsaquo, 8250)
+HTML_ENTITY(euro, 8364)
+
+// Navigator entity extensions
+// This block of entities needs to be at the bottom of the list since it
+// contains duplicate Unicode codepoints. The codepoint to entity name
+// mapping (used by Composer) must ignores them, which occurs only
+// because they are listed later.
+
+// apos is from XML
+HTML_ENTITY(apos, 39)
+// The capitalized versions are required to handle non-standard input.
+HTML_ENTITY(AMP, 38)
+HTML_ENTITY(COPY, 169)
+HTML_ENTITY(GT, 62)
+HTML_ENTITY(LT, 60)
+HTML_ENTITY(QUOT, 34)
+HTML_ENTITY(REG, 174)
+
diff --git a/parser/htmlparser/nsHTMLTagList.h b/parser/htmlparser/nsHTMLTagList.h
new file mode 100644
index 000000000..edd771f7e
--- /dev/null
+++ b/parser/htmlparser/nsHTMLTagList.h
@@ -0,0 +1,186 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// IWYU pragma: private, include "nsHTMLTags.h"
+
+/******
+
+ This file contains the list of all HTML tags.
+ See nsHTMLTags.h for access to the enum values for tags.
+
+ It is designed to be used as inline input to nsHTMLTags.cpp and
+ nsHTMLContentSink *only* through the magic of C preprocessing.
+
+ All entries must be enclosed in the macro HTML_TAG which will have cruel
+ and unusual things done to it.
+
+ It is recommended (but not strictly necessary) to keep all entries
+ in alphabetical order.
+
+ The first argument to HTML_TAG is both the enum identifier of the
+ property and the string value. The second argument is the "creator"
+ method of the form NS_New$TAGNAMEElement, that will be used by
+ nsHTMLContentSink.cpp to create a content object for a tag of that
+ type. Use NOTUSED, if the particular tag has a non-standard creator.
+
+ The HTML_OTHER macro is for values in the nsHTMLTag enum that are
+ not strictly tags.
+
+ Entries *must* use only lowercase characters.
+
+ Don't forget to update /editor/libeditor/HTMLEditUtils.cpp as well.
+
+ ** Break these invariants and bad things will happen. **
+
+ ******/
+HTML_TAG(a, Anchor)
+HTML_HTMLELEMENT_TAG(abbr)
+HTML_HTMLELEMENT_TAG(acronym)
+HTML_HTMLELEMENT_TAG(address)
+HTML_TAG(applet, SharedObject)
+HTML_TAG(area, Area)
+HTML_HTMLELEMENT_TAG(article)
+HTML_HTMLELEMENT_TAG(aside)
+HTML_TAG(audio, Audio)
+HTML_HTMLELEMENT_TAG(b)
+HTML_TAG(base, Shared)
+HTML_HTMLELEMENT_TAG(basefont)
+HTML_HTMLELEMENT_TAG(bdo)
+HTML_TAG(bgsound, Unknown)
+HTML_HTMLELEMENT_TAG(big)
+HTML_TAG(blockquote, Shared)
+HTML_TAG(body, Body)
+HTML_TAG(br, BR)
+HTML_TAG(button, Button)
+HTML_TAG(canvas, Canvas)
+HTML_TAG(caption, TableCaption)
+HTML_HTMLELEMENT_TAG(center)
+HTML_HTMLELEMENT_TAG(cite)
+HTML_HTMLELEMENT_TAG(code)
+HTML_TAG(col, TableCol)
+HTML_TAG(colgroup, TableCol)
+HTML_TAG(content, Content)
+HTML_TAG(data, Data)
+HTML_TAG(datalist, DataList)
+HTML_HTMLELEMENT_TAG(dd)
+HTML_TAG(del, Mod)
+HTML_TAG(details, Details)
+HTML_HTMLELEMENT_TAG(dfn)
+HTML_TAG(dir, Shared)
+HTML_TAG(div, Div)
+HTML_TAG(dl, SharedList)
+HTML_HTMLELEMENT_TAG(dt)
+HTML_HTMLELEMENT_TAG(em)
+HTML_TAG(embed, SharedObject)
+HTML_TAG(fieldset, FieldSet)
+HTML_HTMLELEMENT_TAG(figcaption)
+HTML_HTMLELEMENT_TAG(figure)
+HTML_TAG(font, Font)
+HTML_HTMLELEMENT_TAG(footer)
+HTML_TAG(form, Form)
+HTML_TAG(frame, Frame)
+HTML_TAG(frameset, FrameSet)
+HTML_TAG(h1, Heading)
+HTML_TAG(h2, Heading)
+HTML_TAG(h3, Heading)
+HTML_TAG(h4, Heading)
+HTML_TAG(h5, Heading)
+HTML_TAG(h6, Heading)
+HTML_TAG(head, Shared)
+HTML_HTMLELEMENT_TAG(header)
+HTML_HTMLELEMENT_TAG(hgroup)
+HTML_TAG(hr, HR)
+HTML_TAG(html, Shared)
+HTML_HTMLELEMENT_TAG(i)
+HTML_TAG(iframe, IFrame)
+HTML_HTMLELEMENT_TAG(image)
+HTML_TAG(img, Image)
+HTML_TAG(input, Input)
+HTML_TAG(ins, Mod)
+HTML_HTMLELEMENT_TAG(kbd)
+HTML_TAG(keygen, Span)
+HTML_TAG(label, Label)
+HTML_TAG(legend, Legend)
+HTML_TAG(li, LI)
+HTML_TAG(link, Link)
+HTML_TAG(listing, Pre)
+HTML_HTMLELEMENT_TAG(main)
+HTML_TAG(map, Map)
+HTML_HTMLELEMENT_TAG(mark)
+HTML_TAG(marquee, Div)
+HTML_TAG(menu, Menu)
+HTML_TAG(menuitem, MenuItem)
+HTML_TAG(meta, Meta)
+HTML_TAG(meter, Meter)
+HTML_TAG(multicol, Unknown)
+HTML_HTMLELEMENT_TAG(nav)
+HTML_HTMLELEMENT_TAG(nobr)
+HTML_HTMLELEMENT_TAG(noembed)
+HTML_HTMLELEMENT_TAG(noframes)
+HTML_HTMLELEMENT_TAG(noscript)
+HTML_TAG(object, Object)
+HTML_TAG(ol, SharedList)
+HTML_TAG(optgroup, OptGroup)
+HTML_TAG(option, Option)
+HTML_TAG(output, Output)
+HTML_TAG(p, Paragraph)
+HTML_TAG(param, Shared)
+HTML_TAG(picture, Picture)
+HTML_HTMLELEMENT_TAG(plaintext)
+HTML_TAG(pre, Pre)
+HTML_TAG(progress, Progress)
+HTML_TAG(q, Shared)
+HTML_HTMLELEMENT_TAG(rb)
+HTML_HTMLELEMENT_TAG(rp)
+HTML_HTMLELEMENT_TAG(rt)
+HTML_HTMLELEMENT_TAG(rtc)
+HTML_HTMLELEMENT_TAG(ruby)
+HTML_HTMLELEMENT_TAG(s)
+HTML_HTMLELEMENT_TAG(samp)
+HTML_TAG(script, Script)
+HTML_HTMLELEMENT_TAG(section)
+HTML_TAG(select, Select)
+HTML_TAG(shadow, Shadow)
+HTML_HTMLELEMENT_TAG(small)
+HTML_TAG(source, Source)
+HTML_TAG(span, Span)
+HTML_HTMLELEMENT_TAG(strike)
+HTML_HTMLELEMENT_TAG(strong)
+HTML_TAG(style, Style)
+HTML_HTMLELEMENT_TAG(sub)
+HTML_TAG(summary, Summary)
+HTML_HTMLELEMENT_TAG(sup)
+HTML_TAG(table, Table)
+HTML_TAG(tbody, TableSection)
+HTML_TAG(td, TableCell)
+HTML_TAG(textarea, TextArea)
+HTML_TAG(tfoot, TableSection)
+HTML_TAG(th, TableCell)
+HTML_TAG(thead, TableSection)
+HTML_TAG(template, Template)
+HTML_TAG(time, Time)
+HTML_TAG(title, Title)
+HTML_TAG(tr, TableRow)
+HTML_TAG(track, Track)
+HTML_HTMLELEMENT_TAG(tt)
+HTML_HTMLELEMENT_TAG(u)
+HTML_TAG(ul, SharedList)
+HTML_HTMLELEMENT_TAG(var)
+HTML_TAG(video, Video)
+HTML_HTMLELEMENT_TAG(wbr)
+HTML_TAG(xmp, Pre)
+
+
+/* These are not for tags. But they will be included in the nsHTMLTag
+ enum anyway */
+
+HTML_OTHER(text)
+HTML_OTHER(whitespace)
+HTML_OTHER(newline)
+HTML_OTHER(comment)
+HTML_OTHER(entity)
+HTML_OTHER(doctypeDecl)
+HTML_OTHER(markupDecl)
+HTML_OTHER(instruction)
diff --git a/parser/htmlparser/nsHTMLTags.cpp b/parser/htmlparser/nsHTMLTags.cpp
new file mode 100644
index 000000000..d5a68d46a
--- /dev/null
+++ b/parser/htmlparser/nsHTMLTags.cpp
@@ -0,0 +1,265 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHTMLTags.h"
+#include "nsCRT.h"
+#include "nsReadableUtils.h"
+#include "nsString.h"
+#include "nsStaticAtom.h"
+#include "nsUnicharUtils.h"
+#include "mozilla/HashFunctions.h"
+#include <algorithm>
+
+using namespace mozilla;
+
+// static array of unicode tag names
+#define HTML_TAG(_tag, _classname) (u"" #_tag),
+#define HTML_HTMLELEMENT_TAG(_tag) (u"" #_tag),
+#define HTML_OTHER(_tag)
+const char16_t* const nsHTMLTags::sTagUnicodeTable[] = {
+#include "nsHTMLTagList.h"
+};
+#undef HTML_TAG
+#undef HTML_HTMLELEMENT_TAG
+#undef HTML_OTHER
+
+// static array of tag atoms
+nsIAtom* nsHTMLTags::sTagAtomTable[eHTMLTag_userdefined - 1];
+
+int32_t nsHTMLTags::gTableRefCount;
+PLHashTable* nsHTMLTags::gTagTable;
+PLHashTable* nsHTMLTags::gTagAtomTable;
+
+
+// char16_t* -> id hash
+static PLHashNumber
+HTMLTagsHashCodeUCPtr(const void *key)
+{
+ return HashString(static_cast<const char16_t*>(key));
+}
+
+static int
+HTMLTagsKeyCompareUCPtr(const void *key1, const void *key2)
+{
+ const char16_t *str1 = (const char16_t *)key1;
+ const char16_t *str2 = (const char16_t *)key2;
+
+ return nsCRT::strcmp(str1, str2) == 0;
+}
+
+// nsIAtom* -> id hash
+static PLHashNumber
+HTMLTagsHashCodeAtom(const void *key)
+{
+ return NS_PTR_TO_INT32(key) >> 2;
+}
+
+#define NS_HTMLTAG_NAME_MAX_LENGTH 10
+
+// static
+void
+nsHTMLTags::RegisterAtoms(void)
+{
+#define HTML_TAG(_tag, _classname) NS_STATIC_ATOM_BUFFER(Atombuffer_##_tag, #_tag)
+#define HTML_HTMLELEMENT_TAG(_tag) NS_STATIC_ATOM_BUFFER(Atombuffer_##_tag, #_tag)
+#define HTML_OTHER(_tag)
+#include "nsHTMLTagList.h"
+#undef HTML_TAG
+#undef HTML_HTMLELEMENT_TAG
+#undef HTML_OTHER
+
+// static array of tag StaticAtom structs
+#define HTML_TAG(_tag, _classname) NS_STATIC_ATOM(Atombuffer_##_tag, &nsHTMLTags::sTagAtomTable[eHTMLTag_##_tag - 1]),
+#define HTML_HTMLELEMENT_TAG(_tag) NS_STATIC_ATOM(Atombuffer_##_tag, &nsHTMLTags::sTagAtomTable[eHTMLTag_##_tag - 1]),
+#define HTML_OTHER(_tag)
+ static const nsStaticAtom sTagAtoms_info[] = {
+#include "nsHTMLTagList.h"
+ };
+#undef HTML_TAG
+#undef HTML_HTMLELEMENT_TAG
+#undef HTML_OTHER
+
+ // Fill in our static atom pointers
+ NS_RegisterStaticAtoms(sTagAtoms_info);
+
+
+#if defined(DEBUG)
+ {
+ // let's verify that all names in the the table are lowercase...
+ for (int32_t i = 0; i < NS_HTML_TAG_MAX; ++i) {
+ nsAutoString temp1((char16_t*)sTagAtoms_info[i].mStringBuffer->Data());
+ nsAutoString temp2((char16_t*)sTagAtoms_info[i].mStringBuffer->Data());
+ ToLowerCase(temp1);
+ NS_ASSERTION(temp1.Equals(temp2), "upper case char in table");
+ }
+
+ // let's verify that all names in the unicode strings above are
+ // correct.
+ for (int32_t i = 0; i < NS_HTML_TAG_MAX; ++i) {
+ nsAutoString temp1(sTagUnicodeTable[i]);
+ nsAutoString temp2((char16_t*)sTagAtoms_info[i].mStringBuffer->Data());
+ NS_ASSERTION(temp1.Equals(temp2), "Bad unicode tag name!");
+ }
+
+ // let's verify that NS_HTMLTAG_NAME_MAX_LENGTH is correct
+ uint32_t maxTagNameLength = 0;
+ for (int32_t i = 0; i < NS_HTML_TAG_MAX; ++i) {
+ uint32_t len = NS_strlen(sTagUnicodeTable[i]);
+ maxTagNameLength = std::max(len, maxTagNameLength);
+ }
+ NS_ASSERTION(maxTagNameLength == NS_HTMLTAG_NAME_MAX_LENGTH,
+ "NS_HTMLTAG_NAME_MAX_LENGTH not set correctly!");
+ }
+#endif
+}
+
+// static
+nsresult
+nsHTMLTags::AddRefTable(void)
+{
+ if (gTableRefCount++ == 0) {
+ NS_ASSERTION(!gTagTable && !gTagAtomTable, "pre existing hash!");
+
+ gTagTable = PL_NewHashTable(64, HTMLTagsHashCodeUCPtr,
+ HTMLTagsKeyCompareUCPtr, PL_CompareValues,
+ nullptr, nullptr);
+ NS_ENSURE_TRUE(gTagTable, NS_ERROR_OUT_OF_MEMORY);
+
+ gTagAtomTable = PL_NewHashTable(64, HTMLTagsHashCodeAtom,
+ PL_CompareValues, PL_CompareValues,
+ nullptr, nullptr);
+ NS_ENSURE_TRUE(gTagAtomTable, NS_ERROR_OUT_OF_MEMORY);
+
+ // Fill in gTagTable with the above static char16_t strings as
+ // keys and the value of the corresponding enum as the value in
+ // the table.
+
+ int32_t i;
+ for (i = 0; i < NS_HTML_TAG_MAX; ++i) {
+ PL_HashTableAdd(gTagTable, sTagUnicodeTable[i],
+ NS_INT32_TO_PTR(i + 1));
+
+ PL_HashTableAdd(gTagAtomTable, sTagAtomTable[i],
+ NS_INT32_TO_PTR(i + 1));
+ }
+ }
+
+ return NS_OK;
+}
+
+// static
+void
+nsHTMLTags::ReleaseTable(void)
+{
+ if (0 == --gTableRefCount) {
+ if (gTagTable) {
+ // Nothing to delete/free in this table, just destroy the table.
+
+ PL_HashTableDestroy(gTagTable);
+ PL_HashTableDestroy(gTagAtomTable);
+ gTagTable = nullptr;
+ gTagAtomTable = nullptr;
+ }
+ }
+}
+
+// static
+nsHTMLTag
+nsHTMLTags::LookupTag(const nsAString& aTagName)
+{
+ uint32_t length = aTagName.Length();
+
+ if (length > NS_HTMLTAG_NAME_MAX_LENGTH) {
+ return eHTMLTag_userdefined;
+ }
+
+ char16_t buf[NS_HTMLTAG_NAME_MAX_LENGTH + 1];
+
+ nsAString::const_iterator iter;
+ uint32_t i = 0;
+ char16_t c;
+
+ aTagName.BeginReading(iter);
+
+ // Fast lowercasing-while-copying of ASCII characters into a
+ // char16_t buffer
+
+ while (i < length) {
+ c = *iter;
+
+ if (c <= 'Z' && c >= 'A') {
+ c |= 0x20; // Lowercase the ASCII character.
+ }
+
+ buf[i] = c; // Copy ASCII character.
+
+ ++i;
+ ++iter;
+ }
+
+ buf[i] = 0;
+
+ return CaseSensitiveLookupTag(buf);
+}
+
+#ifdef DEBUG
+void
+nsHTMLTags::TestTagTable()
+{
+ const char16_t *tag;
+ nsHTMLTag id;
+ nsCOMPtr<nsIAtom> atom;
+
+ nsHTMLTags::AddRefTable();
+ // Make sure we can find everything we are supposed to
+ for (int i = 0; i < NS_HTML_TAG_MAX; ++i) {
+ tag = sTagUnicodeTable[i];
+ id = LookupTag(nsDependentString(tag));
+ NS_ASSERTION(id != eHTMLTag_userdefined, "can't find tag id");
+ const char16_t* check = GetStringValue(id);
+ NS_ASSERTION(0 == nsCRT::strcmp(check, tag), "can't map id back to tag");
+
+ nsAutoString uname(tag);
+ ToUpperCase(uname);
+ NS_ASSERTION(id == LookupTag(uname), "wrong id");
+
+ NS_ASSERTION(id == CaseSensitiveLookupTag(tag), "wrong id");
+
+ atom = NS_Atomize(tag);
+ NS_ASSERTION(id == CaseSensitiveLookupTag(atom), "wrong id");
+ NS_ASSERTION(atom == GetAtom(id), "can't map id back to atom");
+ }
+
+ // Make sure we don't find things that aren't there
+ id = LookupTag(NS_LITERAL_STRING("@"));
+ NS_ASSERTION(id == eHTMLTag_userdefined, "found @");
+ id = LookupTag(NS_LITERAL_STRING("zzzzz"));
+ NS_ASSERTION(id == eHTMLTag_userdefined, "found zzzzz");
+
+ atom = NS_Atomize("@");
+ id = CaseSensitiveLookupTag(atom);
+ NS_ASSERTION(id == eHTMLTag_userdefined, "found @");
+ atom = NS_Atomize("zzzzz");
+ id = CaseSensitiveLookupTag(atom);
+ NS_ASSERTION(id == eHTMLTag_userdefined, "found zzzzz");
+
+ tag = GetStringValue((nsHTMLTag) 0);
+ NS_ASSERTION(!tag, "found enum 0");
+ tag = GetStringValue((nsHTMLTag) -1);
+ NS_ASSERTION(!tag, "found enum -1");
+ tag = GetStringValue((nsHTMLTag) (NS_HTML_TAG_MAX + 1));
+ NS_ASSERTION(!tag, "found past max enum");
+
+ atom = GetAtom((nsHTMLTag) 0);
+ NS_ASSERTION(!atom, "found enum 0");
+ atom = GetAtom((nsHTMLTag) -1);
+ NS_ASSERTION(!atom, "found enum -1");
+ atom = GetAtom((nsHTMLTag) (NS_HTML_TAG_MAX + 1));
+ NS_ASSERTION(!atom, "found past max enum");
+
+ ReleaseTable();
+}
+
+#endif // DEBUG
diff --git a/parser/htmlparser/nsHTMLTags.h b/parser/htmlparser/nsHTMLTags.h
new file mode 100644
index 000000000..8f0c86b4b
--- /dev/null
+++ b/parser/htmlparser/nsHTMLTags.h
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHTMLTags_h___
+#define nsHTMLTags_h___
+
+#include "nsString.h"
+#include "plhash.h"
+
+class nsIAtom;
+
+/*
+ Declare the enum list using the magic of preprocessing
+ enum values are "eHTMLTag_foo" (where foo is the tag)
+
+ To change the list of tags, see nsHTMLTagList.h
+
+ */
+#define HTML_TAG(_tag, _classname) eHTMLTag_##_tag,
+#define HTML_HTMLELEMENT_TAG(_tag) eHTMLTag_##_tag,
+#define HTML_OTHER(_tag) eHTMLTag_##_tag,
+enum nsHTMLTag {
+ /* this enum must be first and must be zero */
+ eHTMLTag_unknown = 0,
+#include "nsHTMLTagList.h"
+
+ /* can't be moved into nsHTMLTagList since gcc3.4 doesn't like a
+ comma at the end of enum list*/
+ eHTMLTag_userdefined
+};
+#undef HTML_TAG
+#undef HTML_HTMLELEMENT_TAG
+#undef HTML_OTHER
+
+// All tags before eHTMLTag_text are HTML tags
+#define NS_HTML_TAG_MAX int32_t(eHTMLTag_text - 1)
+
+class nsHTMLTags {
+public:
+ static void RegisterAtoms(void);
+ static nsresult AddRefTable(void);
+ static void ReleaseTable(void);
+
+ // Functions for converting string or atom to id
+ static nsHTMLTag LookupTag(const nsAString& aTagName);
+ static nsHTMLTag CaseSensitiveLookupTag(const char16_t* aTagName)
+ {
+ NS_ASSERTION(gTagTable, "no lookup table, needs addref");
+ NS_ASSERTION(aTagName, "null tagname!");
+
+ void* tag = PL_HashTableLookupConst(gTagTable, aTagName);
+
+ return tag ? (nsHTMLTag)NS_PTR_TO_INT32(tag) : eHTMLTag_userdefined;
+ }
+ static nsHTMLTag CaseSensitiveLookupTag(nsIAtom* aTagName)
+ {
+ NS_ASSERTION(gTagAtomTable, "no lookup table, needs addref");
+ NS_ASSERTION(aTagName, "null tagname!");
+
+ void* tag = PL_HashTableLookupConst(gTagAtomTable, aTagName);
+
+ return tag ? (nsHTMLTag)NS_PTR_TO_INT32(tag) : eHTMLTag_userdefined;
+ }
+
+ // Functions for converting an id to a string or atom
+ static const char16_t *GetStringValue(nsHTMLTag aEnum)
+ {
+ return aEnum <= eHTMLTag_unknown || aEnum > NS_HTML_TAG_MAX ?
+ nullptr : sTagUnicodeTable[aEnum - 1];
+ }
+ static nsIAtom *GetAtom(nsHTMLTag aEnum)
+ {
+ return aEnum <= eHTMLTag_unknown || aEnum > NS_HTML_TAG_MAX ?
+ nullptr : sTagAtomTable[aEnum - 1];
+ }
+
+#ifdef DEBUG
+ static void TestTagTable();
+#endif
+
+private:
+ static nsIAtom* sTagAtomTable[eHTMLTag_userdefined - 1];
+ static const char16_t* const sTagUnicodeTable[];
+
+ static int32_t gTableRefCount;
+ static PLHashTable* gTagTable;
+ static PLHashTable* gTagAtomTable;
+};
+
+#define eHTMLTags nsHTMLTag
+
+#endif /* nsHTMLTags_h___ */
diff --git a/parser/htmlparser/nsHTMLTokenizer.cpp b/parser/htmlparser/nsHTMLTokenizer.cpp
new file mode 100644
index 000000000..f60a48c3c
--- /dev/null
+++ b/parser/htmlparser/nsHTMLTokenizer.cpp
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=2 et tw=78: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+/**
+ * @file nsHTMLTokenizer.cpp
+ * This is an implementation of the nsITokenizer interface.
+ * This file contains the implementation of a tokenizer to tokenize an HTML
+ * document. It attempts to do so, making tradeoffs between compatibility with
+ * older parsers and the SGML specification. Note that most of the real
+ * "tokenization" takes place in nsHTMLTokens.cpp.
+ */
+
+#include "nsHTMLTokenizer.h"
+#include "nsIParser.h"
+#include "nsParserConstants.h"
+
+/************************************************************************
+ And now for the main class -- nsHTMLTokenizer...
+ ************************************************************************/
+
+/**
+ * Satisfy the nsISupports interface.
+ */
+NS_IMPL_ISUPPORTS(nsHTMLTokenizer, nsITokenizer)
+
+/**
+ * Default constructor
+ */
+nsHTMLTokenizer::nsHTMLTokenizer()
+{
+ // TODO Assert about:blank-ness.
+}
+
+nsresult
+nsHTMLTokenizer::WillTokenize(bool aIsFinalChunk)
+{
+ return NS_OK;
+}
+
+/**
+ * This method is repeatedly called by the tokenizer.
+ * Each time, we determine the kind of token we're about to
+ * read, and then we call the appropriate method to handle
+ * that token type.
+ *
+ * @param aScanner The source of our input.
+ * @param aFlushTokens An OUT parameter to tell the caller whether it should
+ * process our queued tokens up to now (e.g., when we
+ * reach a <script>).
+ * @return Success or error
+ */
+nsresult
+nsHTMLTokenizer::ConsumeToken(nsScanner& aScanner, bool& aFlushTokens)
+{
+ return kEOF;
+}
diff --git a/parser/htmlparser/nsHTMLTokenizer.h b/parser/htmlparser/nsHTMLTokenizer.h
new file mode 100644
index 000000000..0d2940c5e
--- /dev/null
+++ b/parser/htmlparser/nsHTMLTokenizer.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+/**
+ * MODULE NOTES:
+ * @update gess 4/1/98
+ *
+ */
+
+#ifndef __NSHTMLTOKENIZER
+#define __NSHTMLTOKENIZER
+
+#include "mozilla/Attributes.h"
+#include "nsISupports.h"
+#include "nsITokenizer.h"
+
+#ifdef _MSC_VER
+#pragma warning( disable : 4275 )
+#endif
+
+class nsHTMLTokenizer final : public nsITokenizer {
+ ~nsHTMLTokenizer() {}
+
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSITOKENIZER
+ nsHTMLTokenizer();
+};
+
+#endif
+
+
diff --git a/parser/htmlparser/nsIContentSink.h b/parser/htmlparser/nsIContentSink.h
new file mode 100644
index 000000000..56c70a1b4
--- /dev/null
+++ b/parser/htmlparser/nsIContentSink.h
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef nsIContentSink_h___
+#define nsIContentSink_h___
+
+/**
+ * MODULE NOTES:
+ * @update gess 4/1/98
+ *
+ * This pure virtual interface is used as the "glue" that connects the parsing
+ * process to the content model construction process.
+ *
+ * The icontentsink interface is a very lightweight wrapper that represents the
+ * content-sink model building process. There is another one that you may care
+ * about more, which is the IHTMLContentSink interface. (See that file for details).
+ */
+#include "nsISupports.h"
+#include "nsString.h"
+#include "mozFlushType.h"
+#include "nsIDTD.h"
+
+class nsParserBase;
+
+#define NS_ICONTENT_SINK_IID \
+{ 0xcf9a7cbb, 0xfcbc, 0x4e13, \
+ { 0x8e, 0xf5, 0x18, 0xef, 0x2d, 0x3d, 0x58, 0x29 } }
+
+class nsIContentSink : public nsISupports {
+public:
+
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENT_SINK_IID)
+
+ /**
+ * This method is called by the parser when it is entered from
+ * the event loop. The content sink wants to know how long the
+ * parser has been active since we last processed events on the
+ * main event loop and this call calibrates that measurement.
+ */
+ NS_IMETHOD WillParse(void)=0;
+
+ /**
+ * This method gets called when the parser begins the process
+ * of building the content model via the content sink.
+ *
+ * Default implementation provided since the sink should have the option of
+ * doing nothing in response to this call.
+ *
+ * @update 5/7/98 gess
+ */
+ NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) {
+ return NS_OK;
+ }
+
+ /**
+ * This method gets called when the parser concludes the process
+ * of building the content model via the content sink.
+ *
+ * Default implementation provided since the sink should have the option of
+ * doing nothing in response to this call.
+ *
+ * @update 5/7/98 gess
+ */
+ NS_IMETHOD DidBuildModel(bool aTerminated) {
+ return NS_OK;
+ }
+
+ /**
+ * This method gets called when the parser gets i/o blocked,
+ * and wants to notify the sink that it may be a while before
+ * more data is available.
+ *
+ * @update 5/7/98 gess
+ */
+ NS_IMETHOD WillInterrupt(void)=0;
+
+ /**
+ * This method gets called when the parser i/o gets unblocked,
+ * and we're about to start dumping content again to the sink.
+ *
+ * @update 5/7/98 gess
+ */
+ NS_IMETHOD WillResume(void)=0;
+
+ /**
+ * This method gets called by the parser so that the content
+ * sink can retain a reference to the parser. The expectation
+ * is that the content sink will drop the reference when it
+ * gets the DidBuildModel notification i.e. when parsing is done.
+ */
+ NS_IMETHOD SetParser(nsParserBase* aParser)=0;
+
+ /**
+ * Flush content so that the content model is in sync with the state
+ * of the sink.
+ *
+ * @param aType the type of flush to perform
+ */
+ virtual void FlushPendingNotifications(mozFlushType aType)=0;
+
+ /**
+ * Set the document character set. This should be passed on to the
+ * document itself.
+ */
+ NS_IMETHOD SetDocumentCharset(nsACString& aCharset)=0;
+
+ /**
+ * Returns the target object (often a document object) into which
+ * the content built by this content sink is being added, if any
+ * (IOW, may return null).
+ */
+ virtual nsISupports *GetTarget()=0;
+
+ /**
+ * Returns true if there's currently script executing that we need to hold
+ * parsing for.
+ */
+ virtual bool IsScriptExecuting()
+ {
+ return false;
+ }
+
+ /**
+ * Posts a runnable that continues parsing.
+ */
+ virtual void ContinueInterruptedParsingAsync() {}
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentSink, NS_ICONTENT_SINK_IID)
+
+#endif /* nsIContentSink_h___ */
diff --git a/parser/htmlparser/nsIDTD.h b/parser/htmlparser/nsIDTD.h
new file mode 100644
index 000000000..cbae4d507
--- /dev/null
+++ b/parser/htmlparser/nsIDTD.h
@@ -0,0 +1,136 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsIDTD_h___
+#define nsIDTD_h___
+
+/**
+ * MODULE NOTES:
+ * @update gess 7/20/98
+ *
+ * This interface defines standard interface for DTD's. Note that this
+ * isn't HTML specific. DTD's have several functions within the parser
+ * system:
+ * 1) To coordinate the consumption of an input stream via the
+ * parser
+ * 2) To serve as proxy to represent the containment rules of the
+ * underlying document
+ * 3) To offer autodetection services to the parser (mainly for doc
+ * conversion)
+ * */
+
+#include "nsISupports.h"
+#include "nsString.h"
+#include "nsITokenizer.h"
+
+#define NS_IDTD_IID \
+{ 0x3de05873, 0xefa7, 0x410d, \
+ { 0xa4, 0x61, 0x80, 0x33, 0xaf, 0xd9, 0xe3, 0x26 } }
+
+enum eAutoDetectResult {
+ eUnknownDetect,
+ eValidDetect,
+ ePrimaryDetect,
+ eInvalidDetect
+};
+
+enum nsDTDMode {
+ eDTDMode_unknown = 0,
+ eDTDMode_quirks, //pre 4.0 versions
+ eDTDMode_almost_standards,
+ eDTDMode_full_standards,
+ eDTDMode_autodetect,
+ eDTDMode_fragment
+};
+
+
+class nsIContentSink;
+class CParserContext;
+
+class nsIDTD : public nsISupports
+{
+public:
+
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDTD_IID)
+
+ NS_IMETHOD WillBuildModel(const CParserContext& aParserContext,
+ nsITokenizer* aTokenizer,
+ nsIContentSink* aSink) = 0;
+
+ /**
+ * Called by the parser after the parsing process has concluded
+ * @update gess5/18/98
+ * @param anErrorCode - contains error code resulting from parse process
+ * @return
+ */
+ NS_IMETHOD DidBuildModel(nsresult anErrorCode) = 0;
+
+ /**
+ * Called (possibly repeatedly) by the parser to parse tokens and construct
+ * the document model via the sink provided to WillBuildModel.
+ *
+ * @param aTokenizer - tokenizer providing the token stream to be parsed
+ * @param aCountLines - informs the DTD whether to count newlines
+ * (not wanted, e.g., when handling document.write)
+ * @param aCharsetPtr - address of an nsCString containing the charset
+ * that the DTD should use (pointer in case the DTD
+ * opts to ignore this parameter)
+ */
+ NS_IMETHOD BuildModel(nsITokenizer* aTokenizer, nsIContentSink* aSink) = 0;
+
+ /**
+ * This method is called to determine whether or not a tag of one
+ * type can contain a tag of another type.
+ *
+ * @update gess 3/25/98
+ * @param aParent -- int tag of parent container
+ * @param aChild -- int tag of child container
+ * @return true if parent can contain child
+ */
+ NS_IMETHOD_(bool) CanContain(int32_t aParent,int32_t aChild) const = 0;
+
+ /**
+ * This method gets called to determine whether a given
+ * tag is itself a container
+ *
+ * @update gess 3/25/98
+ * @param aTag -- tag to test for containership
+ * @return true if given tag can contain other tags
+ */
+ NS_IMETHOD_(bool) IsContainer(int32_t aTag) const = 0;
+
+ /**
+ * Use this id you want to stop the building content model
+ * --------------[ Sets DTD to STOP mode ]----------------
+ * It's recommended to use this method in accordance with
+ * the parser's terminate() method.
+ *
+ * @update harishd 07/22/99
+ * @param
+ * @return
+ */
+ NS_IMETHOD_(void) Terminate() = 0;
+
+ NS_IMETHOD_(int32_t) GetType() = 0;
+
+ /**
+ * Call this method after calling WillBuildModel to determine what mode the
+ * DTD actually is using, as it may differ from aParserContext.mDTDMode.
+ */
+ NS_IMETHOD_(nsDTDMode) GetMode() const = 0;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsIDTD, NS_IDTD_IID)
+
+#define NS_DECL_NSIDTD \
+ NS_IMETHOD WillBuildModel( const CParserContext& aParserContext, nsITokenizer* aTokenizer, nsIContentSink* aSink) override;\
+ NS_IMETHOD DidBuildModel(nsresult anErrorCode) override;\
+ NS_IMETHOD BuildModel(nsITokenizer* aTokenizer, nsIContentSink* aSink) override;\
+ NS_IMETHOD_(bool) CanContain(int32_t aParent,int32_t aChild) const override;\
+ NS_IMETHOD_(bool) IsContainer(int32_t aTag) const override;\
+ NS_IMETHOD_(void) Terminate() override;\
+ NS_IMETHOD_(int32_t) GetType() override;\
+ NS_IMETHOD_(nsDTDMode) GetMode() const override;
+#endif /* nsIDTD_h___ */
diff --git a/parser/htmlparser/nsIExpatSink.idl b/parser/htmlparser/nsIExpatSink.idl
new file mode 100644
index 000000000..df0b2d869
--- /dev/null
+++ b/parser/htmlparser/nsIExpatSink.idl
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+interface nsIScriptError;
+
+/**
+ * This interface should be implemented by any content sink that wants
+ * to get output from expat and do something with it; in other words,
+ * by any sink that handles some sort of XML dialect.
+ */
+
+[scriptable, uuid(01f681af-0f22-4725-a914-0d396114daf0)]
+interface nsIExpatSink : nsISupports
+{
+ /**
+ * Called to handle the opening tag of an element.
+ * @param aName the fully qualified tagname of the element
+ * @param aAtts the array of attribute names and values. There are
+ * aAttsCount/2 names and aAttsCount/2 values, so the total number of
+ * elements in the array is aAttsCount. The names and values
+ * alternate. Thus, if we number attributes starting with 0,
+ * aAtts[2*k] is the name of the k-th attribute and aAtts[2*k+1] is
+ * the value of that attribute Both explicitly specified attributes
+ * and attributes that are defined to have default values in a DTD are
+ * present in aAtts.
+ * @param aAttsCount the number of elements in aAtts.
+ * @param aLineNumber the line number of the start tag in the data stream.
+ */
+ void HandleStartElement(in wstring aName,
+ [array, size_is(aAttsCount)] in wstring aAtts,
+ in unsigned long aAttsCount,
+ in unsigned long aLineNumber);
+
+ /**
+ * Called to handle the closing tag of an element.
+ * @param aName the fully qualified tagname of the element
+ */
+ void HandleEndElement(in wstring aName);
+
+ /**
+ * Called to handle a comment
+ * @param aCommentText the text of the comment (not including the
+ * "<!--" and "-->")
+ */
+ void HandleComment(in wstring aCommentText);
+
+ /**
+ * Called to handle a CDATA section
+ * @param aData the text in the CDATA section. This is null-terminated.
+ * @param aLength the length of the aData string
+ */
+ void HandleCDataSection([size_is(aLength)] in wstring aData,
+ in unsigned long aLength);
+
+ /**
+ * Called to handle the doctype declaration
+ */
+ void HandleDoctypeDecl(in AString aSubset,
+ in AString aName,
+ in AString aSystemId,
+ in AString aPublicId,
+ in nsISupports aCatalogData);
+
+ /**
+ * Called to handle character data. Note that this does NOT get
+ * called for the contents of CDATA sections.
+ * @param aData the data to handle. aData is NOT NULL-TERMINATED.
+ * @param aLength the length of the aData string
+ */
+ void HandleCharacterData([size_is(aLength)] in wstring aData,
+ in unsigned long aLength);
+
+ /**
+ * Called to handle a processing instruction
+ * @param aTarget the PI target (e.g. xml-stylesheet)
+ * @param aData all the rest of the data in the PI
+ */
+ void HandleProcessingInstruction(in wstring aTarget,
+ in wstring aData);
+
+ /**
+ * Handle the XML Declaration.
+ *
+ * @param aVersion The version string, can be null if not specified.
+ * @param aEncoding The encoding string, can be null if not specified.
+ * @param aStandalone -1, 0, or 1 indicating respectively that there was no
+ * standalone parameter in the declaration, that it was
+ * given as no, or that it was given as yes.
+ */
+ void HandleXMLDeclaration(in wstring aVersion,
+ in wstring aEncoding,
+ in long aStandalone);
+
+ /**
+ * Ask the content sink if the expat driver should log an error to the console.
+ *
+ * @param aErrorText Error message to pass to content sink.
+ * @param aSourceText Source text of the document we're parsing.
+ * @param aError Script error object with line number & column number
+ *
+ * @retval True if the expat driver should report the error.
+ */
+ boolean ReportError(in wstring aErrorText,
+ in wstring aSourceText,
+ in nsIScriptError aError);
+};
diff --git a/parser/htmlparser/nsIExtendedExpatSink.idl b/parser/htmlparser/nsIExtendedExpatSink.idl
new file mode 100644
index 000000000..d88f0d974
--- /dev/null
+++ b/parser/htmlparser/nsIExtendedExpatSink.idl
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIExpatSink.idl"
+
+/**
+ * This interface provides notification of syntax-level events.
+ */
+[scriptable, uuid(5e3e4f0c-7b77-47ca-a7c5-a3d87f2a9c82)]
+interface nsIExtendedExpatSink : nsIExpatSink
+{
+ /**
+ * Called at the beginning of the DTD, before any entity or notation
+ * events.
+ * @param aDoctypeName The document type name.
+ * @param aSysid The declared system identifier for the external DTD subset,
+ * or null if none was declared.
+ * @param aPubid The declared public identifier for the external DTD subset,
+ * or null if none was declared.
+ */
+ void handleStartDTD(in wstring aDoctypeName,
+ in wstring aSysid,
+ in wstring aPubid);
+
+ /**
+ * Called when a prefix mapping starts to be in-scope, before any
+ * startElement events.
+ * @param aPrefix The Namespace prefix being declared. An empty string
+ * is used for the default element namespace, which has
+ * no prefix.
+ * @param aUri The Namespace URI the prefix is mapped to.
+ */
+ void handleStartNamespaceDecl(in wstring aPrefix,
+ in wstring aUri);
+
+ /**
+ * Called when a prefix mapping is no longer in-scope, after any
+ * endElement events.
+ * @param aPrefix The prefix that was being mapped. This is the empty string
+ * when a default mapping scope ends.
+ */
+ void handleEndNamespaceDecl(in wstring aPrefix);
+
+ /**
+ * This is called for a declaration of notation. The base argument is
+ * whatever was set by XML_SetBase. aNotationName will never be
+ * null. The other arguments can be.
+ * @param aNotationName The notation name.
+ * @param aSysId The notation's system identifier, or null if none was given.
+ * @param aPubId The notation's pubilc identifier, or null if none was given.
+ */
+ void handleNotationDecl(in wstring aNotationName,
+ in wstring aSysid,
+ in wstring aPubid);
+
+ /**
+ * This is called for a declaration of an unparsed (NDATA) entity.
+ * aName, aSysid and aNotationName arguments will never be
+ * null. The other arguments may be.
+ * @param aName The unparsed entity's name.
+ * @param aSysId The notation's system identifier.
+ * @param aPubId The notation's pubilc identifier, or null if none was given.
+ * @param aNotationName The name of the associated notation.
+ */
+ void handleUnparsedEntityDecl(in wstring aName,
+ in wstring aSysid,
+ in wstring aPubid,
+ in wstring aNotationName);
+
+};
diff --git a/parser/htmlparser/nsIFragmentContentSink.h b/parser/htmlparser/nsIFragmentContentSink.h
new file mode 100644
index 000000000..8d547ed66
--- /dev/null
+++ b/parser/htmlparser/nsIFragmentContentSink.h
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef nsIFragmentContentSink_h___
+#define nsIFragmentContentSink_h___
+
+#include "nsISupports.h"
+
+class nsIDOMDocumentFragment;
+class nsIDocument;
+
+#define NS_I_FRAGMENT_CONTENT_SINK_IID \
+ { 0x1a8ce30b, 0x63fc, 0x441a, \
+ { 0xa3, 0xaa, 0xf7, 0x16, 0xc0, 0xfe, 0x96, 0x69 } }
+
+/**
+ * The fragment sink allows a client to parse a fragment of sink, possibly
+ * surrounded in context. Also see nsIParser::ParseFragment().
+ * Note: once you've parsed a fragment, the fragment sink must be re-set on
+ * the parser in order to parse another fragment.
+ */
+class nsIFragmentContentSink : public nsISupports {
+public:
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_I_FRAGMENT_CONTENT_SINK_IID)
+ /**
+ * This method is used to obtain the fragment created by
+ * a fragment content sink and to release resources held by the parser.
+ *
+ * The sink drops its reference to the fragment.
+ */
+ NS_IMETHOD FinishFragmentParsing(nsIDOMDocumentFragment** aFragment) = 0;
+
+ /**
+ * This method is used to set the target document for this fragment
+ * sink. This document's nodeinfo manager will be used to create
+ * the content objects. This MUST be called before the sink is used.
+ *
+ * @param aDocument the document the new nodes will belong to
+ * (should not be null)
+ */
+ NS_IMETHOD SetTargetDocument(nsIDocument* aDocument) = 0;
+
+ /**
+ * This method is used to indicate to the sink that we're done building
+ * the context and should start paying attention to the incoming content
+ */
+ NS_IMETHOD WillBuildContent() = 0;
+
+ /**
+ * This method is used to indicate to the sink that we're done building
+ * The real content. This is useful if you want to parse additional context
+ * (such as an end context).
+ */
+ NS_IMETHOD DidBuildContent() = 0;
+
+ /**
+ * This method is a total hack to help with parsing fragments. It is called to
+ * tell the fragment sink that a container from the context will be delivered
+ * after the call to WillBuildContent(). This is only relevent for HTML
+ * fragments that use nsHTMLTokenizer/CNavDTD.
+ */
+ NS_IMETHOD IgnoreFirstContainer() = 0;
+
+ /**
+ * Sets whether scripts elements are marked as unexecutable.
+ */
+ NS_IMETHOD SetPreventScriptExecution(bool aPreventScriptExecution) = 0;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsIFragmentContentSink,
+ NS_I_FRAGMENT_CONTENT_SINK_IID)
+
+nsresult
+NS_NewXMLFragmentContentSink(nsIFragmentContentSink** aInstancePtrResult);
+
+#endif
diff --git a/parser/htmlparser/nsIHTMLContentSink.h b/parser/htmlparser/nsIHTMLContentSink.h
new file mode 100644
index 000000000..bf08c4b5e
--- /dev/null
+++ b/parser/htmlparser/nsIHTMLContentSink.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef nsIHTMLContentSink_h___
+#define nsIHTMLContentSink_h___
+
+/**
+ * This interface is OBSOLETE and in the process of being REMOVED.
+ * Do NOT implement!
+ *
+ * This file declares the concrete HTMLContentSink class.
+ * This class is used during the parsing process as the
+ * primary interface between the parser and the content
+ * model.
+ *
+ * After the tokenizer completes, the parser iterates over
+ * the known token list. As the parser identifies valid
+ * elements, it calls the contentsink interface to notify
+ * the content model that a new node or child node is being
+ * created and added to the content model.
+ *
+ * The HTMLContentSink interface assumes 4 underlying
+ * containers: HTML, HEAD, BODY and FRAMESET. Before
+ * accessing any these, the parser will call the appropriate
+ * OpennsIHTMLContentSink method: OpenHTML,OpenHead,OpenBody,OpenFrameSet;
+ * likewise, the ClosensIHTMLContentSink version will be called when the
+ * parser is done with a given section.
+ *
+ * IMPORTANT: The parser may Open each container more than
+ * once! This is due to the irregular nature of HTML files.
+ * For example, it is possible to encounter plain text at
+ * the start of an HTML document (that precedes the HTML tag).
+ * Such text is treated as if it were part of the body.
+ * In such cases, the parser will Open the body, pass the text-
+ * node in and then Close the body. The body will likely be
+ * re-Opened later when the actual <BODY> tag has been seen.
+ *
+ * Containers within the body are Opened and Closed
+ * using the OpenContainer(...) and CloseContainer(...) calls.
+ * It is assumed that the document or contentSink is
+ * maintaining its state to manage where new content should
+ * be added to the underlying document.
+ *
+ * NOTE: OpenHTML() and OpenBody() may get called multiple times
+ * in the same document. That's fine, and it doesn't mean
+ * that we have multiple bodies or HTML's.
+ *
+ * NOTE: I haven't figured out how sub-documents (non-frames)
+ * are going to be handled. Stay tuned.
+ */
+#include "nsIContentSink.h"
+#include "nsHTMLTags.h"
+
+#define NS_IHTML_CONTENT_SINK_IID \
+ {0xefc5af86, 0x5cfd, 0x4918, {0x9d, 0xd3, 0x5f, 0x7a, 0xb2, 0x88, 0xb2, 0x68}}
+
+/**
+ * This interface is OBSOLETE and in the process of being REMOVED.
+ * Do NOT implement!
+ */
+class nsIHTMLContentSink : public nsIContentSink
+{
+public:
+
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_IHTML_CONTENT_SINK_IID)
+
+ enum ElementType { eHTML, eBody };
+
+ /**
+ * This method is used to open a generic container in the sink.
+ *
+ * @update 4/1/98 gess
+ */
+ NS_IMETHOD OpenContainer(ElementType aNodeType) = 0;
+
+ /**
+ * This method gets called by the parser when a close
+ * container tag has been consumed and needs to be closed.
+ *
+ * @param aTag - The tag to be closed.
+ */
+ NS_IMETHOD CloseContainer(ElementType aTag) = 0;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsIHTMLContentSink, NS_IHTML_CONTENT_SINK_IID)
+
+#endif /* nsIHTMLContentSink_h___ */
+
diff --git a/parser/htmlparser/nsIParser.h b/parser/htmlparser/nsIParser.h
new file mode 100644
index 000000000..31666cadb
--- /dev/null
+++ b/parser/htmlparser/nsIParser.h
@@ -0,0 +1,273 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=2 sw=2 et tw=78: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef NS_IPARSER___
+#define NS_IPARSER___
+
+
+ /**
+ * This GECKO-INTERNAL interface is on track to being REMOVED (or refactored
+ * to the point of being near-unrecognizable).
+ *
+ * Please DO NOT #include this file in comm-central code, in your XULRunner
+ * app or binary extensions.
+ *
+ * Please DO NOT #include this into new files even inside Gecko. It is more
+ * likely than not that #including this header is the wrong thing to do.
+ */
+
+#include "nsISupports.h"
+#include "nsIStreamListener.h"
+#include "nsIDTD.h"
+#include "nsString.h"
+#include "nsTArray.h"
+#include "nsIAtom.h"
+#include "nsParserBase.h"
+
+#define NS_IPARSER_IID \
+{ 0x2c4ad90a, 0x740e, 0x4212, \
+ { 0xba, 0x3f, 0xfe, 0xac, 0xda, 0x4b, 0x92, 0x9e } }
+
+// {41421C60-310A-11d4-816F-000064657374}
+#define NS_IDEBUG_DUMP_CONTENT_IID \
+{ 0x41421c60, 0x310a, 0x11d4, \
+{ 0x81, 0x6f, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
+
+class nsIContentSink;
+class nsIRequestObserver;
+class nsString;
+class nsIURI;
+class nsIChannel;
+class nsIContent;
+
+enum eParserCommands {
+ eViewNormal,
+ eViewSource,
+ eViewFragment,
+ eViewErrors
+};
+
+enum eParserDocType {
+ ePlainText = 0,
+ eXML,
+ eHTML_Quirks,
+ eHTML_Strict
+};
+
+enum eStreamState {eNone,eOnStart,eOnDataAvail,eOnStop};
+
+/**
+ * This GECKO-INTERNAL interface is on track to being REMOVED (or refactored
+ * to the point of being near-unrecognizable).
+ *
+ * Please DO NOT #include this file in comm-central code, in your XULRunner
+ * app or binary extensions.
+ *
+ * Please DO NOT #include this into new files even inside Gecko. It is more
+ * likely than not that #including this header is the wrong thing to do.
+ */
+class nsIParser : public nsParserBase {
+ public:
+
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPARSER_IID)
+
+ /**
+ * Select given content sink into parser for parser output
+ * @update gess5/11/98
+ * @param aSink is the new sink to be used by parser
+ * @return
+ */
+ NS_IMETHOD_(void) SetContentSink(nsIContentSink* aSink)=0;
+
+
+ /**
+ * retrieve the sink set into the parser
+ * @update gess5/11/98
+ * @return current sink
+ */
+ NS_IMETHOD_(nsIContentSink*) GetContentSink(void)=0;
+
+ /**
+ * Call this method once you've created a parser, and want to instruct it
+ * about the command which caused the parser to be constructed. For example,
+ * this allows us to select a DTD which can do, say, view-source.
+ *
+ * @update gess 3/25/98
+ * @param aCommand -- ptrs to string that contains command
+ * @return nada
+ */
+ NS_IMETHOD_(void) GetCommand(nsCString& aCommand)=0;
+ NS_IMETHOD_(void) SetCommand(const char* aCommand)=0;
+ NS_IMETHOD_(void) SetCommand(eParserCommands aParserCommand)=0;
+
+ /**
+ * Call this method once you've created a parser, and want to instruct it
+ * about what charset to load
+ *
+ * @update ftang 4/23/99
+ * @param aCharset- the charest of a document
+ * @param aCharsetSource- the soure of the chares
+ * @return nada
+ */
+ NS_IMETHOD_(void) SetDocumentCharset(const nsACString& aCharset, int32_t aSource)=0;
+ NS_IMETHOD_(void) GetDocumentCharset(nsACString& oCharset, int32_t& oSource)=0;
+
+ /**
+ * Get the channel associated with this parser
+ * @update harishd,gagan 07/17/01
+ * @param aChannel out param that will contain the result
+ * @return NS_OK if successful
+ */
+ NS_IMETHOD GetChannel(nsIChannel** aChannel) override = 0;
+
+ /**
+ * Get the DTD associated with this parser
+ * @update vidur 9/29/99
+ * @param aDTD out param that will contain the result
+ * @return NS_OK if successful, NS_ERROR_FAILURE for runtime error
+ */
+ NS_IMETHOD GetDTD(nsIDTD** aDTD) = 0;
+
+ /**
+ * Get the nsIStreamListener for this parser
+ */
+ virtual nsIStreamListener* GetStreamListener() = 0;
+
+ /**************************************************************************
+ * Parse methods always begin with an input source, and perform
+ * conversions until you wind up being emitted to the given contentsink
+ * (which may or may not be a proxy for the NGLayout content model).
+ ************************************************************************/
+
+ // Call this method to resume the parser from an unblocked state.
+ // This can happen, for example, if parsing was interrupted and then the
+ // consumer needed to restart the parser without waiting for more data.
+ // This also happens after loading scripts, which unblock the parser in
+ // order to process the output of document.write() and then need to
+ // continue on with the page load on an enabled parser.
+ NS_IMETHOD ContinueInterruptedParsing() = 0;
+
+ // Stops parsing temporarily.
+ NS_IMETHOD_(void) BlockParser() = 0;
+
+ // Open up the parser for tokenization, building up content
+ // model..etc. However, this method does not resume parsing
+ // automatically. It's the callers' responsibility to restart
+ // the parsing engine.
+ NS_IMETHOD_(void) UnblockParser() = 0;
+
+ /**
+ * Asynchronously continues parsing.
+ */
+ NS_IMETHOD_(void) ContinueInterruptedParsingAsync() = 0;
+
+ NS_IMETHOD_(bool) IsParserEnabled() override = 0;
+ NS_IMETHOD_(bool) IsComplete() = 0;
+
+ NS_IMETHOD Parse(nsIURI* aURL,
+ nsIRequestObserver* aListener = nullptr,
+ void* aKey = 0,
+ nsDTDMode aMode = eDTDMode_autodetect) = 0;
+
+ NS_IMETHOD Terminate(void) = 0;
+
+ /**
+ * This method gets called when you want to parse a fragment of HTML or XML
+ * surrounded by the context |aTagStack|. It requires that the parser have
+ * been given a fragment content sink.
+ *
+ * @param aSourceBuffer The XML or HTML that hasn't been parsed yet.
+ * @param aTagStack The context of the source buffer.
+ * @return Success or failure.
+ */
+ NS_IMETHOD ParseFragment(const nsAString& aSourceBuffer,
+ nsTArray<nsString>& aTagStack) = 0;
+
+ /**
+ * This method gets called when the tokens have been consumed, and it's time
+ * to build the model via the content sink.
+ * @update gess5/11/98
+ * @return error code -- 0 if model building went well .
+ */
+ NS_IMETHOD BuildModel(void) = 0;
+
+ /**
+ * Call this method to cancel any pending parsing events.
+ * Parsing events may be pending if all of the document's content
+ * has been passed to the parser but the parser has been interrupted
+ * because processing the tokens took too long.
+ *
+ * @update kmcclusk 05/18/01
+ * @return NS_OK if succeeded else ERROR.
+ */
+
+ NS_IMETHOD CancelParsingEvents() = 0;
+
+ virtual void Reset() = 0;
+
+ /**
+ * True if the insertion point (per HTML5) is defined.
+ */
+ virtual bool IsInsertionPointDefined() = 0;
+
+ /**
+ * Call immediately before starting to evaluate a parser-inserted script or
+ * in general when the spec says to define an insertion point.
+ */
+ virtual void PushDefinedInsertionPoint() = 0;
+
+ /**
+ * Call immediately after having evaluated a parser-inserted script or
+ * generally want to restore to the state before the last
+ * PushDefinedInsertionPoint call.
+ */
+ virtual void PopDefinedInsertionPoint() = 0;
+
+ /**
+ * Marks the HTML5 parser as not a script-created parser.
+ */
+ virtual void MarkAsNotScriptCreated(const char* aCommand) = 0;
+
+ /**
+ * True if this is a script-created HTML5 parser.
+ */
+ virtual bool IsScriptCreated() = 0;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsIParser, NS_IPARSER_IID)
+
+/* ===========================================================*
+ Some useful constants...
+ * ===========================================================*/
+
+#include "nsError.h"
+
+const nsresult kEOF = NS_ERROR_HTMLPARSER_EOF;
+const nsresult kUnknownError = NS_ERROR_HTMLPARSER_UNKNOWN;
+const nsresult kCantPropagate = NS_ERROR_HTMLPARSER_CANTPROPAGATE;
+const nsresult kContextMismatch = NS_ERROR_HTMLPARSER_CONTEXTMISMATCH;
+const nsresult kBadFilename = NS_ERROR_HTMLPARSER_BADFILENAME;
+const nsresult kBadURL = NS_ERROR_HTMLPARSER_BADURL;
+const nsresult kInvalidParserContext = NS_ERROR_HTMLPARSER_INVALIDPARSERCONTEXT;
+const nsresult kBlocked = NS_ERROR_HTMLPARSER_BLOCK;
+const nsresult kBadStringLiteral = NS_ERROR_HTMLPARSER_UNTERMINATEDSTRINGLITERAL;
+const nsresult kHierarchyTooDeep = NS_ERROR_HTMLPARSER_HIERARCHYTOODEEP;
+const nsresult kFakeEndTag = NS_ERROR_HTMLPARSER_FAKE_ENDTAG;
+const nsresult kNotAComment = NS_ERROR_HTMLPARSER_INVALID_COMMENT;
+
+#define NS_IPARSER_FLAG_UNKNOWN_MODE 0x00000000
+#define NS_IPARSER_FLAG_QUIRKS_MODE 0x00000002
+#define NS_IPARSER_FLAG_STRICT_MODE 0x00000004
+#define NS_IPARSER_FLAG_AUTO_DETECT_MODE 0x00000010
+#define NS_IPARSER_FLAG_VIEW_NORMAL 0x00000020
+#define NS_IPARSER_FLAG_VIEW_SOURCE 0x00000040
+#define NS_IPARSER_FLAG_VIEW_ERRORS 0x00000080
+#define NS_IPARSER_FLAG_PLAIN_TEXT 0x00000100
+#define NS_IPARSER_FLAG_XML 0x00000200
+#define NS_IPARSER_FLAG_HTML 0x00000400
+#define NS_IPARSER_FLAG_SCRIPT_ENABLED 0x00000800
+#define NS_IPARSER_FLAG_FRAMES_ENABLED 0x00001000
+
+#endif
diff --git a/parser/htmlparser/nsIParserService.h b/parser/htmlparser/nsIParserService.h
new file mode 100644
index 000000000..2906974e9
--- /dev/null
+++ b/parser/htmlparser/nsIParserService.h
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsIParserService_h__
+#define nsIParserService_h__
+
+#include "nsISupports.h"
+#include "nsString.h"
+#include "nsHTMLTags.h"
+
+class nsIParser;
+
+#define NS_PARSERSERVICE_CONTRACTID "@mozilla.org/parser/parser-service;1"
+
+// {90a92e37-abd6-441b-9b39-4064d98e1ede}
+#define NS_IPARSERSERVICE_IID \
+{ 0x90a92e37, 0xabd6, 0x441b, { 0x9b, 0x39, 0x40, 0x64, 0xd9, 0x8e, 0x1e, 0xde } }
+
+class nsIParserService : public nsISupports {
+ public:
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPARSERSERVICE_IID)
+
+ /**
+ * Looks up the nsHTMLTag enum value corresponding to the tag in aAtom. The
+ * lookup happens case insensitively.
+ *
+ * @param aAtom The tag to look up.
+ *
+ * @return int32_t The nsHTMLTag enum value corresponding to the tag in aAtom
+ * or eHTMLTag_userdefined if the tag does not correspond to
+ * any of the tag nsHTMLTag enum values.
+ */
+ virtual int32_t HTMLAtomTagToId(nsIAtom* aAtom) const = 0;
+
+ /**
+ * Looks up the nsHTMLTag enum value corresponding to the tag in aAtom.
+ *
+ * @param aAtom The tag to look up.
+ *
+ * @return int32_t The nsHTMLTag enum value corresponding to the tag in aAtom
+ * or eHTMLTag_userdefined if the tag does not correspond to
+ * any of the tag nsHTMLTag enum values.
+ */
+ virtual int32_t HTMLCaseSensitiveAtomTagToId(nsIAtom* aAtom) const = 0;
+
+ /**
+ * Looks up the nsHTMLTag enum value corresponding to the tag in aTag. The
+ * lookup happens case insensitively.
+ *
+ * @param aTag The tag to look up.
+ *
+ * @return int32_t The nsHTMLTag enum value corresponding to the tag in aTag
+ * or eHTMLTag_userdefined if the tag does not correspond to
+ * any of the tag nsHTMLTag enum values.
+ */
+ virtual int32_t HTMLStringTagToId(const nsAString& aTag) const = 0;
+
+ /**
+ * Gets the tag corresponding to the nsHTMLTag enum value in aId. The
+ * returned tag will be in lowercase.
+ *
+ * @param aId The nsHTMLTag enum value to get the tag for.
+ *
+ * @return const char16_t* The tag corresponding to the nsHTMLTag enum
+ * value, or nullptr if the enum value doesn't
+ * correspond to a tag (eHTMLTag_unknown,
+ * eHTMLTag_userdefined, eHTMLTag_text, ...).
+ */
+ virtual const char16_t *HTMLIdToStringTag(int32_t aId) const = 0;
+
+ /**
+ * Gets the tag corresponding to the nsHTMLTag enum value in aId. The
+ * returned tag will be in lowercase.
+ *
+ * @param aId The nsHTMLTag enum value to get the tag for.
+ *
+ * @return nsIAtom* The tag corresponding to the nsHTMLTag enum value, or
+ * nullptr if the enum value doesn't correspond to a tag
+ * (eHTMLTag_unknown, eHTMLTag_userdefined, eHTMLTag_text,
+ * ...).
+ */
+ virtual nsIAtom *HTMLIdToAtomTag(int32_t aId) const = 0;
+
+ NS_IMETHOD HTMLConvertEntityToUnicode(const nsAString& aEntity,
+ int32_t* aUnicode) const = 0;
+
+ NS_IMETHOD HTMLConvertUnicodeToEntity(int32_t aUnicode,
+ nsCString& aEntity) const = 0;
+
+ NS_IMETHOD IsContainer(int32_t aId, bool& aIsContainer) const = 0;
+ NS_IMETHOD IsBlock(int32_t aId, bool& aIsBlock) const = 0;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsIParserService, NS_IPARSERSERVICE_IID)
+
+#endif // nsIParserService_h__
diff --git a/parser/htmlparser/nsITokenizer.h b/parser/htmlparser/nsITokenizer.h
new file mode 100644
index 000000000..2ed09d410
--- /dev/null
+++ b/parser/htmlparser/nsITokenizer.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+/**
+ * MODULE NOTES:
+ * @update gess 4/1/98
+ *
+ */
+
+#ifndef __NSITOKENIZER__
+#define __NSITOKENIZER__
+
+#include "nsISupports.h"
+
+class nsScanner;
+
+#define NS_ITOKENIZER_IID \
+{ 0Xae98a348, 0X5e91, 0X41a8, \
+ { 0Xa5, 0Xb4, 0Xd2, 0X20, 0Xf3, 0X1f, 0Xc4, 0Xab } }
+
+/***************************************************************
+ Notes:
+ ***************************************************************/
+
+
+class nsITokenizer : public nsISupports {
+public:
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_ITOKENIZER_IID)
+
+ NS_IMETHOD WillTokenize(bool aIsFinalChunk)=0;
+ NS_IMETHOD ConsumeToken(nsScanner& aScanner,bool& aFlushTokens)=0;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsITokenizer, NS_ITOKENIZER_IID)
+
+#define NS_DECL_NSITOKENIZER \
+ NS_IMETHOD WillTokenize(bool aIsFinalChunk) override;\
+ NS_IMETHOD ConsumeToken(nsScanner& aScanner,bool& aFlushTokens) override;\
+
+
+#endif
diff --git a/parser/htmlparser/nsParser.cpp b/parser/htmlparser/nsParser.cpp
new file mode 100644
index 000000000..dd140c553
--- /dev/null
+++ b/parser/htmlparser/nsParser.cpp
@@ -0,0 +1,1600 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=2 et tw=79: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIAtom.h"
+#include "nsParser.h"
+#include "nsString.h"
+#include "nsCRT.h"
+#include "nsScanner.h"
+#include "plstr.h"
+#include "nsIStringStream.h"
+#include "nsIChannel.h"
+#include "nsICachingChannel.h"
+#include "nsIInputStream.h"
+#include "CNavDTD.h"
+#include "prenv.h"
+#include "prlock.h"
+#include "prcvar.h"
+#include "nsParserCIID.h"
+#include "nsReadableUtils.h"
+#include "nsCOMPtr.h"
+#include "nsExpatDriver.h"
+#include "nsIServiceManager.h"
+#include "nsICategoryManager.h"
+#include "nsISupportsPrimitives.h"
+#include "nsIFragmentContentSink.h"
+#include "nsStreamUtils.h"
+#include "nsHTMLTokenizer.h"
+#include "nsScriptLoader.h"
+#include "nsDataHashtable.h"
+#include "nsXPCOMCIDInternal.h"
+#include "nsMimeTypes.h"
+#include "mozilla/CondVar.h"
+#include "mozilla/Mutex.h"
+#include "nsParserConstants.h"
+#include "nsCharsetSource.h"
+#include "nsContentUtils.h"
+#include "nsThreadUtils.h"
+#include "nsIHTMLContentSink.h"
+
+#include "mozilla/dom/EncodingUtils.h"
+#include "mozilla/BinarySearch.h"
+
+using namespace mozilla;
+using mozilla::dom::EncodingUtils;
+
+#define NS_PARSER_FLAG_PARSER_ENABLED 0x00000002
+#define NS_PARSER_FLAG_OBSERVERS_ENABLED 0x00000004
+#define NS_PARSER_FLAG_PENDING_CONTINUE_EVENT 0x00000008
+#define NS_PARSER_FLAG_FLUSH_TOKENS 0x00000020
+#define NS_PARSER_FLAG_CAN_TOKENIZE 0x00000040
+
+//-------------- Begin ParseContinue Event Definition ------------------------
+/*
+The parser can be explicitly interrupted by passing a return value of
+NS_ERROR_HTMLPARSER_INTERRUPTED from BuildModel on the DTD. This will cause
+the parser to stop processing and allow the application to return to the event
+loop. The data which was left at the time of interruption will be processed
+the next time OnDataAvailable is called. If the parser has received its final
+chunk of data then OnDataAvailable will no longer be called by the networking
+module, so the parser will schedule a nsParserContinueEvent which will call
+the parser to process the remaining data after returning to the event loop.
+If the parser is interrupted while processing the remaining data it will
+schedule another ParseContinueEvent. The processing of data followed by
+scheduling of the continue events will proceed until either:
+
+ 1) All of the remaining data can be processed without interrupting
+ 2) The parser has been cancelled.
+
+
+This capability is currently used in CNavDTD and nsHTMLContentSink. The
+nsHTMLContentSink is notified by CNavDTD when a chunk of tokens is going to be
+processed and when each token is processed. The nsHTML content sink records
+the time when the chunk has started processing and will return
+NS_ERROR_HTMLPARSER_INTERRUPTED if the token processing time has exceeded a
+threshold called max tokenizing processing time. This allows the content sink
+to limit how much data is processed in a single chunk which in turn gates how
+much time is spent away from the event loop. Processing smaller chunks of data
+also reduces the time spent in subsequent reflows.
+
+This capability is most apparent when loading large documents. If the maximum
+token processing time is set small enough the application will remain
+responsive during document load.
+
+A side-effect of this capability is that document load is not complete when
+the last chunk of data is passed to OnDataAvailable since the parser may have
+been interrupted when the last chunk of data arrived. The document is complete
+when all of the document has been tokenized and there aren't any pending
+nsParserContinueEvents. This can cause problems if the application assumes
+that it can monitor the load requests to determine when the document load has
+been completed. This is what happens in Mozilla. The document is considered
+completely loaded when all of the load requests have been satisfied. To delay
+the document load until all of the parsing has been completed the
+nsHTMLContentSink adds a dummy parser load request which is not removed until
+the nsHTMLContentSink's DidBuildModel is called. The CNavDTD will not call
+DidBuildModel until the final chunk of data has been passed to the parser
+through the OnDataAvailable and there aren't any pending
+nsParserContineEvents.
+
+Currently the parser is ignores requests to be interrupted during the
+processing of script. This is because a document.write followed by JavaScript
+calls to manipulate the DOM may fail if the parser was interrupted during the
+document.write.
+
+For more details @see bugzilla bug 76722
+*/
+
+
+class nsParserContinueEvent : public Runnable
+{
+public:
+ RefPtr<nsParser> mParser;
+
+ explicit nsParserContinueEvent(nsParser* aParser)
+ : mParser(aParser)
+ {}
+
+ NS_IMETHOD Run() override
+ {
+ mParser->HandleParserContinueEvent(this);
+ return NS_OK;
+ }
+};
+
+//-------------- End ParseContinue Event Definition ------------------------
+
+/**
+ * default constructor
+ */
+nsParser::nsParser()
+{
+ Initialize(true);
+}
+
+nsParser::~nsParser()
+{
+ Cleanup();
+}
+
+void
+nsParser::Initialize(bool aConstructor)
+{
+ if (aConstructor) {
+ // Raw pointer
+ mParserContext = 0;
+ }
+ else {
+ // nsCOMPtrs
+ mObserver = nullptr;
+ mUnusedInput.Truncate();
+ }
+
+ mContinueEvent = nullptr;
+ mCharsetSource = kCharsetUninitialized;
+ mCharset.AssignLiteral("ISO-8859-1");
+ mInternalState = NS_OK;
+ mStreamStatus = NS_OK;
+ mCommand = eViewNormal;
+ mFlags = NS_PARSER_FLAG_OBSERVERS_ENABLED |
+ NS_PARSER_FLAG_PARSER_ENABLED |
+ NS_PARSER_FLAG_CAN_TOKENIZE;
+
+ mProcessingNetworkData = false;
+ mIsAboutBlank = false;
+}
+
+void
+nsParser::Cleanup()
+{
+#ifdef DEBUG
+ if (mParserContext && mParserContext->mPrevContext) {
+ NS_WARNING("Extra parser contexts still on the parser stack");
+ }
+#endif
+
+ while (mParserContext) {
+ CParserContext *pc = mParserContext->mPrevContext;
+ delete mParserContext;
+ mParserContext = pc;
+ }
+
+ // It should not be possible for this flag to be set when we are getting
+ // destroyed since this flag implies a pending nsParserContinueEvent, which
+ // has an owning reference to |this|.
+ NS_ASSERTION(!(mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT), "bad");
+}
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsParser)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsParser)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mDTD)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mSink)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mObserver)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsParser)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDTD)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSink)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObserver)
+ CParserContext *pc = tmp->mParserContext;
+ while (pc) {
+ cb.NoteXPCOMChild(pc->mTokenizer);
+ pc = pc->mPrevContext;
+ }
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsParser)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsParser)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsParser)
+ NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
+ NS_INTERFACE_MAP_ENTRY(nsIParser)
+ NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
+ NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIParser)
+NS_INTERFACE_MAP_END
+
+// The parser continue event is posted only if
+// all of the data to parse has been passed to ::OnDataAvailable
+// and the parser has been interrupted by the content sink
+// because the processing of tokens took too long.
+
+nsresult
+nsParser::PostContinueEvent()
+{
+ if (!(mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT)) {
+ // If this flag isn't set, then there shouldn't be a live continue event!
+ NS_ASSERTION(!mContinueEvent, "bad");
+
+ // This creates a reference cycle between this and the event that is
+ // broken when the event fires.
+ nsCOMPtr<nsIRunnable> event = new nsParserContinueEvent(this);
+ if (NS_FAILED(NS_DispatchToCurrentThread(event))) {
+ NS_WARNING("failed to dispatch parser continuation event");
+ } else {
+ mFlags |= NS_PARSER_FLAG_PENDING_CONTINUE_EVENT;
+ mContinueEvent = event;
+ }
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP_(void)
+nsParser::GetCommand(nsCString& aCommand)
+{
+ aCommand = mCommandStr;
+}
+
+/**
+ * Call this method once you've created a parser, and want to instruct it
+ * about the command which caused the parser to be constructed. For example,
+ * this allows us to select a DTD which can do, say, view-source.
+ *
+ * @param aCommand the command string to set
+ */
+NS_IMETHODIMP_(void)
+nsParser::SetCommand(const char* aCommand)
+{
+ mCommandStr.Assign(aCommand);
+ if (mCommandStr.EqualsLiteral("view-source")) {
+ mCommand = eViewSource;
+ } else if (mCommandStr.EqualsLiteral("view-fragment")) {
+ mCommand = eViewFragment;
+ } else {
+ mCommand = eViewNormal;
+ }
+}
+
+/**
+ * Call this method once you've created a parser, and want to instruct it
+ * about the command which caused the parser to be constructed. For example,
+ * this allows us to select a DTD which can do, say, view-source.
+ *
+ * @param aParserCommand the command to set
+ */
+NS_IMETHODIMP_(void)
+nsParser::SetCommand(eParserCommands aParserCommand)
+{
+ mCommand = aParserCommand;
+}
+
+/**
+ * Call this method once you've created a parser, and want to instruct it
+ * about what charset to load
+ *
+ * @param aCharset- the charset of a document
+ * @param aCharsetSource- the source of the charset
+ */
+NS_IMETHODIMP_(void)
+nsParser::SetDocumentCharset(const nsACString& aCharset, int32_t aCharsetSource)
+{
+ mCharset = aCharset;
+ mCharsetSource = aCharsetSource;
+ if (mParserContext && mParserContext->mScanner) {
+ mParserContext->mScanner->SetDocumentCharset(aCharset, aCharsetSource);
+ }
+}
+
+void
+nsParser::SetSinkCharset(nsACString& aCharset)
+{
+ if (mSink) {
+ mSink->SetDocumentCharset(aCharset);
+ }
+}
+
+/**
+ * This method gets called in order to set the content
+ * sink for this parser to dump nodes to.
+ *
+ * @param nsIContentSink interface for node receiver
+ */
+NS_IMETHODIMP_(void)
+nsParser::SetContentSink(nsIContentSink* aSink)
+{
+ NS_PRECONDITION(aSink, "sink cannot be null!");
+ mSink = aSink;
+
+ if (mSink) {
+ mSink->SetParser(this);
+ nsCOMPtr<nsIHTMLContentSink> htmlSink = do_QueryInterface(mSink);
+ if (htmlSink) {
+ mIsAboutBlank = true;
+ }
+ }
+}
+
+/**
+ * retrieve the sink set into the parser
+ * @return current sink
+ */
+NS_IMETHODIMP_(nsIContentSink*)
+nsParser::GetContentSink()
+{
+ return mSink;
+}
+
+static nsIDTD*
+FindSuitableDTD(CParserContext& aParserContext)
+{
+ // We always find a DTD.
+ aParserContext.mAutoDetectStatus = ePrimaryDetect;
+
+ // Quick check for view source.
+ MOZ_ASSERT(aParserContext.mParserCommand != eViewSource,
+ "The old parser is not supposed to be used for View Source "
+ "anymore.");
+
+ // Now see if we're parsing HTML (which, as far as we're concerned, simply
+ // means "not XML").
+ if (aParserContext.mDocType != eXML) {
+ return new CNavDTD();
+ }
+
+ // If we're here, then we'd better be parsing XML.
+ NS_ASSERTION(aParserContext.mDocType == eXML, "What are you trying to send me, here?");
+ return new nsExpatDriver();
+}
+
+NS_IMETHODIMP
+nsParser::CancelParsingEvents()
+{
+ if (mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT) {
+ NS_ASSERTION(mContinueEvent, "mContinueEvent is null");
+ // Revoke the pending continue parsing event
+ mContinueEvent = nullptr;
+ mFlags &= ~NS_PARSER_FLAG_PENDING_CONTINUE_EVENT;
+ }
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+/**
+ * Evalutes EXPR1 and EXPR2 exactly once each, in that order. Stores the value
+ * of EXPR2 in RV is EXPR2 fails, otherwise RV contains the result of EXPR1
+ * (which could be success or failure).
+ *
+ * To understand the motivation for this construct, consider these example
+ * methods:
+ *
+ * nsresult nsSomething::DoThatThing(nsIWhatever* obj) {
+ * nsresult rv = NS_OK;
+ * ...
+ * return obj->DoThatThing();
+ * NS_ENSURE_SUCCESS(rv, rv);
+ * ...
+ * return rv;
+ * }
+ *
+ * void nsCaller::MakeThingsHappen() {
+ * return mSomething->DoThatThing(mWhatever);
+ * }
+ *
+ * Suppose, for whatever reason*, we want to shift responsibility for calling
+ * mWhatever->DoThatThing() from nsSomething::DoThatThing up to
+ * nsCaller::MakeThingsHappen. We might rewrite the two methods as follows:
+ *
+ * nsresult nsSomething::DoThatThing() {
+ * nsresult rv = NS_OK;
+ * ...
+ * ...
+ * return rv;
+ * }
+ *
+ * void nsCaller::MakeThingsHappen() {
+ * nsresult rv;
+ * PREFER_LATTER_ERROR_CODE(mSomething->DoThatThing(),
+ * mWhatever->DoThatThing(),
+ * rv);
+ * return rv;
+ * }
+ *
+ * *Possible reasons include: nsCaller doesn't want to give mSomething access
+ * to mWhatever, nsCaller wants to guarantee that mWhatever->DoThatThing() will
+ * be called regardless of how nsSomething::DoThatThing behaves, &c.
+ */
+#define PREFER_LATTER_ERROR_CODE(EXPR1, EXPR2, RV) { \
+ nsresult RV##__temp = EXPR1; \
+ RV = EXPR2; \
+ if (NS_FAILED(RV)) { \
+ RV = RV##__temp; \
+ } \
+}
+
+/**
+ * This gets called just prior to the model actually
+ * being constructed. It's important to make this the
+ * last thing that happens right before parsing, so we
+ * can delay until the last moment the resolution of
+ * which DTD to use (unless of course we're assigned one).
+ */
+nsresult
+nsParser::WillBuildModel(nsString& aFilename)
+{
+ if (!mParserContext)
+ return kInvalidParserContext;
+
+ if (eUnknownDetect != mParserContext->mAutoDetectStatus)
+ return NS_OK;
+
+ if (eDTDMode_unknown == mParserContext->mDTDMode ||
+ eDTDMode_autodetect == mParserContext->mDTDMode) {
+ if (mIsAboutBlank) {
+ mParserContext->mDTDMode = eDTDMode_quirks;
+ mParserContext->mDocType = eHTML_Quirks;
+ } else {
+ mParserContext->mDTDMode = eDTDMode_full_standards;
+ mParserContext->mDocType = eXML;
+ }
+ } // else XML fragment with nested parser context
+
+ NS_ASSERTION(!mDTD || !mParserContext->mPrevContext,
+ "Clobbering DTD for non-root parser context!");
+ mDTD = FindSuitableDTD(*mParserContext);
+ NS_ENSURE_TRUE(mDTD, NS_ERROR_OUT_OF_MEMORY);
+
+ nsITokenizer* tokenizer;
+ nsresult rv = mParserContext->GetTokenizer(mDTD, mSink, tokenizer);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = mDTD->WillBuildModel(*mParserContext, tokenizer, mSink);
+ nsresult sinkResult = mSink->WillBuildModel(mDTD->GetMode());
+ // nsIDTD::WillBuildModel used to be responsible for calling
+ // nsIContentSink::WillBuildModel, but that obligation isn't expressible
+ // in the nsIDTD interface itself, so it's sounder and simpler to give that
+ // responsibility back to the parser. The former behavior of the DTD was to
+ // NS_ENSURE_SUCCESS the sink WillBuildModel call, so if the sink returns
+ // failure we should use sinkResult instead of rv, to preserve the old error
+ // handling behavior of the DTD:
+ return NS_FAILED(sinkResult) ? sinkResult : rv;
+}
+
+/**
+ * This gets called when the parser is done with its input.
+ * Note that the parser may have been called recursively, so we
+ * have to check for a prev. context before closing out the DTD/sink.
+ */
+nsresult
+nsParser::DidBuildModel(nsresult anErrorCode)
+{
+ nsresult result = anErrorCode;
+
+ if (IsComplete()) {
+ if (mParserContext && !mParserContext->mPrevContext) {
+ // Let sink know if we're about to end load because we've been terminated.
+ // In that case we don't want it to run deferred scripts.
+ bool terminated = mInternalState == NS_ERROR_HTMLPARSER_STOPPARSING;
+ if (mDTD && mSink) {
+ nsresult dtdResult = mDTD->DidBuildModel(anErrorCode),
+ sinkResult = mSink->DidBuildModel(terminated);
+ // nsIDTD::DidBuildModel used to be responsible for calling
+ // nsIContentSink::DidBuildModel, but that obligation isn't expressible
+ // in the nsIDTD interface itself, so it's sounder and simpler to give
+ // that responsibility back to the parser. The former behavior of the
+ // DTD was to NS_ENSURE_SUCCESS the sink DidBuildModel call, so if the
+ // sink returns failure we should use sinkResult instead of dtdResult,
+ // to preserve the old error handling behavior of the DTD:
+ result = NS_FAILED(sinkResult) ? sinkResult : dtdResult;
+ }
+
+ //Ref. to bug 61462.
+ mParserContext->mRequest = nullptr;
+ }
+ }
+
+ return result;
+}
+
+/**
+ * This method adds a new parser context to the list,
+ * pushing the current one to the next position.
+ *
+ * @param ptr to new context
+ */
+void
+nsParser::PushContext(CParserContext& aContext)
+{
+ NS_ASSERTION(aContext.mPrevContext == mParserContext,
+ "Trying to push a context whose previous context differs from "
+ "the current parser context.");
+ mParserContext = &aContext;
+}
+
+/**
+ * This method pops the topmost context off the stack,
+ * returning it to the user. The next context (if any)
+ * becomes the current context.
+ * @update gess7/22/98
+ * @return prev. context
+ */
+CParserContext*
+nsParser::PopContext()
+{
+ CParserContext* oldContext = mParserContext;
+ if (oldContext) {
+ mParserContext = oldContext->mPrevContext;
+ if (mParserContext) {
+ // If the old context was blocked, propagate the blocked state
+ // back to the new one. Also, propagate the stream listener state
+ // but don't override onStop state to guarantee the call to DidBuildModel().
+ if (mParserContext->mStreamListenerState != eOnStop) {
+ mParserContext->mStreamListenerState = oldContext->mStreamListenerState;
+ }
+ }
+ }
+ return oldContext;
+}
+
+/**
+ * Call this when you want control whether or not the parser will parse
+ * and tokenize input (TRUE), or whether it just caches input to be
+ * parsed later (FALSE).
+ *
+ * @param aState determines whether we parse/tokenize or just cache.
+ * @return current state
+ */
+void
+nsParser::SetUnusedInput(nsString& aBuffer)
+{
+ mUnusedInput = aBuffer;
+}
+
+/**
+ * Call this when you want to *force* the parser to terminate the
+ * parsing process altogether. This is binary -- so once you terminate
+ * you can't resume without restarting altogether.
+ */
+NS_IMETHODIMP
+nsParser::Terminate(void)
+{
+ // We should only call DidBuildModel once, so don't do anything if this is
+ // the second time that Terminate has been called.
+ if (mInternalState == NS_ERROR_HTMLPARSER_STOPPARSING) {
+ return NS_OK;
+ }
+
+ nsresult result = NS_OK;
+ // XXX - [ until we figure out a way to break parser-sink circularity ]
+ // Hack - Hold a reference until we are completely done...
+ nsCOMPtr<nsIParser> kungFuDeathGrip(this);
+ mInternalState = result = NS_ERROR_HTMLPARSER_STOPPARSING;
+
+ // CancelParsingEvents must be called to avoid leaking the nsParser object
+ // @see bug 108049
+ // If NS_PARSER_FLAG_PENDING_CONTINUE_EVENT is set then CancelParsingEvents
+ // will reset it so DidBuildModel will call DidBuildModel on the DTD. Note:
+ // The IsComplete() call inside of DidBuildModel looks at the pendingContinueEvents flag.
+ CancelParsingEvents();
+
+ // If we got interrupted in the middle of a document.write, then we might
+ // have more than one parser context on our parsercontext stack. This has
+ // the effect of making DidBuildModel a no-op, meaning that we never call
+ // our sink's DidBuildModel and break the reference cycle, causing a leak.
+ // Since we're getting terminated, we manually clean up our context stack.
+ while (mParserContext && mParserContext->mPrevContext) {
+ CParserContext *prev = mParserContext->mPrevContext;
+ delete mParserContext;
+ mParserContext = prev;
+ }
+
+ if (mDTD) {
+ mDTD->Terminate();
+ DidBuildModel(result);
+ } else if (mSink) {
+ // We have no parser context or no DTD yet (so we got terminated before we
+ // got any data). Manually break the reference cycle with the sink.
+ result = mSink->DidBuildModel(true);
+ NS_ENSURE_SUCCESS(result, result);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsParser::ContinueInterruptedParsing()
+{
+ // If there are scripts executing, then the content sink is jumping the gun
+ // (probably due to a synchronous XMLHttpRequest) and will re-enable us
+ // later, see bug 460706.
+ if (!IsOkToProcessNetworkData()) {
+ return NS_OK;
+ }
+
+ // If the stream has already finished, there's a good chance
+ // that we might start closing things down when the parser
+ // is reenabled. To make sure that we're not deleted across
+ // the reenabling process, hold a reference to ourselves.
+ nsresult result=NS_OK;
+ nsCOMPtr<nsIParser> kungFuDeathGrip(this);
+ nsCOMPtr<nsIContentSink> sinkDeathGrip(mSink);
+
+#ifdef DEBUG
+ if (!(mFlags & NS_PARSER_FLAG_PARSER_ENABLED)) {
+ NS_WARNING("Don't call ContinueInterruptedParsing on a blocked parser.");
+ }
+#endif
+
+ bool isFinalChunk = mParserContext &&
+ mParserContext->mStreamListenerState == eOnStop;
+
+ mProcessingNetworkData = true;
+ if (sinkDeathGrip) {
+ sinkDeathGrip->WillParse();
+ }
+ result = ResumeParse(true, isFinalChunk); // Ref. bug 57999
+ mProcessingNetworkData = false;
+
+ if (result != NS_OK) {
+ result=mInternalState;
+ }
+
+ return result;
+}
+
+/**
+ * Stops parsing temporarily. That's it will prevent the
+ * parser from building up content model.
+ */
+NS_IMETHODIMP_(void)
+nsParser::BlockParser()
+{
+ mFlags &= ~NS_PARSER_FLAG_PARSER_ENABLED;
+}
+
+/**
+ * Open up the parser for tokenization, building up content
+ * model..etc. However, this method does not resume parsing
+ * automatically. It's the callers' responsibility to restart
+ * the parsing engine.
+ */
+NS_IMETHODIMP_(void)
+nsParser::UnblockParser()
+{
+ if (!(mFlags & NS_PARSER_FLAG_PARSER_ENABLED)) {
+ mFlags |= NS_PARSER_FLAG_PARSER_ENABLED;
+ } else {
+ NS_WARNING("Trying to unblock an unblocked parser.");
+ }
+}
+
+NS_IMETHODIMP_(void)
+nsParser::ContinueInterruptedParsingAsync()
+{
+ mSink->ContinueInterruptedParsingAsync();
+}
+
+/**
+ * Call this to query whether the parser is enabled or not.
+ */
+NS_IMETHODIMP_(bool)
+nsParser::IsParserEnabled()
+{
+ return (mFlags & NS_PARSER_FLAG_PARSER_ENABLED) != 0;
+}
+
+/**
+ * Call this to query whether the parser thinks it's done with parsing.
+ */
+NS_IMETHODIMP_(bool)
+nsParser::IsComplete()
+{
+ return !(mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT);
+}
+
+
+void nsParser::HandleParserContinueEvent(nsParserContinueEvent *ev)
+{
+ // Ignore any revoked continue events...
+ if (mContinueEvent != ev)
+ return;
+
+ mFlags &= ~NS_PARSER_FLAG_PENDING_CONTINUE_EVENT;
+ mContinueEvent = nullptr;
+
+ NS_ASSERTION(IsOkToProcessNetworkData(),
+ "Interrupted in the middle of a script?");
+ ContinueInterruptedParsing();
+}
+
+bool
+nsParser::IsInsertionPointDefined()
+{
+ return false;
+}
+
+void
+nsParser::PushDefinedInsertionPoint()
+{
+}
+
+void
+nsParser::PopDefinedInsertionPoint()
+{
+}
+
+void
+nsParser::MarkAsNotScriptCreated(const char* aCommand)
+{
+}
+
+bool
+nsParser::IsScriptCreated()
+{
+ return false;
+}
+
+/**
+ * This is the main controlling routine in the parsing process.
+ * Note that it may get called multiple times for the same scanner,
+ * since this is a pushed based system, and all the tokens may
+ * not have been consumed by the scanner during a given invocation
+ * of this method.
+ */
+NS_IMETHODIMP
+nsParser::Parse(nsIURI* aURL,
+ nsIRequestObserver* aListener,
+ void* aKey,
+ nsDTDMode aMode)
+{
+
+ NS_PRECONDITION(aURL, "Error: Null URL given");
+
+ nsresult result=kBadURL;
+ mObserver = aListener;
+
+ if (aURL) {
+ nsAutoCString spec;
+ nsresult rv = aURL->GetSpec(spec);
+ if (rv != NS_OK) {
+ return rv;
+ }
+ NS_ConvertUTF8toUTF16 theName(spec);
+
+ nsScanner* theScanner = new nsScanner(theName, false);
+ CParserContext* pc = new CParserContext(mParserContext, theScanner, aKey,
+ mCommand, aListener);
+ if (pc && theScanner) {
+ pc->mMultipart = true;
+ pc->mContextType = CParserContext::eCTURL;
+ pc->mDTDMode = aMode;
+ PushContext(*pc);
+
+ result = NS_OK;
+ } else {
+ result = mInternalState = NS_ERROR_HTMLPARSER_BADCONTEXT;
+ }
+ }
+ return result;
+}
+
+/**
+ * Used by XML fragment parsing below.
+ *
+ * @param aSourceBuffer contains a string-full of real content
+ */
+nsresult
+nsParser::Parse(const nsAString& aSourceBuffer,
+ void* aKey,
+ bool aLastCall)
+{
+ nsresult result = NS_OK;
+
+ // Don't bother if we're never going to parse this.
+ if (mInternalState == NS_ERROR_HTMLPARSER_STOPPARSING) {
+ return result;
+ }
+
+ if (!aLastCall && aSourceBuffer.IsEmpty()) {
+ // Nothing is being passed to the parser so return
+ // immediately. mUnusedInput will get processed when
+ // some data is actually passed in.
+ // But if this is the last call, make sure to finish up
+ // stuff correctly.
+ return result;
+ }
+
+ // Maintain a reference to ourselves so we don't go away
+ // till we're completely done.
+ nsCOMPtr<nsIParser> kungFuDeathGrip(this);
+
+ if (aLastCall || !aSourceBuffer.IsEmpty() || !mUnusedInput.IsEmpty()) {
+ // Note: The following code will always find the parser context associated
+ // with the given key, even if that context has been suspended (e.g., for
+ // another document.write call). This doesn't appear to be exactly what IE
+ // does in the case where this happens, but this makes more sense.
+ CParserContext* pc = mParserContext;
+ while (pc && pc->mKey != aKey) {
+ pc = pc->mPrevContext;
+ }
+
+ if (!pc) {
+ // Only make a new context if we don't have one, OR if we do, but has a
+ // different context key.
+ nsScanner* theScanner = new nsScanner(mUnusedInput);
+ NS_ENSURE_TRUE(theScanner, NS_ERROR_OUT_OF_MEMORY);
+
+ eAutoDetectResult theStatus = eUnknownDetect;
+
+ if (mParserContext &&
+ mParserContext->mMimeType.EqualsLiteral("application/xml")) {
+ // Ref. Bug 90379
+ NS_ASSERTION(mDTD, "How come the DTD is null?");
+
+ if (mParserContext) {
+ theStatus = mParserContext->mAutoDetectStatus;
+ // Added this to fix bug 32022.
+ }
+ }
+
+ pc = new CParserContext(mParserContext, theScanner, aKey, mCommand,
+ 0, theStatus, aLastCall);
+ NS_ENSURE_TRUE(pc, NS_ERROR_OUT_OF_MEMORY);
+
+ PushContext(*pc);
+
+ pc->mMultipart = !aLastCall; // By default
+ if (pc->mPrevContext) {
+ pc->mMultipart |= pc->mPrevContext->mMultipart;
+ }
+
+ // Start fix bug 40143
+ if (pc->mMultipart) {
+ pc->mStreamListenerState = eOnDataAvail;
+ if (pc->mScanner) {
+ pc->mScanner->SetIncremental(true);
+ }
+ } else {
+ pc->mStreamListenerState = eOnStop;
+ if (pc->mScanner) {
+ pc->mScanner->SetIncremental(false);
+ }
+ }
+ // end fix for 40143
+
+ pc->mContextType=CParserContext::eCTString;
+ pc->SetMimeType(NS_LITERAL_CSTRING("application/xml"));
+ pc->mDTDMode = eDTDMode_full_standards;
+
+ mUnusedInput.Truncate();
+
+ pc->mScanner->Append(aSourceBuffer);
+ // Do not interrupt document.write() - bug 95487
+ result = ResumeParse(false, false, false);
+ } else {
+ pc->mScanner->Append(aSourceBuffer);
+ if (!pc->mPrevContext) {
+ // Set stream listener state to eOnStop, on the final context - Fix 68160,
+ // to guarantee DidBuildModel() call - Fix 36148
+ if (aLastCall) {
+ pc->mStreamListenerState = eOnStop;
+ pc->mScanner->SetIncremental(false);
+ }
+
+ if (pc == mParserContext) {
+ // If pc is not mParserContext, then this call to ResumeParse would
+ // do the wrong thing and try to continue parsing using
+ // mParserContext. We need to wait to actually resume parsing on pc.
+ ResumeParse(false, false, false);
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
+NS_IMETHODIMP
+nsParser::ParseFragment(const nsAString& aSourceBuffer,
+ nsTArray<nsString>& aTagStack)
+{
+ nsresult result = NS_OK;
+ nsAutoString theContext;
+ uint32_t theCount = aTagStack.Length();
+ uint32_t theIndex = 0;
+
+ // Disable observers for fragments
+ mFlags &= ~NS_PARSER_FLAG_OBSERVERS_ENABLED;
+
+ for (theIndex = 0; theIndex < theCount; theIndex++) {
+ theContext.Append('<');
+ theContext.Append(aTagStack[theCount - theIndex - 1]);
+ theContext.Append('>');
+ }
+
+ if (theCount == 0) {
+ // Ensure that the buffer is not empty. Because none of the DTDs care
+ // about leading whitespace, this doesn't change the result.
+ theContext.Assign(' ');
+ }
+
+ // First, parse the context to build up the DTD's tag stack. Note that we
+ // pass false for the aLastCall parameter.
+ result = Parse(theContext,
+ (void*)&theContext,
+ false);
+ if (NS_FAILED(result)) {
+ mFlags |= NS_PARSER_FLAG_OBSERVERS_ENABLED;
+ return result;
+ }
+
+ if (!mSink) {
+ // Parse must have failed in the XML case and so the sink was killed.
+ return NS_ERROR_HTMLPARSER_STOPPARSING;
+ }
+
+ nsCOMPtr<nsIFragmentContentSink> fragSink = do_QueryInterface(mSink);
+ NS_ASSERTION(fragSink, "ParseFragment requires a fragment content sink");
+
+ fragSink->WillBuildContent();
+ // Now, parse the actual content. Note that this is the last call
+ // for HTML content, but for XML, we will want to build and parse
+ // the end tags. However, if tagStack is empty, it's the last call
+ // for XML as well.
+ if (theCount == 0) {
+ result = Parse(aSourceBuffer,
+ &theContext,
+ true);
+ fragSink->DidBuildContent();
+ } else {
+ // Add an end tag chunk, so expat will read the whole source buffer,
+ // and not worry about ']]' etc.
+ result = Parse(aSourceBuffer + NS_LITERAL_STRING("</"),
+ &theContext,
+ false);
+ fragSink->DidBuildContent();
+
+ if (NS_SUCCEEDED(result)) {
+ nsAutoString endContext;
+ for (theIndex = 0; theIndex < theCount; theIndex++) {
+ // we already added an end tag chunk above
+ if (theIndex > 0) {
+ endContext.AppendLiteral("</");
+ }
+
+ nsString& thisTag = aTagStack[theIndex];
+ // was there an xmlns=?
+ int32_t endOfTag = thisTag.FindChar(char16_t(' '));
+ if (endOfTag == -1) {
+ endContext.Append(thisTag);
+ } else {
+ endContext.Append(Substring(thisTag,0,endOfTag));
+ }
+
+ endContext.Append('>');
+ }
+
+ result = Parse(endContext,
+ &theContext,
+ true);
+ }
+ }
+
+ mFlags |= NS_PARSER_FLAG_OBSERVERS_ENABLED;
+
+ return result;
+}
+
+/**
+ * This routine is called to cause the parser to continue parsing its
+ * underlying stream. This call allows the parse process to happen in
+ * chunks, such as when the content is push based, and we need to parse in
+ * pieces.
+ *
+ * An interesting change in how the parser gets used has led us to add extra
+ * processing to this method. The case occurs when the parser is blocked in
+ * one context, and gets a parse(string) call in another context. In this
+ * case, the parserContexts are linked. No problem.
+ *
+ * The problem is that Parse(string) assumes that it can proceed unabated,
+ * but if the parser is already blocked that assumption is false. So we
+ * needed to add a mechanism here to allow the parser to continue to process
+ * (the pop and free) contexts until 1) it get's blocked again; 2) it runs
+ * out of contexts.
+ *
+ *
+ * @param allowItertion : set to true if non-script resumption is requested
+ * @param aIsFinalChunk : tells us when the last chunk of data is provided.
+ * @return error code -- 0 if ok, non-zero if error.
+ */
+nsresult
+nsParser::ResumeParse(bool allowIteration, bool aIsFinalChunk,
+ bool aCanInterrupt)
+{
+ nsresult result = NS_OK;
+
+ if ((mFlags & NS_PARSER_FLAG_PARSER_ENABLED) &&
+ mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) {
+
+ result = WillBuildModel(mParserContext->mScanner->GetFilename());
+ if (NS_FAILED(result)) {
+ mFlags &= ~NS_PARSER_FLAG_CAN_TOKENIZE;
+ return result;
+ }
+
+ if (mDTD) {
+ mSink->WillResume();
+ bool theIterationIsOk = true;
+
+ while (result == NS_OK && theIterationIsOk) {
+ if (!mUnusedInput.IsEmpty() && mParserContext->mScanner) {
+ // -- Ref: Bug# 22485 --
+ // Insert the unused input into the source buffer
+ // as if it was read from the input stream.
+ // Adding UngetReadable() per vidur!!
+ mParserContext->mScanner->UngetReadable(mUnusedInput);
+ mUnusedInput.Truncate(0);
+ }
+
+ // Only allow parsing to be interrupted in the subsequent call to
+ // build model.
+ nsresult theTokenizerResult = (mFlags & NS_PARSER_FLAG_CAN_TOKENIZE)
+ ? Tokenize(aIsFinalChunk)
+ : NS_OK;
+ result = BuildModel();
+
+ if (result == NS_ERROR_HTMLPARSER_INTERRUPTED && aIsFinalChunk) {
+ PostContinueEvent();
+ }
+
+ theIterationIsOk = theTokenizerResult != kEOF &&
+ result != NS_ERROR_HTMLPARSER_INTERRUPTED;
+
+ // Make sure not to stop parsing too early. Therefore, before shutting
+ // down the parser, it's important to check whether the input buffer
+ // has been scanned to completion (theTokenizerResult should be kEOF).
+ // kEOF -> End of buffer.
+
+ // If we're told to block the parser, we disable all further parsing
+ // (and cache any data coming in) until the parser is re-enabled.
+ if (NS_ERROR_HTMLPARSER_BLOCK == result) {
+ mSink->WillInterrupt();
+ if (mFlags & NS_PARSER_FLAG_PARSER_ENABLED) {
+ // If we were blocked by a recursive invocation, don't re-block.
+ BlockParser();
+ }
+ return NS_OK;
+ }
+ if (NS_ERROR_HTMLPARSER_STOPPARSING == result) {
+ // Note: Parser Terminate() calls DidBuildModel.
+ if (mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) {
+ DidBuildModel(mStreamStatus);
+ mInternalState = result;
+ }
+
+ return NS_OK;
+ }
+ if ((NS_OK == result && theTokenizerResult == kEOF) ||
+ result == NS_ERROR_HTMLPARSER_INTERRUPTED) {
+ bool theContextIsStringBased =
+ CParserContext::eCTString == mParserContext->mContextType;
+
+ if (mParserContext->mStreamListenerState == eOnStop ||
+ !mParserContext->mMultipart || theContextIsStringBased) {
+ if (!mParserContext->mPrevContext) {
+ if (mParserContext->mStreamListenerState == eOnStop) {
+ DidBuildModel(mStreamStatus);
+ return NS_OK;
+ }
+ } else {
+ CParserContext* theContext = PopContext();
+ if (theContext) {
+ theIterationIsOk = allowIteration && theContextIsStringBased;
+ if (theContext->mCopyUnused) {
+ if (!theContext->mScanner->CopyUnusedData(mUnusedInput)) {
+ mInternalState = NS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ delete theContext;
+ }
+
+ result = mInternalState;
+ aIsFinalChunk = mParserContext &&
+ mParserContext->mStreamListenerState == eOnStop;
+ // ...then intentionally fall through to mSink->WillInterrupt()...
+ }
+ }
+ }
+
+ if (theTokenizerResult == kEOF ||
+ result == NS_ERROR_HTMLPARSER_INTERRUPTED) {
+ result = (result == NS_ERROR_HTMLPARSER_INTERRUPTED) ? NS_OK : result;
+ mSink->WillInterrupt();
+ }
+ }
+ } else {
+ mInternalState = result = NS_ERROR_HTMLPARSER_UNRESOLVEDDTD;
+ }
+ }
+
+ return (result == NS_ERROR_HTMLPARSER_INTERRUPTED) ? NS_OK : result;
+}
+
+/**
+ * This is where we loop over the tokens created in the
+ * tokenization phase, and try to make sense out of them.
+ */
+nsresult
+nsParser::BuildModel()
+{
+ nsITokenizer* theTokenizer = nullptr;
+
+ nsresult result = NS_OK;
+ if (mParserContext) {
+ result = mParserContext->GetTokenizer(mDTD, mSink, theTokenizer);
+ }
+
+ if (NS_SUCCEEDED(result)) {
+ if (mDTD) {
+ result = mDTD->BuildModel(theTokenizer, mSink);
+ }
+ } else {
+ mInternalState = result = NS_ERROR_HTMLPARSER_BADTOKENIZER;
+ }
+ return result;
+}
+
+/*******************************************************************
+ These methods are used to talk to the netlib system...
+ *******************************************************************/
+
+nsresult
+nsParser::OnStartRequest(nsIRequest *request, nsISupports* aContext)
+{
+ NS_PRECONDITION(eNone == mParserContext->mStreamListenerState,
+ "Parser's nsIStreamListener API was not setup "
+ "correctly in constructor.");
+ if (mObserver) {
+ mObserver->OnStartRequest(request, aContext);
+ }
+ mParserContext->mStreamListenerState = eOnStart;
+ mParserContext->mAutoDetectStatus = eUnknownDetect;
+ mParserContext->mRequest = request;
+
+ NS_ASSERTION(!mParserContext->mPrevContext,
+ "Clobbering DTD for non-root parser context!");
+ mDTD = nullptr;
+
+ nsresult rv;
+ nsAutoCString contentType;
+ nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
+ if (channel) {
+ rv = channel->GetContentType(contentType);
+ if (NS_SUCCEEDED(rv)) {
+ mParserContext->SetMimeType(contentType);
+ }
+ }
+
+ rv = NS_OK;
+
+ return rv;
+}
+
+static bool
+ExtractCharsetFromXmlDeclaration(const unsigned char* aBytes, int32_t aLen,
+ nsCString& oCharset)
+{
+ // This code is rather pointless to have. Might as well reuse expat as
+ // seen in nsHtml5StreamParser. -- hsivonen
+ oCharset.Truncate();
+ if ((aLen >= 5) &&
+ ('<' == aBytes[0]) &&
+ ('?' == aBytes[1]) &&
+ ('x' == aBytes[2]) &&
+ ('m' == aBytes[3]) &&
+ ('l' == aBytes[4])) {
+ int32_t i;
+ bool versionFound = false, encodingFound = false;
+ for (i = 6; i < aLen && !encodingFound; ++i) {
+ // end of XML declaration?
+ if ((((char*) aBytes)[i] == '?') &&
+ ((i + 1) < aLen) &&
+ (((char*) aBytes)[i + 1] == '>')) {
+ break;
+ }
+ // Version is required.
+ if (!versionFound) {
+ // Want to avoid string comparisons, hence looking for 'n'
+ // and only if found check the string leading to it. Not
+ // foolproof, but fast.
+ // The shortest string allowed before this is (strlen==13):
+ // <?xml version
+ if ((((char*) aBytes)[i] == 'n') &&
+ (i >= 12) &&
+ (0 == PL_strncmp("versio", (char*) (aBytes + i - 6), 6))) {
+ // Fast forward through version
+ char q = 0;
+ for (++i; i < aLen; ++i) {
+ char qi = ((char*) aBytes)[i];
+ if (qi == '\'' || qi == '"') {
+ if (q && q == qi) {
+ // ending quote
+ versionFound = true;
+ break;
+ } else {
+ // Starting quote
+ q = qi;
+ }
+ }
+ }
+ }
+ } else {
+ // encoding must follow version
+ // Want to avoid string comparisons, hence looking for 'g'
+ // and only if found check the string leading to it. Not
+ // foolproof, but fast.
+ // The shortest allowed string before this (strlen==26):
+ // <?xml version="1" encoding
+ if ((((char*) aBytes)[i] == 'g') && (i >= 25) && (0 == PL_strncmp(
+ "encodin", (char*) (aBytes + i - 7), 7))) {
+ int32_t encStart = 0;
+ char q = 0;
+ for (++i; i < aLen; ++i) {
+ char qi = ((char*) aBytes)[i];
+ if (qi == '\'' || qi == '"') {
+ if (q && q == qi) {
+ int32_t count = i - encStart;
+ // encoding value is invalid if it is UTF-16
+ if (count > 0 && PL_strncasecmp("UTF-16",
+ (char*) (aBytes + encStart), count)) {
+ oCharset.Assign((char*) (aBytes + encStart), count);
+ }
+ encodingFound = true;
+ break;
+ } else {
+ encStart = i + 1;
+ q = qi;
+ }
+ }
+ }
+ }
+ } // if (!versionFound)
+ } // for
+ }
+ return !oCharset.IsEmpty();
+}
+
+inline char
+GetNextChar(nsACString::const_iterator& aStart,
+ nsACString::const_iterator& aEnd)
+{
+ NS_ASSERTION(aStart != aEnd, "end of buffer");
+ return (++aStart != aEnd) ? *aStart : '\0';
+}
+
+static nsresult
+NoOpParserWriteFunc(nsIInputStream* in,
+ void* closure,
+ const char* fromRawSegment,
+ uint32_t toOffset,
+ uint32_t count,
+ uint32_t *writeCount)
+{
+ *writeCount = count;
+ return NS_OK;
+}
+
+typedef struct {
+ bool mNeedCharsetCheck;
+ nsParser* mParser;
+ nsScanner* mScanner;
+ nsIRequest* mRequest;
+} ParserWriteStruct;
+
+/*
+ * This function is invoked as a result of a call to a stream's
+ * ReadSegments() method. It is called for each contiguous buffer
+ * of data in the underlying stream or pipe. Using ReadSegments
+ * allows us to avoid copying data to read out of the stream.
+ */
+static nsresult
+ParserWriteFunc(nsIInputStream* in,
+ void* closure,
+ const char* fromRawSegment,
+ uint32_t toOffset,
+ uint32_t count,
+ uint32_t *writeCount)
+{
+ nsresult result;
+ ParserWriteStruct* pws = static_cast<ParserWriteStruct*>(closure);
+ const unsigned char* buf =
+ reinterpret_cast<const unsigned char*> (fromRawSegment);
+ uint32_t theNumRead = count;
+
+ if (!pws) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (pws->mNeedCharsetCheck) {
+ pws->mNeedCharsetCheck = false;
+ int32_t source;
+ nsAutoCString preferred;
+ nsAutoCString maybePrefer;
+ pws->mParser->GetDocumentCharset(preferred, source);
+
+ // This code was bogus when I found it. It expects the BOM or the XML
+ // declaration to be entirely in the first network buffer. -- hsivonen
+ if (nsContentUtils::CheckForBOM(buf, count, maybePrefer)) {
+ // The decoder will swallow the BOM. The UTF-16 will re-sniff for
+ // endianness. The value of preferred is now either "UTF-8" or "UTF-16".
+ preferred.Assign(maybePrefer);
+ source = kCharsetFromByteOrderMark;
+ } else if (source < kCharsetFromChannel) {
+ nsAutoCString declCharset;
+
+ if (ExtractCharsetFromXmlDeclaration(buf, count, declCharset)) {
+ if (EncodingUtils::FindEncodingForLabel(declCharset, maybePrefer)) {
+ preferred.Assign(maybePrefer);
+ source = kCharsetFromMetaTag;
+ }
+ }
+ }
+
+ pws->mParser->SetDocumentCharset(preferred, source);
+ pws->mParser->SetSinkCharset(preferred);
+
+ }
+
+ result = pws->mScanner->Append(fromRawSegment, theNumRead);
+ if (NS_SUCCEEDED(result)) {
+ *writeCount = count;
+ }
+
+ return result;
+}
+
+nsresult
+nsParser::OnDataAvailable(nsIRequest *request, nsISupports* aContext,
+ nsIInputStream *pIStream, uint64_t sourceOffset,
+ uint32_t aLength)
+{
+ NS_PRECONDITION((eOnStart == mParserContext->mStreamListenerState ||
+ eOnDataAvail == mParserContext->mStreamListenerState),
+ "Error: OnStartRequest() must be called before OnDataAvailable()");
+ NS_PRECONDITION(NS_InputStreamIsBuffered(pIStream),
+ "Must have a buffered input stream");
+
+ nsresult rv = NS_OK;
+
+ if (mIsAboutBlank) {
+ MOZ_ASSERT(false, "Must not get OnDataAvailable for about:blank");
+ // ... but if an extension tries to feed us data for about:blank in a
+ // release build, silently ignore the data.
+ uint32_t totalRead;
+ rv = pIStream->ReadSegments(NoOpParserWriteFunc,
+ nullptr,
+ aLength,
+ &totalRead);
+ return rv;
+ }
+
+ CParserContext *theContext = mParserContext;
+
+ while (theContext && theContext->mRequest != request) {
+ theContext = theContext->mPrevContext;
+ }
+
+ if (theContext) {
+ theContext->mStreamListenerState = eOnDataAvail;
+
+ if (eInvalidDetect == theContext->mAutoDetectStatus) {
+ if (theContext->mScanner) {
+ nsScannerIterator iter;
+ theContext->mScanner->EndReading(iter);
+ theContext->mScanner->SetPosition(iter, true);
+ }
+ }
+
+ uint32_t totalRead;
+ ParserWriteStruct pws;
+ pws.mNeedCharsetCheck = true;
+ pws.mParser = this;
+ pws.mScanner = theContext->mScanner;
+ pws.mRequest = request;
+
+ rv = pIStream->ReadSegments(ParserWriteFunc, &pws, aLength, &totalRead);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ if (IsOkToProcessNetworkData()) {
+ nsCOMPtr<nsIParser> kungFuDeathGrip(this);
+ nsCOMPtr<nsIContentSink> sinkDeathGrip(mSink);
+ mProcessingNetworkData = true;
+ if (sinkDeathGrip) {
+ sinkDeathGrip->WillParse();
+ }
+ rv = ResumeParse();
+ mProcessingNetworkData = false;
+ }
+ } else {
+ rv = NS_ERROR_UNEXPECTED;
+ }
+
+ return rv;
+}
+
+/**
+ * This is called by the networking library once the last block of data
+ * has been collected from the net.
+ */
+nsresult
+nsParser::OnStopRequest(nsIRequest *request, nsISupports* aContext,
+ nsresult status)
+{
+ nsresult rv = NS_OK;
+
+ CParserContext *pc = mParserContext;
+ while (pc) {
+ if (pc->mRequest == request) {
+ pc->mStreamListenerState = eOnStop;
+ pc->mScanner->SetIncremental(false);
+ break;
+ }
+
+ pc = pc->mPrevContext;
+ }
+
+ mStreamStatus = status;
+
+ if (IsOkToProcessNetworkData() && NS_SUCCEEDED(rv)) {
+ mProcessingNetworkData = true;
+ if (mSink) {
+ mSink->WillParse();
+ }
+ rv = ResumeParse(true, true);
+ mProcessingNetworkData = false;
+ }
+
+ // If the parser isn't enabled, we don't finish parsing till
+ // it is reenabled.
+
+
+ // XXX Should we wait to notify our observers as well if the
+ // parser isn't yet enabled?
+ if (mObserver) {
+ mObserver->OnStopRequest(request, aContext, status);
+ }
+
+ return rv;
+}
+
+
+/*******************************************************************
+ Here come the tokenization methods...
+ *******************************************************************/
+
+
+/**
+ * Part of the code sandwich, this gets called right before
+ * the tokenization process begins. The main reason for
+ * this call is to allow the delegate to do initialization.
+ */
+bool
+nsParser::WillTokenize(bool aIsFinalChunk)
+{
+ if (!mParserContext) {
+ return true;
+ }
+
+ nsITokenizer* theTokenizer;
+ nsresult result = mParserContext->GetTokenizer(mDTD, mSink, theTokenizer);
+ NS_ENSURE_SUCCESS(result, false);
+ return NS_SUCCEEDED(theTokenizer->WillTokenize(aIsFinalChunk));
+}
+
+
+/**
+ * This is the primary control routine to consume tokens.
+ * It iteratively consumes tokens until an error occurs or
+ * you run out of data.
+ */
+nsresult nsParser::Tokenize(bool aIsFinalChunk)
+{
+ nsITokenizer* theTokenizer;
+
+ nsresult result = NS_ERROR_NOT_AVAILABLE;
+ if (mParserContext) {
+ result = mParserContext->GetTokenizer(mDTD, mSink, theTokenizer);
+ }
+
+ if (NS_SUCCEEDED(result)) {
+ bool flushTokens = false;
+
+ bool killSink = false;
+
+ WillTokenize(aIsFinalChunk);
+ while (NS_SUCCEEDED(result)) {
+ mParserContext->mScanner->Mark();
+ result = theTokenizer->ConsumeToken(*mParserContext->mScanner,
+ flushTokens);
+ if (NS_FAILED(result)) {
+ mParserContext->mScanner->RewindToMark();
+ if (kEOF == result){
+ break;
+ }
+ if (NS_ERROR_HTMLPARSER_STOPPARSING == result) {
+ killSink = true;
+ result = Terminate();
+ break;
+ }
+ } else if (flushTokens && (mFlags & NS_PARSER_FLAG_OBSERVERS_ENABLED)) {
+ // I added the extra test of NS_PARSER_FLAG_OBSERVERS_ENABLED to fix Bug# 23931.
+ // Flush tokens on seeing </SCRIPT> -- Ref: Bug# 22485 --
+ // Also remember to update the marked position.
+ mFlags |= NS_PARSER_FLAG_FLUSH_TOKENS;
+ mParserContext->mScanner->Mark();
+ break;
+ }
+ }
+
+ if (killSink) {
+ mSink = nullptr;
+ }
+ } else {
+ result = mInternalState = NS_ERROR_HTMLPARSER_BADTOKENIZER;
+ }
+
+ return result;
+}
+
+/**
+ * Get the channel associated with this parser
+ *
+ * @param aChannel out param that will contain the result
+ * @return NS_OK if successful
+ */
+NS_IMETHODIMP
+nsParser::GetChannel(nsIChannel** aChannel)
+{
+ nsresult result = NS_ERROR_NOT_AVAILABLE;
+ if (mParserContext && mParserContext->mRequest) {
+ result = CallQueryInterface(mParserContext->mRequest, aChannel);
+ }
+ return result;
+}
+
+/**
+ * Get the DTD associated with this parser
+ */
+NS_IMETHODIMP
+nsParser::GetDTD(nsIDTD** aDTD)
+{
+ if (mParserContext) {
+ NS_IF_ADDREF(*aDTD = mDTD);
+ }
+
+ return NS_OK;
+}
+
+/**
+ * Get this as nsIStreamListener
+ */
+nsIStreamListener*
+nsParser::GetStreamListener()
+{
+ return this;
+}
diff --git a/parser/htmlparser/nsParser.h b/parser/htmlparser/nsParser.h
new file mode 100644
index 000000000..39bfe03b8
--- /dev/null
+++ b/parser/htmlparser/nsParser.h
@@ -0,0 +1,398 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * MODULE NOTES:
+ *
+ * This class does two primary jobs:
+ * 1) It iterates the tokens provided during the
+ * tokenization process, identifing where elements
+ * begin and end (doing validation and normalization).
+ * 2) It controls and coordinates with an instance of
+ * the IContentSink interface, to coordinate the
+ * the production of the content model.
+ *
+ * The basic operation of this class assumes that an HTML
+ * document is non-normalized. Therefore, we don't process
+ * the document in a normalized way. Don't bother to look
+ * for methods like: doHead() or doBody().
+ *
+ * Instead, in order to be backward compatible, we must
+ * scan the set of tokens and perform this basic set of
+ * operations:
+ * 1) Determine the token type (easy, since the tokens know)
+ * 2) Determine the appropriate section of the HTML document
+ * each token belongs in (HTML,HEAD,BODY,FRAMESET).
+ * 3) Insert content into our document (via the sink) into
+ * the correct section.
+ * 4) In the case of tags that belong in the BODY, we must
+ * ensure that our underlying document state reflects
+ * the appropriate context for our tag.
+ *
+ * For example,if we see a <TR>, we must ensure our
+ * document contains a table into which the row can
+ * be placed. This may result in "implicit containers"
+ * created to ensure a well-formed document.
+ *
+ */
+
+#ifndef NS_PARSER__
+#define NS_PARSER__
+
+#include "nsIParser.h"
+#include "nsDeque.h"
+#include "nsIURL.h"
+#include "CParserContext.h"
+#include "nsParserCIID.h"
+#include "nsITokenizer.h"
+#include "nsHTMLTags.h"
+#include "nsIContentSink.h"
+#include "nsCOMArray.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsWeakReference.h"
+
+class nsIDTD;
+class nsIRunnable;
+
+#ifdef _MSC_VER
+#pragma warning( disable : 4275 )
+#endif
+
+
+class nsParser final : public nsIParser,
+ public nsIStreamListener,
+ public nsSupportsWeakReference
+{
+ /**
+ * Destructor
+ * @update gess5/11/98
+ */
+ virtual ~nsParser();
+
+ public:
+ /**
+ * Called on module init
+ */
+ static nsresult Init();
+
+ /**
+ * Called on module shutdown
+ */
+ static void Shutdown();
+
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsParser, nsIParser)
+
+ /**
+ * default constructor
+ * @update gess5/11/98
+ */
+ nsParser();
+
+ /**
+ * Select given content sink into parser for parser output
+ * @update gess5/11/98
+ * @param aSink is the new sink to be used by parser
+ * @return old sink, or nullptr
+ */
+ NS_IMETHOD_(void) SetContentSink(nsIContentSink* aSink) override;
+
+ /**
+ * retrive the sink set into the parser
+ * @update gess5/11/98
+ * @param aSink is the new sink to be used by parser
+ * @return old sink, or nullptr
+ */
+ NS_IMETHOD_(nsIContentSink*) GetContentSink(void) override;
+
+ /**
+ * Call this method once you've created a parser, and want to instruct it
+ * about the command which caused the parser to be constructed. For example,
+ * this allows us to select a DTD which can do, say, view-source.
+ *
+ * @update gess 3/25/98
+ * @param aCommand -- ptrs to string that contains command
+ * @return nada
+ */
+ NS_IMETHOD_(void) GetCommand(nsCString& aCommand) override;
+ NS_IMETHOD_(void) SetCommand(const char* aCommand) override;
+ NS_IMETHOD_(void) SetCommand(eParserCommands aParserCommand) override;
+
+ /**
+ * Call this method once you've created a parser, and want to instruct it
+ * about what charset to load
+ *
+ * @update ftang 4/23/99
+ * @param aCharset- the charset of a document
+ * @param aCharsetSource- the source of the charset
+ * @return nada
+ */
+ NS_IMETHOD_(void) SetDocumentCharset(const nsACString& aCharset, int32_t aSource) override;
+
+ NS_IMETHOD_(void) GetDocumentCharset(nsACString& aCharset, int32_t& aSource) override
+ {
+ aCharset = mCharset;
+ aSource = mCharsetSource;
+ }
+
+ /**
+ * Cause parser to parse input from given URL
+ * @update gess5/11/98
+ * @param aURL is a descriptor for source document
+ * @param aListener is a listener to forward notifications to
+ * @return TRUE if all went well -- FALSE otherwise
+ */
+ NS_IMETHOD Parse(nsIURI* aURL,
+ nsIRequestObserver* aListener = nullptr,
+ void* aKey = 0,
+ nsDTDMode aMode = eDTDMode_autodetect) override;
+
+ /**
+ * This method needs documentation
+ */
+ NS_IMETHOD ParseFragment(const nsAString& aSourceBuffer,
+ nsTArray<nsString>& aTagStack) override;
+
+ /**
+ * This method gets called when the tokens have been consumed, and it's time
+ * to build the model via the content sink.
+ * @update gess5/11/98
+ * @return YES if model building went well -- NO otherwise.
+ */
+ NS_IMETHOD BuildModel(void) override;
+
+ NS_IMETHOD ContinueInterruptedParsing() override;
+ NS_IMETHOD_(void) BlockParser() override;
+ NS_IMETHOD_(void) UnblockParser() override;
+ NS_IMETHOD_(void) ContinueInterruptedParsingAsync() override;
+ NS_IMETHOD Terminate(void) override;
+
+ /**
+ * Call this to query whether the parser is enabled or not.
+ *
+ * @update vidur 4/12/99
+ * @return current state
+ */
+ NS_IMETHOD_(bool) IsParserEnabled() override;
+
+ /**
+ * Call this to query whether the parser thinks it's done with parsing.
+ *
+ * @update rickg 5/12/01
+ * @return complete state
+ */
+ NS_IMETHOD_(bool) IsComplete() override;
+
+ /**
+ * This rather arcane method (hack) is used as a signal between the
+ * DTD and the parser. It allows the DTD to tell the parser that content
+ * that comes through (parser::parser(string)) but not consumed should
+ * propagate into the next string based parse call.
+ *
+ * @update gess 9/1/98
+ * @param aState determines whether we propagate unused string content.
+ * @return current state
+ */
+ void SetUnusedInput(nsString& aBuffer);
+
+ /**
+ * This method gets called (automatically) during incremental parsing
+ * @update gess5/11/98
+ * @return TRUE if all went well, otherwise FALSE
+ */
+ virtual nsresult ResumeParse(bool allowIteration = true,
+ bool aIsFinalChunk = false,
+ bool aCanInterrupt = true);
+
+ //*********************************************
+ // These methods are callback methods used by
+ // net lib to let us know about our inputstream.
+ //*********************************************
+ // nsIRequestObserver methods:
+ NS_DECL_NSIREQUESTOBSERVER
+
+ // nsIStreamListener methods:
+ NS_DECL_NSISTREAMLISTENER
+
+ void PushContext(CParserContext& aContext);
+ CParserContext* PopContext();
+ CParserContext* PeekContext() {return mParserContext;}
+
+ /**
+ * Get the channel associated with this parser
+ * @update harishd,gagan 07/17/01
+ * @param aChannel out param that will contain the result
+ * @return NS_OK if successful
+ */
+ NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
+
+ /**
+ * Get the DTD associated with this parser
+ * @update vidur 9/29/99
+ * @param aDTD out param that will contain the result
+ * @return NS_OK if successful, NS_ERROR_FAILURE for runtime error
+ */
+ NS_IMETHOD GetDTD(nsIDTD** aDTD) override;
+
+ /**
+ * Get the nsIStreamListener for this parser
+ */
+ virtual nsIStreamListener* GetStreamListener() override;
+
+ void SetSinkCharset(nsACString& aCharset);
+
+ /**
+ * Removes continue parsing events
+ * @update kmcclusk 5/18/98
+ */
+
+ NS_IMETHOD CancelParsingEvents() override;
+
+ /**
+ * Return true.
+ */
+ virtual bool IsInsertionPointDefined() override;
+
+ /**
+ * No-op.
+ */
+ virtual void PushDefinedInsertionPoint() override;
+
+ /**
+ * No-op.
+ */
+ virtual void PopDefinedInsertionPoint() override;
+
+ /**
+ * No-op.
+ */
+ virtual void MarkAsNotScriptCreated(const char* aCommand) override;
+
+ /**
+ * Always false.
+ */
+ virtual bool IsScriptCreated() override;
+
+ /**
+ * Set to parser state to indicate whether parsing tokens can be interrupted
+ * @param aCanInterrupt true if parser can be interrupted, false if it can not be interrupted.
+ * @update kmcclusk 5/18/98
+ */
+ void SetCanInterrupt(bool aCanInterrupt);
+
+ /**
+ * This is called when the final chunk has been
+ * passed to the parser and the content sink has
+ * interrupted token processing. It schedules
+ * a ParserContinue PL_Event which will ask the parser
+ * to HandleParserContinueEvent when it is handled.
+ * @update kmcclusk6/1/2001
+ */
+ nsresult PostContinueEvent();
+
+ /**
+ * Fired when the continue parse event is triggered.
+ * @update kmcclusk 5/18/98
+ */
+ void HandleParserContinueEvent(class nsParserContinueEvent *);
+
+ virtual void Reset() override {
+ Cleanup();
+ Initialize();
+ }
+
+ bool IsScriptExecuting() {
+ return mSink && mSink->IsScriptExecuting();
+ }
+
+ bool IsOkToProcessNetworkData() {
+ return !IsScriptExecuting() && !mProcessingNetworkData;
+ }
+
+ protected:
+
+ void Initialize(bool aConstructor = false);
+ void Cleanup();
+
+ /**
+ *
+ * @update gess5/18/98
+ * @param
+ * @return
+ */
+ nsresult WillBuildModel(nsString& aFilename);
+
+ /**
+ *
+ * @update gess5/18/98
+ * @param
+ * @return
+ */
+ nsresult DidBuildModel(nsresult anErrorCode);
+
+private:
+
+ /*******************************************
+ These are the tokenization methods...
+ *******************************************/
+
+ /**
+ * Part of the code sandwich, this gets called right before
+ * the tokenization process begins. The main reason for
+ * this call is to allow the delegate to do initialization.
+ *
+ * @update gess 3/25/98
+ * @param
+ * @return TRUE if it's ok to proceed
+ */
+ bool WillTokenize(bool aIsFinalChunk = false);
+
+
+ /**
+ * This is the primary control routine. It iteratively
+ * consumes tokens until an error occurs or you run out
+ * of data.
+ *
+ * @update gess 3/25/98
+ * @return error code
+ */
+ nsresult Tokenize(bool aIsFinalChunk = false);
+
+ /**
+ * Pushes XML fragment parsing data to expat without an input stream.
+ */
+ nsresult Parse(const nsAString& aSourceBuffer,
+ void* aKey,
+ bool aLastCall);
+
+protected:
+ //*********************************************
+ // And now, some data members...
+ //*********************************************
+
+
+ CParserContext* mParserContext;
+ nsCOMPtr<nsIDTD> mDTD;
+ nsCOMPtr<nsIRequestObserver> mObserver;
+ nsCOMPtr<nsIContentSink> mSink;
+ nsIRunnable* mContinueEvent; // weak ref
+
+ eParserCommands mCommand;
+ nsresult mInternalState;
+ nsresult mStreamStatus;
+ int32_t mCharsetSource;
+
+ uint16_t mFlags;
+
+ nsString mUnusedInput;
+ nsCString mCharset;
+ nsCString mCommandStr;
+
+ bool mProcessingNetworkData;
+ bool mIsAboutBlank;
+};
+
+#endif
+
diff --git a/parser/htmlparser/nsParserBase.h b/parser/htmlparser/nsParserBase.h
new file mode 100644
index 000000000..83b68c554
--- /dev/null
+++ b/parser/htmlparser/nsParserBase.h
@@ -0,0 +1,20 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsParserBase_h_
+#define nsParserBase_h_
+
+#include "nsIChannel.h"
+
+class nsParserBase : public nsISupports
+{
+ public:
+ NS_IMETHOD_(bool) IsParserEnabled() { return true; }
+ NS_IMETHOD GetChannel(nsIChannel** aChannel) {
+ *aChannel = nullptr;
+ return NS_OK;
+ }
+};
+
+#endif // nsParserBase_h_
diff --git a/parser/htmlparser/nsParserCIID.h b/parser/htmlparser/nsParserCIID.h
new file mode 100644
index 000000000..4a2b7b1ad
--- /dev/null
+++ b/parser/htmlparser/nsParserCIID.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsParserCIID_h__
+#define nsParserCIID_h__
+
+#include "nsISupports.h"
+#include "nsIFactory.h"
+#include "nsIComponentManager.h"
+
+// {2ce606b0-bee6-11d1-aad9-00805f8a3e14}
+#define NS_PARSER_CID \
+{ 0x2ce606b0, 0xbee6, 0x11d1, { 0xaa, 0xd9, 0x0, 0x80, 0x5f, 0x8a, 0x3e, 0x14 } }
+
+// XXX: This object should not be exposed outside of the parser.
+// Remove when CNavDTD subclasses do not need access
+#define NS_PARSER_NODE_IID \
+ {0x9039c670, 0x2717, 0x11d2, \
+ {0x92, 0x46, 0x00, 0x80, 0x5f, 0x8a, 0x7a, 0xb6}}
+
+// {a6cf9107-15b3-11d2-932e-00805f8add32}
+#define NS_CNAVDTD_CID \
+{ 0xa6cf9107, 0x15b3, 0x11d2, { 0x93, 0x2e, 0x0, 0x80, 0x5f, 0x8a, 0xdd, 0x32 } }
+
+// {FFF4FBE9-528A-4b37-819D-FC18F3A401A7}
+#define NS_EXPAT_DRIVER_CID \
+{ 0xfff4fbe9, 0x528a, 0x4b37, { 0x81, 0x9d, 0xfc, 0x18, 0xf3, 0xa4, 0x1, 0xa7 } }
+
+// {a6cf910f-15b3-11d2-932e-00805f8add32}
+#define NS_HTMLCONTENTSINKSTREAM_CID \
+{ 0xa6cf910f, 0x15b3, 0x11d2, { 0x93, 0x2e, 0x0, 0x80, 0x5f, 0x8a, 0xdd, 0x32 } }
+
+// {a6cf9112-15b3-11d2-932e-00805f8add32}
+#define NS_PARSERSERVICE_CID \
+{ 0xa6cf9112, 0x15b3, 0x11d2, { 0x93, 0x2e, 0x0, 0x80, 0x5f, 0x8a, 0xdd, 0x32 } }
+
+#endif
diff --git a/parser/htmlparser/nsParserConstants.h b/parser/htmlparser/nsParserConstants.h
new file mode 100644
index 000000000..e07a7e878
--- /dev/null
+++ b/parser/htmlparser/nsParserConstants.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=2 sw=2 et tw=78: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsParserConstants_h_
+#define nsParserConstants_h_
+const char16_t kNewLine = '\n';
+const char16_t kCR = '\r';
+const char16_t kLF = '\n';
+const char16_t kTab = '\t';
+const char16_t kSpace = ' ';
+const char16_t kQuote = '"';
+const char16_t kApostrophe = '\'';
+const char16_t kLessThan = '<';
+const char16_t kGreaterThan = '>';
+const char16_t kAmpersand = '&';
+const char16_t kForwardSlash = '/';
+const char16_t kBackSlash = '\\';
+const char16_t kEqual = '=';
+const char16_t kMinus = '-';
+const char16_t kPlus = '+';
+const char16_t kExclamation = '!';
+const char16_t kSemicolon = ';';
+const char16_t kHashsign = '#';
+const char16_t kAsterisk = '*';
+const char16_t kUnderbar = '_';
+const char16_t kComma = ',';
+const char16_t kLeftParen = '(';
+const char16_t kRightParen = ')';
+const char16_t kLeftBrace = '{';
+const char16_t kRightBrace = '}';
+const char16_t kQuestionMark = '?';
+const char16_t kLeftSquareBracket = '[';
+const char16_t kRightSquareBracket = ']';
+const char16_t kNullCh = '\0';
+
+#endif // nsParserConstants_h_
diff --git a/parser/htmlparser/nsParserModule.cpp b/parser/htmlparser/nsParserModule.cpp
new file mode 100644
index 000000000..00c2d6c56
--- /dev/null
+++ b/parser/htmlparser/nsParserModule.cpp
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIAtom.h"
+#include "nsString.h"
+#include "nspr.h"
+#include "nsCOMPtr.h"
+#include "mozilla/ModuleUtils.h"
+#include "nsParserCIID.h"
+#include "nsParser.h"
+#include "CNavDTD.h"
+#include "nsHTMLEntities.h"
+#include "nsHTMLTokenizer.h"
+//#include "nsTextTokenizer.h"
+#include "nsElementTable.h"
+#include "nsParserService.h"
+#include "nsSAXAttributes.h"
+#include "nsSAXLocator.h"
+#include "nsSAXXMLReader.h"
+
+#if defined(DEBUG)
+#include "nsExpatDriver.h"
+#endif
+
+//----------------------------------------------------------------------
+
+#if defined(DEBUG)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsExpatDriver)
+#endif
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsParser)
+NS_GENERIC_FACTORY_CONSTRUCTOR(CNavDTD)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsParserService)
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsSAXAttributes)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsSAXXMLReader)
+
+#if defined(DEBUG)
+NS_DEFINE_NAMED_CID(NS_EXPAT_DRIVER_CID);
+#endif
+NS_DEFINE_NAMED_CID(NS_PARSER_CID);
+NS_DEFINE_NAMED_CID(NS_CNAVDTD_CID);
+NS_DEFINE_NAMED_CID(NS_PARSERSERVICE_CID);
+NS_DEFINE_NAMED_CID(NS_SAXATTRIBUTES_CID);
+NS_DEFINE_NAMED_CID(NS_SAXXMLREADER_CID);
+
+static const mozilla::Module::CIDEntry kParserCIDs[] = {
+#if defined(DEBUG)
+ { &kNS_EXPAT_DRIVER_CID, false, nullptr, nsExpatDriverConstructor },
+#endif
+ { &kNS_PARSER_CID, false, nullptr, nsParserConstructor },
+ { &kNS_CNAVDTD_CID, false, nullptr, CNavDTDConstructor },
+ { &kNS_PARSERSERVICE_CID, false, nullptr, nsParserServiceConstructor },
+ { &kNS_SAXATTRIBUTES_CID, false, nullptr, nsSAXAttributesConstructor },
+ { &kNS_SAXXMLREADER_CID, false, nullptr, nsSAXXMLReaderConstructor },
+ { nullptr }
+};
+
+static const mozilla::Module::ContractIDEntry kParserContracts[] = {
+ { NS_PARSERSERVICE_CONTRACTID, &kNS_PARSERSERVICE_CID },
+ { NS_SAXATTRIBUTES_CONTRACTID, &kNS_SAXATTRIBUTES_CID },
+ { NS_SAXXMLREADER_CONTRACTID, &kNS_SAXXMLREADER_CID },
+ { nullptr }
+};
+
+static nsresult
+Initialize()
+{
+ nsresult rv = nsHTMLTags::AddRefTable();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = nsHTMLEntities::AddRefTable();
+ if (NS_FAILED(rv)) {
+ nsHTMLTags::ReleaseTable();
+ return rv;
+ }
+#ifdef DEBUG
+ CheckElementTable();
+#endif
+
+#ifdef DEBUG
+ nsHTMLTags::TestTagTable();
+#endif
+
+ return rv;
+}
+
+static void
+Shutdown()
+{
+ nsHTMLTags::ReleaseTable();
+ nsHTMLEntities::ReleaseTable();
+}
+
+static mozilla::Module kParserModule = {
+ mozilla::Module::kVersion,
+ kParserCIDs,
+ kParserContracts,
+ nullptr,
+ nullptr,
+ Initialize,
+ Shutdown
+};
+
+NSMODULE_DEFN(nsParserModule) = &kParserModule;
diff --git a/parser/htmlparser/nsParserMsgUtils.cpp b/parser/htmlparser/nsParserMsgUtils.cpp
new file mode 100644
index 000000000..627f57a0e
--- /dev/null
+++ b/parser/htmlparser/nsParserMsgUtils.cpp
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIServiceManager.h"
+#include "nsIStringBundle.h"
+#include "nsXPIDLString.h"
+#include "nsParserMsgUtils.h"
+#include "nsNetCID.h"
+#include "mozilla/Services.h"
+
+static nsresult GetBundle(const char * aPropFileName, nsIStringBundle **aBundle)
+{
+ NS_ENSURE_ARG_POINTER(aPropFileName);
+ NS_ENSURE_ARG_POINTER(aBundle);
+
+ // Create a bundle for the localization
+
+ nsCOMPtr<nsIStringBundleService> stringService =
+ mozilla::services::GetStringBundleService();
+ if (!stringService)
+ return NS_ERROR_FAILURE;
+
+ return stringService->CreateBundle(aPropFileName, aBundle);
+}
+
+nsresult
+nsParserMsgUtils::GetLocalizedStringByName(const char * aPropFileName, const char* aKey, nsString& oVal)
+{
+ oVal.Truncate();
+
+ NS_ENSURE_ARG_POINTER(aKey);
+
+ nsCOMPtr<nsIStringBundle> bundle;
+ nsresult rv = GetBundle(aPropFileName,getter_AddRefs(bundle));
+ if (NS_SUCCEEDED(rv) && bundle) {
+ nsXPIDLString valUni;
+ nsAutoString key; key.AssignWithConversion(aKey);
+ rv = bundle->GetStringFromName(key.get(), getter_Copies(valUni));
+ if (NS_SUCCEEDED(rv) && valUni) {
+ oVal.Assign(valUni);
+ }
+ }
+
+ return rv;
+}
+
+nsresult
+nsParserMsgUtils::GetLocalizedStringByID(const char * aPropFileName, uint32_t aID, nsString& oVal)
+{
+ oVal.Truncate();
+
+ nsCOMPtr<nsIStringBundle> bundle;
+ nsresult rv = GetBundle(aPropFileName,getter_AddRefs(bundle));
+ if (NS_SUCCEEDED(rv) && bundle) {
+ nsXPIDLString valUni;
+ rv = bundle->GetStringFromID(aID, getter_Copies(valUni));
+ if (NS_SUCCEEDED(rv) && valUni) {
+ oVal.Assign(valUni);
+ }
+ }
+
+ return rv;
+}
diff --git a/parser/htmlparser/nsParserMsgUtils.h b/parser/htmlparser/nsParserMsgUtils.h
new file mode 100644
index 000000000..adf3fda8a
--- /dev/null
+++ b/parser/htmlparser/nsParserMsgUtils.h
@@ -0,0 +1,21 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsParserMsgUtils_h
+#define nsParserMsgUtils_h
+
+#include "nsString.h"
+
+#define XMLPARSER_PROPERTIES "chrome://global/locale/layout/xmlparser.properties"
+
+class nsParserMsgUtils {
+ nsParserMsgUtils(); // Currently this is not meant to be created, use the static methods
+ ~nsParserMsgUtils(); // If perf required, change this to cache values etc.
+public:
+ static nsresult GetLocalizedStringByName(const char * aPropFileName, const char* aKey, nsString& aVal);
+ static nsresult GetLocalizedStringByID(const char * aPropFileName, uint32_t aID, nsString& aVal);
+};
+
+#endif
diff --git a/parser/htmlparser/nsParserService.cpp b/parser/htmlparser/nsParserService.cpp
new file mode 100644
index 000000000..d89badd01
--- /dev/null
+++ b/parser/htmlparser/nsParserService.cpp
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsError.h"
+#include "nsIAtom.h"
+#include "nsParserService.h"
+#include "nsHTMLEntities.h"
+#include "nsElementTable.h"
+#include "nsICategoryManager.h"
+#include "nsCategoryManagerUtils.h"
+
+nsParserService::nsParserService()
+{
+}
+
+nsParserService::~nsParserService()
+{
+}
+
+NS_IMPL_ISUPPORTS(nsParserService, nsIParserService)
+
+int32_t
+nsParserService::HTMLAtomTagToId(nsIAtom* aAtom) const
+{
+ return nsHTMLTags::LookupTag(nsDependentAtomString(aAtom));
+}
+
+int32_t
+nsParserService::HTMLCaseSensitiveAtomTagToId(nsIAtom* aAtom) const
+{
+ return nsHTMLTags::CaseSensitiveLookupTag(aAtom);
+}
+
+int32_t
+nsParserService::HTMLStringTagToId(const nsAString& aTag) const
+{
+ return nsHTMLTags::LookupTag(aTag);
+}
+
+const char16_t*
+nsParserService::HTMLIdToStringTag(int32_t aId) const
+{
+ return nsHTMLTags::GetStringValue((nsHTMLTag)aId);
+}
+
+nsIAtom*
+nsParserService::HTMLIdToAtomTag(int32_t aId) const
+{
+ return nsHTMLTags::GetAtom((nsHTMLTag)aId);
+}
+
+NS_IMETHODIMP
+nsParserService::HTMLConvertEntityToUnicode(const nsAString& aEntity,
+ int32_t* aUnicode) const
+{
+ *aUnicode = nsHTMLEntities::EntityToUnicode(aEntity);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsParserService::HTMLConvertUnicodeToEntity(int32_t aUnicode,
+ nsCString& aEntity) const
+{
+ const char* str = nsHTMLEntities::UnicodeToEntity(aUnicode);
+ if (str) {
+ aEntity.Assign(str);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsParserService::IsContainer(int32_t aId, bool& aIsContainer) const
+{
+ aIsContainer = nsHTMLElement::IsContainer((eHTMLTags)aId);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsParserService::IsBlock(int32_t aId, bool& aIsBlock) const
+{
+ if((aId>eHTMLTag_unknown) && (aId<eHTMLTag_userdefined)) {
+ aIsBlock=((gHTMLElements[aId].IsMemberOf(kBlock)) ||
+ (gHTMLElements[aId].IsMemberOf(kBlockEntity)) ||
+ (gHTMLElements[aId].IsMemberOf(kHeading)) ||
+ (gHTMLElements[aId].IsMemberOf(kPreformatted))||
+ (gHTMLElements[aId].IsMemberOf(kList)));
+ }
+ else {
+ aIsBlock = false;
+ }
+
+ return NS_OK;
+}
diff --git a/parser/htmlparser/nsParserService.h b/parser/htmlparser/nsParserService.h
new file mode 100644
index 000000000..0ea7ec98c
--- /dev/null
+++ b/parser/htmlparser/nsParserService.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef NS_PARSERSERVICE_H__
+#define NS_PARSERSERVICE_H__
+
+#include "nsIParserService.h"
+
+extern "C" int MOZ_XMLIsLetter(const char* ptr);
+extern "C" int MOZ_XMLIsNCNameChar(const char* ptr);
+/**
+ * Decodes an entity into the UTF-16 encoding of a Unicode character. If a ';'
+ * is found between `ptr` and `end` it will try to decode the entity and set
+ * `*next` to point to the character after the ;. The resulting UTF-16 code
+ * units will be written in `*result`, so if the entity is a valid numeric
+ * entity there needs to be space for at least two char16_t at the location
+ * `result` points to.
+ *
+ * @param ptr pointer to the ampersand.
+ * @param end pointer to the position after the last character of the
+ * string.
+ * @param next [out] will be set to the character after the ';' or null if
+ * the decoding was unsuccessful.
+ * @param result the buffer to write the resulting UTF-16 character in.
+ * @return the number of char16_t written to `*result`.
+ */
+extern "C" int MOZ_XMLTranslateEntity(const char* ptr, const char* end,
+ const char** next, char16_t* result);
+
+class nsParserService : public nsIParserService {
+ virtual ~nsParserService();
+
+public:
+ nsParserService();
+
+ NS_DECL_ISUPPORTS
+
+ int32_t HTMLAtomTagToId(nsIAtom* aAtom) const override;
+
+ int32_t HTMLCaseSensitiveAtomTagToId(nsIAtom* aAtom) const override;
+
+ int32_t HTMLStringTagToId(const nsAString& aTag) const override;
+
+ const char16_t *HTMLIdToStringTag(int32_t aId) const override;
+
+ nsIAtom *HTMLIdToAtomTag(int32_t aId) const override;
+
+ NS_IMETHOD HTMLConvertEntityToUnicode(const nsAString& aEntity,
+ int32_t* aUnicode) const override;
+ NS_IMETHOD HTMLConvertUnicodeToEntity(int32_t aUnicode,
+ nsCString& aEntity) const override;
+ NS_IMETHOD IsContainer(int32_t aId, bool& aIsContainer) const override;
+ NS_IMETHOD IsBlock(int32_t aId, bool& aIsBlock) const override;
+};
+
+#endif
diff --git a/parser/htmlparser/nsScanner.cpp b/parser/htmlparser/nsScanner.cpp
new file mode 100644
index 000000000..620764590
--- /dev/null
+++ b/parser/htmlparser/nsScanner.cpp
@@ -0,0 +1,409 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 et tw=78: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+//#define __INCREMENTAL 1
+
+#include "mozilla/Attributes.h"
+#include "mozilla/DebugOnly.h"
+
+#include "nsScanner.h"
+#include "nsDebug.h"
+#include "nsReadableUtils.h"
+#include "nsIInputStream.h"
+#include "nsIFile.h"
+#include "nsUTF8Utils.h" // for LossyConvertEncoding
+#include "nsCRT.h"
+#include "nsParser.h"
+#include "nsCharsetSource.h"
+
+#include "mozilla/dom/EncodingUtils.h"
+
+using mozilla::dom::EncodingUtils;
+
+nsReadEndCondition::nsReadEndCondition(const char16_t* aTerminateChars) :
+ mChars(aTerminateChars), mFilter(char16_t(~0)) // All bits set
+{
+ // Build filter that will be used to filter out characters with
+ // bits that none of the terminal chars have. This works very well
+ // because terminal chars often have only the last 4-6 bits set and
+ // normal ascii letters have bit 7 set. Other letters have even higher
+ // bits set.
+
+ // Calculate filter
+ const char16_t *current = aTerminateChars;
+ char16_t terminalChar = *current;
+ while (terminalChar) {
+ mFilter &= ~terminalChar;
+ ++current;
+ terminalChar = *current;
+ }
+}
+
+/**
+ * Use this constructor if you want i/o to be based on
+ * a single string you hand in during construction.
+ * This short cut was added for Javascript.
+ *
+ * @update gess 5/12/98
+ * @param aMode represents the parser mode (nav, other)
+ * @return
+ */
+nsScanner::nsScanner(const nsAString& anHTMLString)
+{
+ MOZ_COUNT_CTOR(nsScanner);
+
+ mSlidingBuffer = nullptr;
+ if (AppendToBuffer(anHTMLString)) {
+ mSlidingBuffer->BeginReading(mCurrentPosition);
+ } else {
+ /* XXX see hack below, re: bug 182067 */
+ memset(&mCurrentPosition, 0, sizeof(mCurrentPosition));
+ mEndPosition = mCurrentPosition;
+ }
+ mMarkPosition = mCurrentPosition;
+ mIncremental = false;
+ mUnicodeDecoder = nullptr;
+ mCharsetSource = kCharsetUninitialized;
+}
+
+/**
+ * Use this constructor if you want i/o to be based on strings
+ * the scanner receives. If you pass a null filename, you
+ * can still provide data to the scanner via append.
+ */
+nsScanner::nsScanner(nsString& aFilename, bool aCreateStream)
+ : mFilename(aFilename)
+{
+ MOZ_COUNT_CTOR(nsScanner);
+ NS_ASSERTION(!aCreateStream, "This is always true.");
+
+ mSlidingBuffer = nullptr;
+
+ // XXX This is a big hack. We need to initialize the iterators to something.
+ // What matters is that mCurrentPosition == mEndPosition, so that our methods
+ // believe that we are at EOF (see bug 182067). We null out mCurrentPosition
+ // so that we have some hope of catching null pointer dereferences associated
+ // with this hack. --darin
+ memset(&mCurrentPosition, 0, sizeof(mCurrentPosition));
+ mMarkPosition = mCurrentPosition;
+ mEndPosition = mCurrentPosition;
+
+ mIncremental = true;
+
+ mUnicodeDecoder = nullptr;
+ mCharsetSource = kCharsetUninitialized;
+ // XML defaults to UTF-8 and about:blank is UTF-8, too.
+ SetDocumentCharset(NS_LITERAL_CSTRING("UTF-8"), kCharsetFromDocTypeDefault);
+}
+
+nsresult nsScanner::SetDocumentCharset(const nsACString& aCharset , int32_t aSource)
+{
+ if (aSource < mCharsetSource) // priority is lower than the current one
+ return NS_OK;
+
+ mCharsetSource = aSource;
+
+ nsCString charsetName;
+ mozilla::DebugOnly<bool> valid =
+ EncodingUtils::FindEncodingForLabel(aCharset, charsetName);
+ MOZ_ASSERT(valid, "Should never call with a bogus aCharset.");
+
+ if (!mCharset.IsEmpty() && charsetName.Equals(mCharset)) {
+ return NS_OK; // no difference, don't change it
+ }
+
+ // different, need to change it
+
+ mCharset.Assign(charsetName);
+
+ mUnicodeDecoder = EncodingUtils::DecoderForEncoding(mCharset);
+ mUnicodeDecoder->SetInputErrorBehavior(nsIUnicodeDecoder::kOnError_Signal);
+
+ return NS_OK;
+}
+
+
+/**
+ * default destructor
+ *
+ * @update gess 3/25/98
+ * @param
+ * @return
+ */
+nsScanner::~nsScanner() {
+
+ delete mSlidingBuffer;
+
+ MOZ_COUNT_DTOR(nsScanner);
+}
+
+/**
+ * Resets current offset position of input stream to marked position.
+ * This allows us to back up to this point if the need should arise,
+ * such as when tokenization gets interrupted.
+ * NOTE: IT IS REALLY BAD FORM TO CALL RELEASE WITHOUT CALLING MARK FIRST!
+ *
+ * @update gess 5/12/98
+ * @param
+ * @return
+ */
+void nsScanner::RewindToMark(void){
+ if (mSlidingBuffer) {
+ mCurrentPosition = mMarkPosition;
+ }
+}
+
+
+/**
+ * Records current offset position in input stream. This allows us
+ * to back up to this point if the need should arise, such as when
+ * tokenization gets interrupted.
+ *
+ * @update gess 7/29/98
+ * @param
+ * @return
+ */
+int32_t nsScanner::Mark() {
+ int32_t distance = 0;
+ if (mSlidingBuffer) {
+ nsScannerIterator oldStart;
+ mSlidingBuffer->BeginReading(oldStart);
+
+ distance = Distance(oldStart, mCurrentPosition);
+
+ mSlidingBuffer->DiscardPrefix(mCurrentPosition);
+ mSlidingBuffer->BeginReading(mCurrentPosition);
+ mMarkPosition = mCurrentPosition;
+ }
+
+ return distance;
+}
+
+/**
+ * Insert data to our underlying input buffer as
+ * if it were read from an input stream.
+ *
+ * @update harishd 01/12/99
+ * @return error code
+ */
+bool nsScanner::UngetReadable(const nsAString& aBuffer) {
+ if (!mSlidingBuffer) {
+ return false;
+ }
+
+ mSlidingBuffer->UngetReadable(aBuffer,mCurrentPosition);
+ mSlidingBuffer->BeginReading(mCurrentPosition); // Insertion invalidated our iterators
+ mSlidingBuffer->EndReading(mEndPosition);
+
+ return true;
+}
+
+/**
+ * Append data to our underlying input buffer as
+ * if it were read from an input stream.
+ *
+ * @update gess4/3/98
+ * @return error code
+ */
+nsresult nsScanner::Append(const nsAString& aBuffer) {
+ if (!AppendToBuffer(aBuffer))
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+/**
+ *
+ *
+ * @update gess 5/21/98
+ * @param
+ * @return
+ */
+nsresult nsScanner::Append(const char* aBuffer, uint32_t aLen)
+{
+ nsresult res = NS_OK;
+ if (mUnicodeDecoder) {
+ int32_t unicharBufLen = 0;
+
+ nsresult rv = mUnicodeDecoder->GetMaxLength(aBuffer, aLen, &unicharBufLen);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ nsScannerString::Buffer* buffer = nsScannerString::AllocBuffer(unicharBufLen + 1);
+ NS_ENSURE_TRUE(buffer,NS_ERROR_OUT_OF_MEMORY);
+ char16_t *unichars = buffer->DataStart();
+
+ int32_t totalChars = 0;
+ int32_t unicharLength = unicharBufLen;
+
+ do {
+ int32_t srcLength = aLen;
+ res = mUnicodeDecoder->Convert(aBuffer, &srcLength, unichars, &unicharLength);
+
+ totalChars += unicharLength;
+ // Continuation of failure case
+ if(NS_FAILED(res)) {
+ // if we failed, we consume one byte, replace it with the replacement
+ // character and try the conversion again.
+
+ // This is only needed because some decoders don't follow the
+ // nsIUnicodeDecoder contract: they return a failure when *aDestLength
+ // is 0 rather than the correct NS_OK_UDEC_MOREOUTPUT. See bug 244177
+ if ((unichars + unicharLength) >= buffer->DataEnd()) {
+ NS_ERROR("Unexpected end of destination buffer");
+ break;
+ }
+
+ // Since about:blank is empty, this line runs only for XML. Use a
+ // character that's illegal in XML instead of U+FFFD in order to make
+ // expat flag the error.
+ unichars[unicharLength++] = 0xFFFF;
+
+ unichars = unichars + unicharLength;
+ unicharLength = unicharBufLen - (++totalChars);
+
+ mUnicodeDecoder->Reset();
+
+ if(((uint32_t) (srcLength + 1)) > aLen) {
+ srcLength = aLen;
+ }
+ else {
+ ++srcLength;
+ }
+
+ aBuffer += srcLength;
+ aLen -= srcLength;
+ }
+ } while (NS_FAILED(res) && (aLen > 0));
+
+ buffer->SetDataLength(totalChars);
+ // Don't propagate return code of unicode decoder
+ // since it doesn't reflect on our success or failure
+ // - Ref. bug 87110
+ res = NS_OK;
+ if (!AppendToBuffer(buffer))
+ res = NS_ERROR_OUT_OF_MEMORY;
+ }
+ else {
+ NS_WARNING("No decoder found.");
+ res = NS_ERROR_FAILURE;
+ }
+
+ return res;
+}
+
+/**
+ * retrieve next char from scanners internal input stream
+ *
+ * @update gess 3/25/98
+ * @param
+ * @return error code reflecting read status
+ */
+nsresult nsScanner::GetChar(char16_t& aChar) {
+ if (!mSlidingBuffer || mCurrentPosition == mEndPosition) {
+ aChar = 0;
+ return kEOF;
+ }
+
+ aChar = *mCurrentPosition++;
+
+ return NS_OK;
+}
+
+
+void nsScanner::BindSubstring(nsScannerSubstring& aSubstring, const nsScannerIterator& aStart, const nsScannerIterator& aEnd)
+{
+ aSubstring.Rebind(*mSlidingBuffer, aStart, aEnd);
+}
+
+void nsScanner::CurrentPosition(nsScannerIterator& aPosition)
+{
+ aPosition = mCurrentPosition;
+}
+
+void nsScanner::EndReading(nsScannerIterator& aPosition)
+{
+ aPosition = mEndPosition;
+}
+
+void nsScanner::SetPosition(nsScannerIterator& aPosition, bool aTerminate)
+{
+ if (mSlidingBuffer) {
+ mCurrentPosition = aPosition;
+ if (aTerminate && (mCurrentPosition == mEndPosition)) {
+ mMarkPosition = mCurrentPosition;
+ mSlidingBuffer->DiscardPrefix(mCurrentPosition);
+ }
+ }
+}
+
+bool nsScanner::AppendToBuffer(nsScannerString::Buffer* aBuf)
+{
+ if (!mSlidingBuffer) {
+ mSlidingBuffer = new nsScannerString(aBuf);
+ if (!mSlidingBuffer)
+ return false;
+ mSlidingBuffer->BeginReading(mCurrentPosition);
+ mMarkPosition = mCurrentPosition;
+ mSlidingBuffer->EndReading(mEndPosition);
+ }
+ else {
+ mSlidingBuffer->AppendBuffer(aBuf);
+ if (mCurrentPosition == mEndPosition) {
+ mSlidingBuffer->BeginReading(mCurrentPosition);
+ }
+ mSlidingBuffer->EndReading(mEndPosition);
+ }
+
+ return true;
+}
+
+/**
+ * call this to copy bytes out of the scanner that have not yet been consumed
+ * by the tokenization process.
+ *
+ * @update gess 5/12/98
+ * @param aCopyBuffer is where the scanner buffer will be copied to
+ * @return true if OK or false on OOM
+ */
+bool nsScanner::CopyUnusedData(nsString& aCopyBuffer) {
+ if (!mSlidingBuffer) {
+ aCopyBuffer.Truncate();
+ return true;
+ }
+
+ nsScannerIterator start, end;
+ start = mCurrentPosition;
+ end = mEndPosition;
+
+ return CopyUnicodeTo(start, end, aCopyBuffer);
+}
+
+/**
+ * Retrieve the name of the file that the scanner is reading from.
+ * In some cases, it's just a given name, because the scanner isn't
+ * really reading from a file.
+ *
+ * @update gess 5/12/98
+ * @return
+ */
+nsString& nsScanner::GetFilename(void) {
+ return mFilename;
+}
+
+/**
+ * Conduct self test. Actually, selftesting for this class
+ * occurs in the parser selftest.
+ *
+ * @update gess 3/25/98
+ * @param
+ * @return
+ */
+
+void nsScanner::SelfTest(void) {
+#ifdef _DEBUG
+#endif
+}
diff --git a/parser/htmlparser/nsScanner.h b/parser/htmlparser/nsScanner.h
new file mode 100644
index 000000000..88edcf74e
--- /dev/null
+++ b/parser/htmlparser/nsScanner.h
@@ -0,0 +1,190 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+/**
+ * MODULE NOTES:
+ * @update gess 4/1/98
+ *
+ * The scanner is a low-level service class that knows
+ * how to consume characters out of an (internal) stream.
+ * This class also offers a series of utility methods
+ * that most tokenizers want, such as readUntil()
+ * and SkipWhitespace().
+ */
+
+
+#ifndef SCANNER
+#define SCANNER
+
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "nsIParser.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsScannerString.h"
+#include "mozilla/CheckedInt.h"
+
+class nsReadEndCondition {
+public:
+ const char16_t *mChars;
+ char16_t mFilter;
+ explicit nsReadEndCondition(const char16_t* aTerminateChars);
+private:
+ nsReadEndCondition(const nsReadEndCondition& aOther); // No copying
+ void operator=(const nsReadEndCondition& aOther); // No assigning
+};
+
+class nsScanner {
+ public:
+
+ /**
+ * Use this constructor for the XML fragment parsing case
+ */
+ explicit nsScanner(const nsAString& anHTMLString);
+
+ /**
+ * Use this constructor if you want i/o to be based on
+ * a file (therefore a stream) or just data you provide via Append().
+ */
+ nsScanner(nsString& aFilename, bool aCreateStream);
+
+ ~nsScanner();
+
+ /**
+ * retrieve next char from internal input stream
+ *
+ * @update gess 3/25/98
+ * @param ch is the char to accept new value
+ * @return error code reflecting read status
+ */
+ nsresult GetChar(char16_t& ch);
+
+ /**
+ * Records current offset position in input stream. This allows us
+ * to back up to this point if the need should arise, such as when
+ * tokenization gets interrupted.
+ *
+ * @update gess 5/12/98
+ * @param
+ * @return
+ */
+ int32_t Mark(void);
+
+ /**
+ * Resets current offset position of input stream to marked position.
+ * This allows us to back up to this point if the need should arise,
+ * such as when tokenization gets interrupted.
+ * NOTE: IT IS REALLY BAD FORM TO CALL RELEASE WITHOUT CALLING MARK FIRST!
+ *
+ * @update gess 5/12/98
+ * @param
+ * @return
+ */
+ void RewindToMark(void);
+
+
+ /**
+ *
+ *
+ * @update harishd 01/12/99
+ * @param
+ * @return
+ */
+ bool UngetReadable(const nsAString& aBuffer);
+
+ /**
+ *
+ *
+ * @update gess 5/13/98
+ * @param
+ * @return
+ */
+ nsresult Append(const nsAString& aBuffer);
+
+ /**
+ *
+ *
+ * @update gess 5/21/98
+ * @param
+ * @return
+ */
+ nsresult Append(const char* aBuffer, uint32_t aLen);
+
+ /**
+ * Call this to copy bytes out of the scanner that have not yet been consumed
+ * by the tokenization process.
+ *
+ * @update gess 5/12/98
+ * @param aCopyBuffer is where the scanner buffer will be copied to
+ * @return true if OK or false on OOM
+ */
+ bool CopyUnusedData(nsString& aCopyBuffer);
+
+ /**
+ * Retrieve the name of the file that the scanner is reading from.
+ * In some cases, it's just a given name, because the scanner isn't
+ * really reading from a file.
+ *
+ * @update gess 5/12/98
+ * @return
+ */
+ nsString& GetFilename(void);
+
+ static void SelfTest();
+
+ /**
+ * Use this setter to change the scanner's unicode decoder
+ *
+ * @update ftang 3/02/99
+ * @param aCharset a normalized (alias resolved) charset name
+ * @param aCharsetSource- where the charset info came from
+ * @return
+ */
+ nsresult SetDocumentCharset(const nsACString& aCharset, int32_t aSource);
+
+ void BindSubstring(nsScannerSubstring& aSubstring, const nsScannerIterator& aStart, const nsScannerIterator& aEnd);
+ void CurrentPosition(nsScannerIterator& aPosition);
+ void EndReading(nsScannerIterator& aPosition);
+ void SetPosition(nsScannerIterator& aPosition,
+ bool aTruncate = false);
+
+ /**
+ * Internal method used to cause the internal buffer to
+ * be filled with data.
+ *
+ * @update gess4/3/98
+ */
+ bool IsIncremental(void) {return mIncremental;}
+ void SetIncremental(bool anIncrValue) {mIncremental=anIncrValue;}
+
+ protected:
+
+ bool AppendToBuffer(nsScannerString::Buffer* aBuffer);
+ bool AppendToBuffer(const nsAString& aStr)
+ {
+ nsScannerString::Buffer* buf = nsScannerString::AllocBufferFromString(aStr);
+ if (!buf)
+ return false;
+ AppendToBuffer(buf);
+ return true;
+ }
+
+ nsScannerString* mSlidingBuffer;
+ nsScannerIterator mCurrentPosition; // The position we will next read from in the scanner buffer
+ nsScannerIterator mMarkPosition; // The position last marked (we may rewind to here)
+ nsScannerIterator mEndPosition; // The current end of the scanner buffer
+ nsString mFilename;
+ bool mIncremental;
+ int32_t mCharsetSource;
+ nsCString mCharset;
+ nsCOMPtr<nsIUnicodeDecoder> mUnicodeDecoder;
+
+ private:
+ nsScanner &operator =(const nsScanner &); // Not implemented.
+};
+
+#endif
+
+
diff --git a/parser/htmlparser/nsScannerString.cpp b/parser/htmlparser/nsScannerString.cpp
new file mode 100644
index 000000000..b492b9054
--- /dev/null
+++ b/parser/htmlparser/nsScannerString.cpp
@@ -0,0 +1,650 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <stdlib.h>
+#include "nsScannerString.h"
+#include "mozilla/CheckedInt.h"
+
+
+ /**
+ * nsScannerBufferList
+ */
+
+#define MAX_CAPACITY ((UINT32_MAX / sizeof(char16_t)) - \
+ (sizeof(Buffer) + sizeof(char16_t)))
+
+nsScannerBufferList::Buffer*
+nsScannerBufferList::AllocBufferFromString( const nsAString& aString )
+ {
+ uint32_t len = aString.Length();
+ Buffer* buf = AllocBuffer(len);
+
+ if (buf)
+ {
+ nsAString::const_iterator source;
+ aString.BeginReading(source);
+ nsCharTraits<char16_t>::copy(buf->DataStart(), source.get(), len);
+ }
+ return buf;
+ }
+
+nsScannerBufferList::Buffer*
+nsScannerBufferList::AllocBuffer( uint32_t capacity )
+ {
+ if (capacity > MAX_CAPACITY)
+ return nullptr;
+
+ void* ptr = malloc(sizeof(Buffer) + (capacity + 1) * sizeof(char16_t));
+ if (!ptr)
+ return nullptr;
+
+ Buffer* buf = new (ptr) Buffer();
+
+ buf->mUsageCount = 0;
+ buf->mDataEnd = buf->DataStart() + capacity;
+
+ // XXX null terminate. this shouldn't be required, but we do it because
+ // nsScanner erroneously thinks it can dereference DataEnd :-(
+ *buf->mDataEnd = char16_t(0);
+ return buf;
+ }
+
+void
+nsScannerBufferList::ReleaseAll()
+ {
+ while (!mBuffers.isEmpty())
+ {
+ Buffer* node = mBuffers.popFirst();
+ //printf(">>> freeing buffer @%p\n", node);
+ free(node);
+ }
+ }
+
+void
+nsScannerBufferList::SplitBuffer( const Position& pos )
+ {
+ // splitting to the right keeps the work string and any extant token
+ // pointing to and holding a reference count on the same buffer.
+
+ Buffer* bufferToSplit = pos.mBuffer;
+ NS_ASSERTION(bufferToSplit, "null pointer");
+
+ uint32_t splitOffset = pos.mPosition - bufferToSplit->DataStart();
+ NS_ASSERTION(pos.mPosition >= bufferToSplit->DataStart() &&
+ splitOffset <= bufferToSplit->DataLength(),
+ "split offset is outside buffer");
+
+ uint32_t len = bufferToSplit->DataLength() - splitOffset;
+ Buffer* new_buffer = AllocBuffer(len);
+ if (new_buffer)
+ {
+ nsCharTraits<char16_t>::copy(new_buffer->DataStart(),
+ bufferToSplit->DataStart() + splitOffset,
+ len);
+ InsertAfter(new_buffer, bufferToSplit);
+ bufferToSplit->SetDataLength(splitOffset);
+ }
+ }
+
+void
+nsScannerBufferList::DiscardUnreferencedPrefix( Buffer* aBuf )
+ {
+ if (aBuf == Head())
+ {
+ while (!mBuffers.isEmpty() && !Head()->IsInUse())
+ {
+ Buffer* buffer = Head();
+ buffer->remove();
+ free(buffer);
+ }
+ }
+ }
+
+size_t
+nsScannerBufferList::Position::Distance( const Position& aStart, const Position& aEnd )
+ {
+ size_t result = 0;
+ if (aStart.mBuffer == aEnd.mBuffer)
+ {
+ result = aEnd.mPosition - aStart.mPosition;
+ }
+ else
+ {
+ result = aStart.mBuffer->DataEnd() - aStart.mPosition;
+ for (Buffer* b = aStart.mBuffer->Next(); b != aEnd.mBuffer; b = b->Next())
+ result += b->DataLength();
+ result += aEnd.mPosition - aEnd.mBuffer->DataStart();
+ }
+ return result;
+ }
+
+
+/**
+ * nsScannerSubstring
+ */
+
+nsScannerSubstring::nsScannerSubstring()
+ : mStart(nullptr, nullptr)
+ , mEnd(nullptr, nullptr)
+ , mBufferList(nullptr)
+ , mLength(0)
+ , mIsDirty(true)
+ {
+ }
+
+nsScannerSubstring::nsScannerSubstring( const nsAString& s )
+ : mBufferList(nullptr)
+ , mIsDirty(true)
+ {
+ Rebind(s);
+ }
+
+nsScannerSubstring::~nsScannerSubstring()
+ {
+ release_ownership_of_buffer_list();
+ }
+
+int32_t
+nsScannerSubstring::CountChar( char16_t c ) const
+ {
+ /*
+ re-write this to use a counting sink
+ */
+
+ size_type result = 0;
+ size_type lengthToExamine = Length();
+
+ nsScannerIterator iter;
+ for ( BeginReading(iter); ; )
+ {
+ int32_t lengthToExamineInThisFragment = iter.size_forward();
+ const char16_t* fromBegin = iter.get();
+ result += size_type(NS_COUNT(fromBegin, fromBegin+lengthToExamineInThisFragment, c));
+ if ( !(lengthToExamine -= lengthToExamineInThisFragment) )
+ return result;
+ iter.advance(lengthToExamineInThisFragment);
+ }
+ // never reached; quiets warnings
+ return 0;
+ }
+
+void
+nsScannerSubstring::Rebind( const nsScannerSubstring& aString,
+ const nsScannerIterator& aStart,
+ const nsScannerIterator& aEnd )
+ {
+ // allow for the case where &aString == this
+
+ aString.acquire_ownership_of_buffer_list();
+ release_ownership_of_buffer_list();
+
+ mStart = aStart;
+ mEnd = aEnd;
+ mBufferList = aString.mBufferList;
+ mLength = Distance(aStart, aEnd);
+ mIsDirty = true;
+ }
+
+void
+nsScannerSubstring::Rebind( const nsAString& aString )
+ {
+ release_ownership_of_buffer_list();
+
+ mBufferList = new nsScannerBufferList(AllocBufferFromString(aString));
+ mIsDirty = true;
+
+ init_range_from_buffer_list();
+ acquire_ownership_of_buffer_list();
+ }
+
+const nsSubstring&
+nsScannerSubstring::AsString() const
+ {
+ if (mIsDirty)
+ {
+ nsScannerSubstring* mutable_this = const_cast<nsScannerSubstring*>(this);
+
+ if (mStart.mBuffer == mEnd.mBuffer) {
+ // We only have a single fragment to deal with, so just return it
+ // as a substring.
+ mutable_this->mFlattenedRep.Rebind(mStart.mPosition, mEnd.mPosition);
+ } else {
+ // Otherwise, we need to copy the data into a flattened buffer.
+ nsScannerIterator start, end;
+ CopyUnicodeTo(BeginReading(start), EndReading(end), mutable_this->mFlattenedRep);
+ }
+
+ mutable_this->mIsDirty = false;
+ }
+
+ return mFlattenedRep;
+ }
+
+nsScannerIterator&
+nsScannerSubstring::BeginReading( nsScannerIterator& iter ) const
+ {
+ iter.mOwner = this;
+
+ iter.mFragment.mBuffer = mStart.mBuffer;
+ iter.mFragment.mFragmentStart = mStart.mPosition;
+ if (mStart.mBuffer == mEnd.mBuffer)
+ iter.mFragment.mFragmentEnd = mEnd.mPosition;
+ else
+ iter.mFragment.mFragmentEnd = mStart.mBuffer->DataEnd();
+
+ iter.mPosition = mStart.mPosition;
+ iter.normalize_forward();
+ return iter;
+ }
+
+nsScannerIterator&
+nsScannerSubstring::EndReading( nsScannerIterator& iter ) const
+ {
+ iter.mOwner = this;
+
+ iter.mFragment.mBuffer = mEnd.mBuffer;
+ iter.mFragment.mFragmentEnd = mEnd.mPosition;
+ if (mStart.mBuffer == mEnd.mBuffer)
+ iter.mFragment.mFragmentStart = mStart.mPosition;
+ else
+ iter.mFragment.mFragmentStart = mEnd.mBuffer->DataStart();
+
+ iter.mPosition = mEnd.mPosition;
+ // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )|
+ return iter;
+ }
+
+bool
+nsScannerSubstring::GetNextFragment( nsScannerFragment& frag ) const
+ {
+ // check to see if we are at the end of the buffer list
+ if (frag.mBuffer == mEnd.mBuffer)
+ return false;
+
+ frag.mBuffer = frag.mBuffer->getNext();
+
+ if (frag.mBuffer == mStart.mBuffer)
+ frag.mFragmentStart = mStart.mPosition;
+ else
+ frag.mFragmentStart = frag.mBuffer->DataStart();
+
+ if (frag.mBuffer == mEnd.mBuffer)
+ frag.mFragmentEnd = mEnd.mPosition;
+ else
+ frag.mFragmentEnd = frag.mBuffer->DataEnd();
+
+ return true;
+ }
+
+bool
+nsScannerSubstring::GetPrevFragment( nsScannerFragment& frag ) const
+ {
+ // check to see if we are at the beginning of the buffer list
+ if (frag.mBuffer == mStart.mBuffer)
+ return false;
+
+ frag.mBuffer = frag.mBuffer->getPrevious();
+
+ if (frag.mBuffer == mStart.mBuffer)
+ frag.mFragmentStart = mStart.mPosition;
+ else
+ frag.mFragmentStart = frag.mBuffer->DataStart();
+
+ if (frag.mBuffer == mEnd.mBuffer)
+ frag.mFragmentEnd = mEnd.mPosition;
+ else
+ frag.mFragmentEnd = frag.mBuffer->DataEnd();
+
+ return true;
+ }
+
+
+ /**
+ * nsScannerString
+ */
+
+nsScannerString::nsScannerString( Buffer* aBuf )
+ {
+ mBufferList = new nsScannerBufferList(aBuf);
+
+ init_range_from_buffer_list();
+ acquire_ownership_of_buffer_list();
+ }
+
+void
+nsScannerString::AppendBuffer( Buffer* aBuf )
+ {
+ mBufferList->Append(aBuf);
+ mLength += aBuf->DataLength();
+
+ mEnd.mBuffer = aBuf;
+ mEnd.mPosition = aBuf->DataEnd();
+
+ mIsDirty = true;
+ }
+
+void
+nsScannerString::DiscardPrefix( const nsScannerIterator& aIter )
+ {
+ Position old_start(mStart);
+ mStart = aIter;
+ mLength -= Position::Distance(old_start, mStart);
+
+ mStart.mBuffer->IncrementUsageCount();
+ old_start.mBuffer->DecrementUsageCount();
+
+ mBufferList->DiscardUnreferencedPrefix(old_start.mBuffer);
+
+ mIsDirty = true;
+ }
+
+void
+nsScannerString::UngetReadable( const nsAString& aReadable, const nsScannerIterator& aInsertPoint )
+ /*
+ * Warning: this routine manipulates the shared buffer list in an unexpected way.
+ * The original design did not really allow for insertions, but this call promises
+ * that if called for a point after the end of all extant token strings, that no token string
+ * or the work string will be invalidated.
+ *
+ * This routine is protected because it is the responsibility of the derived class to keep those promises.
+ */
+ {
+ Position insertPos(aInsertPoint);
+
+ mBufferList->SplitBuffer(insertPos);
+ // splitting to the right keeps the work string and any extant token pointing to and
+ // holding a reference count on the same buffer
+
+ Buffer* new_buffer = AllocBufferFromString(aReadable);
+ // make a new buffer with all the data to insert...
+ // BULLSHIT ALERT: we may have empty space to re-use in the split buffer, measure the cost
+ // of this and decide if we should do the work to fill it
+
+ Buffer* buffer_to_split = insertPos.mBuffer;
+ mBufferList->InsertAfter(new_buffer, buffer_to_split);
+ mLength += aReadable.Length();
+
+ mEnd.mBuffer = mBufferList->Tail();
+ mEnd.mPosition = mEnd.mBuffer->DataEnd();
+
+ mIsDirty = true;
+ }
+
+ /**
+ * nsScannerSharedSubstring
+ */
+
+void
+nsScannerSharedSubstring::Rebind(const nsScannerIterator &aStart,
+ const nsScannerIterator &aEnd)
+{
+ // If the start and end positions are inside the same buffer, we must
+ // acquire ownership of the buffer. If not, we can optimize by not holding
+ // onto it.
+
+ Buffer *buffer = const_cast<Buffer*>(aStart.buffer());
+ bool sameBuffer = buffer == aEnd.buffer();
+
+ nsScannerBufferList *bufferList;
+
+ if (sameBuffer) {
+ bufferList = aStart.mOwner->mBufferList;
+ bufferList->AddRef();
+ buffer->IncrementUsageCount();
+ }
+
+ if (mBufferList)
+ ReleaseBuffer();
+
+ if (sameBuffer) {
+ mBuffer = buffer;
+ mBufferList = bufferList;
+ mString.Rebind(aStart.mPosition, aEnd.mPosition);
+ } else {
+ mBuffer = nullptr;
+ mBufferList = nullptr;
+ CopyUnicodeTo(aStart, aEnd, mString);
+ }
+}
+
+void
+nsScannerSharedSubstring::ReleaseBuffer()
+{
+ NS_ASSERTION(mBufferList, "Should only be called with non-null mBufferList");
+ mBuffer->DecrementUsageCount();
+ mBufferList->DiscardUnreferencedPrefix(mBuffer);
+ mBufferList->Release();
+}
+
+void
+nsScannerSharedSubstring::MakeMutable()
+{
+ nsString temp(mString); // this will force a copy of the data
+ mString.Assign(temp); // mString will now share the just-allocated buffer
+
+ ReleaseBuffer();
+
+ mBuffer = nullptr;
+ mBufferList = nullptr;
+}
+
+ /**
+ * utils -- based on code from nsReadableUtils.cpp
+ */
+
+// private helper function
+static inline
+nsAString::iterator&
+copy_multifragment_string( nsScannerIterator& first, const nsScannerIterator& last, nsAString::iterator& result )
+ {
+ typedef nsCharSourceTraits<nsScannerIterator> source_traits;
+ typedef nsCharSinkTraits<nsAString::iterator> sink_traits;
+
+ while ( first != last )
+ {
+ uint32_t distance = source_traits::readable_distance(first, last);
+ sink_traits::write(result, source_traits::read(first), distance);
+ NS_ASSERTION(distance > 0, "|copy_multifragment_string| will never terminate");
+ source_traits::advance(first, distance);
+ }
+
+ return result;
+ }
+
+bool
+CopyUnicodeTo( const nsScannerIterator& aSrcStart,
+ const nsScannerIterator& aSrcEnd,
+ nsAString& aDest )
+ {
+ nsAString::iterator writer;
+
+ mozilla::CheckedInt<nsAString::size_type> distance(Distance(aSrcStart, aSrcEnd));
+ if (!distance.isValid()) {
+ return false; // overflow detected
+ }
+
+ if (!aDest.SetLength(distance.value(), mozilla::fallible)) {
+ aDest.Truncate();
+ return false; // out of memory
+ }
+ aDest.BeginWriting(writer);
+ nsScannerIterator fromBegin(aSrcStart);
+
+ copy_multifragment_string(fromBegin, aSrcEnd, writer);
+ return true;
+ }
+
+bool
+AppendUnicodeTo( const nsScannerIterator& aSrcStart,
+ const nsScannerIterator& aSrcEnd,
+ nsScannerSharedSubstring& aDest )
+ {
+ // Check whether we can just create a dependent string.
+ if (aDest.str().IsEmpty()) {
+ // We can just make |aDest| point to the buffer.
+ // This will take care of copying if the buffer spans fragments.
+ aDest.Rebind(aSrcStart, aSrcEnd);
+ return true;
+ }
+ // The dest string is not empty, so it can't be a dependent substring.
+ return AppendUnicodeTo(aSrcStart, aSrcEnd, aDest.writable());
+ }
+
+bool
+AppendUnicodeTo( const nsScannerIterator& aSrcStart,
+ const nsScannerIterator& aSrcEnd,
+ nsAString& aDest )
+ {
+ nsAString::iterator writer;
+ const nsAString::size_type oldLength = aDest.Length();
+ CheckedInt<nsAString::size_type> newLen(Distance(aSrcStart, aSrcEnd));
+ newLen += oldLength;
+ if (!newLen.isValid()) {
+ return false; // overflow detected
+ }
+
+ if (!aDest.SetLength(newLen.value(), mozilla::fallible))
+ return false; // out of memory
+ aDest.BeginWriting(writer).advance(oldLength);
+ nsScannerIterator fromBegin(aSrcStart);
+
+ copy_multifragment_string(fromBegin, aSrcEnd, writer);
+ return true;
+ }
+
+bool
+FindCharInReadable( char16_t aChar,
+ nsScannerIterator& aSearchStart,
+ const nsScannerIterator& aSearchEnd )
+ {
+ while ( aSearchStart != aSearchEnd )
+ {
+ int32_t fragmentLength;
+ if ( SameFragment(aSearchStart, aSearchEnd) )
+ fragmentLength = aSearchEnd.get() - aSearchStart.get();
+ else
+ fragmentLength = aSearchStart.size_forward();
+
+ const char16_t* charFoundAt = nsCharTraits<char16_t>::find(aSearchStart.get(), fragmentLength, aChar);
+ if ( charFoundAt ) {
+ aSearchStart.advance( charFoundAt - aSearchStart.get() );
+ return true;
+ }
+
+ aSearchStart.advance(fragmentLength);
+ }
+
+ return false;
+ }
+
+bool
+FindInReadable( const nsAString& aPattern,
+ nsScannerIterator& aSearchStart,
+ nsScannerIterator& aSearchEnd,
+ const nsStringComparator& compare )
+ {
+ bool found_it = false;
+
+ // only bother searching at all if we're given a non-empty range to search
+ if ( aSearchStart != aSearchEnd )
+ {
+ nsAString::const_iterator aPatternStart, aPatternEnd;
+ aPattern.BeginReading(aPatternStart);
+ aPattern.EndReading(aPatternEnd);
+
+ // outer loop keeps searching till we find it or run out of string to search
+ while ( !found_it )
+ {
+ // fast inner loop (that's what it's called, not what it is) looks for a potential match
+ while ( aSearchStart != aSearchEnd &&
+ compare(aPatternStart.get(), aSearchStart.get(), 1, 1) )
+ ++aSearchStart;
+
+ // if we broke out of the `fast' loop because we're out of string ... we're done: no match
+ if ( aSearchStart == aSearchEnd )
+ break;
+
+ // otherwise, we're at a potential match, let's see if we really hit one
+ nsAString::const_iterator testPattern(aPatternStart);
+ nsScannerIterator testSearch(aSearchStart);
+
+ // slow inner loop verifies the potential match (found by the `fast' loop) at the current position
+ for(;;)
+ {
+ // we already compared the first character in the outer loop,
+ // so we'll advance before the next comparison
+ ++testPattern;
+ ++testSearch;
+
+ // if we verified all the way to the end of the pattern, then we found it!
+ if ( testPattern == aPatternEnd )
+ {
+ found_it = true;
+ aSearchEnd = testSearch; // return the exact found range through the parameters
+ break;
+ }
+
+ // if we got to end of the string we're searching before we hit the end of the
+ // pattern, we'll never find what we're looking for
+ if ( testSearch == aSearchEnd )
+ {
+ aSearchStart = aSearchEnd;
+ break;
+ }
+
+ // else if we mismatched ... it's time to advance to the next search position
+ // and get back into the `fast' loop
+ if ( compare(testPattern.get(), testSearch.get(), 1, 1) )
+ {
+ ++aSearchStart;
+ break;
+ }
+ }
+ }
+ }
+
+ return found_it;
+ }
+
+ /**
+ * This implementation is simple, but does too much work.
+ * It searches the entire string from left to right, and returns the last match found, if any.
+ * This implementation will be replaced when I get |reverse_iterator|s working.
+ */
+bool
+RFindInReadable( const nsAString& aPattern,
+ nsScannerIterator& aSearchStart,
+ nsScannerIterator& aSearchEnd,
+ const nsStringComparator& aComparator )
+ {
+ bool found_it = false;
+
+ nsScannerIterator savedSearchEnd(aSearchEnd);
+ nsScannerIterator searchStart(aSearchStart), searchEnd(aSearchEnd);
+
+ while ( searchStart != searchEnd )
+ {
+ if ( FindInReadable(aPattern, searchStart, searchEnd, aComparator) )
+ {
+ found_it = true;
+
+ // this is the best match so far, so remember it
+ aSearchStart = searchStart;
+ aSearchEnd = searchEnd;
+
+ // ...and get ready to search some more
+ // (it's tempting to set |searchStart=searchEnd| ... but that misses overlapping patterns)
+ ++searchStart;
+ searchEnd = savedSearchEnd;
+ }
+ }
+
+ // if we never found it, return an empty range
+ if ( !found_it )
+ aSearchStart = aSearchEnd;
+
+ return found_it;
+ }
diff --git a/parser/htmlparser/nsScannerString.h b/parser/htmlparser/nsScannerString.h
new file mode 100644
index 000000000..7b722238f
--- /dev/null
+++ b/parser/htmlparser/nsScannerString.h
@@ -0,0 +1,604 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsScannerString_h___
+#define nsScannerString_h___
+
+#include "nsString.h"
+#include "nsUnicharUtils.h" // for nsCaseInsensitiveStringComparator
+#include "mozilla/LinkedList.h"
+#include <algorithm>
+
+
+ /**
+ * NOTE: nsScannerString (and the other classes defined in this file) are
+ * not related to nsAString or any of the other xpcom/string classes.
+ *
+ * nsScannerString is based on the nsSlidingString implementation that used
+ * to live in xpcom/string. Now that nsAString is limited to representing
+ * only single fragment strings, nsSlidingString can no longer be used.
+ *
+ * An advantage to this design is that it does not employ any virtual
+ * functions.
+ *
+ * This file uses SCC-style indenting in deference to the nsSlidingString
+ * code from which this code is derived ;-)
+ */
+
+class nsScannerIterator;
+class nsScannerSubstring;
+class nsScannerString;
+
+
+ /**
+ * nsScannerBufferList
+ *
+ * This class maintains a list of heap-allocated Buffer objects. The buffers
+ * are maintained in a circular linked list. Each buffer has a usage count
+ * that is decremented by the owning nsScannerSubstring.
+ *
+ * The buffer list itself is reference counted. This allows the buffer list
+ * to be shared by multiple nsScannerSubstring objects. The reference
+ * counting is not threadsafe, which is not at all a requirement.
+ *
+ * When a nsScannerSubstring releases its reference to a buffer list, it
+ * decrements the usage count of the first buffer in the buffer list that it
+ * was referencing. It informs the buffer list that it can discard buffers
+ * starting at that prefix. The buffer list will do so if the usage count of
+ * that buffer is 0 and if it is the first buffer in the list. It will
+ * continue to prune buffers starting from the front of the buffer list until
+ * it finds a buffer that has a usage count that is non-zero.
+ */
+class nsScannerBufferList
+ {
+ public:
+
+ /**
+ * Buffer objects are directly followed by a data segment. The start
+ * of the data segment is determined by increment the |this| pointer
+ * by 1 unit.
+ */
+ class Buffer : public mozilla::LinkedListElement<Buffer>
+ {
+ public:
+
+ void IncrementUsageCount() { ++mUsageCount; }
+ void DecrementUsageCount() { --mUsageCount; }
+
+ bool IsInUse() const { return mUsageCount != 0; }
+
+ const char16_t* DataStart() const { return (const char16_t*) (this+1); }
+ char16_t* DataStart() { return ( char16_t*) (this+1); }
+
+ const char16_t* DataEnd() const { return mDataEnd; }
+ char16_t* DataEnd() { return mDataEnd; }
+
+ const Buffer* Next() const { return getNext(); }
+ Buffer* Next() { return getNext(); }
+
+ const Buffer* Prev() const { return getPrevious(); }
+ Buffer* Prev() { return getPrevious(); }
+
+ uint32_t DataLength() const { return mDataEnd - DataStart(); }
+ void SetDataLength(uint32_t len) { mDataEnd = DataStart() + len; }
+
+ private:
+
+ friend class nsScannerBufferList;
+
+ int32_t mUsageCount;
+ char16_t* mDataEnd;
+ };
+
+ /**
+ * Position objects serve as lightweight pointers into a buffer list.
+ * The mPosition member must be contained with mBuffer->DataStart()
+ * and mBuffer->DataEnd().
+ */
+ class Position
+ {
+ public:
+
+ Position() {}
+
+ Position( Buffer* buffer, char16_t* position )
+ : mBuffer(buffer)
+ , mPosition(position)
+ {}
+
+ inline
+ explicit Position( const nsScannerIterator& aIter );
+
+ inline
+ Position& operator=( const nsScannerIterator& aIter );
+
+ static size_t Distance( const Position& p1, const Position& p2 );
+
+ Buffer* mBuffer;
+ char16_t* mPosition;
+ };
+
+ static Buffer* AllocBufferFromString( const nsAString& );
+ static Buffer* AllocBuffer( uint32_t capacity ); // capacity = number of chars
+
+ explicit nsScannerBufferList( Buffer* buf )
+ : mRefCnt(0)
+ {
+ mBuffers.insertBack(buf);
+ }
+
+ void AddRef() { ++mRefCnt; }
+ void Release() { if (--mRefCnt == 0) delete this; }
+
+ void Append( Buffer* buf ) { mBuffers.insertBack(buf); }
+ void InsertAfter( Buffer* buf, Buffer* prev ) { prev->setNext(buf); }
+ void SplitBuffer( const Position& );
+ void DiscardUnreferencedPrefix( Buffer* );
+
+ Buffer* Head() { return mBuffers.getFirst(); }
+ const Buffer* Head() const { return mBuffers.getFirst(); }
+
+ Buffer* Tail() { return mBuffers.getLast(); }
+ const Buffer* Tail() const { return mBuffers.getLast(); }
+
+ private:
+
+ friend class nsScannerSubstring;
+
+ ~nsScannerBufferList() { ReleaseAll(); }
+ void ReleaseAll();
+
+ int32_t mRefCnt;
+ mozilla::LinkedList<Buffer> mBuffers;
+ };
+
+
+ /**
+ * nsScannerFragment represents a "slice" of a Buffer object.
+ */
+struct nsScannerFragment
+ {
+ typedef nsScannerBufferList::Buffer Buffer;
+
+ const Buffer* mBuffer;
+ const char16_t* mFragmentStart;
+ const char16_t* mFragmentEnd;
+ };
+
+
+ /**
+ * nsScannerSubstring is the base class for nsScannerString. It provides
+ * access to iterators and methods to bind the substring to another
+ * substring or nsAString instance.
+ *
+ * This class owns the buffer list.
+ */
+class nsScannerSubstring
+ {
+ public:
+ typedef nsScannerBufferList::Buffer Buffer;
+ typedef nsScannerBufferList::Position Position;
+ typedef uint32_t size_type;
+
+ nsScannerSubstring();
+ explicit nsScannerSubstring( const nsAString& s );
+
+ ~nsScannerSubstring();
+
+ nsScannerIterator& BeginReading( nsScannerIterator& iter ) const;
+ nsScannerIterator& EndReading( nsScannerIterator& iter ) const;
+
+ size_type Length() const { return mLength; }
+
+ int32_t CountChar( char16_t ) const;
+
+ void Rebind( const nsScannerSubstring&, const nsScannerIterator&, const nsScannerIterator& );
+ void Rebind( const nsAString& );
+
+ const nsSubstring& AsString() const;
+
+ bool GetNextFragment( nsScannerFragment& ) const;
+ bool GetPrevFragment( nsScannerFragment& ) const;
+
+ static inline Buffer* AllocBufferFromString( const nsAString& aStr ) { return nsScannerBufferList::AllocBufferFromString(aStr); }
+ static inline Buffer* AllocBuffer( size_type aCapacity ) { return nsScannerBufferList::AllocBuffer(aCapacity); }
+
+ protected:
+
+ void acquire_ownership_of_buffer_list() const
+ {
+ mBufferList->AddRef();
+ mStart.mBuffer->IncrementUsageCount();
+ }
+
+ void release_ownership_of_buffer_list()
+ {
+ if (mBufferList)
+ {
+ mStart.mBuffer->DecrementUsageCount();
+ mBufferList->DiscardUnreferencedPrefix(mStart.mBuffer);
+ mBufferList->Release();
+ }
+ }
+
+ void init_range_from_buffer_list()
+ {
+ mStart.mBuffer = mBufferList->Head();
+ mStart.mPosition = mStart.mBuffer->DataStart();
+
+ mEnd.mBuffer = mBufferList->Tail();
+ mEnd.mPosition = mEnd.mBuffer->DataEnd();
+
+ mLength = Position::Distance(mStart, mEnd);
+ }
+
+ Position mStart;
+ Position mEnd;
+ nsScannerBufferList *mBufferList;
+ size_type mLength;
+
+ // these fields are used to implement AsString
+ nsDependentSubstring mFlattenedRep;
+ bool mIsDirty;
+
+ friend class nsScannerSharedSubstring;
+ };
+
+
+ /**
+ * nsScannerString provides methods to grow and modify a buffer list.
+ */
+class nsScannerString : public nsScannerSubstring
+ {
+ public:
+
+ explicit nsScannerString( Buffer* );
+
+ // you are giving ownership to the string, it takes and keeps your
+ // buffer, deleting it when done.
+ // Use AllocBuffer or AllocBufferFromString to create a Buffer object
+ // for use with this function.
+ void AppendBuffer( Buffer* );
+
+ void DiscardPrefix( const nsScannerIterator& );
+ // any other way you want to do this?
+
+ void UngetReadable(const nsAString& aReadable, const nsScannerIterator& aCurrentPosition);
+ };
+
+
+ /**
+ * nsScannerSharedSubstring implements copy-on-write semantics for
+ * nsScannerSubstring. When you call .writable(), it will copy the data
+ * and return a mutable string object. This class also manages releasing
+ * the reference to the scanner buffer when it is no longer needed.
+ */
+
+class nsScannerSharedSubstring
+ {
+ public:
+ nsScannerSharedSubstring()
+ : mBuffer(nullptr), mBufferList(nullptr) { }
+
+ ~nsScannerSharedSubstring()
+ {
+ if (mBufferList)
+ ReleaseBuffer();
+ }
+
+ // Acquire a copy-on-write reference to the given substring.
+ void Rebind(const nsScannerIterator& aStart,
+ const nsScannerIterator& aEnd);
+
+ // Get a mutable reference to this string
+ nsSubstring& writable()
+ {
+ if (mBufferList)
+ MakeMutable();
+
+ return mString;
+ }
+
+ // Get a const reference to this string
+ const nsSubstring& str() const { return mString; }
+
+ private:
+ typedef nsScannerBufferList::Buffer Buffer;
+
+ void ReleaseBuffer();
+ void MakeMutable();
+
+ nsDependentSubstring mString;
+ Buffer *mBuffer;
+ nsScannerBufferList *mBufferList;
+ };
+
+ /**
+ * nsScannerIterator works just like nsReadingIterator<CharT> except that
+ * it knows how to iterate over a list of scanner buffers.
+ */
+class nsScannerIterator
+ {
+ public:
+ typedef nsScannerIterator self_type;
+ typedef ptrdiff_t difference_type;
+ typedef char16_t value_type;
+ typedef const char16_t* pointer;
+ typedef const char16_t& reference;
+ typedef nsScannerSubstring::Buffer Buffer;
+
+ protected:
+
+ nsScannerFragment mFragment;
+ const char16_t* mPosition;
+ const nsScannerSubstring* mOwner;
+
+ friend class nsScannerSubstring;
+ friend class nsScannerSharedSubstring;
+
+ public:
+ nsScannerIterator() {}
+ // nsScannerIterator( const nsScannerIterator& ); // auto-generated copy-constructor OK
+ // nsScannerIterator& operator=( const nsScannerIterator& ); // auto-generated copy-assignment operator OK
+
+ inline void normalize_forward();
+ inline void normalize_backward();
+
+ pointer get() const
+ {
+ return mPosition;
+ }
+
+ char16_t operator*() const
+ {
+ return *get();
+ }
+
+ const nsScannerFragment& fragment() const
+ {
+ return mFragment;
+ }
+
+ const Buffer* buffer() const
+ {
+ return mFragment.mBuffer;
+ }
+
+ self_type& operator++()
+ {
+ ++mPosition;
+ normalize_forward();
+ return *this;
+ }
+
+ self_type operator++( int )
+ {
+ self_type result(*this);
+ ++mPosition;
+ normalize_forward();
+ return result;
+ }
+
+ self_type& operator--()
+ {
+ normalize_backward();
+ --mPosition;
+ return *this;
+ }
+
+ self_type operator--( int )
+ {
+ self_type result(*this);
+ normalize_backward();
+ --mPosition;
+ return result;
+ }
+
+ difference_type size_forward() const
+ {
+ return mFragment.mFragmentEnd - mPosition;
+ }
+
+ difference_type size_backward() const
+ {
+ return mPosition - mFragment.mFragmentStart;
+ }
+
+ self_type& advance( difference_type n )
+ {
+ while ( n > 0 )
+ {
+ difference_type one_hop = std::min(n, size_forward());
+
+ NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a reading iterator beyond the end of a string");
+ // perhaps I should |break| if |!one_hop|?
+
+ mPosition += one_hop;
+ normalize_forward();
+ n -= one_hop;
+ }
+
+ while ( n < 0 )
+ {
+ normalize_backward();
+ difference_type one_hop = std::max(n, -size_backward());
+
+ NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a reading iterator beyond the end of a string");
+ // perhaps I should |break| if |!one_hop|?
+
+ mPosition += one_hop;
+ n -= one_hop;
+ }
+
+ return *this;
+ }
+ };
+
+
+inline
+bool
+SameFragment( const nsScannerIterator& a, const nsScannerIterator& b )
+ {
+ return a.fragment().mFragmentStart == b.fragment().mFragmentStart;
+ }
+
+
+ /**
+ * this class is needed in order to make use of the methods in nsAlgorithm.h
+ */
+template <>
+struct nsCharSourceTraits<nsScannerIterator>
+ {
+ typedef nsScannerIterator::difference_type difference_type;
+
+ static
+ uint32_t
+ readable_distance( const nsScannerIterator& first, const nsScannerIterator& last )
+ {
+ return uint32_t(SameFragment(first, last) ? last.get() - first.get() : first.size_forward());
+ }
+
+ static
+ const nsScannerIterator::value_type*
+ read( const nsScannerIterator& iter )
+ {
+ return iter.get();
+ }
+
+ static
+ void
+ advance( nsScannerIterator& s, difference_type n )
+ {
+ s.advance(n);
+ }
+ };
+
+
+ /**
+ * inline methods follow
+ */
+
+inline
+void
+nsScannerIterator::normalize_forward()
+ {
+ while (mPosition == mFragment.mFragmentEnd && mOwner->GetNextFragment(mFragment))
+ mPosition = mFragment.mFragmentStart;
+ }
+
+inline
+void
+nsScannerIterator::normalize_backward()
+ {
+ while (mPosition == mFragment.mFragmentStart && mOwner->GetPrevFragment(mFragment))
+ mPosition = mFragment.mFragmentEnd;
+ }
+
+inline
+bool
+operator==( const nsScannerIterator& lhs, const nsScannerIterator& rhs )
+ {
+ return lhs.get() == rhs.get();
+ }
+
+inline
+bool
+operator!=( const nsScannerIterator& lhs, const nsScannerIterator& rhs )
+ {
+ return lhs.get() != rhs.get();
+ }
+
+
+inline
+nsScannerBufferList::Position::Position(const nsScannerIterator& aIter)
+ : mBuffer(const_cast<Buffer*>(aIter.buffer()))
+ , mPosition(const_cast<char16_t*>(aIter.get()))
+ {}
+
+inline
+nsScannerBufferList::Position&
+nsScannerBufferList::Position::operator=(const nsScannerIterator& aIter)
+ {
+ mBuffer = const_cast<Buffer*>(aIter.buffer());
+ mPosition = const_cast<char16_t*>(aIter.get());
+ return *this;
+ }
+
+
+ /**
+ * scanner string utils
+ *
+ * These methods mimic the API provided by nsReadableUtils in xpcom/string.
+ * Here we provide only the methods that the htmlparser module needs.
+ */
+
+inline
+size_t
+Distance( const nsScannerIterator& aStart, const nsScannerIterator& aEnd )
+ {
+ typedef nsScannerBufferList::Position Position;
+ return Position::Distance(Position(aStart), Position(aEnd));
+ }
+
+bool
+CopyUnicodeTo( const nsScannerIterator& aSrcStart,
+ const nsScannerIterator& aSrcEnd,
+ nsAString& aDest );
+
+inline
+bool
+CopyUnicodeTo( const nsScannerSubstring& aSrc, nsAString& aDest )
+ {
+ nsScannerIterator begin, end;
+ return CopyUnicodeTo(aSrc.BeginReading(begin), aSrc.EndReading(end), aDest);
+ }
+
+bool
+AppendUnicodeTo( const nsScannerIterator& aSrcStart,
+ const nsScannerIterator& aSrcEnd,
+ nsAString& aDest );
+
+inline
+bool
+AppendUnicodeTo( const nsScannerSubstring& aSrc, nsAString& aDest )
+ {
+ nsScannerIterator begin, end;
+ return AppendUnicodeTo(aSrc.BeginReading(begin), aSrc.EndReading(end), aDest);
+ }
+
+bool
+AppendUnicodeTo( const nsScannerIterator& aSrcStart,
+ const nsScannerIterator& aSrcEnd,
+ nsScannerSharedSubstring& aDest );
+
+bool
+FindCharInReadable( char16_t aChar,
+ nsScannerIterator& aStart,
+ const nsScannerIterator& aEnd );
+
+bool
+FindInReadable( const nsAString& aPattern,
+ nsScannerIterator& aStart,
+ nsScannerIterator& aEnd,
+ const nsStringComparator& = nsDefaultStringComparator() );
+
+bool
+RFindInReadable( const nsAString& aPattern,
+ nsScannerIterator& aStart,
+ nsScannerIterator& aEnd,
+ const nsStringComparator& = nsDefaultStringComparator() );
+
+inline
+bool
+CaseInsensitiveFindInReadable( const nsAString& aPattern,
+ nsScannerIterator& aStart,
+ nsScannerIterator& aEnd )
+ {
+ return FindInReadable(aPattern, aStart, aEnd,
+ nsCaseInsensitiveStringComparator());
+ }
+
+#endif // !defined(nsScannerString_h___)
diff --git a/parser/htmlparser/nsToken.h b/parser/htmlparser/nsToken.h
new file mode 100644
index 000000000..6221aca57
--- /dev/null
+++ b/parser/htmlparser/nsToken.h
@@ -0,0 +1,19 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef CTOKEN__
+#define CTOKEN__
+
+enum eHTMLTokenTypes {
+ eToken_unknown=0,
+ eToken_start=1, eToken_end, eToken_comment, eToken_entity,
+ eToken_whitespace, eToken_newline, eToken_text, eToken_attribute,
+ eToken_instruction, eToken_cdatasection, eToken_doctypeDecl, eToken_markupDecl,
+ eToken_last //make sure this stays the last token...
+};
+
+#endif
+
+
diff --git a/parser/htmlparser/tests/crashtests/121591-1.html b/parser/htmlparser/tests/crashtests/121591-1.html
new file mode 100644
index 000000000..b411a1851
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/121591-1.html
@@ -0,0 +1,22 @@
+<HTML>
+<body>
+<span>
+<head><link></head>
+ <table border=1>
+ <tr><td>
+ <table border=1 align="left">
+ <tr><td></td></tr>
+ <tr><td>
+ <form>
+ <button></button>
+ </form>
+ </td></tr>
+ </table>
+ </td></tr>
+ </table>
+</span>
+</body>
+</html>
+
+
+
diff --git a/parser/htmlparser/tests/crashtests/147179-1.html b/parser/htmlparser/tests/crashtests/147179-1.html
new file mode 100644
index 000000000..2aaac1984
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/147179-1.html
@@ -0,0 +1,7 @@
+<html><head><title>Testcase for bug 141561</title></head>
+<body>
+
+<script>document.write("<form><input type='password'></form>");</script>
+
+</body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/151956-1.html b/parser/htmlparser/tests/crashtests/151956-1.html
new file mode 100644
index 000000000..0ae77f6a6
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/151956-1.html
@@ -0,0 +1,18 @@
+<html>
+<body>
+<!-- script isn't actually required for the crash of bug 151956 -->
+<table border>
+ <tbody>
+ <form>
+ <script>
+ var foo = 42;
+ </script>
+ </form>
+ <tr>
+ <td> X </td>
+ </tr>
+ </tbody>
+</table>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/crashtests/152444-1.html b/parser/htmlparser/tests/crashtests/152444-1.html
new file mode 100644
index 000000000..657644454
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/152444-1.html
@@ -0,0 +1,15 @@
+<html>
+<head>
+<title>Untitled</title>
+</head>
+<body>
+<table>
+<tbody>
+<form>
+<tr><td colspan=2></td></tr>
+<tr><td></td><td></td></tr>
+</form>
+</tbody>
+</table>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/185073-1.html b/parser/htmlparser/tests/crashtests/185073-1.html
new file mode 100644
index 000000000..39504ede2
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/185073-1.html
@@ -0,0 +1,15 @@
+<html>
+ <head>
+ <title>bug 185073</title>
+ </head>
+ <body>
+ <font>
+ <div id="updateText">
+ <script language=javascript type=text/javascript>
+ document.write('</div>');
+ document.getElementById("updateText").innerHTML = "foo";
+ </script>
+ </div>
+ </font>
+ </body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/188474-1.html b/parser/htmlparser/tests/crashtests/188474-1.html
new file mode 100644
index 000000000..2e8b03d19
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/188474-1.html
@@ -0,0 +1,13 @@
+<HTML><HEAD>
+<SCRIPT language="javascript" type="text/javascript">
+
+var header ="<body><div id=\"foo\"></div><div id=\"foo2\"><!-- comment -->";
+
+var footer = "</div><!-- comment -->";
+
+</SCRIPT>
+<SCRIPT language="javascript" type="text/javascript">document.write(header);</SCRIPT>
+</HEAD>
+<BODY>
+<SCRIPT language="javascript" type="text/javascript">document.write(footer);</SCRIPT>
+</BODY></HTML>
diff --git a/parser/htmlparser/tests/crashtests/194329-1.html b/parser/htmlparser/tests/crashtests/194329-1.html
new file mode 100644
index 000000000..c7ab69007
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/194329-1.html
@@ -0,0 +1,15 @@
+<html>
+ <head>
+ <title>bug 188474</title>
+ </head>
+ <body>
+ <head>
+ <div>
+ <script>
+ document.write("<\/div>");
+ </script>
+ <noscript>
+ </div>
+ </noscript><!-- End PayPal Logo -->
+ </body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/197052-1.html b/parser/htmlparser/tests/crashtests/197052-1.html
new file mode 100644
index 000000000..d0b30c761
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/197052-1.html
@@ -0,0 +1 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd"> <html> <head> <title>testcase - crasher</title> </head> <body> <div id="uniqid"> <script language="JavaScript" type="text/JavaScript"> document.write("&gt;"+document.getElementById('uniqid').innerHTML+"&lt;"); </script> </div> </body> </html> \ No newline at end of file
diff --git a/parser/htmlparser/tests/crashtests/220542-1.html b/parser/htmlparser/tests/crashtests/220542-1.html
new file mode 100644
index 000000000..f66473466
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/220542-1.html
@@ -0,0 +1,2 @@
+<script>document.write('<link href="l:\\" rel=stylesheet>')</script>
+
diff --git a/parser/htmlparser/tests/crashtests/253979-1.html b/parser/htmlparser/tests/crashtests/253979-1.html
new file mode 100644
index 000000000..5e47ee84c
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/253979-1.html
@@ -0,0 +1,4 @@
+<html><head></head><body>
+<a><a><p><font><p><font><b><a></font></a>
+</body></html>
+
diff --git a/parser/htmlparser/tests/crashtests/269095-1.html b/parser/htmlparser/tests/crashtests/269095-1.html
new file mode 100644
index 000000000..83cc52828
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/269095-1.html
@@ -0,0 +1 @@
+<TABLE > <FRAMESET> <PARAM> <FORM> <MAP> <FORM> <TABLE> <RTABLE> \ No newline at end of file
diff --git a/parser/htmlparser/tests/crashtests/286733-1.html b/parser/htmlparser/tests/crashtests/286733-1.html
new file mode 100644
index 000000000..04be4f11d
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/286733-1.html
@@ -0,0 +1,4 @@
+<TABLE>
+<FRAMESET><FRAME></FRAMESET>
+<TR><TD><TABLE>
+ <TR><BR><TD><MAP><TABLE><BR></MAP>
diff --git a/parser/htmlparser/tests/crashtests/286733-2.html b/parser/htmlparser/tests/crashtests/286733-2.html
new file mode 100644
index 000000000..5fcf7a7ff
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/286733-2.html
@@ -0,0 +1,4 @@
+<TABLE>
+<FRAMESET><FRAME></FRAMESET>
+<TR><TD><TABLE>
+ <TR><BR><TD><MAP><TABLE><TR><BR></MAP>
diff --git a/parser/htmlparser/tests/crashtests/299036-1.html b/parser/htmlparser/tests/crashtests/299036-1.html
new file mode 100644
index 000000000..e21ce2b9b
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/299036-1.html
@@ -0,0 +1,2 @@
+<table><textarea></textarea></table>
+
diff --git a/parser/htmlparser/tests/crashtests/30885-1.html b/parser/htmlparser/tests/crashtests/30885-1.html
new file mode 100644
index 000000000..2dc0fe035
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/30885-1.html
@@ -0,0 +1,17 @@
+<HTML>
+ <BODY>
+
+ <TABLE BORDER="1">
+ <TR>
+ <TD>
+ <A HREF="foo.htm">
+ <FONT></A>
+ <A HREF="bar.htm">
+ <FONT>
+ MacDesktops</A>
+ </FONT>
+ </TD>
+ </TR>
+</TABLE>
+</BODY>
+</HTML>
diff --git a/parser/htmlparser/tests/crashtests/30956-1.html b/parser/htmlparser/tests/crashtests/30956-1.html
new file mode 100644
index 000000000..508149a97
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/30956-1.html
@@ -0,0 +1,10 @@
+<HTML>
+
+<body>
+<table>
+ <td>
+ <li><font size="-1">
+ <li><a href="foo.html"></font></a>
+</table>
+</body>
+</html> \ No newline at end of file
diff --git a/parser/htmlparser/tests/crashtests/31392-1.html b/parser/htmlparser/tests/crashtests/31392-1.html
new file mode 100644
index 000000000..0a4a138b3
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/31392-1.html
@@ -0,0 +1,15 @@
+<html>
+<head>
+<title>Crash Test page</title>
+</head>
+<body>
+
+<table>
+<tr>
+<td>
+<LINK REL="stylesheet" HREF="garbagestyle.css" TYPE="text/css">
+</td>
+</tr>
+</table>
+</body>
+</html> \ No newline at end of file
diff --git a/parser/htmlparser/tests/crashtests/31694-1.html b/parser/htmlparser/tests/crashtests/31694-1.html
new file mode 100644
index 000000000..8be2d47f0
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/31694-1.html
@@ -0,0 +1,8 @@
+<HTML><HEAD>
+<script src="foo.js"></script>
+<csactions>
+<csaction name="bar" class="foobar" type="ONEVENT">
+</csactions>
+</HEAD>
+<BODY>
+<DD></DD></BODY></HTML>
diff --git a/parser/htmlparser/tests/crashtests/31940-1.html b/parser/htmlparser/tests/crashtests/31940-1.html
new file mode 100644
index 000000000..ec2f370e8
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/31940-1.html
@@ -0,0 +1,15 @@
+<HEAD>
+ <LINK rel="stylesheet">
+ <rdf:RDF>
+ <rdf:Description/>
+ </rdf:RDF>
+</HEAD>
+
+<BODY>
+
+<rdf:RDF>
+<rdfs:Class/>
+</rdf:RDF>
+
+</BODY>
+</HTML>
diff --git a/parser/htmlparser/tests/crashtests/32613-1.html b/parser/htmlparser/tests/crashtests/32613-1.html
new file mode 100644
index 000000000..f50c342e9
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/32613-1.html
@@ -0,0 +1,18 @@
+<P><font color="003366" FACE="Serif">
+<P><FONT size="2"></P>
+<P><FONT size="2"></P>
+<P><FONT size="2"></P>
+<P><FONT size="2"></P>
+<P><FONT size="2"></P>
+<P><FONT size="2"></P>
+<P><FONT size="2"></P>
+<P><FONT size="2"></P>
+<P><FONT size="2"></P>
+<P><FONT size="2"></P>
+<P><FONT size="2"></P>
+<P><FONT size="2"></P>
+<P><FONT size="2"></P>
+<P><FONT size="2"></P>
+<P><FONT size="2"></P>
+<P><FONT size="2"></P>
+</FONT><BR>
diff --git a/parser/htmlparser/tests/crashtests/328751-1.html b/parser/htmlparser/tests/crashtests/328751-1.html
new file mode 100644
index 000000000..37b46af34
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/328751-1.html
@@ -0,0 +1,9 @@
+<HEAD >
+<OBJECT >
+<APPLET CODE=" >
+<BODY TEXT=https://n%ItGEv5%&N8%6USN5i9"
+<TABLE >
+<ISINDEX >
+<TITLE >
+<TBODY >
+</HEAD > \ No newline at end of file
diff --git a/parser/htmlparser/tests/crashtests/34168-1.html b/parser/htmlparser/tests/crashtests/34168-1.html
new file mode 100644
index 000000000..a191a0368
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/34168-1.html
@@ -0,0 +1 @@
+<!ENTITY editAwayMessageSpecial3.label " %d = Current date"> \ No newline at end of file
diff --git a/parser/htmlparser/tests/crashtests/34168-1.xml b/parser/htmlparser/tests/crashtests/34168-1.xml
new file mode 100644
index 000000000..71a058c31
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/34168-1.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<!DOCTYPE foo [
+<!ENTITY editAwayMessageSpecial3.label " %%d = Current date">
+<!ELEMENT foo EMPTY>
+]>
+<foo/>
diff --git a/parser/htmlparser/tests/crashtests/408939-1.html b/parser/htmlparser/tests/crashtests/408939-1.html
new file mode 100644
index 000000000..844c70e72
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/408939-1.html
@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+
+<div>
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+</div>
+
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+
+</body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/41427-1.html b/parser/htmlparser/tests/crashtests/41427-1.html
new file mode 100644
index 000000000..5612153da
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/41427-1.html
@@ -0,0 +1 @@
+<A HREF=""><font><B>t</A><head><script>
diff --git a/parser/htmlparser/tests/crashtests/423373-1.html b/parser/htmlparser/tests/crashtests/423373-1.html
new file mode 100644
index 000000000..487609548
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/423373-1.html
@@ -0,0 +1 @@
+<body><asdf><legend>
diff --git a/parser/htmlparser/tests/crashtests/44178-1.html b/parser/htmlparser/tests/crashtests/44178-1.html
new file mode 100644
index 000000000..0ecb40ef7
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/44178-1.html
@@ -0,0 +1,8 @@
+<html>
+<body>
+<div>
+<server>
+</server>
+</div>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/445171-1-inner.svg b/parser/htmlparser/tests/crashtests/445171-1-inner.svg
new file mode 100644
index 000000000..98d538ad5
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/445171-1-inner.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" onload="location = 'data:text/html,&lt;script&gt;parent.done()&lt;/script&gt;';">
+
+<rect x="5" y="5" width="50" height="50" />
+
+</svg>
diff --git a/parser/htmlparser/tests/crashtests/445171-1.html b/parser/htmlparser/tests/crashtests/445171-1.html
new file mode 100644
index 000000000..0abaacdfb
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/445171-1.html
@@ -0,0 +1,9 @@
+<html class="reftest-wait">
+<head>
+<script>
+function done() { document.documentElement.removeAttribute("class"); }
+</script>
+<body>
+<iframe src="445171-1-inner.svg"></iframe>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/46495-1.html b/parser/htmlparser/tests/crashtests/46495-1.html
new file mode 100644
index 000000000..a0947ff2c
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/46495-1.html
@@ -0,0 +1,5 @@
+<html>
+ <body>
+ <p ">
+ </body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/468538-1.xhtml b/parser/htmlparser/tests/crashtests/468538-1.xhtml
new file mode 100644
index 000000000..576b333c1
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/468538-1.xhtml
@@ -0,0 +1,15 @@
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+<head>
+<script type="text/javascript">
+
+function boom()
+{
+ var v = document.getElementById("v");
+ document.body.removeChild(document.body.firstChild);
+ v.innerHTML = "f";
+}
+
+</script>
+</head>
+<body onload="boom();"><xul:box><div id="v"/></xul:box></body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/50134-1.html b/parser/htmlparser/tests/crashtests/50134-1.html
new file mode 100644
index 000000000..efe680a1f
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/50134-1.html
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>Mozilla Bug 50134</title>
+ </head>
+ <body>
+ <!--->
+ </body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/502103.html b/parser/htmlparser/tests/crashtests/502103.html
new file mode 100644
index 000000000..171a2890e
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/502103.html
@@ -0,0 +1 @@
+<isindex action=""> \ No newline at end of file
diff --git a/parser/htmlparser/tests/crashtests/502869-iframe.html b/parser/htmlparser/tests/crashtests/502869-iframe.html
new file mode 100644
index 000000000..cbd1908f4
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/502869-iframe.html
@@ -0,0 +1,9 @@
+<html><head><title>[HTML5] Crash [@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster] with document.write and removing stuff</title></head><body><a>
+<script>
+var x=document.getElementsByTagName("*");
+x[1].parentNode.removeChild(x[1]);
+x[2].parentNode.removeChild(x[2]);
+</script>
+<div>
+<script>document.write('<'+'script>document.removeChild(document.documentElement);<'+'/script>');</script>
+</a></body></html>
diff --git a/parser/htmlparser/tests/crashtests/502869.html b/parser/htmlparser/tests/crashtests/502869.html
new file mode 100644
index 000000000..5da23b507
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/502869.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait"><head>
+ <meta charset="utf-8">
+ <title>Testcase for bug 502869</title>
+<script>
+function done()
+{
+ document.documentElement.removeAttribute("class");
+}
+</script>
+</head>
+<body onload="setTimeout(done,1000)">
+
+<iframe src="502869-iframe.html"></iframe>
+
+
+</body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/50994-1.html b/parser/htmlparser/tests/crashtests/50994-1.html
new file mode 100644
index 000000000..11bd9aaf0
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/50994-1.html
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML>
+ <HEAD>
+ <TITLE>Mozilla Bug 50994</TITLE>
+ </HEAD>
+ <BODY>
+ <P>
+ <FORM action="">
+ <P>
+ </FORM>
+ </BODY>
+</HTML>
diff --git a/parser/htmlparser/tests/crashtests/515278-1.html b/parser/htmlparser/tests/crashtests/515278-1.html
new file mode 100644
index 000000000..33e01f222
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/515278-1.html
@@ -0,0 +1,3 @@
+
+<fooz>
+
diff --git a/parser/htmlparser/tests/crashtests/515533-1-inner.html b/parser/htmlparser/tests/crashtests/515533-1-inner.html
new file mode 100644
index 000000000..6bd0684e2
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/515533-1-inner.html
@@ -0,0 +1,12 @@
+<html>
+<head>
+</head>
+<body>
+<!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
+<!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
+<!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
+<script language="javascript">
+window.location.replace("data:text/plain,");
+</script>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/515533-1.html b/parser/htmlparser/tests/crashtests/515533-1.html
new file mode 100644
index 000000000..b0d5b570b
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/515533-1.html
@@ -0,0 +1 @@
+<iframe src="515533-1-inner.html"></iframe>
diff --git a/parser/htmlparser/tests/crashtests/515816-1.html b/parser/htmlparser/tests/crashtests/515816-1.html
new file mode 100644
index 000000000..c518d2a3c
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/515816-1.html
@@ -0,0 +1,11 @@
+<html>
+<body>
+<!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
+<!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
+<!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
+<!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
+<!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
+<!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
+<form>
+<input>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
diff --git a/parser/htmlparser/tests/crashtests/522326-1.html b/parser/htmlparser/tests/crashtests/522326-1.html
new file mode 100644
index 000000000..d06ab6cf7
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/522326-1.html
@@ -0,0 +1 @@
+<html><head><META http-equiv="Content-Type" content="text/html; charset=utf-16"><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"></head><body>abcd</body></html>
diff --git a/parser/htmlparser/tests/crashtests/525229-1.html b/parser/htmlparser/tests/crashtests/525229-1.html
new file mode 100644
index 000000000..8bffa7d60
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/525229-1.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<title>Test for bug 525229</title>
+<body>
+<script>
+document.write("<script src='data:text/javascript,'><\/script><div>");
+</script>
+text
diff --git a/parser/htmlparser/tests/crashtests/536097-1.html b/parser/htmlparser/tests/crashtests/536097-1.html
new file mode 100644
index 000000000..76befb3cc
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/536097-1.html
@@ -0,0 +1 @@
+<script>document.write("<iframe></iframe\n");</script><img>
diff --git a/parser/htmlparser/tests/crashtests/555462-iframe.html b/parser/htmlparser/tests/crashtests/555462-iframe.html
new file mode 100644
index 000000000..3ddd6282d
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/555462-iframe.html
@@ -0,0 +1,3 @@
+<!--mmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmm mmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm mmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmm mmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmm mmmmmmmmmm mmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmm mmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmm mmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm mmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmm mmmmmmmmmmmmm mmmmmmmmmmm mmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmm mmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmm -->
+<textarea><mmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm mmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmm mmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm mmmmmmmmmmmmm mmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmmmmmmmmmm mmmmmmmmmmmmmmm
+</textarea> \ No newline at end of file
diff --git a/parser/htmlparser/tests/crashtests/555462.html b/parser/htmlparser/tests/crashtests/555462.html
new file mode 100644
index 000000000..f8d4afad7
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/555462.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait"><head>
+ <meta charset="utf-8">
+ <title>Testcase for bug 555462</title>
+<script>
+function f1() {
+ window.frames[0].frameElement.removeAttribute("onload");
+ window.frames[0].location.reload();
+ setTimeout(f2,200);
+}
+function f2() { window.frames[0].location.reload(); setTimeout(done,400); }
+function done() { document.documentElement.removeAttribute("class"); }
+</script>
+</head>
+<body>
+
+<iframe src="555462-iframe.html" onload="setTimeout(f1,100)"></iframe>
+
+
+</body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/563514-1.html b/parser/htmlparser/tests/crashtests/563514-1.html
new file mode 100644
index 000000000..b96ce1466
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/563514-1.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<head>
+<script>
+function boom()
+{
+ document.createElement("span").innerHTML = "<body a='b'>";
+}
+</script>
+</head>
+<body onload="boom();"></body> \ No newline at end of file
diff --git a/parser/htmlparser/tests/crashtests/574884-1.html b/parser/htmlparser/tests/crashtests/574884-1.html
new file mode 100644
index 000000000..19de3c74a
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/574884-1.html
@@ -0,0 +1 @@
+<svg></html>
diff --git a/parser/htmlparser/tests/crashtests/574884-2.html b/parser/htmlparser/tests/crashtests/574884-2.html
new file mode 100644
index 000000000..09bec52e6
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/574884-2.html
@@ -0,0 +1 @@
+<math></html>
diff --git a/parser/htmlparser/tests/crashtests/58455-1.html b/parser/htmlparser/tests/crashtests/58455-1.html
new file mode 100644
index 000000000..7c235f980
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/58455-1.html
@@ -0,0 +1,15 @@
+<html>
+<head>
+ <title>Computer Market Online</title>
+ <BASE HREF="http://www.computermarket.com.au/">
+</head>
+
+<body bgcolor="#ffffff">
+
+<table>
+<tr><td><a href='prodDetail.asp?id=6007&catid=241'>This shows</a></td></tr>
+<tr><td><a href='prodDetail.asp?id=6007&catid=241'">This does not show</a></td></tr>
+</table>
+
+</body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/591330-1.html b/parser/htmlparser/tests/crashtests/591330-1.html
new file mode 100644
index 000000000..31719fac6
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/591330-1.html
@@ -0,0 +1,284 @@
+<script>
+var sleep = 500; // 0.5 seconds
+var start = Number(new Date());
+while(Number(new Date()) - start < sleep) {
+}
+document.write("<div>"); // make speculation fail
+</script>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+
diff --git a/parser/htmlparser/tests/crashtests/60110-1.html b/parser/htmlparser/tests/crashtests/60110-1.html
new file mode 100644
index 000000000..34f8c406b
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/60110-1.html
@@ -0,0 +1,22 @@
+<HTML><HEAD>
+<TITLE>Edit parameters</TITLE>
+
+
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000"
+LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000" >
+
+<p>
+Any item you check Reset on will get reset to its default value.
+<form method=post action=doeditparams.cgi><table>
+
+<tr><td valign=top><input type=checkbox name=reset-newchangedmail>Reset</td><td>
+<textarea wrap=hard name=newchangedmail rows=10 cols=80>From: bugzilla-daemon&#010;To: %to%&#013;&#010;Cc: %cc%&#013;&#010;Subject: [Bug %bugid%] %neworchanged% - %summary%&#013;&#010;&#013;&#010;%urlbase%show_bug.cgi?id=%bugid%&#013;&#010;&#013;&#010;%diffs%</textarea>
+</td></tr>
+<tr><td valign=top><input type=checkbox name=reset-whinemail>Reset</td><td>
+<textarea wrap=hard name=whinemail rows=10 cols=80>From: bugzilla-daemon&#010;To: %email%&#013;&#010;Subject: Your Bugzilla buglist needs attention.&#013;&#010;&#013;&#010;[This e-mail has been automatically generated.]&#013;&#010;&#013;&#010;You have one or more bugs assigned to you in the Bugzilla &#013;&#010;bugsystem (%urlbase%) that require&#013;&#010;attention.&#013;&#010;&#013;&#010;All of these bugs are in the NEW state, and have not been touched&#013;&#010;in %whinedays% days or more. You need to take a look at them, and &#013;&#010;decide on an initial action.&#013;&#010;&#013;&#010;&#013;&#010;&#013;&#010;</textarea>
+</td></tr>
+<tr><td></td><td>2.11</td></tr></table>
+<input type=reset value="Reset form"><br>
+<input type=submit value="Submit changes">
+</form> \ No newline at end of file
diff --git a/parser/htmlparser/tests/crashtests/650501-1.xhtml b/parser/htmlparser/tests/crashtests/650501-1.xhtml
new file mode 100644
index 000000000..c701a0c76
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/650501-1.xhtml
@@ -0,0 +1,22 @@
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<script>
+<![CDATA[
+
+function boom()
+{
+ var a = document.createElement("div");
+ a.innerHTML = "<script>1;<\/script>";
+
+ var b = document.createElement("div")
+ try { b.innerHTML = "<"; } catch (invalidXML) { }
+
+ document.documentElement.appendChild(a);
+}
+
+]]>
+</script>
+</head>
+<body onload="boom();"></body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/696651-1.html b/parser/htmlparser/tests/crashtests/696651-1.html
new file mode 100644
index 000000000..8c5ee9ed3
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/696651-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<script>
+function runTest() {
+ var iframe = document.getElementsByTagName("iframe")[0];
+ var doc = iframe.contentDocument;
+ doc.write("\u003cscript>document.close();\u003c/script>foo");
+}
+</script>
+<body onload="runTest();">
+<iframe></iframe>
+
diff --git a/parser/htmlparser/tests/crashtests/699347-1.xml b/parser/htmlparser/tests/crashtests/699347-1.xml
new file mode 100644
index 000000000..c6dd4bfa1
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/699347-1.xml
@@ -0,0 +1 @@
+<?xml version="1.0"?><root/>
diff --git a/parser/htmlparser/tests/crashtests/721313-1.html b/parser/htmlparser/tests/crashtests/721313-1.html
new file mode 100644
index 000000000..06497cd65
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/721313-1.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<script>(new DOMParser()).parseFromString("", "text/html");</script>
diff --git a/parser/htmlparser/tests/crashtests/73331-1.html b/parser/htmlparser/tests/crashtests/73331-1.html
new file mode 100644
index 000000000..6761a6686
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/73331-1.html
@@ -0,0 +1,27 @@
+<html>
+<head>
+<script>
+function crashme() {
+ var obj = document.getElementById('popupid');
+ obj.style.visibility='hidden';
+}
+</script>
+</head>
+<body onload="crashme();">
+<a href="http://www.mozilla.org/">http://www.mozilla.org/</a>
+
+<div id="popupid">
+<font>
+<script>
+ document.write('<form>');
+ document.write('<span>');
+ document.write('<input>');
+ document.write('</span>');
+ document.write('<br>');
+ document.write('</form>');
+</script>
+</font>
+</div>
+
+</body>
+</html>
diff --git a/parser/htmlparser/tests/crashtests/742414-1.html b/parser/htmlparser/tests/crashtests/742414-1.html
new file mode 100644
index 000000000..e35b12560
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/742414-1.html
@@ -0,0 +1,4 @@
+<script></script
+><script></script
+><script></script
+>
diff --git a/parser/htmlparser/tests/crashtests/92647-1.html b/parser/htmlparser/tests/crashtests/92647-1.html
new file mode 100644
index 000000000..16be8d98e
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/92647-1.html
@@ -0,0 +1,33 @@
+<HTML>
+<BODY>
+ <form>
+<TABLE border="1">
+ <TR>
+ <TD>
+ <TABLE border="2">
+ <TR>
+ <TD WIDTH="30%">
+ Member Number:
+ </TD>
+ <TD WIDTH="70%">
+ <INPUT NAME="EchoUser" TYPE="TEXT">
+ </TD>
+ </TR>
+ <TR>
+ <TD>
+ PIN:
+ </TD>
+ <TD>
+ <INPUT TYPE="password">
+ </TD>
+ <TD>
+ </TD>
+ </TR>
+ </TABLE>
+ </TD>
+ </TR>
+</TABLE>
+</Form>
+</BODY>
+</HTML>
+
diff --git a/parser/htmlparser/tests/crashtests/92788-1.html b/parser/htmlparser/tests/crashtests/92788-1.html
new file mode 100644
index 000000000..955301e3f
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/92788-1.html
@@ -0,0 +1,20 @@
+<HTML><HEAD><TITLE>Bug #92788</TITLE></HEAD>
+<BODY>
+<TABLE>
+ <TR>
+ <TD>
+ <CENTER>
+ <TR>
+ <TD>
+ <IFRAME
+ marginWidth=0 marginHeight=0 src="foo" frameBorder=0 width=125 scrolling=no
+ height=125><SCRIPT LANGUAGE="JavaScript">document.write('<SCR'+'IPT LANGUAGE="JavaScript" SRC="http://ads1.ad-flow.com/?DC=tweak3d+-+rst&JS=Y&TARGET=_blank"></SCR'+'IPT>');</SCRIPT><NOSCRIPT><A HREF="http://ads1.ad-flow.com/?SHT=tweak3d+-+rst" TARGET="_blank"><IMG SRC="http://ads1.ad-flow.com/?SIT=tweak3d+-+rst" HEIGHT="125" WIDTH="125"></A></NOSCRIPT></IFRAME>--&gt;
+ <FORM name=EmailSub onsubmit="if ( (document.EmailSub.email.length == 0) || (document.EmailSub.email.value.indexOf('@') == -1) || (document.EmailSub.email.value.indexOf('.') == -1) ) {('Invalid Email address');return false;} window.open('http://www.pluginnewsletter.com/nl-popsub.cfm?wsnum=369&amp;' + 'Email=' + document.EmailSub.email.value,'WinOpen','toolbar=no,scrollbars=yes,resizable=yes,width=666,height=666'); return false;">
+ <SCRIPT language=JavaScript src="foo.js"></SCRIPT>
+ <NOSCRIPT><A target=_blank href="http://ads1.ad-flow.com/?SHT=tweak3d-lst" WIDTH="468" HEIGHT="60"><IMG src="Tweak3D_net - Your Freakin' Tweakin' Source!_fichiers/ads1.ad-flow.gif"></A>
+ </NOSCRIPT></CENTER>
+
+ <TR bgColor=#ffffff>
+ <CENTER><IFRAME marginWidth=0 marginHeight=0 src="foo" frameBorder=0 width=468 scrolling=no height=60><SCRIPT LANGUAGE="JavaScript">document.write('<SCR'+'IPT LANGUAGE="JavaScript" SRC="http://ads1.ad-flow.com/?DC=tweak3d-top&JS=Y&TARGET=_blank"></SCR'+'IPT>');</SCRIPT><NOSCRIPT><A HREF="http://ads1.ad-flow.com/?SHT=tweak3d-top" TARGET="_blank"><IMG SRC="http://ads1.ad-flow.com/?SIT=tweak3d-top&SC=Y" HEIGHT="60" WIDTH="468"></A></NOSCRIPT></IFRAME>
+</CENTER></TR>
+</BODY></HTML>
diff --git a/parser/htmlparser/tests/crashtests/981279-1.html b/parser/htmlparser/tests/crashtests/981279-1.html
new file mode 100644
index 000000000..5f14c8af3
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/981279-1.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset=utf-8>
+</head>
+<body>
+<div></div>
+<script>
+var div = document.getElementsByTagName("div")[0];
+div.innerHTML = "<div À à Â Ã Ä Å ";
+div.innerHTML = "<div a>";
+</script>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/crashtests/982285-1.html b/parser/htmlparser/tests/crashtests/982285-1.html
new file mode 100644
index 000000000..d3e124d95
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/982285-1.html
@@ -0,0 +1,19 @@
+<q>
+<u>
+<pre>
+<pre>
+<center>
+<em>
+<center>
+<center>
+</rp>
+<address>
+<address>
+<address>
+</rt>
+<q>
+<q>
+<rt>
+</u>
+<pre>
+</em>
diff --git a/parser/htmlparser/tests/crashtests/crashtests.list b/parser/htmlparser/tests/crashtests/crashtests.list
new file mode 100644
index 000000000..63d5ed6ff
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/crashtests.list
@@ -0,0 +1,57 @@
+load 30885-1.html
+load 30956-1.html
+load 31392-1.html
+load 31694-1.html
+load 31940-1.html
+load 32613-1.html
+load 34168-1.html
+load 34168-1.xml
+load 41427-1.html
+load 44178-1.html
+load 46495-1.html
+load 50134-1.html
+load 50994-1.html
+load 58455-1.html
+load 60110-1.html
+load 73331-1.html
+load 92647-1.html
+load 92788-1.html
+load 121591-1.html
+load 147179-1.html
+load 151956-1.html
+load 152444-1.html
+load 185073-1.html
+load 188474-1.html
+load 194329-1.html
+load 197052-1.html
+load 220542-1.html
+load 253979-1.html
+load 269095-1.html
+load 286733-1.html
+load 286733-2.html
+load 299036-1.html
+skip-if(cocoaWidget&&browserIsRemote) load 328751-1.html # Bug 849747
+load 408939-1.html
+load 423373-1.html
+load 445171-1.html
+load 468538-1.xhtml
+load 502103.html
+load 502869.html
+load 515278-1.html
+load 515533-1.html
+load 515816-1.html
+load 522326-1.html
+load 525229-1.html
+load 536097-1.html
+load 555462.html
+load 563514-1.html
+load 574884-1.html
+load 574884-2.html
+load 591330-1.html
+load 650501-1.xhtml
+load 696651-1.html
+load view-source:699347-1.xml
+load 721313-1.html
+load view-source:742414-1.html
+load 981279-1.html
+load 982285-1.html
diff --git a/parser/htmlparser/tests/mochitest/blue.png b/parser/htmlparser/tests/mochitest/blue.png
new file mode 100644
index 000000000..8df58f3a5
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/blue.png
Binary files differ
diff --git a/parser/htmlparser/tests/mochitest/browser.ini b/parser/htmlparser/tests/mochitest/browser.ini
new file mode 100644
index 000000000..888211178
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/browser.ini
@@ -0,0 +1,6 @@
+[DEFAULT]
+
+[browser_viewsource.js]
+support-files =
+ file_viewsource.html
+
diff --git a/parser/htmlparser/tests/mochitest/browser_viewsource.js b/parser/htmlparser/tests/mochitest/browser_viewsource.js
new file mode 100644
index 000000000..2e45e81a9
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/browser_viewsource.js
@@ -0,0 +1,22 @@
+"use strict";
+
+add_task(function*() {
+ const PAGE_URL = getRootDirectory(gTestPath) + "file_viewsource.html";
+ let viewSourceTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "view-source:" + PAGE_URL);
+
+ let xhrPromise = new Promise(resolve => {
+ let xhr = new XMLHttpRequest();
+ xhr.open("GET", PAGE_URL, true);
+ xhr.onload = event => resolve(event.target.responseText);
+ xhr.send();
+ });
+
+ let viewSourceContentPromise = ContentTask.spawn(viewSourceTab.linkedBrowser, null, function*() {
+ return content.document.body.textContent;
+ });
+
+ let results = yield Promise.all([viewSourceContentPromise, xhrPromise]);
+ is(results[0], results[1], "Sources should match");
+ yield BrowserTestUtils.removeTab(viewSourceTab);
+});
+
diff --git a/parser/htmlparser/tests/mochitest/bug_502091_iframe.html b/parser/htmlparser/tests/mochitest/bug_502091_iframe.html
new file mode 100644
index 000000000..72cdc242c
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/bug_502091_iframe.html
@@ -0,0 +1,17 @@
+<html>
+<head>
+<title>Crash [@ nsContentSink::ProcessHeaderData] with meta in innerHTML</title>
+</head>
+<body>
+<div id="testdiv">
+ testdiv
+ </div>
+<script>
+var x=document.createElement('div');
+x.innerHTML = '<meta http-equiv="Content-Type" content="text/html;"></meta>';
+document.getElementById("testdiv").appendChild(x);
+</script>
+some text here
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/dir_bug534293/file_bug534293.sjs b/parser/htmlparser/tests/mochitest/dir_bug534293/file_bug534293.sjs
new file mode 100644
index 000000000..ec3d3c80d
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/dir_bug534293/file_bug534293.sjs
@@ -0,0 +1,14 @@
+function handleRequest(request, response)
+{
+ response.setHeader("Content-Type", "text/javascript", false);
+ if (request.queryString.indexOf("report") != -1) {
+ if (getState("loaded") == "loaded") {
+ response.write("ok(true, 'This script was supposed to get fetched.');");
+ } else {
+ response.write("ok(false, 'This script was supposed to get fetched.');");
+ }
+ } else {
+ setState("loaded", "loaded");
+ response.write("ok(true, 'This script is supposed to run.');");
+ }
+}
diff --git a/parser/htmlparser/tests/mochitest/file_async_bug1104732.sjs b/parser/htmlparser/tests/mochitest/file_async_bug1104732.sjs
new file mode 100644
index 000000000..b2ea43fdd
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_async_bug1104732.sjs
@@ -0,0 +1,14 @@
+var timer = null;
+
+function handleRequest(request, response)
+{
+ response.processAsync();
+ response.setHeader("Content-Type", "application/javascript", false);
+ response.write("asyncState = 'mid-async';\n");
+
+ timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
+ timer.initWithCallback(function() {
+ response.write("asyncState = 'loaded';\n");
+ response.finish();
+ }, 5 * 1000 /* milliseconds */, timer.TYPE_ONE_SHOT);
+}
diff --git a/parser/htmlparser/tests/mochitest/file_bug102699.sjs b/parser/htmlparser/tests/mochitest/file_bug102699.sjs
new file mode 100644
index 000000000..8f4075ae7
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug102699.sjs
@@ -0,0 +1,15 @@
+function handleRequest(request, response)
+{
+ response.setHeader("Content-Type", "text/javascript", false);
+ if (request.queryString.indexOf("report") != -1) {
+ if (getState("loaded") == "loaded") {
+ response.write("ok(false, 'This script was not supposed to get fetched.'); continueAfterReport();");
+ } else {
+ response.write("ok(true, 'This script was not supposed to get fetched.'); continueAfterReport();");
+ }
+ } else {
+ setState("loaded", "loaded");
+ response.write('document.documentElement.setAttribute("data-fail", "FAIL");');
+ }
+}
+
diff --git a/parser/htmlparser/tests/mochitest/file_bug534293-slow.sjs b/parser/htmlparser/tests/mochitest/file_bug534293-slow.sjs
new file mode 100644
index 000000000..ec456f3eb
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug534293-slow.sjs
@@ -0,0 +1,14 @@
+var timer;
+
+function handleRequest(request, response)
+{
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setHeader("Content-Type", "text/javascript", false);
+ response.write("ok(true, 'Slow script ran.');");
+ response.processAsync();
+ timer = Components.classes["@mozilla.org/timer;1"]
+ .createInstance(Components.interfaces.nsITimer);
+ timer.initWithCallback(function() {
+ response.finish();
+ }, 500, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
+}
diff --git a/parser/htmlparser/tests/mochitest/file_bug534293.sjs b/parser/htmlparser/tests/mochitest/file_bug534293.sjs
new file mode 100644
index 000000000..02b1a1ede
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug534293.sjs
@@ -0,0 +1,14 @@
+function handleRequest(request, response)
+{
+ response.setHeader("Content-Type", "text/javascript", false);
+ if (request.queryString.indexOf("report") != -1) {
+ if (getState("loaded") == "loaded") {
+ response.write("ok(false, 'This script was not supposed to get fetched.');");
+ } else {
+ response.write("ok(true, 'This script was not supposed to get fetched.');");
+ }
+ } else {
+ setState("loaded", "loaded");
+ response.write("ok(false, 'This script is not supposed to run.');");
+ }
+}
diff --git a/parser/htmlparser/tests/mochitest/file_bug543062.sjs b/parser/htmlparser/tests/mochitest/file_bug543062.sjs
new file mode 100644
index 000000000..cb693d2f5
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug543062.sjs
@@ -0,0 +1,32 @@
+var timer;
+
+function armTimer(response) {
+ timer = Components.classes["@mozilla.org/timer;1"]
+ .createInstance(Components.interfaces.nsITimer);
+ timer.initWithCallback(function() {
+ if (getState("docwritepreloadssecond") == "second" && getState("docwritepreloadsthird") == "third") {
+ response.write("ok(true, 'Second and third scripts should have started loading while the first one is loading');");
+ response.finish();
+ } else {
+ armTimer(response);
+ }
+ }, 20, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
+}
+
+function handleRequest(request, response)
+{
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setHeader("Content-Type", "text/javascript", false);
+ if (request.queryString.indexOf("first") != -1) {
+ response.write("// first\n");
+ response.processAsync();
+ armTimer(response);
+ } else if (request.queryString.indexOf("second") != -1) {
+ response.write("// second\n");
+ setState("docwritepreloadssecond", "second");
+ } else {
+ response.write("// third\n");
+ setState("docwritepreloadsthird", "third");
+ }
+}
+
diff --git a/parser/htmlparser/tests/mochitest/file_bug568470-script.sjs b/parser/htmlparser/tests/mochitest/file_bug568470-script.sjs
new file mode 100644
index 000000000..f9150a094
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug568470-script.sjs
@@ -0,0 +1,16 @@
+var timer = null; // Declare outside to prevent premature GC
+
+function handleRequest(request, response)
+{
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setHeader("Content-Type", "text/javascript", false);
+ response.write("var i = 0;");
+ response.bodyOutputStream.flush();
+ response.processAsync();
+ timer = Components.classes["@mozilla.org/timer;1"]
+ .createInstance(Components.interfaces.nsITimer);
+ timer.initWithCallback(function() {
+ response.finish();
+ }, 500, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
+}
+
diff --git a/parser/htmlparser/tests/mochitest/file_bug568470.sjs b/parser/htmlparser/tests/mochitest/file_bug568470.sjs
new file mode 100644
index 000000000..ddc3d0141
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug568470.sjs
@@ -0,0 +1,21 @@
+var timer; // Place timer in global scope to avoid it getting GC'ed prematurely
+
+function handleRequest(request, response)
+{
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setHeader("Content-Type", "text/html", false);
+ response.write("<script src='file_bug568470-script.sjs'></script>");
+ response.write("<div id='flushable'>");
+ for (var i = 0; i < 2000; i++) {
+ response.write("Lorem ipsum dolor sit amet. ");
+ }
+ response.write("</div>");
+ response.bodyOutputStream.flush();
+ response.processAsync();
+ timer = Components.classes["@mozilla.org/timer;1"]
+ .createInstance(Components.interfaces.nsITimer);
+ timer.initWithCallback(function() {
+ response.finish();
+ }, 1200, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
+}
+
diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-1.html b/parser/htmlparser/tests/mochitest/file_bug594730-1.html
new file mode 100644
index 000000000..8877311e2
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug594730-1.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta charset="Windows-1250">
+<script>parent.is("ø", "\u0159", "Decoded bytes should have matched the Unicode escape.");</script>
diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-2.html b/parser/htmlparser/tests/mochitest/file_bug594730-2.html
new file mode 100644
index 000000000..f609df397
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug594730-2.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta http-equiv="content-TYPE" content="text/html; charset=Windows-1250">
+<script>parent.is("ø", "\u0159", "Decoded bytes should have matched the Unicode escape.");</script>
diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-3.html b/parser/htmlparser/tests/mochitest/file_bug594730-3.html
new file mode 100644
index 000000000..d6470d80f
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug594730-3.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta content="text/html; charset=Windows-1250" http-equiv="content-TYPE">
+<script>parent.is("ø", "\u0159", "Decoded bytes should have matched the Unicode escape.");</script>
diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-4.html b/parser/htmlparser/tests/mochitest/file_bug594730-4.html
new file mode 100644
index 000000000..bdce353a5
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug594730-4.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta content="text/html; charset=Windows-1250">
+<script>parent.isnot("ø", "\u0159", "Decoded bytes should not have matched the Unicode escape.");</script>
diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-5.html b/parser/htmlparser/tests/mochitest/file_bug594730-5.html
new file mode 100644
index 000000000..9fdbdded5
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug594730-5.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta charset="Windows-1250" content="text/html; charset=Windows-1252">
+<script>parent.is("ø", "\u0159", "Decoded bytes should have matched the Unicode escape.");</script>
diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-6.html b/parser/htmlparser/tests/mochitest/file_bug594730-6.html
new file mode 100644
index 000000000..570fa460b
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug594730-6.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta charset="Windows-1250" http-equiv="Content-Type" content="text/html; charset=Windows-1252">
+<script>parent.is("ø", "\u0159", "Decoded bytes should have matched the Unicode escape.");</script>
diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-7.html b/parser/htmlparser/tests/mochitest/file_bug594730-7.html
new file mode 100644
index 000000000..92c19c8ff
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug594730-7.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta content="text/html; charset=Windows-1250" http-equiv="Content-Type" content="text/html; charset=Windows-1252">
+<script>parent.is("ø", "\u0159", "Decoded bytes should have matched the Unicode escape.");</script>
diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-8.html b/parser/htmlparser/tests/mochitest/file_bug594730-8.html
new file mode 100644
index 000000000..a9e7525c2
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug594730-8.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta charset="Windows-1250" charset="Windows-1252">
+<script>parent.is("ø", "\u0159", "Decoded bytes should have matched the Unicode escape.");</script>
diff --git a/parser/htmlparser/tests/mochitest/file_bug594730-9.html b/parser/htmlparser/tests/mochitest/file_bug594730-9.html
new file mode 100644
index 000000000..60fab3a39
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug594730-9.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset="
+ Windows-1250
+ ">
+<script>parent.is("ø", "\u0159", "Decoded bytes should have matched the Unicode escape.");</script>
diff --git a/parser/htmlparser/tests/mochitest/file_bug642908.sjs b/parser/htmlparser/tests/mochitest/file_bug642908.sjs
new file mode 100644
index 000000000..73ba20288
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug642908.sjs
@@ -0,0 +1,16 @@
+function handleRequest(request, response)
+{
+ if (request.queryString.indexOf("report") != -1) {
+ response.setHeader("Content-Type", "text/javascript", false);
+ if (getState("loaded") == "loaded") {
+ response.write("ok(false, 'There was an attempt to preload the image.');");
+ } else {
+ response.write("ok(true, 'There was no attempt to preload the image.');");
+ }
+ response.write("SimpleTest.finish();");
+ } else {
+ setState("loaded", "loaded");
+ response.setHeader("Content-Type", "image/svg", false);
+ response.write("<svg xmlns='http://www.w3.org/2000/svg'>Not supposed to load this</svg>");
+ }
+}
diff --git a/parser/htmlparser/tests/mochitest/file_bug655682.sjs b/parser/htmlparser/tests/mochitest/file_bug655682.sjs
new file mode 100644
index 000000000..2b5316b2d
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug655682.sjs
@@ -0,0 +1,37 @@
+var timer;
+var callback;
+
+function handleRequest(request, response)
+{
+ if (request.queryString.indexOf("trigger") != -1) {
+ setState("triggered", "triggered");
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setHeader("Content-Type", "text/javascript; charset=utf-8", false);
+ response.write(";");
+ } else {
+ // Reset the state when running more than once in same browser session.
+ setState("triggered", "");
+
+ response.processAsync();
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setHeader("Content-Type", "text/html; charset=utf-8", false);
+ response.write("<table><tr><td>A</td> ");
+ response.bodyOutputStream.flush();
+ timer = Components.classes["@mozilla.org/timer;1"]
+ .createInstance(Components.interfaces.nsITimer);
+
+ callback = function() {
+ if (getState("triggered") == "triggered") {
+ response.write("<td>B</td></tr></table>");
+ response.finish();
+ } else {
+ timer.initWithCallback(callback,
+ 10,
+ Components.interfaces.nsITimer.TYPE_ONE_SHOT);
+ }
+ }
+ timer.initWithCallback(callback,
+ 10,
+ Components.interfaces.nsITimer.TYPE_ONE_SHOT);
+ }
+}
diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_bomless_utf16.html b/parser/htmlparser/tests/mochitest/file_bug672453_bomless_utf16.html
new file mode 100644
index 000000000..104d50399
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug672453_bomless_utf16.html
Binary files differ
diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html b/parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html
new file mode 100644
index 000000000..0e76edd65
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html
@@ -0,0 +1 @@
+<!DOCTYPE html>
diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html^headers^ b/parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html^headers^
new file mode 100644
index 000000000..35885d0cc
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html^headers^
@@ -0,0 +1,2 @@
+HTTP 200 OK
+Content-Type: text/html; charset=bogus
diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_late_meta.html b/parser/htmlparser/tests/mochitest/file_bug672453_late_meta.html
new file mode 100644
index 000000000..1e0b5870f
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug672453_late_meta.html
@@ -0,0 +1,1028 @@
+<!DOCTYPE html>
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+<meta charset="UTF-8">
diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_meta_non_superset.html b/parser/htmlparser/tests/mochitest/file_bug672453_meta_non_superset.html
new file mode 100644
index 000000000..dab863528
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug672453_meta_non_superset.html
@@ -0,0 +1 @@
+<meta charset="x-imap4-modified-utf7">
diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_meta_restart.html b/parser/htmlparser/tests/mochitest/file_bug672453_meta_restart.html
new file mode 100644
index 000000000..84bd1d364
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug672453_meta_restart.html
@@ -0,0 +1,1028 @@
+<!DOCTYPE html>
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+<meta charset="ISO-8859-2">
diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_meta_unsupported.html b/parser/htmlparser/tests/mochitest/file_bug672453_meta_unsupported.html
new file mode 100644
index 000000000..91111d7e7
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug672453_meta_unsupported.html
@@ -0,0 +1 @@
+<meta charset="bogus">
diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_meta_userdefined.html b/parser/htmlparser/tests/mochitest/file_bug672453_meta_userdefined.html
new file mode 100644
index 000000000..250f6fa67
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug672453_meta_userdefined.html
@@ -0,0 +1 @@
+<meta charset="x-user-defined">
diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_meta_utf16.html b/parser/htmlparser/tests/mochitest/file_bug672453_meta_utf16.html
new file mode 100644
index 000000000..2e6fb9c8b
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug672453_meta_utf16.html
@@ -0,0 +1 @@
+<meta charset="UTF-16">
diff --git a/parser/htmlparser/tests/mochitest/file_bug672453_not_declared.html b/parser/htmlparser/tests/mochitest/file_bug672453_not_declared.html
new file mode 100644
index 000000000..0e76edd65
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug672453_not_declared.html
@@ -0,0 +1 @@
+<!DOCTYPE html>
diff --git a/parser/htmlparser/tests/mochitest/file_bug688580.js b/parser/htmlparser/tests/mochitest/file_bug688580.js
new file mode 100644
index 000000000..b567150f6
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug688580.js
@@ -0,0 +1,4 @@
+is(document.readyState, "interactive", "readyState should be interactive during defer.");
+is(state, "readyState interactive", "Bad state upon defer");
+state = "defer";
+
diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-16.html b/parser/htmlparser/tests/mochitest/file_bug716579-16.html
new file mode 100644
index 000000000..1cd07ca9a
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug716579-16.html
Binary files differ
diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-16.html^headers^ b/parser/htmlparser/tests/mochitest/file_bug716579-16.html^headers^
new file mode 100644
index 000000000..3fadd3bad
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug716579-16.html^headers^
@@ -0,0 +1 @@
+Content-Type: text/html; charset=windows-874
diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-16.xhtml b/parser/htmlparser/tests/mochitest/file_bug716579-16.xhtml
new file mode 100644
index 000000000..cc828a7ce
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug716579-16.xhtml
Binary files differ
diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-16.xhtml^headers^ b/parser/htmlparser/tests/mochitest/file_bug716579-16.xhtml^headers^
new file mode 100644
index 000000000..208b923e8
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug716579-16.xhtml^headers^
@@ -0,0 +1 @@
+Content-Type: application/xhtml+xml; charset=windows-874
diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-8.html b/parser/htmlparser/tests/mochitest/file_bug716579-8.html
new file mode 100644
index 000000000..bbeb036db
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug716579-8.html
@@ -0,0 +1,3 @@
+<script>
+parent.html8 = "€";
+</script>
diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-8.html^headers^ b/parser/htmlparser/tests/mochitest/file_bug716579-8.html^headers^
new file mode 100644
index 000000000..3fadd3bad
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug716579-8.html^headers^
@@ -0,0 +1 @@
+Content-Type: text/html; charset=windows-874
diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml b/parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml
new file mode 100644
index 000000000..a1221cafc
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml
@@ -0,0 +1,7 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<body>
+<script>
+parent.xml8 = "€";
+</script>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml^headers^ b/parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml^headers^
new file mode 100644
index 000000000..208b923e8
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug716579-8.xhtml^headers^
@@ -0,0 +1 @@
+Content-Type: application/xhtml+xml; charset=windows-874
diff --git a/parser/htmlparser/tests/mochitest/file_bug717180.html b/parser/htmlparser/tests/mochitest/file_bug717180.html
new file mode 100644
index 000000000..ff43ca409
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_bug717180.html
@@ -0,0 +1 @@
+SUCCESS
diff --git a/parser/htmlparser/tests/mochitest/file_defer_bug1104732.js b/parser/htmlparser/tests/mochitest/file_defer_bug1104732.js
new file mode 100644
index 000000000..a1bba50cd
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_defer_bug1104732.js
@@ -0,0 +1,3 @@
+is(document.readyState, "interactive", "readyState should be interactive during defer.");
+state = "defer";
+
diff --git a/parser/htmlparser/tests/mochitest/file_img_picture_preload.html b/parser/htmlparser/tests/mochitest/file_img_picture_preload.html
new file mode 100644
index 000000000..e9b2c4c3b
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_img_picture_preload.html
@@ -0,0 +1,167 @@
+<!DOCTYPE html>
+<html>
+<!--
+ Helper for test_img_picture_preload.htm. Can be merged in to the test file
+ when dom.image.{picture,srcset} are removed and we don't need to do pref
+ flipping before the load.
+
+ https://bugzilla.mozilla.org/show_bug.cgi?id=1067345
+-->
+<head>
+ <title>Test for Bug 1067345</title>
+</head>
+<body onload="afterLoad();">
+ <script type="text/javascript">
+ var is = window.parent.is;
+ var ok = window.parent.ok;
+ var SimpleTest = window.parent.SimpleTest;
+ // Called with number of requests made
+ var notifyTestFinished = window.parent.childTestFinished;
+ var currentDPI = window.parent.currentDPI;
+
+ // This script is intentionally blocking the images below from
+ // loading. It issues sync XHRs to the sjs to wait for the files
+ // to be requested before unblocking DOM creation, then asserts
+ // that the same sources were selected by the preloader and the
+ // real DOM.
+
+ // Number of images to wait for before unblocking load
+ const EXPECTED_PRELOADS = 11;
+
+ function busyWait(waitms) {
+ var start = Date.now();
+ while (Date.now() < start + waitms);
+ }
+
+ // Send sync XHRs asking the sjs what images it's seen until we
+ // see EXPECTED_PRELOADS images. (If this test is timing out, you broke
+ // the preloader)
+ var preloadedImages = [];
+ while (preloadedImages.length < EXPECTED_PRELOADS) {
+ var request = new XMLHttpRequest();
+ request.open('GET', "./file_img_picture_preload.sjs?status", false);
+ request.send(null);
+ is(request.status, 200, "Getting status from sjs helper should succeed");
+ if (request.status === 200) {
+ var preloadedImages = JSON.parse(request.responseText);
+ }
+ }
+
+ // Ensure the DOM is still blocked on us before proceeding
+ is(document.querySelector("img"), null, "No <img> elements should exist yet");
+ </script>
+
+ <!-- All images below will be checked, use sources of the format
+ ./file_img_picture_preload.sjs?imgName:sourceName
+ Update numImages when adding or removing images below -->
+
+ <!-- Basic src -->
+ <img id="img1"
+ src="./file_img_picture_preload.sjs?img1:source1">
+ <!-- Basic srcset, no src -->
+ <img id="img2"
+ srcset="./file_img_picture_preload.sjs?img2:source1, ./file_img_picture_preload.sjs?img2:source2 2x, ./file_img_picture_preload.sjs?img2:source3 0.5x">
+ <!-- srcset + src, srcset should shadow entirley -->
+ <img id="img3"
+ srcset="./file_img_picture_preload.sjs?img3:source1, ./file_img_picture_preload.sjs?img3:source2 2x, ./file_img_picture_preload.sjs?img3:source3 0.5x">
+ <!-- Ditto with sizes selector -->
+ <img id="img4"
+ sizes="50vw"
+ srcset="./file_img_picture_preload.sjs?img4:source1 500w, ./file_img_picture_preload.sjs?img4:source2 200w, ./file_img_picture_preload.sjs?img4:source3 5w">
+ <!-- Default source shouldn't be selected -->
+ <img id="img5"
+ srcset="./file_img_picture_preload.sjs?img5:source1, ./file_img_picture_preload.sjs?img5:source2 2x"
+ src="./file_img_picture_preload.sjs?img5:source3">
+ <!-- Default source should be the 1x source, but srcset for others -->
+ <img id="img6"
+ srcset="./file_img_picture_preload.sjs?img6:source1 0.5x, ./file_img_picture_preload.sjs?img6:source2 2x"
+ src="./file_img_picture_preload.sjs?img6:source3">
+
+ <!-- Ensure we skip various invalid sources -->
+ <picture>
+ <source type="image/png">
+ <source type="image/png" srcset="">
+ <source media="(min-width: 1px)">
+ <source media="(min-width: 1px)" srcset=" ">
+ <source type="invalid/x-bogus-type" srcset="./file_img_picture_preload.sjs?img7:source1">
+ <source media="(unknown-query-value-thing: 1000something)" srcset="./file_img_picture_preload.sjs?img7:source2">
+ <source media="(unknown-query-value-thing: 1000something)" srcset="bogus ./file_img_picture_preload.sjs?img7:source3 ./file_img_picture_preload.sjs?img7:source4">
+ <img id="img7" src="./file_img_picture_preload.sjs?img7:source5">
+ </picture>
+
+ <!-- Should select matching sources with known type, and shouldn't select later sources that have closer densities-->
+ <picture>
+ <source type="invalid/x-unsupported-image-type" srcset="./file_img_picture_preload.sjs?img8:source1">
+ <source type="image/png" srcset="./file_img_picture_preload.sjs?img8:source2 2x">
+ <source type="image/png" srcset="./file_img_picture_preload.sjs?img8:source3 1x">
+ <img id="img8" src="./file_img_picture_preload.sjs?img8:source4" srcset="./file_img_picture_preload.sjs?img8:source5 2x">
+ </picture>
+
+ <!-- Should select matching sources by media, and shouldn't select later sources that have closer densities -->
+ <picture>
+ <source media="(bogusxx)" srcset="./file_img_picture_preload.sjs?img9:source1">
+ <source media="(minimum-width: 1px)" srcset="./file_img_picture_preload.sjs?img9:source2 2x">
+ <source media="(max-resolution: 0.5dppx)" srcset="./file_img_picture_preload.sjs?img9:source3 1x">
+ <source media="(min-resolution: 2dppx)" srcset="./file_img_picture_preload.sjs?img9:source4 1x">
+ <source media="(min-resolution: 1dppx)" srcset="./file_img_picture_preload.sjs?img9:source5 1x">
+ <source media="(min-resolution: 1dppx)" srcset="./file_img_picture_preload.sjs?img9:source6 2x">
+ <img id="img9" src="./file_img_picture_preload.sjs?img9:source7" srcset="./file_img_picture_preload.sjs?img9:source8 2x">
+ </picture>
+
+ <!-- Make sure we consider sizes properly in sources -->
+ <picture>
+ <source type="image/png"
+ sizes="10px"
+ srcset="./file_img_picture_preload.sjs?img10:source1 10w, ./file_img_picture_preload.sjs?img10:source2 20w">
+ <img id="img10" src="./file_img_picture_preload.sjs?img10:source3">
+ </picture>
+
+ <!-- Make sure we consider sizes properly -->
+ <img id="img11" sizes="10px"
+ srcset="./file_img_picture_preload.sjs?img11:source1 10w, ./file_img_picture_preload.sjs?img11:source2 20w"
+ src="./file_img_picture_preload.sjs?img11:source3">
+
+ <script type="text/javascript">
+ function afterLoad() {
+ // All images should have picked a source of the format
+ // imgName:sourceName, ensure we have one source per image and
+ // that it was preloaded.
+
+ is(preloadedImages.length, EXPECTED_PRELOADS,
+ "Should have exactly " + EXPECTED_PRELOADS + " preloaded URLs");
+
+ // Split "imgName:source" sources we saw preload by img name
+ var preloadByName = {};
+ for (var preload of preloadedImages) {
+ var split = preload.split(":");
+ // Ensure we didn't preload two sources for the same image
+ ok(preloadByName[split[0]] === undefined,
+ "Should not have queried multiple sources for " + split[0] +
+ " (got " + split[1] + ", already had " + preloadByName[split[0]] + ")");
+ preloadByName[split[0]] = split[1];
+ }
+
+ // Check all images, ensure each one had a preload
+ var images = document.querySelectorAll('img');
+ for (var img of images) {
+ var imgName = img.id;
+ if (img.currentSrc) {
+ var split = img.currentSrc.split("?")[1].split(":");
+ is(split[0], imgName,
+ "image " + imgName + " source matches element id");
+ is(split[1], preloadByName[imgName],
+ "image " + imgName + " source should match preloaded source");
+ // Remove from array
+ delete preloadByName[imgName];
+ } else {
+ // img loaded nothing
+ is(preloadByName[imgName], null,
+ "Should not have preloaded anything for image " + imgName);
+ }
+ }
+
+ notifyTestFinished(preloadedImages.length);
+ }
+ </script>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/file_img_picture_preload.sjs b/parser/htmlparser/tests/mochitest/file_img_picture_preload.sjs
new file mode 100644
index 000000000..e4a3ba780
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_img_picture_preload.sjs
@@ -0,0 +1,28 @@
+// Return a PNG, saving an array of query strings we see as state. When query
+// string is 'status', return array as JSON
+
+function handleRequest(request, response)
+{
+ var seenImages = getState("seenImages");
+ seenImages = seenImages ? JSON.parse(seenImages) : [];
+
+ response.setHeader("Cache-Control", "must-revalidate", false);
+
+ if (request.queryString == "status") {
+ response.setHeader("Content-Type", "text/javascript", false);
+ response.write(JSON.stringify(seenImages));
+ } else if (request.queryString == "reset") {
+ // Respond with how many requests we had seen, drop them
+ response.setHeader("Content-Type", "text/plain", false);
+ response.write(String(seenImages.length));
+ seenImages = [];
+ } else {
+ // Return an image
+ response.setStatusLine("1.1", 302, "Found");
+ response.setHeader("Location", "blue.png", false);
+ dump(request.queryString + '\n');
+ seenImages.push(request.queryString);
+ }
+
+ setState("seenImages", JSON.stringify(seenImages));
+}
diff --git a/parser/htmlparser/tests/mochitest/file_viewsource.html b/parser/htmlparser/tests/mochitest/file_viewsource.html
new file mode 100644
index 000000000..3ed00150a
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/file_viewsource.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>Test for view source</title>
+ </head>
+
+ <body>
+
+<!--
+ this is a multi-line comment
+-->
+
+ <script class="testbody" type="text/javascript">
+ // This is a script comment / text.
+ </script>
+
+ </body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/html5_tree_construction_exceptions.js b/parser/htmlparser/tests/mochitest/html5_tree_construction_exceptions.js
new file mode 100644
index 000000000..ce92a71ec
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5_tree_construction_exceptions.js
@@ -0,0 +1,11 @@
+/*
+ * These are the tests we don't pass. The test data comes from the .dat
+ * files under html5lib_tree_construction/. Please see
+ * html5lib_tree_construction/html5lib_license.txt for the license for these
+ * tests.
+ */
+var html5Exceptions = {
+ "<!doctype html><keygen><frameset>" : true, // Bug 101019
+ "<select><keygen>" : true, // Bug 101019
+ "<!DOCTYPE html><body><keygen>A" : true, // Bug 101019
+}
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/README.md b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/README.md
new file mode 100644
index 000000000..be41fa44f
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/README.md
@@ -0,0 +1,104 @@
+Tree Construction Tests
+=======================
+
+Each file containing tree construction tests consists of any number of
+tests separated by two newlines (LF) and a single newline before the end
+of the file. For instance:
+
+ [TEST]LF
+ LF
+ [TEST]LF
+ LF
+ [TEST]LF
+
+Where [TEST] is the following format:
+
+Each test must begin with a string "\#data" followed by a newline (LF).
+All subsequent lines until a line that says "\#errors" are the test data
+and must be passed to the system being tested unchanged, except with the
+final newline (on the last line) removed.
+
+Then there must be a line that says "\#errors". It must be followed by
+one line per parse error that a conformant checker would return. It
+doesn't matter what those lines are, although they can't be
+"\#document-fragment", "\#document", "\#script-off", "\#script-on", or
+empty, the only thing that matters is that there be the right number
+of parse errors.
+
+Then there \*may\* be a line that says "\#document-fragment", which must
+be followed by a newline (LF), followed by a string of characters that
+indicates the context element, followed by a newline (LF). If the string
+of characters starts with "svg ", the context element is in the SVG
+namespace and the substring after "svg " is the local name. If the
+string of characters starts with "math ", the context element is in the
+MathML namespace and the substring after "math " is the local name.
+Otherwise, the context element is in the HTML namespace and the string
+is the local name. If this line is present the "\#data" must be parsed
+using the HTML fragment parsing algorithm with the context element as
+context.
+
+Then there \*may\* be a line that says "\#script-off" or
+"\#script-in". If a line that says "\#script-off" is present, the
+parser must set the scripting flag to disabled. If a line that says
+"\#script-on" is present, it must set it to enabled. Otherwise, the
+test should be run in both modes.
+
+Then there must be a line that says "\#document", which must be followed
+by a dump of the tree of the parsed DOM. Each node must be represented
+by a single line. Each line must start with "| ", followed by two spaces
+per parent node that the node has before the root document node.
+
+- Element nodes must be represented by a "`<`" then the *tag name
+ string* "`>`", and all the attributes must be given, sorted
+ lexicographically by UTF-16 code unit according to their *attribute
+ name string*, on subsequent lines, as if they were children of the
+ element node.
+- Attribute nodes must have the *attribute name string*, then an "="
+ sign, then the attribute value in double quotes (").
+- Text nodes must be the string, in double quotes. Newlines aren't
+ escaped.
+- Comments must be "`<`" then "`!-- `" then the data then "` -->`".
+- DOCTYPEs must be "`<!DOCTYPE `" then the name then if either of the
+ system id or public id is non-empty a space, public id in
+ double-quotes, another space an the system id in double-quotes, and
+ then in any case "`>`".
+- Processing instructions must be "`<?`", then the target, then a
+ space, then the data and then "`>`". (The HTML parser cannot emit
+ processing instructions, but scripts can, and the WebVTT to DOM
+ rules can emit them.)
+- Template contents are represented by the string "content" with the
+ children below it.
+
+The *tag name string* is the local name prefixed by a namespace
+designator. For the HTML namespace, the namespace designator is the
+empty string, i.e. there's no prefix. For the SVG namespace, the
+namespace designator is "svg ". For the MathML namespace, the namespace
+designator is "math ".
+
+The *attribute name string* is the local name prefixed by a namespace
+designator. For no namespace, the namespace designator is the empty
+string, i.e. there's no prefix. For the XLink namespace, the namespace
+designator is "xlink ". For the XML namespace, the namespace designator
+is "xml ". For the XMLNS namespace, the namespace designator is "xmlns
+". Note the difference between "xlink:href" which is an attribute in no
+namespace with the local name "xlink:href" and "xlink href" which is an
+attribute in the xlink namespace with the local name "href".
+
+If there is also a "\#document-fragment" the bit following "\#document"
+must be a representation of the HTML fragment serialization for the
+context element given by "\#document-fragment".
+
+For example:
+
+ #data
+ <p>One<p>Two
+ #errors
+ 3: Missing document type declaration
+ #document
+ | <html>
+ | <head>
+ | <body>
+ | <p>
+ | "One"
+ | <p>
+ | "Two"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/adoption01.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/adoption01.dat
new file mode 100644
index 000000000..2e1127e51
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/adoption01.dat
@@ -0,0 +1,337 @@
+#data
+<a><p></a></p>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,10): adoption-agency-1.3
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <p>
+| <a>
+
+#data
+<a>1<p>2</a>3</p>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,12): adoption-agency-1.3
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| "1"
+| <p>
+| <a>
+| "2"
+| "3"
+
+#data
+<a>1<button>2</a>3</button>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,17): adoption-agency-1.3
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| "1"
+| <button>
+| <a>
+| "2"
+| "3"
+
+#data
+<a>1<b>2</a>3</b>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,12): adoption-agency-1.3
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| "1"
+| <b>
+| "2"
+| <b>
+| "3"
+
+#data
+<a>1<div>2<div>3</a>4</div>5</div>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,20): adoption-agency-1.3
+(1,20): adoption-agency-1.3
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| "1"
+| <div>
+| <a>
+| "2"
+| <div>
+| <a>
+| "3"
+| "4"
+| "5"
+
+#data
+<table><a>1<p>2</a>3</p>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,10): unexpected-start-tag-implies-table-voodoo
+(1,11): unexpected-character-implies-table-voodoo
+(1,14): unexpected-start-tag-implies-table-voodoo
+(1,15): unexpected-character-implies-table-voodoo
+(1,19): unexpected-end-tag-implies-table-voodoo
+(1,19): adoption-agency-1.3
+(1,20): unexpected-character-implies-table-voodoo
+(1,24): unexpected-end-tag-implies-table-voodoo
+(1,24): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| "1"
+| <p>
+| <a>
+| "2"
+| "3"
+| <table>
+
+#data
+<b><b><a><p></a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,16): adoption-agency-1.3
+(1,16): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| <b>
+| <a>
+| <p>
+| <a>
+
+#data
+<b><a><b><p></a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,16): adoption-agency-1.3
+(1,16): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| <a>
+| <b>
+| <b>
+| <p>
+| <a>
+
+#data
+<a><b><b><p></a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,16): adoption-agency-1.3
+(1,16): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <b>
+| <b>
+| <b>
+| <b>
+| <p>
+| <a>
+
+#data
+<p>1<s id="A">2<b id="B">3</p>4</s>5</b>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,30): unexpected-end-tag
+(1,35): adoption-agency-1.3
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| "1"
+| <s>
+| id="A"
+| "2"
+| <b>
+| id="B"
+| "3"
+| <s>
+| id="A"
+| <b>
+| id="B"
+| "4"
+| <b>
+| id="B"
+| "5"
+
+#data
+<table><a>1<td>2</td>3</table>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,10): unexpected-start-tag-implies-table-voodoo
+(1,11): unexpected-character-implies-table-voodoo
+(1,15): unexpected-cell-in-table-body
+(1,30): unexpected-implied-end-tag-in-table-view
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| "1"
+| <a>
+| "3"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| "2"
+
+#data
+<table>A<td>B</td>C</table>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,8): unexpected-character-implies-table-voodoo
+(1,12): unexpected-cell-in-table-body
+(1,22): unexpected-character-implies-table-voodoo
+#document
+| <html>
+| <head>
+| <body>
+| "AC"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| "B"
+
+#data
+<a><svg><tr><input></a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,23): unexpected-end-tag
+(1,23): adoption-agency-1.3
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <svg svg>
+| <svg tr>
+| <svg input>
+
+#data
+<div><a><b><div><div><div><div><div><div><div><div><div><div></a>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,65): adoption-agency-1.3
+(1,65): adoption-agency-1.3
+(1,65): adoption-agency-1.3
+(1,65): adoption-agency-1.3
+(1,65): adoption-agency-1.3
+(1,65): adoption-agency-1.3
+(1,65): adoption-agency-1.3
+(1,65): adoption-agency-1.3
+(1,65): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <a>
+| <b>
+| <b>
+| <div>
+| <a>
+| <div>
+| <a>
+| <div>
+| <a>
+| <div>
+| <a>
+| <div>
+| <a>
+| <div>
+| <a>
+| <div>
+| <a>
+| <div>
+| <a>
+| <div>
+| <div>
+
+#data
+<div><a><b><u><i><code><div></a>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,32): adoption-agency-1.3
+(1,32): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <a>
+| <b>
+| <u>
+| <i>
+| <code>
+| <u>
+| <i>
+| <code>
+| <div>
+| <a>
+
+#data
+<b><b><b><b>x</b></b></b></b>y
+#errors
+(1,3): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| <b>
+| <b>
+| <b>
+| "x"
+| "y"
+
+#data
+<p><b><b><b><b><p>x
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,18): unexpected-end-tag
+(1,19): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <b>
+| <b>
+| <b>
+| <b>
+| <p>
+| <b>
+| <b>
+| <b>
+| "x"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/adoption02.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/adoption02.dat
new file mode 100644
index 000000000..0502cf302
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/adoption02.dat
@@ -0,0 +1,99 @@
+#data
+<b>1<i>2<p>3</b>4
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,16): adoption-agency-1.3
+(1,17): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| "1"
+| <i>
+| "2"
+| <i>
+| <p>
+| <b>
+| "3"
+| "4"
+
+#data
+<a><div><style></style><address><a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,35): unexpected-start-tag-implies-end-tag
+(1,35): adoption-agency-1.3
+(1,35): adoption-agency-1.3
+(1,35): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <div>
+| <a>
+| <style>
+| <address>
+| <a>
+| <a>
+
+#data
+<b><i><a><s><tt><div></b>first</b></div></tt></s></a>second</i>
+#errors
+3: Start tag seen without seeing a doctype first. Expected "<!DOCTYPE html>".
+25: End tag "b" violates nesting rules.
+34: Stray end tag "b".
+63: Stray end tag "i".
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| <i>
+| <a>
+| <s>
+| <tt>
+| <a>
+| <s>
+| <tt>
+| <div>
+| <b>
+| "first"
+| "second"
+
+#data
+<code foo="bar"><code><code><code><code></code></code></code></code>text</code>
+#errors
+16: Start tag seen without seeing a doctype first. Expected "<!DOCTYPE html>".
+#document
+| <html>
+| <head>
+| <body>
+| <code>
+| foo="bar"
+| <code>
+| <code>
+| <code>
+| <code>
+| "text"
+
+#data
+<code foo="bar"><code><code><code><div><code></div></code></code></code></code>text</code>
+#errors
+16: Start tag seen without seeing a doctype first. Expected "<!DOCTYPE html>".
+51: End tag "div" seen, but there were open elements.
+45: Unclosed element "code".
+58: No "code" element in scope but a "code" end tag seen.
+#document
+| <html>
+| <head>
+| <body>
+| <code>
+| foo="bar"
+| <code>
+| <code>
+| <code>
+| <div>
+| <code>
+| "text"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/comments01.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/comments01.dat
new file mode 100644
index 000000000..35ec6cced
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/comments01.dat
@@ -0,0 +1,178 @@
+#data
+FOO<!-- BAR -->BAZ
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <!-- BAR -->
+| "BAZ"
+
+#data
+FOO<!-- BAR --!>BAZ
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,15): unexpected-bang-after-double-dash-in-comment
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <!-- BAR -->
+| "BAZ"
+
+#data
+FOO<!-- BAR -- >BAZ
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,15): unexpected-char-in-comment
+(1,21): eof-in-comment
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <!-- BAR -- >BAZ -->
+
+#data
+FOO<!-- BAR -- <QUX> -- MUX -->BAZ
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,15): unexpected-char-in-comment
+(1,24): unexpected-char-in-comment
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <!-- BAR -- <QUX> -- MUX -->
+| "BAZ"
+
+#data
+FOO<!-- BAR -- <QUX> -- MUX --!>BAZ
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,15): unexpected-char-in-comment
+(1,24): unexpected-char-in-comment
+(1,31): unexpected-bang-after-double-dash-in-comment
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <!-- BAR -- <QUX> -- MUX -->
+| "BAZ"
+
+#data
+FOO<!-- BAR -- <QUX> -- MUX -- >BAZ
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,15): unexpected-char-in-comment
+(1,24): unexpected-char-in-comment
+(1,31): unexpected-char-in-comment
+(1,35): eof-in-comment
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <!-- BAR -- <QUX> -- MUX -- >BAZ -->
+
+#data
+FOO<!---->BAZ
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <!-- -->
+| "BAZ"
+
+#data
+FOO<!--->BAZ
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,9): incorrect-comment
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <!-- -->
+| "BAZ"
+
+#data
+FOO<!-->BAZ
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,8): incorrect-comment
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <!-- -->
+| "BAZ"
+
+#data
+<?xml version="1.0">Hi
+#errors
+(1,1): expected-tag-name-but-got-question-mark
+(1,22): expected-doctype-but-got-chars
+#document
+| <!-- ?xml version="1.0" -->
+| <html>
+| <head>
+| <body>
+| "Hi"
+
+#data
+<?xml version="1.0">
+#errors
+(1,1): expected-tag-name-but-got-question-mark
+(1,20): expected-doctype-but-got-eof
+#document
+| <!-- ?xml version="1.0" -->
+| <html>
+| <head>
+| <body>
+
+#data
+<?xml version
+#errors
+(1,1): expected-tag-name-but-got-question-mark
+(1,13): expected-doctype-but-got-eof
+#document
+| <!-- ?xml version -->
+| <html>
+| <head>
+| <body>
+
+#data
+FOO<!----->BAZ
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,10): unexpected-dash-after-double-dash-in-comment
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <!-- - -->
+| "BAZ"
+
+#data
+<html><!-- comment --><title>Comment before head</title>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <!-- comment -->
+| <head>
+| <title>
+| "Comment before head"
+| <body>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/doctype01.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/doctype01.dat
new file mode 100644
index 000000000..cec663897
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/doctype01.dat
@@ -0,0 +1,424 @@
+#data
+<!DOCTYPE html>Hello
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!dOctYpE HtMl>Hello
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPEhtml>Hello
+#errors
+(1,9): need-space-after-doctype
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE>Hello
+#errors
+(1,9): need-space-after-doctype
+(1,10): expected-doctype-name-but-got-right-bracket
+(1,10): unknown-doctype
+#document
+| <!DOCTYPE >
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE >Hello
+#errors
+(1,11): expected-doctype-name-but-got-right-bracket
+(1,11): unknown-doctype
+#document
+| <!DOCTYPE >
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato>Hello
+#errors
+(1,17): unknown-doctype
+#document
+| <!DOCTYPE potato>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato >Hello
+#errors
+(1,18): unknown-doctype
+#document
+| <!DOCTYPE potato>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato taco>Hello
+#errors
+(1,17): expected-space-or-right-bracket-in-doctype
+(1,22): unknown-doctype
+#document
+| <!DOCTYPE potato>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato taco "ddd>Hello
+#errors
+(1,17): expected-space-or-right-bracket-in-doctype
+(1,27): unknown-doctype
+#document
+| <!DOCTYPE potato>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato sYstEM>Hello
+#errors
+(1,24): unexpected-char-in-doctype
+(1,24): unknown-doctype
+#document
+| <!DOCTYPE potato>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato sYstEM >Hello
+#errors
+(1,28): unexpected-char-in-doctype
+(1,28): unknown-doctype
+#document
+| <!DOCTYPE potato>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato sYstEM ggg>Hello
+#errors
+(1,34): unexpected-char-in-doctype
+(1,37): unknown-doctype
+#document
+| <!DOCTYPE potato>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato SYSTEM taco >Hello
+#errors
+(1,25): unexpected-char-in-doctype
+(1,31): unknown-doctype
+#document
+| <!DOCTYPE potato>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato SYSTEM 'taco"'>Hello
+#errors
+(1,32): unknown-doctype
+#document
+| <!DOCTYPE potato "" "taco"">
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato SYSTEM "taco">Hello
+#errors
+(1,31): unknown-doctype
+#document
+| <!DOCTYPE potato "" "taco">
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato SYSTEM "tai'co">Hello
+#errors
+(1,33): unknown-doctype
+#document
+| <!DOCTYPE potato "" "tai'co">
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato SYSTEMtaco "ddd">Hello
+#errors
+(1,24): unexpected-char-in-doctype
+(1,34): unknown-doctype
+#document
+| <!DOCTYPE potato>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato grass SYSTEM taco>Hello
+#errors
+(1,17): expected-space-or-right-bracket-in-doctype
+(1,35): unknown-doctype
+#document
+| <!DOCTYPE potato>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato pUbLIc>Hello
+#errors
+(1,24): unexpected-end-of-doctype
+(1,24): unknown-doctype
+#document
+| <!DOCTYPE potato>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato pUbLIc >Hello
+#errors
+(1,25): unexpected-end-of-doctype
+(1,25): unknown-doctype
+#document
+| <!DOCTYPE potato>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato pUbLIcgoof>Hello
+#errors
+(1,24): unexpected-char-in-doctype
+(1,28): unknown-doctype
+#document
+| <!DOCTYPE potato>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato PUBLIC goof>Hello
+#errors
+(1,25): unexpected-char-in-doctype
+(1,29): unknown-doctype
+#document
+| <!DOCTYPE potato>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato PUBLIC "go'of">Hello
+#errors
+(1,32): unknown-doctype
+#document
+| <!DOCTYPE potato "go'of" "">
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato PUBLIC 'go'of'>Hello
+#errors
+(1,29): unexpected-char-in-doctype
+(1,32): unknown-doctype
+#document
+| <!DOCTYPE potato "go" "">
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato PUBLIC 'go:hh of' >Hello
+#errors
+(1,38): unknown-doctype
+#document
+| <!DOCTYPE potato "go:hh of" "">
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE potato PUBLIC "W3C-//dfdf" SYSTEM ggg>Hello
+#errors
+(1,38): unexpected-char-in-doctype
+(1,48): unknown-doctype
+#document
+| <!DOCTYPE potato "W3C-//dfdf" "">
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">Hello
+#errors
+#document
+| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE ...>Hello
+#errors
+(1,14): unknown-doctype
+#document
+| <!DOCTYPE ...>
+| <html>
+| <head>
+| <body>
+| "Hello"
+
+#data
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+#errors
+(2,58): unknown-doctype
+#document
+| <!DOCTYPE html "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+| <html>
+| <head>
+| <body>
+
+#data
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+#errors
+(2,54): unknown-doctype
+#document
+| <!DOCTYPE html "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+| <html>
+| <head>
+| <body>
+
+#data
+<!DOCTYPE root-element [SYSTEM OR PUBLIC FPI] "uri" [
+<!-- internal declarations -->
+]>
+#errors
+(1,23): expected-space-or-right-bracket-in-doctype
+(2,30): unknown-doctype
+#document
+| <!DOCTYPE root-element>
+| <html>
+| <head>
+| <body>
+| "]>"
+
+#data
+<!DOCTYPE html PUBLIC
+ "-//WAPFORUM//DTD XHTML Mobile 1.0//EN"
+ "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
+#errors
+(3,53): unknown-doctype
+#document
+| <!DOCTYPE html "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
+| <html>
+| <head>
+| <body>
+
+#data
+<!DOCTYPE HTML SYSTEM "http://www.w3.org/DTD/HTML4-strict.dtd"><body><b>Mine!</b></body>
+#errors
+(1,63): unknown-doctype
+#document
+| <!DOCTYPE html "" "http://www.w3.org/DTD/HTML4-strict.dtd">
+| <html>
+| <head>
+| <body>
+| <b>
+| "Mine!"
+
+#data
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
+#errors
+(1,50): unexpected-char-in-doctype
+#document
+| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+| <html>
+| <head>
+| <body>
+
+#data
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"'http://www.w3.org/TR/html4/strict.dtd'>
+#errors
+(1,50): unexpected-char-in-doctype
+#document
+| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+| <html>
+| <head>
+| <body>
+
+#data
+<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.01//EN"'http://www.w3.org/TR/html4/strict.dtd'>
+#errors
+(1,21): unexpected-char-in-doctype
+(1,49): unexpected-char-in-doctype
+#document
+| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+| <html>
+| <head>
+| <body>
+
+#data
+<!DOCTYPE HTML PUBLIC'-//W3C//DTD HTML 4.01//EN''http://www.w3.org/TR/html4/strict.dtd'>
+#errors
+(1,21): unexpected-char-in-doctype
+(1,49): unexpected-char-in-doctype
+#document
+| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+| <html>
+| <head>
+| <body>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/domjs-unsafe.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/domjs-unsafe.dat
new file mode 100644
index 000000000..34b4e6271
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/domjs-unsafe.dat
Binary files differ
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/entities01.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/entities01.dat
new file mode 100644
index 000000000..b271f8220
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/entities01.dat
@@ -0,0 +1,792 @@
+#data
+FOO&gt;BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO>BAR"
+
+#data
+FOO&gtBAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,6): named-entity-without-semicolon
+#document
+| <html>
+| <head>
+| <body>
+| "FOO>BAR"
+
+#data
+FOO&gt BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,6): named-entity-without-semicolon
+#document
+| <html>
+| <head>
+| <body>
+| "FOO> BAR"
+
+#data
+FOO&gt;;;BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO>;;BAR"
+
+#data
+I'm &notit; I tell you
+#errors
+(1,4): expected-doctype-but-got-chars
+(1,9): named-entity-without-semicolon
+#document
+| <html>
+| <head>
+| <body>
+| "I'm ¬it; I tell you"
+
+#data
+I'm &notin; I tell you
+#errors
+(1,4): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "I'm ∉ I tell you"
+
+#data
+FOO& BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO& BAR"
+
+#data
+FOO&<BAR>
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,9): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| "FOO&"
+| <bar>
+
+#data
+FOO&&&&gt;BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO&&&>BAR"
+
+#data
+FOO&#41;BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO)BAR"
+
+#data
+FOO&#x41;BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOOABAR"
+
+#data
+FOO&#X41;BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOOABAR"
+
+#data
+FOO&#BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,5): expected-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO&#BAR"
+
+#data
+FOO&#ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,5): expected-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO&#ZOO"
+
+#data
+FOO&#xBAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,7): expected-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOºR"
+
+#data
+FOO&#xZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,6): expected-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO&#xZOO"
+
+#data
+FOO&#XZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,6): expected-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO&#XZOO"
+
+#data
+FOO&#41BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,7): numeric-entity-without-semicolon
+#document
+| <html>
+| <head>
+| <body>
+| "FOO)BAR"
+
+#data
+FOO&#x41BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,10): numeric-entity-without-semicolon
+#document
+| <html>
+| <head>
+| <body>
+| "FOO䆺R"
+
+#data
+FOO&#x41ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,8): numeric-entity-without-semicolon
+#document
+| <html>
+| <head>
+| <body>
+| "FOOAZOO"
+
+#data
+FOO&#x0000;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO�ZOO"
+
+#data
+FOO&#x0078;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOOxZOO"
+
+#data
+FOO&#x0079;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOOyZOO"
+
+#data
+FOO&#x0080;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO€ZOO"
+
+#data
+FOO&#x0081;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOÂZOO"
+
+#data
+FOO&#x0082;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO‚ZOO"
+
+#data
+FOO&#x0083;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOÆ’ZOO"
+
+#data
+FOO&#x0084;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO„ZOO"
+
+#data
+FOO&#x0085;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO…ZOO"
+
+#data
+FOO&#x0086;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO†ZOO"
+
+#data
+FOO&#x0087;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO‡ZOO"
+
+#data
+FOO&#x0088;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOˆZOO"
+
+#data
+FOO&#x0089;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO‰ZOO"
+
+#data
+FOO&#x008A;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOÅ ZOO"
+
+#data
+FOO&#x008B;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO‹ZOO"
+
+#data
+FOO&#x008C;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOÅ’ZOO"
+
+#data
+FOO&#x008D;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOÂZOO"
+
+#data
+FOO&#x008E;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOŽZOO"
+
+#data
+FOO&#x008F;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOÂZOO"
+
+#data
+FOO&#x0090;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOÂZOO"
+
+#data
+FOO&#x0091;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO‘ZOO"
+
+#data
+FOO&#x0092;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO’ZOO"
+
+#data
+FOO&#x0093;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO“ZOO"
+
+#data
+FOO&#x0094;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOâ€ZOO"
+
+#data
+FOO&#x0095;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO•ZOO"
+
+#data
+FOO&#x0096;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO–ZOO"
+
+#data
+FOO&#x0097;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO—ZOO"
+
+#data
+FOO&#x0098;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOËœZOO"
+
+#data
+FOO&#x0099;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOâ„¢ZOO"
+
+#data
+FOO&#x009A;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOÅ¡ZOO"
+
+#data
+FOO&#x009B;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO›ZOO"
+
+#data
+FOO&#x009C;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOÅ“ZOO"
+
+#data
+FOO&#x009D;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOÂZOO"
+
+#data
+FOO&#x009E;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOžZOO"
+
+#data
+FOO&#x009F;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOŸZOO"
+
+#data
+FOO&#x00A0;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO ZOO"
+
+#data
+FOO&#xD7FF;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO퟿ZOO"
+
+#data
+FOO&#xD800;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO�ZOO"
+
+#data
+FOO&#xD801;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO�ZOO"
+
+#data
+FOO&#xDFFE;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO�ZOO"
+
+#data
+FOO&#xDFFF;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,11): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO�ZOO"
+
+#data
+FOO&#xE000;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOOZOO"
+
+#data
+FOO&#x10FFFE;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,13): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOô¿¾ZOO"
+
+#data
+FOO&#x1087D4;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO􈟔ZOO"
+
+#data
+FOO&#x10FFFF;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,13): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOOô¿¿ZOO"
+
+#data
+FOO&#x110000;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,13): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO�ZOO"
+
+#data
+FOO&#xFFFFFF;ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,13): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO�ZOO"
+
+#data
+FOO&#11111111111
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,13): illegal-codepoint-for-numeric-entity
+(1,13): eof-in-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO�"
+
+#data
+FOO&#1111111111
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,13): illegal-codepoint-for-numeric-entity
+(1,13): eof-in-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO�"
+
+#data
+FOO&#111111111111
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,13): illegal-codepoint-for-numeric-entity
+(1,13): eof-in-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO�"
+
+#data
+FOO&#11111111111ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,13): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO�ZOO"
+
+#data
+FOO&#1111111111ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,13): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO�ZOO"
+
+#data
+FOO&#111111111111ZOO
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,13): illegal-codepoint-for-numeric-entity
+#document
+| <html>
+| <head>
+| <body>
+| "FOO�ZOO"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/entities02.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/entities02.dat
new file mode 100644
index 000000000..f117f068a
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/entities02.dat
@@ -0,0 +1,283 @@
+#data
+<div bar="ZZ&gt;YY"></div>
+#errors
+(1,20): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ>YY"
+
+#data
+<div bar="ZZ&"></div>
+#errors
+(1,15): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ&"
+
+#data
+<div bar='ZZ&'></div>
+#errors
+(1,15): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ&"
+
+#data
+<div bar=ZZ&></div>
+#errors
+(1,13): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ&"
+
+#data
+<div bar="ZZ&gt=YY"></div>
+#errors
+(1,15): named-entity-without-semicolon
+(1,20): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ&gt=YY"
+
+#data
+<div bar="ZZ&gt0YY"></div>
+#errors
+(1,20): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ&gt0YY"
+
+#data
+<div bar="ZZ&gt9YY"></div>
+#errors
+(1,20): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ&gt9YY"
+
+#data
+<div bar="ZZ&gtaYY"></div>
+#errors
+(1,20): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ&gtaYY"
+
+#data
+<div bar="ZZ&gtZYY"></div>
+#errors
+(1,20): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ&gtZYY"
+
+#data
+<div bar="ZZ&gt YY"></div>
+#errors
+(1,15): named-entity-without-semicolon
+(1,20): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ> YY"
+
+#data
+<div bar="ZZ&gt"></div>
+#errors
+(1,15): named-entity-without-semicolon
+(1,17): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ>"
+
+#data
+<div bar='ZZ&gt'></div>
+#errors
+(1,15): named-entity-without-semicolon
+(1,17): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ>"
+
+#data
+<div bar=ZZ&gt></div>
+#errors
+(1,14): named-entity-without-semicolon
+(1,15): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ>"
+
+#data
+<div bar="ZZ&pound_id=23"></div>
+#errors
+(1,18): named-entity-without-semicolon
+(1,26): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ£_id=23"
+
+#data
+<div bar="ZZ&prod_id=23"></div>
+#errors
+(1,25): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ&prod_id=23"
+
+#data
+<div bar="ZZ&pound;_id=23"></div>
+#errors
+(1,27): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ£_id=23"
+
+#data
+<div bar="ZZ&prod;_id=23"></div>
+#errors
+(1,26): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZâˆ_id=23"
+
+#data
+<div bar="ZZ&pound=23"></div>
+#errors
+(1,18): named-entity-without-semicolon
+(1,23): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ&pound=23"
+
+#data
+<div bar="ZZ&prod=23"></div>
+#errors
+(1,22): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| bar="ZZ&prod=23"
+
+#data
+<div>ZZ&pound_id=23</div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,13): named-entity-without-semicolon
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| "ZZ£_id=23"
+
+#data
+<div>ZZ&prod_id=23</div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| "ZZ&prod_id=23"
+
+#data
+<div>ZZ&pound;_id=23</div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| "ZZ£_id=23"
+
+#data
+<div>ZZ&prod;_id=23</div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| "ZZâˆ_id=23"
+
+#data
+<div>ZZ&pound=23</div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,13): named-entity-without-semicolon
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| "ZZ£=23"
+
+#data
+<div>ZZ&prod=23</div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| "ZZ&prod=23"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/foreign-fragment.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/foreign-fragment.dat
new file mode 100644
index 000000000..2e3cb6c6f
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/foreign-fragment.dat
@@ -0,0 +1,550 @@
+#data
+<nobr>X
+#errors
+6: HTML start tag “nobr†in a foreign namespace context.
+7: End of file seen and there were open elements.
+6: Unclosed element “nobrâ€.
+#document-fragment
+svg path
+#document
+| <svg nobr>
+| "X"
+
+#data
+<font color></font>X
+#errors
+12: HTML start tag “font†in a foreign namespace context.
+#document-fragment
+svg path
+#document
+| <svg font>
+| color=""
+| "X"
+
+#data
+<font></font>X
+#errors
+#document-fragment
+svg path
+#document
+| <svg font>
+| "X"
+
+#data
+<g></path>X
+#errors
+10: End tag “path†did not match the name of the current open element (“gâ€).
+11: End of file seen and there were open elements.
+3: Unclosed element “gâ€.
+#document-fragment
+svg path
+#document
+| <svg g>
+| "X"
+
+#data
+</path>X
+#errors
+5: Stray end tag “pathâ€.
+#document-fragment
+svg path
+#document
+| "X"
+
+#data
+</foreignObject>X
+#errors
+5: Stray end tag “foreignobjectâ€.
+#document-fragment
+svg foreignObject
+#document
+| "X"
+
+#data
+</desc>X
+#errors
+5: Stray end tag “descâ€.
+#document-fragment
+svg desc
+#document
+| "X"
+
+#data
+</title>X
+#errors
+5: Stray end tag “titleâ€.
+#document-fragment
+svg title
+#document
+| "X"
+
+#data
+</svg>X
+#errors
+5: Stray end tag “svgâ€.
+#document-fragment
+svg svg
+#document
+| "X"
+
+#data
+</mfenced>X
+#errors
+5: Stray end tag “mfencedâ€.
+#document-fragment
+math mfenced
+#document
+| "X"
+
+#data
+</malignmark>X
+#errors
+5: Stray end tag “malignmarkâ€.
+#document-fragment
+math malignmark
+#document
+| "X"
+
+#data
+</math>X
+#errors
+5: Stray end tag “mathâ€.
+#document-fragment
+math math
+#document
+| "X"
+
+#data
+</annotation-xml>X
+#errors
+5: Stray end tag “annotation-xmlâ€.
+#document-fragment
+math annotation-xml
+#document
+| "X"
+
+#data
+</mtext>X
+#errors
+5: Stray end tag “mtextâ€.
+#document-fragment
+math mtext
+#document
+| "X"
+
+#data
+</mi>X
+#errors
+5: Stray end tag “miâ€.
+#document-fragment
+math mi
+#document
+| "X"
+
+#data
+</mo>X
+#errors
+5: Stray end tag “moâ€.
+#document-fragment
+math mo
+#document
+| "X"
+
+#data
+</mn>X
+#errors
+5: Stray end tag “mnâ€.
+#document-fragment
+math mn
+#document
+| "X"
+
+#data
+</ms>X
+#errors
+5: Stray end tag “msâ€.
+#document-fragment
+math ms
+#document
+| "X"
+
+#data
+<b></b><mglyph/><i></i><malignmark/><u></u><ms/>X
+#errors
+51: Self-closing syntax (“/>â€) used on a non-void HTML element. Ignoring the slash and treating as a start tag.
+52: End of file seen and there were open elements.
+51: Unclosed element “msâ€.
+#document-fragment
+math ms
+#document
+| <b>
+| <math mglyph>
+| <i>
+| <math malignmark>
+| <u>
+| <ms>
+| "X"
+
+#data
+<malignmark></malignmark>
+#errors
+#document-fragment
+math ms
+#document
+| <math malignmark>
+
+#data
+<div></div>
+#errors
+#document-fragment
+math ms
+#document
+| <div>
+
+#data
+<figure></figure>
+#errors
+#document-fragment
+math ms
+#document
+| <figure>
+
+#data
+<b></b><mglyph/><i></i><malignmark/><u></u><mn/>X
+#errors
+51: Self-closing syntax (“/>â€) used on a non-void HTML element. Ignoring the slash and treating as a start tag.
+52: End of file seen and there were open elements.
+51: Unclosed element “mnâ€.
+#document-fragment
+math mn
+#document
+| <b>
+| <math mglyph>
+| <i>
+| <math malignmark>
+| <u>
+| <mn>
+| "X"
+
+#data
+<malignmark></malignmark>
+#errors
+#document-fragment
+math mn
+#document
+| <math malignmark>
+
+#data
+<div></div>
+#errors
+#document-fragment
+math mn
+#document
+| <div>
+
+#data
+<figure></figure>
+#errors
+#document-fragment
+math mn
+#document
+| <figure>
+
+#data
+<b></b><mglyph/><i></i><malignmark/><u></u><mo/>X
+#errors
+51: Self-closing syntax (“/>â€) used on a non-void HTML element. Ignoring the slash and treating as a start tag.
+52: End of file seen and there were open elements.
+51: Unclosed element “moâ€.
+#document-fragment
+math mo
+#document
+| <b>
+| <math mglyph>
+| <i>
+| <math malignmark>
+| <u>
+| <mo>
+| "X"
+
+#data
+<malignmark></malignmark>
+#errors
+#document-fragment
+math mo
+#document
+| <math malignmark>
+
+#data
+<div></div>
+#errors
+#document-fragment
+math mo
+#document
+| <div>
+
+#data
+<figure></figure>
+#errors
+#document-fragment
+math mo
+#document
+| <figure>
+
+#data
+<b></b><mglyph/><i></i><malignmark/><u></u><mi/>X
+#errors
+51: Self-closing syntax (“/>â€) used on a non-void HTML element. Ignoring the slash and treating as a start tag.
+52: End of file seen and there were open elements.
+51: Unclosed element “miâ€.
+#document-fragment
+math mi
+#document
+| <b>
+| <math mglyph>
+| <i>
+| <math malignmark>
+| <u>
+| <mi>
+| "X"
+
+#data
+<malignmark></malignmark>
+#errors
+#document-fragment
+math mi
+#document
+| <math malignmark>
+
+#data
+<div></div>
+#errors
+#document-fragment
+math mi
+#document
+| <div>
+
+#data
+<figure></figure>
+#errors
+#document-fragment
+math mi
+#document
+| <figure>
+
+#data
+<b></b><mglyph/><i></i><malignmark/><u></u><mtext/>X
+#errors
+51: Self-closing syntax (“/>â€) used on a non-void HTML element. Ignoring the slash and treating as a start tag.
+52: End of file seen and there were open elements.
+51: Unclosed element “mtextâ€.
+#document-fragment
+math mtext
+#document
+| <b>
+| <math mglyph>
+| <i>
+| <math malignmark>
+| <u>
+| <mtext>
+| "X"
+
+#data
+<malignmark></malignmark>
+#errors
+#document-fragment
+math mtext
+#document
+| <math malignmark>
+
+#data
+<div></div>
+#errors
+#document-fragment
+math mtext
+#document
+| <div>
+
+#data
+<figure></figure>
+#errors
+#document-fragment
+math mtext
+#document
+| <figure>
+
+#data
+<div></div>
+#errors
+5: HTML start tag “div†in a foreign namespace context.
+#document-fragment
+math annotation-xml
+#document
+| <math div>
+
+#data
+<figure></figure>
+#errors
+#document-fragment
+math annotation-xml
+#document
+| <math figure>
+
+#data
+<div></div>
+#errors
+5: HTML start tag “div†in a foreign namespace context.
+#document-fragment
+math math
+#document
+| <math div>
+
+#data
+<figure></figure>
+#errors
+#document-fragment
+math math
+#document
+| <math figure>
+
+#data
+<div></div>
+#errors
+#document-fragment
+svg foreignObject
+#document
+| <div>
+
+#data
+<figure></figure>
+#errors
+#document-fragment
+svg foreignObject
+#document
+| <figure>
+
+#data
+<div></div>
+#errors
+#document-fragment
+svg title
+#document
+| <div>
+
+#data
+<figure></figure>
+#errors
+#document-fragment
+svg title
+#document
+| <figure>
+
+#data
+<figure></figure>
+#errors
+#document-fragment
+svg desc
+#document
+| <figure>
+
+#data
+<div><h1>X</h1></div>
+#errors
+5: HTML start tag “div†in a foreign namespace context.
+9: HTML start tag “h1†in a foreign namespace context.
+#document-fragment
+svg svg
+#document
+| <svg div>
+| <svg h1>
+| "X"
+
+#data
+<div></div>
+#errors
+5: HTML start tag “div†in a foreign namespace context.
+#document-fragment
+svg svg
+#document
+| <svg div>
+
+#data
+<div></div>
+#errors
+#document-fragment
+svg desc
+#document
+| <div>
+
+#data
+<figure></figure>
+#errors
+#document-fragment
+svg desc
+#document
+| <figure>
+
+#data
+<plaintext><foo>
+#errors
+16: End of file seen and there were open elements.
+11: Unclosed element “plaintextâ€.
+#document-fragment
+svg desc
+#document
+| <plaintext>
+| "<foo>"
+
+#data
+<frameset>X
+#errors
+6: Stray start tag “framesetâ€.
+#document-fragment
+svg desc
+#document
+| "X"
+
+#data
+<head>X
+#errors
+6: Stray start tag “headâ€.
+#document-fragment
+svg desc
+#document
+| "X"
+
+#data
+<body>X
+#errors
+6: Stray start tag “bodyâ€.
+#document-fragment
+svg desc
+#document
+| "X"
+
+#data
+<html>X
+#errors
+6: Stray start tag “htmlâ€.
+#document-fragment
+svg desc
+#document
+| "X"
+
+#data
+<html class="foo">X
+#errors
+6: Stray start tag “htmlâ€.
+#document-fragment
+svg desc
+#document
+| "X"
+
+#data
+<body class="foo">X
+#errors
+6: Stray start tag “bodyâ€.
+#document-fragment
+svg desc
+#document
+| "X"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/html5lib_license.txt b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/html5lib_license.txt
new file mode 100644
index 000000000..63faa963e
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/html5lib_license.txt
@@ -0,0 +1,21 @@
+Copyright (c) 2006-2010 The Authors
+
+Contributors:
+James Graham - jg307@cam.ac.uk
+Anne van Kesteren - annevankesteren@gmail.com
+Lachlan Hunt - lachlan.hunt@lachy.id.au
+Matt McDonald - kanashii@kanashii.ca
+Sam Ruby - rubys@intertwingly.net
+Ian Hickson (Google) - ian@hixie.ch
+Thomas Broyer - t.broyer@ltgt.net
+Jacques Distler - distler@golem.ph.utexas.edu
+Henri Sivonen - hsivonen@iki.fi
+Adam Barth - abarth@webkit.org
+Eric Seidel - eric@webkit.org
+The Mozilla Foundation (contributions from Henri Sivonen since 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/html5lib_upstream.txt b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/html5lib_upstream.txt
new file mode 100644
index 000000000..5b466c614
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/html5lib_upstream.txt
@@ -0,0 +1,11 @@
+The test data in this directory comes from the html5lib project
+(http://code.google.com/p/html5lib/). Please avoid making
+mozilla-central-specific changes to these files. If Gecko doesn't pass a test,
+please add the test's input data to ../html5_tree_construction_exceptions.js
+instead of removing it.
+
+If you add or edit tests, please push the test to upstream and then
+resynchronize this directory with the upstream.
+
+See html5lib_license.txt for the license that covers the files in this
+directory.
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/html5test-com.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/html5test-com.dat
new file mode 100644
index 000000000..8c6ec40cd
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/html5test-com.dat
@@ -0,0 +1,291 @@
+#data
+<div<div>
+#errors
+(1,9): expected-doctype-but-got-start-tag
+(1,9): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div<div>
+
+#data
+<div foo<bar=''>
+#errors
+(1,9): invalid-character-in-attribute-name
+(1,16): expected-doctype-but-got-start-tag
+(1,16): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| foo<bar=""
+
+#data
+<div foo=`bar`>
+#errors
+(1,10): equals-in-unquoted-attribute-value
+(1,14): unexpected-character-in-unquoted-attribute-value
+(1,15): expected-doctype-but-got-start-tag
+(1,15): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| foo="`bar`"
+
+#data
+<div \"foo=''>
+#errors
+(1,7): invalid-character-in-attribute-name
+(1,14): expected-doctype-but-got-start-tag
+(1,14): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| \"foo=""
+
+#data
+<a href='\nbar'></a>
+#errors
+(1,16): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| href="\nbar"
+
+#data
+<!DOCTYPE html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+
+#data
+&lang;&rang;
+#errors
+(1,6): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "⟨⟩"
+
+#data
+&apos;
+#errors
+(1,6): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "'"
+
+#data
+&ImaginaryI;
+#errors
+(1,12): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "â…ˆ"
+
+#data
+&Kopf;
+#errors
+(1,6): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "ð•‚"
+
+#data
+&notinva;
+#errors
+(1,9): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "∉"
+
+#data
+<?import namespace="foo" implementation="#bar">
+#errors
+(1,1): expected-tag-name-but-got-question-mark
+(1,47): expected-doctype-but-got-eof
+#document
+| <!-- ?import namespace="foo" implementation="#bar" -->
+| <html>
+| <head>
+| <body>
+
+#data
+<!--foo--bar-->
+#errors
+(1,10): unexpected-char-in-comment
+(1,15): expected-doctype-but-got-eof
+#document
+| <!-- foo--bar -->
+| <html>
+| <head>
+| <body>
+
+#data
+<![CDATA[x]]>
+#errors
+(1,2): expected-dashes-or-doctype
+(1,13): expected-doctype-but-got-eof
+#document
+| <!-- [CDATA[x]] -->
+| <html>
+| <head>
+| <body>
+
+#data
+<textarea><!--</textarea>--></textarea>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(1,39): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <textarea>
+| "<!--"
+| "-->"
+
+#data
+<textarea><!--</textarea>-->
+#errors
+(1,10): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <textarea>
+| "<!--"
+| "-->"
+
+#data
+<style><!--</style>--></style>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,30): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <style>
+| "<!--"
+| <body>
+| "-->"
+
+#data
+<style><!--</style>-->
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <style>
+| "<!--"
+| <body>
+| "-->"
+
+#data
+<ul><li>A </li> <li>B</li></ul>
+#errors
+(1,4): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ul>
+| <li>
+| "A "
+| " "
+| <li>
+| "B"
+
+#data
+<table><form><input type=hidden><input></form><div></div></table>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,13): unexpected-form-in-table
+(1,32): unexpected-hidden-input-in-table
+(1,39): unexpected-start-tag-implies-table-voodoo
+(1,46): unexpected-end-tag-implies-table-voodoo
+(1,46): unexpected-end-tag
+(1,51): unexpected-start-tag-implies-table-voodoo
+(1,57): unexpected-end-tag-implies-table-voodoo
+#document
+| <html>
+| <head>
+| <body>
+| <input>
+| <div>
+| <table>
+| <form>
+| <input>
+| type="hidden"
+
+#data
+<i>A<b>B<p></i>C</b>D
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,15): adoption-agency-1.3
+(1,20): adoption-agency-1.3
+#document
+| <html>
+| <head>
+| <body>
+| <i>
+| "A"
+| <b>
+| "B"
+| <b>
+| <p>
+| <b>
+| <i>
+| "C"
+| "D"
+
+#data
+<div></div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+
+#data
+<svg></svg>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+
+#data
+<math></math>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/inbody01.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/inbody01.dat
new file mode 100644
index 000000000..10f6520f6
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/inbody01.dat
@@ -0,0 +1,54 @@
+#data
+<button>1</foo>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,15): unexpected-end-tag
+(1,15): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <button>
+| "1"
+
+#data
+<foo>1<p>2</foo>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,16): unexpected-end-tag
+(1,16): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <foo>
+| "1"
+| <p>
+| "2"
+
+#data
+<dd>1</foo>
+#errors
+(1,4): expected-doctype-but-got-start-tag
+(1,11): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <dd>
+| "1"
+
+#data
+<foo>1<dd>2</foo>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,17): unexpected-end-tag
+(1,17): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <foo>
+| "1"
+| <dd>
+| "2"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/isindex.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/isindex.dat
new file mode 100644
index 000000000..b187e11b7
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/isindex.dat
@@ -0,0 +1,67 @@
+#data
+<isindex>
+#errors
+(1,9): expected-doctype-but-got-start-tag
+(1,9): deprecated-tag
+#document
+| <html>
+| <head>
+| <body>
+| <form>
+| <hr>
+| <label>
+| "This is a searchable index. Enter search keywords: "
+| <input>
+| name="isindex"
+| <hr>
+
+#data
+<isindex name="A" action="B" prompt="C" foo="D">
+#errors
+(1,48): expected-doctype-but-got-start-tag
+(1,48): deprecated-tag
+#document
+| <html>
+| <head>
+| <body>
+| <form>
+| action="B"
+| <hr>
+| <label>
+| "C"
+| <input>
+| foo="D"
+| name="isindex"
+| <hr>
+
+#data
+<form><isindex>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,15): deprecated-tag
+(1,15): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <form>
+
+#data
+<body><isindex><form>
+#errors
+6: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>â€.
+15: “isindex†seen.
+21: End of file seen and there were open elements.
+21: Unclosed element “formâ€.
+#document
+| <html>
+| <head>
+| <body>
+| <form>
+| <hr>
+| <label>
+| "This is a searchable index. Enter search keywords: "
+| <input>
+| name="isindex"
+| <hr>
+| <form>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/main-element.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/main-element.dat
new file mode 100644
index 000000000..0d2102ed3
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/main-element.dat
@@ -0,0 +1,44 @@
+#data
+<!doctype html><p>foo<main>bar<p>baz
+#errors
+(1,36): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| "foo"
+| <main>
+| "bar"
+| <p>
+| "baz"
+
+#data
+<!doctype html><main><p>foo</main>bar
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <main>
+| <p>
+| "foo"
+| "bar"
+
+#data
+<!DOCTYPE html>xxx<svg><x><g><a><main><b>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "xxx"
+| <svg svg>
+| <svg x>
+| <svg g>
+| <svg a>
+| <svg main>
+| <b>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/pending-spec-changes-plain-text-unsafe.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/pending-spec-changes-plain-text-unsafe.dat
new file mode 100644
index 000000000..3ee8cec90
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/pending-spec-changes-plain-text-unsafe.dat
Binary files differ
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/pending-spec-changes.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/pending-spec-changes.dat
new file mode 100644
index 000000000..1647d7f23
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/pending-spec-changes.dat
@@ -0,0 +1,46 @@
+#data
+<input type="hidden"><frameset>
+#errors
+(1,21): expected-doctype-but-got-start-tag
+(1,31): unexpected-start-tag
+(1,31): eof-in-frameset
+#document
+| <html>
+| <head>
+| <frameset>
+
+#data
+<!DOCTYPE html><table><caption><svg>foo</table>bar
+#errors
+(1,47): unexpected-end-tag
+(1,47): end-table-tag-in-caption
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+| <svg svg>
+| "foo"
+| "bar"
+
+#data
+<table><tr><td><svg><desc><td></desc><circle>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,30): unexpected-cell-end-tag
+(1,37): unexpected-end-tag
+(1,45): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <svg svg>
+| <svg desc>
+| <td>
+| <circle>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/plain-text-unsafe.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/plain-text-unsafe.dat
new file mode 100644
index 000000000..f40dd5760
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/plain-text-unsafe.dat
Binary files differ
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/ruby.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/ruby.dat
new file mode 100644
index 000000000..1ca8016cf
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/ruby.dat
@@ -0,0 +1,298 @@
+#data
+<html><ruby>a<rb>b<rb></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rb>
+| "b"
+| <rb>
+
+#data
+<html><ruby>a<rb>b<rt></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rb>
+| "b"
+| <rt>
+
+#data
+<html><ruby>a<rb>b<rtc></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rb>
+| "b"
+| <rtc>
+
+#data
+<html><ruby>a<rb>b<rp></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rb>
+| "b"
+| <rp>
+
+#data
+<html><ruby>a<rb>b<span></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rb>
+| "b"
+| <span>
+
+#data
+<html><ruby>a<rt>b<rb></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rt>
+| "b"
+| <rb>
+
+#data
+<html><ruby>a<rt>b<rt></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rt>
+| "b"
+| <rt>
+
+#data
+<html><ruby>a<rt>b<rtc></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rt>
+| "b"
+| <rtc>
+
+#data
+<html><ruby>a<rt>b<rp></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rt>
+| "b"
+| <rp>
+
+#data
+<html><ruby>a<rt>b<span></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rt>
+| "b"
+| <span>
+
+#data
+<html><ruby>a<rtc>b<rb></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rtc>
+| "b"
+| <rb>
+
+#data
+<html><ruby>a<rtc>b<rt>c<rt>d</ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rtc>
+| "b"
+| <rt>
+| "c"
+| <rt>
+| "d"
+
+#data
+<html><ruby>a<rtc>b<rtc></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rtc>
+| "b"
+| <rtc>
+
+#data
+<html><ruby>a<rtc>b<rp></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rtc>
+| "b"
+| <rp>
+
+#data
+<html><ruby>a<rtc>b<span></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rtc>
+| "b"
+| <span>
+
+#data
+<html><ruby>a<rp>b<rb></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rp>
+| "b"
+| <rb>
+
+#data
+<html><ruby>a<rp>b<rt></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rp>
+| "b"
+| <rt>
+
+#data
+<html><ruby>a<rp>b<rtc></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rp>
+| "b"
+| <rtc>
+
+#data
+<html><ruby>a<rp>b<rp></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rp>
+| "b"
+| <rp>
+
+#data
+<html><ruby>a<rp>b<span></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rp>
+| "b"
+| <span>
+
+#data
+<html><ruby><rtc><ruby>a<rb>b<rt></ruby></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| <rtc>
+| <ruby>
+| "a"
+| <rb>
+| "b"
+| <rt>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/scriptdata01.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/scriptdata01.dat
new file mode 100644
index 000000000..710f5414b
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/scriptdata01.dat
@@ -0,0 +1,352 @@
+#data
+FOO<script>'Hello'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "'Hello'"
+| "BAR"
+
+#data
+FOO<script></script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "BAR"
+
+#data
+FOO<script></script >BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "BAR"
+
+#data
+FOO<script></script/>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,21): self-closing-flag-on-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "BAR"
+
+#data
+FOO<script></script/ >BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,20): unexpected-character-after-solidus-in-tag
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "BAR"
+
+#data
+FOO<script type="text/plain"></scriptx>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,42): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| type="text/plain"
+| "</scriptx>BAR"
+
+#data
+FOO<script></script foo=">" dd>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,31): attributes-in-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "BAR"
+
+#data
+FOO<script>'<'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "'<'"
+| "BAR"
+
+#data
+FOO<script>'<!'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "'<!'"
+| "BAR"
+
+#data
+FOO<script>'<!-'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "'<!-'"
+| "BAR"
+
+#data
+FOO<script>'<!--'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "'<!--'"
+| "BAR"
+
+#data
+FOO<script>'<!---'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "'<!---'"
+| "BAR"
+
+#data
+FOO<script>'<!-->'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "'<!-->'"
+| "BAR"
+
+#data
+FOO<script>'<!-->'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "'<!-->'"
+| "BAR"
+
+#data
+FOO<script>'<!-- potato'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "'<!-- potato'"
+| "BAR"
+
+#data
+FOO<script>'<!-- <sCrIpt'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "'<!-- <sCrIpt'"
+| "BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt>'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,56): expected-script-data-but-got-eof
+(1,56): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| type="text/plain"
+| "'<!-- <sCrIpt>'</script>BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt> -'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,58): expected-script-data-but-got-eof
+(1,58): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| type="text/plain"
+| "'<!-- <sCrIpt> -'</script>BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt> --'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,59): expected-script-data-but-got-eof
+(1,59): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| type="text/plain"
+| "'<!-- <sCrIpt> --'</script>BAR"
+
+#data
+FOO<script>'<!-- <sCrIpt> -->'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| "'<!-- <sCrIpt> -->'"
+| "BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt> --!>'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,61): expected-script-data-but-got-eof
+(1,61): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| type="text/plain"
+| "'<!-- <sCrIpt> --!>'</script>BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt> -- >'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,61): expected-script-data-but-got-eof
+(1,61): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| type="text/plain"
+| "'<!-- <sCrIpt> -- >'</script>BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt '</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,56): expected-script-data-but-got-eof
+(1,56): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| type="text/plain"
+| "'<!-- <sCrIpt '</script>BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt/'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+(1,56): expected-script-data-but-got-eof
+(1,56): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| type="text/plain"
+| "'<!-- <sCrIpt/'</script>BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt\'</script>BAR
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| type="text/plain"
+| "'<!-- <sCrIpt\'"
+| "BAR"
+
+#data
+FOO<script type="text/plain">'<!-- <sCrIpt/'</script>BAR</script>QUX
+#errors
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "FOO"
+| <script>
+| type="text/plain"
+| "'<!-- <sCrIpt/'</script>BAR"
+| "QUX"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/scripted/adoption01.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/scripted/adoption01.dat
new file mode 100644
index 000000000..4e08d0e84
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/scripted/adoption01.dat
@@ -0,0 +1,15 @@
+#data
+<p><b id="A"><script>document.getElementById("A").id = "B"</script></p>TEXT</b>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <b>
+| id="B"
+| <script>
+| "document.getElementById("A").id = "B""
+| <b>
+| id="A"
+| "TEXT"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/scripted/ark.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/scripted/ark.dat
new file mode 100644
index 000000000..acbac41df
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/scripted/ark.dat
@@ -0,0 +1,26 @@
+#data
+<p><font size=4><font size=4><font size=4><script>document.getElementsByTagName("font")[2].setAttribute("size", "5");</script><font size=4><p>X
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <font>
+| size="5"
+| <script>
+| "document.getElementsByTagName("font")[2].setAttribute("size", "5");"
+| <font>
+| size="4"
+| <p>
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <font>
+| size="4"
+| "X"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/scripted/webkit01.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/scripted/webkit01.dat
new file mode 100644
index 000000000..ef4a41ca0
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/scripted/webkit01.dat
@@ -0,0 +1,28 @@
+#data
+1<script>document.write("2")</script>3
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| "1"
+| <script>
+| "document.write("2")"
+| "23"
+
+#data
+1<script>document.write("<script>document.write('2')</scr"+ "ipt><script>document.write('3')</scr" + "ipt>")</script>4
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| "1"
+| <script>
+| "document.write("<script>document.write('2')</scr"+ "ipt><script>document.write('3')</scr" + "ipt>")"
+| <script>
+| "document.write('2')"
+| "2"
+| <script>
+| "document.write('3')"
+| "34"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tables01.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tables01.dat
new file mode 100644
index 000000000..f0caaa3c5
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tables01.dat
@@ -0,0 +1,286 @@
+#data
+<table><th>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,11): unexpected-cell-in-table-body
+(1,11): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <th>
+
+#data
+<table><td>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,11): unexpected-cell-in-table-body
+(1,11): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+
+#data
+<table><col foo='bar'>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,22): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <colgroup>
+| <col>
+| foo="bar"
+
+#data
+<table><colgroup></html>foo
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,24): unexpected-end-tag
+(1,27): foster-parenting-character-in-table
+(1,27): foster-parenting-character-in-table
+(1,27): foster-parenting-character-in-table
+(1,27): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| "foo"
+| <table>
+| <colgroup>
+
+#data
+<table></table><p>foo
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <p>
+| "foo"
+
+#data
+<table></body></caption></col></colgroup></html></tbody></td></tfoot></th></thead></tr><td>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,14): unexpected-end-tag
+(1,24): unexpected-end-tag
+(1,30): unexpected-end-tag
+(1,41): unexpected-end-tag
+(1,48): unexpected-end-tag
+(1,56): unexpected-end-tag
+(1,61): unexpected-end-tag
+(1,69): unexpected-end-tag
+(1,74): unexpected-end-tag
+(1,82): unexpected-end-tag
+(1,87): unexpected-end-tag
+(1,91): unexpected-cell-in-table-body
+(1,91): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+
+#data
+<table><select><option>3</select></table>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,15): unexpected-start-tag-implies-table-voodoo
+#document
+| <html>
+| <head>
+| <body>
+| <select>
+| <option>
+| "3"
+| <table>
+
+#data
+<table><select><table></table></select></table>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,15): unexpected-start-tag-implies-table-voodoo
+(1,22): unexpected-table-element-start-tag-in-select-in-table
+(1,22): unexpected-start-tag-implies-end-tag
+(1,39): unexpected-end-tag
+(1,47): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <select>
+| <table>
+| <table>
+
+#data
+<table><select></table>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,15): unexpected-start-tag-implies-table-voodoo
+(1,23): unexpected-table-element-end-tag-in-select-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <select>
+| <table>
+
+#data
+<table><select><option>A<tr><td>B</td></tr></table>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,15): unexpected-start-tag-implies-table-voodoo
+(1,28): unexpected-table-element-start-tag-in-select-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <select>
+| <option>
+| "A"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| "B"
+
+#data
+<table><td></body></caption></col></colgroup></html>foo
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,11): unexpected-cell-in-table-body
+(1,18): unexpected-end-tag
+(1,28): unexpected-end-tag
+(1,34): unexpected-end-tag
+(1,45): unexpected-end-tag
+(1,52): unexpected-end-tag
+(1,55): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| "foo"
+
+#data
+<table><td>A</table>B
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,11): unexpected-cell-in-table-body
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| "A"
+| "B"
+
+#data
+<table><tr><caption>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,20): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <caption>
+
+#data
+<table><tr></body></caption></col></colgroup></html></td></th><td>foo
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,18): unexpected-end-tag-in-table-row
+(1,28): unexpected-end-tag-in-table-row
+(1,34): unexpected-end-tag-in-table-row
+(1,45): unexpected-end-tag-in-table-row
+(1,52): unexpected-end-tag-in-table-row
+(1,57): unexpected-end-tag-in-table-row
+(1,62): unexpected-end-tag-in-table-row
+(1,69): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| "foo"
+
+#data
+<table><td><tr>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,11): unexpected-cell-in-table-body
+(1,15): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <tr>
+
+#data
+<table><td><button><td>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,11): unexpected-cell-in-table-body
+(1,23): unexpected-cell-end-tag
+(1,23): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <button>
+| <td>
+
+#data
+<table><tr><td><svg><desc><td>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,30): unexpected-cell-end-tag
+(1,30): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <svg svg>
+| <svg desc>
+| <td>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/template.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/template.dat
new file mode 100644
index 000000000..a4235681f
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/template.dat
@@ -0,0 +1,1418 @@
+#data
+<body><template>Hello</template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| "Hello"
+
+#data
+<template>Hello</template>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| "Hello"
+| <body>
+
+#data
+<template></template><div></div>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <body>
+| <div>
+
+#data
+<html><template>Hello</template>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| "Hello"
+| <body>
+
+#data
+<head><template><div></div></template></head>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <div>
+| <body>
+
+#data
+<div><template><div><span></template><b>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <template>
+| content
+| <div>
+| <span>
+| <b>
+
+#data
+<div><template></div>Hello
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <template>
+| content
+| "Hello"
+
+#data
+<div></template></div>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+
+#data
+<table><template></template></table>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <template>
+| content
+
+#data
+<table><template></template></div>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <template>
+| content
+
+#data
+<table><div><template></template></div>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <template>
+| content
+| <table>
+
+#data
+<table><template></template><div></div>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <table>
+| <template>
+| content
+
+#data
+<table> <template></template></table>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| " "
+| <template>
+| content
+
+#data
+<table><tbody><template></template></tbody>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <template>
+| content
+
+#data
+<table><tbody><template></tbody></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <template>
+| content
+
+#data
+<table><tbody><template></template></tbody></table>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <template>
+| content
+
+#data
+<table><thead><template></template></thead>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <thead>
+| <template>
+| content
+
+#data
+<table><tfoot><template></template></tfoot>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tfoot>
+| <template>
+| content
+
+#data
+<select><template></template></select>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <select>
+| <template>
+| content
+
+#data
+<select><template><option></option></template></select>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <select>
+| <template>
+| content
+| <option>
+
+#data
+<template><option></option></select><option></option></template>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <option>
+| <option>
+| <body>
+
+#data
+<select><template></template><option></select>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <select>
+| <template>
+| content
+| <option>
+
+#data
+<select><option><template></template></select>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <select>
+| <option>
+| <template>
+| content
+
+#data
+<select><template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <select>
+| <template>
+| content
+
+#data
+<select><option></option><template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <select>
+| <option>
+| <template>
+| content
+
+#data
+<select><option></option><template><option>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <select>
+| <option>
+| <template>
+| content
+| <option>
+
+#data
+<table><thead><template><td></template></table>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <thead>
+| <template>
+| content
+| <td>
+
+#data
+<table><template><thead></template></table>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <template>
+| content
+| <thead>
+
+#data
+<body><table><template><td></tr><div></template></table>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <template>
+| content
+| <td>
+| <div>
+
+#data
+<table><template><thead></template></thead></table>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <template>
+| content
+| <thead>
+
+#data
+<table><thead><template><tr></template></table>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <thead>
+| <template>
+| content
+| <tr>
+
+#data
+<table><template><tr></template></table>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <template>
+| content
+| <tr>
+
+#data
+<table><tr><template><td>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <template>
+| content
+| <td>
+
+#data
+<table><template><tr><template><td></template></tr></template></table>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <template>
+| content
+| <tr>
+| <template>
+| content
+| <td>
+
+#data
+<table><template><tr><template><td></td></template></tr></template></table>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <template>
+| content
+| <tr>
+| <template>
+| content
+| <td>
+
+#data
+<table><template><td></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <template>
+| content
+| <td>
+
+#data
+<body><template><td></td></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <td>
+
+#data
+<body><template><template><tr></tr></template><td></td></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <template>
+| content
+| <tr>
+| <td>
+
+#data
+<table><colgroup><template><col>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <colgroup>
+| <template>
+| content
+| <col>
+
+#data
+<frameset><template><frame></frame></template></frameset>
+#errors
+#document
+| <html>
+| <head>
+| <frameset>
+| <frame>
+
+#data
+<template><frame></frame></frameset><frame></frame></template>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <body>
+
+#data
+<template><div><frameset><span></span></div><span></span></template>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <div>
+| <span>
+| <span>
+| <body>
+
+#data
+<body><template><div><frameset><span></span></div><span></span></template></body>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <div>
+| <span>
+| <span>
+
+#data
+<body><template><script>var i = 1;</script><td></td></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <script>
+| "var i = 1;"
+| <td>
+
+#data
+<body><template><tr><div></div></tr></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <tr>
+| <div>
+
+#data
+<body><template><tr>Foo</tr></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <tr>
+| "Foo"
+
+#data
+<body><template><tr></tr><td></td></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <tr>
+| <tr>
+| <td>
+
+#data
+<body><template><td></td></tr><td></td></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <td>
+| <td>
+
+#data
+<body><template><td></td><tbody><td></td></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <td>
+| <td>
+
+#data
+<body><template><td></td><caption></caption><td></td></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <td>
+| <td>
+
+#data
+<body><template><td></td><colgroup></caption><td></td></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <td>
+| <td>
+
+#data
+<body><template><td></td></table><td></td></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <td>
+| <td>
+
+#data
+<body><template><tr></tr><tbody><tr></tr></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <tr>
+| <tr>
+
+#data
+<body><template><tr></tr><caption><tr></tr></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <tr>
+| <tr>
+
+#data
+<body><template><tr></tr></table><tr></tr></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <tr>
+| <tr>
+
+#data
+<body><template><thead></thead><caption></caption><tbody></tbody></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <thead>
+| <caption>
+| <tbody>
+
+#data
+<body><template><thead></thead></table><tbody></tbody></template></body>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <thead>
+| <tbody>
+
+#data
+<body><template><div><tr></tr></div></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <div>
+
+#data
+<body><template><em>Hello</em></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <em>
+| "Hello"
+
+#data
+<body><template><!--comment--></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <!-- comment -->
+
+#data
+<body><template><style></style><td></td></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <style>
+| <td>
+
+#data
+<body><template><meta><td></td></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <meta>
+| <td>
+
+#data
+<body><template><link><td></td></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <link>
+| <td>
+
+#data
+<body><template><template><tr></tr></template><td></td></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <template>
+| content
+| <tr>
+| <td>
+
+#data
+<body><table><colgroup><template><col></col></template></colgroup></table></body>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <colgroup>
+| <template>
+| content
+| <col>
+
+#data
+<body a=b><template><div></div><body c=d><div></div></body></template></body>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| a="b"
+| <template>
+| content
+| <div>
+| <div>
+
+#data
+<html a=b><template><div><html b=c><span></template>
+#errors
+#document
+| <html>
+| a="b"
+| <head>
+| <template>
+| content
+| <div>
+| <span>
+| <body>
+
+#data
+<html a=b><template><col></col><html b=c><col></col></template>
+#errors
+#document
+| <html>
+| a="b"
+| <head>
+| <template>
+| content
+| <col>
+| <col>
+| <body>
+
+#data
+<html a=b><template><frame></frame><html b=c><frame></frame></template>
+#errors
+#document
+| <html>
+| a="b"
+| <head>
+| <template>
+| content
+| <body>
+
+#data
+<body><template><tr></tr><template></template><td></td></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <tr>
+| <template>
+| content
+| <tr>
+| <td>
+
+#data
+<body><template><thead></thead><template><tr></tr></template><tr></tr><tfoot></tfoot></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <thead>
+| <template>
+| content
+| <tr>
+| <tbody>
+| <tr>
+| <tfoot>
+
+#data
+<body><template><template><b><template></template></template>text</template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <template>
+| content
+| <b>
+| <template>
+| content
+| "text"
+
+#data
+<body><template><col><colgroup>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <col>
+
+#data
+<body><template><col></colgroup>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <col>
+
+#data
+<body><template><col><colgroup></template></body>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <col>
+
+#data
+<body><template><col><div>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <col>
+
+#data
+<body><template><col></div>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <col>
+
+#data
+<body><template><col>Hello
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <col>
+
+#data
+<body><template><i><menu>Foo</i>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <i>
+| <menu>
+| <i>
+| "Foo"
+
+#data
+<body><template></div><div>Foo</div><template></template><tr></tr>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <div>
+| "Foo"
+| <template>
+| content
+
+#data
+<body><div><template></div><tr><td>Foo</td></tr></template>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <template>
+| content
+| <tr>
+| <td>
+| "Foo"
+
+#data
+<template></figcaption><sub><table></table>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <sub>
+| <table>
+| <body>
+
+#data
+<template><template>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <template>
+| content
+| <body>
+
+#data
+<template><div>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <div>
+| <body>
+
+#data
+<template><template><div>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <template>
+| content
+| <div>
+| <body>
+
+#data
+<template><template><table>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <template>
+| content
+| <table>
+| <body>
+
+#data
+<template><template><tbody>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <template>
+| content
+| <tbody>
+| <body>
+
+#data
+<template><template><tr>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <template>
+| content
+| <tr>
+| <body>
+
+#data
+<template><template><td>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <template>
+| content
+| <td>
+| <body>
+
+#data
+<template><template><caption>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <template>
+| content
+| <caption>
+| <body>
+
+#data
+<template><template><colgroup>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <template>
+| content
+| <colgroup>
+| <body>
+
+#data
+<template><template><col>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <template>
+| content
+| <col>
+| <body>
+
+#data
+<template><template><tbody><select>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <template>
+| content
+| <tbody>
+| <select>
+| <body>
+
+#data
+<template><template><table>Foo
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <template>
+| content
+| "Foo"
+| <table>
+| <body>
+
+#data
+<template><template><table><div>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <template>
+| content
+| <div>
+| <table>
+| <body>
+
+#data
+<template><template><frame>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <template>
+| content
+| <body>
+
+#data
+<template><template><script>var i
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <template>
+| content
+| <script>
+| "var i"
+| <body>
+
+#data
+<template><template><style>var i
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <template>
+| content
+| <style>
+| "var i"
+| <body>
+
+#data
+<template><table></template><body><span>Foo
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <table>
+| <body>
+| <span>
+| "Foo"
+
+#data
+<template><td></template><body><span>Foo
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <td>
+| <body>
+| <span>
+| "Foo"
+
+#data
+<template><object></template><body><span>Foo
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <object>
+| <body>
+| <span>
+| "Foo"
+
+#data
+<template><svg><template>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <svg svg>
+| <svg template>
+| <body>
+
+#data
+<template><svg><foo><template><foreignObject><div></template><div>
+#errors
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <svg svg>
+| <svg foo>
+| <svg template>
+| <svg foreignObject>
+| <div>
+| <body>
+| <div>
+
+#data
+<dummy><template><span></dummy>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <dummy>
+| <template>
+| content
+| <span>
+
+#data
+<body><table><tr><td><select><template>Foo</template><caption>A</table>
+#errors
+(1,62): unexpected-caption-in-select-in-table
+(1,71): unexpected-table-end-in-caption
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <select>
+| <template>
+| content
+| "Foo"
+| <caption>
+| "A"
+
+#data
+<body></body><template>
+#errors
+(1,23): template-after-body
+(1,24): eof-in-template
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+
+#data
+<head></head><template>
+#errors
+(1,23): template-after-head
+(1,24): eof-in-template
+#document
+| <html>
+| <head>
+| <template>
+| content
+| <body>
+
+#data
+<head></head><template>Foo</template>
+#errors
+(1,23): template-after-head
+#document
+| <html>
+| <head>
+| <template>
+| content
+| "Foo"
+| <body>
+
+#data
+<body><form><template><form>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <form>
+| <template>
+| content
+| <form>
+
+#data
+<body><template><table><form>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <table>
+
+#data
+<body><template><form><form>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <template>
+| content
+| <form>
+| <form>
+
+#data
+<body><form><template><isindex>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <form>
+| <template>
+| content
+| <form>
+| <hr>
+| <label>
+| "This is a searchable index. Enter search keywords: "
+| <input>
+| name="isindex"
+| <hr>
+
+#data
+<body><form><template><isindex><form>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <form>
+| <template>
+| content
+| <form>
+| <hr>
+| <label>
+| "This is a searchable index. Enter search keywords: "
+| <input>
+| name="isindex"
+| <hr>
+| <form>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests1.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests1.dat
new file mode 100644
index 000000000..f12e87178
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests1.dat
@@ -0,0 +1,1959 @@
+#data
+Test
+#errors
+(1,0): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "Test"
+
+#data
+<p>One<p>Two
+#errors
+(1,3): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| "One"
+| <p>
+| "Two"
+
+#data
+Line1<br>Line2<br>Line3<br>Line4
+#errors
+(1,0): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "Line1"
+| <br>
+| "Line2"
+| <br>
+| "Line3"
+| <br>
+| "Line4"
+
+#data
+<html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<head>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<body>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<html><head>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<html><head></head>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<html><head></head><body>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<html><head></head><body></body>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<html><head><body></body></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<html><head></body></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<html><head><body></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<html><body></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<body></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<head></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+</head>
+#errors
+(1,7): expected-doctype-but-got-end-tag
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+</body>
+#errors
+(1,7): expected-doctype-but-got-end-tag element.
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+</html>
+#errors
+(1,7): expected-doctype-but-got-end-tag element.
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<b><table><td><i></table>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,14): unexpected-cell-in-table-body
+(1,25): unexpected-cell-end-tag
+(1,25): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <i>
+
+#data
+<b><table><td></b><i></table>X
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,14): unexpected-cell-in-table-body
+(1,18): unexpected-end-tag
+(1,29): unexpected-cell-end-tag
+(1,30): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <i>
+| "X"
+
+#data
+<h1>Hello<h2>World
+#errors
+(1,4): expected-doctype-but-got-start-tag
+(1,13): unexpected-start-tag
+(1,18): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <h1>
+| "Hello"
+| <h2>
+| "World"
+
+#data
+<a><p>X<a>Y</a>Z</p></a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,10): unexpected-start-tag-implies-end-tag
+(1,10): adoption-agency-1.3
+(1,24): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <p>
+| <a>
+| "X"
+| <a>
+| "Y"
+| "Z"
+
+#data
+<b><button>foo</b>bar
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,18): adoption-agency-1.3
+(1,21): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| <button>
+| <b>
+| "foo"
+| "bar"
+
+#data
+<!DOCTYPE html><span><button>foo</span>bar
+#errors
+(1,39): unexpected-end-tag
+(1,42): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <span>
+| <button>
+| "foobar"
+
+#data
+<p><b><div><marquee></p></b></div>X
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,11): unexpected-end-tag
+(1,24): unexpected-end-tag
+(1,28): unexpected-end-tag
+(1,34): end-tag-too-early
+(1,35): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <b>
+| <div>
+| <b>
+| <marquee>
+| <p>
+| "X"
+
+#data
+<script><div></script></div><title><p></title><p><p>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,28): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <script>
+| "<div>"
+| <title>
+| "<p>"
+| <body>
+| <p>
+| <p>
+
+#data
+<!--><div>--<!-->
+#errors
+(1,5): incorrect-comment
+(1,10): expected-doctype-but-got-start-tag
+(1,17): incorrect-comment
+(1,17): expected-closing-tag-but-got-eof
+#document
+| <!-- -->
+| <html>
+| <head>
+| <body>
+| <div>
+| "--"
+| <!-- -->
+
+#data
+<p><hr></p>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,11): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <hr>
+| <p>
+
+#data
+<select><b><option><select><option></b></select>X
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,11): unexpected-start-tag-in-select
+(1,27): unexpected-select-in-select
+(1,39): unexpected-end-tag
+(1,48): unexpected-end-tag
+(1,49): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <select>
+| <option>
+| <option>
+| "X"
+
+#data
+<a><table><td><a><table></table><a></tr><a></table><b>X</b>C<a>Y
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,14): unexpected-cell-in-table-body
+(1,35): unexpected-start-tag-implies-end-tag
+(1,40): unexpected-cell-end-tag
+(1,43): unexpected-start-tag-implies-table-voodoo
+(1,43): unexpected-start-tag-implies-end-tag
+(1,43): unexpected-end-tag
+(1,63): unexpected-start-tag-implies-end-tag
+(1,64): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <a>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <a>
+| <table>
+| <a>
+| <a>
+| <b>
+| "X"
+| "C"
+| <a>
+| "Y"
+
+#data
+<a X>0<b>1<a Y>2
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,15): unexpected-start-tag-implies-end-tag
+(1,15): adoption-agency-1.3
+(1,16): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| x=""
+| "0"
+| <b>
+| "1"
+| <b>
+| <a>
+| y=""
+| "2"
+
+#data
+<!-----><font><div>hello<table>excite!<b>me!<th><i>please!</tr><!--X-->
+#errors
+(1,7): unexpected-dash-after-double-dash-in-comment
+(1,14): expected-doctype-but-got-start-tag
+(1,41): unexpected-start-tag-implies-table-voodoo
+(1,48): foster-parenting-character-in-table
+(1,48): foster-parenting-character-in-table
+(1,48): foster-parenting-character-in-table
+(1,48): foster-parenting-character-in-table
+(1,48): foster-parenting-character-in-table
+(1,48): foster-parenting-character-in-table
+(1,48): foster-parenting-character-in-table
+(1,48): foster-parenting-start-tag-in-table
+(1,48): foster-parenting-character-in-table
+(1,48): foster-parenting-character-in-table
+(1,48): foster-parenting-character-in-table
+(1,48): unexpected-cell-in-table-body
+(1,63): unexpected-cell-end-tag
+(1,71): eof-in-table
+#document
+| <!-- - -->
+| <html>
+| <head>
+| <body>
+| <font>
+| <div>
+| "helloexcite!"
+| <b>
+| "me!"
+| <table>
+| <tbody>
+| <tr>
+| <th>
+| <i>
+| "please!"
+| <!-- X -->
+
+#data
+<!DOCTYPE html><li>hello<li>world<ul>how<li>do</ul>you</body><!--do-->
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <li>
+| "hello"
+| <li>
+| "world"
+| <ul>
+| "how"
+| <li>
+| "do"
+| "you"
+| <!-- do -->
+
+#data
+<!DOCTYPE html>A<option>B<optgroup>C<select>D</option>E
+#errors
+(1,54): unexpected-end-tag-in-select
+(1,55): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "A"
+| <option>
+| "B"
+| <optgroup>
+| "C"
+| <select>
+| "DE"
+
+#data
+<
+#errors
+(1,1): expected-tag-name
+(1,1): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "<"
+
+#data
+<#
+#errors
+(1,1): expected-tag-name
+(1,1): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "<#"
+
+#data
+</
+#errors
+(1,2): expected-closing-tag-but-got-eof
+(1,2): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "</"
+
+#data
+</#
+#errors
+(1,2): expected-closing-tag-but-got-char
+(1,3): expected-doctype-but-got-eof
+#document
+| <!-- # -->
+| <html>
+| <head>
+| <body>
+
+#data
+<?
+#errors
+(1,1): expected-tag-name-but-got-question-mark
+(1,2): expected-doctype-but-got-eof
+#document
+| <!-- ? -->
+| <html>
+| <head>
+| <body>
+
+#data
+<?#
+#errors
+(1,1): expected-tag-name-but-got-question-mark
+(1,3): expected-doctype-but-got-eof
+#document
+| <!-- ?# -->
+| <html>
+| <head>
+| <body>
+
+#data
+<!
+#errors
+(1,2): expected-dashes-or-doctype
+(1,2): expected-doctype-but-got-eof
+#document
+| <!-- -->
+| <html>
+| <head>
+| <body>
+
+#data
+<!#
+#errors
+(1,2): expected-dashes-or-doctype
+(1,3): expected-doctype-but-got-eof
+#document
+| <!-- # -->
+| <html>
+| <head>
+| <body>
+
+#data
+<?COMMENT?>
+#errors
+(1,1): expected-tag-name-but-got-question-mark
+(1,11): expected-doctype-but-got-eof
+#document
+| <!-- ?COMMENT? -->
+| <html>
+| <head>
+| <body>
+
+#data
+<!COMMENT>
+#errors
+(1,2): expected-dashes-or-doctype
+(1,10): expected-doctype-but-got-eof
+#document
+| <!-- COMMENT -->
+| <html>
+| <head>
+| <body>
+
+#data
+</ COMMENT >
+#errors
+(1,2): expected-closing-tag-but-got-char
+(1,12): expected-doctype-but-got-eof
+#document
+| <!-- COMMENT -->
+| <html>
+| <head>
+| <body>
+
+#data
+<?COM--MENT?>
+#errors
+(1,1): expected-tag-name-but-got-question-mark
+(1,13): expected-doctype-but-got-eof
+#document
+| <!-- ?COM--MENT? -->
+| <html>
+| <head>
+| <body>
+
+#data
+<!COM--MENT>
+#errors
+(1,2): expected-dashes-or-doctype
+(1,12): expected-doctype-but-got-eof
+#document
+| <!-- COM--MENT -->
+| <html>
+| <head>
+| <body>
+
+#data
+</ COM--MENT >
+#errors
+(1,2): expected-closing-tag-but-got-char
+(1,14): expected-doctype-but-got-eof
+#document
+| <!-- COM--MENT -->
+| <html>
+| <head>
+| <body>
+
+#data
+<!DOCTYPE html><style> EOF
+#errors
+(1,26): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <style>
+| " EOF"
+| <body>
+
+#data
+<!DOCTYPE html><script> <!-- </script> --> </script> EOF
+#errors
+(1,52): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| " <!-- "
+| " "
+| <body>
+| "--> EOF"
+
+#data
+<b><p></b>TEST
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,10): adoption-agency-1.3
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| <p>
+| <b>
+| "TEST"
+
+#data
+<p id=a><b><p id=b></b>TEST
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,19): unexpected-end-tag
+(1,23): adoption-agency-1.2
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| id="a"
+| <b>
+| <p>
+| id="b"
+| "TEST"
+
+#data
+<b id=a><p><b id=b></p></b>TEST
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,23): unexpected-end-tag
+(1,27): adoption-agency-1.2
+(1,31): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| id="a"
+| <p>
+| <b>
+| id="b"
+| "TEST"
+
+#data
+<!DOCTYPE html><title>U-test</title><body><div><p>Test<u></p></div></body>
+#errors
+(1,61): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <title>
+| "U-test"
+| <body>
+| <div>
+| <p>
+| "Test"
+| <u>
+
+#data
+<!DOCTYPE html><font><table></font></table></font>
+#errors
+(1,35): unexpected-end-tag-implies-table-voodoo
+(1,35): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <font>
+| <table>
+
+#data
+<font><p>hello<b>cruel</font>world
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,29): adoption-agency-1.3
+(1,29): adoption-agency-1.3
+(1,34): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <font>
+| <p>
+| <font>
+| "hello"
+| <b>
+| "cruel"
+| <b>
+| "world"
+
+#data
+<b>Test</i>Test
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,11): unexpected-end-tag
+(1,15): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| "TestTest"
+
+#data
+<b>A<cite>B<div>C
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,17): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| "A"
+| <cite>
+| "B"
+| <div>
+| "C"
+
+#data
+<b>A<cite>B<div>C</cite>D
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,24): unexpected-end-tag
+(1,25): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| "A"
+| <cite>
+| "B"
+| <div>
+| "CD"
+
+#data
+<b>A<cite>B<div>C</b>D
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,21): adoption-agency-1.3
+(1,22): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| "A"
+| <cite>
+| "B"
+| <div>
+| <b>
+| "C"
+| "D"
+
+#data
+
+#errors
+(1,0): expected-doctype-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<DIV>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,5): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+
+#data
+<DIV> abc
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,9): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| " abc"
+
+#data
+<DIV> abc <B>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,13): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| " abc "
+| <b>
+
+#data
+<DIV> abc <B> def
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,17): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| " abc "
+| <b>
+| " def"
+
+#data
+<DIV> abc <B> def <I>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,21): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| " abc "
+| <b>
+| " def "
+| <i>
+
+#data
+<DIV> abc <B> def <I> ghi
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,25): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| " abc "
+| <b>
+| " def "
+| <i>
+| " ghi"
+
+#data
+<DIV> abc <B> def <I> ghi <P>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,29): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| " abc "
+| <b>
+| " def "
+| <i>
+| " ghi "
+| <p>
+
+#data
+<DIV> abc <B> def <I> ghi <P> jkl
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,33): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| " abc "
+| <b>
+| " def "
+| <i>
+| " ghi "
+| <p>
+| " jkl"
+
+#data
+<DIV> abc <B> def <I> ghi <P> jkl </B>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,38): adoption-agency-1.3
+(1,38): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| " abc "
+| <b>
+| " def "
+| <i>
+| " ghi "
+| <i>
+| <p>
+| <b>
+| " jkl "
+
+#data
+<DIV> abc <B> def <I> ghi <P> jkl </B> mno
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,38): adoption-agency-1.3
+(1,42): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| " abc "
+| <b>
+| " def "
+| <i>
+| " ghi "
+| <i>
+| <p>
+| <b>
+| " jkl "
+| " mno"
+
+#data
+<DIV> abc <B> def <I> ghi <P> jkl </B> mno </I>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,38): adoption-agency-1.3
+(1,47): adoption-agency-1.3
+(1,47): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| " abc "
+| <b>
+| " def "
+| <i>
+| " ghi "
+| <i>
+| <p>
+| <i>
+| <b>
+| " jkl "
+| " mno "
+
+#data
+<DIV> abc <B> def <I> ghi <P> jkl </B> mno </I> pqr
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,38): adoption-agency-1.3
+(1,47): adoption-agency-1.3
+(1,51): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| " abc "
+| <b>
+| " def "
+| <i>
+| " ghi "
+| <i>
+| <p>
+| <i>
+| <b>
+| " jkl "
+| " mno "
+| " pqr"
+
+#data
+<DIV> abc <B> def <I> ghi <P> jkl </B> mno </I> pqr </P>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,38): adoption-agency-1.3
+(1,47): adoption-agency-1.3
+(1,56): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| " abc "
+| <b>
+| " def "
+| <i>
+| " ghi "
+| <i>
+| <p>
+| <i>
+| <b>
+| " jkl "
+| " mno "
+| " pqr "
+
+#data
+<DIV> abc <B> def <I> ghi <P> jkl </B> mno </I> pqr </P> stu
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,38): adoption-agency-1.3
+(1,47): adoption-agency-1.3
+(1,60): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| " abc "
+| <b>
+| " def "
+| <i>
+| " ghi "
+| <i>
+| <p>
+| <i>
+| <b>
+| " jkl "
+| " mno "
+| " pqr "
+| " stu"
+
+#data
+<test attribute---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------->
+#errors
+(1,1040): expected-doctype-but-got-start-tag
+(1,1040): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <test>
+| attribute----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------=""
+
+#data
+<a href="blah">aba<table><a href="foo">br<tr><td></td></tr>x</table>aoe
+#errors
+(1,15): expected-doctype-but-got-start-tag
+(1,39): unexpected-start-tag-implies-table-voodoo
+(1,39): unexpected-start-tag-implies-end-tag
+(1,39): unexpected-end-tag
+(1,45): foster-parenting-character-in-table
+(1,45): foster-parenting-character-in-table
+(1,68): foster-parenting-character-in-table
+(1,71): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| href="blah"
+| "aba"
+| <a>
+| href="foo"
+| "br"
+| <a>
+| href="foo"
+| "x"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <a>
+| href="foo"
+| "aoe"
+
+#data
+<a href="blah">aba<table><tr><td><a href="foo">br</td></tr>x</table>aoe
+#errors
+(1,15): expected-doctype-but-got-start-tag
+(1,54): unexpected-cell-end-tag
+(1,71): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| href="blah"
+| "abax"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <a>
+| href="foo"
+| "br"
+| "aoe"
+
+#data
+<table><a href="blah">aba<tr><td><a href="foo">br</td></tr>x</table>aoe
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,22): unexpected-start-tag-implies-table-voodoo
+(1,29): foster-parenting-character-in-table
+(1,29): foster-parenting-character-in-table
+(1,29): foster-parenting-character-in-table
+(1,54): unexpected-cell-end-tag
+(1,68): foster-parenting-character-in-table
+(1,71): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| href="blah"
+| "aba"
+| <a>
+| href="blah"
+| "x"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <a>
+| href="foo"
+| "br"
+| <a>
+| href="blah"
+| "aoe"
+
+#data
+<a href=a>aa<marquee>aa<a href=b>bb</marquee>aa
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(1,45): end-tag-too-early
+(1,47): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| href="a"
+| "aa"
+| <marquee>
+| "aa"
+| <a>
+| href="b"
+| "bb"
+| "aa"
+
+#data
+<wbr><strike><code></strike><code><strike></code>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,28): adoption-agency-1.3
+(1,49): adoption-agency-1.3
+(1,49): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <wbr>
+| <strike>
+| <code>
+| <code>
+| <code>
+| <strike>
+
+#data
+<!DOCTYPE html><spacer>foo
+#errors
+(1,26): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <spacer>
+| "foo"
+
+#data
+<title><meta></title><link><title><meta></title>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <title>
+| "<meta>"
+| <link>
+| <title>
+| "<meta>"
+| <body>
+
+#data
+<style><!--</style><meta><script>--><link></script>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <style>
+| "<!--"
+| <meta>
+| <script>
+| "--><link>"
+| <body>
+
+#data
+<head><meta></head><link>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,25): unexpected-start-tag-out-of-my-head
+#document
+| <html>
+| <head>
+| <meta>
+| <link>
+| <body>
+
+#data
+<table><tr><tr><td><td><span><th><span>X</table>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,33): unexpected-cell-end-tag
+(1,48): unexpected-cell-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <tr>
+| <td>
+| <td>
+| <span>
+| <th>
+| <span>
+| "X"
+
+#data
+<body><body><base><link><meta><title><p></title><body><p></body>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,12): unexpected-start-tag
+(1,54): unexpected-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <base>
+| <link>
+| <meta>
+| <title>
+| "<p>"
+| <p>
+
+#data
+<textarea><p></textarea>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <textarea>
+| "<p>"
+
+#data
+<p><image></p>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,10): unexpected-start-tag-treated-as
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <img>
+
+#data
+<a><table><a></table><p><a><div><a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,13): unexpected-start-tag-implies-table-voodoo
+(1,13): unexpected-start-tag-implies-end-tag
+(1,13): adoption-agency-1.3
+(1,27): unexpected-start-tag-implies-end-tag
+(1,27): adoption-agency-1.2
+(1,32): unexpected-end-tag
+(1,35): unexpected-start-tag-implies-end-tag
+(1,35): adoption-agency-1.2
+(1,35): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <a>
+| <table>
+| <p>
+| <a>
+| <div>
+| <a>
+
+#data
+<head></p><meta><p>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,10): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <meta>
+| <body>
+| <p>
+
+#data
+<head></html><meta><p>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,19): expected-eof-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <meta>
+| <p>
+
+#data
+<b><table><td><i></table>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,14): unexpected-cell-in-table-body
+(1,25): unexpected-cell-end-tag
+(1,25): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <i>
+
+#data
+<b><table><td></b><i></table>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,14): unexpected-cell-in-table-body
+(1,18): unexpected-end-tag
+(1,29): unexpected-cell-end-tag
+(1,29): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <i>
+
+#data
+<h1><h2>
+#errors
+(1,4): expected-doctype-but-got-start-tag
+(1,8): unexpected-start-tag
+(1,8): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <h1>
+| <h2>
+
+#data
+<a><p><a></a></p></a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,9): unexpected-start-tag-implies-end-tag
+(1,9): adoption-agency-1.3
+(1,21): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <p>
+| <a>
+| <a>
+
+#data
+<b><button></b></button></b>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,15): adoption-agency-1.3
+(1,28): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| <button>
+| <b>
+
+#data
+<p><b><div><marquee></p></b></div>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,11): unexpected-end-tag
+(1,24): unexpected-end-tag
+(1,28): unexpected-end-tag
+(1,34): end-tag-too-early
+(1,34): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <b>
+| <div>
+| <b>
+| <marquee>
+| <p>
+
+#data
+<script></script></div><title></title><p><p>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,23): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <script>
+| <title>
+| <body>
+| <p>
+| <p>
+
+#data
+<p><hr></p>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,11): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <hr>
+| <p>
+
+#data
+<select><b><option><select><option></b></select>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,11): unexpected-start-tag-in-select
+(1,27): unexpected-select-in-select
+(1,39): unexpected-end-tag
+(1,48): unexpected-end-tag
+(1,48): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <select>
+| <option>
+| <option>
+
+#data
+<html><head><title></title><body></body></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <title>
+| <body>
+
+#data
+<a><table><td><a><table></table><a></tr><a></table><a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,14): unexpected-cell-in-table-body
+(1,35): unexpected-start-tag-implies-end-tag
+(1,40): unexpected-cell-end-tag
+(1,43): unexpected-start-tag-implies-table-voodoo
+(1,43): unexpected-start-tag-implies-end-tag
+(1,43): unexpected-end-tag
+(1,54): unexpected-start-tag-implies-end-tag
+(1,54): adoption-agency-1.2
+(1,54): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <a>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <a>
+| <table>
+| <a>
+| <a>
+
+#data
+<ul><li></li><div><li></div><li><li><div><li><address><li><b><em></b><li></ul>
+#errors
+(1,4): expected-doctype-but-got-start-tag
+(1,45): end-tag-too-early
+(1,58): end-tag-too-early
+(1,69): adoption-agency-1.3
+#document
+| <html>
+| <head>
+| <body>
+| <ul>
+| <li>
+| <div>
+| <li>
+| <li>
+| <li>
+| <div>
+| <li>
+| <address>
+| <li>
+| <b>
+| <em>
+| <li>
+
+#data
+<ul><li><ul></li><li>a</li></ul></li></ul>
+#errors
+(1,4): expected-doctype-but-got-start-tag
+(1,17): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ul>
+| <li>
+| <ul>
+| <li>
+| "a"
+
+#data
+<frameset><frame><frameset><frame></frameset><noframes></noframes></frameset>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <frameset>
+| <frame>
+| <frameset>
+| <frame>
+| <noframes>
+
+#data
+<h1><table><td><h3></table><h3></h1>
+#errors
+(1,4): expected-doctype-but-got-start-tag
+(1,15): unexpected-cell-in-table-body
+(1,27): unexpected-cell-end-tag
+(1,31): unexpected-start-tag
+(1,36): end-tag-too-early
+#document
+| <html>
+| <head>
+| <body>
+| <h1>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <h3>
+| <h3>
+
+#data
+<table><colgroup><col><colgroup><col><col><col><colgroup><col><col><thead><tr><td></table>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <colgroup>
+| <col>
+| <colgroup>
+| <col>
+| <col>
+| <col>
+| <colgroup>
+| <col>
+| <col>
+| <thead>
+| <tr>
+| <td>
+
+#data
+<table><col><tbody><col><tr><col><td><col></table><col>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,37): unexpected-cell-in-table-body
+(1,55): unexpected-start-tag-ignored
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <colgroup>
+| <col>
+| <tbody>
+| <colgroup>
+| <col>
+| <tbody>
+| <tr>
+| <colgroup>
+| <col>
+| <tbody>
+| <tr>
+| <td>
+| <colgroup>
+| <col>
+
+#data
+<table><colgroup><tbody><colgroup><tr><colgroup><td><colgroup></table><colgroup>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,52): unexpected-cell-in-table-body
+(1,80): unexpected-start-tag-ignored
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <colgroup>
+| <tbody>
+| <colgroup>
+| <tbody>
+| <tr>
+| <colgroup>
+| <tbody>
+| <tr>
+| <td>
+| <colgroup>
+
+#data
+</strong></b></em></i></u></strike></s></blink></tt></pre></big></small></font></select></h1></h2></h3></h4></h5></h6></body></br></a></img></title></span></style></script></table></th></td></tr></frame></area></link></param></hr></input></col></base></meta></basefont></bgsound></embed></spacer></p></dd></dt></caption></colgroup></tbody></tfoot></thead></address></blockquote></center></dir></div></dl></fieldset></listing></menu></ol></ul></li></nobr></wbr></form></button></marquee></object></html></frameset></head></iframe></image></isindex></noembed></noframes></noscript></optgroup></option></plaintext></textarea>
+#errors
+(1,9): expected-doctype-but-got-end-tag
+(1,9): unexpected-end-tag-before-html
+(1,13): unexpected-end-tag-before-html
+(1,18): unexpected-end-tag-before-html
+(1,22): unexpected-end-tag-before-html
+(1,26): unexpected-end-tag-before-html
+(1,35): unexpected-end-tag-before-html
+(1,39): unexpected-end-tag-before-html
+(1,47): unexpected-end-tag-before-html
+(1,52): unexpected-end-tag-before-html
+(1,58): unexpected-end-tag-before-html
+(1,64): unexpected-end-tag-before-html
+(1,72): unexpected-end-tag-before-html
+(1,79): unexpected-end-tag-before-html
+(1,88): unexpected-end-tag-before-html
+(1,93): unexpected-end-tag-before-html
+(1,98): unexpected-end-tag-before-html
+(1,103): unexpected-end-tag-before-html
+(1,108): unexpected-end-tag-before-html
+(1,113): unexpected-end-tag-before-html
+(1,118): unexpected-end-tag-before-html
+(1,130): unexpected-end-tag-after-body
+(1,130): unexpected-end-tag-treated-as
+(1,134): unexpected-end-tag
+(1,140): unexpected-end-tag
+(1,148): unexpected-end-tag
+(1,155): unexpected-end-tag
+(1,163): unexpected-end-tag
+(1,172): unexpected-end-tag
+(1,180): unexpected-end-tag
+(1,185): unexpected-end-tag
+(1,190): unexpected-end-tag
+(1,195): unexpected-end-tag
+(1,203): unexpected-end-tag
+(1,210): unexpected-end-tag
+(1,217): unexpected-end-tag
+(1,225): unexpected-end-tag
+(1,230): unexpected-end-tag
+(1,238): unexpected-end-tag
+(1,244): unexpected-end-tag
+(1,251): unexpected-end-tag
+(1,258): unexpected-end-tag
+(1,269): unexpected-end-tag
+(1,279): unexpected-end-tag
+(1,287): unexpected-end-tag
+(1,296): unexpected-end-tag
+(1,300): unexpected-end-tag
+(1,305): unexpected-end-tag
+(1,310): unexpected-end-tag
+(1,320): unexpected-end-tag
+(1,331): unexpected-end-tag
+(1,339): unexpected-end-tag
+(1,347): unexpected-end-tag
+(1,355): unexpected-end-tag
+(1,365): end-tag-too-early
+(1,378): end-tag-too-early
+(1,387): end-tag-too-early
+(1,393): end-tag-too-early
+(1,399): end-tag-too-early
+(1,404): end-tag-too-early
+(1,415): end-tag-too-early
+(1,425): end-tag-too-early
+(1,432): end-tag-too-early
+(1,437): end-tag-too-early
+(1,442): end-tag-too-early
+(1,447): unexpected-end-tag
+(1,454): unexpected-end-tag
+(1,460): unexpected-end-tag
+(1,467): unexpected-end-tag
+(1,476): end-tag-too-early
+(1,486): end-tag-too-early
+(1,495): end-tag-too-early
+(1,513): expected-eof-but-got-end-tag
+(1,513): unexpected-end-tag
+(1,520): unexpected-end-tag
+(1,529): unexpected-end-tag
+(1,537): unexpected-end-tag
+(1,547): unexpected-end-tag
+(1,557): unexpected-end-tag
+(1,568): unexpected-end-tag
+(1,579): unexpected-end-tag
+(1,590): unexpected-end-tag
+(1,599): unexpected-end-tag
+(1,611): unexpected-end-tag
+(1,622): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <br>
+| <p>
+
+#data
+<table><tr></strong></b></em></i></u></strike></s></blink></tt></pre></big></small></font></select></h1></h2></h3></h4></h5></h6></body></br></a></img></title></span></style></script></table></th></td></tr></frame></area></link></param></hr></input></col></base></meta></basefont></bgsound></embed></spacer></p></dd></dt></caption></colgroup></tbody></tfoot></thead></address></blockquote></center></dir></div></dl></fieldset></listing></menu></ol></ul></li></nobr></wbr></form></button></marquee></object></html></frameset></head></iframe></image></isindex></noembed></noframes></noscript></optgroup></option></plaintext></textarea>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,20): unexpected-end-tag-implies-table-voodoo
+(1,20): unexpected-end-tag
+(1,24): unexpected-end-tag-implies-table-voodoo
+(1,24): unexpected-end-tag
+(1,29): unexpected-end-tag-implies-table-voodoo
+(1,29): unexpected-end-tag
+(1,33): unexpected-end-tag-implies-table-voodoo
+(1,33): unexpected-end-tag
+(1,37): unexpected-end-tag-implies-table-voodoo
+(1,37): unexpected-end-tag
+(1,46): unexpected-end-tag-implies-table-voodoo
+(1,46): unexpected-end-tag
+(1,50): unexpected-end-tag-implies-table-voodoo
+(1,50): unexpected-end-tag
+(1,58): unexpected-end-tag-implies-table-voodoo
+(1,58): unexpected-end-tag
+(1,63): unexpected-end-tag-implies-table-voodoo
+(1,63): unexpected-end-tag
+(1,69): unexpected-end-tag-implies-table-voodoo
+(1,69): end-tag-too-early
+(1,75): unexpected-end-tag-implies-table-voodoo
+(1,75): unexpected-end-tag
+(1,83): unexpected-end-tag-implies-table-voodoo
+(1,83): unexpected-end-tag
+(1,90): unexpected-end-tag-implies-table-voodoo
+(1,90): unexpected-end-tag
+(1,99): unexpected-end-tag-implies-table-voodoo
+(1,99): unexpected-end-tag
+(1,104): unexpected-end-tag-implies-table-voodoo
+(1,104): end-tag-too-early
+(1,109): unexpected-end-tag-implies-table-voodoo
+(1,109): end-tag-too-early
+(1,114): unexpected-end-tag-implies-table-voodoo
+(1,114): end-tag-too-early
+(1,119): unexpected-end-tag-implies-table-voodoo
+(1,119): end-tag-too-early
+(1,124): unexpected-end-tag-implies-table-voodoo
+(1,124): end-tag-too-early
+(1,129): unexpected-end-tag-implies-table-voodoo
+(1,129): end-tag-too-early
+(1,136): unexpected-end-tag-in-table-row
+(1,141): unexpected-end-tag-implies-table-voodoo
+(1,141): unexpected-end-tag-treated-as
+(1,145): unexpected-end-tag-implies-table-voodoo
+(1,145): unexpected-end-tag
+(1,151): unexpected-end-tag-implies-table-voodoo
+(1,151): unexpected-end-tag
+(1,159): unexpected-end-tag-implies-table-voodoo
+(1,159): unexpected-end-tag
+(1,166): unexpected-end-tag-implies-table-voodoo
+(1,166): unexpected-end-tag
+(1,174): unexpected-end-tag-implies-table-voodoo
+(1,174): unexpected-end-tag
+(1,183): unexpected-end-tag-implies-table-voodoo
+(1,183): unexpected-end-tag
+(1,196): unexpected-end-tag
+(1,201): unexpected-end-tag
+(1,206): unexpected-end-tag
+(1,214): unexpected-end-tag
+(1,221): unexpected-end-tag
+(1,228): unexpected-end-tag
+(1,236): unexpected-end-tag
+(1,241): unexpected-end-tag
+(1,249): unexpected-end-tag
+(1,255): unexpected-end-tag
+(1,262): unexpected-end-tag
+(1,269): unexpected-end-tag
+(1,280): unexpected-end-tag
+(1,290): unexpected-end-tag
+(1,298): unexpected-end-tag
+(1,307): unexpected-end-tag
+(1,311): unexpected-end-tag
+(1,316): unexpected-end-tag
+(1,321): unexpected-end-tag
+(1,331): unexpected-end-tag
+(1,342): unexpected-end-tag
+(1,350): unexpected-end-tag
+(1,358): unexpected-end-tag
+(1,366): unexpected-end-tag
+(1,376): end-tag-too-early
+(1,389): end-tag-too-early
+(1,398): end-tag-too-early
+(1,404): end-tag-too-early
+(1,410): end-tag-too-early
+(1,415): end-tag-too-early
+(1,426): end-tag-too-early
+(1,436): end-tag-too-early
+(1,443): end-tag-too-early
+(1,448): end-tag-too-early
+(1,453): end-tag-too-early
+(1,458): unexpected-end-tag
+(1,465): unexpected-end-tag
+(1,471): unexpected-end-tag
+(1,478): unexpected-end-tag
+(1,487): end-tag-too-early
+(1,497): end-tag-too-early
+(1,506): end-tag-too-early
+(1,524): expected-eof-but-got-end-tag
+(1,524): unexpected-end-tag
+(1,531): unexpected-end-tag
+(1,540): unexpected-end-tag
+(1,548): unexpected-end-tag
+(1,558): unexpected-end-tag
+(1,568): unexpected-end-tag
+(1,579): unexpected-end-tag
+(1,590): unexpected-end-tag
+(1,601): unexpected-end-tag
+(1,610): unexpected-end-tag
+(1,622): unexpected-end-tag
+(1,633): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <br>
+| <table>
+| <tbody>
+| <tr>
+| <p>
+
+#data
+<frameset>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(1,10): eof-in-frameset
+#document
+| <html>
+| <head>
+| <frameset>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests10.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests10.dat
new file mode 100644
index 000000000..87d94786b
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests10.dat
@@ -0,0 +1,847 @@
+#data
+<!DOCTYPE html><svg></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+
+#data
+<!DOCTYPE html><svg></svg><![CDATA[a]]>
+#errors
+(1,28) expected-dashes-or-doctype
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <!-- [CDATA[a]] -->
+
+#data
+<!DOCTYPE html><body><svg></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+
+#data
+<!DOCTYPE html><body><select><svg></svg></select>
+#errors
+(1,34) unexpected-start-tag-in-select
+(1,40) unexpected-end-tag-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+
+#data
+<!DOCTYPE html><body><select><option><svg></svg></option></select>
+#errors
+(1,42) unexpected-start-tag-in-select
+(1,48) unexpected-end-tag-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| <option>
+
+#data
+<!DOCTYPE html><body><table><svg></svg></table>
+#errors
+(1,33) foster-parenting-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <table>
+
+#data
+<!DOCTYPE html><body><table><svg><g>foo</g></svg></table>
+#errors
+(1,33) foster-parenting-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg g>
+| "foo"
+| <table>
+
+#data
+<!DOCTYPE html><body><table><svg><g>foo</g><g>bar</g></svg></table>
+#errors
+(1,33) foster-parenting-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg g>
+| "foo"
+| <svg g>
+| "bar"
+| <table>
+
+#data
+<!DOCTYPE html><body><table><tbody><svg><g>foo</g><g>bar</g></svg></tbody></table>
+#errors
+(1,40) foster-parenting-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg g>
+| "foo"
+| <svg g>
+| "bar"
+| <table>
+| <tbody>
+
+#data
+<!DOCTYPE html><body><table><tbody><tr><svg><g>foo</g><g>bar</g></svg></tr></tbody></table>
+#errors
+(1,44) foster-parenting-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg g>
+| "foo"
+| <svg g>
+| "bar"
+| <table>
+| <tbody>
+| <tr>
+
+#data
+<!DOCTYPE html><body><table><tbody><tr><td><svg><g>foo</g><g>bar</g></svg></td></tr></tbody></table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <svg svg>
+| <svg g>
+| "foo"
+| <svg g>
+| "bar"
+
+#data
+<!DOCTYPE html><body><table><tbody><tr><td><svg><g>foo</g><g>bar</g></svg><p>baz</td></tr></tbody></table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <svg svg>
+| <svg g>
+| "foo"
+| <svg g>
+| "bar"
+| <p>
+| "baz"
+
+#data
+<!DOCTYPE html><body><table><caption><svg><g>foo</g><g>bar</g></svg><p>baz</caption></table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+| <svg svg>
+| <svg g>
+| "foo"
+| <svg g>
+| "bar"
+| <p>
+| "baz"
+
+#data
+<!DOCTYPE html><body><table><caption><svg><g>foo</g><g>bar</g><p>baz</table><p>quux
+#errors
+(1,65) unexpected-html-element-in-foreign-content
+(1,76) XXX-undefined-error
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+| <svg svg>
+| <svg g>
+| "foo"
+| <svg g>
+| "bar"
+| <p>
+| "baz"
+| <p>
+| "quux"
+
+#data
+<!DOCTYPE html><body><table><caption><svg><g>foo</g><g>bar</g>baz</table><p>quux
+#errors
+(1,73) unexpected-end-tag
+(1,73) expected-one-end-tag-but-got-another
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+| <svg svg>
+| <svg g>
+| "foo"
+| <svg g>
+| "bar"
+| "baz"
+| <p>
+| "quux"
+
+#data
+<!DOCTYPE html><body><table><colgroup><svg><g>foo</g><g>bar</g><p>baz</table><p>quux
+#errors
+(1,43) foster-parenting-start-tag
+(1,66) foster-parenting-start-tag
+(1,67) foster-parenting-character
+(1,68) foster-parenting-character
+(1,69) foster-parenting-character
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg g>
+| "foo"
+| <svg g>
+| "bar"
+| <p>
+| "baz"
+| <table>
+| <colgroup>
+| <p>
+| "quux"
+
+#data
+<!DOCTYPE html><body><table><tr><td><select><svg><g>foo</g><g>bar</g><p>baz</table><p>quux
+#errors
+(1,49) unexpected-start-tag-in-select
+(1,52) unexpected-start-tag-in-select
+(1,59) unexpected-end-tag-in-select
+(1,62) unexpected-start-tag-in-select
+(1,69) unexpected-end-tag-in-select
+(1,72) unexpected-start-tag-in-select
+(1,83) unexpected-table-element-end-tag-in-select-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <select>
+| "foobarbaz"
+| <p>
+| "quux"
+
+#data
+<!DOCTYPE html><body><table><select><svg><g>foo</g><g>bar</g><p>baz</table><p>quux
+#errors
+(1,36) unexpected-start-tag-implies-table-voodoo
+(1,41) unexpected-start-tag-in-select
+(1,44) unexpected-start-tag-in-select
+(1,51) unexpected-end-tag-in-select
+(1,54) unexpected-start-tag-in-select
+(1,61) unexpected-end-tag-in-select
+(1,64) unexpected-start-tag-in-select
+(1,75) unexpected-table-element-end-tag-in-select-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| "foobarbaz"
+| <table>
+| <p>
+| "quux"
+
+#data
+<!DOCTYPE html><body></body></html><svg><g>foo</g><g>bar</g><p>baz
+#errors
+(1,40) expected-eof-but-got-start-tag
+(1,63) unexpected-html-element-in-foreign-content
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg g>
+| "foo"
+| <svg g>
+| "bar"
+| <p>
+| "baz"
+
+#data
+<!DOCTYPE html><body></body><svg><g>foo</g><g>bar</g><p>baz
+#errors
+(1,33) unexpected-start-tag-after-body
+(1,56) unexpected-html-element-in-foreign-content
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg g>
+| "foo"
+| <svg g>
+| "bar"
+| <p>
+| "baz"
+
+#data
+<!DOCTYPE html><frameset><svg><g></g><g></g><p><span>
+#errors
+(1,30) unexpected-start-tag-in-frameset
+(1,33) unexpected-start-tag-in-frameset
+(1,37) unexpected-end-tag-in-frameset
+(1,40) unexpected-start-tag-in-frameset
+(1,44) unexpected-end-tag-in-frameset
+(1,47) unexpected-start-tag-in-frameset
+(1,53) unexpected-start-tag-in-frameset
+(1,53) eof-in-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+
+#data
+<!DOCTYPE html><frameset></frameset><svg><g></g><g></g><p><span>
+#errors
+(1,41) unexpected-start-tag-after-frameset
+(1,44) unexpected-start-tag-after-frameset
+(1,48) unexpected-end-tag-after-frameset
+(1,51) unexpected-start-tag-after-frameset
+(1,55) unexpected-end-tag-after-frameset
+(1,58) unexpected-start-tag-after-frameset
+(1,64) unexpected-start-tag-after-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+
+#data
+<!DOCTYPE html><body xlink:href=foo><svg xlink:href=foo></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| xlink:href="foo"
+| <svg svg>
+| xlink href="foo"
+
+#data
+<!DOCTYPE html><body xlink:href=foo xml:lang=en><svg><g xml:lang=en xlink:href=foo></g></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| xlink:href="foo"
+| xml:lang="en"
+| <svg svg>
+| <svg g>
+| xlink href="foo"
+| xml lang="en"
+
+#data
+<!DOCTYPE html><body xlink:href=foo xml:lang=en><svg><g xml:lang=en xlink:href=foo /></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| xlink:href="foo"
+| xml:lang="en"
+| <svg svg>
+| <svg g>
+| xlink href="foo"
+| xml lang="en"
+
+#data
+<!DOCTYPE html><body xlink:href=foo xml:lang=en><svg><g xml:lang=en xlink:href=foo />bar</svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| xlink:href="foo"
+| xml:lang="en"
+| <svg svg>
+| <svg g>
+| xlink href="foo"
+| xml lang="en"
+| "bar"
+
+#data
+<svg></path>
+#errors
+(1,5) expected-doctype-but-got-start-tag
+(1,12) unexpected-end-tag
+(1,12) unexpected-end-tag
+(1,12) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+
+#data
+<div><svg></div>a
+#errors
+(1,5) expected-doctype-but-got-start-tag
+(1,16) unexpected-end-tag
+(1,16) end-tag-too-early
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <svg svg>
+| "a"
+
+#data
+<div><svg><path></div>a
+#errors
+(1,5) expected-doctype-but-got-start-tag
+(1,22) unexpected-end-tag
+(1,22) end-tag-too-early
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <svg svg>
+| <svg path>
+| "a"
+
+#data
+<div><svg><path></svg><path>
+#errors
+(1,5) expected-doctype-but-got-start-tag
+(1,22) unexpected-end-tag
+(1,28) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <svg svg>
+| <svg path>
+| <path>
+
+#data
+<div><svg><path><foreignObject><math></div>a
+#errors
+(1,5) expected-doctype-but-got-start-tag
+(1,43) unexpected-end-tag
+(1,43) end-tag-too-early
+(1,44) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <svg svg>
+| <svg path>
+| <svg foreignObject>
+| <math math>
+| "a"
+
+#data
+<div><svg><path><foreignObject><p></div>a
+#errors
+(1,5) expected-doctype-but-got-start-tag
+(1,40) end-tag-too-early
+(1,41) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <svg svg>
+| <svg path>
+| <svg foreignObject>
+| <p>
+| "a"
+
+#data
+<!DOCTYPE html><svg><desc><div><svg><ul>a
+#errors
+(1,40) unexpected-html-element-in-foreign-content
+(1,41) expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg desc>
+| <div>
+| <svg svg>
+| <ul>
+| "a"
+
+#data
+<!DOCTYPE html><svg><desc><svg><ul>a
+#errors
+(1,35) unexpected-html-element-in-foreign-content
+(1,36) expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg desc>
+| <svg svg>
+| <ul>
+| "a"
+
+#data
+<!DOCTYPE html><p><svg><desc><p>
+#errors
+(1,32) expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <svg svg>
+| <svg desc>
+| <p>
+
+#data
+<!DOCTYPE html><p><svg><title><p>
+#errors
+(1,33) expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <svg svg>
+| <svg title>
+| <p>
+
+#data
+<div><svg><path><foreignObject><p></foreignObject><p>
+#errors
+(1,5) expected-doctype-but-got-start-tag
+(1,50) unexpected-end-tag
+(1,53) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <svg svg>
+| <svg path>
+| <svg foreignObject>
+| <p>
+| <p>
+
+#data
+<math><mi><div><object><div><span></span></div></object></div></mi><mi>
+#errors
+(1,6) expected-doctype-but-got-start-tag
+(1,71) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mi>
+| <div>
+| <object>
+| <div>
+| <span>
+| <math mi>
+
+#data
+<math><mi><svg><foreignObject><div><div></div></div></foreignObject></svg></mi><mi>
+#errors
+(1,6) expected-doctype-but-got-start-tag
+(1,83) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mi>
+| <svg svg>
+| <svg foreignObject>
+| <div>
+| <div>
+| <math mi>
+
+#data
+<svg><script></script><path>
+#errors
+(1,5) expected-doctype-but-got-start-tag
+(1,28) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg script>
+| <svg path>
+
+#data
+<table><svg></svg><tr>
+#errors
+(1,7) expected-doctype-but-got-start-tag
+(1,12) unexpected-start-tag-implies-table-voodoo
+(1,22) eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <table>
+| <tbody>
+| <tr>
+
+#data
+<math><mi><mglyph>
+#errors
+(1,6) expected-doctype-but-got-start-tag
+(1,18) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mi>
+| <math mglyph>
+
+#data
+<math><mi><malignmark>
+#errors
+(1,6) expected-doctype-but-got-start-tag
+(1,22) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mi>
+| <math malignmark>
+
+#data
+<math><mo><mglyph>
+#errors
+(1,6) expected-doctype-but-got-start-tag
+(1,18) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mo>
+| <math mglyph>
+
+#data
+<math><mo><malignmark>
+#errors
+(1,6) expected-doctype-but-got-start-tag
+(1,22) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mo>
+| <math malignmark>
+
+#data
+<math><mn><mglyph>
+#errors
+(1,6) expected-doctype-but-got-start-tag
+(1,18) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mn>
+| <math mglyph>
+
+#data
+<math><mn><malignmark>
+#errors
+(1,6) expected-doctype-but-got-start-tag
+(1,22) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mn>
+| <math malignmark>
+
+#data
+<math><ms><mglyph>
+#errors
+(1,6) expected-doctype-but-got-start-tag
+(1,18) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math ms>
+| <math mglyph>
+
+#data
+<math><ms><malignmark>
+#errors
+(1,6) expected-doctype-but-got-start-tag
+(1,22) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math ms>
+| <math malignmark>
+
+#data
+<math><mtext><mglyph>
+#errors
+(1,6) expected-doctype-but-got-start-tag
+(1,21) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mtext>
+| <math mglyph>
+
+#data
+<math><mtext><malignmark>
+#errors
+(1,6) expected-doctype-but-got-start-tag
+(1,25) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mtext>
+| <math malignmark>
+
+#data
+<math><annotation-xml><svg></svg></annotation-xml><mi>
+#errors
+(1,6) expected-doctype-but-got-start-tag
+(1,54) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math annotation-xml>
+| <svg svg>
+| <math mi>
+
+#data
+<math><annotation-xml><svg><foreignObject><div><math><mi></mi></math><span></span></div></foreignObject><path></path></svg></annotation-xml><mi>
+#errors
+(1,6) expected-doctype-but-got-start-tag
+(1,144) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math annotation-xml>
+| <svg svg>
+| <svg foreignObject>
+| <div>
+| <math math>
+| <math mi>
+| <span>
+| <svg path>
+| <math mi>
+
+#data
+<math><annotation-xml><svg><foreignObject><math><mi><svg></svg></mi><mo></mo></math><span></span></foreignObject><path></path></svg></annotation-xml><mi>
+#errors
+(1,6) expected-doctype-but-got-start-tag
+(1,153) expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math annotation-xml>
+| <svg svg>
+| <svg foreignObject>
+| <math math>
+| <math mi>
+| <svg svg>
+| <math mo>
+| <span>
+| <svg path>
+| <math mi>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests11.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests11.dat
new file mode 100644
index 000000000..ad62cdf65
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests11.dat
@@ -0,0 +1,482 @@
+#data
+<!DOCTYPE html><body><svg attributeName='' attributeType='' baseFrequency='' baseProfile='' calcMode='' clipPathUnits='' contentScriptType='' contentStyleType='' diffuseConstant='' edgeMode='' externalResourcesRequired='' filterRes='' filterUnits='' glyphRef='' gradientTransform='' gradientUnits='' kernelMatrix='' kernelUnitLength='' keyPoints='' keySplines='' keyTimes='' lengthAdjust='' limitingConeAngle='' markerHeight='' markerUnits='' markerWidth='' maskContentUnits='' maskUnits='' numOctaves='' pathLength='' patternContentUnits='' patternTransform='' patternUnits='' pointsAtX='' pointsAtY='' pointsAtZ='' preserveAlpha='' preserveAspectRatio='' primitiveUnits='' refX='' refY='' repeatCount='' repeatDur='' requiredExtensions='' requiredFeatures='' specularConstant='' specularExponent='' spreadMethod='' startOffset='' stdDeviation='' stitchTiles='' surfaceScale='' systemLanguage='' tableValues='' targetX='' targetY='' textLength='' viewBox='' viewTarget='' xChannelSelector='' yChannelSelector='' zoomAndPan=''></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| attributeName=""
+| attributeType=""
+| baseFrequency=""
+| baseProfile=""
+| calcMode=""
+| clipPathUnits=""
+| contentscripttype=""
+| contentstyletype=""
+| diffuseConstant=""
+| edgeMode=""
+| externalresourcesrequired=""
+| filterUnits=""
+| filterres=""
+| glyphRef=""
+| gradientTransform=""
+| gradientUnits=""
+| kernelMatrix=""
+| kernelUnitLength=""
+| keyPoints=""
+| keySplines=""
+| keyTimes=""
+| lengthAdjust=""
+| limitingConeAngle=""
+| markerHeight=""
+| markerUnits=""
+| markerWidth=""
+| maskContentUnits=""
+| maskUnits=""
+| numOctaves=""
+| pathLength=""
+| patternContentUnits=""
+| patternTransform=""
+| patternUnits=""
+| pointsAtX=""
+| pointsAtY=""
+| pointsAtZ=""
+| preserveAlpha=""
+| preserveAspectRatio=""
+| primitiveUnits=""
+| refX=""
+| refY=""
+| repeatCount=""
+| repeatDur=""
+| requiredExtensions=""
+| requiredFeatures=""
+| specularConstant=""
+| specularExponent=""
+| spreadMethod=""
+| startOffset=""
+| stdDeviation=""
+| stitchTiles=""
+| surfaceScale=""
+| systemLanguage=""
+| tableValues=""
+| targetX=""
+| targetY=""
+| textLength=""
+| viewBox=""
+| viewTarget=""
+| xChannelSelector=""
+| yChannelSelector=""
+| zoomAndPan=""
+
+#data
+<!DOCTYPE html><BODY><SVG ATTRIBUTENAME='' ATTRIBUTETYPE='' BASEFREQUENCY='' BASEPROFILE='' CALCMODE='' CLIPPATHUNITS='' CONTENTSCRIPTTYPE='' CONTENTSTYLETYPE='' DIFFUSECONSTANT='' EDGEMODE='' EXTERNALRESOURCESREQUIRED='' FILTERRES='' FILTERUNITS='' GLYPHREF='' GRADIENTTRANSFORM='' GRADIENTUNITS='' KERNELMATRIX='' KERNELUNITLENGTH='' KEYPOINTS='' KEYSPLINES='' KEYTIMES='' LENGTHADJUST='' LIMITINGCONEANGLE='' MARKERHEIGHT='' MARKERUNITS='' MARKERWIDTH='' MASKCONTENTUNITS='' MASKUNITS='' NUMOCTAVES='' PATHLENGTH='' PATTERNCONTENTUNITS='' PATTERNTRANSFORM='' PATTERNUNITS='' POINTSATX='' POINTSATY='' POINTSATZ='' PRESERVEALPHA='' PRESERVEASPECTRATIO='' PRIMITIVEUNITS='' REFX='' REFY='' REPEATCOUNT='' REPEATDUR='' REQUIREDEXTENSIONS='' REQUIREDFEATURES='' SPECULARCONSTANT='' SPECULAREXPONENT='' SPREADMETHOD='' STARTOFFSET='' STDDEVIATION='' STITCHTILES='' SURFACESCALE='' SYSTEMLANGUAGE='' TABLEVALUES='' TARGETX='' TARGETY='' TEXTLENGTH='' VIEWBOX='' VIEWTARGET='' XCHANNELSELECTOR='' YCHANNELSELECTOR='' ZOOMANDPAN=''></SVG>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| attributeName=""
+| attributeType=""
+| baseFrequency=""
+| baseProfile=""
+| calcMode=""
+| clipPathUnits=""
+| contentscripttype=""
+| contentstyletype=""
+| diffuseConstant=""
+| edgeMode=""
+| externalresourcesrequired=""
+| filterUnits=""
+| filterres=""
+| glyphRef=""
+| gradientTransform=""
+| gradientUnits=""
+| kernelMatrix=""
+| kernelUnitLength=""
+| keyPoints=""
+| keySplines=""
+| keyTimes=""
+| lengthAdjust=""
+| limitingConeAngle=""
+| markerHeight=""
+| markerUnits=""
+| markerWidth=""
+| maskContentUnits=""
+| maskUnits=""
+| numOctaves=""
+| pathLength=""
+| patternContentUnits=""
+| patternTransform=""
+| patternUnits=""
+| pointsAtX=""
+| pointsAtY=""
+| pointsAtZ=""
+| preserveAlpha=""
+| preserveAspectRatio=""
+| primitiveUnits=""
+| refX=""
+| refY=""
+| repeatCount=""
+| repeatDur=""
+| requiredExtensions=""
+| requiredFeatures=""
+| specularConstant=""
+| specularExponent=""
+| spreadMethod=""
+| startOffset=""
+| stdDeviation=""
+| stitchTiles=""
+| surfaceScale=""
+| systemLanguage=""
+| tableValues=""
+| targetX=""
+| targetY=""
+| textLength=""
+| viewBox=""
+| viewTarget=""
+| xChannelSelector=""
+| yChannelSelector=""
+| zoomAndPan=""
+
+#data
+<!DOCTYPE html><body><svg attributename='' attributetype='' basefrequency='' baseprofile='' calcmode='' clippathunits='' contentscripttype='' contentstyletype='' diffuseconstant='' edgemode='' externalresourcesrequired='' filterres='' filterunits='' glyphref='' gradienttransform='' gradientunits='' kernelmatrix='' kernelunitlength='' keypoints='' keysplines='' keytimes='' lengthadjust='' limitingconeangle='' markerheight='' markerunits='' markerwidth='' maskcontentunits='' maskunits='' numoctaves='' pathlength='' patterncontentunits='' patterntransform='' patternunits='' pointsatx='' pointsaty='' pointsatz='' preservealpha='' preserveaspectratio='' primitiveunits='' refx='' refy='' repeatcount='' repeatdur='' requiredextensions='' requiredfeatures='' specularconstant='' specularexponent='' spreadmethod='' startoffset='' stddeviation='' stitchtiles='' surfacescale='' systemlanguage='' tablevalues='' targetx='' targety='' textlength='' viewbox='' viewtarget='' xchannelselector='' ychannelselector='' zoomandpan=''></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| attributeName=""
+| attributeType=""
+| baseFrequency=""
+| baseProfile=""
+| calcMode=""
+| clipPathUnits=""
+| contentscripttype=""
+| contentstyletype=""
+| diffuseConstant=""
+| edgeMode=""
+| externalresourcesrequired=""
+| filterUnits=""
+| filterres=""
+| glyphRef=""
+| gradientTransform=""
+| gradientUnits=""
+| kernelMatrix=""
+| kernelUnitLength=""
+| keyPoints=""
+| keySplines=""
+| keyTimes=""
+| lengthAdjust=""
+| limitingConeAngle=""
+| markerHeight=""
+| markerUnits=""
+| markerWidth=""
+| maskContentUnits=""
+| maskUnits=""
+| numOctaves=""
+| pathLength=""
+| patternContentUnits=""
+| patternTransform=""
+| patternUnits=""
+| pointsAtX=""
+| pointsAtY=""
+| pointsAtZ=""
+| preserveAlpha=""
+| preserveAspectRatio=""
+| primitiveUnits=""
+| refX=""
+| refY=""
+| repeatCount=""
+| repeatDur=""
+| requiredExtensions=""
+| requiredFeatures=""
+| specularConstant=""
+| specularExponent=""
+| spreadMethod=""
+| startOffset=""
+| stdDeviation=""
+| stitchTiles=""
+| surfaceScale=""
+| systemLanguage=""
+| tableValues=""
+| targetX=""
+| targetY=""
+| textLength=""
+| viewBox=""
+| viewTarget=""
+| xChannelSelector=""
+| yChannelSelector=""
+| zoomAndPan=""
+
+#data
+<!DOCTYPE html><body><math attributeName='' attributeType='' baseFrequency='' baseProfile='' calcMode='' clipPathUnits='' contentScriptType='' contentStyleType='' diffuseConstant='' edgeMode='' externalResourcesRequired='' filterRes='' filterUnits='' glyphRef='' gradientTransform='' gradientUnits='' kernelMatrix='' kernelUnitLength='' keyPoints='' keySplines='' keyTimes='' lengthAdjust='' limitingConeAngle='' markerHeight='' markerUnits='' markerWidth='' maskContentUnits='' maskUnits='' numOctaves='' pathLength='' patternContentUnits='' patternTransform='' patternUnits='' pointsAtX='' pointsAtY='' pointsAtZ='' preserveAlpha='' preserveAspectRatio='' primitiveUnits='' refX='' refY='' repeatCount='' repeatDur='' requiredExtensions='' requiredFeatures='' specularConstant='' specularExponent='' spreadMethod='' startOffset='' stdDeviation='' stitchTiles='' surfaceScale='' systemLanguage='' tableValues='' targetX='' targetY='' textLength='' viewBox='' viewTarget='' xChannelSelector='' yChannelSelector='' zoomAndPan=''></math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+| attributename=""
+| attributetype=""
+| basefrequency=""
+| baseprofile=""
+| calcmode=""
+| clippathunits=""
+| contentscripttype=""
+| contentstyletype=""
+| diffuseconstant=""
+| edgemode=""
+| externalresourcesrequired=""
+| filterres=""
+| filterunits=""
+| glyphref=""
+| gradienttransform=""
+| gradientunits=""
+| kernelmatrix=""
+| kernelunitlength=""
+| keypoints=""
+| keysplines=""
+| keytimes=""
+| lengthadjust=""
+| limitingconeangle=""
+| markerheight=""
+| markerunits=""
+| markerwidth=""
+| maskcontentunits=""
+| maskunits=""
+| numoctaves=""
+| pathlength=""
+| patterncontentunits=""
+| patterntransform=""
+| patternunits=""
+| pointsatx=""
+| pointsaty=""
+| pointsatz=""
+| preservealpha=""
+| preserveaspectratio=""
+| primitiveunits=""
+| refx=""
+| refy=""
+| repeatcount=""
+| repeatdur=""
+| requiredextensions=""
+| requiredfeatures=""
+| specularconstant=""
+| specularexponent=""
+| spreadmethod=""
+| startoffset=""
+| stddeviation=""
+| stitchtiles=""
+| surfacescale=""
+| systemlanguage=""
+| tablevalues=""
+| targetx=""
+| targety=""
+| textlength=""
+| viewbox=""
+| viewtarget=""
+| xchannelselector=""
+| ychannelselector=""
+| zoomandpan=""
+
+#data
+<!DOCTYPE html><body><svg><altGlyph /><altGlyphDef /><altGlyphItem /><animateColor /><animateMotion /><animateTransform /><clipPath /><feBlend /><feColorMatrix /><feComponentTransfer /><feComposite /><feConvolveMatrix /><feDiffuseLighting /><feDisplacementMap /><feDistantLight /><feFlood /><feFuncA /><feFuncB /><feFuncG /><feFuncR /><feGaussianBlur /><feImage /><feMerge /><feMergeNode /><feMorphology /><feOffset /><fePointLight /><feSpecularLighting /><feSpotLight /><feTile /><feTurbulence /><foreignObject /><glyphRef /><linearGradient /><radialGradient /><textPath /></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg altGlyph>
+| <svg altGlyphDef>
+| <svg altGlyphItem>
+| <svg animateColor>
+| <svg animateMotion>
+| <svg animateTransform>
+| <svg clipPath>
+| <svg feBlend>
+| <svg feColorMatrix>
+| <svg feComponentTransfer>
+| <svg feComposite>
+| <svg feConvolveMatrix>
+| <svg feDiffuseLighting>
+| <svg feDisplacementMap>
+| <svg feDistantLight>
+| <svg feFlood>
+| <svg feFuncA>
+| <svg feFuncB>
+| <svg feFuncG>
+| <svg feFuncR>
+| <svg feGaussianBlur>
+| <svg feImage>
+| <svg feMerge>
+| <svg feMergeNode>
+| <svg feMorphology>
+| <svg feOffset>
+| <svg fePointLight>
+| <svg feSpecularLighting>
+| <svg feSpotLight>
+| <svg feTile>
+| <svg feTurbulence>
+| <svg foreignObject>
+| <svg glyphRef>
+| <svg linearGradient>
+| <svg radialGradient>
+| <svg textPath>
+
+#data
+<!DOCTYPE html><body><svg><altglyph /><altglyphdef /><altglyphitem /><animatecolor /><animatemotion /><animatetransform /><clippath /><feblend /><fecolormatrix /><fecomponenttransfer /><fecomposite /><feconvolvematrix /><fediffuselighting /><fedisplacementmap /><fedistantlight /><feflood /><fefunca /><fefuncb /><fefuncg /><fefuncr /><fegaussianblur /><feimage /><femerge /><femergenode /><femorphology /><feoffset /><fepointlight /><fespecularlighting /><fespotlight /><fetile /><feturbulence /><foreignobject /><glyphref /><lineargradient /><radialgradient /><textpath /></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg altGlyph>
+| <svg altGlyphDef>
+| <svg altGlyphItem>
+| <svg animateColor>
+| <svg animateMotion>
+| <svg animateTransform>
+| <svg clipPath>
+| <svg feBlend>
+| <svg feColorMatrix>
+| <svg feComponentTransfer>
+| <svg feComposite>
+| <svg feConvolveMatrix>
+| <svg feDiffuseLighting>
+| <svg feDisplacementMap>
+| <svg feDistantLight>
+| <svg feFlood>
+| <svg feFuncA>
+| <svg feFuncB>
+| <svg feFuncG>
+| <svg feFuncR>
+| <svg feGaussianBlur>
+| <svg feImage>
+| <svg feMerge>
+| <svg feMergeNode>
+| <svg feMorphology>
+| <svg feOffset>
+| <svg fePointLight>
+| <svg feSpecularLighting>
+| <svg feSpotLight>
+| <svg feTile>
+| <svg feTurbulence>
+| <svg foreignObject>
+| <svg glyphRef>
+| <svg linearGradient>
+| <svg radialGradient>
+| <svg textPath>
+
+#data
+<!DOCTYPE html><BODY><SVG><ALTGLYPH /><ALTGLYPHDEF /><ALTGLYPHITEM /><ANIMATECOLOR /><ANIMATEMOTION /><ANIMATETRANSFORM /><CLIPPATH /><FEBLEND /><FECOLORMATRIX /><FECOMPONENTTRANSFER /><FECOMPOSITE /><FECONVOLVEMATRIX /><FEDIFFUSELIGHTING /><FEDISPLACEMENTMAP /><FEDISTANTLIGHT /><FEFLOOD /><FEFUNCA /><FEFUNCB /><FEFUNCG /><FEFUNCR /><FEGAUSSIANBLUR /><FEIMAGE /><FEMERGE /><FEMERGENODE /><FEMORPHOLOGY /><FEOFFSET /><FEPOINTLIGHT /><FESPECULARLIGHTING /><FESPOTLIGHT /><FETILE /><FETURBULENCE /><FOREIGNOBJECT /><GLYPHREF /><LINEARGRADIENT /><RADIALGRADIENT /><TEXTPATH /></SVG>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg altGlyph>
+| <svg altGlyphDef>
+| <svg altGlyphItem>
+| <svg animateColor>
+| <svg animateMotion>
+| <svg animateTransform>
+| <svg clipPath>
+| <svg feBlend>
+| <svg feColorMatrix>
+| <svg feComponentTransfer>
+| <svg feComposite>
+| <svg feConvolveMatrix>
+| <svg feDiffuseLighting>
+| <svg feDisplacementMap>
+| <svg feDistantLight>
+| <svg feFlood>
+| <svg feFuncA>
+| <svg feFuncB>
+| <svg feFuncG>
+| <svg feFuncR>
+| <svg feGaussianBlur>
+| <svg feImage>
+| <svg feMerge>
+| <svg feMergeNode>
+| <svg feMorphology>
+| <svg feOffset>
+| <svg fePointLight>
+| <svg feSpecularLighting>
+| <svg feSpotLight>
+| <svg feTile>
+| <svg feTurbulence>
+| <svg foreignObject>
+| <svg glyphRef>
+| <svg linearGradient>
+| <svg radialGradient>
+| <svg textPath>
+
+#data
+<!DOCTYPE html><body><math><altGlyph /><altGlyphDef /><altGlyphItem /><animateColor /><animateMotion /><animateTransform /><clipPath /><feBlend /><feColorMatrix /><feComponentTransfer /><feComposite /><feConvolveMatrix /><feDiffuseLighting /><feDisplacementMap /><feDistantLight /><feFlood /><feFuncA /><feFuncB /><feFuncG /><feFuncR /><feGaussianBlur /><feImage /><feMerge /><feMergeNode /><feMorphology /><feOffset /><fePointLight /><feSpecularLighting /><feSpotLight /><feTile /><feTurbulence /><foreignObject /><glyphRef /><linearGradient /><radialGradient /><textPath /></math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math altglyph>
+| <math altglyphdef>
+| <math altglyphitem>
+| <math animatecolor>
+| <math animatemotion>
+| <math animatetransform>
+| <math clippath>
+| <math feblend>
+| <math fecolormatrix>
+| <math fecomponenttransfer>
+| <math fecomposite>
+| <math feconvolvematrix>
+| <math fediffuselighting>
+| <math fedisplacementmap>
+| <math fedistantlight>
+| <math feflood>
+| <math fefunca>
+| <math fefuncb>
+| <math fefuncg>
+| <math fefuncr>
+| <math fegaussianblur>
+| <math feimage>
+| <math femerge>
+| <math femergenode>
+| <math femorphology>
+| <math feoffset>
+| <math fepointlight>
+| <math fespecularlighting>
+| <math fespotlight>
+| <math fetile>
+| <math feturbulence>
+| <math foreignobject>
+| <math glyphref>
+| <math lineargradient>
+| <math radialgradient>
+| <math textpath>
+
+#data
+<!DOCTYPE html><body><svg><solidColor /></svg>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg solidcolor>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests12.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests12.dat
new file mode 100644
index 000000000..63107d277
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests12.dat
@@ -0,0 +1,62 @@
+#data
+<!DOCTYPE html><body><p>foo<math><mtext><i>baz</i></mtext><annotation-xml><svg><desc><b>eggs</b></desc><g><foreignObject><P>spam<TABLE><tr><td><img></td></table></foreignObject></g><g>quux</g></svg></annotation-xml></math>bar
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| "foo"
+| <math math>
+| <math mtext>
+| <i>
+| "baz"
+| <math annotation-xml>
+| <svg svg>
+| <svg desc>
+| <b>
+| "eggs"
+| <svg g>
+| <svg foreignObject>
+| <p>
+| "spam"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <img>
+| <svg g>
+| "quux"
+| "bar"
+
+#data
+<!DOCTYPE html><body>foo<math><mtext><i>baz</i></mtext><annotation-xml><svg><desc><b>eggs</b></desc><g><foreignObject><P>spam<TABLE><tr><td><img></td></table></foreignObject></g><g>quux</g></svg></annotation-xml></math>bar
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "foo"
+| <math math>
+| <math mtext>
+| <i>
+| "baz"
+| <math annotation-xml>
+| <svg svg>
+| <svg desc>
+| <b>
+| "eggs"
+| <svg g>
+| <svg foreignObject>
+| <p>
+| "spam"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <img>
+| <svg g>
+| "quux"
+| "bar"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests14.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests14.dat
new file mode 100644
index 000000000..a08b7649e
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests14.dat
@@ -0,0 +1,75 @@
+#data
+<!DOCTYPE html><html><body><xyz:abc></xyz:abc>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <xyz:abc>
+
+#data
+<!DOCTYPE html><html><body><xyz:abc></xyz:abc><span></span>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <xyz:abc>
+| <span>
+
+#data
+<!DOCTYPE html><html><html abc:def=gh><xyz:abc></xyz:abc>
+#errors
+(1,38): non-html-root
+#document
+| <!DOCTYPE html>
+| <html>
+| abc:def="gh"
+| <head>
+| <body>
+| <xyz:abc>
+
+#data
+<!DOCTYPE html><html xml:lang=bar><html xml:lang=foo>
+#errors
+(1,53): non-html-root
+#document
+| <!DOCTYPE html>
+| <html>
+| xml:lang="bar"
+| <head>
+| <body>
+
+#data
+<!DOCTYPE html><html 123=456>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| 123="456"
+| <head>
+| <body>
+
+#data
+<!DOCTYPE html><html 123=456><html 789=012>
+#errors
+(1,43): non-html-root
+#document
+| <!DOCTYPE html>
+| <html>
+| 123="456"
+| 789="012"
+| <head>
+| <body>
+
+#data
+<!DOCTYPE html><html><body 789=012>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| 789="012"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests15.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests15.dat
new file mode 100644
index 000000000..93d06a871
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests15.dat
@@ -0,0 +1,216 @@
+#data
+<!DOCTYPE html><p><b><i><u></p> <p>X
+#errors
+(1,31): unexpected-end-tag
+(1,36): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <b>
+| <i>
+| <u>
+| <b>
+| <i>
+| <u>
+| " "
+| <p>
+| "X"
+
+#data
+<p><b><i><u></p>
+<p>X
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,16): unexpected-end-tag
+(2,4): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <b>
+| <i>
+| <u>
+| <b>
+| <i>
+| <u>
+| "
+"
+| <p>
+| "X"
+
+#data
+<!doctype html></html> <head>
+#errors
+(1,29): expected-eof-but-got-start-tag
+(1,29): unexpected-start-tag-ignored
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| " "
+
+#data
+<!doctype html></body><meta>
+#errors
+(1,28): unexpected-start-tag-after-body
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <meta>
+
+#data
+<html></html><!-- foo -->
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <!-- foo -->
+
+#data
+<!doctype html></body><title>X</title>
+#errors
+(1,29): unexpected-start-tag-after-body
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <title>
+| "X"
+
+#data
+<!doctype html><table> X<meta></table>
+#errors
+(1,23): foster-parenting-character
+(1,24): foster-parenting-character
+(1,30): foster-parenting-start-character
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| " X"
+| <meta>
+| <table>
+
+#data
+<!doctype html><table> x</table>
+#errors
+(1,23): foster-parenting-character
+(1,24): foster-parenting-character
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| " x"
+| <table>
+
+#data
+<!doctype html><table> x </table>
+#errors
+(1,23): foster-parenting-character
+(1,24): foster-parenting-character
+(1,25): foster-parenting-character
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| " x "
+| <table>
+
+#data
+<!doctype html><table><tr> x</table>
+#errors
+(1,27): foster-parenting-character
+(1,28): foster-parenting-character
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| " x"
+| <table>
+| <tbody>
+| <tr>
+
+#data
+<!doctype html><table>X<style> <tr>x </style> </table>
+#errors
+(1,23): foster-parenting-character
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "X"
+| <table>
+| <style>
+| " <tr>x "
+| " "
+
+#data
+<!doctype html><div><table><a>foo</a> <tr><td>bar</td> </tr></table></div>
+#errors
+(1,30): foster-parenting-start-tag
+(1,31): foster-parenting-character
+(1,32): foster-parenting-character
+(1,33): foster-parenting-character
+(1,37): foster-parenting-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <div>
+| <a>
+| "foo"
+| <table>
+| " "
+| <tbody>
+| <tr>
+| <td>
+| "bar"
+| " "
+
+#data
+<frame></frame></frame><frameset><frame><frameset><frame></frameset><noframes></frameset><noframes>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,7): unexpected-start-tag-ignored
+(1,15): unexpected-end-tag
+(1,23): unexpected-end-tag
+(1,33): unexpected-start-tag
+(1,99): expected-named-closing-tag-but-got-eof
+(1,99): eof-in-frameset
+#document
+| <html>
+| <head>
+| <frameset>
+| <frame>
+| <frameset>
+| <frame>
+| <noframes>
+| "</frameset><noframes>"
+
+#data
+<!DOCTYPE html><object></html>
+#errors
+(1,30): expected-body-in-scope
+(1,30): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <object>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests16.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests16.dat
new file mode 100644
index 000000000..c8f6d4370
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests16.dat
@@ -0,0 +1,2374 @@
+#data
+<!doctype html><script>
+#errors
+(1,23): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| <body>
+
+#data
+<!doctype html><script>a
+#errors
+(1,24): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "a"
+| <body>
+
+#data
+<!doctype html><script><
+#errors
+(1,24): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<"
+| <body>
+
+#data
+<!doctype html><script></
+#errors
+(1,25): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "</"
+| <body>
+
+#data
+<!doctype html><script></S
+#errors
+(1,26): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "</S"
+| <body>
+
+#data
+<!doctype html><script></SC
+#errors
+(1,27): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "</SC"
+| <body>
+
+#data
+<!doctype html><script></SCR
+#errors
+(1,28): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "</SCR"
+| <body>
+
+#data
+<!doctype html><script></SCRI
+#errors
+(1,29): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "</SCRI"
+| <body>
+
+#data
+<!doctype html><script></SCRIP
+#errors
+(1,30): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "</SCRIP"
+| <body>
+
+#data
+<!doctype html><script></SCRIPT
+#errors
+(1,31): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "</SCRIPT"
+| <body>
+
+#data
+<!doctype html><script></SCRIPT
+#errors
+(1,32): expected-attribute-name-but-got-eof
+(1,32): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| <body>
+
+#data
+<!doctype html><script></s
+#errors
+(1,26): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "</s"
+| <body>
+
+#data
+<!doctype html><script></sc
+#errors
+(1,27): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "</sc"
+| <body>
+
+#data
+<!doctype html><script></scr
+#errors
+(1,28): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "</scr"
+| <body>
+
+#data
+<!doctype html><script></scri
+#errors
+(1,29): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "</scri"
+| <body>
+
+#data
+<!doctype html><script></scrip
+#errors
+(1,30): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "</scrip"
+| <body>
+
+#data
+<!doctype html><script></script
+#errors
+(1,31): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "</script"
+| <body>
+
+#data
+<!doctype html><script></script
+#errors
+(1,32): expected-attribute-name-but-got-eof
+(1,32): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| <body>
+
+#data
+<!doctype html><script><!
+#errors
+(1,25): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!"
+| <body>
+
+#data
+<!doctype html><script><!a
+#errors
+(1,26): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!a"
+| <body>
+
+#data
+<!doctype html><script><!-
+#errors
+(1,26): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!-"
+| <body>
+
+#data
+<!doctype html><script><!-a
+#errors
+(1,27): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!-a"
+| <body>
+
+#data
+<!doctype html><script><!--
+#errors
+(1,27): expected-named-closing-tag-but-got-eof
+(1,27): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--"
+| <body>
+
+#data
+<!doctype html><script><!--a
+#errors
+(1,28): expected-named-closing-tag-but-got-eof
+(1,28): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--a"
+| <body>
+
+#data
+<!doctype html><script><!--<
+#errors
+(1,28): expected-named-closing-tag-but-got-eof
+(1,28): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<"
+| <body>
+
+#data
+<!doctype html><script><!--<a
+#errors
+(1,29): expected-named-closing-tag-but-got-eof
+(1,29): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<a"
+| <body>
+
+#data
+<!doctype html><script><!--</
+#errors
+(1,29): expected-named-closing-tag-but-got-eof
+(1,29): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--</"
+| <body>
+
+#data
+<!doctype html><script><!--</script
+#errors
+(1,35): expected-named-closing-tag-but-got-eof
+(1,35): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--</script"
+| <body>
+
+#data
+<!doctype html><script><!--</script
+#errors
+(1,36): expected-attribute-name-but-got-eof
+(1,36): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--"
+| <body>
+
+#data
+<!doctype html><script><!--<s
+#errors
+(1,29): expected-named-closing-tag-but-got-eof
+(1,29): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<s"
+| <body>
+
+#data
+<!doctype html><script><!--<script
+#errors
+(1,34): expected-named-closing-tag-but-got-eof
+(1,34): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script"
+| <body>
+
+#data
+<!doctype html><script><!--<script
+#errors
+(1,35): eof-in-script-in-script
+(1,35): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script "
+| <body>
+
+#data
+<!doctype html><script><!--<script <
+#errors
+(1,36): eof-in-script-in-script
+(1,36): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script <"
+| <body>
+
+#data
+<!doctype html><script><!--<script <a
+#errors
+(1,37): eof-in-script-in-script
+(1,37): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script <a"
+| <body>
+
+#data
+<!doctype html><script><!--<script </
+#errors
+(1,37): eof-in-script-in-script
+(1,37): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script </"
+| <body>
+
+#data
+<!doctype html><script><!--<script </s
+#errors
+(1,38): eof-in-script-in-script
+(1,38): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script </s"
+| <body>
+
+#data
+<!doctype html><script><!--<script </script
+#errors
+(1,43): eof-in-script-in-script
+(1,43): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script </script"
+| <body>
+
+#data
+<!doctype html><script><!--<script </scripta
+#errors
+(1,44): eof-in-script-in-script
+(1,44): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script </scripta"
+| <body>
+
+#data
+<!doctype html><script><!--<script </script
+#errors
+(1,44): expected-named-closing-tag-but-got-eof
+(1,44): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script </script "
+| <body>
+
+#data
+<!doctype html><script><!--<script </script>
+#errors
+(1,44): expected-named-closing-tag-but-got-eof
+(1,44): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script </script>"
+| <body>
+
+#data
+<!doctype html><script><!--<script </script/
+#errors
+(1,44): expected-named-closing-tag-but-got-eof
+(1,44): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script </script/"
+| <body>
+
+#data
+<!doctype html><script><!--<script </script <
+#errors
+(1,45): expected-named-closing-tag-but-got-eof
+(1,45): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script </script <"
+| <body>
+
+#data
+<!doctype html><script><!--<script </script <a
+#errors
+(1,46): expected-named-closing-tag-but-got-eof
+(1,46): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script </script <a"
+| <body>
+
+#data
+<!doctype html><script><!--<script </script </
+#errors
+(1,46): expected-named-closing-tag-but-got-eof
+(1,46): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script </script </"
+| <body>
+
+#data
+<!doctype html><script><!--<script </script </script
+#errors
+(1,52): expected-named-closing-tag-but-got-eof
+(1,52): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script </script </script"
+| <body>
+
+#data
+<!doctype html><script><!--<script </script </script
+#errors
+(1,53): expected-attribute-name-but-got-eof
+(1,53): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script </script "
+| <body>
+
+#data
+<!doctype html><script><!--<script </script </script/
+#errors
+(1,53): unexpected-EOF-after-solidus-in-tag
+(1,53): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script </script "
+| <body>
+
+#data
+<!doctype html><script><!--<script </script </script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script </script "
+| <body>
+
+#data
+<!doctype html><script><!--<script -
+#errors
+(1,36): eof-in-script-in-script
+(1,36): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script -"
+| <body>
+
+#data
+<!doctype html><script><!--<script -a
+#errors
+(1,37): eof-in-script-in-script
+(1,37): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script -a"
+| <body>
+
+#data
+<!doctype html><script><!--<script -<
+#errors
+(1,37): eof-in-script-in-script
+(1,37): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script -<"
+| <body>
+
+#data
+<!doctype html><script><!--<script --
+#errors
+(1,37): eof-in-script-in-script
+(1,37): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script --"
+| <body>
+
+#data
+<!doctype html><script><!--<script --a
+#errors
+(1,38): eof-in-script-in-script
+(1,38): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script --a"
+| <body>
+
+#data
+<!doctype html><script><!--<script --<
+#errors
+(1,38): eof-in-script-in-script
+(1,38): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script --<"
+| <body>
+
+#data
+<!doctype html><script><!--<script -->
+#errors
+(1,38): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script -->"
+| <body>
+
+#data
+<!doctype html><script><!--<script --><
+#errors
+(1,39): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script --><"
+| <body>
+
+#data
+<!doctype html><script><!--<script --></
+#errors
+(1,40): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script --></"
+| <body>
+
+#data
+<!doctype html><script><!--<script --></script
+#errors
+(1,46): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script --></script"
+| <body>
+
+#data
+<!doctype html><script><!--<script --></script
+#errors
+(1,47): expected-attribute-name-but-got-eof
+(1,47): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script -->"
+| <body>
+
+#data
+<!doctype html><script><!--<script --></script/
+#errors
+(1,47): unexpected-EOF-after-solidus-in-tag
+(1,47): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script -->"
+| <body>
+
+#data
+<!doctype html><script><!--<script --></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script -->"
+| <body>
+
+#data
+<!doctype html><script><!--<script><\/script>--></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script><\/script>-->"
+| <body>
+
+#data
+<!doctype html><script><!--<script></scr'+'ipt>--></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script></scr'+'ipt>-->"
+| <body>
+
+#data
+<!doctype html><script><!--<script></script><script></script></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script></script><script></script>"
+| <body>
+
+#data
+<!doctype html><script><!--<script></script><script></script>--><!--</script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script></script><script></script>--><!--"
+| <body>
+
+#data
+<!doctype html><script><!--<script></script><script></script>-- ></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script></script><script></script>-- >"
+| <body>
+
+#data
+<!doctype html><script><!--<script></script><script></script>- -></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script></script><script></script>- ->"
+| <body>
+
+#data
+<!doctype html><script><!--<script></script><script></script>- - ></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script></script><script></script>- - >"
+| <body>
+
+#data
+<!doctype html><script><!--<script></script><script></script>-></script>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script></script><script></script>->"
+| <body>
+
+#data
+<!doctype html><script><!--<script>--!></script>X
+#errors
+(1,49): expected-named-closing-tag-but-got-eof
+(1,49): unexpected-EOF-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script>--!></script>X"
+| <body>
+
+#data
+<!doctype html><script><!--<scr'+'ipt></script>--></script>
+#errors
+(1,59): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<scr'+'ipt>"
+| <body>
+| "-->"
+
+#data
+<!doctype html><script><!--<script></scr'+'ipt></script>X
+#errors
+(1,57): expected-named-closing-tag-but-got-eof
+(1,57): unexpected-eof-in-text-mode
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "<!--<script></scr'+'ipt></script>X"
+| <body>
+
+#data
+<!doctype html><style><!--<style></style>--></style>
+#errors
+(1,52): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <style>
+| "<!--<style>"
+| <body>
+| "-->"
+
+#data
+<!doctype html><style><!--</style>X
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <style>
+| "<!--"
+| <body>
+| "X"
+
+#data
+<!doctype html><style><!--...</style>...--></style>
+#errors
+(1,51): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <style>
+| "<!--..."
+| <body>
+| "...-->"
+
+#data
+<!doctype html><style><!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style></style>X
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <style>
+| "<!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style>"
+| <body>
+| "X"
+
+#data
+<!doctype html><style><!--...<style><!--...--!></style>--></style>
+#errors
+(1,66): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <style>
+| "<!--...<style><!--...--!>"
+| <body>
+| "-->"
+
+#data
+<!doctype html><style><!--...</style><!-- --><style>@import ...</style>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <style>
+| "<!--..."
+| <!-- -->
+| <style>
+| "@import ..."
+| <body>
+
+#data
+<!doctype html><style>...<style><!--...</style><!-- --></style>
+#errors
+(1,63): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <style>
+| "...<style><!--..."
+| <!-- -->
+| <body>
+
+#data
+<!doctype html><style>...<!--[if IE]><style>...</style>X
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <style>
+| "...<!--[if IE]><style>..."
+| <body>
+| "X"
+
+#data
+<!doctype html><title><!--<title></title>--></title>
+#errors
+(1,52): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <title>
+| "<!--<title>"
+| <body>
+| "-->"
+
+#data
+<!doctype html><title>&lt;/title></title>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <title>
+| "</title>"
+| <body>
+
+#data
+<!doctype html><title>foo/title><link></head><body>X
+#errors
+(1,52): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <title>
+| "foo/title><link></head><body>X"
+| <body>
+
+#data
+<!doctype html><noscript><!--<noscript></noscript>--></noscript>
+#errors
+(1,64): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <noscript>
+| "<!--<noscript>"
+| <body>
+| "-->"
+
+#data
+<!doctype html><noscript><!--</noscript>X<noscript>--></noscript>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <noscript>
+| "<!--"
+| <body>
+| "X"
+| <noscript>
+| "-->"
+
+#data
+<!doctype html><noscript><iframe></noscript>X
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <noscript>
+| "<iframe>"
+| <body>
+| "X"
+
+#data
+<!doctype html><noframes><!--<noframes></noframes>--></noframes>
+#errors
+(1,64): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <noframes>
+| "<!--<noframes>"
+| <body>
+| "-->"
+
+#data
+<!doctype html><noframes><body><script><!--...</script></body></noframes></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <noframes>
+| "<body><script><!--...</script></body>"
+| <body>
+
+#data
+<!doctype html><textarea><!--<textarea></textarea>--></textarea>
+#errors
+(1,64): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <textarea>
+| "<!--<textarea>"
+| "-->"
+
+#data
+<!doctype html><textarea>&lt;/textarea></textarea>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <textarea>
+| "</textarea>"
+
+#data
+<!doctype html><textarea>&lt;</textarea>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <textarea>
+| "<"
+
+#data
+<!doctype html><textarea>a&lt;b</textarea>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <textarea>
+| "a<b"
+
+#data
+<!doctype html><iframe><!--<iframe></iframe>--></iframe>
+#errors
+(1,56): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <iframe>
+| "<!--<iframe>"
+| "-->"
+
+#data
+<!doctype html><iframe>...<!--X->...<!--/X->...</iframe>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <iframe>
+| "...<!--X->...<!--/X->..."
+
+#data
+<!doctype html><xmp><!--<xmp></xmp>--></xmp>
+#errors
+(1,44): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <xmp>
+| "<!--<xmp>"
+| "-->"
+
+#data
+<!doctype html><noembed><!--<noembed></noembed>--></noembed>
+#errors
+(1,60): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <noembed>
+| "<!--<noembed>"
+| "-->"
+
+#data
+<script>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,8): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| <body>
+
+#data
+<script>a
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,9): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "a"
+| <body>
+
+#data
+<script><
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,9): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<"
+| <body>
+
+#data
+<script></
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,10): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "</"
+| <body>
+
+#data
+<script></S
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,11): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "</S"
+| <body>
+
+#data
+<script></SC
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,12): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "</SC"
+| <body>
+
+#data
+<script></SCR
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,13): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "</SCR"
+| <body>
+
+#data
+<script></SCRI
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,14): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "</SCRI"
+| <body>
+
+#data
+<script></SCRIP
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,15): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "</SCRIP"
+| <body>
+
+#data
+<script></SCRIPT
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,16): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "</SCRIPT"
+| <body>
+
+#data
+<script></SCRIPT
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,17): expected-attribute-name-but-got-eof
+(1,17): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| <body>
+
+#data
+<script></s
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,11): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "</s"
+| <body>
+
+#data
+<script></sc
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,12): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "</sc"
+| <body>
+
+#data
+<script></scr
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,13): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "</scr"
+| <body>
+
+#data
+<script></scri
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,14): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "</scri"
+| <body>
+
+#data
+<script></scrip
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,15): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "</scrip"
+| <body>
+
+#data
+<script></script
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,16): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "</script"
+| <body>
+
+#data
+<script></script
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,17): expected-attribute-name-but-got-eof
+(1,17): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| <body>
+
+#data
+<script><!
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,10): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!"
+| <body>
+
+#data
+<script><!a
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,11): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!a"
+| <body>
+
+#data
+<script><!-
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,11): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!-"
+| <body>
+
+#data
+<script><!-a
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,12): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!-a"
+| <body>
+
+#data
+<script><!--
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,12): expected-named-closing-tag-but-got-eof
+(1,12): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--"
+| <body>
+
+#data
+<script><!--a
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,13): expected-named-closing-tag-but-got-eof
+(1,13): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--a"
+| <body>
+
+#data
+<script><!--<
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,13): expected-named-closing-tag-but-got-eof
+(1,13): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<"
+| <body>
+
+#data
+<script><!--<a
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,14): expected-named-closing-tag-but-got-eof
+(1,14): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<a"
+| <body>
+
+#data
+<script><!--</
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,14): expected-named-closing-tag-but-got-eof
+(1,14): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--</"
+| <body>
+
+#data
+<script><!--</script
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,20): expected-named-closing-tag-but-got-eof
+(1,20): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--</script"
+| <body>
+
+#data
+<script><!--</script
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,21): expected-attribute-name-but-got-eof
+(1,21): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--"
+| <body>
+
+#data
+<script><!--<s
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,14): expected-named-closing-tag-but-got-eof
+(1,14): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<s"
+| <body>
+
+#data
+<script><!--<script
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,19): expected-named-closing-tag-but-got-eof
+(1,19): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script"
+| <body>
+
+#data
+<script><!--<script
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,20): eof-in-script-in-script
+(1,20): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script "
+| <body>
+
+#data
+<script><!--<script <
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,21): eof-in-script-in-script
+(1,21): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script <"
+| <body>
+
+#data
+<script><!--<script <a
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,22): eof-in-script-in-script
+(1,22): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script <a"
+| <body>
+
+#data
+<script><!--<script </
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,22): eof-in-script-in-script
+(1,22): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script </"
+| <body>
+
+#data
+<script><!--<script </s
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,23): eof-in-script-in-script
+(1,23): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script </s"
+| <body>
+
+#data
+<script><!--<script </script
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,28): eof-in-script-in-script
+(1,28): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script </script"
+| <body>
+
+#data
+<script><!--<script </scripta
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,29): eof-in-script-in-script
+(1,29): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script </scripta"
+| <body>
+
+#data
+<script><!--<script </script
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,29): expected-named-closing-tag-but-got-eof
+(1,29): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script </script "
+| <body>
+
+#data
+<script><!--<script </script>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,29): expected-named-closing-tag-but-got-eof
+(1,29): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script </script>"
+| <body>
+
+#data
+<script><!--<script </script/
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,29): expected-named-closing-tag-but-got-eof
+(1,29): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script </script/"
+| <body>
+
+#data
+<script><!--<script </script <
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,30): expected-named-closing-tag-but-got-eof
+(1,30): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script </script <"
+| <body>
+
+#data
+<script><!--<script </script <a
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,31): expected-named-closing-tag-but-got-eof
+(1,31): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script </script <a"
+| <body>
+
+#data
+<script><!--<script </script </
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,31): expected-named-closing-tag-but-got-eof
+(1,31): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script </script </"
+| <body>
+
+#data
+<script><!--<script </script </script
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,37): expected-named-closing-tag-but-got-eof
+(1,37): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script </script </script"
+| <body>
+
+#data
+<script><!--<script </script </script
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,38): expected-attribute-name-but-got-eof
+(1,38): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script </script "
+| <body>
+
+#data
+<script><!--<script </script </script/
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,38): unexpected-EOF-after-solidus-in-tag
+(1,38): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script </script "
+| <body>
+
+#data
+<script><!--<script </script </script>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script </script "
+| <body>
+
+#data
+<script><!--<script -
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,21): eof-in-script-in-script
+(1,21): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script -"
+| <body>
+
+#data
+<script><!--<script -a
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,22): eof-in-script-in-script
+(1,22): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script -a"
+| <body>
+
+#data
+<script><!--<script --
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,22): eof-in-script-in-script
+(1,22): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script --"
+| <body>
+
+#data
+<script><!--<script --a
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,23): eof-in-script-in-script
+(1,23): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script --a"
+| <body>
+
+#data
+<script><!--<script -->
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,23): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script -->"
+| <body>
+
+#data
+<script><!--<script --><
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,24): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script --><"
+| <body>
+
+#data
+<script><!--<script --></
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,25): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script --></"
+| <body>
+
+#data
+<script><!--<script --></script
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,31): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script --></script"
+| <body>
+
+#data
+<script><!--<script --></script
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,32): expected-attribute-name-but-got-eof
+(1,32): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script -->"
+| <body>
+
+#data
+<script><!--<script --></script/
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,32): unexpected-EOF-after-solidus-in-tag
+(1,32): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script -->"
+| <body>
+
+#data
+<script><!--<script --></script>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script -->"
+| <body>
+
+#data
+<script><!--<script><\/script>--></script>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script><\/script>-->"
+| <body>
+
+#data
+<script><!--<script></scr'+'ipt>--></script>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script></scr'+'ipt>-->"
+| <body>
+
+#data
+<script><!--<script></script><script></script></script>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script></script><script></script>"
+| <body>
+
+#data
+<script><!--<script></script><script></script>--><!--</script>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script></script><script></script>--><!--"
+| <body>
+
+#data
+<script><!--<script></script><script></script>-- ></script>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script></script><script></script>-- >"
+| <body>
+
+#data
+<script><!--<script></script><script></script>- -></script>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script></script><script></script>- ->"
+| <body>
+
+#data
+<script><!--<script></script><script></script>- - ></script>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script></script><script></script>- - >"
+| <body>
+
+#data
+<script><!--<script></script><script></script>-></script>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script></script><script></script>->"
+| <body>
+
+#data
+<script><!--<script>--!></script>X
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,34): expected-named-closing-tag-but-got-eof
+(1,34): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script>--!></script>X"
+| <body>
+
+#data
+<script><!--<scr'+'ipt></script>--></script>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,44): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<scr'+'ipt>"
+| <body>
+| "-->"
+
+#data
+<script><!--<script></scr'+'ipt></script>X
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,42): expected-named-closing-tag-but-got-eof
+(1,42): unexpected-eof-in-text-mode
+#document
+| <html>
+| <head>
+| <script>
+| "<!--<script></scr'+'ipt></script>X"
+| <body>
+
+#data
+<style><!--<style></style>--></style>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,37): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <style>
+| "<!--<style>"
+| <body>
+| "-->"
+
+#data
+<style><!--</style>X
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <style>
+| "<!--"
+| <body>
+| "X"
+
+#data
+<style><!--...</style>...--></style>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,36): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <style>
+| "<!--..."
+| <body>
+| "...-->"
+
+#data
+<style><!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style></style>X
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <style>
+| "<!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style>"
+| <body>
+| "X"
+
+#data
+<style><!--...<style><!--...--!></style>--></style>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,51): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <style>
+| "<!--...<style><!--...--!>"
+| <body>
+| "-->"
+
+#data
+<style><!--...</style><!-- --><style>@import ...</style>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <style>
+| "<!--..."
+| <!-- -->
+| <style>
+| "@import ..."
+| <body>
+
+#data
+<style>...<style><!--...</style><!-- --></style>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,48): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <style>
+| "...<style><!--..."
+| <!-- -->
+| <body>
+
+#data
+<style>...<!--[if IE]><style>...</style>X
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <style>
+| "...<!--[if IE]><style>..."
+| <body>
+| "X"
+
+#data
+<title><!--<title></title>--></title>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,37): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <title>
+| "<!--<title>"
+| <body>
+| "-->"
+
+#data
+<title>&lt;/title></title>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <title>
+| "</title>"
+| <body>
+
+#data
+<title>foo/title><link></head><body>X
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,37): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <title>
+| "foo/title><link></head><body>X"
+| <body>
+
+#data
+<noscript><!--<noscript></noscript>--></noscript>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(1,49): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <noscript>
+| "<!--<noscript>"
+| <body>
+| "-->"
+
+#data
+<noscript><!--</noscript>X<noscript>--></noscript>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <noscript>
+| "<!--"
+| <body>
+| "X"
+| <noscript>
+| "-->"
+
+#data
+<noscript><iframe></noscript>X
+#errors
+(1,10): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <noscript>
+| "<iframe>"
+| <body>
+| "X"
+
+#data
+<noframes><!--<noframes></noframes>--></noframes>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(1,49): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <noframes>
+| "<!--<noframes>"
+| <body>
+| "-->"
+
+#data
+<noframes><body><script><!--...</script></body></noframes></html>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <noframes>
+| "<body><script><!--...</script></body>"
+| <body>
+
+#data
+<textarea><!--<textarea></textarea>--></textarea>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(1,49): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <textarea>
+| "<!--<textarea>"
+| "-->"
+
+#data
+<textarea>&lt;/textarea></textarea>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <textarea>
+| "</textarea>"
+
+#data
+<iframe><!--<iframe></iframe>--></iframe>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,41): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <iframe>
+| "<!--<iframe>"
+| "-->"
+
+#data
+<iframe>...<!--X->...<!--/X->...</iframe>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <iframe>
+| "...<!--X->...<!--/X->..."
+
+#data
+<xmp><!--<xmp></xmp>--></xmp>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,29): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <xmp>
+| "<!--<xmp>"
+| "-->"
+
+#data
+<noembed><!--<noembed></noembed>--></noembed>
+#errors
+(1,9): expected-doctype-but-got-start-tag
+(1,45): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <noembed>
+| "<!--<noembed>"
+| "-->"
+
+#data
+<!doctype html><table>
+
+#errors
+(2,0): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| "
+"
+
+#data
+<!doctype html><table><td><span><font></span><span>
+#errors
+(1,26): unexpected-cell-in-table-body
+(1,45): unexpected-end-tag
+(1,51): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <span>
+| <font>
+| <font>
+| <span>
+
+#data
+<!doctype html><form><table></form><form></table></form>
+#errors
+(1,35): unexpected-end-tag-implies-table-voodoo
+(1,35): unexpected-end-tag
+(1,41): unexpected-form-in-table
+(1,56): unexpected-end-tag
+(1,56): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <form>
+| <table>
+| <form>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests17.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests17.dat
new file mode 100644
index 000000000..37a7be418
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests17.dat
@@ -0,0 +1,180 @@
+#data
+<!doctype html><table><tbody><select><tr>
+#errors
+(1,37): unexpected-start-tag-implies-table-voodoo
+(1,41): unexpected-table-element-start-tag-in-select-in-table
+(1,41): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| <table>
+| <tbody>
+| <tr>
+
+#data
+<!doctype html><table><tr><select><td>
+#errors
+(1,34): unexpected-start-tag-implies-table-voodoo
+(1,38): unexpected-table-element-start-tag-in-select-in-table
+(1,38): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+
+#data
+<!doctype html><table><tr><td><select><td>
+#errors
+(1,42): unexpected-table-element-start-tag-in-select-in-table
+(1,42): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <select>
+| <td>
+
+#data
+<!doctype html><table><tr><th><select><td>
+#errors
+(1,42): unexpected-table-element-start-tag-in-select-in-table
+(1,42): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <th>
+| <select>
+| <td>
+
+#data
+<!doctype html><table><caption><select><tr>
+#errors
+(1,43): unexpected-table-element-start-tag-in-select-in-table
+(1,43): XXX-undefined-error
+(1,43): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+| <select>
+| <tbody>
+| <tr>
+
+#data
+<!doctype html><select><tr>
+#errors
+(1,27): unexpected-start-tag-in-select
+(1,27): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+
+#data
+<!doctype html><select><td>
+#errors
+(1,27): unexpected-start-tag-in-select
+(1,27): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+
+#data
+<!doctype html><select><th>
+#errors
+(1,27): unexpected-start-tag-in-select
+(1,27): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+
+#data
+<!doctype html><select><tbody>
+#errors
+(1,30): unexpected-start-tag-in-select
+(1,30): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+
+#data
+<!doctype html><select><thead>
+#errors
+(1,30): unexpected-start-tag-in-select
+(1,30): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+
+#data
+<!doctype html><select><tfoot>
+#errors
+(1,30): unexpected-start-tag-in-select
+(1,30): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+
+#data
+<!doctype html><select><caption>
+#errors
+(1,32): unexpected-start-tag-in-select
+(1,32): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+
+#data
+<!doctype html><table><tr></table>a
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| "a"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests18.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests18.dat
new file mode 100644
index 000000000..926bccb38
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests18.dat
@@ -0,0 +1,322 @@
+#data
+<!doctype html><plaintext></plaintext>
+#errors
+(1,38): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <plaintext>
+| "</plaintext>"
+
+#data
+<!doctype html><table><plaintext></plaintext>
+#errors
+(1,33): foster-parenting-start-tag
+(1,34): foster-parenting-character
+(1,35): foster-parenting-character
+(1,36): foster-parenting-character
+(1,37): foster-parenting-character
+(1,38): foster-parenting-character
+(1,39): foster-parenting-character
+(1,40): foster-parenting-character
+(1,41): foster-parenting-character
+(1,42): foster-parenting-character
+(1,43): foster-parenting-character
+(1,44): foster-parenting-character
+(1,45): foster-parenting-character
+(1,45): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <plaintext>
+| "</plaintext>"
+| <table>
+
+#data
+<!doctype html><table><tbody><plaintext></plaintext>
+#errors
+(1,40): foster-parenting-start-tag
+(1,41): foster-parenting-character
+(1,41): foster-parenting-character
+(1,41): foster-parenting-character
+(1,41): foster-parenting-character
+(1,41): foster-parenting-character
+(1,41): foster-parenting-character
+(1,41): foster-parenting-character
+(1,41): foster-parenting-character
+(1,41): foster-parenting-character
+(1,41): foster-parenting-character
+(1,41): foster-parenting-character
+(1,41): foster-parenting-character
+(1,52): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <plaintext>
+| "</plaintext>"
+| <table>
+| <tbody>
+
+#data
+<!doctype html><table><tbody><tr><plaintext></plaintext>
+#errors
+(1,44): foster-parenting-start-tag
+(1,45): foster-parenting-character
+(1,46): foster-parenting-character
+(1,47): foster-parenting-character
+(1,48): foster-parenting-character
+(1,49): foster-parenting-character
+(1,50): foster-parenting-character
+(1,51): foster-parenting-character
+(1,52): foster-parenting-character
+(1,53): foster-parenting-character
+(1,54): foster-parenting-character
+(1,55): foster-parenting-character
+(1,56): foster-parenting-character
+(1,56): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <plaintext>
+| "</plaintext>"
+| <table>
+| <tbody>
+| <tr>
+
+#data
+<!doctype html><table><td><plaintext></plaintext>
+#errors
+(1,26): unexpected-cell-in-table-body
+(1,49): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <plaintext>
+| "</plaintext>"
+
+#data
+<!doctype html><table><caption><plaintext></plaintext>
+#errors
+(1,54): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+| <plaintext>
+| "</plaintext>"
+
+#data
+<!doctype html><table><tr><style></script></style>abc
+#errors
+(1,51): foster-parenting-character
+(1,52): foster-parenting-character
+(1,53): foster-parenting-character
+(1,53): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "abc"
+| <table>
+| <tbody>
+| <tr>
+| <style>
+| "</script>"
+
+#data
+<!doctype html><table><tr><script></style></script>abc
+#errors
+(1,52): foster-parenting-character
+(1,53): foster-parenting-character
+(1,54): foster-parenting-character
+(1,54): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "abc"
+| <table>
+| <tbody>
+| <tr>
+| <script>
+| "</style>"
+
+#data
+<!doctype html><table><caption><style></script></style>abc
+#errors
+(1,58): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+| <style>
+| "</script>"
+| "abc"
+
+#data
+<!doctype html><table><td><style></script></style>abc
+#errors
+(1,26): unexpected-cell-in-table-body
+(1,53): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <style>
+| "</script>"
+| "abc"
+
+#data
+<!doctype html><select><script></style></script>abc
+#errors
+(1,51): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| <script>
+| "</style>"
+| "abc"
+
+#data
+<!doctype html><table><select><script></style></script>abc
+#errors
+(1,30): unexpected-start-tag-implies-table-voodoo
+(1,58): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| <script>
+| "</style>"
+| "abc"
+| <table>
+
+#data
+<!doctype html><table><tr><select><script></style></script>abc
+#errors
+(1,34): unexpected-start-tag-implies-table-voodoo
+(1,62): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| <script>
+| "</style>"
+| "abc"
+| <table>
+| <tbody>
+| <tr>
+
+#data
+<!doctype html><frameset></frameset><noframes>abc
+#errors
+(1,49): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+| <noframes>
+| "abc"
+
+#data
+<!doctype html><frameset></frameset><noframes>abc</noframes><!--abc-->
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+| <noframes>
+| "abc"
+| <!-- abc -->
+
+#data
+<!doctype html><frameset></frameset></html><noframes>abc
+#errors
+(1,56): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+| <noframes>
+| "abc"
+
+#data
+<!doctype html><frameset></frameset></html><noframes>abc</noframes><!--abc-->
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+| <noframes>
+| "abc"
+| <!-- abc -->
+
+#data
+<!doctype html><table><tr></tbody><tfoot>
+#errors
+(1,41): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <tfoot>
+
+#data
+<!doctype html><table><td><svg></svg>abc<td>
+#errors
+(1,26): unexpected-cell-in-table-body
+(1,44): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <svg svg>
+| "abc"
+| <td>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests19.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests19.dat
new file mode 100644
index 000000000..cd1be6ed8
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests19.dat
@@ -0,0 +1,1523 @@
+#data
+<!doctype html><math><mn DefinitionUrl="foo">
+#errors
+(1,45): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mn>
+| definitionURL="foo"
+
+#data
+<!doctype html><html></p><!--foo-->
+#errors
+(1,25): end-tag-after-implied-root
+#document
+| <!DOCTYPE html>
+| <html>
+| <!-- foo -->
+| <head>
+| <body>
+
+#data
+<!doctype html><head></head></p><!--foo-->
+#errors
+(1,32): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <!-- foo -->
+| <body>
+
+#data
+<!doctype html><body><p><pre>
+#errors
+(1,29): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <pre>
+
+#data
+<!doctype html><body><p><listing>
+#errors
+(1,33): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <listing>
+
+#data
+<!doctype html><p><plaintext>
+#errors
+(1,29): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <plaintext>
+
+#data
+<!doctype html><p><h1>
+#errors
+(1,22): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <h1>
+
+#data
+<!doctype html><form><isindex>
+#errors
+(1,30): deprecated-tag
+(1,30): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <form>
+
+#data
+<!doctype html><isindex action="POST">
+#errors
+(1,38): deprecated-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <form>
+| action="POST"
+| <hr>
+| <label>
+| "This is a searchable index. Enter search keywords: "
+| <input>
+| name="isindex"
+| <hr>
+
+#data
+<!doctype html><isindex prompt="this is isindex">
+#errors
+(1,49): deprecated-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <form>
+| <hr>
+| <label>
+| "this is isindex"
+| <input>
+| name="isindex"
+| <hr>
+
+#data
+<!doctype html><isindex type="hidden">
+#errors
+(1,38): deprecated-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <form>
+| <hr>
+| <label>
+| "This is a searchable index. Enter search keywords: "
+| <input>
+| name="isindex"
+| type="hidden"
+| <hr>
+
+#data
+<!doctype html><isindex name="foo">
+#errors
+(1,35): deprecated-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <form>
+| <hr>
+| <label>
+| "This is a searchable index. Enter search keywords: "
+| <input>
+| name="isindex"
+| <hr>
+
+#data
+<!doctype html><ruby><p><rp>
+#errors
+(1,28): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <ruby>
+| <p>
+| <rp>
+
+#data
+<!doctype html><ruby><div><span><rp>
+#errors
+(1,36): XXX-undefined-error
+(1,36): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <ruby>
+| <div>
+| <span>
+| <rp>
+
+#data
+<!doctype html><ruby><div><p><rp>
+#errors
+(1,33): XXX-undefined-error
+(1,33): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <ruby>
+| <div>
+| <p>
+| <rp>
+
+#data
+<!doctype html><ruby><p><rt>
+#errors
+(1,28): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <ruby>
+| <p>
+| <rt>
+
+#data
+<!doctype html><ruby><div><span><rt>
+#errors
+(1,36): XXX-undefined-error
+(1,36): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <ruby>
+| <div>
+| <span>
+| <rt>
+
+#data
+<!doctype html><ruby><div><p><rt>
+#errors
+(1,33): XXX-undefined-error
+(1,33): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <ruby>
+| <div>
+| <p>
+| <rt>
+
+#data
+<html><ruby>a<rb>b<rt></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rb>
+| "b"
+| <rt>
+
+#data
+<html><ruby>a<rp>b<rt></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rp>
+| "b"
+| <rt>
+
+#data
+<html><ruby>a<rt>b<rt></ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rt>
+| "b"
+| <rt>
+
+#data
+<html><ruby>a<rtc>b<rt>c<rb>d</ruby></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| "a"
+| <rtc>
+| "b"
+| <rt>
+| "c"
+| <rb>
+| "d"
+
+#data
+<!doctype html><math/><foo>
+#errors
+(1,27): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+| <foo>
+
+#data
+<!doctype html><svg/><foo>
+#errors
+(1,26): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <foo>
+
+#data
+<!doctype html><div></body><!--foo-->
+#errors
+(1,27): expected-one-end-tag-but-got-another
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <div>
+| <!-- foo -->
+
+#data
+<!doctype html><h1><div><h3><span></h1>foo
+#errors
+(1,39): end-tag-too-early
+(1,42): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <h1>
+| <div>
+| <h3>
+| <span>
+| "foo"
+
+#data
+<!doctype html><p></h3>foo
+#errors
+(1,23): end-tag-too-early
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| "foo"
+
+#data
+<!doctype html><h3><li>abc</h2>foo
+#errors
+(1,31): end-tag-too-early
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <h3>
+| <li>
+| "abc"
+| "foo"
+
+#data
+<!doctype html><table>abc<!--foo-->
+#errors
+(1,23): foster-parenting-character
+(1,24): foster-parenting-character
+(1,25): foster-parenting-character
+(1,35): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "abc"
+| <table>
+| <!-- foo -->
+
+#data
+<!doctype html><table> <!--foo-->
+#errors
+(1,34): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| " "
+| <!-- foo -->
+
+#data
+<!doctype html><table> b <!--foo-->
+#errors
+(1,23): foster-parenting-character
+(1,24): foster-parenting-character
+(1,25): foster-parenting-character
+(1,35): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| " b "
+| <table>
+| <!-- foo -->
+
+#data
+<!doctype html><select><option><option>
+#errors
+(1,39): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| <option>
+| <option>
+
+#data
+<!doctype html><select><option></optgroup>
+#errors
+(1,42): unexpected-end-tag-in-select
+(1,42): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| <option>
+
+#data
+<!doctype html><select><option></optgroup>
+#errors
+(1,42): unexpected-end-tag-in-select
+(1,42): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| <option>
+
+#data
+<!doctype html><dd><optgroup><dd>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <dd>
+| <optgroup>
+| <dd>
+
+#data
+<!doctype html><p><math><mi><p><h1>
+#errors
+(1,35): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <math math>
+| <math mi>
+| <p>
+| <h1>
+
+#data
+<!doctype html><p><math><mo><p><h1>
+#errors
+(1,35): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <math math>
+| <math mo>
+| <p>
+| <h1>
+
+#data
+<!doctype html><p><math><mn><p><h1>
+#errors
+(1,35): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <math math>
+| <math mn>
+| <p>
+| <h1>
+
+#data
+<!doctype html><p><math><ms><p><h1>
+#errors
+(1,35): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <math math>
+| <math ms>
+| <p>
+| <h1>
+
+#data
+<!doctype html><p><math><mtext><p><h1>
+#errors
+(1,38): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <math math>
+| <math mtext>
+| <p>
+| <h1>
+
+#data
+<!doctype html><frameset></noframes>
+#errors
+(1,36): unexpected-end-tag-in-frameset
+(1,36): eof-in-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+
+#data
+<!doctype html><html c=d><body></html><html a=b>
+#errors
+(1,48): non-html-root
+#document
+| <!DOCTYPE html>
+| <html>
+| a="b"
+| c="d"
+| <head>
+| <body>
+
+#data
+<!doctype html><html c=d><frameset></frameset></html><html a=b>
+#errors
+(1,63): non-html-root
+#document
+| <!DOCTYPE html>
+| <html>
+| a="b"
+| c="d"
+| <head>
+| <frameset>
+
+#data
+<!doctype html><html><frameset></frameset></html><!--foo-->
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+| <!-- foo -->
+
+#data
+<!doctype html><html><frameset></frameset></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+| " "
+
+#data
+<!doctype html><html><frameset></frameset></html>abc
+#errors
+(1,50): expected-eof-but-got-char
+(1,51): expected-eof-but-got-char
+(1,52): expected-eof-but-got-char
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+
+#data
+<!doctype html><html><frameset></frameset></html><p>
+#errors
+(1,52): expected-eof-but-got-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+
+#data
+<!doctype html><html><frameset></frameset></html></p>
+#errors
+(1,53): expected-eof-but-got-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+
+#data
+<html><frameset></frameset></html><!doctype html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,49): unexpected-doctype
+#document
+| <html>
+| <head>
+| <frameset>
+
+#data
+<!doctype html><body><frameset>
+#errors
+(1,31): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+
+#data
+<!doctype html><p><frameset><frame>
+#errors
+(1,28): unexpected-start-tag
+(1,35): eof-in-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+| <frame>
+
+#data
+<!doctype html><p>a<frameset>
+#errors
+(1,29): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| "a"
+
+#data
+<!doctype html><p> <frameset><frame>
+#errors
+(1,29): unexpected-start-tag
+(1,36): eof-in-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+| <frame>
+
+#data
+<!doctype html><pre><frameset>
+#errors
+(1,30): unexpected-start-tag
+(1,30): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <pre>
+
+#data
+<!doctype html><listing><frameset>
+#errors
+(1,34): unexpected-start-tag
+(1,34): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <listing>
+
+#data
+<!doctype html><li><frameset>
+#errors
+(1,29): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <li>
+
+#data
+<!doctype html><dd><frameset>
+#errors
+(1,29): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <dd>
+
+#data
+<!doctype html><dt><frameset>
+#errors
+(1,29): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <dt>
+
+#data
+<!doctype html><button><frameset>
+#errors
+(1,33): unexpected-start-tag
+(1,33): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <button>
+
+#data
+<!doctype html><applet><frameset>
+#errors
+(1,33): unexpected-start-tag
+(1,33): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <applet>
+
+#data
+<!doctype html><marquee><frameset>
+#errors
+(1,34): unexpected-start-tag
+(1,34): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <marquee>
+
+#data
+<!doctype html><object><frameset>
+#errors
+(1,33): unexpected-start-tag
+(1,33): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <object>
+
+#data
+<!doctype html><table><frameset>
+#errors
+(1,32): unexpected-start-tag-implies-table-voodoo
+(1,32): unexpected-start-tag
+(1,32): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+
+#data
+<!doctype html><area><frameset>
+#errors
+(1,31): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <area>
+
+#data
+<!doctype html><basefont><frameset>
+#errors
+(1,35): eof-in-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <basefont>
+| <frameset>
+
+#data
+<!doctype html><bgsound><frameset>
+#errors
+(1,34): eof-in-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <bgsound>
+| <frameset>
+
+#data
+<!doctype html><br><frameset>
+#errors
+(1,29): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <br>
+
+#data
+<!doctype html><embed><frameset>
+#errors
+(1,32): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <embed>
+
+#data
+<!doctype html><img><frameset>
+#errors
+(1,30): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <img>
+
+#data
+<!doctype html><input><frameset>
+#errors
+(1,32): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <input>
+
+#data
+<!doctype html><keygen><frameset>
+#errors
+(1,33): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <keygen>
+
+#data
+<!doctype html><wbr><frameset>
+#errors
+(1,30): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <wbr>
+
+#data
+<!doctype html><hr><frameset>
+#errors
+(1,29): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <hr>
+
+#data
+<!doctype html><textarea></textarea><frameset>
+#errors
+(1,46): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <textarea>
+
+#data
+<!doctype html><xmp></xmp><frameset>
+#errors
+(1,36): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <xmp>
+
+#data
+<!doctype html><iframe></iframe><frameset>
+#errors
+(1,42): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <iframe>
+
+#data
+<!doctype html><select></select><frameset>
+#errors
+(1,42): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+
+#data
+<!doctype html><svg></svg><frameset><frame>
+#errors
+(1,36): unexpected-start-tag
+(1,43): eof-in-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+| <frame>
+
+#data
+<!doctype html><math></math><frameset><frame>
+#errors
+(1,38): unexpected-start-tag
+(1,45): eof-in-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+| <frame>
+
+#data
+<!doctype html><svg><foreignObject><div> <frameset><frame>
+#errors
+(1,51): unexpected-start-tag
+(1,58): eof-in-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+| <frame>
+
+#data
+<!doctype html><svg>a</svg><frameset><frame>
+#errors
+(1,37): unexpected-start-tag
+(1,44): unexpected-start-tag-ignored
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "a"
+
+#data
+<!doctype html><svg> </svg><frameset><frame>
+#errors
+(1,37): unexpected-start-tag
+(1,44): eof-in-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+| <frame>
+
+#data
+<html>aaa<frameset></frameset>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,19): unexpected-start-tag
+(1,30): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| "aaa"
+
+#data
+<html> a <frameset></frameset>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,19): unexpected-start-tag
+(1,30): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| "a "
+
+#data
+<!doctype html><div><frameset>
+#errors
+(1,30): unexpected-start-tag
+(1,30): eof-in-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+
+#data
+<!doctype html><div><body><frameset>
+#errors
+(1,26): unexpected-start-tag
+(1,36): unexpected-start-tag
+(1,36): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <div>
+
+#data
+<!doctype html><p><math></p>a
+#errors
+(1,28): unexpected-end-tag
+(1,28): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <math math>
+| "a"
+
+#data
+<!doctype html><p><math><mn><span></p>a
+#errors
+(1,38): unexpected-end-tag
+(1,39): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <math math>
+| <math mn>
+| <span>
+| <p>
+| "a"
+
+#data
+<!doctype html><math></html>
+#errors
+(1,28): unexpected-end-tag
+(1,28): expected-one-end-tag-but-got-another
+(1,28): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+
+#data
+<!doctype html><meta charset="ascii">
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <meta>
+| charset="ascii"
+| <body>
+
+#data
+<!doctype html><meta http-equiv="content-type" content="text/html;charset=ascii">
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <meta>
+| content="text/html;charset=ascii"
+| http-equiv="content-type"
+| <body>
+
+#data
+<!doctype html><head><!--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa--><meta charset="utf8">
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <!-- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -->
+| <meta>
+| charset="utf8"
+| <body>
+
+#data
+<!doctype html><html a=b><head></head><html c=d>
+#errors
+(1,48): non-html-root
+#document
+| <!DOCTYPE html>
+| <html>
+| a="b"
+| c="d"
+| <head>
+| <body>
+
+#data
+<!doctype html><image/>
+#errors
+(1,23): image-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <img>
+
+#data
+<!doctype html>a<i>b<table>c<b>d</i>e</b>f
+#errors
+(1,28): foster-parenting-character
+(1,31): foster-parenting-start-tag
+(1,32): foster-parenting-character
+(1,36): foster-parenting-end-tag
+(1,36): adoption-agency-1.3
+(1,37): foster-parenting-character
+(1,41): foster-parenting-end-tag
+(1,42): foster-parenting-character
+(1,42): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "a"
+| <i>
+| "bc"
+| <b>
+| "de"
+| "f"
+| <table>
+
+#data
+<!doctype html><table><i>a<b>b<div>c<a>d</i>e</b>f
+#errors
+(1,25): foster-parenting-start-tag
+(1,26): foster-parenting-character
+(1,29): foster-parenting-start-tag
+(1,30): foster-parenting-character
+(1,35): foster-parenting-start-tag
+(1,36): foster-parenting-character
+(1,39): foster-parenting-start-tag
+(1,40): foster-parenting-character
+(1,44): foster-parenting-end-tag
+(1,44): adoption-agency-1.3
+(1,44): adoption-agency-1.3
+(1,45): foster-parenting-character
+(1,49): foster-parenting-end-tag
+(1,49): adoption-agency-1.3
+(1,49): adoption-agency-1.3
+(1,50): foster-parenting-character
+(1,50): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <i>
+| "a"
+| <b>
+| "b"
+| <b>
+| <div>
+| <b>
+| <i>
+| "c"
+| <a>
+| "d"
+| <a>
+| "e"
+| <a>
+| "f"
+| <table>
+
+#data
+<!doctype html><i>a<b>b<div>c<a>d</i>e</b>f
+#errors
+(1,37): adoption-agency-1.3
+(1,37): adoption-agency-1.3
+(1,42): adoption-agency-1.3
+(1,42): adoption-agency-1.3
+(1,43): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <i>
+| "a"
+| <b>
+| "b"
+| <b>
+| <div>
+| <b>
+| <i>
+| "c"
+| <a>
+| "d"
+| <a>
+| "e"
+| <a>
+| "f"
+
+#data
+<!doctype html><table><i>a<b>b<div>c</i>
+#errors
+(1,25): foster-parenting-start-tag
+(1,26): foster-parenting-character
+(1,29): foster-parenting-start-tag
+(1,30): foster-parenting-character
+(1,35): foster-parenting-start-tag
+(1,36): foster-parenting-character
+(1,40): foster-parenting-end-tag
+(1,40): adoption-agency-1.3
+(1,40): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <i>
+| "a"
+| <b>
+| "b"
+| <b>
+| <div>
+| <i>
+| "c"
+| <table>
+
+#data
+<!doctype html><table><i>a<b>b<div>c<a>d</i>e</b>f
+#errors
+(1,25): foster-parenting-start-tag
+(1,26): foster-parenting-character
+(1,29): foster-parenting-start-tag
+(1,30): foster-parenting-character
+(1,35): foster-parenting-start-tag
+(1,36): foster-parenting-character
+(1,39): foster-parenting-start-tag
+(1,40): foster-parenting-character
+(1,44): foster-parenting-end-tag
+(1,44): adoption-agency-1.3
+(1,44): adoption-agency-1.3
+(1,45): foster-parenting-character
+(1,49): foster-parenting-end-tag
+(1,44): adoption-agency-1.3
+(1,44): adoption-agency-1.3
+(1,50): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <i>
+| "a"
+| <b>
+| "b"
+| <b>
+| <div>
+| <b>
+| <i>
+| "c"
+| <a>
+| "d"
+| <a>
+| "e"
+| <a>
+| "f"
+| <table>
+
+#data
+<!doctype html><table><i>a<div>b<tr>c<b>d</i>e
+#errors
+(1,25): foster-parenting-start-tag
+(1,26): foster-parenting-character
+(1,31): foster-parenting-start-tag
+(1,32): foster-parenting-character
+(1,37): foster-parenting-character
+(1,40): foster-parenting-start-tag
+(1,41): foster-parenting-character
+(1,45): foster-parenting-end-tag
+(1,45): adoption-agency-1.3
+(1,46): foster-parenting-character
+(1,46): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <i>
+| "a"
+| <div>
+| "b"
+| <i>
+| "c"
+| <b>
+| "d"
+| <b>
+| "e"
+| <table>
+| <tbody>
+| <tr>
+
+#data
+<!doctype html><table><td><table><i>a<div>b<b>c</i>d
+#errors
+(1,26): unexpected-cell-in-table-body
+(1,36): foster-parenting-start-tag
+(1,37): foster-parenting-character
+(1,42): foster-parenting-start-tag
+(1,43): foster-parenting-character
+(1,46): foster-parenting-start-tag
+(1,47): foster-parenting-character
+(1,51): foster-parenting-end-tag
+(1,51): adoption-agency-1.3
+(1,51): adoption-agency-1.3
+(1,52): foster-parenting-character
+(1,52): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <i>
+| "a"
+| <div>
+| <i>
+| "b"
+| <b>
+| "c"
+| <b>
+| "d"
+| <table>
+
+#data
+<!doctype html><body><bgsound>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <bgsound>
+
+#data
+<!doctype html><body><basefont>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <basefont>
+
+#data
+<!doctype html><a><b></a><basefont>
+#errors
+(1,25): adoption-agency-1.3
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <a>
+| <b>
+| <basefont>
+
+#data
+<!doctype html><a><b></a><bgsound>
+#errors
+(1,25): adoption-agency-1.3
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <a>
+| <b>
+| <bgsound>
+
+#data
+<!doctype html><figcaption><article></figcaption>a
+#errors
+(1,49): end-tag-too-early
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <figcaption>
+| <article>
+| "a"
+
+#data
+<!doctype html><summary><article></summary>a
+#errors
+(1,43): end-tag-too-early
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <summary>
+| <article>
+| "a"
+
+#data
+<!doctype html><p><a><plaintext>b
+#errors
+(1,32): unexpected-end-tag
+(1,33): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <a>
+| <plaintext>
+| <a>
+| "b"
+
+#data
+<!DOCTYPE html><div>a<a></div>b<p>c</p>d
+#errors
+(1,30): end-tag-too-early
+(1,40): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <div>
+| "a"
+| <a>
+| <a>
+| "b"
+| <p>
+| "c"
+| "d"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests2.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests2.dat
new file mode 100644
index 000000000..0ad77086b
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests2.dat
@@ -0,0 +1,770 @@
+#data
+<!DOCTYPE html>Test
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "Test"
+
+#data
+<textarea>test</div>test
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(1,24): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <textarea>
+| "test</div>test"
+
+#data
+<table><td>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,11): unexpected-cell-in-table-body
+(1,11): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+
+#data
+<table><td>test</tbody></table>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,11): unexpected-cell-in-table-body
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| "test"
+
+#data
+<frame>test
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,7): unexpected-start-tag-ignored
+#document
+| <html>
+| <head>
+| <body>
+| "test"
+
+#data
+<!DOCTYPE html><frameset>test
+#errors
+(1,29): unexpected-char-in-frameset
+(1,29): unexpected-char-in-frameset
+(1,29): unexpected-char-in-frameset
+(1,29): unexpected-char-in-frameset
+(1,29): eof-in-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+
+#data
+<!DOCTYPE html><frameset><!DOCTYPE html>
+#errors
+(1,40): unexpected-doctype
+(1,40): eof-in-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+
+#data
+<!DOCTYPE html><font><p><b>test</font>
+#errors
+(1,38): adoption-agency-1.3
+(1,38): adoption-agency-1.3
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <font>
+| <p>
+| <font>
+| <b>
+| "test"
+
+#data
+<!DOCTYPE html><dt><div><dd>
+#errors
+(1,28): end-tag-too-early
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <dt>
+| <div>
+| <dd>
+
+#data
+<script></x
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,11): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <script>
+| "</x"
+| <body>
+
+#data
+<table><plaintext><td>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,18): unexpected-start-tag-implies-table-voodoo
+(1,22): foster-parenting-character-in-table
+(1,22): foster-parenting-character-in-table
+(1,22): foster-parenting-character-in-table
+(1,22): foster-parenting-character-in-table
+(1,22): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <plaintext>
+| "<td>"
+| <table>
+
+#data
+<plaintext></plaintext>
+#errors
+(1,11): expected-doctype-but-got-start-tag
+(1,23): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <plaintext>
+| "</plaintext>"
+
+#data
+<!DOCTYPE html><table><tr>TEST
+#errors
+(1,30): foster-parenting-character-in-table
+(1,30): foster-parenting-character-in-table
+(1,30): foster-parenting-character-in-table
+(1,30): foster-parenting-character-in-table
+(1,30): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "TEST"
+| <table>
+| <tbody>
+| <tr>
+
+#data
+<!DOCTYPE html><body t1=1><body t2=2><body t3=3 t4=4>
+#errors
+(1,37): unexpected-start-tag
+(1,53): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| t1="1"
+| t2="2"
+| t3="3"
+| t4="4"
+
+#data
+</b test
+#errors
+(1,8): eof-in-attribute-name
+(1,8): expected-doctype-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<!DOCTYPE html></b test<b &=&amp>X
+#errors
+(1,24): invalid-character-in-attribute-name
+(1,32): named-entity-without-semicolon
+(1,33): attributes-in-end-tag
+(1,33): unexpected-end-tag-before-html
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "X"
+
+#data
+<!doctypehtml><scrIPt type=text/x-foobar;baz>X</SCRipt
+#errors
+(1,9): need-space-after-doctype
+(1,54): expected-named-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| type="text/x-foobar;baz"
+| "X</SCRipt"
+| <body>
+
+#data
+&
+#errors
+(1,1): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "&"
+
+#data
+&#
+#errors
+(1,2): expected-numeric-entity
+(1,2): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "&#"
+
+#data
+&#X
+#errors
+(1,3): expected-numeric-entity
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "&#X"
+
+#data
+&#x
+#errors
+(1,3): expected-numeric-entity
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "&#x"
+
+#data
+&#45
+#errors
+(1,4): numeric-entity-without-semicolon
+(1,4): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "-"
+
+#data
+&x-test
+#errors
+(1,2): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "&x-test"
+
+#data
+<!doctypehtml><p><li>
+#errors
+(1,9): need-space-after-doctype
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <li>
+
+#data
+<!doctypehtml><p><dt>
+#errors
+(1,9): need-space-after-doctype
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <dt>
+
+#data
+<!doctypehtml><p><dd>
+#errors
+(1,9): need-space-after-doctype
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <dd>
+
+#data
+<!doctypehtml><p><form>
+#errors
+(1,9): need-space-after-doctype
+(1,23): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <form>
+
+#data
+<!DOCTYPE html><p></P>X
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| "X"
+
+#data
+&AMP
+#errors
+(1,4): named-entity-without-semicolon
+(1,4): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "&"
+
+#data
+&AMp;
+#errors
+(1,3): expected-named-entity
+(1,3): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "&AMp;"
+
+#data
+<!DOCTYPE html><html><head></head><body><thisISasillyTESTelementNameToMakeSureCrazyTagNamesArePARSEDcorrectLY>
+#errors
+(1,110): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <thisisasillytestelementnametomakesurecrazytagnamesareparsedcorrectly>
+
+#data
+<!DOCTYPE html>X</body>X
+#errors
+(1,24): unexpected-char-after-body
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "XX"
+
+#data
+<!DOCTYPE html><!-- X
+#errors
+(1,21): eof-in-comment
+#document
+| <!DOCTYPE html>
+| <!-- X -->
+| <html>
+| <head>
+| <body>
+
+#data
+<!DOCTYPE html><table><caption>test TEST</caption><td>test
+#errors
+(1,54): unexpected-cell-in-table-body
+(1,58): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+| "test TEST"
+| <tbody>
+| <tr>
+| <td>
+| "test"
+
+#data
+<!DOCTYPE html><select><option><optgroup>
+#errors
+(1,41): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| <option>
+| <optgroup>
+
+#data
+<!DOCTYPE html><select><optgroup><option></optgroup><option><select><option>
+#errors
+(1,68): unexpected-select-in-select
+(1,76): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| <optgroup>
+| <option>
+| <option>
+| <option>
+
+#data
+<!DOCTYPE html><select><optgroup><option><optgroup>
+#errors
+(1,51): eof-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| <optgroup>
+| <option>
+| <optgroup>
+
+#data
+<!DOCTYPE html><datalist><option>foo</datalist>bar
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <datalist>
+| <option>
+| "foo"
+| "bar"
+
+#data
+<!DOCTYPE html><font><input><input></font>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <font>
+| <input>
+| <input>
+
+#data
+<!DOCTYPE html><!-- XXX - XXX -->
+#errors
+#document
+| <!DOCTYPE html>
+| <!-- XXX - XXX -->
+| <html>
+| <head>
+| <body>
+
+#data
+<!DOCTYPE html><!-- XXX - XXX
+#errors
+(1,29): eof-in-comment
+#document
+| <!DOCTYPE html>
+| <!-- XXX - XXX -->
+| <html>
+| <head>
+| <body>
+
+#data
+<!DOCTYPE html><!-- XXX - XXX - XXX -->
+#errors
+#document
+| <!DOCTYPE html>
+| <!-- XXX - XXX - XXX -->
+| <html>
+| <head>
+| <body>
+
+#data
+<isindex test=x name=x>
+#errors
+(1,23): expected-doctype-but-got-start-tag
+(1,23): deprecated-tag
+#document
+| <html>
+| <head>
+| <body>
+| <form>
+| <hr>
+| <label>
+| "This is a searchable index. Enter search keywords: "
+| <input>
+| name="isindex"
+| test="x"
+| <hr>
+
+#data
+test
+test
+#errors
+(2,4): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "test
+test"
+
+#data
+<!DOCTYPE html><body><title>test</body></title>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <title>
+| "test</body>"
+
+#data
+<!DOCTYPE html><body><title>X</title><meta name=z><link rel=foo><style>
+x { content:"</style" } </style>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <title>
+| "X"
+| <meta>
+| name="z"
+| <link>
+| rel="foo"
+| <style>
+| "
+x { content:"</style" } "
+
+#data
+<!DOCTYPE html><select><optgroup></optgroup></select>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| <optgroup>
+
+#data
+
+
+#errors
+(2,1): expected-doctype-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<!DOCTYPE html> <html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+
+#data
+<!DOCTYPE html><script>
+</script> <title>x</title> </head>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <script>
+| "
+"
+| " "
+| <title>
+| "x"
+| " "
+| <body>
+
+#data
+<!DOCTYPE html><html><body><html id=x>
+#errors
+(1,38): non-html-root
+#document
+| <!DOCTYPE html>
+| <html>
+| id="x"
+| <head>
+| <body>
+
+#data
+<!DOCTYPE html>X</body><html id="x">
+#errors
+(1,36): non-html-root
+#document
+| <!DOCTYPE html>
+| <html>
+| id="x"
+| <head>
+| <body>
+| "X"
+
+#data
+<!DOCTYPE html><head><html id=x>
+#errors
+(1,32): non-html-root
+#document
+| <!DOCTYPE html>
+| <html>
+| id="x"
+| <head>
+| <body>
+
+#data
+<!DOCTYPE html>X</html>X
+#errors
+(1,24): expected-eof-but-got-char
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "XX"
+
+#data
+<!DOCTYPE html>X</html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "X "
+
+#data
+<!DOCTYPE html>X</html><p>X
+#errors
+(1,26): expected-eof-but-got-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "X"
+| <p>
+| "X"
+
+#data
+<!DOCTYPE html>X<p/x/y/z>
+#errors
+(1,19): unexpected-character-after-solidus-in-tag
+(1,21): unexpected-character-after-solidus-in-tag
+(1,23): unexpected-character-after-solidus-in-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "X"
+| <p>
+| x=""
+| y=""
+| z=""
+
+#data
+<!DOCTYPE html><!--x--
+#errors
+(1,22): eof-in-comment-double-dash
+#document
+| <!DOCTYPE html>
+| <!-- x -->
+| <html>
+| <head>
+| <body>
+
+#data
+<!DOCTYPE html><table><tr><td></p></table>
+#errors
+(1,34): unexpected-end-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <p>
+
+#data
+<!DOCTYPE <!DOCTYPE HTML>><!--<!--x-->-->
+#errors
+(1,20): expected-space-or-right-bracket-in-doctype
+(1,25): unknown-doctype
+(1,35): unexpected-char-in-comment
+#document
+| <!DOCTYPE <!doctype>
+| <html>
+| <head>
+| <body>
+| ">"
+| <!-- <!--x -->
+| "-->"
+
+#data
+<!doctype html><div><form></form><div></div></div>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <div>
+| <form>
+| <div>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests20.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests20.dat
new file mode 100644
index 000000000..52c5acdc6
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests20.dat
@@ -0,0 +1,516 @@
+#data
+<!doctype html><p><button><button>
+#errors
+(1,34): unexpected-start-tag-implies-end-tag
+(1,34): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <button>
+
+#data
+<!doctype html><p><button><address>
+#errors
+(1,35): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <address>
+
+#data
+<!doctype html><p><button><blockquote>
+#errors
+(1,38): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <blockquote>
+
+#data
+<!doctype html><p><button><menu>
+#errors
+(1,32): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <menu>
+
+#data
+<!doctype html><p><button><p>
+#errors
+(1,29): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <p>
+
+#data
+<!doctype html><p><button><ul>
+#errors
+(1,30): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <ul>
+
+#data
+<!doctype html><p><button><h1>
+#errors
+(1,30): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <h1>
+
+#data
+<!doctype html><p><button><h6>
+#errors
+(1,30): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <h6>
+
+#data
+<!doctype html><p><button><listing>
+#errors
+(1,35): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <listing>
+
+#data
+<!doctype html><p><button><pre>
+#errors
+(1,31): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <pre>
+
+#data
+<!doctype html><p><button><form>
+#errors
+(1,32): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <form>
+
+#data
+<!doctype html><p><button><li>
+#errors
+(1,30): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <li>
+
+#data
+<!doctype html><p><button><dd>
+#errors
+(1,30): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <dd>
+
+#data
+<!doctype html><p><button><dt>
+#errors
+(1,30): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <dt>
+
+#data
+<!doctype html><p><button><plaintext>
+#errors
+(1,37): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <plaintext>
+
+#data
+<!doctype html><p><button><table>
+#errors
+(1,33): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <table>
+
+#data
+<!doctype html><p><button><hr>
+#errors
+(1,30): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <hr>
+
+#data
+<!doctype html><p><button><xmp>
+#errors
+(1,31): expected-named-closing-tag-but-got-eof
+(1,31): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <xmp>
+
+#data
+<!doctype html><p><button></p>
+#errors
+(1,30): unexpected-end-tag
+(1,30): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <button>
+| <p>
+
+#data
+<!doctype html><address><button></address>a
+#errors
+(1,42): end-tag-too-early
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <address>
+| <button>
+| "a"
+
+#data
+<!doctype html><address><button></address>a
+#errors
+(1,42): end-tag-too-early
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <address>
+| <button>
+| "a"
+
+#data
+<p><table></p>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,14): unexpected-end-tag-implies-table-voodoo
+(1,14): unexpected-end-tag
+(1,14): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <p>
+| <table>
+
+#data
+<!doctype html><svg>
+#errors
+(1,20): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+
+#data
+<!doctype html><p><figcaption>
+#errors
+(1,30): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <figcaption>
+
+#data
+<!doctype html><p><summary>
+#errors
+(1,27): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <summary>
+
+#data
+<!doctype html><form><table><form>
+#errors
+(1,34): unexpected-form-in-table
+(1,34): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <form>
+| <table>
+
+#data
+<!doctype html><table><form><form>
+#errors
+(1,28): unexpected-form-in-table
+(1,34): unexpected-form-in-table
+(1,34): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <form>
+
+#data
+<!doctype html><table><form></table><form>
+#errors
+(1,28): unexpected-form-in-table
+(1,42): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <form>
+
+#data
+<!doctype html><svg><foreignObject><p>
+#errors
+(1,38): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg foreignObject>
+| <p>
+
+#data
+<!doctype html><svg><title>abc
+#errors
+(1,30): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg title>
+| "abc"
+
+#data
+<option><span><option>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,22): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <option>
+| <span>
+| <option>
+
+#data
+<option><option>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,16): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <option>
+| <option>
+
+#data
+<math><annotation-xml><div>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,27): unexpected-html-element-in-foreign-content
+(1,27): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math annotation-xml>
+| <div>
+
+#data
+<math><annotation-xml encoding="application/svg+xml"><div>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,58): unexpected-html-element-in-foreign-content
+(1,58): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math annotation-xml>
+| encoding="application/svg+xml"
+| <div>
+
+#data
+<math><annotation-xml encoding="application/xhtml+xml"><div>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,60): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math annotation-xml>
+| encoding="application/xhtml+xml"
+| <div>
+
+#data
+<math><annotation-xml encoding="aPPlication/xhtmL+xMl"><div>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,60): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math annotation-xml>
+| encoding="aPPlication/xhtmL+xMl"
+| <div>
+
+#data
+<math><annotation-xml encoding="text/html"><div>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,48): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math annotation-xml>
+| encoding="text/html"
+| <div>
+
+#data
+<math><annotation-xml encoding="Text/htmL"><div>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,48): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math annotation-xml>
+| encoding="Text/htmL"
+| <div>
+
+#data
+<math><annotation-xml encoding=" text/html "><div>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,50): unexpected-html-element-in-foreign-content
+(1,50): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math annotation-xml>
+| encoding=" text/html "
+| <div>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests21.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests21.dat
new file mode 100644
index 000000000..d384a5556
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests21.dat
@@ -0,0 +1,305 @@
+#data
+<svg><![CDATA[foo]]>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,20): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "foo"
+
+#data
+<math><![CDATA[foo]]>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,21): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| "foo"
+
+#data
+<div><![CDATA[foo]]>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,7): expected-dashes-or-doctype
+(1,20): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <!-- [CDATA[foo]] -->
+
+#data
+<svg><![CDATA[foo
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,17): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "foo"
+
+#data
+<svg><![CDATA[foo
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,17): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "foo"
+
+#data
+<svg><![CDATA[
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,14): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+
+#data
+<svg><![CDATA[]]>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,17): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+
+#data
+<svg><![CDATA[]] >]]>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,21): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "]] >"
+
+#data
+<svg><![CDATA[]] >]]>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,21): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "]] >"
+
+#data
+<svg><![CDATA[]]
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,16): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "]]"
+
+#data
+<svg><![CDATA[]
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,15): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "]"
+
+#data
+<svg><![CDATA[]>a
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,17): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "]>a"
+
+#data
+<!DOCTYPE html><svg><![CDATA[foo]]]>
+#errors
+(1,36): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "foo]"
+
+#data
+<!DOCTYPE html><svg><![CDATA[foo]]]]>
+#errors
+(1,37): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "foo]]"
+
+#data
+<!DOCTYPE html><svg><![CDATA[foo]]]]]>
+#errors
+(1,38): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "foo]]]"
+
+#data
+<svg><foreignObject><div><![CDATA[foo]]>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,27): expected-dashes-or-doctype
+(1,40): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg foreignObject>
+| <div>
+| <!-- [CDATA[foo]] -->
+
+#data
+<svg><![CDATA[<svg>]]>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,22): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "<svg>"
+
+#data
+<svg><![CDATA[</svg>a]]>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,24): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "</svg>a"
+
+#data
+<svg><![CDATA[<svg>a
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,20): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "<svg>a"
+
+#data
+<svg><![CDATA[</svg>a
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,21): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "</svg>a"
+
+#data
+<svg><![CDATA[<svg>]]><path>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,28): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "<svg>"
+| <svg path>
+
+#data
+<svg><![CDATA[<svg>]]></path>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,29): unexpected-end-tag
+(1,29): unexpected-end-tag
+(1,29): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "<svg>"
+
+#data
+<svg><![CDATA[<svg>]]><!--path-->
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,33): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "<svg>"
+| <!-- path -->
+
+#data
+<svg><![CDATA[<svg>]]>path
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,26): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "<svg>path"
+
+#data
+<svg><![CDATA[<!--svg-->]]>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,27): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| "<!--svg-->"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests22.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests22.dat
new file mode 100644
index 000000000..31e6d9e33
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests22.dat
@@ -0,0 +1,190 @@
+#data
+<a><b><big><em><strong><div>X</a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,33): adoption-agency-1.3
+(1,33): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <b>
+| <big>
+| <em>
+| <strong>
+| <big>
+| <em>
+| <strong>
+| <div>
+| <a>
+| "X"
+
+#data
+<a><b><div id=1><div id=2><div id=3><div id=4><div id=5><div id=6><div id=7><div id=8>A</a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,91): adoption-agency-1.3
+(1,91): adoption-agency-1.3
+(1,91): adoption-agency-1.3
+(1,91): adoption-agency-1.3
+(1,91): adoption-agency-1.3
+(1,91): adoption-agency-1.3
+(1,91): adoption-agency-1.3
+(1,91): adoption-agency-1.3
+(1,91): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <b>
+| <b>
+| <div>
+| id="1"
+| <a>
+| <div>
+| id="2"
+| <a>
+| <div>
+| id="3"
+| <a>
+| <div>
+| id="4"
+| <a>
+| <div>
+| id="5"
+| <a>
+| <div>
+| id="6"
+| <a>
+| <div>
+| id="7"
+| <a>
+| <div>
+| id="8"
+| <a>
+| "A"
+
+#data
+<a><b><div id=1><div id=2><div id=3><div id=4><div id=5><div id=6><div id=7><div id=8><div id=9>A</a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,101): adoption-agency-1.3
+(1,101): adoption-agency-1.3
+(1,101): adoption-agency-1.3
+(1,101): adoption-agency-1.3
+(1,101): adoption-agency-1.3
+(1,101): adoption-agency-1.3
+(1,101): adoption-agency-1.3
+(1,101): adoption-agency-1.3
+(1,101): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <b>
+| <b>
+| <div>
+| id="1"
+| <a>
+| <div>
+| id="2"
+| <a>
+| <div>
+| id="3"
+| <a>
+| <div>
+| id="4"
+| <a>
+| <div>
+| id="5"
+| <a>
+| <div>
+| id="6"
+| <a>
+| <div>
+| id="7"
+| <a>
+| <div>
+| id="8"
+| <a>
+| <div>
+| id="9"
+| "A"
+
+#data
+<a><b><div id=1><div id=2><div id=3><div id=4><div id=5><div id=6><div id=7><div id=8><div id=9><div id=10>A</a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,112): adoption-agency-1.3
+(1,112): adoption-agency-1.3
+(1,112): adoption-agency-1.3
+(1,112): adoption-agency-1.3
+(1,112): adoption-agency-1.3
+(1,112): adoption-agency-1.3
+(1,112): adoption-agency-1.3
+(1,112): adoption-agency-1.3
+(1,112): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <b>
+| <b>
+| <div>
+| id="1"
+| <a>
+| <div>
+| id="2"
+| <a>
+| <div>
+| id="3"
+| <a>
+| <div>
+| id="4"
+| <a>
+| <div>
+| id="5"
+| <a>
+| <div>
+| id="6"
+| <a>
+| <div>
+| id="7"
+| <a>
+| <div>
+| id="8"
+| <a>
+| <div>
+| id="9"
+| <div>
+| id="10"
+| "A"
+
+#data
+<cite><b><cite><i><cite><i><cite><i><div>X</b>TEST
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,46): adoption-agency-1.3
+(1,50): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <cite>
+| <b>
+| <cite>
+| <i>
+| <cite>
+| <i>
+| <cite>
+| <i>
+| <i>
+| <i>
+| <div>
+| <b>
+| "X"
+| "TEST"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests23.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests23.dat
new file mode 100644
index 000000000..49e4a4ace
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests23.dat
@@ -0,0 +1,168 @@
+#data
+<p><font size=4><font color=red><font size=4><font size=4><font size=4><font size=4><font size=4><font color=red><p>X
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,116): unexpected-end-tag
+(1,117): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <font>
+| size="4"
+| <font>
+| color="red"
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <font>
+| color="red"
+| <p>
+| <font>
+| color="red"
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <font>
+| color="red"
+| "X"
+
+#data
+<p><font size=4><font size=4><font size=4><font size=4><p>X
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,58): unexpected-end-tag
+(1,59): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <p>
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <font>
+| size="4"
+| "X"
+
+#data
+<p><font size=4><font size=4><font size=4><font size="5"><font size=4><p>X
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,73): unexpected-end-tag
+(1,74): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <font>
+| size="5"
+| <font>
+| size="4"
+| <p>
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <font>
+| size="5"
+| <font>
+| size="4"
+| "X"
+
+#data
+<p><font size=4 id=a><font size=4 id=b><font size=4><font size=4><p>X
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,68): unexpected-end-tag
+(1,69): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <font>
+| id="a"
+| size="4"
+| <font>
+| id="b"
+| size="4"
+| <font>
+| size="4"
+| <font>
+| size="4"
+| <p>
+| <font>
+| id="a"
+| size="4"
+| <font>
+| id="b"
+| size="4"
+| <font>
+| size="4"
+| <font>
+| size="4"
+| "X"
+
+#data
+<p><b id=a><b id=a><b id=a><b><object><b id=a><b id=a>X</object><p>Y
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,64): end-tag-too-early
+(1,67): unexpected-end-tag
+(1,68): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <b>
+| id="a"
+| <b>
+| id="a"
+| <b>
+| id="a"
+| <b>
+| <object>
+| <b>
+| id="a"
+| <b>
+| id="a"
+| "X"
+| <p>
+| <b>
+| id="a"
+| <b>
+| id="a"
+| <b>
+| id="a"
+| <b>
+| "Y"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests24.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests24.dat
new file mode 100644
index 000000000..f6dc7eb48
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests24.dat
@@ -0,0 +1,79 @@
+#data
+<!DOCTYPE html>&NotEqualTilde;
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "≂̸"
+
+#data
+<!DOCTYPE html>&NotEqualTilde;A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "≂̸A"
+
+#data
+<!DOCTYPE html>&ThickSpace;
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "âŸâ€Š"
+
+#data
+<!DOCTYPE html>&ThickSpace;A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "âŸâ€ŠA"
+
+#data
+<!DOCTYPE html>&NotSubset;
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "⊂⃒"
+
+#data
+<!DOCTYPE html>&NotSubset;A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "⊂⃒A"
+
+#data
+<!DOCTYPE html>&Gopf;
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "ð”¾"
+
+#data
+<!DOCTYPE html>&Gopf;A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "ð”¾A"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests25.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests25.dat
new file mode 100644
index 000000000..cbc00512b
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests25.dat
@@ -0,0 +1,220 @@
+#data
+<!DOCTYPE html><body><foo>A
+#errors
+(1,27): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <foo>
+| "A"
+
+#data
+<!DOCTYPE html><body><area>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <area>
+| "A"
+
+#data
+<!DOCTYPE html><body><base>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <base>
+| "A"
+
+#data
+<!DOCTYPE html><body><basefont>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <basefont>
+| "A"
+
+#data
+<!DOCTYPE html><body><bgsound>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <bgsound>
+| "A"
+
+#data
+<!DOCTYPE html><body><br>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <br>
+| "A"
+
+#data
+<!DOCTYPE html><body><col>A
+#errors
+(1,26): unexpected-start-tag-ignored
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "A"
+
+#data
+<!DOCTYPE html><body><command>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <command>
+| "A"
+
+#data
+<!DOCTYPE html><body><embed>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <embed>
+| "A"
+
+#data
+<!DOCTYPE html><body><frame>A
+#errors
+(1,28): unexpected-start-tag-ignored
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "A"
+
+#data
+<!DOCTYPE html><body><hr>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <hr>
+| "A"
+
+#data
+<!DOCTYPE html><body><img>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <img>
+| "A"
+
+#data
+<!DOCTYPE html><body><input>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <input>
+| "A"
+
+#data
+<!DOCTYPE html><body><keygen>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <keygen>
+| "A"
+
+#data
+<!DOCTYPE html><body><link>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <link>
+| "A"
+
+#data
+<!DOCTYPE html><body><meta>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <meta>
+| "A"
+
+#data
+<!DOCTYPE html><body><param>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <param>
+| "A"
+
+#data
+<!DOCTYPE html><body><source>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <source>
+| "A"
+
+#data
+<!DOCTYPE html><body><track>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <track>
+| "A"
+
+#data
+<!DOCTYPE html><body><wbr>A
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <wbr>
+| "A"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests26.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests26.dat
new file mode 100644
index 000000000..867bbeecd
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests26.dat
@@ -0,0 +1,411 @@
+#data
+<!DOCTYPE html><body><a href='#1'><nobr>1<nobr></a><br><a href='#2'><nobr>2<nobr></a><br><a href='#3'><nobr>3<nobr></a>
+#errors
+(1,47): unexpected-start-tag-implies-end-tag
+(1,51): adoption-agency-1.3
+(1,74): unexpected-start-tag-implies-end-tag
+(1,74): adoption-agency-1.3
+(1,81): unexpected-start-tag-implies-end-tag
+(1,85): adoption-agency-1.3
+(1,108): unexpected-start-tag-implies-end-tag
+(1,108): adoption-agency-1.3
+(1,115): unexpected-start-tag-implies-end-tag
+(1,119): adoption-agency-1.3
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <a>
+| href="#1"
+| <nobr>
+| "1"
+| <nobr>
+| <nobr>
+| <br>
+| <a>
+| href="#2"
+| <a>
+| href="#2"
+| <nobr>
+| "2"
+| <nobr>
+| <nobr>
+| <br>
+| <a>
+| href="#3"
+| <a>
+| href="#3"
+| <nobr>
+| "3"
+| <nobr>
+
+#data
+<!DOCTYPE html><body><b><nobr>1<nobr></b><i><nobr>2<nobr></i>3
+#errors
+(1,37): unexpected-start-tag-implies-end-tag
+(1,41): adoption-agency-1.3
+(1,50): unexpected-start-tag-implies-end-tag
+(1,50): adoption-agency-1.3
+(1,57): unexpected-start-tag-implies-end-tag
+(1,61): adoption-agency-1.3
+(1,62): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <b>
+| <nobr>
+| "1"
+| <nobr>
+| <nobr>
+| <i>
+| <i>
+| <nobr>
+| "2"
+| <nobr>
+| <nobr>
+| "3"
+
+#data
+<!DOCTYPE html><body><b><nobr>1<table><nobr></b><i><nobr>2<nobr></i>3
+#errors
+(1,44): foster-parenting-start-tag
+(1,48): foster-parenting-end-tag
+(1,48): adoption-agency-1.3
+(1,51): foster-parenting-start-tag
+(1,57): foster-parenting-start-tag
+(1,57): nobr-already-in-scope
+(1,57): adoption-agency-1.2
+(1,58): foster-parenting-character
+(1,64): foster-parenting-start-tag
+(1,64): nobr-already-in-scope
+(1,68): foster-parenting-end-tag
+(1,68): adoption-agency-1.2
+(1,69): foster-parenting-character
+(1,69): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <b>
+| <nobr>
+| "1"
+| <nobr>
+| <i>
+| <i>
+| <nobr>
+| "2"
+| <nobr>
+| <nobr>
+| "3"
+| <table>
+
+#data
+<!DOCTYPE html><body><b><nobr>1<table><tr><td><nobr></b><i><nobr>2<nobr></i>3
+#errors
+(1,56): unexpected-end-tag
+(1,65): unexpected-start-tag-implies-end-tag
+(1,65): adoption-agency-1.3
+(1,72): unexpected-start-tag-implies-end-tag
+(1,76): adoption-agency-1.3
+(1,77): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <b>
+| <nobr>
+| "1"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <nobr>
+| <i>
+| <i>
+| <nobr>
+| "2"
+| <nobr>
+| <nobr>
+| "3"
+
+#data
+<!DOCTYPE html><body><b><nobr>1<div><nobr></b><i><nobr>2<nobr></i>3
+#errors
+(1,42): unexpected-start-tag-implies-end-tag
+(1,42): adoption-agency-1.3
+(1,46): adoption-agency-1.3
+(1,46): adoption-agency-1.3
+(1,55): unexpected-start-tag-implies-end-tag
+(1,55): adoption-agency-1.3
+(1,62): unexpected-start-tag-implies-end-tag
+(1,66): adoption-agency-1.3
+(1,67): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <b>
+| <nobr>
+| "1"
+| <div>
+| <b>
+| <nobr>
+| <nobr>
+| <nobr>
+| <i>
+| <i>
+| <nobr>
+| "2"
+| <nobr>
+| <nobr>
+| "3"
+
+#data
+<!DOCTYPE html><body><b><nobr>1<nobr></b><div><i><nobr>2<nobr></i>3
+#errors
+(1,37): unexpected-start-tag-implies-end-tag
+(1,41): adoption-agency-1.3
+(1,55): unexpected-start-tag-implies-end-tag
+(1,55): adoption-agency-1.3
+(1,62): unexpected-start-tag-implies-end-tag
+(1,66): adoption-agency-1.3
+(1,67): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <b>
+| <nobr>
+| "1"
+| <nobr>
+| <div>
+| <nobr>
+| <i>
+| <i>
+| <nobr>
+| "2"
+| <nobr>
+| <nobr>
+| "3"
+
+#data
+<!DOCTYPE html><body><b><nobr>1<nobr><ins></b><i><nobr>
+#errors
+(1,37): unexpected-start-tag-implies-end-tag
+(1,46): adoption-agency-1.3
+(1,55): unexpected-start-tag-implies-end-tag
+(1,55): adoption-agency-1.3
+(1,55): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <b>
+| <nobr>
+| "1"
+| <nobr>
+| <ins>
+| <nobr>
+| <i>
+| <i>
+| <nobr>
+
+#data
+<!DOCTYPE html><body><b><nobr>1<ins><nobr></b><i>2
+#errors
+(1,42): unexpected-start-tag-implies-end-tag
+(1,42): adoption-agency-1.3
+(1,46): adoption-agency-1.3
+(1,50): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <b>
+| <nobr>
+| "1"
+| <ins>
+| <nobr>
+| <nobr>
+| <i>
+| "2"
+
+#data
+<!DOCTYPE html><body><b>1<nobr></b><i><nobr>2</i>
+#errors
+(1,35): adoption-agency-1.3
+(1,44): unexpected-start-tag-implies-end-tag
+(1,44): adoption-agency-1.3
+(1,49): adoption-agency-1.3
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <b>
+| "1"
+| <nobr>
+| <nobr>
+| <i>
+| <i>
+| <nobr>
+| "2"
+
+#data
+<p><code x</code></p>
+
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,11): invalid-character-in-attribute-name
+(1,12): unexpected-character-after-solidus-in-tag
+(1,21): unexpected-end-tag
+(2,0): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <code>
+| code=""
+| x<=""
+| <code>
+| code=""
+| x<=""
+| "
+"
+
+#data
+<!DOCTYPE html><svg><foreignObject><p><i></p>a
+#errors
+(1,45): unexpected-end-tag
+(1,46): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg foreignObject>
+| <p>
+| <i>
+| <i>
+| "a"
+
+#data
+<!DOCTYPE html><table><tr><td><svg><foreignObject><p><i></p>a
+#errors
+(1,60): unexpected-end-tag
+(1,61): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <svg svg>
+| <svg foreignObject>
+| <p>
+| <i>
+| <i>
+| "a"
+
+#data
+<!DOCTYPE html><math><mtext><p><i></p>a
+#errors
+(1,38): unexpected-end-tag
+(1,39): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mtext>
+| <p>
+| <i>
+| <i>
+| "a"
+
+#data
+<!DOCTYPE html><table><tr><td><math><mtext><p><i></p>a
+#errors
+(1,53): unexpected-end-tag
+(1,54): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <math math>
+| <math mtext>
+| <p>
+| <i>
+| <i>
+| "a"
+
+#data
+<!DOCTYPE html><body><div><!/div>a
+#errors
+(1,28): expected-dashes-or-doctype
+(1,34): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <div>
+| <!-- /div -->
+| "a"
+
+#data
+<button><p><button>
+#errors
+Line 1 Col 8 Unexpected start tag (button). Expected DOCTYPE.
+Line 1 Col 19 Unexpected start tag (button) implies end tag (button).
+Line 1 Col 19 Expected closing tag. Unexpected end of file.
+#document
+| <html>
+| <head>
+| <body>
+| <button>
+| <p>
+| <button>
+
+#data
+<!DOCTYPE html><html><frameset></frameset></html></frameset>
+#errors
+60: Stray end tag “framesetâ€.
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+
+#data
+<!DOCTYPE html><html><frameset></frameset></html>XXX</frameset>
+#errors
+52: Non-space character in page trailer.
+52: Non-space character in page trailer.
+52: Non-space character in page trailer.
+63: Stray end tag “framesetâ€.
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests3.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests3.dat
new file mode 100644
index 000000000..423e2b3ca
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests3.dat
@@ -0,0 +1,306 @@
+#data
+<head></head><style></style>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,20): unexpected-start-tag-out-of-my-head
+#document
+| <html>
+| <head>
+| <style>
+| <body>
+
+#data
+<head></head><script></script>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,21): unexpected-start-tag-out-of-my-head
+#document
+| <html>
+| <head>
+| <script>
+| <body>
+
+#data
+<head></head><!-- --><style></style><!-- --><script></script>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,28): unexpected-start-tag-out-of-my-head
+(1,52): unexpected-start-tag-out-of-my-head
+#document
+| <html>
+| <head>
+| <style>
+| <script>
+| <!-- -->
+| <!-- -->
+| <body>
+
+#data
+<head></head><!-- -->x<style></style><!-- --><script></script>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <!-- -->
+| <body>
+| "x"
+| <style>
+| <!-- -->
+| <script>
+
+#data
+<!DOCTYPE html><html><head></head><body><pre>
+</pre></body></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <pre>
+
+#data
+<!DOCTYPE html><html><head></head><body><pre>
+foo</pre></body></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <pre>
+| "foo"
+
+#data
+<!DOCTYPE html><html><head></head><body><pre>
+
+foo</pre></body></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <pre>
+| "
+foo"
+
+#data
+<!DOCTYPE html><html><head></head><body><pre>
+foo
+</pre></body></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <pre>
+| "foo
+"
+
+#data
+<!DOCTYPE html><html><head></head><body><pre>x</pre><span>
+</span></body></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <pre>
+| "x"
+| <span>
+| "
+"
+
+#data
+<!DOCTYPE html><html><head></head><body><pre>x
+y</pre></body></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <pre>
+| "x
+y"
+
+#data
+<!DOCTYPE html><html><head></head><body><pre>x<div>
+y</pre></body></html>
+#errors
+(2,7): end-tag-too-early
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <pre>
+| "x"
+| <div>
+| "
+y"
+
+#data
+<!DOCTYPE html><pre>&#x0a;&#x0a;A</pre>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <pre>
+| "
+A"
+
+#data
+<!DOCTYPE html><HTML><META><HEAD></HEAD></HTML>
+#errors
+(1,33): two-heads-are-not-better-than-one
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <meta>
+| <body>
+
+#data
+<!DOCTYPE html><HTML><HEAD><head></HEAD></HTML>
+#errors
+(1,33): two-heads-are-not-better-than-one
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+
+#data
+<textarea>foo<span>bar</span><i>baz
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(1,35): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <textarea>
+| "foo<span>bar</span><i>baz"
+
+#data
+<title>foo<span>bar</em><i>baz
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,30): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <title>
+| "foo<span>bar</em><i>baz"
+| <body>
+
+#data
+<!DOCTYPE html><textarea>
+</textarea>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <textarea>
+
+#data
+<!DOCTYPE html><textarea>
+foo</textarea>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <textarea>
+| "foo"
+
+#data
+<!DOCTYPE html><textarea>
+
+foo</textarea>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <textarea>
+| "
+foo"
+
+#data
+<!DOCTYPE html><html><head></head><body><ul><li><div><p><li></ul></body></html>
+#errors
+(1,60): end-tag-too-early
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <ul>
+| <li>
+| <div>
+| <p>
+| <li>
+
+#data
+<!doctype html><nobr><nobr><nobr>
+#errors
+(1,27): unexpected-start-tag-implies-end-tag
+(1,33): unexpected-start-tag-implies-end-tag
+(1,33): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <nobr>
+| <nobr>
+| <nobr>
+
+#data
+<!doctype html><nobr><nobr></nobr><nobr>
+#errors
+(1,27): unexpected-start-tag-implies-end-tag
+(1,40): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <nobr>
+| <nobr>
+| <nobr>
+
+#data
+<!doctype html><html><body><p><table></table></body></html>
+#errors
+Not known
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <table>
+
+#data
+<p><table></table>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <table>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests4.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests4.dat
new file mode 100644
index 000000000..0a6174c36
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests4.dat
@@ -0,0 +1,58 @@
+#data
+direct div content
+#errors
+#document-fragment
+div
+#document
+| "direct div content"
+
+#data
+direct textarea content
+#errors
+#document-fragment
+textarea
+#document
+| "direct textarea content"
+
+#data
+textarea content with <em>pseudo</em> <foo>markup
+#errors
+#document-fragment
+textarea
+#document
+| "textarea content with <em>pseudo</em> <foo>markup"
+
+#data
+this is &#x0043;DATA inside a <style> element
+#errors
+#document-fragment
+style
+#document
+| "this is &#x0043;DATA inside a <style> element"
+
+#data
+</plaintext>
+#errors
+#document-fragment
+plaintext
+#document
+| "</plaintext>"
+
+#data
+setting html's innerHTML
+#errors
+#document-fragment
+html
+#document
+| <head>
+| <body>
+| "setting html's innerHTML"
+
+#data
+<title>setting head's innerHTML</title>
+#errors
+#document-fragment
+head
+#document
+| <title>
+| "setting head's innerHTML"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests5.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests5.dat
new file mode 100644
index 000000000..4d5fcd7a7
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests5.dat
@@ -0,0 +1,197 @@
+#data
+<style> <!-- </style>x
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <style>
+| " <!-- "
+| <body>
+| "x"
+
+#data
+<style> <!-- </style> --> </style>x
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,34): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <style>
+| " <!-- "
+| " "
+| <body>
+| "--> x"
+
+#data
+<style> <!--> </style>x
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <style>
+| " <!--> "
+| <body>
+| "x"
+
+#data
+<style> <!---> </style>x
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <style>
+| " <!---> "
+| <body>
+| "x"
+
+#data
+<iframe> <!---> </iframe>x
+#errors
+(1,8): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <iframe>
+| " <!---> "
+| "x"
+
+#data
+<iframe> <!--- </iframe>->x</iframe> --> </iframe>x
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,36): unexpected-end-tag
+(1,50): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <iframe>
+| " <!--- "
+| "->x --> x"
+
+#data
+<script> <!-- </script> --> </script>x
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,37): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <script>
+| " <!-- "
+| " "
+| <body>
+| "--> x"
+
+#data
+<title> <!-- </title> --> </title>x
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,34): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <title>
+| " <!-- "
+| " "
+| <body>
+| "--> x"
+
+#data
+<textarea> <!--- </textarea>->x</textarea> --> </textarea>x
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(1,42): unexpected-end-tag
+(1,58): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <textarea>
+| " <!--- "
+| "->x --> x"
+
+#data
+<style> <!</-- </style>x
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <style>
+| " <!</-- "
+| <body>
+| "x"
+
+#data
+<p><xmp></xmp>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <xmp>
+
+#data
+<xmp> <!-- > --> </xmp>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <xmp>
+| " <!-- > --> "
+
+#data
+<title>&amp;</title>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <title>
+| "&"
+| <body>
+
+#data
+<title><!--&amp;--></title>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <title>
+| "<!--&-->"
+| <body>
+
+#data
+<title><!--</title>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <title>
+| "<!--"
+| <body>
+
+#data
+<noscript><!--</noscript>--></noscript>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(1,39): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <noscript>
+| "<!--"
+| <body>
+| "-->"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests6.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests6.dat
new file mode 100644
index 000000000..fedc64e93
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests6.dat
@@ -0,0 +1,662 @@
+#data
+<!doctype html></head> <head>
+#errors
+(1,29): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| " "
+| <body>
+
+#data
+<!doctype html><form><div></form><div>
+#errors
+(1,33): end-tag-too-early-ignored
+(1,38): expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <form>
+| <div>
+| <div>
+
+#data
+<!doctype html><title>&amp;</title>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <title>
+| "&"
+| <body>
+
+#data
+<!doctype html><title><!--&amp;--></title>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <title>
+| "<!--&-->"
+| <body>
+
+#data
+<!doctype>
+#errors
+(1,9): need-space-after-doctype
+(1,10): expected-doctype-name-but-got-right-bracket
+(1,10): unknown-doctype
+#document
+| <!DOCTYPE >
+| <html>
+| <head>
+| <body>
+
+#data
+<!---x
+#errors
+(1,6): eof-in-comment
+(1,6): expected-doctype-but-got-eof
+#document
+| <!-- -x -->
+| <html>
+| <head>
+| <body>
+
+#data
+<body>
+<div>
+#errors
+(1,6): unexpected-start-tag
+(2,5): expected-closing-tag-but-got-eof
+#document-fragment
+div
+#document
+| "
+"
+| <div>
+
+#data
+<frameset></frameset>
+foo
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(2,1): unexpected-char-after-frameset
+(2,2): unexpected-char-after-frameset
+(2,3): unexpected-char-after-frameset
+#document
+| <html>
+| <head>
+| <frameset>
+| "
+"
+
+#data
+<frameset></frameset>
+<noframes>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(2,10): expected-named-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <frameset>
+| "
+"
+| <noframes>
+
+#data
+<frameset></frameset>
+<div>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(2,5): unexpected-start-tag-after-frameset
+#document
+| <html>
+| <head>
+| <frameset>
+| "
+"
+
+#data
+<frameset></frameset>
+</html>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <frameset>
+| "
+"
+
+#data
+<frameset></frameset>
+</div>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(2,6): unexpected-end-tag-after-frameset
+#document
+| <html>
+| <head>
+| <frameset>
+| "
+"
+
+#data
+<form><form>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,12): unexpected-start-tag
+(1,12): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <form>
+
+#data
+<button><button>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,16): unexpected-start-tag-implies-end-tag
+(1,16): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <button>
+| <button>
+
+#data
+<table><tr><td></th>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,20): unexpected-end-tag
+(1,20): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+
+#data
+<table><caption><td>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,20): XXX-undefined-error
+(1,20): unexpected-cell-in-table-body
+(1,20): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+| <tbody>
+| <tr>
+| <td>
+
+#data
+<table><caption><div>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,21): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+| <div>
+
+#data
+</caption><div>
+#errors
+(1,10): XXX-undefined-error
+(1,15): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <div>
+
+#data
+<table><caption><div></caption>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,31): expected-one-end-tag-but-got-another
+(1,31): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+| <div>
+
+#data
+<table><caption></table>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,24): end-table-tag-in-caption
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+
+#data
+</table><div>
+#errors
+(1,8): unexpected-end-tag
+(1,13): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <div>
+
+#data
+<table><caption></body></col></colgroup></html></tbody></td></tfoot></th></thead></tr>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,23): unexpected-end-tag
+(1,29): unexpected-end-tag
+(1,40): unexpected-end-tag
+(1,47): unexpected-end-tag
+(1,55): unexpected-end-tag
+(1,60): unexpected-end-tag
+(1,68): unexpected-end-tag
+(1,73): unexpected-end-tag
+(1,81): unexpected-end-tag
+(1,86): unexpected-end-tag
+(1,86): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+
+#data
+<table><caption><div></div>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,27): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+| <div>
+
+#data
+<table><tr><td></body></caption></col></colgroup></html>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,22): unexpected-end-tag
+(1,32): unexpected-end-tag
+(1,38): unexpected-end-tag
+(1,49): unexpected-end-tag
+(1,56): unexpected-end-tag
+(1,56): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+
+#data
+</table></tbody></tfoot></thead></tr><div>
+#errors
+(1,8): unexpected-end-tag
+(1,16): unexpected-end-tag
+(1,24): unexpected-end-tag
+(1,32): unexpected-end-tag
+(1,37): unexpected-end-tag
+(1,42): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <div>
+
+#data
+<table><colgroup>foo
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,18): foster-parenting-character-in-table
+(1,19): foster-parenting-character-in-table
+(1,20): foster-parenting-character-in-table
+(1,20): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| "foo"
+| <table>
+| <colgroup>
+
+#data
+foo<col>
+#errors
+(1,1): unexpected-character-in-colgroup
+(1,2): unexpected-character-in-colgroup
+(1,3): unexpected-character-in-colgroup
+#document-fragment
+colgroup
+#document
+| <col>
+
+#data
+<table><colgroup></col>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,23): no-end-tag
+(1,23): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <colgroup>
+
+#data
+<frameset><div>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(1,15): unexpected-start-tag-in-frameset
+(1,15): eof-in-frameset
+#document
+| <html>
+| <head>
+| <frameset>
+
+#data
+</frameset><frame>
+#errors
+(1,11): unexpected-frameset-in-frameset-innerhtml
+#document-fragment
+frameset
+#document
+| <frame>
+
+#data
+<frameset></div>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+(1,16): unexpected-end-tag-in-frameset
+(1,16): eof-in-frameset
+#document
+| <html>
+| <head>
+| <frameset>
+
+#data
+</body><div>
+#errors
+(1,7): unexpected-close-tag
+(1,12): expected-closing-tag-but-got-eof
+#document-fragment
+body
+#document
+| <div>
+
+#data
+<table><tr><div>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,16): unexpected-start-tag-implies-table-voodoo
+(1,16): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <table>
+| <tbody>
+| <tr>
+
+#data
+</tr><td>
+#errors
+(1,5): unexpected-end-tag
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+</tbody></tfoot></thead><td>
+#errors
+(1,8): unexpected-end-tag
+(1,16): unexpected-end-tag
+(1,24): unexpected-end-tag
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<table><tr><div><td>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,16): foster-parenting-start-tag
+(1,20): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+
+#data
+<caption><col><colgroup><tbody><tfoot><thead><tr>
+#errors
+(1,9): unexpected-start-tag
+(1,14): unexpected-start-tag
+(1,24): unexpected-start-tag
+(1,31): unexpected-start-tag
+(1,38): unexpected-start-tag
+(1,45): unexpected-start-tag
+#document-fragment
+tbody
+#document
+| <tr>
+
+#data
+<table><tbody></thead>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,22): unexpected-end-tag-in-table-body
+(1,22): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+
+#data
+</table><tr>
+#errors
+(1,8): unexpected-end-tag
+#document-fragment
+tbody
+#document
+| <tr>
+
+#data
+<table><tbody></body></caption></col></colgroup></html></td></th></tr>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,21): unexpected-end-tag-in-table-body
+(1,31): unexpected-end-tag-in-table-body
+(1,37): unexpected-end-tag-in-table-body
+(1,48): unexpected-end-tag-in-table-body
+(1,55): unexpected-end-tag-in-table-body
+(1,60): unexpected-end-tag-in-table-body
+(1,65): unexpected-end-tag-in-table-body
+(1,70): unexpected-end-tag-in-table-body
+(1,70): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+
+#data
+<table><tbody></div>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,20): unexpected-end-tag-implies-table-voodoo
+(1,20): end-tag-too-early
+(1,20): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+
+#data
+<table><table>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,14): unexpected-start-tag-implies-end-tag
+(1,14): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <table>
+
+#data
+<table></body></caption></col></colgroup></html></tbody></td></tfoot></th></thead></tr>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,14): unexpected-end-tag
+(1,24): unexpected-end-tag
+(1,30): unexpected-end-tag
+(1,41): unexpected-end-tag
+(1,48): unexpected-end-tag
+(1,56): unexpected-end-tag
+(1,61): unexpected-end-tag
+(1,69): unexpected-end-tag
+(1,74): unexpected-end-tag
+(1,82): unexpected-end-tag
+(1,87): unexpected-end-tag
+(1,87): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+
+#data
+</table><tr>
+#errors
+(1,8): unexpected-end-tag
+#document-fragment
+table
+#document
+| <tbody>
+| <tr>
+
+#data
+<body></body></html>
+#errors
+(1,20): unexpected-end-tag-after-body-innerhtml
+#document-fragment
+html
+#document
+| <head>
+| <body>
+
+#data
+<html><frameset></frameset></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <frameset>
+| " "
+
+#data
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"><html></html>
+#errors
+(1,50): unknown-doctype element.
+#document
+| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "">
+| <html>
+| <head>
+| <body>
+
+#data
+<param><frameset></frameset>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,17): unexpected-start-tag
+#document
+| <html>
+| <head>
+| <frameset>
+
+#data
+<source><frameset></frameset>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,18): unexpected-start-tag
+#document
+| <html>
+| <head>
+| <frameset>
+
+#data
+<track><frameset></frameset>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,17): unexpected-start-tag
+#document
+| <html>
+| <head>
+| <frameset>
+
+#data
+</html><frameset></frameset>
+#errors
+(1,7): expected-doctype-but-got-end-tag
+(1,17): expected-eof-but-got-start-tag
+(1,17): unexpected-start-tag
+#document
+| <html>
+| <head>
+| <frameset>
+
+#data
+</body><frameset></frameset>
+#errors
+(1,7): expected-doctype-but-got-end-tag
+(1,17): unexpected-start-tag-after-body
+(1,17): unexpected-start-tag
+#document
+| <html>
+| <head>
+| <frameset>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests7.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests7.dat
new file mode 100644
index 000000000..f9471b9a3
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests7.dat
@@ -0,0 +1,402 @@
+#data
+<!doctype html><body><title>X</title>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <title>
+| "X"
+
+#data
+<!doctype html><table><title>X</title></table>
+#errors
+(1,29): unexpected-start-tag-implies-table-voodoo
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <title>
+| "X"
+| <table>
+
+#data
+<!doctype html><head></head><title>X</title>
+#errors
+(1,35): unexpected-start-tag-out-of-my-head
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <title>
+| "X"
+| <body>
+
+#data
+<!doctype html></head><title>X</title>
+#errors
+(1,29): unexpected-start-tag-out-of-my-head
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <title>
+| "X"
+| <body>
+
+#data
+<!doctype html><table><meta></table>
+#errors
+(1,28): unexpected-start-tag-implies-table-voodoo
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <meta>
+| <table>
+
+#data
+<!doctype html><table>X<tr><td><table> <meta></table></table>
+#errors
+(1,45): unexpected-start-tag-implies-table-voodoo
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "X"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <meta>
+| <table>
+| " "
+
+#data
+<!doctype html><html> <head>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+
+#data
+<!doctype html> <head>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+
+#data
+<!doctype html><table><style> <tr>x </style> </table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <style>
+| " <tr>x "
+| " "
+
+#data
+<!doctype html><table><TBODY><script> <tr>x </script> </table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <script>
+| " <tr>x "
+| " "
+
+#data
+<!doctype html><p><applet><p>X</p></applet>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <p>
+| <applet>
+| <p>
+| "X"
+
+#data
+<!doctype html><listing>
+X</listing>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <listing>
+| "X"
+
+#data
+<!doctype html><select><input>X
+#errors
+(1,30): unexpected-input-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| <input>
+| "X"
+
+#data
+<!doctype html><select><select>X
+#errors
+(1,31): unexpected-select-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| "X"
+
+#data
+<!doctype html><table><input type=hidDEN></table>
+#errors
+(1,41): unexpected-hidden-input-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <input>
+| type="hidDEN"
+
+#data
+<!doctype html><table>X<input type=hidDEN></table>
+#errors
+(1,23): foster-parenting-character
+(1,42): unexpected-hidden-input-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| "X"
+| <table>
+| <input>
+| type="hidDEN"
+
+#data
+<!doctype html><table> <input type=hidDEN></table>
+#errors
+(1,43): unexpected-hidden-input-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| " "
+| <input>
+| type="hidDEN"
+
+#data
+<!doctype html><table> <input type='hidDEN'></table>
+#errors
+(1,45): unexpected-hidden-input-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| " "
+| <input>
+| type="hidDEN"
+
+#data
+<!doctype html><table><input type=" hidden"><input type=hidDEN></table>
+#errors
+(1,44): unexpected-start-tag-implies-table-voodoo
+(1,63): unexpected-hidden-input-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <input>
+| type=" hidden"
+| <table>
+| <input>
+| type="hidDEN"
+
+#data
+<!doctype html><table><select>X<tr>
+#errors
+(1,30): unexpected-start-tag-implies-table-voodoo
+(1,35): unexpected-table-element-start-tag-in-select-in-table
+(1,35): eof-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| "X"
+| <table>
+| <tbody>
+| <tr>
+
+#data
+<!doctype html><select>X</select>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| "X"
+
+#data
+<!DOCTYPE hTmL><html></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+
+#data
+<!DOCTYPE HTML><html></html>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+
+#data
+<body>X</body></body>
+#errors
+(1,21): unexpected-end-tag-after-body
+#document-fragment
+html
+#document
+| <head>
+| <body>
+| "X"
+
+#data
+<div><p>a</x> b
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,13): unexpected-end-tag
+(1,15): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <p>
+| "a b"
+
+#data
+<table><tr><td><code></code> </table>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <code>
+| " "
+
+#data
+<table><b><tr><td>aaa</td></tr>bbb</table>ccc
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,10): foster-parenting-start-tag
+(1,32): foster-parenting-character
+(1,33): foster-parenting-character
+(1,34): foster-parenting-character
+(1,45): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| <b>
+| "bbb"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| "aaa"
+| <b>
+| "ccc"
+
+#data
+A<table><tr> B</tr> B</table>
+#errors
+(1,1): expected-doctype-but-got-chars
+(1,13): foster-parenting-character
+(1,14): foster-parenting-character
+(1,20): foster-parenting-character
+(1,21): foster-parenting-character
+#document
+| <html>
+| <head>
+| <body>
+| "A B B"
+| <table>
+| <tbody>
+| <tr>
+
+#data
+A<table><tr> B</tr> </em>C</table>
+#errors
+(1,1): expected-doctype-but-got-chars
+(1,13): foster-parenting-character
+(1,14): foster-parenting-character
+(1,20): foster-parenting-character
+(1,25): unexpected-end-tag
+(1,26): foster-parenting-character
+#document
+| <html>
+| <head>
+| <body>
+| "A BC"
+| <table>
+| <tbody>
+| <tr>
+| " "
+
+#data
+<select><keygen>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,16): unexpected-input-in-select
+#document
+| <html>
+| <head>
+| <body>
+| <select>
+| <keygen>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests8.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests8.dat
new file mode 100644
index 000000000..93289f39c
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests8.dat
@@ -0,0 +1,149 @@
+#data
+<div>
+<div></div>
+</span>x
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(3,7): unexpected-end-tag
+(3,8): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| "
+"
+| <div>
+| "
+x"
+
+#data
+<div>x<div></div>
+</span>x
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(2,7): unexpected-end-tag
+(2,8): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| "x"
+| <div>
+| "
+x"
+
+#data
+<div>x<div></div>x</span>x
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,25): unexpected-end-tag
+(1,26): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| "x"
+| <div>
+| "xx"
+
+#data
+<div>x<div></div>y</span>z
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,25): unexpected-end-tag
+(1,26): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| "x"
+| <div>
+| "yz"
+
+#data
+<table><div>x<div></div>x</span>x
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,12): foster-parenting-start-tag
+(1,13): foster-parenting-character
+(1,18): foster-parenting-start-tag
+(1,24): foster-parenting-end-tag
+(1,25): foster-parenting-start-tag
+(1,32): foster-parenting-end-tag
+(1,32): unexpected-end-tag
+(1,33): foster-parenting-character
+(1,33): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| "x"
+| <div>
+| "xx"
+| <table>
+
+#data
+x<table>x
+#errors
+(1,1): expected-doctype-but-got-chars
+(1,9): foster-parenting-character
+#document
+| <html>
+| <head>
+| <body>
+| "xx"
+| <table>
+
+#data
+x<table><table>x
+#errors
+(1,1): expected-doctype-but-got-chars
+(1,15): unexpected-start-tag-implies-end-tag
+(1,16): foster-parenting-character
+#document
+| <html>
+| <head>
+| <body>
+| "x"
+| <table>
+| "x"
+| <table>
+
+#data
+<b>a<div></div><div></b>y
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,24): adoption-agency-1.3
+(1,25): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| "a"
+| <div>
+| <div>
+| <b>
+| "y"
+
+#data
+<a><div><p></a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,15): adoption-agency-1.3
+(1,15): adoption-agency-1.3
+(1,15): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <div>
+| <a>
+| <p>
+| <a>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests9.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests9.dat
new file mode 100644
index 000000000..40651a061
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests9.dat
@@ -0,0 +1,473 @@
+#data
+<!DOCTYPE html><math></math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+
+#data
+<!DOCTYPE html><body><math></math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+
+#data
+<!DOCTYPE html><math><mi>
+#errors
+(1,25) expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mi>
+
+#data
+<!DOCTYPE html><math><annotation-xml><svg><u>
+#errors
+(1,45) unexpected-html-element-in-foreign-content
+(1,45) expected-closing-tag-but-got-eof
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math annotation-xml>
+| <svg svg>
+| <u>
+
+#data
+<!DOCTYPE html><body><select><math></math></select>
+#errors
+(1,35) unexpected-start-tag-in-select
+(1,42) unexpected-end-tag-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+
+#data
+<!DOCTYPE html><body><select><option><math></math></option></select>
+#errors
+(1,43) unexpected-start-tag-in-select
+(1,50) unexpected-end-tag-in-select
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| <option>
+
+#data
+<!DOCTYPE html><body><table><math></math></table>
+#errors
+(1,34) unexpected-start-tag-implies-table-voodoo
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+| <table>
+
+#data
+<!DOCTYPE html><body><table><math><mi>foo</mi></math></table>
+#errors
+(1,34) foster-parenting-start-token
+(1,39) foster-parenting-character
+(1,40) foster-parenting-character
+(1,41) foster-parenting-character
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mi>
+| "foo"
+| <table>
+
+#data
+<!DOCTYPE html><body><table><math><mi>foo</mi><mi>bar</mi></math></table>
+#errors
+(1,34) foster-parenting-start-tag
+(1,39) foster-parenting-character
+(1,40) foster-parenting-character
+(1,41) foster-parenting-character
+(1,51) foster-parenting-character
+(1,52) foster-parenting-character
+(1,53) foster-parenting-character
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mi>
+| "foo"
+| <math mi>
+| "bar"
+| <table>
+
+#data
+<!DOCTYPE html><body><table><tbody><math><mi>foo</mi><mi>bar</mi></math></tbody></table>
+#errors
+(1,41) foster-parenting-start-tag
+(1,46) foster-parenting-character
+(1,47) foster-parenting-character
+(1,48) foster-parenting-character
+(1,58) foster-parenting-character
+(1,59) foster-parenting-character
+(1,60) foster-parenting-character
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mi>
+| "foo"
+| <math mi>
+| "bar"
+| <table>
+| <tbody>
+
+#data
+<!DOCTYPE html><body><table><tbody><tr><math><mi>foo</mi><mi>bar</mi></math></tr></tbody></table>
+#errors
+(1,45) foster-parenting-start-tag
+(1,50) foster-parenting-character
+(1,51) foster-parenting-character
+(1,52) foster-parenting-character
+(1,62) foster-parenting-character
+(1,63) foster-parenting-character
+(1,64) foster-parenting-character
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mi>
+| "foo"
+| <math mi>
+| "bar"
+| <table>
+| <tbody>
+| <tr>
+
+#data
+<!DOCTYPE html><body><table><tbody><tr><td><math><mi>foo</mi><mi>bar</mi></math></td></tr></tbody></table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <math math>
+| <math mi>
+| "foo"
+| <math mi>
+| "bar"
+
+#data
+<!DOCTYPE html><body><table><tbody><tr><td><math><mi>foo</mi><mi>bar</mi></math><p>baz</td></tr></tbody></table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <math math>
+| <math mi>
+| "foo"
+| <math mi>
+| "bar"
+| <p>
+| "baz"
+
+#data
+<!DOCTYPE html><body><table><caption><math><mi>foo</mi><mi>bar</mi></math><p>baz</caption></table>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+| <math math>
+| <math mi>
+| "foo"
+| <math mi>
+| "bar"
+| <p>
+| "baz"
+
+#data
+<!DOCTYPE html><body><table><caption><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux
+#errors
+(1,70) unexpected-html-element-in-foreign-content
+(1,81) XXX-undefined-error
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+| <math math>
+| <math mi>
+| "foo"
+| <math mi>
+| "bar"
+| <p>
+| "baz"
+| <p>
+| "quux"
+
+#data
+<!DOCTYPE html><body><table><caption><math><mi>foo</mi><mi>bar</mi>baz</table><p>quux
+#errors
+(1,78) unexpected-end-tag
+(1,78) expected-one-end-tag-but-got-another
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <caption>
+| <math math>
+| <math mi>
+| "foo"
+| <math mi>
+| "bar"
+| "baz"
+| <p>
+| "quux"
+
+#data
+<!DOCTYPE html><body><table><colgroup><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux
+#errors
+(1,44) foster-parenting-start-tag
+(1,49) foster-parenting-character
+(1,50) foster-parenting-character
+(1,51) foster-parenting-character
+(1,61) foster-parenting-character
+(1,62) foster-parenting-character
+(1,63) foster-parenting-character
+(1,71) unexpected-html-element-in-foreign-content
+(1,71) foster-parenting-start-tag
+(1,63) foster-parenting-character
+(1,63) foster-parenting-character
+(1,63) foster-parenting-character
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mi>
+| "foo"
+| <math mi>
+| "bar"
+| <p>
+| "baz"
+| <table>
+| <colgroup>
+| <p>
+| "quux"
+
+#data
+<!DOCTYPE html><body><table><tr><td><select><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux
+#errors
+(1,50) unexpected-start-tag-in-select
+(1,54) unexpected-start-tag-in-select
+(1,62) unexpected-end-tag-in-select
+(1,66) unexpected-start-tag-in-select
+(1,74) unexpected-end-tag-in-select
+(1,77) unexpected-start-tag-in-select
+(1,88) unexpected-table-element-end-tag-in-select-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <select>
+| "foobarbaz"
+| <p>
+| "quux"
+
+#data
+<!DOCTYPE html><body><table><select><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux
+#errors
+(1,36) unexpected-start-tag-implies-table-voodoo
+(1,42) unexpected-start-tag-in-select
+(1,46) unexpected-start-tag-in-select
+(1,54) unexpected-end-tag-in-select
+(1,58) unexpected-start-tag-in-select
+(1,66) unexpected-end-tag-in-select
+(1,69) unexpected-start-tag-in-select
+(1,80) unexpected-table-element-end-tag-in-select-in-table
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <select>
+| "foobarbaz"
+| <table>
+| <p>
+| "quux"
+
+#data
+<!DOCTYPE html><body></body></html><math><mi>foo</mi><mi>bar</mi><p>baz
+#errors
+(1,41) expected-eof-but-got-start-tag
+(1,68) unexpected-html-element-in-foreign-content
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mi>
+| "foo"
+| <math mi>
+| "bar"
+| <p>
+| "baz"
+
+#data
+<!DOCTYPE html><body></body><math><mi>foo</mi><mi>bar</mi><p>baz
+#errors
+(1,34) unexpected-start-tag-after-body
+(1,61) unexpected-html-element-in-foreign-content
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mi>
+| "foo"
+| <math mi>
+| "bar"
+| <p>
+| "baz"
+
+#data
+<!DOCTYPE html><frameset><math><mi></mi><mi></mi><p><span>
+#errors
+(1,31) unexpected-start-tag-in-frameset
+(1,35) unexpected-start-tag-in-frameset
+(1,40) unexpected-end-tag-in-frameset
+(1,44) unexpected-start-tag-in-frameset
+(1,49) unexpected-end-tag-in-frameset
+(1,52) unexpected-start-tag-in-frameset
+(1,58) unexpected-start-tag-in-frameset
+(1,58) eof-in-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+
+#data
+<!DOCTYPE html><frameset></frameset><math><mi></mi><mi></mi><p><span>
+#errors
+(1,42) unexpected-start-tag-after-frameset
+(1,46) unexpected-start-tag-after-frameset
+(1,51) unexpected-end-tag-after-frameset
+(1,55) unexpected-start-tag-after-frameset
+(1,60) unexpected-end-tag-after-frameset
+(1,63) unexpected-start-tag-after-frameset
+(1,69) unexpected-start-tag-after-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+
+#data
+<!DOCTYPE html><body xlink:href=foo><math xlink:href=foo></math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| xlink:href="foo"
+| <math math>
+| xlink href="foo"
+
+#data
+<!DOCTYPE html><body xlink:href=foo xml:lang=en><math><mi xml:lang=en xlink:href=foo></mi></math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| xlink:href="foo"
+| xml:lang="en"
+| <math math>
+| <math mi>
+| xlink href="foo"
+| xml lang="en"
+
+#data
+<!DOCTYPE html><body xlink:href=foo xml:lang=en><math><mi xml:lang=en xlink:href=foo /></math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| xlink:href="foo"
+| xml:lang="en"
+| <math math>
+| <math mi>
+| xlink href="foo"
+| xml lang="en"
+
+#data
+<!DOCTYPE html><body xlink:href=foo xml:lang=en><math><mi xml:lang=en xlink:href=foo />bar</math>
+#errors
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| xlink:href="foo"
+| xml:lang="en"
+| <math math>
+| <math mi>
+| xlink href="foo"
+| xml lang="en"
+| "bar"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests_innerHTML_1.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests_innerHTML_1.dat
new file mode 100644
index 000000000..5ede639bc
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tests_innerHTML_1.dat
@@ -0,0 +1,902 @@
+#data
+<body><span>
+#errors
+(1,6): unexpected-start-tag
+(1,12): expected-closing-tag-but-got-eof
+#document-fragment
+body
+#document
+| <span>
+
+#data
+<span><body>
+#errors
+(1,12): unexpected-start-tag
+(1,12): expected-closing-tag-but-got-eof
+#document-fragment
+body
+#document
+| <span>
+
+#data
+<span><body>
+#errors
+(1,12): unexpected-start-tag
+(1,12): expected-closing-tag-but-got-eof
+#document-fragment
+div
+#document
+| <span>
+
+#data
+<body><span>
+#errors
+(1,12): expected-closing-tag-but-got-eof
+#document-fragment
+html
+#document
+| <head>
+| <body>
+| <span>
+
+#data
+<frameset><span>
+#errors
+(1,10): unexpected-start-tag
+(1,16): expected-closing-tag-but-got-eof
+#document-fragment
+body
+#document
+| <span>
+
+#data
+<span><frameset>
+#errors
+(1,16): unexpected-start-tag
+(1,16): expected-closing-tag-but-got-eof
+#document-fragment
+body
+#document
+| <span>
+
+#data
+<span><frameset>
+#errors
+(1,16): unexpected-start-tag
+(1,16): expected-closing-tag-but-got-eof
+#document-fragment
+div
+#document
+| <span>
+
+#data
+<frameset><span>
+#errors
+(1,16): unexpected-start-tag-in-frameset
+(1,16): eof-in-frameset
+#document-fragment
+html
+#document
+| <head>
+| <frameset>
+
+#data
+<table><tr>
+#errors
+(1,7): unexpected-start-tag
+#document-fragment
+table
+#document
+| <tbody>
+| <tr>
+
+#data
+</table><tr>
+#errors
+(1,8): unexpected-end-tag
+#document-fragment
+table
+#document
+| <tbody>
+| <tr>
+
+#data
+<a>
+#errors
+(1,3): unexpected-start-tag-implies-table-voodoo
+(1,3): eof-in-table
+#document-fragment
+table
+#document
+| <a>
+
+#data
+<a>
+#errors
+(1,3): unexpected-start-tag-implies-table-voodoo
+(1,3): eof-in-table
+#document-fragment
+table
+#document
+| <a>
+
+#data
+<a><caption>a
+#errors
+(1,3): unexpected-start-tag-implies-table-voodoo
+(1,13): expected-closing-tag-but-got-eof
+#document-fragment
+table
+#document
+| <a>
+| <caption>
+| "a"
+
+#data
+<a><colgroup><col>
+#errors
+(1,3): foster-parenting-start-token
+(1,18): expected-closing-tag-but-got-eof
+#document-fragment
+table
+#document
+| <a>
+| <colgroup>
+| <col>
+
+#data
+<a><tbody><tr>
+#errors
+(1,3): foster-parenting-start-tag
+#document-fragment
+table
+#document
+| <a>
+| <tbody>
+| <tr>
+
+#data
+<a><tfoot><tr>
+#errors
+(1,3): foster-parenting-start-tag
+#document-fragment
+table
+#document
+| <a>
+| <tfoot>
+| <tr>
+
+#data
+<a><thead><tr>
+#errors
+(1,3): foster-parenting-start-tag
+#document-fragment
+table
+#document
+| <a>
+| <thead>
+| <tr>
+
+#data
+<a><tr>
+#errors
+(1,3): foster-parenting-start-tag
+#document-fragment
+table
+#document
+| <a>
+| <tbody>
+| <tr>
+
+#data
+<a><th>
+#errors
+(1,3): unexpected-start-tag-implies-table-voodoo
+(1,7): unexpected-cell-in-table-body
+#document-fragment
+table
+#document
+| <a>
+| <tbody>
+| <tr>
+| <th>
+
+#data
+<a><td>
+#errors
+(1,3): unexpected-start-tag-implies-table-voodoo
+(1,7): unexpected-cell-in-table-body
+#document-fragment
+table
+#document
+| <a>
+| <tbody>
+| <tr>
+| <td>
+
+#data
+<table></table><tbody>
+#errors
+(1,22): unexpected-start-tag
+#document-fragment
+caption
+#document
+| <table>
+
+#data
+</table><span>
+#errors
+(1,8): unexpected-end-tag
+(1,14): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <span>
+
+#data
+<span></table>
+#errors
+(1,14): unexpected-end-tag
+(1,14): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <span>
+
+#data
+</caption><span>
+#errors
+(1,10): XXX-undefined-error
+(1,16): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <span>
+
+#data
+<span></caption><span>
+#errors
+(1,16): XXX-undefined-error
+(1,22): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <span>
+| <span>
+
+#data
+<span><caption><span>
+#errors
+(1,15): unexpected-start-tag
+(1,21): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <span>
+| <span>
+
+#data
+<span><col><span>
+#errors
+(1,11): unexpected-start-tag
+(1,17): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <span>
+| <span>
+
+#data
+<span><colgroup><span>
+#errors
+(1,16): unexpected-start-tag
+(1,22): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <span>
+| <span>
+
+#data
+<span><html><span>
+#errors
+(1,12): non-html-root
+(1,18): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <span>
+| <span>
+
+#data
+<span><tbody><span>
+#errors
+(1,13): unexpected-start-tag
+(1,19): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <span>
+| <span>
+
+#data
+<span><td><span>
+#errors
+(1,10): unexpected-start-tag
+(1,16): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <span>
+| <span>
+
+#data
+<span><tfoot><span>
+#errors
+(1,13): unexpected-start-tag
+(1,19): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <span>
+| <span>
+
+#data
+<span><thead><span>
+#errors
+(1,13): unexpected-start-tag
+(1,19): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <span>
+| <span>
+
+#data
+<span><th><span>
+#errors
+(1,10): unexpected-start-tag
+(1,16): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <span>
+| <span>
+
+#data
+<span><tr><span>
+#errors
+(1,10): unexpected-start-tag
+(1,16): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <span>
+| <span>
+
+#data
+<span></table><span>
+#errors
+(1,14): unexpected-end-tag
+(1,20): expected-closing-tag-but-got-eof
+#document-fragment
+caption
+#document
+| <span>
+| <span>
+
+#data
+</colgroup><col>
+#errors
+(1,11): XXX-undefined-error
+#document-fragment
+colgroup
+#document
+| <col>
+
+#data
+<a><col>
+#errors
+(1,3): XXX-undefined-error
+#document-fragment
+colgroup
+#document
+| <col>
+
+#data
+<caption><a>
+#errors
+(1,9): XXX-undefined-error
+(1,12): unexpected-start-tag-implies-table-voodoo
+(1,12): eof-in-table
+#document-fragment
+tbody
+#document
+| <a>
+
+#data
+<col><a>
+#errors
+(1,5): XXX-undefined-error
+(1,8): unexpected-start-tag-implies-table-voodoo
+(1,8): eof-in-table
+#document-fragment
+tbody
+#document
+| <a>
+
+#data
+<colgroup><a>
+#errors
+(1,10): XXX-undefined-error
+(1,13): unexpected-start-tag-implies-table-voodoo
+(1,13): eof-in-table
+#document-fragment
+tbody
+#document
+| <a>
+
+#data
+<tbody><a>
+#errors
+(1,7): XXX-undefined-error
+(1,10): unexpected-start-tag-implies-table-voodoo
+(1,10): eof-in-table
+#document-fragment
+tbody
+#document
+| <a>
+
+#data
+<tfoot><a>
+#errors
+(1,7): XXX-undefined-error
+(1,10): unexpected-start-tag-implies-table-voodoo
+(1,10): eof-in-table
+#document-fragment
+tbody
+#document
+| <a>
+
+#data
+<thead><a>
+#errors
+(1,7): XXX-undefined-error
+(1,10): unexpected-start-tag-implies-table-voodoo
+(1,10): eof-in-table
+#document-fragment
+tbody
+#document
+| <a>
+
+#data
+</table><a>
+#errors
+(1,8): XXX-undefined-error
+(1,11): unexpected-start-tag-implies-table-voodoo
+(1,11): eof-in-table
+#document-fragment
+tbody
+#document
+| <a>
+
+#data
+<a><tr>
+#errors
+(1,3): unexpected-start-tag-implies-table-voodoo
+#document-fragment
+tbody
+#document
+| <a>
+| <tr>
+
+#data
+<a><td>
+#errors
+(1,3): unexpected-start-tag-implies-table-voodoo
+(1,7): unexpected-cell-in-table-body
+#document-fragment
+tbody
+#document
+| <a>
+| <tr>
+| <td>
+
+#data
+<a><td>
+#errors
+(1,3): unexpected-start-tag-implies-table-voodoo
+(1,7): unexpected-cell-in-table-body
+#document-fragment
+tbody
+#document
+| <a>
+| <tr>
+| <td>
+
+#data
+<a><td>
+#errors
+(1,3): unexpected-start-tag-implies-table-voodoo
+(1,7): unexpected-cell-in-table-body
+#document-fragment
+tbody
+#document
+| <a>
+| <tr>
+| <td>
+
+#data
+<td><table><tbody><a><tr>
+#errors
+(1,4): unexpected-cell-in-table-body
+(1,21): unexpected-start-tag-implies-table-voodoo
+(1,25): eof-in-table
+#document-fragment
+tbody
+#document
+| <tr>
+| <td>
+| <a>
+| <table>
+| <tbody>
+| <tr>
+
+#data
+</tr><td>
+#errors
+(1,5): XXX-undefined-error
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<td><table><a><tr></tr><tr>
+#errors
+(1,14): unexpected-start-tag-implies-table-voodoo
+(1,27): eof-in-table
+#document-fragment
+tr
+#document
+| <td>
+| <a>
+| <table>
+| <tbody>
+| <tr>
+| <tr>
+
+#data
+<caption><td>
+#errors
+(1,9): XXX-undefined-error
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<col><td>
+#errors
+(1,5): XXX-undefined-error
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<colgroup><td>
+#errors
+(1,10): XXX-undefined-error
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<tbody><td>
+#errors
+(1,7): XXX-undefined-error
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<tfoot><td>
+#errors
+(1,7): XXX-undefined-error
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<thead><td>
+#errors
+(1,7): XXX-undefined-error
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<tr><td>
+#errors
+(1,4): XXX-undefined-error
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+</table><td>
+#errors
+(1,8): XXX-undefined-error
+#document-fragment
+tr
+#document
+| <td>
+
+#data
+<td><table></table><td>
+#errors
+#document-fragment
+tr
+#document
+| <td>
+| <table>
+| <td>
+
+#data
+<td><table></table><td>
+#errors
+#document-fragment
+tr
+#document
+| <td>
+| <table>
+| <td>
+
+#data
+<caption><a>
+#errors
+(1,9): XXX-undefined-error
+(1,12): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<col><a>
+#errors
+(1,5): XXX-undefined-error
+(1,8): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<colgroup><a>
+#errors
+(1,10): XXX-undefined-error
+(1,13): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<tbody><a>
+#errors
+(1,7): XXX-undefined-error
+(1,10): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<tfoot><a>
+#errors
+(1,7): XXX-undefined-error
+(1,10): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<th><a>
+#errors
+(1,4): XXX-undefined-error
+(1,7): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<thead><a>
+#errors
+(1,7): XXX-undefined-error
+(1,10): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<tr><a>
+#errors
+(1,4): XXX-undefined-error
+(1,7): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <a>
+
+#data
+</table><a>
+#errors
+(1,8): XXX-undefined-error
+(1,11): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <a>
+
+#data
+</tbody><a>
+#errors
+(1,8): XXX-undefined-error
+(1,11): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <a>
+
+#data
+</td><a>
+#errors
+(1,5): unexpected-end-tag
+(1,8): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <a>
+
+#data
+</tfoot><a>
+#errors
+(1,8): XXX-undefined-error
+(1,11): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <a>
+
+#data
+</thead><a>
+#errors
+(1,8): XXX-undefined-error
+(1,11): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <a>
+
+#data
+</th><a>
+#errors
+(1,5): unexpected-end-tag
+(1,8): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <a>
+
+#data
+</tr><a>
+#errors
+(1,5): XXX-undefined-error
+(1,8): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <a>
+
+#data
+<table><td><td>
+#errors
+(1,11): unexpected-cell-in-table-body
+(1,15): expected-closing-tag-but-got-eof
+#document-fragment
+td
+#document
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| <td>
+
+#data
+</select><option>
+#errors
+(1,9): XXX-undefined-error
+(1,17): eof-in-select
+#document-fragment
+select
+#document
+| <option>
+
+#data
+<input><option>
+#errors
+(1,7): unexpected-input-in-select
+(1,15): eof-in-select
+#document-fragment
+select
+#document
+| <option>
+
+#data
+<keygen><option>
+#errors
+(1,8): unexpected-input-in-select
+(1,16): eof-in-select
+#document-fragment
+select
+#document
+| <option>
+
+#data
+<textarea><option>
+#errors
+(1,10): unexpected-input-in-select
+(1,18): eof-in-select
+#document-fragment
+select
+#document
+| <option>
+
+#data
+</html><!--abc-->
+#errors
+(1,7): unexpected-end-tag-after-body-innerhtml
+#document-fragment
+html
+#document
+| <head>
+| <body>
+| <!-- abc -->
+
+#data
+</frameset><frame>
+#errors
+(1,11): unexpected-frameset-in-frameset-innerhtml
+#document-fragment
+frameset
+#document
+| <frame>
+
+#data
+#errors
+#document-fragment
+html
+#document
+| <head>
+| <body>
+
+#data
+<head></head><script></script>
+#errors
+21: “script†element between “head†and “bodyâ€.
+#document-fragment
+html
+#document
+| <head>
+| <script>
+| <body>
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tricky01.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tricky01.dat
new file mode 100644
index 000000000..f7065214e
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/tricky01.dat
@@ -0,0 +1,334 @@
+#data
+<b><p>Bold </b> Not bold</p>
+Also not bold.
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,15): adoption-agency-1.3
+#document
+| <html>
+| <head>
+| <body>
+| <b>
+| <p>
+| <b>
+| "Bold "
+| " Not bold"
+| "
+Also not bold."
+
+#data
+<html>
+<font color=red><i>Italic and Red<p>Italic and Red </font> Just italic.</p> Italic only.</i> Plain
+<p>I should not be red. <font color=red>Red. <i>Italic and red.</p>
+<p>Italic and red. </i> Red.</font> I should not be red.</p>
+<b>Bold <i>Bold and italic</b> Only Italic </i> Plain
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(2,58): adoption-agency-1.3
+(3,67): unexpected-end-tag
+(4,23): adoption-agency-1.3
+(4,35): adoption-agency-1.3
+(5,30): adoption-agency-1.3
+#document
+| <html>
+| <head>
+| <body>
+| <font>
+| color="red"
+| <i>
+| "Italic and Red"
+| <i>
+| <p>
+| <font>
+| color="red"
+| "Italic and Red "
+| " Just italic."
+| " Italic only."
+| " Plain
+"
+| <p>
+| "I should not be red. "
+| <font>
+| color="red"
+| "Red. "
+| <i>
+| "Italic and red."
+| <font>
+| color="red"
+| <i>
+| "
+"
+| <p>
+| <font>
+| color="red"
+| <i>
+| "Italic and red. "
+| " Red."
+| " I should not be red."
+| "
+"
+| <b>
+| "Bold "
+| <i>
+| "Bold and italic"
+| <i>
+| " Only Italic "
+| " Plain"
+
+#data
+<html><body>
+<p><font size="7">First paragraph.</p>
+<p>Second paragraph.</p></font>
+<b><p><i>Bold and Italic</b> Italic</p>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(2,38): unexpected-end-tag
+(4,28): adoption-agency-1.3
+(4,28): adoption-agency-1.3
+(4,39): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| "
+"
+| <p>
+| <font>
+| size="7"
+| "First paragraph."
+| <font>
+| size="7"
+| "
+"
+| <p>
+| "Second paragraph."
+| "
+"
+| <b>
+| <p>
+| <b>
+| <i>
+| "Bold and Italic"
+| <i>
+| " Italic"
+
+#data
+<html>
+<dl>
+<dt><b>Boo
+<dd>Goo?
+</dl>
+</html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(4,4): end-tag-too-early
+(5,5): end-tag-too-early
+(6,7): expected-one-end-tag-but-got-another
+#document
+| <html>
+| <head>
+| <body>
+| <dl>
+| "
+"
+| <dt>
+| <b>
+| "Boo
+"
+| <dd>
+| <b>
+| "Goo?
+"
+| <b>
+| "
+"
+
+#data
+<html><body>
+<label><a><div>Hello<div>World</div></a></label>
+</body></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(2,40): adoption-agency-1.3
+(2,48): unexpected-end-tag
+(3,7): expected-one-end-tag-but-got-another
+#document
+| <html>
+| <head>
+| <body>
+| "
+"
+| <label>
+| <a>
+| <div>
+| <a>
+| "Hello"
+| <div>
+| "World"
+| "
+"
+
+#data
+<table><center> <font>a</center> <img> <tr><td> </td> </tr> </table>
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,15): foster-parenting-start-tag
+(1,16): foster-parenting-character
+(1,22): foster-parenting-start-tag
+(1,23): foster-parenting-character
+(1,32): foster-parenting-end-tag
+(1,32): end-tag-too-early
+(1,33): foster-parenting-character
+(1,38): foster-parenting-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <center>
+| " "
+| <font>
+| "a"
+| <font>
+| <img>
+| " "
+| <table>
+| " "
+| <tbody>
+| <tr>
+| <td>
+| " "
+| " "
+| " "
+
+#data
+<table><tr><p><a><p>You should see this text.
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,14): unexpected-start-tag-implies-table-voodoo
+(1,17): unexpected-start-tag-implies-table-voodoo
+(1,20): unexpected-start-tag-implies-table-voodoo
+(1,20): closing-non-current-p-element
+(1,21): foster-parenting-character
+(1,22): foster-parenting-character
+(1,23): foster-parenting-character
+(1,24): foster-parenting-character
+(1,25): foster-parenting-character
+(1,26): foster-parenting-character
+(1,27): foster-parenting-character
+(1,28): foster-parenting-character
+(1,29): foster-parenting-character
+(1,30): foster-parenting-character
+(1,31): foster-parenting-character
+(1,32): foster-parenting-character
+(1,33): foster-parenting-character
+(1,34): foster-parenting-character
+(1,35): foster-parenting-character
+(1,36): foster-parenting-character
+(1,37): foster-parenting-character
+(1,38): foster-parenting-character
+(1,39): foster-parenting-character
+(1,40): foster-parenting-character
+(1,41): foster-parenting-character
+(1,42): foster-parenting-character
+(1,43): foster-parenting-character
+(1,44): foster-parenting-character
+(1,45): foster-parenting-character
+(1,45): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| <a>
+| <p>
+| <a>
+| "You should see this text."
+| <table>
+| <tbody>
+| <tr>
+
+#data
+<TABLE>
+<TR>
+<CENTER><CENTER><TD></TD></TR><TR>
+<FONT>
+<TABLE><tr></tr></TABLE>
+</P>
+<a></font><font></a>
+This page contains an insanely badly-nested tag sequence.
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(3,8): unexpected-start-tag-implies-table-voodoo
+(3,16): unexpected-start-tag-implies-table-voodoo
+(4,6): unexpected-start-tag-implies-table-voodoo
+(5,7): unexpected-start-tag-implies-end-tag
+(7,10): adoption-agency-1.3
+(7,20): adoption-agency-1.3
+(8,57): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <center>
+| <center>
+| <font>
+| "
+"
+| <table>
+| "
+"
+| <tbody>
+| <tr>
+| "
+"
+| <td>
+| <tr>
+| "
+"
+| <table>
+| <tbody>
+| <tr>
+| <font>
+| "
+"
+| <p>
+| "
+"
+| <a>
+| <a>
+| <font>
+| <font>
+| "
+This page contains an insanely badly-nested tag sequence."
+
+#data
+<html>
+<body>
+<b><nobr><div>This text is in a div inside a nobr</nobr>More text that should not be in the nobr, i.e., the
+nobr should have closed the div inside it implicitly. </b><pre>A pre tag outside everything else.</pre>
+</body>
+</html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(3,56): adoption-agency-1.3
+(4,58): adoption-agency-1.3
+(5,7): expected-one-end-tag-but-got-another
+#document
+| <html>
+| <head>
+| <body>
+| "
+"
+| <b>
+| <nobr>
+| <div>
+| <b>
+| <nobr>
+| "This text is in a div inside a nobr"
+| "More text that should not be in the nobr, i.e., the
+nobr should have closed the div inside it implicitly. "
+| <pre>
+| "A pre tag outside everything else."
+| "
+
+"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/webkit01.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/webkit01.dat
new file mode 100644
index 000000000..c480accd9
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/webkit01.dat
@@ -0,0 +1,705 @@
+#data
+Test
+#errors
+(1,4): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "Test"
+
+#data
+<div></div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+
+#data
+<div>Test</div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| "Test"
+
+#data
+<di
+#errors
+(1,3): eof-in-tag-name
+(1,3): expected-doctype-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<div>Hello</div>
+<script>
+console.log("PASS");
+</script>
+<div>Bye</div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| "Hello"
+| "
+"
+| <script>
+| "
+console.log("PASS");
+"
+| "
+"
+| <div>
+| "Bye"
+
+#data
+<div foo="bar">Hello</div>
+#errors
+(1,15): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| foo="bar"
+| "Hello"
+
+#data
+<div>Hello</div>
+<script>
+console.log("FOO<span>BAR</span>BAZ");
+</script>
+<div>Bye</div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| "Hello"
+| "
+"
+| <script>
+| "
+console.log("FOO<span>BAR</span>BAZ");
+"
+| "
+"
+| <div>
+| "Bye"
+
+#data
+<foo bar="baz"></foo><potato quack="duck"></potato>
+#errors
+(1,15): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <foo>
+| bar="baz"
+| <potato>
+| quack="duck"
+
+#data
+<foo bar="baz"><potato quack="duck"></potato></foo>
+#errors
+(1,15): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <foo>
+| bar="baz"
+| <potato>
+| quack="duck"
+
+#data
+<foo></foo bar="baz"><potato></potato quack="duck">
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,21): attributes-in-end-tag
+(1,51): attributes-in-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <foo>
+| <potato>
+
+#data
+</ tttt>
+#errors
+(1,2): expected-closing-tag-but-got-char
+(1,8): expected-doctype-but-got-eof
+#document
+| <!-- tttt -->
+| <html>
+| <head>
+| <body>
+
+#data
+<div FOO ><img><img></div>
+#errors
+(1,10): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| foo=""
+| <img>
+| <img>
+
+#data
+<p>Test</p<p>Test2</p>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,13): unexpected-end-tag
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| "TestTest2"
+
+#data
+<rdar://problem/6869687>
+#errors
+(1,7): unexpected-character-after-solidus-in-tag
+(1,8): unexpected-character-after-solidus-in-tag
+(1,16): unexpected-character-after-solidus-in-tag
+(1,24): expected-doctype-but-got-start-tag
+(1,24): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <rdar:>
+| 6869687=""
+| problem=""
+
+#data
+<A>test< /A>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,8): expected-tag-name
+(1,12): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| "test< /A>"
+
+#data
+&lt;
+#errors
+(1,4): expected-doctype-but-got-chars
+#document
+| <html>
+| <head>
+| <body>
+| "<"
+
+#data
+<body foo='bar'><body foo='baz' yo='mama'>
+#errors
+(1,16): expected-doctype-but-got-start-tag
+(1,42): unexpected-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| foo="bar"
+| yo="mama"
+
+#data
+<body></br foo="bar"></body>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,21): attributes-in-end-tag
+(1,21): unexpected-end-tag-treated-as
+#document
+| <html>
+| <head>
+| <body>
+| <br>
+
+#data
+<bdy><br foo="bar"></body>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,26): expected-one-end-tag-but-got-another
+#document
+| <html>
+| <head>
+| <body>
+| <bdy>
+| <br>
+| foo="bar"
+
+#data
+<body></body></br foo="bar">
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,28): attributes-in-end-tag
+(1,28): unexpected-end-tag-after-body
+(1,28): unexpected-end-tag-treated-as
+#document
+| <html>
+| <head>
+| <body>
+| <br>
+
+#data
+<bdy></body><br foo="bar">
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,12): expected-one-end-tag-but-got-another
+(1,26): unexpected-start-tag-after-body
+(1,26): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <bdy>
+| <br>
+| foo="bar"
+
+#data
+<html><body></body></html><!-- Hi there -->
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <!-- Hi there -->
+
+#data
+<html><body></body></html>x<!-- Hi there -->
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,27): expected-eof-but-got-char
+#document
+| <html>
+| <head>
+| <body>
+| "x"
+| <!-- Hi there -->
+
+#data
+<html><body></body></html>x<!-- Hi there --></html><!-- Again -->
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,27): expected-eof-but-got-char
+#document
+| <html>
+| <head>
+| <body>
+| "x"
+| <!-- Hi there -->
+| <!-- Again -->
+
+#data
+<html><body></body></html>x<!-- Hi there --></body></html><!-- Again -->
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,27): expected-eof-but-got-char
+#document
+| <html>
+| <head>
+| <body>
+| "x"
+| <!-- Hi there -->
+| <!-- Again -->
+
+#data
+<html><body><ruby><div><rp>xx</rp></div></ruby></body></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,27): XXX-undefined-error
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| <div>
+| <rp>
+| "xx"
+
+#data
+<html><body><ruby><div><rt>xx</rt></div></ruby></body></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,27): XXX-undefined-error
+#document
+| <html>
+| <head>
+| <body>
+| <ruby>
+| <div>
+| <rt>
+| "xx"
+
+#data
+<html><frameset><!--1--><noframes>A</noframes><!--2--></frameset><!--3--><noframes>B</noframes><!--4--></html><!--5--><noframes>C</noframes><!--6-->
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <frameset>
+| <!-- 1 -->
+| <noframes>
+| "A"
+| <!-- 2 -->
+| <!-- 3 -->
+| <noframes>
+| "B"
+| <!-- 4 -->
+| <noframes>
+| "C"
+| <!-- 5 -->
+| <!-- 6 -->
+
+#data
+<select><option>A<select><option>B<select><option>C<select><option>D<select><option>E<select><option>F<select><option>G<select>
+#errors
+(1,8): expected-doctype-but-got-start-tag
+(1,25): unexpected-select-in-select
+(1,59): unexpected-select-in-select
+(1,93): unexpected-select-in-select
+(1,127): unexpected-select-in-select
+(1,127): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <select>
+| <option>
+| "A"
+| <option>
+| "B"
+| <select>
+| <option>
+| "C"
+| <option>
+| "D"
+| <select>
+| <option>
+| "E"
+| <option>
+| "F"
+| <select>
+| <option>
+| "G"
+
+#data
+<dd><dd><dt><dt><dd><li><li>
+#errors
+(1,4): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <dd>
+| <dd>
+| <dt>
+| <dt>
+| <dd>
+| <li>
+| <li>
+
+#data
+<div><b></div><div><nobr>a<nobr>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,14): end-tag-too-early
+(1,32): unexpected-start-tag-implies-end-tag
+(1,32): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <b>
+| <div>
+| <b>
+| <nobr>
+| "a"
+| <nobr>
+
+#data
+<head></head>
+<body></body>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| "
+"
+| <body>
+
+#data
+<head></head> <style></style>ddd
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,21): unexpected-start-tag-out-of-my-head
+#document
+| <html>
+| <head>
+| <style>
+| " "
+| <body>
+| "ddd"
+
+#data
+<kbd><table></kbd><col><select><tr>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,18): unexpected-end-tag-implies-table-voodoo
+(1,18): unexpected-end-tag
+(1,31): unexpected-start-tag-implies-table-voodoo
+(1,35): unexpected-table-element-start-tag-in-select-in-table
+(1,35): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| <kbd>
+| <select>
+| <table>
+| <colgroup>
+| <col>
+| <tbody>
+| <tr>
+
+#data
+<kbd><table></kbd><col><select><tr></table><div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,18): unexpected-end-tag-implies-table-voodoo
+(1,18): unexpected-end-tag
+(1,31): unexpected-start-tag-implies-table-voodoo
+(1,35): unexpected-table-element-start-tag-in-select-in-table
+(1,48): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <kbd>
+| <select>
+| <table>
+| <colgroup>
+| <col>
+| <tbody>
+| <tr>
+| <div>
+
+#data
+<a><li><style></style><title></title></a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,41): adoption-agency-1.3
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <li>
+| <a>
+| <style>
+| <title>
+
+#data
+<font></p><p><meta><title></title></font>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,10): unexpected-end-tag
+(1,41): adoption-agency-1.3
+#document
+| <html>
+| <head>
+| <body>
+| <font>
+| <p>
+| <p>
+| <font>
+| <meta>
+| <title>
+
+#data
+<a><center><title></title><a>
+#errors
+(1,3): expected-doctype-but-got-start-tag
+(1,29): unexpected-start-tag-implies-end-tag
+(1,29): adoption-agency-1.3
+(1,29): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <a>
+| <center>
+| <a>
+| <title>
+| <a>
+
+#data
+<svg><title><div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,17): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg title>
+| <div>
+
+#data
+<svg><title><rect><div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,23): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg title>
+| <rect>
+| <div>
+
+#data
+<svg><title><svg><div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,22): unexpected-html-element-in-foreign-content
+(1,22): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg title>
+| <svg svg>
+| <div>
+
+#data
+<img <="" FAIL>
+#errors
+(1,6): invalid-character-in-attribute-name
+(1,15): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <img>
+| <=""
+| fail=""
+
+#data
+<ul><li><div id='foo'/>A</li><li>B<div>C</div></li></ul>
+#errors
+(1,4): expected-doctype-but-got-start-tag
+(1,23): non-void-element-with-trailing-solidus
+(1,29): end-tag-too-early
+#document
+| <html>
+| <head>
+| <body>
+| <ul>
+| <li>
+| <div>
+| id="foo"
+| "A"
+| <li>
+| "B"
+| <div>
+| "C"
+
+#data
+<svg><em><desc></em>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,9): unexpected-html-element-in-foreign-content
+(1,20): adoption-agency-1.3
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <em>
+| <desc>
+
+#data
+<svg><tfoot></mi><td>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+(1,17): unexpected-end-tag
+(1,17): unexpected-end-tag
+(1,21): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <svg svg>
+| <svg tfoot>
+| <svg td>
+
+#data
+<math><mrow><mrow><mn>1</mn></mrow><mi>a</mi></mrow></math>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math mrow>
+| <math mrow>
+| <math mn>
+| "1"
+| <math mi>
+| "a"
+
+#data
+<!doctype html><input type="hidden"><frameset>
+#errors
+(1,46): unexpected-start-tag
+(1,46): eof-in-frameset
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <frameset>
+
+#data
+<!doctype html><input type="button"><frameset>
+#errors
+(1,46): unexpected-start-tag
+#document
+| <!DOCTYPE html>
+| <html>
+| <head>
+| <body>
+| <input>
+| type="button"
diff --git a/parser/htmlparser/tests/mochitest/html5lib_tree_construction/webkit02.dat b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/webkit02.dat
new file mode 100644
index 000000000..647fcfd41
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/html5lib_tree_construction/webkit02.dat
@@ -0,0 +1,116 @@
+#data
+<foo bar=qux/>
+#errors
+(1,14): expected-doctype-but-got-start-tag
+(1,14): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <foo>
+| bar="qux/"
+
+#data
+<p id="status"><noscript><strong>A</strong></noscript><span>B</span></p>
+#errors
+(1,15): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <p>
+| id="status"
+| <noscript>
+| "<strong>A</strong>"
+| <span>
+| "B"
+
+#data
+<div><sarcasm><div></div></sarcasm></div>
+#errors
+(1,5): expected-doctype-but-got-start-tag
+#document
+| <html>
+| <head>
+| <body>
+| <div>
+| <sarcasm>
+| <div>
+
+#data
+<html><body><img src="" border="0" alt="><div>A</div></body></html>
+#errors
+(1,6): expected-doctype-but-got-start-tag
+(1,67): eof-in-attribute-value-double-quote
+#document
+| <html>
+| <head>
+| <body>
+
+#data
+<table><td></tbody>A
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,11): unexpected-cell-in-table-body
+(1,20): foster-parenting-character
+(1,20): eof-in-table
+#document
+| <html>
+| <head>
+| <body>
+| "A"
+| <table>
+| <tbody>
+| <tr>
+| <td>
+
+#data
+<table><td></thead>A
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,11): unexpected-cell-in-table-body
+(1,19): XXX-undefined-error
+(1,20): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| "A"
+
+#data
+<table><td></tfoot>A
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,11): unexpected-cell-in-table-body
+(1,19): XXX-undefined-error
+(1,20): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <tbody>
+| <tr>
+| <td>
+| "A"
+
+#data
+<table><thead><td></tbody>A
+#errors
+(1,7): expected-doctype-but-got-start-tag
+(1,18): unexpected-cell-in-table-body
+(1,26): XXX-undefined-error
+(1,27): expected-closing-tag-but-got-eof
+#document
+| <html>
+| <head>
+| <body>
+| <table>
+| <thead>
+| <tr>
+| <td>
+| "A"
diff --git a/parser/htmlparser/tests/mochitest/iframe_bug599584.html b/parser/htmlparser/tests/mochitest/iframe_bug599584.html
new file mode 100644
index 000000000..4512a4d63
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/iframe_bug599584.html
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=599584
+-->
+<head>
+ <title>Iframe for Bug 599584</title>
+</head>
+<body>
+<script>
+document.getElementsByTagName("head")[0].innerHTML = '<meta http-equiv="Refresh" content="1; url=iframe_bug599584.html?navigated">'
+parent.startTest();
+</script>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/invalidchar.xml b/parser/htmlparser/tests/mochitest/invalidchar.xml
new file mode 100644
index 000000000..d4ad7f057
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/invalidchar.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root>
+ <fail> This is an invalid byte in UTF-8: ¿ </fail>
+</root>
diff --git a/parser/htmlparser/tests/mochitest/mochitest.ini b/parser/htmlparser/tests/mochitest/mochitest.ini
new file mode 100644
index 000000000..dcb30d6e8
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/mochitest.ini
@@ -0,0 +1,149 @@
+[DEFAULT]
+support-files =
+ bug_502091_iframe.html
+ file_bug102699.sjs
+ file_bug534293-slow.sjs
+ file_bug534293.sjs
+ file_bug543062.sjs
+ file_bug594730-1.html
+ file_bug594730-2.html
+ file_bug594730-3.html
+ file_bug594730-4.html
+ file_bug594730-5.html
+ file_bug594730-6.html
+ file_bug594730-7.html
+ file_bug594730-8.html
+ file_bug594730-9.html
+ file_bug642908.sjs
+ file_bug655682.sjs
+ file_bug672453_bomless_utf16.html
+ file_bug672453_http_unsupported.html
+ file_bug672453_http_unsupported.html^headers^
+ file_bug672453_late_meta.html
+ file_bug672453_meta_non_superset.html
+ file_bug672453_meta_restart.html
+ file_bug672453_meta_unsupported.html
+ file_bug672453_meta_utf16.html
+ file_bug688580.js
+ file_bug672453_not_declared.html
+ file_bug672453_meta_userdefined.html
+ file_bug716579-16.html
+ file_bug716579-16.html^headers^
+ file_bug716579-16.xhtml
+ file_bug716579-16.xhtml^headers^
+ file_bug716579-8.html
+ file_bug716579-8.html^headers^
+ file_bug716579-8.xhtml
+ file_bug716579-8.xhtml^headers^
+ file_bug717180.html
+ file_img_picture_preload.html
+ file_img_picture_preload.sjs
+ html5_tree_construction_exceptions.js
+ iframe_bug599584.html
+ invalidchar.xml
+ parser_datreader.js
+ parser_web_testrunner.js
+ dir_bug534293/file_bug534293.sjs
+ html5lib_tree_construction/adoption01.dat
+ html5lib_tree_construction/adoption02.dat
+ html5lib_tree_construction/comments01.dat
+ html5lib_tree_construction/doctype01.dat
+ html5lib_tree_construction/domjs-unsafe.dat
+ html5lib_tree_construction/entities01.dat
+ html5lib_tree_construction/entities02.dat
+ html5lib_tree_construction/foreign-fragment.dat
+ html5lib_tree_construction/html5test-com.dat
+ html5lib_tree_construction/inbody01.dat
+ html5lib_tree_construction/isindex.dat
+ html5lib_tree_construction/pending-spec-changes.dat
+ html5lib_tree_construction/pending-spec-changes-plain-text-unsafe.dat
+ html5lib_tree_construction/plain-text-unsafe.dat
+ html5lib_tree_construction/scriptdata01.dat
+ html5lib_tree_construction/tables01.dat
+ html5lib_tree_construction/template.dat
+ html5lib_tree_construction/tests10.dat
+ html5lib_tree_construction/tests11.dat
+ html5lib_tree_construction/tests12.dat
+ html5lib_tree_construction/tests14.dat
+ html5lib_tree_construction/tests15.dat
+ html5lib_tree_construction/tests16.dat
+ html5lib_tree_construction/tests17.dat
+ html5lib_tree_construction/tests18.dat
+ html5lib_tree_construction/tests19.dat
+ html5lib_tree_construction/tests1.dat
+ html5lib_tree_construction/tests20.dat
+ html5lib_tree_construction/tests21.dat
+ html5lib_tree_construction/tests22.dat
+ html5lib_tree_construction/tests23.dat
+ html5lib_tree_construction/tests24.dat
+ html5lib_tree_construction/tests25.dat
+ html5lib_tree_construction/tests26.dat
+ html5lib_tree_construction/tests2.dat
+ html5lib_tree_construction/tests3.dat
+ html5lib_tree_construction/tests4.dat
+ html5lib_tree_construction/tests5.dat
+ html5lib_tree_construction/tests6.dat
+ html5lib_tree_construction/tests7.dat
+ html5lib_tree_construction/tests8.dat
+ html5lib_tree_construction/tests9.dat
+ html5lib_tree_construction/tests_innerHTML_1.dat
+ html5lib_tree_construction/tricky01.dat
+ html5lib_tree_construction/webkit01.dat
+ html5lib_tree_construction/webkit02.dat
+ html5lib_tree_construction/main-element.dat
+ html5lib_tree_construction/ruby.dat
+ html5lib_tree_construction/scripted/adoption01.dat
+ html5lib_tree_construction/scripted/webkit01.dat
+ html5lib_tree_construction/scripted/ark.dat
+ blue.png
+
+[test_bug102699.html]
+[test_bug174351.html]
+[test_bug213517.html]
+[test_bug339350.xhtml]
+[test_bug358797.html]
+[test_bug396568.html]
+[test_bug418464.html]
+[test_bug460437.xhtml]
+[test_bug502091.html]
+[test_bug543062.html]
+[test_bug552938-2.html]
+[test_bug552938.html]
+[test_bug563322.xhtml]
+[test_bug566879.html]
+[test_bug594730.html]
+[test_bug599584.html]
+[test_bug613662.html]
+[test_bug613662.xhtml]
+[test_bug639362.html]
+[test_bug642908.html]
+[test_bug645115.html]
+[test_bug655682.html]
+[test_bug667533.html]
+[test_bug672453.html]
+[test_bug688580.html]
+[test_bug688580.xhtml]
+[test_bug709083.html]
+[test_bug715112.html]
+[test_bug715739.html]
+[test_bug716579.html]
+[test_bug717180.html]
+[test_bug1104732.html]
+support-files =
+ file_defer_bug1104732.js
+ file_async_bug1104732.sjs
+
+[test_compatmode.html]
+[test_html5_tree_construction.html]
+skip-if = toolkit == 'android' #TIMED_OUT
+[test_html5_tree_construction_part2.html]
+skip-if = toolkit == 'android' #TIMED_OUT
+[test_img_picture_preload.html]
+[test_xml_mislabeled.html]
+# Disabled test due to orange on Linux
+# test_bug568470.html
+# file_bug568470.sjs
+# file_bug568470-script.sjs
+# Disable test due to frequent orange on Mac
+# test_bug534293.html
+[test_bug1209658.html]
diff --git a/parser/htmlparser/tests/mochitest/parser_datreader.js b/parser/htmlparser/tests/mochitest/parser_datreader.js
new file mode 100644
index 000000000..645d14413
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/parser_datreader.js
@@ -0,0 +1,207 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * A test suite that runs WHATWG HTML parser tests.
+ * The tests are from html5lib.
+ *
+ * http://html5lib.googlecode.com/
+ */
+
+/**
+ * A few utility functions.
+ */
+function log(entry) {
+
+}
+
+function startsWith(s, s2) {
+ return s.indexOf(s2)==0;
+}
+
+function trimString(s) {
+ return(s.replace(/^\s+/,'').replace(/\s+$/,''));
+}
+
+/**
+ * Parses an individual testcase into an array containing the input
+ * string, a string representing the expected tree (DOM), and a list
+ * of error messages.
+ *
+ * @param A string containing a single testcase
+ */
+function parseTestcase(testcase) {
+ var lines = testcase.split("\n");
+
+ /* check that the first non-empty, non-comment line is #data */
+ for (var line of lines) {
+ if (!line || startsWith(line, "##")) {
+ continue;
+ }
+ if (line == "#data")
+ break;
+ log(lines);
+ throw "Unknown test format."
+ }
+
+ var input = [];
+ var output = [];
+ var errors = [];
+ var fragment = [];
+ var currentList = input;
+ for (var line of lines) {
+ if (startsWith(line, "##todo")) {
+ todo(false, line.substring(6));
+ continue;
+ }
+ if (!(startsWith(line, "#error") ||
+ startsWith(line, "#document") ||
+ startsWith(line, "#document-fragment") ||
+ startsWith(line, "#data"))) {
+ currentList.push(line);
+ } else if (line == "#errors") {
+ currentList = errors;
+ } else if (line == "#document") {
+ currentList = output;
+ } else if (line == "#document-fragment") {
+ currentList = fragment;
+ }
+ }
+ while (!output[output.length - 1]) {
+ output.pop(); // zap trailing blank lines
+ }
+ //logger.log(input.length, output.length, errors.length);
+ return [input.join("\n"), output.join("\n"), errors, fragment[0]];
+}
+
+/**
+ * A generator function that accepts a list of strings. Each list
+ * member corresponds to the contents of a ".dat" file from the
+ * html5lib test suite.
+ *
+ * @param The list of strings
+ */
+function test_parser(testlist) {
+ for (var testgroup of testlist) {
+ var tests = testgroup.split("#data\n");
+ tests = tests.filter(test => test).map(test => "#data\n" + test);
+ for (var test of tests) {
+ yield parseTestcase(test);
+ }
+ }
+}
+
+/**
+ * Transforms a DOM document to a string matching the format in
+ * the test cases.
+ *
+ * @param the DOM document
+ */
+function docToTestOutput(doc) {
+ var walker = doc.createTreeWalker(doc, NodeFilter.SHOW_ALL, null);
+ return addLevels(walker, "", "| ").slice(0,-1); // remove the last newline
+}
+
+/**
+ * Creates a walker for a fragment that skips over the root node.
+ *
+ * @param an element
+ */
+function createFragmentWalker(elt) {
+ return elt.ownerDocument.createTreeWalker(elt, NodeFilter.SHOW_ALL,
+ function (node) {
+ return elt == node ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_ACCEPT;
+ });
+}
+
+/**
+ * Transforms the descendants of an element to a string matching the format
+ * in the test cases.
+ *
+ * @param an element
+ */
+function fragmentToTestOutput(elt) {
+ var walker = createFragmentWalker(elt);
+ return addLevels(walker, "", "| ").slice(0,-1); // remove the last newline
+}
+
+function addLevels(walker, buf, indent) {
+ if(walker.firstChild()) {
+ do {
+ buf += indent;
+ switch (walker.currentNode.nodeType) {
+ case Node.ELEMENT_NODE:
+ buf += "<"
+ var ns = walker.currentNode.namespaceURI;
+ if ("http://www.w3.org/1998/Math/MathML" == ns) {
+ buf += "math ";
+ } else if ("http://www.w3.org/2000/svg" == ns) {
+ buf += "svg ";
+ } else if ("http://www.w3.org/1999/xhtml" != ns) {
+ buf += "otherns ";
+ }
+ buf += walker.currentNode.localName + ">";
+ if (walker.currentNode.hasAttributes()) {
+ var valuesByName = {};
+ var attrs = walker.currentNode.attributes;
+ for (var i = 0; i < attrs.length; ++i) {
+ var localName = attrs[i].localName;
+ var name;
+ var attrNs = attrs[i].namespaceURI;
+ if (null == attrNs) {
+ name = localName;
+ } else if ("http://www.w3.org/XML/1998/namespace" == attrNs) {
+ name = "xml " + localName;
+ } else if ("http://www.w3.org/1999/xlink" == attrNs) {
+ name = "xlink " + localName;
+ } else if ("http://www.w3.org/2000/xmlns/" == attrNs) {
+ name = "xmlns " + localName;
+ } else {
+ name = "otherns " + localName;
+ }
+ valuesByName[name] = attrs[i].value;
+ }
+ var keys = Object.keys(valuesByName).sort();
+ for (var i = 0; i < keys.length; ++i) {
+ buf += "\n" + indent + " " + keys[i] +
+ "=\"" + valuesByName[keys[i]] +"\"";
+ }
+ }
+ break;
+ case Node.DOCUMENT_TYPE_NODE:
+ buf += "<!DOCTYPE " + walker.currentNode.name;
+ if (walker.currentNode.publicId || walker.currentNode.systemId) {
+ buf += " \"";
+ buf += walker.currentNode.publicId;
+ buf += "\" \"";
+ buf += walker.currentNode.systemId;
+ buf += "\"";
+ }
+ buf += ">";
+ break;
+ case Node.COMMENT_NODE:
+ buf += "<!-- " + walker.currentNode.nodeValue + " -->";
+ break;
+ case Node.TEXT_NODE:
+ buf += "\"" + walker.currentNode.nodeValue + "\"";
+ break;
+ }
+ buf += "\n";
+ // In the case of template elements, children do not get inserted as
+ // children of the template element, instead they are inserted
+ // as children of the template content (which is a document fragment).
+ if (walker.currentNode instanceof HTMLTemplateElement) {
+ buf += indent + " content\n";
+ // Walk through the template content.
+ var templateWalker = createFragmentWalker(walker.currentNode.content);
+ buf = addLevels(templateWalker, buf, indent + " ");
+ }
+ buf = addLevels(walker, buf, indent + " ");
+ } while(walker.nextSibling());
+ walker.parentNode();
+ }
+ return buf;
+}
+
diff --git a/parser/htmlparser/tests/mochitest/parser_web_testrunner.js b/parser/htmlparser/tests/mochitest/parser_web_testrunner.js
new file mode 100644
index 000000000..9428a5394
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/parser_web_testrunner.js
@@ -0,0 +1,141 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Runs html5lib-formatted test cases in the browser. Requires SimpleTest.
+ *
+ * Define an array named parserDatFiles before loading this script,
+ * and it will load each of those dat files into an array, then run
+ * the test parser on each and run the tests by assigning the input
+ * data to an iframe's url.
+ *
+ * Your test document should have an element with id "display" and
+ * an iframe with id "testframe".
+ */
+
+var functionsToRunAsync = [];
+
+window.addEventListener("message", function(event) {
+ if (event.source == window && event.data == "async-run") {
+ event.stopPropagation();
+ var fn = functionsToRunAsync.shift();
+ fn();
+ }
+}, true);
+
+function asyncRun(fn) {
+ functionsToRunAsync.push(fn);
+ window.postMessage("async-run", "*");
+}
+
+function writeErrorSummary(input, expected, got, isTodo) {
+ if (isTodo) {
+ $("display").appendChild(createEl('h2', null, "Unexpected Success:"));
+ } else {
+ $("display").appendChild(createEl('h2', null, "Unexpected Failure:"));
+ }
+ $("display").appendChild(createEl('br'));
+ $("display").appendChild(createEl('span', null, "Matched: "));
+ $("display").appendChild(document.createTextNode("" + (expected == got)));
+ var pre = createEl('pre');
+ pre.appendChild(document.createTextNode("Input: \n" + input, "\n-\n"));
+ pre.appendChild(document.createTextNode("Expected:\n" + expected, "\n-\n"));
+ pre.appendChild(document.createTextNode("Output:\n" + got + "\n-\n"));
+ $("display").appendChild(pre);
+ $("display").appendChild(createEl('hr'));
+}
+
+/**
+ * Control will bounce back and forth between nextTest() and the
+ * event handler returned by makeTestChecker() or the callback returned by
+ * makeFragmentTestChecker() until the 'testcases' iterator is spent.
+ */
+function makeTestChecker(input, expected, errors) {
+ return function (e) {
+ var domAsString = docToTestOutput(e.target.contentDocument);
+ if (html5Exceptions[input]) {
+ todo_is(domAsString, expected, "HTML5 expected success.");
+ if (domAsString == expected) {
+ writeErrorSummary(input, expected, domAsString, true);
+ }
+ } else {
+ is(domAsString, expected, "HTML5 expected success.");
+ if (domAsString != expected) {
+ writeErrorSummary(input, expected, domAsString, false);
+ }
+ }
+ nextTest(e.target);
+ }
+}
+
+function makeFragmentTestChecker(input,
+ expected,
+ errors,
+ fragment,
+ testframe) {
+ return function () {
+ var context;
+ if (fragment.startsWith("svg ")) {
+ context = document.createElementNS("http://www.w3.org/2000/svg",
+ fragment.substring(4));
+ } else if (fragment.startsWith("math ")) {
+ context = document.createElementNS("http://www.w3.org/1998/Math/MathML",
+ fragment.substring(5));
+ } else {
+ context = document.createElementNS("http://www.w3.org/1999/xhtml",
+ fragment);
+ }
+ context.innerHTML = input;
+ var domAsString = fragmentToTestOutput(context);
+ is(domAsString, expected, "HTML5 expected success. " + new Date());
+ if (domAsString != expected) {
+ writeErrorSummary(input, expected, domAsString, false);
+ }
+ nextTest(testframe);
+ }
+}
+
+var testcases;
+function nextTest(testframe) {
+ var test = 0;
+ try {
+ var [input, output, errors, fragment] = testcases.next();
+ if (fragment) {
+ asyncRun(makeFragmentTestChecker(input,
+ output,
+ errors,
+ fragment,
+ testframe));
+ } else {
+ dataURL = "data:text/html;charset=utf-8," + encodeURIComponent(input);
+ testframe.onload = makeTestChecker(input, output, errors);
+ testframe.src = dataURL;
+ }
+ } catch (err if err instanceof StopIteration) {
+ SimpleTest.finish();
+ }
+}
+
+var testFileContents = [];
+function loadNextTestFile() {
+ var datFile = parserDatFiles.shift();
+ if (datFile) {
+ var xhr = new XMLHttpRequest();
+ xhr.onreadystatechange = function () {
+ if (this.readyState == 4) {
+ testFileContents.push(this.responseText);
+ loadNextTestFile();
+ }
+ };
+ xhr.open("GET", "html5lib_tree_construction/" + datFile);
+ xhr.send();
+ } else {
+ testcases = test_parser(testFileContents);
+ nextTest($("testframe"));
+ }
+}
+
+addLoadEvent(loadNextTestFile);
+SimpleTest.waitForExplicitFinish();
diff --git a/parser/htmlparser/tests/mochitest/test_bug102699.html b/parser/htmlparser/tests/mochitest/test_bug102699.html
new file mode 100644
index 000000000..3f454424c
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug102699.html
@@ -0,0 +1,75 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=102699
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 102699</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=102699">Mozilla Bug 102699</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 102699 **/
+
+SimpleTest.waitForExplicitFinish();
+
+var p = new DOMParser();
+
+var d = p.parseFromString(
+'<meta charset="windows-1252">' +
+'\u003cscript>' +
+'document.documentElement.setAttribute("data-fail", "FAIL");' +
+'\u003c/script>' +
+'\u003cscript src="http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug102699.sjs">\u003c/script>' +
+'\u003cscript src="http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug102699.sjs" defer>\u003c/script>' +
+'\u003cscript src="http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug102699.sjs" async>\u003c/script>' +
+'<link type="stylesheet" href="http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug102699.sjs">' +
+'<body onload=\'document.documentElement.setAttribute("data-fail", "FAIL");\'>' +
+'<img src="http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug102699.sjs">' +
+'<iframe src="http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug102699.sjs"></iframe>' +
+'<video poster="http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug102699.sjs" src="http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug102699.sjs"></video>' +
+'<object data="http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug102699.sjs"></object>' +
+'<noscript><div></div></noscript>"', "text/html");
+
+is(d.createElement("div").tagName, "DIV", "The created document should have HTML nature.");
+
+is(d.getElementsByTagName("div").length, 1, "There should be one div.");
+
+is(d.contentType, "text/html", "contentType should be text/html");
+
+is(d.characterSet, "UTF-8", "Expected the <meta> to be ignored.");
+
+is(d.compatMode, "BackCompat", "Should be in the quirks mode.");
+
+var scripts = d.getElementsByTagName("script");
+is(scripts.length, 4, "Unexpected number of scripts.");
+while (scripts.length) {
+ // These should not run when moved to another doc
+ document.body.appendChild(scripts[0]);
+}
+var s = document.createElement("script");
+s.src = "file_bug102699.sjs?report=1";
+document.body.appendChild(s);
+
+function continueAfterReport() {
+ ok(!d.documentElement.hasAttribute("data-fail"), "Should not have a data-fail attribute.");
+
+ d = p.parseFromString("<!DOCTYPE html>", "text/html");
+ is(d.compatMode, "CSS1Compat", "Should be in the standards mode.");
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug1104732.html b/parser/htmlparser/tests/mochitest/test_bug1104732.html
new file mode 100644
index 000000000..b9fba66ab
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug1104732.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1104732
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1104732</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1104732 **/
+
+ // Expected order of the values of the "state" variable:
+ // Test starting
+ // defer
+ // DOMContentLoaded
+ // load
+
+ // In the meantime, the async script load should happen before load.
+ // Ideally, we would want to assert that it happens after DOMContentLoaded,
+ // because it shouldn't be holding up DOMContentLoaded, but there is
+ // no *guarantee* that this is the case, so we cannot assert it.
+
+ var state = "Test starting";
+ var asyncState = "not loaded";
+ SimpleTest.waitForExplicitFinish();
+ is(document.readyState, "loading", "Document should have been loading.");
+ document.addEventListener("DOMContentLoaded", function () {
+ is(document.readyState, "interactive", "readyState should be interactive during DOMContentLoaded.");
+ is(state, "defer", "Bad state upon DOMContentLoaded");
+ state = "DOMContentLoaded";
+ // This doesn't work (see above), but we can't "todo" this assertion either, because
+ // it will sometimes be the case...
+ // isnot(asyncState, "loaded", "Async script should not have delayed domcontentloaded");
+ });
+ window.addEventListener("load", function () {
+ is(document.readyState, "complete", "readyState should be complete during load.");
+ is(state, "DOMContentLoaded", "Bad state upon load")
+ state = "load";
+ is(asyncState, "loaded", "Async script should be loaded upon document load event");
+ SimpleTest.finish();
+ });
+ </script>
+ <script defer src="file_defer_bug1104732.js"></script>
+ <script async src="file_async_bug1104732.sjs"></script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1104732">Mozilla Bug 1104732</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/test_bug1209658.html b/parser/htmlparser/tests/mochitest/test_bug1209658.html
new file mode 100644
index 000000000..f8704626b
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug1209658.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1209658
+-->
+<head>
+ <title>Test for Bug 1209658</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1209658">Mozilla Bug 1209658</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+addLoadEvent(function loaded() {
+ for (var iframe of document.querySelectorAll("iframe")) {
+ is(iframe.contentWindow.location.href, iframe.src, "should load correct URL");
+ is(iframe.contentDocument.body.textContent, '{"<p>Hello</p>": null}',
+ iframe.getAttribute("mimeType") + " should be treated as text");
+ }
+ SimpleTest.finish();
+});
+</script>
+<iframe src="data:text/json,{&quot;<p>Hello</p>&quot;:%20null}"
+ mimeType="text/json"></iframe>
+<!-- Totally not valid VTT data, but doesn't matter for our purposes here -->
+<iframe src="data:text/vtt,{&quot;<p>Hello</p>&quot;:%20null}"
+ mimeType="text/vtt"></iframe>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug174351.html b/parser/htmlparser/tests/mochitest/test_bug174351.html
new file mode 100644
index 000000000..3f9316752
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug174351.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=174351
+-->
+<head>
+ <title>Test for Bug 174351</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=174351">Mozilla Bug 174351</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+ var iframe = document.createElement('iframe');
+ iframe.src = "invalidchar.xml";
+ iframe.onload = function () {
+ var doc = document.getElementById('test').childNodes[1].contentDocument;
+ ok(doc.documentElement.tagName != "root", "Since XML has invalid enconding, must throw error");
+ };
+
+ document.getElementById('test').appendChild(iframe);
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/test_bug213517.html b/parser/htmlparser/tests/mochitest/test_bug213517.html
new file mode 100644
index 000000000..36174fd4c
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug213517.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=213517
+-->
+<head>
+ <meta charset="x-user-defined">
+ <title>Test for Bug 213517</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 213517 **/
+
+ is(document.characterSet, "windows-1252", "x-user-defined in <meta> should have gotten mapped to windows-1252");
+
+
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=213517">Mozilla Bug 213517</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug339350.xhtml b/parser/htmlparser/tests/mochitest/test_bug339350.xhtml
new file mode 100644
index 000000000..e443858d0
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug339350.xhtml
@@ -0,0 +1,60 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+Tests by Sam Ruby - WTFPL License (http://sam.zoy.org/wtfpl/)
+
+http://www.intertwingly.net/blog/2006/10/03/Firefox-XHTML-innerHTML-quirk#comments
+https://bugzilla.mozilla.org/show_bug.cgi?id=339350
+-->
+<head>
+ <!-- XHTML needs the packed version -->
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"/>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=339350">Mozilla Bug 339350</a>
+<div style="display: none">
+ <table border="1" cellspacing="0">
+ <thead>
+ <th></th>
+ <th>plain</th>
+ <th>brackets</th>
+ <th>braces</th>
+ </thead>
+
+ <tr>
+ <th>innerHTML</th>
+ <td><div id="i1"/></td>
+ <td style="background:yellow"><div id="i2"/></td>
+ <td><div id="i3"/></td>
+ </tr>
+ <tr>
+ <th>textNode</th>
+ <td><div id="t1"/></td>
+ <td><div id="t2"/></td>
+ <td><div id="t3"/></td>
+ </tr>
+ </table>
+</div>
+<pre id="test">
+<script type="text/javascript">
+var text1 = 'foo bar';
+var text2 = 'foo [bar]';
+var text3 = 'foo {bar}';
+
+<!-- This is the long way to write this stuff,
+ you can use MochiKit functions too -->
+document.getElementById('i1').innerHTML = text1;
+document.getElementById('i2').innerHTML = text2;
+document.getElementById('i3').innerHTML = text3;
+
+document.getElementById('t1').appendChild(document.createTextNode(text1));
+document.getElementById('t2').appendChild(document.createTextNode(text2));
+document.getElementById('t3').appendChild(document.createTextNode(text3));
+
+<!-- The is() function is one way to add a test -->
+is(document.getElementById('i2').innerHTML, text2, "XHTML innerHTML with trailing brackets ']]'");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug358797.html b/parser/htmlparser/tests/mochitest/test_bug358797.html
new file mode 100644
index 000000000..554f1c7e2
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug358797.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=358797
+-->
+<head>
+ <title>Test for Bug 358797</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=358797">Mozilla Bug 358797</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 358797 **/
+
+var range = document.createRange();
+range.selectNode(document.firstChild);
+var cf = range.createContextualFragment('<span></span>');
+ok(cf != null,
+ "range.createContextualFragment() should work when range node is DocType");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug396568.html b/parser/htmlparser/tests/mochitest/test_bug396568.html
new file mode 100644
index 000000000..08f210140
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug396568.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=396568
+-->
+<head>
+ <title>Test for Bug 396568</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <!--These script tags are part of the test, complete with indentation!-->
+ <script language="javascript"
+
+
+
+
+
+
+
+ type="text/javascript"></script>
+ <script language="javascript"
+ type="text/javascript"></script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=396568">Mozilla Bug 396568</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 396568 **/
+
+ var reached = false;
+ try {
+ noSuchIdentifier;
+ reached = true;
+ } catch (e) {
+ is(e.lineNumber, 36, "Unexpected line number"); //this line number is dependent on the line number of noSuchIdentifier
+ }
+ is(reached, false, "Exception needed to be thrown");
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/test_bug418464.html b/parser/htmlparser/tests/mochitest/test_bug418464.html
new file mode 100644
index 000000000..f960989fa
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug418464.html
@@ -0,0 +1,43 @@
+<form name="formGo" method="post">
+ <input type="hidden">
+</form>
+<script>
+ var form1 = document.formGo;
+</script>
+<form name="formGo2" method="post">
+ <input type="Hidden">
+</form>
+<script>
+ var form2 = document.formGo2;
+</script>
+ <!-- NOTE: The forms and scripts above this comment _must_ come first in this file-->
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=418464
+-->
+<head>
+ <title>Test for Bug 418464</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=418464">Mozilla Bug 418464</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 418464 **/
+ is(form1 instanceof HTMLFormElement, true,
+ "Should have a form here");
+ is(form2 instanceof HTMLFormElement, true,
+ "Should have a form here");
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/test_bug460437.xhtml b/parser/htmlparser/tests/mochitest/test_bug460437.xhtml
new file mode 100644
index 000000000..34e7fe720
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug460437.xhtml
@@ -0,0 +1,39 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=460437
+-->
+<head>
+ <title>Test for Bug 460437</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=460437">Mozilla Bug 460437</a>
+<p id="display"><b id="test460437">orig</b></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+<![CDATA[
+
+SimpleTest.expectAssertions(1);
+
+/** Test for Bug 460437 **/
+
+var s = '<i>invalid</i';
+try {
+ document.getElementById('test460437').innerHTML = s;
+} catch (e) {
+}
+is(document.getElementById('test460437').innerHTML, "", "setting invalid innerHTML should clear it");
+s = '<i>valid</i>';
+document.getElementById('test460437').innerHTML = s;
+is(document.getElementById('test460437').innerHTML, "<i xmlns=\"http://www.w3.org/1999/xhtml\">valid</i>", "failed to set valid innerHTML");
+
+
+]]>
+</script>
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug502091.html b/parser/htmlparser/tests/mochitest/test_bug502091.html
new file mode 100644
index 000000000..f213c01d0
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug502091.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=502091
+
+Adding a <meta> element by writing to innerHTML should work correctly.
+-->
+<head>
+ <title>Test for Bug 502091</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=502091">Mozilla Bug 502091</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<div id="test">
+<script class="testbody" type="text/javascript">
+ function $(id) { return document.getElementById(id); }
+
+ var iframe=document.createElement("iframe");
+ iframe.setAttribute("id", "iframe");
+ iframe.src = "bug_502091_iframe.html";
+ iframe.onload = function () {
+ var div = $("iframe").contentDocument.getElementById("testdiv");
+ var meta = div.getElementsByTagName("meta");
+ is(meta.length, 1, "meta element not added to div");
+ };
+ $("test").appendChild(iframe);
+
+</script>
+</div>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/test_bug534293.html b/parser/htmlparser/tests/mochitest/test_bug534293.html
new file mode 100644
index 000000000..dbf6309f8
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug534293.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=534293
+-->
+<head>
+ <title>Test for Bug 534293</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug534293-slow.sjs"></script>
+ <base href="dir_bug534293/">
+ <script src="file_bug534293.sjs"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=534293">Mozilla Bug 534293</a>
+
+<script src="http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug534293.sjs?report=1"></script>
+<script src="http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/dir_bug534293/file_bug534293.sjs?report=1"></script>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/test_bug543062.html b/parser/htmlparser/tests/mochitest/test_bug543062.html
new file mode 100644
index 000000000..bb3f91e20
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug543062.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=543062
+-->
+<head>
+ <title>Test for Bug 543062</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=543062">Mozilla Bug 543062</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+document.write("\u003Cscript src='file_bug543062.sjs?first'>\u003C/script>\u003Cscript src='file_bug543062.sjs?second'>\u003C/script>");
+document.write("\u003Cscript src='file_bug543062.sjs?third'>\u003C/script>");
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/test_bug552938-2.html b/parser/htmlparser/tests/mochitest/test_bug552938-2.html
new file mode 100644
index 000000000..7477cdd77
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug552938-2.html
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=552938
+-->
+<head>
+ <title>Test for Bug 552938</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload='runTest();'>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=552938">Mozilla Bug 552938</a>
+<script>
+var svgLoadFired = false;
+</script>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <svg>
+ <script>
+ document.getElementsByTagName("svg")[0].addEventListener("SVGLoad",
+ function() { svgLoadFired = true; }, false);
+ </script>
+ </svg>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 552938 **/
+function runTest() {
+ ok(svgLoadFired, "The SVG load event should have fired.");
+ SimpleTest.finish();
+}
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug552938.html b/parser/htmlparser/tests/mochitest/test_bug552938.html
new file mode 100644
index 000000000..4391d4890
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug552938.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=552938
+-->
+<head>
+ <title>Test for Bug 552938</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload='runTest();'>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=552938">Mozilla Bug 552938</a>
+<script>
+var svgLoadFired = false;
+</script>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <svg onload="svgLoadFired = true;"></svg>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 552938 **/
+function runTest() {
+ ok(svgLoadFired, "The SVG load event should have fired.");
+ SimpleTest.finish();
+}
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug563322.xhtml b/parser/htmlparser/tests/mochitest/test_bug563322.xhtml
new file mode 100644
index 000000000..42bc6806e
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug563322.xhtml
@@ -0,0 +1,33 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=563322
+-->
+<head>
+ <title>Test for Bug 563322</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=563322">Mozilla Bug 563322</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+<![CDATA[
+
+/** Test for Bug 563322 **/
+
+var div = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
+div.innerHTML = "<script>ok(false, 'Script ran but should not have')</script><script>ok(false, 'Script ran but should not have')</script>"
+
+document.getElementById("content").appendChild(div);
+
+ok(true, "Keep the harness happy");
+
+]]>
+</script>
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug566879.html b/parser/htmlparser/tests/mochitest/test_bug566879.html
new file mode 100644
index 000000000..8fe2d0349
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug566879.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=566879
+-->
+<head>
+ <title>Test for Bug 566879</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload='runTest();'>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=566879">Mozilla Bug 566879</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<form>
+<input type=text id=textfield name=textfield>
+<input type=checkbox id=checkbox name=checkbox>
+<input type=radio id=radio1 name=radio>
+<input type=radio id=radio2 name=radio>
+<textarea name=textarea id=textarea></textarea>
+<select name=select id=select>
+<option value=foo>Foo</option>
+<option value=bar selected>Bar</option>
+</select>
+</form>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+function runTest() {
+ initialState = document.getElementById('content').innerHTML;
+ document.getElementById('textfield').value = "foo";
+ document.getElementById('checkbox').checked = true;
+ document.getElementById('radio2').checked = true;
+ document.getElementById('textarea').value = "foo";
+ document.getElementById('select').value = "foo";
+ setTimeout(continuation1, 1);
+}
+
+function continuation1() {
+ document.getElementById('content').innerHTML = initialState;
+ setTimeout(continuation2, 1);
+}
+
+function continuation2() {
+ is(document.getElementById('textfield').value, "", "The text field should have gone back to its initial state.");
+ ok(!document.getElementById('checkbox').checked, "The checkbox should have gone back to its initial state.");
+ ok(!document.getElementById('radio2').checked, "The second radio button should have gone back to its initial state.");
+ is(document.getElementById('textarea').value, "", "The text area should have gone back to its initial state.");
+ is(document.getElementById('select').value, "bar", "The select should have gone back to its initial state.");
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/test_bug568470.html b/parser/htmlparser/tests/mochitest/test_bug568470.html
new file mode 100644
index 000000000..01801de1f
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug568470.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=568470
+-->
+<head>
+ <title>Test for Bug 568470</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=568470">Mozilla Bug 568470</a>
+<p id="display"></p>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 568470 **/
+SimpleTest.waitForExplicitFinish();
+
+// assuming the test runs in less than a year...
+var time = new Date().getTime() + 1000*60*60*24*365;
+
+var interval = setInterval(function() {
+ var iframe = document.getElementsByTagName("iframe")[0];
+ if (iframe) {
+ var doc = iframe.contentDocument;
+ if (doc) {
+ if (doc.getElementById("flushable")) {
+ time = new Date();
+ clearInterval(interval);
+ }
+ }
+ }
+}, 25);
+
+function finish() {
+ clearInterval(interval);
+ var elapsed = new Date().getTime() - time;
+ ok(elapsed > 350,
+ "Content flush time and parse end time not enough apart.");
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+<div id="content" style="display: none">
+ <iframe onload="finish();" src="file_bug568470.sjs"></iframe>
+</div>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/test_bug594730.html b/parser/htmlparser/tests/mochitest/test_bug594730.html
new file mode 100644
index 000000000..8d2cdf5e8
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug594730.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=594730
+-->
+<head>
+ <title>Test for Bug 594730</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=594730">Mozilla Bug 594730</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe src=file_bug594730-1.html></iframe>
+<iframe src=file_bug594730-2.html></iframe>
+<iframe src=file_bug594730-3.html></iframe>
+<iframe src=file_bug594730-4.html></iframe>
+<iframe src=file_bug594730-5.html></iframe>
+<iframe src=file_bug594730-6.html></iframe>
+<iframe src=file_bug594730-7.html></iframe>
+<iframe src=file_bug594730-8.html></iframe>
+<iframe src=file_bug594730-9.html></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/test_bug599584.html b/parser/htmlparser/tests/mochitest/test_bug599584.html
new file mode 100644
index 000000000..ea79a5a68
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug599584.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=599584
+-->
+<head>
+ <title>Test for Bug 599584</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=599584">Mozilla Bug 599584</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <iframe src="iframe_bug599584.html"></iframe>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 599584 **/
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+var alreadyRan = false;
+
+function startTest() {
+ if (alreadyRan) {
+ // Make the test finish only once when it fails.
+ return;
+ }
+ alreadyRan = true;
+ setTimeout(function () {
+ var iframe = document.getElementsByTagName("iframe")[0];
+ is(iframe.contentWindow.location.search, "", "Should not have navigated with query string.");
+ SimpleTest.finish();
+ }, 1500);
+}
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/test_bug613662.html b/parser/htmlparser/tests/mochitest/test_bug613662.html
new file mode 100644
index 000000000..608db5f2e
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug613662.html
@@ -0,0 +1,132 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=613662
+-->
+<head>
+ <title>Test for Bug 613662</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=613662">Mozilla Bug 613662</a>
+<p id="display"></p><div id="content" style="display: none"></div><div id="content2" style="display: none"></div><pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 613662 **/
+
+function testPositions(node) {
+ node.insertAdjacentHTML("beforeBegin", "\u003Cscript>ok(false, 'script should not have run');\u003C/script><i></i>");
+ is(node.previousSibling.localName, "i", "Should have had <i> as previous sibling");
+ node.insertAdjacentHTML("Afterbegin", "<b></b>\u003Cscript>ok(false, 'script should not have run');\u003C/script>");
+ is(node.firstChild.localName, "b", "Should have had <b> as first child");
+ node.insertAdjacentHTML("BeforeEnd", "\u003Cscript>ok(false, 'script should not have run');\u003C/script><u></u>");
+ is(node.lastChild.localName, "u", "Should have had <u> as last child");
+ node.insertAdjacentHTML("afterend", "<a></a>\u003Cscript>ok(false, 'script should not have run');\u003C/script>");
+ is(node.nextSibling.localName, "a", "Should have had <a> as next sibling");
+}
+
+var content = document.getElementById("content");
+testPositions(content); // without next sibling
+testPositions(content); // test again when there's next sibling
+
+try {
+ content.insertAdjacentHTML("bar", "foo");
+ ok(false, "insertAdjacentHTML should have thrown");
+} catch (e) {
+ is(e.name, "SyntaxError", "insertAdjacentHTML should throw SyntaxError");
+ is(e.code, 12, "insertAdjacentHTML should throw SYNTAX_ERR");
+}
+
+var parent = document.createElement("div");
+var child = document.createElement("div");
+
+try {
+ child.insertAdjacentHTML("Beforebegin", "foo");
+ ok(false, "insertAdjacentHTML should have thrown");
+} catch (e) {
+ is(e.name, "NoModificationAllowedError", "insertAdjacentHTML should throw NoModificationAllowedError");
+ is(e.code, 7, "insertAdjacentHTML should throw NO_MODIFICATION_ALLOWED_ERR");
+}
+
+try {
+ child.insertAdjacentHTML("AfterEnd", "foo");
+ ok(false, "insertAdjacentHTML should have thrown");
+} catch (e) {
+ is(e.name, "NoModificationAllowedError", "insertAdjacentHTML should throw NoModificationAllowedError");
+ is(e.code, 7, "insertAdjacentHTML should throw NO_MODIFICATION_ALLOWED_ERR");
+}
+
+child.insertAdjacentHTML("afterBegin", "foo"); // mustn't throw
+child.insertAdjacentHTML("beforeend", "foo"); // mustn't throw
+
+parent.appendChild(child);
+testPositions(child); // node not in tree but has parent
+
+content.appendChild(parent); // must not run scripts
+
+try {
+ document.documentElement.insertAdjacentHTML("afterend", "<div></div>");
+ ok(false, "insertAdjacentHTML should have thrown");
+} catch (e) {
+ is(e.name, "NoModificationAllowedError", "insertAdjacentHTML should throw NoModificationAllowedError");
+ is(e.code, 7, "insertAdjacentHTML should throw NO_MODIFICATION_ALLOWED_ERR");
+}
+
+var content2 = document.getElementById("content2");
+
+var events = [
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMSubtreeModified", null ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMSubtreeModified", null ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMSubtreeModified", null ],
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMSubtreeModified", null ],
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMSubtreeModified", null ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMSubtreeModified", null ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMSubtreeModified", null ],
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMSubtreeModified", null ]
+];
+
+function mutationEventListener(evt) {
+ var expected = events.shift();
+ is(evt.type, expected[0], "Unexpected mutation type");
+ is(evt.relatedNode, expected[1], "Unexpected related node");
+}
+/*
+document.addEventListener("DOMSubtreeModified", mutationEventListener, false);
+document.addEventListener("DOMNodeInserted", mutationEventListener, false);
+document.addEventListener("DOMNodeRemoved", mutationEventListener, false);
+document.addEventListener("DOMNodeRemovedFromDocument", mutationEventListener, false);
+document.addEventListener("DOMNodeInsertedIntoDocument", mutationEventListener, false);
+document.addEventListener("DOMAttrModified", mutationEventListener, false);
+document.addEventListener("DOMCharacterDataModified", mutationEventListener, false);
+
+testPositions(content2); // without next sibling
+testPositions(content2); // test again when there's next sibling
+
+is(events.length, 0, "Not all expected events fired.");
+*/
+// HTML only
+document.body.insertAdjacentHTML("afterend", "<p>");
+document.head.insertAdjacentHTML("beforebegin", "<p>");
+is(document.getElementsByTagName("head").length, 1, "Should still have one head");
+is(document.getElementsByTagName("body").length, 1, "Should still have one body");
+
+</script>
+</pre>
+</body></html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug613662.xhtml b/parser/htmlparser/tests/mochitest/test_bug613662.xhtml
new file mode 100644
index 000000000..1c44f88fb
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug613662.xhtml
@@ -0,0 +1,137 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=613662
+-->
+<head>
+ <title>Test for Bug 613662</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=613662">Mozilla Bug 613662</a>
+<p id="display"></p><div id="content" style="display: none"></div><div id="content2" style="display: none"></div><pre id="test">
+<script type="application/javascript"><![CDATA[
+
+SimpleTest.expectAssertions(1);
+
+/** Test for Bug 613662 **/
+
+function testPositions(node) {
+ node.insertAdjacentHTML("beforeBegin", "\u003Cscript>ok(false, 'script should not have run');\u003C/script><i></i>");
+ is(node.previousSibling.localName, "i", "Should have had <i> as previous sibling");
+ node.insertAdjacentHTML("Afterbegin", "<b></b>\u003Cscript>ok(false, 'script should not have run');\u003C/script>");
+ is(node.firstChild.localName, "b", "Should have had <b> as first child");
+ node.insertAdjacentHTML("BeforeEnd", "\u003Cscript>ok(false, 'script should not have run');\u003C/script><u></u>");
+ is(node.lastChild.localName, "u", "Should have had <u> as last child");
+ node.insertAdjacentHTML("afterend", "<a></a>\u003Cscript>ok(false, 'script should not have run');\u003C/script>");
+ is(node.nextSibling.localName, "a", "Should have had <a> as next sibling");
+}
+
+var content = document.getElementById("content");
+testPositions(content); // without next sibling
+testPositions(content); // test again when there's next sibling
+
+try {
+ content.insertAdjacentHTML("bar", "foo");
+ ok(false, "insertAdjacentHTML should have thrown");
+} catch (e) {
+ is(e.name, "SyntaxError", "insertAdjacentHTML should throw SyntaxError");
+ is(e.code, 12, "insertAdjacentHTML should throw SYNTAX_ERR");
+}
+
+var parent = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
+var child = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
+
+try {
+ child.insertAdjacentHTML("Beforebegin", "foo");
+ ok(false, "insertAdjacentHTML should have thrown");
+} catch (e) {
+ is(e.name, "NoModificationAllowedError", "insertAdjacentHTML should throw NoModificationAllowedError");
+ is(e.code, 7, "insertAdjacentHTML should throw NO_MODIFICATION_ALLOWED_ERR");
+}
+
+try {
+ child.insertAdjacentHTML("AfterEnd", "foo");
+ ok(false, "insertAdjacentHTML should have thrown");
+} catch (e) {
+ is(e.name, "NoModificationAllowedError", "insertAdjacentHTML should throw NoModificationAllowedError");
+ is(e.code, 7, "insertAdjacentHTML should throw NO_MODIFICATION_ALLOWED_ERR");
+}
+
+child.insertAdjacentHTML("afterBegin", "foo"); // mustn't throw
+child.insertAdjacentHTML("beforeend", "foo"); // mustn't throw
+
+parent.appendChild(child);
+testPositions(child); // node not in tree but has parent
+
+content.appendChild(parent); // must not run scripts
+
+try {
+ document.documentElement.insertAdjacentHTML("afterend", "<div></div>");
+ ok(false, "insertAdjacentHTML should have thrown");
+} catch (e) {
+ is(e.name, "NoModificationAllowedError", "insertAdjacentHTML should throw NoModificationAllowedError");
+ is(e.code, 7, "insertAdjacentHTML should throw NO_MODIFICATION_ALLOWED_ERR");
+}
+
+var content2 = document.getElementById("content2");
+
+var events = [
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMSubtreeModified", null ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMSubtreeModified", null ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMSubtreeModified", null ],
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMSubtreeModified", null ],
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMSubtreeModified", null ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMSubtreeModified", null ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMNodeInserted", content2 ],
+ [ "DOMSubtreeModified", null ],
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMNodeInserted", document.body ],
+ [ "DOMSubtreeModified", null ]
+];
+
+function mutationEventListener(evt) {
+ var expected = events.shift();
+ is(evt.type, expected[0], "Unexpected mutation type");
+ is(evt.relatedNode, expected[1], "Unexpected related node");
+}
+
+document.addEventListener("DOMSubtreeModified", mutationEventListener, false);
+document.addEventListener("DOMNodeInserted", mutationEventListener, false);
+document.addEventListener("DOMNodeRemoved", mutationEventListener, false);
+document.addEventListener("DOMNodeRemovedFromDocument", mutationEventListener, false);
+document.addEventListener("DOMNodeInsertedIntoDocument", mutationEventListener, false);
+document.addEventListener("DOMAttrModified", mutationEventListener, false);
+document.addEventListener("DOMCharacterDataModified", mutationEventListener, false);
+
+testPositions(content2); // without next sibling
+testPositions(content2); // test again when there's next sibling
+
+is(events.length, 0, "Not all expected events fired.");
+
+// XML-only:
+try {
+ content.insertAdjacentHTML("beforeend", "<p>");
+ ok(false, "insertAdjacentHTML should have thrown");
+} catch (e) {
+ is(e.name, "SyntaxError", "insertAdjacentHTML should throw SyntaxError");
+ is(e.code, 12, "insertAdjacentHTML should throw SYNTAX_ERR");
+}
+
+]]></script>
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug639362.html b/parser/htmlparser/tests/mochitest/test_bug639362.html
new file mode 100644
index 000000000..6b4921d49
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug639362.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=639362
+-->
+<head>
+ <title>Test for Bug 639362</title>
+ <script type="application/javascript" src="/MochiKit/packed.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=639362">Mozilla Bug 639362</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+function loaded(iframe) {
+ is(iframe.contentWindow.location.href, iframe.src, "should load correct URL");
+ is(iframe.contentDocument.body.textContent, 'CACHE MANIFEST', "text/cache-manifest should be treated as text");
+ SimpleTest.finish();
+}
+</script>
+<iframe src="data:text/cache-manifest,CACHE MANIFEST" onload="loaded(this);"></iframe>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug642908.html b/parser/htmlparser/tests/mochitest/test_bug642908.html
new file mode 100644
index 000000000..97a6fc124
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug642908.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=642908
+-->
+<head>
+ <title>Test for Bug 642908</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="loaded();">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=642908">Mozilla Bug 642908</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+document.write("\u003Cscript src='data:text/javascript,1;'>\u003C/script>");
+document.write("<noscript><img src='file_bug642908.sjs'></noscript>");
+
+function loaded() {
+ var s = document.createElement("script");
+ s.src = "file_bug642908.sjs?report=1";
+ document.body.appendChild(s);
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug645115.html b/parser/htmlparser/tests/mochitest/test_bug645115.html
new file mode 100644
index 000000000..2d02e84f9
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug645115.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=645115
+-->
+<head>
+ <title>Test for Bug 645115</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=645115">Mozilla Bug 645115</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 645115 **/
+var div = document.createElement("div");
+div.innerHTML = "\u003Cscript>ok(false, 'innerHTML script ran');\u003C/script>\u003Cscript>";
+document.getElementById("content").appendChild(div);
+
+ok(true, "Keep the test harness happy.");
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/test_bug655682.html b/parser/htmlparser/tests/mochitest/test_bug655682.html
new file mode 100644
index 000000000..e90967a61
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug655682.html
@@ -0,0 +1,80 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=655682
+-->
+<head>
+ <title>Test for Bug 655682</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=655682">Mozilla Bug 655682</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <iframe src=file_bug655682.sjs></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 655682 **/
+
+var gotOnload = false;
+var finishedTesting = false;
+
+function tryFinishTest() {
+ if (gotOnload && finishedTesting) {
+ SimpleTest.finish();
+ }
+}
+
+addLoadEvent(function() {
+ // Hit the event loop again just to make sure that we're not ending the test
+ // before all activity we care about is done.
+ SimpleTest.executeSoon(function() {
+ gotOnload = true;
+ tryFinishTest();
+ });
+});
+
+var tdsSeen = 0;
+
+var triggeredSecondTd = false;
+
+var iframe = document.getElementsByTagName("iframe")[0];
+
+SimpleTest.waitForExplicitFinish();
+
+function probe() {
+ var tds = iframe.contentDocument.getElementsByTagName("td").length;
+ switch (tds) {
+ case 0:
+ setTimeout(probe, 0);
+ return;
+ case 1:
+ tdsSeen = tds;
+ if (!triggeredSecondTd) {
+ triggeredSecondTd = true;
+ var script = document.createElement("script");
+ script.src = "file_bug655682.sjs?trigger=1";
+ document.head.appendChild(script);
+ }
+ setTimeout(probe, 0);
+ return;
+ case 2:
+ is(tdsSeen, 1, "Should have seen one td before seeing two.");
+ finishedTesting = true;
+ tryFinishTest();
+ return;
+ default:
+ ok(false, "Wrong number of tds");
+ SimpleTest.finish();
+ }
+}
+
+setTimeout(probe, 0);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug667533.html b/parser/htmlparser/tests/mochitest/test_bug667533.html
new file mode 100644
index 000000000..c5b24394e
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug667533.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=667533
+-->
+<head>
+ <title>Test for Bug 667533</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=667533">Mozilla Bug 667533</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+function loaded(iframe) {
+ is(iframe.contentWindow.location.href, iframe.src, "should load correct URL");
+ is(iframe.contentDocument.body.textContent, '{"<p>Hello</p>": null}', "application/json should be treated as text");
+ SimpleTest.finish();
+}
+</script>
+<iframe src="data:application/json,{&quot;<p>Hello</p>&quot;:%20null}" onload="loaded(this);"></iframe>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug672453.html b/parser/htmlparser/tests/mochitest/test_bug672453.html
new file mode 100644
index 000000000..a0fb43682
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug672453.html
@@ -0,0 +1,100 @@
+<!doctype html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=672453
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 672453</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=672453"
+ >Mozilla Bug 672453</a>
+<iframe></iframe>
+<script>
+/** Test for Bug 672453 **/
+
+var tests = [
+ "file_bug672453_not_declared.html",
+ "file_bug672453_late_meta.html",
+ "file_bug672453_meta_restart.html",
+ "file_bug672453_meta_unsupported.html",
+ "file_bug672453_http_unsupported.html",
+ "file_bug672453_bomless_utf16.html",
+ "file_bug672453_meta_utf16.html",
+ "file_bug672453_meta_non_superset.html",
+ "file_bug672453_meta_userdefined.html",
+];
+
+var expectedErrors = [
+ { errorMessage: "The character encoding of a framed document was not declared. The document may appear different if viewed without the document framing it.",
+ sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_not_declared.html",
+ lineNumber: 0,
+ isWarning: true,
+ isException: false },
+ { errorMessage: "The character encoding declaration of the framed HTML document was not found when prescanning the first 1024 bytes of the file. When viewed without the document framing it, the page will reload automatically. The encoding declaration needs to be moved to be within the first 1024 bytes of the file.",
+ sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_late_meta.html",
+ lineNumber: 1028,
+ isWarning: true,
+ isException: false },
+ { errorMessage: "The page was reloaded, because the character encoding declaration of the HTML document was not found when prescanning the first 1024 bytes of the file. The encoding declaration needs to be moved to be within the first 1024 bytes of the file.",
+ sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_meta_restart.html",
+ lineNumber: 1028,
+ isWarning: true,
+ isException: false },
+ { errorMessage: "An unsupported character encoding was declared for the HTML document using a meta tag. The declaration was ignored.",
+ sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_meta_unsupported.html",
+ lineNumber: 1,
+ isWarning: false,
+ isException: false },
+ { errorMessage: "An unsupported character encoding was declared on the transfer protocol level. The declaration was ignored.",
+ sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html",
+ lineNumber: 0,
+ isWarning: false,
+ isException: false },
+ { errorMessage: "Detected UTF-16-encoded Basic Latin-only text without a byte order mark and without a transfer protocol-level declaration. Encoding this content in UTF-16 is inefficient and the character encoding should have been declared in any case.",
+ sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_bomless_utf16.html",
+ lineNumber: 0,
+ isWarning: false,
+ isException: false },
+ { errorMessage: "A meta tag was used to declare the character encoding as UTF-16. This was interpreted as an UTF-8 declaration instead.",
+ sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_meta_utf16.html",
+ lineNumber: 1,
+ isWarning: false,
+ isException: false },
+ { errorMessage: "An unsupported character encoding was declared for the HTML document using a meta tag. The declaration was ignored.",
+ sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_meta_non_superset.html",
+ lineNumber: 1,
+ isWarning: false,
+ isException: false },
+ { errorMessage: "A meta tag was used to declare the character encoding as x-user-defined. This was interpreted as a windows-1252 declaration instead for compatibility with intentionally mis-encoded legacy fonts. This site should migrate to Unicode.",
+ sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_meta_userdefined.html",
+ lineNumber: 1,
+ isWarning: false,
+ isException: false },
+];
+
+SimpleTest.waitForExplicitFinish();
+
+window.onload = function() {
+ var iframe = document.getElementsByTagName("iframe")[0];
+
+ function runNextTest() {
+ var url = tests.shift();
+ if (!url) {
+ SimpleTest.endMonitorConsole();
+ return;
+ }
+ iframe.src = url;
+ }
+ iframe.onload = runNextTest;
+
+ SimpleTest.monitorConsole(SimpleTest.finish, expectedErrors);
+ runNextTest();
+}
+</script>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug688580.html b/parser/htmlparser/tests/mochitest/test_bug688580.html
new file mode 100644
index 000000000..8bc75a892
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug688580.html
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=688580
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 688580</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 688580 **/
+
+ // Expected order:
+ // Test starting
+ // readyState interactive
+ // defer
+ // DOMContentLoaded
+ // readyState complete
+ // load
+
+ var state = "Test starting";
+ var readyStateCall = 0;
+ SimpleTest.waitForExplicitFinish();
+ is(document.readyState, "loading", "Document should have been loading.");
+ document.addEventListener("DOMContentLoaded", function () {
+ is(document.readyState, "interactive", "readyState should be interactive during DOMContentLoaded.");
+ is(state, "defer", "Bad state upon DOMContentLoaded");
+ state = "DOMContentLoaded";
+ });
+ document.addEventListener("readystatechange", function () {
+ readyStateCall++;
+ if (readyStateCall == 1) {
+ is(document.readyState, "interactive", "readyState should have changed to interactive.");
+ is(state, "Test starting", "Bad state upon first readystatechange.");
+ state = "readyState interactive";
+ } else if (readyStateCall == 2) {
+ is(document.readyState, "complete", "readyState should have changed to complete.");
+ is(state, "DOMContentLoaded", "Bad state upon second readystatechange.");
+ state = "readyState complete";
+ } else {
+ ok(false, "Too many readystatechanges");
+ }
+ });
+ window.addEventListener("load", function () {
+ is(document.readyState, "complete", "readyState should be complete during load.");
+ is(state, "readyState complete", "Bad state upon load")
+ state = "load";
+ SimpleTest.finish();
+ });
+ </script>
+ <script defer src="file_bug688580.js"></script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=688580">Mozilla Bug 688580</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug688580.xhtml b/parser/htmlparser/tests/mochitest/test_bug688580.xhtml
new file mode 100644
index 000000000..1301376f2
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug688580.xhtml
@@ -0,0 +1,62 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=688580
+-->
+<head>
+ <title>Test for Bug 688580</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 688580 **/
+
+ // Expected order:
+ // Test starting
+ // readyState interactive
+ // defer
+ // DOMContentLoaded
+ // readyState complete
+ // load
+
+ var state = "Test starting";
+ var readyStateCall = 0;
+ SimpleTest.waitForExplicitFinish();
+ is(document.readyState, "loading", "Document should have been loading.");
+ document.addEventListener("DOMContentLoaded", function () {
+ is(document.readyState, "interactive", "readyState should be interactive during DOMContentLoaded.");
+ is(state, "defer", "Bad state upon DOMContentLoaded");
+ state = "DOMContentLoaded";
+ });
+ document.addEventListener("readystatechange", function () {
+ readyStateCall++;
+ if (readyStateCall == 1) {
+ is(document.readyState, "interactive", "readyState should have changed to interactive.");
+ is(state, "Test starting", "Bad state upon first readystatechange.");
+ state = "readyState interactive";
+ } else if (readyStateCall == 2) {
+ is(document.readyState, "complete", "readyState should have changed to complete.");
+ is(state, "DOMContentLoaded", "Bad state upon second readystatechange.");
+ state = "readyState complete";
+ } else {
+ ok(false, "Too many readystatechanges");
+ }
+ });
+ window.addEventListener("load", function () {
+ is(document.readyState, "complete", "readyState should be complete during load.");
+ is(state, "readyState complete", "Bad state upon load")
+ state = "load";
+ SimpleTest.finish();
+ });
+ </script>
+ <script defer="" src="file_bug688580.js"></script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=688580">Mozilla Bug 688580</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug709083.html b/parser/htmlparser/tests/mochitest/test_bug709083.html
new file mode 100644
index 000000000..a5d24ba02
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug709083.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=709083
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 709083</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=709083">Mozilla Bug 709083</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<video muted>
+<script type="application/javascript">
+
+/** Test for Bug 709083 **/
+
+ok(document.getElementsByTagName("video")[0].muted, "Should be muted already.");
+
+</script>
+</video>
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug715112.html b/parser/htmlparser/tests/mochitest/test_bug715112.html
new file mode 100644
index 000000000..425f2e33f
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug715112.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=715112
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 715112</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=715112">Mozilla Bug 715112</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 715112 **/
+
+SimpleTest.waitForExplicitFinish();
+
+var expected = [
+ "First",
+ "Second",
+];
+
+function log(str) {
+ is(str, expected.shift(), "Unexpected log string.");
+}
+
+var w = window.open();
+w.document.open();
+w.document.addEventListener("DOMContentLoaded", function() {
+ is(expected.length, 0, "Not all expected messages were logged.");
+ is(w.document.getElementsByTagName("script").length, 3, "The document should have 3 scripts.");
+ w.close();
+ SimpleTest.finish();
+});
+w.document.write("\u003cscript>opener.log('First');\u003c/script>");
+w.document.write("\u003cscript>document.close();\u003c/script>");
+w.document.write("\u003cscript>opener.log('Second');\u003c/script>");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug715739.html b/parser/htmlparser/tests/mochitest/test_bug715739.html
new file mode 100644
index 000000000..597160a19
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug715739.html
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=715739
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 715739</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="tick()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=715739">Mozilla Bug 715739</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 715739 **/
+
+SimpleTest.waitForExplicitFinish();
+
+var runNumber = 0;
+
+function textChildren(node) {
+ var s = "";
+ var n = node.firstChild;
+ while (n) {
+ if (n.nodeType == Node.TEXT_NODE) {
+ s += n.nodeValue;
+ }
+ n = n.nextSibling;
+ }
+ return s;
+}
+
+function tick() {
+ runNumber++;
+ var f = document.getElementsByTagName("iframe")[0];
+ var d = f.contentDocument;
+
+ if (runNumber == 1) {
+ d.open();
+ f.addEventListener("load", tick);
+ d.write("X");
+ d.write("\u003cscript>document.write('Y');\u003c/script>");
+ d.write("Z");
+ d.close();
+ return;
+ }
+
+ if (runNumber == 2) {
+ var text = textChildren(d.body);
+ is(text, "XYZ", "Wrong text before reload.");
+ f.contentWindow.location.reload();
+ return;
+ }
+
+ if (runNumber == 3) {
+ var text = textChildren(d.body);
+ is(text, "XYZ", "Wrong text after reload.");
+ SimpleTest.finish();
+ return;
+ }
+}
+
+</script>
+</pre>
+<div id="content" style="display: none">
+ <iframe></iframe>
+</div>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug716579.html b/parser/htmlparser/tests/mochitest/test_bug716579.html
new file mode 100644
index 000000000..6baa7d6ed
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug716579.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=716579
+-->
+<head>
+ <meta charset="windows-1251">
+ <title>Test for Bug 716579</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=716579">Mozilla Bug 716579</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 716579 **/
+
+var html8 = "FAIL";
+var html16 = "FAIL";
+var xml8 = "FAIL";
+var xml16 = "FAIL";
+
+SimpleTest.waitForExplicitFinish();
+
+window.onload = function() {
+ is(html8, "\u20AC", "HTML UTF-8 failed.");
+ is(html16, "\u20AC", "HTML UTF-16 failed.");
+ is(xml8, "\u20AC", "XML UTF-8 failed.");
+ is(xml16, "\u20AC", "XML UTF-16 failed.");
+ SimpleTest.finish();
+};
+
+</script>
+</pre>
+<div id="content" style="display: none">
+<iframe src="file_bug716579-8.html"></iframe>
+<iframe src="file_bug716579-16.html"></iframe>
+<iframe src="file_bug716579-8.xhtml"></iframe>
+<iframe src="file_bug716579-16.xhtml"></iframe>
+</div>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_bug717180.html b/parser/htmlparser/tests/mochitest/test_bug717180.html
new file mode 100644
index 000000000..13e61b223
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug717180.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=717180
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 717180</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717180">Mozilla Bug 717180</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <iframe></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 717180 **/
+
+SimpleTest.waitForExplicitFinish();
+
+window.addEventListener("load", function () {
+ var iframe = document.getElementsByTagName("iframe")[0];
+ var d = iframe.contentDocument;
+ d.open();
+ iframe.addEventListener("load", function() {
+ is(iframe.contentDocument.body.textContent, "SUCCESS\n", "Wrong text");
+ SimpleTest.finish();
+ });
+ d.write("\u003Cscript>");
+ d.write("window.location = 'file_bug717180.html';")
+ d.write("\u003C/script>");
+ d.write("FAIL");
+ d.close();
+ is(iframe.contentDocument.body, null, "The document should not have a body right now.");
+});
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_compatmode.html b/parser/htmlparser/tests/mochitest/test_compatmode.html
new file mode 100644
index 000000000..c46a1d996
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_compatmode.html
@@ -0,0 +1,93 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+ <title>Mochitest for DOCTYPE parsing</title>
+
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=363883">Mozilla Bug 363883</a>
+
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+var doctypes = [
+/* from bug 363883 */
+'BackCompat' , '<!DOCTYPE>',
+'BackCompat' , '<!DOCTYPEz>',
+'BackCompat' , '<! DOCTYPE>',
+'BackCompat' , '<!zDOCTYPE>',
+'CSS1Compat' , '<!DOCTYPEHTML>',
+'BackCompat' , '<!DOCTYPEz HTML>',
+'CSS1Compat' , '<!DOCTYPE HTML>',
+'BackCompat' , '<!zDOCTYPE HTML>',
+'BackCompat' , '<!DOCTYPE HTMLz>',
+'BackCompat' , '<!DOCTYPE zHTML>',
+'BackCompat' , '<!DOCTYPE XHTML>',
+'BackCompat' , '<!DOCTYPE zzHTML>',
+'BackCompat' , '<!DOCTYPEzHTML>',
+'BackCompat' , '<!DOCTYPEzzHTML>',
+'BackCompat' , '<!DOCTYPE "bla">',
+'BackCompat' , '<!DOCTYPE HTML "bla">',
+'BackCompat' , '<!DOCTYPE HTML "html">',
+'BackCompat' , '<!DOCTYPE PUBLIC>',
+'BackCompat' , '<!DOCTYPE PUBLIC "bla">',
+'BackCompat' , '<!DOCTYPE PUBLIC "html">',
+'CSS1Compat' , '<!DOCTYPE HTML PUBLIC "bla">',
+'BackCompat' , '<!DOCTYPE HTML PUBLIC "html">',
+'BackCompat' , '<!DOCTYPEz HTML PUBLIC "html">',
+'BackCompat' , '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//en">',
+'BackCompat' , '<!DOCTYPEz HTML PUBLIC "-//IETF//DTD HTML 3.2//en">',
+'BackCompat' , '<!DOCTYPE HTMLz PUBLIC "DTD HTML 3.2">',
+'BackCompat' , '<!DOCTYPE "DTD HTML 3.2">',
+/* end from bug 363883 */
+// from bug 502600
+'BackCompat' , '<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">',
+];
+
+function test(mode,i){
+ is(mode,doctypes[i],doctypes[i+1]);
+ if (i == doctypes.length - 2) {
+ SimpleTest.finish();
+ }
+}
+
+////
+// Insert a hidden iframe into the document, with the src
+// containing the test doctype. The iframe's onload
+// function is set to call the test's verification step.
+//
+function insert_iframe(doctype,expected) {
+ var elm = document.createElement('iframe');
+ elm.setAttribute('src', 'data:text/html,' + doctype +
+ '<html><body onload="parent.test(document.compatMode,'+i+')"></body>');
+ elm.setAttribute('style', 'display:none');
+ document.getElementsByTagName('body')[0].appendChild(elm);
+}
+
+////
+// Iterate over the tests
+//
+function doTest() {
+ for (i=0; i < doctypes.length; i+=2) {
+ insert_iframe(doctypes[i+1],doctypes[i]);
+ }
+}
+
+////
+// Run the compatbility mode tests.
+//
+SimpleTest.waitForExplicitFinish();
+doTest();
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_html5_tree_construction.html b/parser/htmlparser/tests/mochitest/test_html5_tree_construction.html
new file mode 100644
index 000000000..bd17eb7ae
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_html5_tree_construction.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=366936
+-->
+<head>
+ <meta charset=utf-8>
+ <title>Test for Bug 366936</title>
+ <script type="text/javascript"
+ src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="/tests/SimpleTest/test.css" />
+ <script type="application/javascript;version=1.7"
+ src="parser_datreader.js"></script>
+ <script type="application/javascript"
+ src="html5_tree_construction_exceptions.js"></script>
+ <script class="testbody" type="application/javascript;version=1.7">
+ var parserDatFiles = ["adoption01.dat",
+ "adoption02.dat",
+ "comments01.dat",
+ "doctype01.dat",
+ "domjs-unsafe.dat",
+ "entities01.dat",
+ "entities02.dat",
+ "html5test-com.dat",
+ "inbody01.dat",
+ "isindex.dat",
+ "pending-spec-changes.dat",
+ "pending-spec-changes-plain-text-unsafe.dat",
+ "plain-text-unsafe.dat",
+ "scripted/adoption01.dat",
+ "scripted/webkit01.dat",
+ "scripted/ark.dat",
+ "scriptdata01.dat",
+ "tables01.dat",
+ "template.dat",
+ "tests10.dat",
+ "tests11.dat",
+ "tests12.dat",
+ "tests14.dat",
+ "tests15.dat",
+ "tests16.dat"];
+
+ </script>
+ <script type="application/javascript;version=1.7"
+ src="parser_web_testrunner.js"></script>
+</head>
+<body>
+<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=366936"
+ target="_blank">Mozilla Bug 366936</a>
+<div id="content">
+<iframe src="" id="testframe"></iframe>
+</div>
+See https://github.com/html5lib/html5lib-tests for original test data<br>
+<div id="display">
+
+</div>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/test_html5_tree_construction_part2.html b/parser/htmlparser/tests/mochitest/test_html5_tree_construction_part2.html
new file mode 100644
index 000000000..70b36673e
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_html5_tree_construction_part2.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=366936
+-->
+<head>
+ <meta charset=utf-8>
+ <title>Test for Bug 366936</title>
+ <script type="text/javascript"
+ src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="/tests/SimpleTest/test.css" />
+ <script type="application/javascript;version=1.7"
+ src="parser_datreader.js"></script>
+ <script type="application/javascript"
+ src="html5_tree_construction_exceptions.js"></script>
+ <script class="testbody" type="application/javascript;version=1.7">
+ var parserDatFiles = ["tests17.dat",
+ "tests18.dat",
+ "tests19.dat",
+ "tests1.dat",
+ "tests20.dat",
+ "tests21.dat",
+ "tests22.dat",
+ "tests23.dat",
+ "tests24.dat",
+ "tests25.dat",
+ "tests26.dat",
+ "tests2.dat",
+ "tests3.dat",
+ "tests4.dat",
+ "tests5.dat",
+ "tests6.dat",
+ "tests7.dat",
+ "tests8.dat",
+ "tests9.dat",
+ "tests_innerHTML_1.dat",
+ "tricky01.dat",
+ "webkit01.dat",
+ "webkit02.dat",
+ "main-element.dat",
+ "foreign-fragment.dat",
+ "ruby.dat"];
+ </script>
+ <script type="application/javascript;version=1.7"
+ src="parser_web_testrunner.js"></script>
+</head>
+<body>
+<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=366936"
+ target="_blank">Mozilla Bug 366936</a>
+<div id="content">
+<iframe src="" id="testframe"></iframe>
+</div>
+See https://github.com/html5lib/html5lib-tests for original test data<br>
+<div id="display">
+
+</div>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/mochitest/test_img_picture_preload.html b/parser/htmlparser/tests/mochitest/test_img_picture_preload.html
new file mode 100644
index 000000000..8193dd2a8
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_img_picture_preload.html
@@ -0,0 +1,87 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1067345
+-->
+<head>
+ <title>Test for Bug 1067345</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+ <script type="text/javascript">
+ // Ensure srcset/picture are enabled, re-run the test at different DPI
+ // levels to ensure preload step does the right responsive image selection
+
+ SimpleTest.waitForExplicitFinish();
+
+ var testDPIs = [ "1.0", "0.5", "2.0", "1.5" ];
+ var iframe = document.createElement("iframe");
+
+ // These accessed by child frame
+ var currentDPI;
+
+ document.body.appendChild(iframe);
+
+ SpecialPowers.pushPrefEnv({'set': [ [ "dom.image.srcset.enabled", true ],
+ [ "dom.image.picture.enabled", true ]] },
+ function() {
+ // Reset the sjs helper so repeat runs work
+ resetRequests();
+ setTimeout(nextTest, 0);
+ });
+
+ function resetRequests() {
+ // Ask the SJS to reset requests
+ var request = new XMLHttpRequest();
+ request.open('GET', "./file_img_picture_preload.sjs?reset", false);
+ request.send(null);
+ is(request.status, 200, "Sending reset to helper should succeed");
+ // Script responds with pre-reset request count
+ var previousRequests = +request.responseText;
+
+ return previousRequests;
+ }
+
+ // Called when iframe is finished
+ function childTestFinished(requestsMade) {
+ setTimeout(function() {
+ // Reset sjs, ensure no new requests appeared after test finished
+ var requestsCleared = resetRequests();
+ is(requestsCleared, requestsMade,
+ "Should not have recorded new requests after test iteration completed");
+
+ setTimeout(nextTest, 0);
+ }, 0);
+ }
+
+ function nextTest() {
+ // Re-run test for each DPI level
+ if (testDPIs.length) {
+ currentDPI = testDPIs.pop();
+ info("Starting test for DPI: " + currentDPI);
+ // To avoid spurious image loads being reported when the resolution changes,
+ // load an intermediate iframe.
+ iframe.src = "about:blank";
+ iframe.addEventListener('load', function on_iframe_load() {
+ iframe.removeEventListener('load', on_iframe_load);
+ SpecialPowers.pushPrefEnv({'set': [ [ "layout.css.devPixelsPerPx", currentDPI ]] },
+ function() {
+ // Clear image cache for next run (we don't try to validate cached items
+ // in preload).
+ SpecialPowers.Cc["@mozilla.org/image/tools;1"]
+ .getService(SpecialPowers.Ci.imgITools)
+ .getImgCacheForDocument(iframe.contentDocument)
+ .clearCache(false);
+ iframe.src = "./file_img_picture_preload.html?" + currentDPI;
+ });
+ });
+ } else {
+ SimpleTest.finish();
+ }
+ }
+ </script>
+
+</body>
+</html>
diff --git a/parser/htmlparser/tests/mochitest/test_xml_mislabeled.html b/parser/htmlparser/tests/mochitest/test_xml_mislabeled.html
new file mode 100644
index 000000000..821edd42a
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_xml_mislabeled.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html><meta charset=utf-8>
+<title>Test for mislabeled or unlabeled XML entities with U+xxD8</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css" />
+<body>
+<script class="testbody">
+'use strict';
+
+SimpleTest.waitForExplicitFinish();
+
+var declaredEncodings = [null, 'utf-8', 'uTf-8', 'UTF-8', 'utf-16', 'uTf-16', 'UTF-16'];
+var actualEncodings = ['utf-8', 'utf-16be', 'utf-16le'];
+var i = 0, j = 0
+testxhr(declaredEncodings[i], actualEncodings[j]);
+
+function testxhr(declaredEncoding, actualEncoding) {
+ // utf-16 XML requres the BOM
+ var bom = actualEncoding.startsWith('utf-16') ? '\uFEFF' : '';
+ var xmlDecl = declaredEncoding ? '<?xml version="1.0" encoding="' + declaredEncoding + '" ?>\n' : '';
+ // The test string need to contain U+xxD8 (bug 860180)
+ var xmlString = bom + xmlDecl + '<test>testãƒãƒ’フヘホ</test>';
+ var xml = new TextEncoder(actualEncoding).encode(xmlString);
+ var description = declaredEncoding ? ' labeled with ' + declaredEncoding : ' without XML declaration';
+ if (!declaredEncoding || actualEncoding !== declaredEncoding.toLowerCase()) {
+ description += ' but actually encoded with ' + actualEncoding;
+ }
+ var xhr = new XMLHttpRequest();
+ var url = URL.createObjectURL(new Blob([xml], {type: 'text/xml'}));
+ xhr.open('GET', url);
+ xhr.send();
+ xhr.onload = xhr.onerror = function(e) {
+ URL.revokeObjectURL(url);
+ is(e.type, 'load', 'xhr loading should succeed for XML' + description);
+ is(xhr.responseXML.documentElement.textContent, 'testãƒãƒ’フヘホ',
+ 'response should be available for XML' + description);
+ testiframe(description, xml);
+ };
+}
+
+function testiframe(description, xml) {
+ var iframe = document.createElement('iframe');
+ var url = URL.createObjectURL(new Blob([xml], {type: 'text/xml'}))
+ iframe.src = url;
+ iframe.onload = iframe.onerror = function(e) {
+ URL.revokeObjectURL(url);
+ is(e.type, 'load', 'iframe loading should succeed for XML' + description);
+ is(iframe.contentDocument.documentElement.textContent, 'testãƒãƒ’フヘホ',
+ 'iframe content should be available for XML' + description);
+ if (++i >= declaredEncodings.length) {
+ i = 0;
+ if (++j >= actualEncodings.length) {
+ SimpleTest.finish();
+ return;
+ }
+ }
+ testxhr(declaredEncodings[i], actualEncodings[j]);
+ };
+ document.body.appendChild(iframe);
+}
+</script>
+<div id="display"></div>
+</body>
diff --git a/parser/htmlparser/tests/reftest/bug482921-1-ref.html b/parser/htmlparser/tests/reftest/bug482921-1-ref.html
new file mode 100644
index 000000000..d388a14bc
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug482921-1-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html><html><head><title></title><link rel="stylesheet" type="text/css" href="resource://gre-resources/viewsource.css"></head><body id="viewsource" class="wrap highlight"><pre id><span class="doctype">&lt;!DOCTYPE html&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">html</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">head</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">title</span>&gt;</span><span>Title</span><span>&lt;/<span class="end-tag">title</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">script</span>&gt;</span>
+<span id></span>var lt = "&lt;";
+<span id></span>&lt;!--
+<span id></span>var s = "&lt;script&gt;foo&lt;/script&gt;";
+<span id></span>--&gt;
+<span id></span><span>&lt;/<span class="end-tag">script</span>&gt;</span><span></span><span class="comment">&lt;!-- Comment. --&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">style</span>&gt;</span>
+<span id></span>/* &lt;/foo&gt; */
+<span id></span><span>&lt;/<span class="end-tag">style</span>&gt;</span>
+<span id></span><span>&lt;/<span class="end-tag">head</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">body</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">p</span>&gt;</span><span>Entity: <span class="entity"><span>&amp;</span>amp; </span></span><span>&lt;/<span class="end-tag">p</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">iframe</span>&gt;</span>&lt;img&gt;<span>&lt;/<span class="end-tag">iframe</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">noscript</span>&gt;</span>&lt;p&gt;Not para&lt;/p&gt;<span>&lt;/<span class="end-tag">noscript</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">svg</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">title</span>&gt;</span><span></span><span class="cdata">&lt;![CDATA[bar]]&gt;</span><span></span><span>&lt;/<span class="end-tag">title</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span class="comment">&lt;!-- this is a comment --&gt;</span><span></span><span>&lt;/<span class="end-tag">script</span>&gt;</span>
+<span id></span><span>&lt;/<span class="end-tag">svg</span>&gt;</span>
+<span id></span><span>&lt;/<span class="end-tag">body</span>&gt;</span>
+<span id></span><span>&lt;/<span class="end-tag">html</span>&gt;</span>
+<span id></span>
+</pre>
+<!-- View source CSS matches the <pre id> and <span id> elements and produces line numbers. -->
diff --git a/parser/htmlparser/tests/reftest/bug482921-1.html b/parser/htmlparser/tests/reftest/bug482921-1.html
new file mode 100644
index 000000000..ca603844f
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug482921-1.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Title</title>
+<script>
+var lt = "<";
+<!--
+var s = "<script>foo</script>";
+-->
+</script><!-- Comment. -->
+<style>
+/* </foo> */
+</style>
+</head>
+<body>
+<p>Entity: &amp; </p>
+<iframe><img></iframe>
+<noscript><p>Not para</p></noscript>
+<svg>
+<title><![CDATA[bar]]></title>
+<script><!-- this is a comment --></script>
+</svg>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/reftest/bug482921-2-ref.html b/parser/htmlparser/tests/reftest/bug482921-2-ref.html
new file mode 100644
index 000000000..44f6c03df
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug482921-2-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html><html><head><title></title><link rel="stylesheet" type="text/css" href="resource://gre-resources/viewsource.css"></head><body id="viewsource" class="wrap highlight"><pre id><span class="pi">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
+<span id></span><span class="pi">&lt;?foo bar?&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">html</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">head</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">title</span>&gt;</span><span>Title</span><span>&lt;/<span class="end-tag">title</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">script</span>&gt;</span>
+<span id></span>var s = "<span>&lt;<span class="start-tag">script</span>&gt;</span><span>foo</span><span>&lt;/<span class="end-tag">script</span>&gt;</span>";
+<span id></span><span class="comment">&lt;!--
+<span id></span>var s = "&lt;script&gt;foo&lt;/script&gt;";
+<span id></span>--&gt;</span>
+<span id></span><span>&lt;/<span class="end-tag">script</span>&gt;</span><span></span>
+<span id></span><span>&lt;<span class="start-tag">style</span>&gt;</span>
+<span id></span>/* <span>&lt;<span class="start-tag">foo</span><span>/</span>&gt;</span> */
+<span id></span><span>&lt;/<span class="end-tag">style</span>&gt;</span>
+<span id></span><span>&lt;/<span class="end-tag">head</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">body</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">p</span>&gt;</span><span>Entity: <span class="entity"><span>&amp;</span>amp; </span></span><span>&lt;/<span class="end-tag">p</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">iframe</span>&gt;</span><span></span><span>&lt;<span class="start-tag">img</span>&gt;</span><span>&lt;/<span class="end-tag">iframe</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">noscript</span>&gt;</span><span>&lt;<span class="start-tag">p</span>&gt;</span><span>Not para</span><span>&lt;/<span class="end-tag">p</span>&gt;</span><span>&lt;/<span class="end-tag">noscript</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">svg</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">title</span>&gt;</span><span></span><span class="cdata">&lt;![CDATA[bar]]&gt;</span><span></span><span>&lt;/<span class="end-tag">title</span>&gt;</span>
+<span id></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span class="comment">&lt;!-- this is a comment --&gt;</span><span></span><span>&lt;/<span class="end-tag">script</span>&gt;</span>
+<span id></span><span>&lt;/<span class="end-tag">svg</span>&gt;</span>
+<span id></span><span>&lt;/<span class="end-tag">body</span>&gt;</span>
+<span id></span><span>&lt;/<span class="end-tag">html</span>&gt;</span>
+<span id></span>
+</pre>
+<!-- View source CSS matches the <pre id> and <span id> elements and produces line numbers. -->
diff --git a/parser/htmlparser/tests/reftest/bug482921-2.xhtml b/parser/htmlparser/tests/reftest/bug482921-2.xhtml
new file mode 100644
index 000000000..4d3f0b6a7
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug482921-2.xhtml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<?foo bar?>
+<html>
+<head>
+<title>Title</title>
+<script>
+var s = "<script>foo</script>";
+<!--
+var s = "<script>foo</script>";
+-->
+</script>
+<style>
+/* <foo/> */
+</style>
+</head>
+<body>
+<p>Entity: &amp; </p>
+<iframe><img></iframe>
+<noscript><p>Not para</p></noscript>
+<svg>
+<title><![CDATA[bar]]></title>
+<script><!-- this is a comment --></script>
+</svg>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/reftest/bug535530-1-ref.html b/parser/htmlparser/tests/reftest/bug535530-1-ref.html
new file mode 100644
index 000000000..22d0dc0b0
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug535530-1-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html><meta charset=utf-8>
+XX&amp;XX XX&amp;nXX XX&amp;noXX XX¬XX XX¬iXX XX¬inXX XX&amp;;XX XX&amp;n;XX XX&amp;no;XX XX¬XX XX¬i;XX XX∉XX
diff --git a/parser/htmlparser/tests/reftest/bug535530-1.html b/parser/htmlparser/tests/reftest/bug535530-1.html
new file mode 100644
index 000000000..63f2d8782
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug535530-1.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+XX&XX
+XX&nXX
+XX&noXX
+XX&notXX
+XX&notiXX
+XX&notinXX
+XX&;XX
+XX&n;XX
+XX&no;XX
+XX&not;XX
+XX&noti;XX
+XX&notin;XX
+
diff --git a/parser/htmlparser/tests/reftest/bug535530-2-ref.html b/parser/htmlparser/tests/reftest/bug535530-2-ref.html
new file mode 100644
index 000000000..5931b9b16
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug535530-2-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html><html><head><title></title><link rel="stylesheet" type="text/css" href="resource://gre-resources/viewsource.css"></head><body id="viewsource" class="wrap highlight"><pre id><span class="doctype">&lt;!DOCTYPE html&gt;</span>
+<span id></span>XX<span class="error">&amp;</span>XX
+<span id></span>XX<span class="error">&amp;</span>nXX
+<span id></span>XX<span class="error">&amp;</span>noXX
+<span id></span>XX<span class="error entity">&amp;not</span>XX
+<span id></span>XX<span class="error entity">&amp;noti</span>XX
+<span id></span>XX<span class="error entity">&amp;notin</span>XX
+<span id></span>XX<span class="error">&amp;</span>;XX
+<span id></span>XX<span class="error">&amp;</span>n;XX
+<span id></span>XX<span class="error">&amp;</span>no;XX
+<span id></span>XX<span class="entity">&amp;not;</span>XX
+<span id></span>XX<span class="error entity">&amp;noti</span>;XX
+<span id></span>XX<span class="entity">&amp;notin;</span>XX
+<span id></span>
+<span id></span>
+</pre>
+<!-- View source CSS matches the <pre id> and <span id> elements and produces line numbers. -->
diff --git a/parser/htmlparser/tests/reftest/bug535530-2.html b/parser/htmlparser/tests/reftest/bug535530-2.html
new file mode 100644
index 000000000..63f2d8782
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug535530-2.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+XX&XX
+XX&nXX
+XX&noXX
+XX&notXX
+XX&notiXX
+XX&notinXX
+XX&;XX
+XX&n;XX
+XX&no;XX
+XX&not;XX
+XX&noti;XX
+XX&notin;XX
+
diff --git a/parser/htmlparser/tests/reftest/bug566280-1-ref.html b/parser/htmlparser/tests/reftest/bug566280-1-ref.html
new file mode 100644
index 000000000..6585cac38
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug566280-1-ref.html
@@ -0,0 +1,2 @@
+<body>hello world
+
diff --git a/parser/htmlparser/tests/reftest/bug566280-1.html b/parser/htmlparser/tests/reftest/bug566280-1.html
new file mode 100644
index 000000000..3aa60caf3
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug566280-1.html
Binary files differ
diff --git a/parser/htmlparser/tests/reftest/bug569229-1-ref.xml b/parser/htmlparser/tests/reftest/bug569229-1-ref.xml
new file mode 100644
index 000000000..652f1d7da
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug569229-1-ref.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" standalone="yes" ?>
+<html xmlns="http://www.w3.org/1999/xhtml"><p>abcd</p></html>
diff --git a/parser/htmlparser/tests/reftest/bug569229-1.xml b/parser/htmlparser/tests/reftest/bug569229-1.xml
new file mode 100644
index 000000000..2e1ff7560
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug569229-1.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" standalone="yes" ?>
+<!DOCTYPE html [
+ <!ENTITY inner "<script src='script.js'></script><p>abcd</p>">
+ <!ENTITY outer "&inner;">
+]>
+<html xmlns="http://www.w3.org/1999/xhtml">&outer;</html>
diff --git a/parser/htmlparser/tests/reftest/bug577418-1-ref.html b/parser/htmlparser/tests/reftest/bug577418-1-ref.html
new file mode 100644
index 000000000..ff773d536
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug577418-1-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<style>
+html {
+ background-color: lime;
+}
+</style>
diff --git a/parser/htmlparser/tests/reftest/bug577418-1.html b/parser/htmlparser/tests/reftest/bug577418-1.html
new file mode 100644
index 000000000..cfd53be0a
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug577418-1.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html style="width:100%;height:100%;margin:0;border:0;overflow:hidden">
+<body style="width:100%;height:100%;margin:0;border:0;overflow:hidden">
+<svg style="width:100%;height:100%">
+ <rect height="100%" width="100%" fill="red"/>
+ <foreignObject>
+ <html>
+ <body>
+ </body>
+ </html>
+ </foreignObject>
+ <rect height="100%" width="100%" fill="lime"/>
+</svg>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/reftest/bug582788-1-ref.html b/parser/htmlparser/tests/reftest/bug582788-1-ref.html
new file mode 100644
index 000000000..c1f684807
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug582788-1-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8">
+<title>Not ISO-10646</title>
+</head>
+<body>
+<p>Not ISO-10646</p>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/reftest/bug582788-1.html b/parser/htmlparser/tests/reftest/bug582788-1.html
new file mode 100644
index 000000000..ee31b3de9
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug582788-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-10646">
+<title>Not ISO-10646</title>
+</head>
+<body>
+<p>Not ISO-10646</p>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/reftest/bug582940-1-ref.html b/parser/htmlparser/tests/reftest/bug582940-1-ref.html
new file mode 100644
index 000000000..7209c8e69
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug582940-1-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<head>
+<meta charset=utf-8>
+<title>Fragment nav</title>
+<script>
+function loaded() {
+ document.documentElement.removeAttribute("class");
+}
+</script>
+</head>
+<body onload='setTimeout(loaded, 10);'>
+<iframe src="frame582940-ref.html#ref"></iframe>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/reftest/bug582940-1.html b/parser/htmlparser/tests/reftest/bug582940-1.html
new file mode 100644
index 000000000..fd721a8bc
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug582940-1.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<head>
+<meta charset=utf-8>
+<title>Fragment nav</title>
+<script>
+function loaded() {
+ document.documentElement.removeAttribute("class");
+}
+</script>
+</head>
+<body onload='setTimeout(loaded, 10);'>
+<iframe src="frame582940.html#ref%20ref"></iframe>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/reftest/bug592656-1-ref.html b/parser/htmlparser/tests/reftest/bug592656-1-ref.html
new file mode 100644
index 000000000..824d81563
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug592656-1-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>document.write() from script-inserted inline scripts and script@onload</title>
+</head>
+<body>
+1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
+</body>
+</html>
diff --git a/parser/htmlparser/tests/reftest/bug592656-1.html b/parser/htmlparser/tests/reftest/bug592656-1.html
new file mode 100644
index 000000000..769f62f64
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug592656-1.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>document.write() from script-inserted inline scripts and script@onload</title>
+</head>
+<body>
+1
+<script>
+function write(num) {
+ document.write(num + " ");
+}
+function scriptload() {
+ document.write("\u003Cscript src='data:text/javascript,write(9)'>\u003C/script> 10 \u003Cscript>write(11)\u003C/script>");
+ write(12);
+}
+function scripterror() {
+ document.write("\u003Cscript src='data:text/javascript,write(16)'>\u003C/script> 17 \u003Cscript>write(18)\u003C/script>");
+ write(19);
+}
+write(2);
+document.write("\u003Cscript src='data:text/javascript,write(3)'>\u003C/script> 4 \u003Cscript>write(5)\u003C/script>");
+var s = document.createElement("script");
+s.textContent = "write(6)";
+document.body.appendChild(s);
+write(7);
+document.write("\u003Cscript src='data:text/javascript,write(8)' onload='scriptload()'>\u003C/script> 13 \u003Cscript>write(14)\u003C/script>");
+write(15);
+document.write(`\u003Cscript src='nosuchscriptoutthere.js' onload='write("fail")' onerror='scripterror()'>\u003C/script> 20 \u003Cscript>write(21)\u003C/script>`);
+write(22);
+</script>
+</body>
+</html>
diff --git a/parser/htmlparser/tests/reftest/bug599320-1-ref.html b/parser/htmlparser/tests/reftest/bug599320-1-ref.html
new file mode 100644
index 000000000..bb48fe5d2
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug599320-1-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset=utf-8>
+<meta content="width=device-width, initial-scale=1" name="viewport">
+<title>UTF-16 doc</title>
+</head>
+<body>
+<h1>UTF-16 doc</h1>
+
+<p>Euro sign: €</p>
+<p>iframe:</p>
+<iframe src=frame599320-1-ref.html width=300 height=400></iframe>
+
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/reftest/bug599320-1.html b/parser/htmlparser/tests/reftest/bug599320-1.html
new file mode 100644
index 000000000..590e9126c
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug599320-1.html
Binary files differ
diff --git a/parser/htmlparser/tests/reftest/bug608373-1-ref.html b/parser/htmlparser/tests/reftest/bug608373-1-ref.html
new file mode 100644
index 000000000..69fec47d0
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug608373-1-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+ <iframe src="data:text/html,TEXT"></iframe>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/reftest/bug608373-1.html b/parser/htmlparser/tests/reftest/bug608373-1.html
new file mode 100644
index 000000000..7bc47552f
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug608373-1.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<head>
+<script>
+function write() {
+ document.getElementsByTagName("iframe")[0].contentDocument.write('\u003Cscript src="data:text/javascript,var i = 0;">\u003C\/script>TEXT\u003Cscript>parent.document.documentElement.removeAttribute("class");\u003c/script>');
+}
+</script>
+</head>
+<body onload="write();">
+ <iframe></iframe>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/reftest/bug659763-1-ref.html b/parser/htmlparser/tests/reftest/bug659763-1-ref.html
new file mode 100644
index 000000000..51dc2b005
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug659763-1-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<iframe src="data:text/plain,<i>foo</i>"></iframe>
diff --git a/parser/htmlparser/tests/reftest/bug659763-1.html b/parser/htmlparser/tests/reftest/bug659763-1.html
new file mode 100644
index 000000000..46dbde092
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug659763-1.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<iframe></iframe>
+<script>
+var iframe = document.getElementsByTagName("iframe")[0];
+var doc = iframe.contentDocument;
+doc.open("text/plain");
+doc.write("<i>foo</i>");
+doc.close();
+</script>
diff --git a/parser/htmlparser/tests/reftest/bug659763-2-ref.html b/parser/htmlparser/tests/reftest/bug659763-2-ref.html
new file mode 100644
index 000000000..51dc2b005
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug659763-2-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<iframe src="data:text/plain,<i>foo</i>"></iframe>
diff --git a/parser/htmlparser/tests/reftest/bug659763-2.html b/parser/htmlparser/tests/reftest/bug659763-2.html
new file mode 100644
index 000000000..c6152193a
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug659763-2.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<iframe></iframe>
+<script>
+var iframe = document.getElementsByTagName("iframe")[0];
+var doc = iframe.contentDocument;
+doc.open("TEXT/PLAIN");
+doc.write("<i>foo</i>");
+doc.close();
+</script>
diff --git a/parser/htmlparser/tests/reftest/bug659763-3-ref.html b/parser/htmlparser/tests/reftest/bug659763-3-ref.html
new file mode 100644
index 000000000..51dc2b005
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug659763-3-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<iframe src="data:text/plain,<i>foo</i>"></iframe>
diff --git a/parser/htmlparser/tests/reftest/bug659763-3.html b/parser/htmlparser/tests/reftest/bug659763-3.html
new file mode 100644
index 000000000..bd2ed094b
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug659763-3.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<iframe></iframe>
+<script>
+var iframe = document.getElementsByTagName("iframe")[0];
+var doc = iframe.contentDocument;
+doc.open("foo/bar");
+doc.write("<i>foo</i>");
+doc.close();
+</script>
diff --git a/parser/htmlparser/tests/reftest/bug659763-4-ref.html b/parser/htmlparser/tests/reftest/bug659763-4-ref.html
new file mode 100644
index 000000000..99429bf4e
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug659763-4-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<iframe src="data:text/html,<i>foo</i>"></iframe>
diff --git a/parser/htmlparser/tests/reftest/bug659763-4.html b/parser/htmlparser/tests/reftest/bug659763-4.html
new file mode 100644
index 000000000..531718635
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug659763-4.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<iframe></iframe>
+<script>
+var iframe = document.getElementsByTagName("iframe")[0];
+var doc = iframe.contentDocument;
+doc.open("text/html");
+doc.write("<i>foo</i>");
+doc.close();
+</script>
diff --git a/parser/htmlparser/tests/reftest/bug659763-5-ref.html b/parser/htmlparser/tests/reftest/bug659763-5-ref.html
new file mode 100644
index 000000000..99429bf4e
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug659763-5-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<iframe src="data:text/html,<i>foo</i>"></iframe>
diff --git a/parser/htmlparser/tests/reftest/bug659763-5.html b/parser/htmlparser/tests/reftest/bug659763-5.html
new file mode 100644
index 000000000..23e9fd8e6
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug659763-5.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<iframe></iframe>
+<script>
+var iframe = document.getElementsByTagName("iframe")[0];
+var doc = iframe.contentDocument;
+doc.open();
+doc.write("<i>foo</i>");
+doc.close();
+</script>
diff --git a/parser/htmlparser/tests/reftest/bug659763-6-ref.html b/parser/htmlparser/tests/reftest/bug659763-6-ref.html
new file mode 100644
index 000000000..99429bf4e
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug659763-6-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<iframe src="data:text/html,<i>foo</i>"></iframe>
diff --git a/parser/htmlparser/tests/reftest/bug659763-6.html b/parser/htmlparser/tests/reftest/bug659763-6.html
new file mode 100644
index 000000000..f0a5ea8d3
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug659763-6.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<iframe></iframe>
+<script>
+var iframe = document.getElementsByTagName("iframe")[0];
+var doc = iframe.contentDocument;
+doc.open("TEXT/HTML");
+doc.write("<i>foo</i>");
+doc.close();
+</script>
diff --git a/parser/htmlparser/tests/reftest/bug673094-1-ref.html b/parser/htmlparser/tests/reftest/bug673094-1-ref.html
new file mode 100644
index 000000000..f8f8ce593
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug673094-1-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<title>bidi in attribute</title>
+</head>
+<body>
+<p>Persian <a href="http://en.wiktionary.org/wiki/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C" title="wikt:Ùارسی‎" >Ùارسی</a></p>
+</p>
+</body>
diff --git a/parser/htmlparser/tests/reftest/bug673094-1.html b/parser/htmlparser/tests/reftest/bug673094-1.html
new file mode 100644
index 000000000..2fbdbfb10
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug673094-1.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<title>bidi in attribute</title>
+</head>
+<body>
+<p>Persian <a href="http://en.wiktionary.org/wiki/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C" title="wikt:Ùارسی" >Ùارسی</a></p>
+</p>
+</body>
diff --git a/parser/htmlparser/tests/reftest/bug696651-1-ref.html b/parser/htmlparser/tests/reftest/bug696651-1-ref.html
new file mode 100644
index 000000000..02f59b7ae
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug696651-1-ref.html
@@ -0,0 +1 @@
+<!DOCTYPE html>CcBbAa
diff --git a/parser/htmlparser/tests/reftest/bug696651-1.html b/parser/htmlparser/tests/reftest/bug696651-1.html
new file mode 100644
index 000000000..50a9135aa
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug696651-1.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<body><script>document.write("\u003cscript>document.write(\"\\u003cscript src='bug696651-external.js'>\\u003c/script>B\"); document.write(\"b\");\u003c/script>A"); document.write("a");</script>
diff --git a/parser/htmlparser/tests/reftest/bug696651-2-ref.html b/parser/htmlparser/tests/reftest/bug696651-2-ref.html
new file mode 100644
index 000000000..7999785c0
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug696651-2-ref.html
@@ -0,0 +1 @@
+<!DOCTYPE html><iframe src="data:text/html,<!DOCTYPE html>CcBbAa"></iframe>
diff --git a/parser/htmlparser/tests/reftest/bug696651-2.html b/parser/htmlparser/tests/reftest/bug696651-2.html
new file mode 100644
index 000000000..2d3515b6a
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug696651-2.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<body>
+<iframe></iframe>
+<script>
+var doc = document.getElementsByTagName("iframe")[0].contentDocument;
+doc.open(); doc.write("\u003cscript>document.write(\"\\u003cscript src='bug696651-external.js'>\\u003c/script>B\"); document.write(\"b\");\u003c/script>A"); doc.write("a"); doc.close();</script>
diff --git a/parser/htmlparser/tests/reftest/bug696651-external.js b/parser/htmlparser/tests/reftest/bug696651-external.js
new file mode 100644
index 000000000..c1c2a8f78
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug696651-external.js
@@ -0,0 +1 @@
+document.write("C"); document.write("c");
diff --git a/parser/htmlparser/tests/reftest/bug700260-1-ref.html b/parser/htmlparser/tests/reftest/bug700260-1-ref.html
new file mode 100644
index 000000000..0ba4495a0
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug700260-1-ref.html
@@ -0,0 +1,3 @@
+ 1
+ 2
+ 3
diff --git a/parser/htmlparser/tests/reftest/bug700260-1.html b/parser/htmlparser/tests/reftest/bug700260-1.html
new file mode 100644
index 000000000..37d300834
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug700260-1.html
@@ -0,0 +1,3 @@
+ 1
+ 2
+ 3
diff --git a/parser/htmlparser/tests/reftest/bug704667-1-ref.html b/parser/htmlparser/tests/reftest/bug704667-1-ref.html
new file mode 100644
index 000000000..db05bd524
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug704667-1-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html><html><head><title></title><link rel="stylesheet" type="text/css" href="resource://gre-resources/viewsource.css"></head><body id="viewsource" class="wrap highlight"><pre id><span class="error comment">&lt;!--&gt;</span> <span class="error comment">&lt;!X&gt;</span>
+<span id></span>
+</pre>
+<!-- View source CSS matches the <pre id> and <span id> elements and produces line numbers. -->
diff --git a/parser/htmlparser/tests/reftest/bug704667-1.html b/parser/htmlparser/tests/reftest/bug704667-1.html
new file mode 100644
index 000000000..553c62b30
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug704667-1.html
@@ -0,0 +1 @@
+<!--> <!X>
diff --git a/parser/htmlparser/tests/reftest/bug731234-1-ref.html b/parser/htmlparser/tests/reftest/bug731234-1-ref.html
new file mode 100644
index 000000000..31b808ec4
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug731234-1-ref.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html><html><head><title></title><link rel="stylesheet" type="text/css" href="resource://gre-resources/viewsource.css"></head><body id="viewsource" class="wrap highlight"><pre id><span class="doctype">&lt;!DOCTYPE html&gt;</span><span>
+<span id></span></span><span>&lt;<span class="start-tag">body</span>&gt;</span><span>
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;/<span class="end-tag">script</span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;/<span class="end-tag">script</span> &gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;/<span class="end-tag">script</span>
+<span id></span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span title="End tag had attributes." class="error">&lt;/<span class="end-tag">script</span> <span class="attribute-name">foo</span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span title="End tag had attributes." class="error">&lt;/<span class="end-tag">script</span> <span class="attribute-name">foo</span>=<a class="attribute-value">bar</a>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span title="End tag had attributes." class="error">&lt;/<span class="end-tag">script</span> <span class="attribute-name">foo</span>="<a class="attribute-value">bar</a>"&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>--</span><span>&lt;/<span class="end-tag">script</span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>-- </span><span>&lt;/<span class="end-tag">script</span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>-- </span><span>&lt;/<span class="end-tag">script</span> &gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>-- </span><span>&lt;/<span class="end-tag">script</span>
+<span id></span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>-- </span><span title="End tag had attributes." class="error">&lt;/<span class="end-tag">script</span> <span class="attribute-name">foo</span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>-- </span><span title="End tag had attributes." class="error">&lt;/<span class="end-tag">script</span> <span class="attribute-name">foo</span>=<a class="attribute-value">bar</a>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>-- </span><span title="End tag had attributes." class="error">&lt;/<span class="end-tag">script</span> <span class="attribute-name">foo</span>="<a class="attribute-value">bar</a>"&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>-- -</span><span>&lt;/<span class="end-tag">script</span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>-- --</span><span>&lt;/<span class="end-tag">script</span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>-- --&gt;</span><span>&lt;/<span class="end-tag">script</span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>--</span><span>&lt;s</span><span>cript&gt; &lt;/script&gt; </span><span>&lt;/<span class="end-tag">script</span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>--</span><span>&lt;s</span><span>cript&gt; &lt;/script&gt; --&gt;</span><span>&lt;/<span class="end-tag">script</span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>--</span><span>&lt;s</span><span>cript &lt;/script&gt; --&gt;</span><span>&lt;/<span class="end-tag">script</span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>--</span><span>&lt;s</span><span>cript&gt; &lt;/script &gt; --&gt;</span><span>&lt;/<span class="end-tag">script</span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>--</span><span>&lt;s</span><span>cript&gt; &lt;/script foo&gt; --&gt;</span><span>&lt;/<span class="end-tag">script</span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>--</span><span>&lt;s</span><span>cript&gt; &lt;/script foo=bar&gt; --&gt;</span><span>&lt;/<span class="end-tag">script</span>&gt;</span><span>X
+<span id></span></span><span>&lt;<span class="start-tag">script</span>&gt;</span><span></span><span>&lt;!</span><span>--</span><span>&lt;s</span><span>cript&gt; &lt;/script foo="bar"&gt; --&gt;</span><span>&lt;/<span class="end-tag">script</span>&gt;</span><span>X
+<span id></span></span>
+</pre>
+<!-- View source CSS matches the <pre id> and <span id> elements and produces line numbers. -->
diff --git a/parser/htmlparser/tests/reftest/bug731234-1.html b/parser/htmlparser/tests/reftest/bug731234-1.html
new file mode 100644
index 000000000..313e44cca
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug731234-1.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<body>
+<script></script>X
+<script></script >X
+<script></script
+>X
+<script></script foo>X
+<script></script foo=bar>X
+<script></script foo="bar">X
+<script><!--</script>X
+<script><!-- </script>X
+<script><!-- </script >X
+<script><!-- </script
+>X
+<script><!-- </script foo>X
+<script><!-- </script foo=bar>X
+<script><!-- </script foo="bar">X
+<script><!-- -</script>X
+<script><!-- --</script>X
+<script><!-- --></script>X
+<script><!--<script> </script> </script>X
+<script><!--<script> </script> --></script>X
+<script><!--<script </script> --></script>X
+<script><!--<script> </script > --></script>X
+<script><!--<script> </script foo> --></script>X
+<script><!--<script> </script foo=bar> --></script>X
+<script><!--<script> </script foo="bar"> --></script>X
diff --git a/parser/htmlparser/tests/reftest/bug820508-1-ref.html b/parser/htmlparser/tests/reftest/bug820508-1-ref.html
new file mode 100644
index 000000000..e624b1688
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug820508-1-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<title>main { display: block; }</title>
+<style>div {
+ border: 2px solid blue;
+}</style>
+<div>foo</div><div>bar</div>
diff --git a/parser/htmlparser/tests/reftest/bug820508-1.html b/parser/htmlparser/tests/reftest/bug820508-1.html
new file mode 100644
index 000000000..60eabee67
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug820508-1.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<title>main { display: block; }</title>
+<style>main {
+ border: 2px solid blue;
+}</style>
+<main>foo</main><main>bar</main>
diff --git a/parser/htmlparser/tests/reftest/bug910588-1-ref.html b/parser/htmlparser/tests/reftest/bug910588-1-ref.html
new file mode 100644
index 000000000..da9c6867a
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug910588-1-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html><html><head><title></title><link rel="stylesheet" type="text/css" href="resource://gre-resources/viewsource.css"></head><body id="viewsource" class="highlight" style="-moz-tab-size: 4"><pre id="line1"><span></span><span class="doctype">&lt;!DOCTYPE html&gt;</span><span></span><span>&lt;<span class="start-tag">table</span>&gt;</span><span></span><span title="Start tag “input†seen in “tableâ€." class="error">&lt;<span class="start-tag">input</span> <span class="attribute-name">type</span>=<a class="attribute-value">hidden</a>&gt;</span><span></span><span>&lt;/<span class="end-tag">table</span>&gt;</span><span>
+<span id="line2"></span></span></pre></body></html>
diff --git a/parser/htmlparser/tests/reftest/bug910588-1.html b/parser/htmlparser/tests/reftest/bug910588-1.html
new file mode 100644
index 000000000..d0f595858
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug910588-1.html
@@ -0,0 +1 @@
+<!DOCTYPE html><table><input type=hidden></table>
diff --git a/parser/htmlparser/tests/reftest/frame582940-ref.html b/parser/htmlparser/tests/reftest/frame582940-ref.html
new file mode 100644
index 000000000..ac665679b
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/frame582940-ref.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset=utf-8>
+<title>Fragment nav</title>
+</head>
+<body>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p><a name='ref'>Ref!</a></p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/reftest/frame582940.html b/parser/htmlparser/tests/reftest/frame582940.html
new file mode 100644
index 000000000..646b7d5a7
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/frame582940.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset=utf-8>
+<title>Fragment nav</title>
+</head>
+<body>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p><a name='ref%20ref'>Ref!</a></p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+<p>Filler</p>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/reftest/frame599320-1-ref.html b/parser/htmlparser/tests/reftest/frame599320-1-ref.html
new file mode 100644
index 000000000..735c368f8
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/frame599320-1-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset=utf-8>
+<meta content="width=device-width, initial-scale=1" name="viewport">
+<title>Non-UTF-16 doc</title>
+</head>
+<body>
+<h1>Non-UTF-16 doc</h1>
+
+<p>Euro sign: €</p>
+
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/reftest/frame599320-1.html b/parser/htmlparser/tests/reftest/frame599320-1.html
new file mode 100644
index 000000000..145ee94ba
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/frame599320-1.html
@@ -0,0 +1,1092 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<!-- More than 1 KB of space -->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<meta charset=utf-8>
+<meta content="width=device-width, initial-scale=1" name="viewport">
+<title>Non-UTF-16 doc</title>
+</head>
+<body>
+<h1>Non-UTF-16 doc</h1>
+
+<p>Euro sign: €</p>
+<script>
+window.onload = function() {
+ window.requestAnimationFrame(function() {
+ parent.document.documentElement.removeAttribute("class");
+ });
+}
+</script>
+</body>
+</html>
+
diff --git a/parser/htmlparser/tests/reftest/reftest-stylo.list b/parser/htmlparser/tests/reftest/reftest-stylo.list
new file mode 100644
index 000000000..30686c95d
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/reftest-stylo.list
@@ -0,0 +1,26 @@
+# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
+== bug535530-1.html bug535530-1.html
+skip == view-source:bug535530-2.html view-source:bug535530-2.html
+== bug566280-1.html bug566280-1.html
+== bug577418-1.html bug577418-1.html
+== bug582788-1.html bug582788-1.html
+skip-if(B2G) fuzzy-if(skiaContent,2,5) == bug582940-1.html bug582940-1.html
+random == bug592656-1.html bug592656-1.html
+# skip fuzzy-if(skiaContent,1,5) == bug599320-1.html bug599320-1.html
+skip fuzzy-if(skiaContent,2,5) == bug608373-1.html bug608373-1.html
+fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated&&!azureSkia,73,1) == view-source:bug482921-1.html view-source:bug482921-1.html
+== view-source:bug482921-2.xhtml view-source:bug482921-2.xhtml
+fuzzy-if(skiaContent,2,5) == bug659763-1.html bug659763-1.html
+fuzzy-if(skiaContent,1,5) == bug659763-2.html bug659763-2.html
+skip fuzzy-if(skiaContent,1,5) == bug659763-3.html bug659763-3.html
+fails fuzzy-if(skiaContent,2,3) == bug659763-4.html bug659763-4.html
+fails fuzzy-if(skiaContent,1,5) == bug659763-5.html bug659763-5.html
+fails fuzzy-if(skiaContent,1,5) == bug659763-6.html bug659763-6.html
+skip skip-if(B2G) == view-source:bug673094-1.html view-source:bug673094-1.html
+random == bug696651-1.html bug696651-1.html
+skip-if(B2G) == bug696651-2.html bug696651-2.html
+== view-source:bug700260-1.html view-source:bug700260-1.html
+== view-source:bug704667-1.html view-source:bug704667-1.html
+== view-source:bug731234-1.html view-source:bug731234-1.html
+== bug820508-1.html bug820508-1.html
+skip == view-source:bug910588-1.html view-source:bug910588-1.html
diff --git a/parser/htmlparser/tests/reftest/reftest.list b/parser/htmlparser/tests/reftest/reftest.list
new file mode 100644
index 000000000..a549c9481
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/reftest.list
@@ -0,0 +1,26 @@
+== bug535530-1.html bug535530-1-ref.html
+== view-source:bug535530-2.html bug535530-2-ref.html
+== bug566280-1.html bug566280-1-ref.html
+== bug569229-1.xml bug569229-1-ref.xml
+== bug577418-1.html bug577418-1-ref.html
+== bug582788-1.html bug582788-1-ref.html
+fuzzy-if(skiaContent,2,5) == bug582940-1.html bug582940-1-ref.html
+== bug592656-1.html bug592656-1-ref.html
+fuzzy-if(skiaContent,1,5) == bug599320-1.html bug599320-1-ref.html
+fuzzy-if(skiaContent,2,5) == bug608373-1.html bug608373-1-ref.html
+fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated&&!azureSkia,73,1) == view-source:bug482921-1.html bug482921-1-ref.html
+== view-source:bug482921-2.xhtml bug482921-2-ref.html
+fuzzy-if(skiaContent,2,5) == bug659763-1.html bug659763-1-ref.html
+fuzzy-if(skiaContent,1,5) == bug659763-2.html bug659763-2-ref.html
+fuzzy-if(skiaContent,1,5) == bug659763-3.html bug659763-3-ref.html
+fuzzy-if(skiaContent,2,3) == bug659763-4.html bug659763-4-ref.html
+fuzzy-if(skiaContent,1,5) == bug659763-5.html bug659763-5-ref.html
+fuzzy-if(skiaContent,1,5) == bug659763-6.html bug659763-6-ref.html
+== view-source:bug673094-1.html view-source:bug673094-1-ref.html
+== bug696651-1.html bug696651-1-ref.html
+== bug696651-2.html bug696651-2-ref.html
+== view-source:bug700260-1.html view-source:bug700260-1-ref.html
+== view-source:bug704667-1.html bug704667-1-ref.html
+== view-source:bug731234-1.html bug731234-1-ref.html
+== bug820508-1.html bug820508-1-ref.html
+== view-source:bug910588-1.html bug910588-1-ref.html
diff --git a/parser/moz.build b/parser/moz.build
new file mode 100644
index 000000000..9d819d59d
--- /dev/null
+++ b/parser/moz.build
@@ -0,0 +1,12 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DIRS += ['expat', 'xml', 'htmlparser', 'html']
+
+EXPORTS += [
+ 'nsCharsetSource.h',
+]
+
diff --git a/parser/nsCharsetSource.h b/parser/nsCharsetSource.h
new file mode 100644
index 000000000..bd85bba10
--- /dev/null
+++ b/parser/nsCharsetSource.h
@@ -0,0 +1,26 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsCharsetSource_h_
+#define nsCharsetSource_h_
+
+// note: the value order defines the priority; higher numbers take priority
+#define kCharsetUninitialized 0
+#define kCharsetFromFallback 1
+#define kCharsetFromTopLevelDomain 2
+#define kCharsetFromDocTypeDefault 3 // This and up confident for XHR
+#define kCharsetFromCache 4
+#define kCharsetFromParentFrame 5
+#define kCharsetFromAutoDetection 6
+#define kCharsetFromHintPrevDoc 7
+#define kCharsetFromMetaPrescan 8 // this one and smaller: HTML5 Tentative
+#define kCharsetFromMetaTag 9 // this one and greater: HTML5 Confident
+#define kCharsetFromIrreversibleAutoDetection 10
+#define kCharsetFromChannel 11
+#define kCharsetFromOtherComponent 12
+#define kCharsetFromParentForced 13 // propagates to child frames
+#define kCharsetFromUserForced 14 // propagates to child frames
+#define kCharsetFromByteOrderMark 15
+
+#endif /* nsCharsetSource_h_ */
diff --git a/parser/xml/moz.build b/parser/xml/moz.build
new file mode 100644
index 000000000..fbce634c1
--- /dev/null
+++ b/parser/xml/moz.build
@@ -0,0 +1,36 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+TEST_DIRS += ['test']
+
+XPIDL_SOURCES += [
+ 'nsIMozSAXXMLDeclarationHandler.idl',
+ 'nsISAXAttributes.idl',
+ 'nsISAXContentHandler.idl',
+ 'nsISAXDTDHandler.idl',
+ 'nsISAXErrorHandler.idl',
+ 'nsISAXLexicalHandler.idl',
+ 'nsISAXLocator.idl',
+ 'nsISAXMutableAttributes.idl',
+ 'nsISAXXMLFilter.idl',
+ 'nsISAXXMLReader.idl',
+]
+
+XPIDL_MODULE = 'saxparser'
+
+EXPORTS += [
+ 'nsSAXAttributes.h',
+ 'nsSAXLocator.h',
+ 'nsSAXXMLReader.h',
+]
+
+SOURCES += [
+ 'nsSAXAttributes.cpp',
+ 'nsSAXLocator.cpp',
+ 'nsSAXXMLReader.cpp',
+]
+
+FINAL_LIBRARY = 'xul'
diff --git a/parser/xml/nsIMozSAXXMLDeclarationHandler.idl b/parser/xml/nsIMozSAXXMLDeclarationHandler.idl
new file mode 100644
index 000000000..2e9c0d6d6
--- /dev/null
+++ b/parser/xml/nsIMozSAXXMLDeclarationHandler.idl
@@ -0,0 +1,15 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+/* This is a helper for the XML declaration in a document:
+ * <?xml version='1.0' encoding='UTF-8' standalone='yes'?>
+ */
+
+[scriptable, function, uuid(c0e461cb-0e5e-284c-b97d-cffeec467eba)]
+interface nsIMozSAXXMLDeclarationHandler: nsISupports {
+ void handleXMLDeclaration(in AString version, in AString encoding, in boolean standalone);
+};
diff --git a/parser/xml/nsISAXAttributes.idl b/parser/xml/nsISAXAttributes.idl
new file mode 100644
index 000000000..c9b0a8a7e
--- /dev/null
+++ b/parser/xml/nsISAXAttributes.idl
@@ -0,0 +1,150 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+/**
+ * Interface for a list of XML attributes.
+ *
+ * This interface allows access to a list of attributes in
+ * three different ways:
+ *
+ * 1.) by attribute index;
+ * 2.) by Namespace-qualified name; or
+ * 3.) by XML qualified name.
+ *
+ * The list will not contain attributes that were declared #IMPLIED
+ * but not specified in the start tag. It will also not contain
+ * attributes used as Namespace declarations (xmlns*) unless the
+ * http://xml.org/sax/features/namespace-prefixes feature
+ * is set to true (it is false by default).
+ *
+ * The order of attributes in the list is unspecified.
+ */
+[scriptable, uuid(e347005e-6cd0-11da-be43-001422106990)]
+interface nsISAXAttributes : nsISupports
+{
+ /**
+ * Look up the index of an attribute by Namespace name.
+ * @param uri The Namespace URI, or the empty string
+ * if the name has no Namespace URI.
+ * @param localName The attribute's local name.
+ * @return The index of the attribute, or -1
+ * if it does not appear in the list.
+ */
+ long getIndexFromName(in AString uri, in AString localName);
+
+ /**
+ * Look up the index of an attribute by XML qualified name.
+ * @param qName The qualified name.
+ * @return The index of the attribute, or -1
+ * if it does not appear in the list.
+ */
+ long getIndexFromQName(in AString qName);
+
+ /**
+ * Return the number of attributes in the list. Once you know the
+ * number of attributes, you can iterate through the list.
+ *
+ * @return The number of attributes in the list.
+ */
+ readonly attribute long length;
+
+ /**
+ * Look up an attribute's local name by index.
+ * @param index The attribute index (zero-based).
+ * @return The local name, or null if the index is out of range.
+ */
+ AString getLocalName(in unsigned long index);
+
+ /**
+ * Look up an attribute's XML qualified name by index.
+ * @param index The attribute index (zero-based).
+ * @return The XML qualified name, or the empty string if none is
+ * available, or null if the index is out of range.
+ */
+ AString getQName(in unsigned long index);
+
+ /**
+ * Look up an attribute's type by index. The attribute type is one
+ * of the strings "CDATA", "ID", "IDREF", "IDREFS", "NMTOKEN",
+ * "NMTOKENS", "ENTITY", "ENTITIES", or "NOTATION" (always in upper
+ * case). If the parser has not read a declaration for the
+ * attribute, or if the parser does not report attribute types, then
+ * it must return the value "CDATA" as stated in the XML 1.0
+ * Recommendation (clause 3.3.3, "Attribute-Value
+ * Normalization"). For an enumerated attribute that is not a
+ * notation, the parser will report the type as "NMTOKEN".
+ *
+ * @param index The attribute index (zero-based).
+ * @return The attribute's type as a string, or null if the index is
+ * out of range.
+ */
+ AString getType(in unsigned long index);
+
+ /**
+ * Look up an attribute's type by Namespace name.
+ * @param uri The Namespace URI, or the empty string
+ * if the name has no Namespace URI.
+ * @param localName The attribute's local name.
+ * @return The attribute type as a string, or null if the attribute
+ * is not in the list.
+ */
+ AString getTypeFromName(in AString uri, in AString localName);
+
+ /**
+ * Look up an attribute's type by XML qualified name.
+ * @param qName The qualified name.
+ * @return The attribute type as a string, or null if the attribute
+ * is not in the list.
+ */
+ AString getTypeFromQName(in AString qName);
+
+ /**
+ * Look up an attribute's Namespace URI by index.
+ * @param index The attribute index (zero-based).
+ * @return The Namespace URI, or the empty string if none is available,
+ * or null if the index is out of range.
+ */
+ AString getURI(in unsigned long index);
+
+ /**
+ * Look up an attribute's value by index. If the attribute value is
+ * a list of tokens (IDREFS, ENTITIES, or NMTOKENS), the tokens will
+ * be concatenated into a single string with each token separated by
+ * a single space.
+ *
+ * @param index The attribute index (zero-based).
+ * @return The attribute's value as a string, or null if the index is
+ * out of range.
+ */
+ AString getValue(in unsigned long index);
+
+ /**
+ * Look up an attribute's value by Namespace name. If the attribute
+ * value is a list of tokens (IDREFS, ENTITIES, or NMTOKENS), the
+ * tokens will be concatenated into a single string with each token
+ * separated by a single space.
+ *
+ * @param uri The Namespace URI, or the empty string
+ * if the name has no Namespace URI.
+ * @param localName The attribute's local name.
+ * @return The attribute's value as a string, or null if the attribute is
+ * not in the list.
+ */
+ AString getValueFromName(in AString uri, in AString localName);
+
+ /**
+ * Look up an attribute's value by XML qualified (prefixed) name.
+ * If the attribute value is a list of tokens (IDREFS, ENTITIES, or
+ * NMTOKENS), the tokens will be concatenated into a single string
+ * with each token separated by a single space.
+ *
+ * @param qName The qualified (prefixed) name.
+ * @return The attribute's value as a string, or null if the attribute is
+ * not in the list.
+ */
+ AString getValueFromQName(in AString qName);
+};
diff --git a/parser/xml/nsISAXContentHandler.idl b/parser/xml/nsISAXContentHandler.idl
new file mode 100644
index 000000000..43b7e48c5
--- /dev/null
+++ b/parser/xml/nsISAXContentHandler.idl
@@ -0,0 +1,225 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsISAXAttributes;
+
+/**
+ * Receive notification of the logical content of a document.
+ *
+ * This is the main interface that most SAX applications implement: if
+ * the application needs to be informed of basic parsing events, it
+ * implements this interface and registers an instance with the SAX
+ * parser. The parser uses the instance to report basic
+ * document-related events like the start and end of elements and
+ * character data.
+ *
+ * The order of events in this interface is very important, and
+ * mirrors the order of information in the document itself. For
+ * example, all of an element's content (character data, processing
+ * instructions, and/or subelements) will appear, in order, between
+ * the startElement event and the corresponding endElement event.
+ */
+[scriptable, uuid(2a99c757-dfee-4806-bff3-f721440412e0)]
+interface nsISAXContentHandler : nsISupports
+{
+ /**
+ * Receive notification of the beginning of a document.
+ *
+ * The SAX parser will invoke this method only once, before any
+ * other event callbacks.
+ */
+ void startDocument();
+
+ /**
+ * Receive notification of the end of a document.
+ *
+ * There is an apparent contradiction between the documentation for
+ * this method and the documentation for ErrorHandler.fatalError().
+ * Until this ambiguity is resolved in a future major release,
+ * clients should make no assumptions about whether endDocument()
+ * will or will not be invoked when the parser has reported a
+ * fatalError() or thrown an exception.
+ *
+ * The SAX parser will invoke this method only once, and it will be
+ * the last method invoked during the parse. The parser shall not
+ * invoke this method until it has either abandoned parsing (because
+ * of an unrecoverable error) or reached the end of input.
+ */
+ void endDocument();
+
+ /**
+ * Receive notification of the beginning of an element.
+ *
+ * The Parser will invoke this method at the beginning of every
+ * element in the XML document; there will be a corresponding
+ * endElement event for every startElement event (even when the
+ * element is empty). All of the element's content will be reported,
+ * in order, before the corresponding endElement event.
+ *
+ * This event allows up to three name components for each element:
+ *
+ * 1.) the Namespace URI;
+ * 2.) the local name; and
+ * 3.) the qualified (prefixed) name.
+ *
+ * Any or all of these may be provided, depending on the values of
+ * the http://xml.org/sax/features/namespaces and the
+ * http://xml.org/sax/features/namespace-prefixes properties:
+ *
+ * The Namespace URI and local name are required when the namespaces
+ * property is true (the default), and are optional when the
+ * namespaces property is false (if one is specified, both must be);
+ *
+ * The qualified name is required when the namespace-prefixes
+ * property is true, and is optional when the namespace-prefixes
+ * property is false (the default).
+ *
+ * Note that the attribute list provided will contain only
+ * attributes with explicit values (specified or defaulted):
+ * #IMPLIED attributes will be omitted. The attribute list will
+ * contain attributes used for Namespace declarations (xmlns*
+ * attributes) only if the
+ * http://xml.org/sax/features/namespace-prefixes property is true
+ * (it is false by default, and support for a true value is
+ * optional).
+ *
+ * @param uri the Namespace URI, or the empty string if the
+ * element has no Namespace URI or if Namespace
+ * processing is not being performed
+ * @param localName the local name (without prefix), or the
+ * empty string if Namespace processing is not being
+ * performed
+ * @param qName the qualified name (with prefix), or the
+ * empty string if qualified names are not available
+ * @param atts the attributes attached to the element. If
+ * there are no attributes, it shall be an empty
+ * SAXAttributes object. The value of this object after
+ * startElement returns is undefined
+ */
+ void startElement(in AString uri, in AString localName,
+ in AString qName, in nsISAXAttributes attributes);
+
+ /**
+ * Receive notification of the end of an element.
+ *
+ * The SAX parser will invoke this method at the end of every
+ * element in the XML document; there will be a corresponding
+ * startElement event for every endElement event (even when the
+ * element is empty).
+ *
+ * For information on the names, see startElement.
+ *
+ * @param uri the Namespace URI, or the empty string if the
+ * element has no Namespace URI or if Namespace
+ * processing is not being performed
+ * @param localName the local name (without prefix), or the
+ * empty string if Namespace processing is not being
+ * performed
+ * @param qName the qualified XML name (with prefix), or the
+ * empty string if qualified names are not available
+ */
+ void endElement(in AString uri, in AString localName, in AString qName);
+
+ /**
+ * Receive notification of character data.
+ *
+ * The Parser will call this method to report each chunk of
+ * character data. SAX parsers may return all contiguous character
+ * data in a single chunk, or they may split it into several chunks;
+ * however, all of the characters in any single event must come from
+ * the same external entity so that the Locator provides useful
+ * information.
+ *
+ * Note that some parsers will report whitespace in element
+ * content using the ignorableWhitespace method rather than this one
+ * (validating parsers must do so).
+ *
+ * @param value the characters from the XML document
+ */
+ void characters(in AString value);
+
+ /**
+ * Receive notification of a processing instruction.
+ *
+ * The Parser will invoke this method once for each processing
+ * instruction found: note that processing instructions may occur
+ * before or after the main document element.
+ *
+ * A SAX parser must never report an XML declaration (XML 1.0,
+ * section 2.8) or a text declaration (XML 1.0, section 4.3.1) using
+ * this method.
+ *
+ * @param target the processing instruction target
+ * @param data the processing instruction data, or null if
+ * none was supplied. The data does not include any
+ * whitespace separating it from the target
+ */
+ void processingInstruction(in AString target, in AString data);
+
+ /**
+ * Receive notification of ignorable whitespace in element content.
+ *
+ * Validating Parsers must use this method to report each chunk of
+ * whitespace in element content (see the W3C XML 1.0
+ * recommendation, section 2.10): non-validating parsers may also
+ * use this method if they are capable of parsing and using content
+ * models.
+ *
+ * SAX parsers may return all contiguous whitespace in a single
+ * chunk, or they may split it into several chunks; however, all of
+ * the characters in any single event must come from the same
+ * external entity, so that the Locator provides useful information.
+ *
+ * @param whitespace the characters from the XML document
+ */
+ void ignorableWhitespace(in AString whitespace);
+
+ /**
+ * Begin the scope of a prefix-URI Namespace mapping.
+ *
+ * The information from this event is not necessary for normal
+ * Namespace processing: the SAX XML reader will automatically
+ * replace prefixes for element and attribute names when the
+ * http://xml.org/sax/features/namespaces feature is
+ * true (the default).
+ *
+ * There are cases, however, when applications need to use prefixes
+ * in character data or in attribute values, where they cannot
+ * safely be expanded automatically; the start/endPrefixMapping
+ * event supplies the information to the application to expand
+ * prefixes in those contexts itself, if necessary.
+ *
+ * Note that start/endPrefixMapping events are not guaranteed to be
+ * properly nested relative to each other: all startPrefixMapping
+ * events will occur immediately before the corresponding
+ * startElement event, and all endPrefixMapping events will occur
+ * immediately after the corresponding endElement event, but their
+ * order is not otherwise guaranteed.
+ *
+ * There should never be start/endPrefixMapping events for the
+ * "xml" prefix, since it is predeclared and immutable.
+ *
+ * @param prefix The Namespace prefix being declared. An empty
+ * string is used for the default element namespace,
+ * which has no prefix.
+ * @param uri The Namespace URI the prefix is mapped to.
+ */
+ void startPrefixMapping(in AString prefix, in AString uri);
+
+ /**
+ * End the scope of a prefix-URI mapping.
+ *
+ * See startPrefixMapping for details. These events will always
+ * occur immediately after the corresponding endElement event, but
+ * the order of endPrefixMapping events is not otherwise guaranteed.
+ *
+ * @param prefix The prefix that was being mapped. This is the empty
+ * string when a default mapping scope ends.
+ */
+ void endPrefixMapping(in AString prefix);
+ //XXX documentLocator
+};
diff --git a/parser/xml/nsISAXDTDHandler.idl b/parser/xml/nsISAXDTDHandler.idl
new file mode 100644
index 000000000..b4cb51d1b
--- /dev/null
+++ b/parser/xml/nsISAXDTDHandler.idl
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+/**
+ * Receive notification of basic DTD-related events.
+ *
+ * If a SAX application needs information about notations and
+ * unparsed entities, then the application implements this interface
+ * and registers an instance with the SAX parser using the parser's
+ * setDTDHandler method. The parser uses the instance to report
+ * notation and unparsed entity declarations to the application.
+ *
+ * Note that this interface includes only those DTD events that the
+ * XML recommendation requires processors to report: notation and
+ * unparsed entity declarations.
+ *
+ * The SAX parser may report these events in any order, regardless
+ * of the order in which the notations and unparsed entities were
+ * declared; however, all DTD events must be reported after the
+ * document handler's startDocument event, and before the first
+ * startElement event. (If the LexicalHandler is used, these events
+ * must also be reported before the endDTD event.)
+ */
+[scriptable, uuid(4d01f225-6cc5-11da-be43-001422106990)]
+interface nsISAXDTDHandler : nsISupports {
+
+ /**
+ * Receive notification of a notation declaration event.
+ *
+ * It is up to the application to record the notation for later
+ * reference, if necessary; notations may appear as attribute values
+ * and in unparsed entity declarations, and are sometime used with
+ * processing instruction target names.
+ *
+ * At least one of publicId and systemId must be non-null. If a
+ * system identifier is present, and it is a URL, the SAX parser
+ * must resolve it fully before passing it to the application
+ * through this event.
+ *
+ * There is no guarantee that the notation declaration will be
+ * reported before any unparsed entities that use it.
+ *
+ * @param name The notation name.
+ * @param publicId The notation's public identifier, or null if none was
+ * given.
+ * @param systemId The notation's system identifier, or null if none was
+ * given.
+ */
+ void notationDecl(in AString name,
+ in AString publicId,
+ in AString systemId);
+
+ /**
+ * Receive notification of an unparsed entity declaration event.
+ *
+ * Note that the notation name corresponds to a notation reported
+ * by the notationDecl event. It is up to the application to record
+ * the entity for later reference, if necessary; unparsed entities
+ * may appear as attribute values.
+ *
+ * If the system identifier is a URL, the parser must resolve it
+ * fully before passing it to the application.
+ *
+ * @param name The unparsed entity's name.
+ * @param publicId The entity's public identifier, or null if none was
+ * given.
+ * @param systemId The entity's system identifier, or null if none was
+ * given.
+ * @param notationName The name of the associated notation.
+ */
+ void unparsedEntityDecl(in AString name, in AString publicId,
+ in AString systemId, in AString notationName);
+};
diff --git a/parser/xml/nsISAXErrorHandler.idl b/parser/xml/nsISAXErrorHandler.idl
new file mode 100644
index 000000000..ea8af79ce
--- /dev/null
+++ b/parser/xml/nsISAXErrorHandler.idl
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsISAXLocator;
+
+/**
+ * Basic interface for SAX error handlers.
+ *
+ * If a SAX application needs to implement customized error
+ * handling, it must implement this interface and then register an
+ * instance with the XML reader. The parser will then report all
+ * errors and warnings through this interface.
+ *
+ * WARNING: If an application does not register an ErrorHandler,
+ * XML parsing errors will go unreported. In order to detect validity
+ * errors, an ErrorHandler that does something with error() calls must
+ * be registered.
+ *
+ */
+[scriptable, uuid(e02b6693-6cca-11da-be43-001422106990)]
+interface nsISAXErrorHandler: nsISupports {
+
+ /**
+ * Receive notification of a recoverable error.
+ *
+ * This corresponds to the definition of "error" in section 1.2
+ * of the W3C XML 1.0 Recommendation. For example, a validating
+ * parser would use this callback to report the violation of a
+ * validity constraint. The default behaviour is to take no
+ * action.
+ *
+ * The SAX parser must continue to provide normal parsing events
+ * after invoking this method: it should still be possible for the
+ * application to process the document through to the end. If the
+ * application cannot do so, then the parser should report a fatal
+ * error even if the XML recommendation does not require it to do
+ * so.
+ *
+ * Filters may use this method to report other, non-XML errors as
+ * well.
+ *
+ * @param locator The locator object for the error (may be null).
+ * @param error The error message.
+ */
+ void error(in nsISAXLocator locator, in AString error);
+
+ /**
+ * Receive notification of a non-recoverable error.
+ *
+ * There is an apparent contradiction between the documentation
+ * for this method and the documentation for
+ * ContentHandler.endDocument(). Until this ambiguity is resolved in
+ * a future major release, clients should make no assumptions about
+ * whether endDocument() will or will not be invoked when the parser
+ * has reported a fatalError() or thrown an exception.
+ *
+ * This corresponds to the definition of "fatal error" in section
+ * 1.2 of the W3C XML 1.0 Recommendation. For example, a parser
+ * would use this callback to report the violation of a
+ * well-formedness constraint.
+ *
+ * The application must assume that the document is unusable
+ * after the parser has invoked this method, and should continue (if
+ * at all) only for the sake of collecting additional error
+ * messages: in fact, SAX parsers are free to stop reporting any
+ * other events once this method has been invoked.
+ *
+ * @param locator The locator object for the error (may be null).
+ * @param error The error message.
+ */
+ void fatalError(in nsISAXLocator locator, in AString error);
+
+ /**
+ * Receive notification of a warning.
+ *
+ * SAX parsers will use this method to report conditions that are
+ * not errors or fatal errors as defined by the XML
+ * recommendation. The default behaviour is to take no action.
+ *
+ * The SAX parser must continue to provide normal parsing events
+ * after invoking this method: it should still be possible for the
+ * application to process the document through to the end.
+ *
+ * Filters may use this method to report other, non-XML warnings
+ * as well.
+ *
+ * @param locator The locator object for the warning (may be null).
+ * @param error The warning message.
+ */
+ void ignorableWarning(in nsISAXLocator locator, in AString error);
+};
diff --git a/parser/xml/nsISAXLexicalHandler.idl b/parser/xml/nsISAXLexicalHandler.idl
new file mode 100644
index 000000000..ed50de2b7
--- /dev/null
+++ b/parser/xml/nsISAXLexicalHandler.idl
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+/**
+ * SAX2 extension handler for lexical events.
+ *
+ * This is an extension handler for SAX2 to provide lexical
+ * information about an XML document, such as comments and CDATA
+ * section boundaries.
+ *
+ * The events in the lexical handler apply to the entire document,
+ * not just to the document element, and all lexical handler events
+ * must appear between the content handler's startDocument and
+ * endDocument events.
+ */
+[scriptable, uuid(23c26a56-adff-440c-8caf-95c2dc2e399b)]
+interface nsISAXLexicalHandler : nsISupports {
+
+ /**
+ * Report an XML comment anywhere in the document.
+ *
+ * This callback will be used for comments inside or outside the
+ * document element, including comments in the external DTD subset
+ * (if read). Comments in the DTD must be properly nested inside
+ * start/endDTD and start/endEntity events (if used).
+ *
+ * @param chars The characters in the comment.
+ */
+ void comment(in AString chars);
+
+ /**
+ * Report the start of DTD declarations, if any.
+ *
+ * This method is intended to report the beginning of the
+ * DOCTYPE declaration; if the document has no DOCTYPE declaration,
+ * this method will not be invoked.
+ *
+ * All declarations reported through DTDHandler or DeclHandler
+ * events must appear between the startDTD and endDTD events.
+ * Declarations are assumed to belong to the internal DTD subset
+ * unless they appear between startEntity and endEntity events.
+ * Comments and processing instructions from the DTD should also be
+ * reported between the startDTD and endDTD events, in their
+ * original order of (logical) occurrence; they are not required to
+ * appear in their correct locations relative to DTDHandler or
+ * DeclHandler events, however.
+ *
+ * Note that the start/endDTD events will appear within the
+ * start/endDocument events from ContentHandler and before the first
+ * startElement event.
+ *
+ * @param name The document type name.
+ * @param publicId The declared public identifier for the
+ * external DTD subset, or null if none was declared.
+ * @param systemId The declared system identifier for the
+ * external DTD subset, or null if none was declared.
+ * (Note that this is not resolved against the document
+ * base URI.)
+ */
+ void startDTD(in AString name, in AString publicId, in AString systemId);
+
+ /**
+ * Report the end of DTD declarations.
+ *
+ * This method is intended to report the end of the
+ * DOCTYPE declaration; if the document has no DOCTYPE declaration,
+ * this method will not be invoked.
+ */
+ void endDTD();
+
+ /**
+ * Report the start of a CDATA section.
+ *
+ * The contents of the CDATA section will be reported through the
+ * regular characters event; this event is intended only to report
+ * the boundary.
+ */
+ void startCDATA();
+
+ /**
+ * Report the end of a CDATA section.
+ */
+ void endCDATA();
+
+ /**
+ * Report the beginning of some internal and external XML entities.
+ *
+ * Because of the streaming event model that SAX uses, some
+ * entity boundaries cannot be reported under any circumstances:
+ *
+ * 1.) general entities within attribute values
+ * 2.) parameter entities within declarations
+ *
+ * These will be silently expanded, with no indication of where
+ * the original entity boundaries were.
+ *
+ * Note also that the boundaries of character references (which
+ * are not really entities anyway) are not reported.
+ *
+ * All start/endEntity events must be properly nested.
+ *
+ * @param name The name of the entity. If it is a parameter
+ * entity, the name will begin with '%', and if it is the
+ * external DTD subset, it will be "[dtd]".
+ */
+ void startEntity(in AString name);
+
+ /**
+ * Report the end of an entity.
+ *
+ * @param name The name of the entity that is ending.
+ */
+ void endEntity(in AString name);
+};
diff --git a/parser/xml/nsISAXLocator.idl b/parser/xml/nsISAXLocator.idl
new file mode 100644
index 000000000..a5808313f
--- /dev/null
+++ b/parser/xml/nsISAXLocator.idl
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+/**
+ * Interface for associating a SAX event with a document location.
+ *
+ * Note that the results returned by the object will be valid only
+ * during the scope of each callback method: the application will
+ * receive unpredictable results if it attempts to use the locator at
+ * any other time, or after parsing completes.
+ */
+[scriptable, uuid(7a307c6c-6cc9-11da-be43-001422106990)]
+interface nsISAXLocator: nsISupports {
+
+ /**
+ * Return the column number where the current document event ends.
+ *
+ * Warning: The return value from the method is intended only as an
+ * approximation for the sake of diagnostics; it is not intended to
+ * provide sufficient information to edit the character content of
+ * the original XML document. For example, when lines contain
+ * combining character sequences, wide characters, surrogate pairs,
+ * or bi-directional text, the value may not correspond to the
+ * column in a text editor's display.
+ *
+ * The return value is an approximation of the column number in the
+ * document entity or external parsed entity where the markup
+ * triggering the event appears.
+ *
+ * If possible, the SAX driver should provide the line position of
+ * the first character after the text associated with the document
+ * event. The first column in each line is column 1.
+ *
+ * @return The column number, or -1 if none is available.
+ */
+ readonly attribute long columnNumber;
+
+ /**
+ * Return the line number where the current document event ends.
+ * Lines are delimited by line ends, which are defined in the XML
+ * specification.
+ *
+ * Warning: The return value from the method is intended only as an
+ * approximation for the sake of diagnostics; it is not intended to
+ * provide sufficient information to edit the character content of
+ * the original XML document. In some cases, these "line" numbers
+ * match what would be displayed as columns, and in others they may
+ * not match the source text due to internal entity expansion.
+ *
+ * The return value is an approximation of the line number in the
+ * document entity or external parsed entity where the markup
+ * triggering the event appears.
+ *
+ * If possible, the SAX driver should provide the line position of
+ * the first character after the text associated with the document
+ * event. The first line is line 1.
+ *
+ * @return The line number, or -1 if none is available.
+ */
+ readonly attribute long lineNumber;
+
+ /**
+ * Return the public identifier for the current document event.
+ *
+ * The return value is the public identifier of the document entity
+ * or of the external parsed entity in which the markup triggering
+ * the event appears.
+ *
+ * @return A string containing the public identifier, or
+ * null if none is available.
+ */
+ readonly attribute AString publicId;
+
+ /**
+ * Return the system identifier for the current document event.
+ *
+ * The return value is the system identifier of the document entity
+ * or of the external parsed entity in which the markup triggering
+ * the event appears.
+ *
+ * @return A string containing the system identifier, or null
+ * if none is available.
+ */
+ readonly attribute AString systemId;
+};
diff --git a/parser/xml/nsISAXMutableAttributes.idl b/parser/xml/nsISAXMutableAttributes.idl
new file mode 100644
index 000000000..c3c205005
--- /dev/null
+++ b/parser/xml/nsISAXMutableAttributes.idl
@@ -0,0 +1,127 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+#include "nsISAXAttributes.idl"
+
+/**
+ * This interface extends the nsISAXAttributes interface with
+ * manipulators so that the list can be modified or reused.
+ */
+[scriptable, uuid(8b1de83d-cebb-49fa-8245-c0fe319eb7b6)]
+interface nsISAXMutableAttributes : nsISAXAttributes {
+
+ /**
+ * Add an attribute to the end of the list.
+ *
+ * For the sake of speed, this method does no checking
+ * to see if the attribute is already in the list: that is
+ * the responsibility of the application.
+ *
+ * @param uri The Namespace URI, or the empty string if
+ * none is available or Namespace processing is not
+ * being performed.
+ * @param localName The local name, or the empty string if
+ * Namespace processing is not being performed.
+ * @param qName The qualified (prefixed) name, or the empty string
+ * if qualified names are not available.
+ * @param type The attribute type as a string.
+ * @param value The attribute value.
+ */
+ void addAttribute(in AString uri,
+ in AString localName,
+ in AString qName,
+ in AString type,
+ in AString value);
+
+ /**
+ * Clear the attribute list for reuse.
+ */
+ void clear();
+
+ /**
+ * Remove an attribute from the list.
+ *
+ * @param index The index of the attribute (zero-based).
+ */
+ void removeAttribute(in unsigned long index);
+
+ /**
+ * Set the attributes list. This method will clear any attributes in
+ * the list before adding the attributes from the argument.
+ *
+ * @param attributes The attributes object to replace populate the
+ * list with.
+ */
+ void setAttributes(in nsISAXAttributes attributes);
+
+ /**
+ * Set an attribute in the list.
+ *
+ * For the sake of speed, this method does no checking for name
+ * conflicts or well-formedness: such checks are the responsibility
+ * of the application.
+ *
+ * @param index The index of the attribute (zero-based).
+ * @param uri The Namespace URI, or the empty string if
+ * none is available or Namespace processing is not
+ * being performed.
+ * @param localName The local name, or the empty string if
+ * Namespace processing is not being performed.
+ * @param qName The qualified name, or the empty string
+ * if qualified names are not available.
+ * @param type The attribute type as a string.
+ * @param value The attribute value.
+ */
+ void setAttribute(in unsigned long index,
+ in AString uri,
+ in AString localName,
+ in AString qName,
+ in AString type,
+ in AString value);
+
+ /**
+ * Set the local name of a specific attribute.
+ *
+ * @param index The index of the attribute (zero-based).
+ * @param localName The attribute's local name, or the empty
+ * string for none.
+ */
+ void setLocalName(in unsigned long index, in AString localName);
+
+ /**
+ * Set the qualified name of a specific attribute.
+ *
+ * @param index The index of the attribute (zero-based).
+ * @param qName The attribute's qualified name, or the empty
+ * string for none.
+ */
+ void setQName(in unsigned long index, in AString qName);
+
+ /**
+ * Set the type of a specific attribute.
+ *
+ * @param index The index of the attribute (zero-based).
+ * @param type The attribute's type.
+ */
+ void setType(in unsigned long index, in AString type);
+
+ /**
+ * Set the Namespace URI of a specific attribute.
+ *
+ * @param index The index of the attribute (zero-based).
+ * @param uri The attribute's Namespace URI, or the empty
+ * string for none.
+ */
+ void setURI(in unsigned long index, in AString uri);
+
+ /**
+ * Set the value of a specific attribute.
+ *
+ * @param index The index of the attribute (zero-based).
+ * @param value The attribute's value.
+ */
+ void setValue(in unsigned long index, in AString value);
+};
diff --git a/parser/xml/nsISAXXMLFilter.idl b/parser/xml/nsISAXXMLFilter.idl
new file mode 100644
index 000000000..44b637db9
--- /dev/null
+++ b/parser/xml/nsISAXXMLFilter.idl
@@ -0,0 +1,29 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+#include "nsISAXXMLReader.idl"
+
+/**
+ * Interface for an XML filter.
+ *
+ * An XML filter is like an XML reader, except that it obtains its
+ * events from another XML reader rather than a primary source like an
+ * XML document or database. Filters can modify a stream of events as
+ * they pass on to the final application.
+ */
+[scriptable, uuid(77a22cf0-6cdf-11da-be43-001422106990)]
+interface nsISAXXMLFilter : nsISAXXMLReader {
+
+ /**
+ * The parent reader.
+ *
+ * Allows the application to query the parent reader (which may be
+ * another filter). It is generally a bad idea to perform any
+ * operations on the parent reader directly: they should all pass
+ * through this filter.
+ */
+ attribute nsISAXXMLReader parent;
+};
diff --git a/parser/xml/nsISAXXMLReader.idl b/parser/xml/nsISAXXMLReader.idl
new file mode 100644
index 000000000..8dedcc3f6
--- /dev/null
+++ b/parser/xml/nsISAXXMLReader.idl
@@ -0,0 +1,207 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIStreamListener.idl"
+
+interface nsIInputStream;
+interface nsIRequestObserver;
+interface nsIURI;
+
+interface nsISAXContentHandler;
+interface nsISAXDTDHandler;
+interface nsISAXEntityResolver;
+interface nsISAXErrorHandler;
+interface nsISAXLexicalHandler;
+interface nsIMozSAXXMLDeclarationHandler;
+
+/**
+ * Interface for reading an XML document using callbacks.
+ *
+ * nsISAXXMLReader is the interface that an XML parser's SAX2
+ * driver must implement. This interface allows an application to set
+ * and query features and properties in the parser, to register event
+ * handlers for document processing, and to initiate a document
+ * parse.
+ */
+[scriptable, uuid(5b1de802-9091-454f-9972-5753c0d0c70e)]
+interface nsISAXXMLReader : nsIStreamListener {
+
+ /**
+ * The base URI.
+ */
+ attribute nsIURI baseURI;
+
+ /**
+ * If the application does not register a content handler, all
+ * content events reported by the SAX parser will be silently
+ * ignored.
+ *
+ * Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.
+ */
+ attribute nsISAXContentHandler contentHandler;
+
+ /**
+ * If the application does not register a DTD handler, all DTD
+ * events reported by the SAX parser will be silently ignored.
+ *
+ * Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.
+ */
+ attribute nsISAXDTDHandler dtdHandler;
+
+
+ /**
+ * If the application does not register an error handler, all
+ * error events reported by the SAX parser will be silently ignored;
+ * however, normal processing may not continue. It is highly
+ * recommended that all SAX applications implement an error handler
+ * to avoid unexpected bugs.
+ *
+ * Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.
+ */
+ attribute nsISAXErrorHandler errorHandler;
+
+ /**
+ * A handler for the (optional) XML declaration of a document.
+ * <?xml version='1.0'?>
+ *
+ * @note This is not part of the SAX standard.
+ */
+ attribute nsIMozSAXXMLDeclarationHandler declarationHandler;
+
+ /**
+ * If the application does not register a lexical handler, all
+ * lexical events (e.g. startDTD) reported by the SAX parser will be
+ * silently ignored.
+ *
+ * Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.
+ */
+ attribute nsISAXLexicalHandler lexicalHandler;
+
+ /**
+ * Set the value of a feature flag.
+ *
+ * The feature name is any fully-qualified URI. It is possible
+ * for an XMLReader to expose a feature value but to be unable to
+ * change the current value. Some feature values may be immutable
+ * or mutable only in specific contexts, such as before, during, or
+ * after a parse.
+ *
+ * All XMLReaders are required to support setting
+ * http://xml.org/sax/features/namespaces to true and
+ * http://xml.org/sax/features/namespace-prefixes to false.
+ *
+ * @param name String flag for a parser feature.
+ * @param value Turn the feature on/off.
+ *
+ * @note This is currently supported only for
+ * http://xml.org/sax/features/namespace-prefixes . All other
+ * features will result in a NOT_IMPLEMENTED exception.
+ */
+ void setFeature(in AString name, in boolean value);
+
+ /**
+ * Look up the value of a feature flag.
+ *
+ * The feature name is any fully-qualified URI. It is
+ * possible for an XMLReader to recognize a feature name but
+ * temporarily be unable to return its value.
+ * Some feature values may be available only in specific
+ * contexts, such as before, during, or after a parse.
+ *
+ * All XMLReaders are required to recognize the
+ * http://xml.org/sax/features/namespaces and the
+ * http://xml.org/sax/features/namespace-prefixes feature names.
+ *
+ * @param name String flag for a parser feature.
+ *
+ * @note This is currently supported only for
+ * http://xml.org/sax/features/namespace-prefixes . All other
+ * features will result in a NOT_IMPLEMENTED exception.
+ */
+ boolean getFeature(in AString name);
+
+ /**
+ * Set the value of a property. NOT CURRENTLY IMPLEMENTED.
+ *
+ * The property name is any fully-qualified URI. It is possible
+ * for an XMLReader to recognize a property name but to be unable to
+ * change the current value. Some property values may be immutable
+ * or mutable only in specific contexts, such as before, during, or
+ * after a parse.
+ *
+ * XMLReaders are not required to recognize setting any specific
+ * property names, though a core set is defined by SAX2.
+ *
+ * This method is also the standard mechanism for setting
+ * extended handlers.
+ *
+ * @param name String flag for a parser feature
+ * @param value Turn the feature on/off.
+ */
+ void setProperty(in AString name, in nsISupports value);
+
+ /**
+ * Look up the value of a property. NOT CURRENTLY IMPLEMENTED.
+ *
+ * The property name is any fully-qualified URI. It is
+ * possible for an XMLReader to recognize a property name but
+ * temporarily be unable to return its value.
+ * Some property values may be available only in specific
+ * contexts, such as before, during, or after a parse.
+ *
+ * XMLReaders are not required to recognize any specific
+ * property names, though an initial core set is documented for
+ * SAX2.
+ *
+ * Implementors are free (and encouraged) to invent their own properties,
+ * using names built on their own URIs.
+ *
+ * @param name The property name, which is a fully-qualified URI.
+ * @return The current value of the property.
+ */
+ boolean getProperty(in AString name);
+
+ /**
+ *
+ * @param str The UTF16 string to be parsed
+ * @param contentType The content type of the string (see parseFromStream)
+ *
+ */
+ void parseFromString(in AString str, in string contentType);
+
+ /**
+ *
+ * @param stream The byte stream whose contents are parsed
+ * @param charset The character set that was used to encode the byte
+ * stream. NULL if not specified.
+ * @param contentType The content type of the string - either text/xml,
+ * application/xml, or application/xhtml+xml.
+ * Must not be NULL.
+ *
+ */
+ void parseFromStream(in nsIInputStream stream,
+ in string charset,
+ in string contentType);
+
+ /**
+ * Begin an asynchronous parse. This method initializes the parser,
+ * and must be called before any nsIStreamListener methods. It is
+ * then the caller's duty to call nsIStreamListener methods to drive
+ * the parser. Once this method is called, the caller must not call
+ * one of the other parse methods.
+ *
+ * @param observer The nsIRequestObserver to notify upon start or stop.
+ * Can be NULL.
+ */
+ void parseAsync(in nsIRequestObserver observer);
+};
diff --git a/parser/xml/nsSAXAttributes.cpp b/parser/xml/nsSAXAttributes.cpp
new file mode 100644
index 000000000..3984186e4
--- /dev/null
+++ b/parser/xml/nsSAXAttributes.cpp
@@ -0,0 +1,332 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsSAXAttributes.h"
+
+NS_IMPL_ISUPPORTS(nsSAXAttributes, nsISAXAttributes, nsISAXMutableAttributes)
+
+NS_IMETHODIMP
+nsSAXAttributes::GetIndexFromName(const nsAString &aURI,
+ const nsAString &aLocalName,
+ int32_t *aResult)
+{
+ int32_t len = mAttrs.Length();
+ int32_t i;
+ for (i = 0; i < len; ++i) {
+ const SAXAttr &att = mAttrs[i];
+ if (att.localName.Equals(aLocalName) && att.uri.Equals(aURI)) {
+ *aResult = i;
+ return NS_OK;
+ }
+ }
+ *aResult = -1;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::GetIndexFromQName(const nsAString &aQName, int32_t *aResult)
+{
+ int32_t len = mAttrs.Length();
+ int32_t i;
+ for (i = 0; i < len; ++i) {
+ const SAXAttr &att = mAttrs[i];
+ if (att.qName.Equals(aQName)) {
+ *aResult = i;
+ return NS_OK;
+ }
+ }
+ *aResult = -1;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::GetLength(int32_t *aResult)
+{
+ *aResult = mAttrs.Length();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::GetLocalName(uint32_t aIndex, nsAString &aResult)
+{
+ uint32_t len = mAttrs.Length();
+ if (aIndex >= len) {
+ aResult.SetIsVoid(true);
+ } else {
+ const SAXAttr &att = mAttrs[aIndex];
+ aResult = att.localName;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::GetQName(uint32_t aIndex, nsAString &aResult)
+{
+ uint32_t len = mAttrs.Length();
+ if (aIndex >= len) {
+ aResult.SetIsVoid(true);
+ } else {
+ const SAXAttr &att = mAttrs[aIndex];
+ aResult = att.qName;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::GetType(uint32_t aIndex, nsAString &aResult)
+{
+ uint32_t len = mAttrs.Length();
+ if (aIndex >= len) {
+ aResult.SetIsVoid(true);
+ } else {
+ const SAXAttr &att = mAttrs[aIndex];
+ aResult = att.type;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::GetTypeFromName(const nsAString &aURI,
+ const nsAString &aLocalName,
+ nsAString &aResult)
+{
+ int32_t index = -1;
+ GetIndexFromName(aURI, aLocalName, &index);
+ if (index >= 0) {
+ aResult = mAttrs[index].type;
+ } else {
+ aResult.SetIsVoid(true);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::GetTypeFromQName(const nsAString &aQName, nsAString &aResult)
+{
+ int32_t index = -1;
+ GetIndexFromQName(aQName, &index);
+ if (index >= 0) {
+ aResult = mAttrs[index].type;
+ } else {
+ aResult.SetIsVoid(true);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::GetURI(uint32_t aIndex, nsAString &aResult)
+{
+ uint32_t len = mAttrs.Length();
+ if (aIndex >= len) {
+ aResult.SetIsVoid(true);
+ } else {
+ const SAXAttr &att = mAttrs[aIndex];
+ aResult = att.uri;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::GetValue(uint32_t aIndex, nsAString &aResult)
+{
+ uint32_t len = mAttrs.Length();
+ if (aIndex >= len) {
+ aResult.SetIsVoid(true);
+ } else {
+ const SAXAttr &att = mAttrs[aIndex];
+ aResult = att.value;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::GetValueFromName(const nsAString &aURI,
+ const nsAString &aLocalName,
+ nsAString &aResult)
+{
+ int32_t index = -1;
+ GetIndexFromName(aURI, aLocalName, &index);
+ if (index >= 0) {
+ aResult = mAttrs[index].value;
+ } else {
+ aResult.SetIsVoid(true);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::GetValueFromQName(const nsAString &aQName,
+ nsAString &aResult)
+{
+ int32_t index = -1;
+ GetIndexFromQName(aQName, &index);
+ if (index >= 0) {
+ aResult = mAttrs[index].value;
+ } else {
+ aResult.SetIsVoid(true);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::AddAttribute(const nsAString &aURI,
+ const nsAString &aLocalName,
+ const nsAString &aQName,
+ const nsAString &aType,
+ const nsAString &aValue)
+{
+ SAXAttr *att = mAttrs.AppendElement();
+ if (!att) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ att->uri = aURI;
+ att->localName = aLocalName;
+ att->qName = aQName;
+ att->type = aType;
+ att->value = aValue;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::Clear()
+{
+ mAttrs.Clear();
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::RemoveAttribute(uint32_t aIndex)
+{
+ if (aIndex >= mAttrs.Length()) {
+ return NS_ERROR_FAILURE;
+ }
+ mAttrs.RemoveElementAt(aIndex);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::SetAttributes(nsISAXAttributes *aAttributes)
+{
+ NS_ENSURE_ARG(aAttributes);
+
+ nsresult rv;
+ int32_t len;
+ rv = aAttributes->GetLength(&len);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mAttrs.Clear();
+ SAXAttr *att;
+ int32_t i;
+ for (i = 0; i < len; ++i) {
+ att = mAttrs.AppendElement();
+ if (!att) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ rv = aAttributes->GetURI(i, att->uri);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = aAttributes->GetLocalName(i, att->localName);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = aAttributes->GetQName(i, att->qName);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = aAttributes->GetType(i, att->type);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = aAttributes->GetValue(i, att->value);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::SetAttribute(uint32_t aIndex,
+ const nsAString &aURI,
+ const nsAString &aLocalName,
+ const nsAString &aQName,
+ const nsAString &aType,
+ const nsAString &aValue)
+{
+ if (aIndex >= mAttrs.Length()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ SAXAttr &att = mAttrs[aIndex];
+ att.uri = aURI;
+ att.localName = aLocalName;
+ att.qName = aQName;
+ att.type = aType;
+ att.value = aValue;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::SetLocalName(uint32_t aIndex, const nsAString &aLocalName)
+{
+ if (aIndex >= mAttrs.Length()) {
+ return NS_ERROR_FAILURE;
+ }
+ mAttrs[aIndex].localName = aLocalName;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::SetQName(uint32_t aIndex, const nsAString &aQName)
+{
+ if (aIndex >= mAttrs.Length()) {
+ return NS_ERROR_FAILURE;
+ }
+ mAttrs[aIndex].qName = aQName;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::SetType(uint32_t aIndex, const nsAString &aType)
+{
+ if (aIndex >= mAttrs.Length()) {
+ return NS_ERROR_FAILURE;
+ }
+ mAttrs[aIndex].type = aType;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::SetURI(uint32_t aIndex, const nsAString &aURI)
+{
+ if (aIndex >= mAttrs.Length()) {
+ return NS_ERROR_FAILURE;
+ }
+ mAttrs[aIndex].uri = aURI;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXAttributes::SetValue(uint32_t aIndex, const nsAString &aValue)
+{
+ if (aIndex >= mAttrs.Length()) {
+ return NS_ERROR_FAILURE;
+ }
+ mAttrs[aIndex].value = aValue;
+
+ return NS_OK;
+}
diff --git a/parser/xml/nsSAXAttributes.h b/parser/xml/nsSAXAttributes.h
new file mode 100644
index 000000000..f8da6f8a1
--- /dev/null
+++ b/parser/xml/nsSAXAttributes.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsSAXAttributes_h__
+#define nsSAXAttributes_h__
+
+#include "nsISupports.h"
+#include "nsISAXAttributes.h"
+#include "nsISAXMutableAttributes.h"
+#include "nsTArray.h"
+#include "nsString.h"
+#include "mozilla/Attributes.h"
+
+#define NS_SAXATTRIBUTES_CONTRACTID "@mozilla.org/saxparser/attributes;1"
+#define NS_SAXATTRIBUTES_CID \
+{/* {7bb40992-77eb-43db-9a4e-39d3bcc483ae}*/ \
+0x7bb40992, 0x77eb, 0x43db, \
+{ 0x9a, 0x4e, 0x39, 0xd3, 0xbc, 0xc3, 0x83, 0xae} }
+
+struct SAXAttr
+{
+ nsString uri;
+ nsString localName;
+ nsString qName;
+ nsString type;
+ nsString value;
+};
+
+class nsSAXAttributes final : public nsISAXMutableAttributes
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSISAXATTRIBUTES
+ NS_DECL_NSISAXMUTABLEATTRIBUTES
+
+private:
+ ~nsSAXAttributes() {}
+ nsTArray<SAXAttr> mAttrs;
+};
+
+#endif // nsSAXAttributes_h__
diff --git a/parser/xml/nsSAXLocator.cpp b/parser/xml/nsSAXLocator.cpp
new file mode 100644
index 000000000..16a056ac6
--- /dev/null
+++ b/parser/xml/nsSAXLocator.cpp
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsSAXLocator.h"
+
+NS_IMPL_ISUPPORTS(nsSAXLocator, nsISAXLocator)
+
+nsSAXLocator::nsSAXLocator(nsString& aPublicId,
+ nsString& aSystemId,
+ int32_t aLineNumber,
+ int32_t aColumnNumber) :
+ mPublicId(aPublicId),
+ mSystemId(aSystemId),
+ mLineNumber(aLineNumber),
+ mColumnNumber(aColumnNumber)
+{
+}
+
+NS_IMETHODIMP
+nsSAXLocator::GetColumnNumber(int32_t *aColumnNumber)
+{
+ *aColumnNumber = mColumnNumber;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXLocator::GetLineNumber(int32_t *aLineNumber)
+{
+ *aLineNumber = mLineNumber;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXLocator::GetPublicId(nsAString &aPublicId)
+{
+ aPublicId = mPublicId;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXLocator::GetSystemId(nsAString &aSystemId)
+{
+ aSystemId = mSystemId;
+ return NS_OK;
+}
diff --git a/parser/xml/nsSAXLocator.h b/parser/xml/nsSAXLocator.h
new file mode 100644
index 000000000..14b9ef063
--- /dev/null
+++ b/parser/xml/nsSAXLocator.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsSAXLocator_h__
+#define nsSAXLocator_h__
+
+#include "nsISAXLocator.h"
+#include "nsString.h"
+#include "mozilla/Attributes.h"
+
+#define NS_SAXLOCATOR_CONTRACTID "@mozilla.org/saxparser/locator;1"
+#define NS_SAXLOCATOR_CID \
+{/* {c1cd4045-846b-43bb-a95e-745a3d7b40e0}*/ \
+0xc1cd4045, 0x846b, 0x43bb, \
+{ 0xa9, 0x5e, 0x74, 0x5a, 0x3d, 0x7b, 0x40, 0xe0} }
+
+class nsSAXLocator final : public nsISAXLocator
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSISAXLOCATOR
+
+ nsSAXLocator(nsString& aPublicId,
+ nsString& aSystemId,
+ int32_t aLineNumber,
+ int32_t aColumnNumber);
+
+private:
+ ~nsSAXLocator() {}
+
+ nsString mPublicId;
+ nsString mSystemId;
+ int32_t mLineNumber;
+ int32_t mColumnNumber;
+};
+
+#endif //nsSAXLocator_h__
diff --git a/parser/xml/nsSAXXMLReader.cpp b/parser/xml/nsSAXXMLReader.cpp
new file mode 100644
index 000000000..a84e0d63b
--- /dev/null
+++ b/parser/xml/nsSAXXMLReader.cpp
@@ -0,0 +1,719 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIInputStream.h"
+#include "nsNetCID.h"
+#include "nsNetUtil.h"
+#include "nsNullPrincipal.h"
+#include "nsIParser.h"
+#include "nsParserCIID.h"
+#include "nsStreamUtils.h"
+#include "nsStringStream.h"
+#include "nsIScriptError.h"
+#include "nsSAXAttributes.h"
+#include "nsSAXLocator.h"
+#include "nsSAXXMLReader.h"
+#include "nsCharsetSource.h"
+
+#include "mozilla/dom/EncodingUtils.h"
+
+using mozilla::dom::EncodingUtils;
+
+#define XMLNS_URI "http://www.w3.org/2000/xmlns/"
+
+static NS_DEFINE_CID(kParserCID, NS_PARSER_CID);
+
+NS_IMPL_CYCLE_COLLECTION(nsSAXXMLReader,
+ mContentHandler,
+ mDTDHandler,
+ mErrorHandler,
+ mLexicalHandler,
+ mDeclarationHandler,
+ mBaseURI,
+ mListener,
+ mParserObserver)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSAXXMLReader)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSAXXMLReader)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSAXXMLReader)
+ NS_INTERFACE_MAP_ENTRY(nsISAXXMLReader)
+ NS_INTERFACE_MAP_ENTRY(nsIExpatSink)
+ NS_INTERFACE_MAP_ENTRY(nsIExtendedExpatSink)
+ NS_INTERFACE_MAP_ENTRY(nsIContentSink)
+ NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
+ NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISAXXMLReader)
+NS_INTERFACE_MAP_END
+
+nsSAXXMLReader::nsSAXXMLReader() :
+ mIsAsyncParse(false),
+ mEnableNamespacePrefixes(false)
+{
+}
+
+// nsIContentSink
+NS_IMETHODIMP
+nsSAXXMLReader::WillBuildModel(nsDTDMode)
+{
+ if (mContentHandler)
+ return mContentHandler->StartDocument();
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::DidBuildModel(bool aTerminated)
+{
+ if (mContentHandler)
+ return mContentHandler->EndDocument();
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::SetParser(nsParserBase *aParser)
+{
+ return NS_OK;
+}
+
+// nsIExtendedExpatSink
+NS_IMETHODIMP
+nsSAXXMLReader::HandleStartElement(const char16_t *aName,
+ const char16_t **aAtts,
+ uint32_t aAttsCount,
+ uint32_t aLineNumber)
+{
+ if (!mContentHandler)
+ return NS_OK;
+
+ RefPtr<nsSAXAttributes> atts = new nsSAXAttributes();
+ if (!atts)
+ return NS_ERROR_OUT_OF_MEMORY;
+ nsAutoString uri, localName, qName;
+ for (; *aAtts; aAtts += 2) {
+ SplitExpatName(aAtts[0], uri, localName, qName);
+ // XXX don't have attr type information
+ NS_NAMED_LITERAL_STRING(cdataType, "CDATA");
+ // could support xmlns reporting, it's a standard SAX feature
+ if (mEnableNamespacePrefixes || !uri.EqualsLiteral(XMLNS_URI)) {
+ NS_ASSERTION(aAtts[1], "null passed to handler");
+ atts->AddAttribute(uri, localName, qName, cdataType,
+ nsDependentString(aAtts[1]));
+ }
+ }
+
+ // Deal with the element name
+ SplitExpatName(aName, uri, localName, qName);
+ return mContentHandler->StartElement(uri, localName, qName, atts);
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::HandleEndElement(const char16_t *aName)
+{
+ if (mContentHandler) {
+ nsAutoString uri, localName, qName;
+ SplitExpatName(aName, uri, localName, qName);
+ return mContentHandler->EndElement(uri, localName, qName);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::HandleComment(const char16_t *aName)
+{
+ NS_ASSERTION(aName, "null passed to handler");
+ if (mLexicalHandler)
+ return mLexicalHandler->Comment(nsDependentString(aName));
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::HandleCDataSection(const char16_t *aData,
+ uint32_t aLength)
+{
+ nsresult rv;
+ if (mLexicalHandler) {
+ rv = mLexicalHandler->StartCDATA();
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ if (mContentHandler) {
+ rv = mContentHandler->Characters(Substring(aData, aData+aLength));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ if (mLexicalHandler) {
+ rv = mLexicalHandler->EndCDATA();
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::HandleStartDTD(const char16_t *aName,
+ const char16_t *aSystemId,
+ const char16_t *aPublicId)
+{
+ char16_t nullChar = char16_t(0);
+ if (!aName)
+ aName = &nullChar;
+ if (!aSystemId)
+ aSystemId = &nullChar;
+ if (!aPublicId)
+ aPublicId = &nullChar;
+
+ mSystemId = aSystemId;
+ mPublicId = aPublicId;
+ if (mLexicalHandler) {
+ return mLexicalHandler->StartDTD(nsDependentString(aName),
+ nsDependentString(aPublicId),
+ nsDependentString(aSystemId));
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::HandleDoctypeDecl(const nsAString & aSubset,
+ const nsAString & aName,
+ const nsAString & aSystemId,
+ const nsAString & aPublicId,
+ nsISupports* aCatalogData)
+{
+ if (mLexicalHandler)
+ return mLexicalHandler->EndDTD();
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::HandleCharacterData(const char16_t *aData,
+ uint32_t aLength)
+{
+ if (mContentHandler)
+ return mContentHandler->Characters(Substring(aData, aData+aLength));
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::HandleStartNamespaceDecl(const char16_t *aPrefix,
+ const char16_t *aUri)
+{
+ if (!mContentHandler)
+ return NS_OK;
+
+ char16_t nullChar = char16_t(0);
+ if (!aPrefix)
+ aPrefix = &nullChar;
+ if (!aUri)
+ aUri = &nullChar;
+
+ return mContentHandler->StartPrefixMapping(nsDependentString(aPrefix),
+ nsDependentString(aUri));
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::HandleEndNamespaceDecl(const char16_t *aPrefix)
+{
+ if (!mContentHandler)
+ return NS_OK;
+
+ if (aPrefix)
+ return mContentHandler->EndPrefixMapping(nsDependentString(aPrefix));
+
+ return mContentHandler->EndPrefixMapping(EmptyString());
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::HandleProcessingInstruction(const char16_t *aTarget,
+ const char16_t *aData)
+{
+ NS_ASSERTION(aTarget && aData, "null passed to handler");
+ if (mContentHandler) {
+ return mContentHandler->ProcessingInstruction(nsDependentString(aTarget),
+ nsDependentString(aData));
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::HandleNotationDecl(const char16_t *aNotationName,
+ const char16_t *aSystemId,
+ const char16_t *aPublicId)
+{
+ NS_ASSERTION(aNotationName, "null passed to handler");
+ if (mDTDHandler) {
+ char16_t nullChar = char16_t(0);
+ if (!aSystemId)
+ aSystemId = &nullChar;
+ if (!aPublicId)
+ aPublicId = &nullChar;
+
+ return mDTDHandler->NotationDecl(nsDependentString(aNotationName),
+ nsDependentString(aSystemId),
+ nsDependentString(aPublicId));
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::HandleUnparsedEntityDecl(const char16_t *aEntityName,
+ const char16_t *aSystemId,
+ const char16_t *aPublicId,
+ const char16_t *aNotationName)
+{
+ NS_ASSERTION(aEntityName && aNotationName, "null passed to handler");
+ if (mDTDHandler) {
+ char16_t nullChar = char16_t(0);
+ if (!aSystemId)
+ aSystemId = &nullChar;
+ if (!aPublicId)
+ aPublicId = &nullChar;
+
+ return mDTDHandler->UnparsedEntityDecl(nsDependentString(aEntityName),
+ nsDependentString(aSystemId),
+ nsDependentString(aPublicId),
+ nsDependentString(aNotationName));
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::HandleXMLDeclaration(const char16_t *aVersion,
+ const char16_t *aEncoding,
+ int32_t aStandalone)
+{
+ NS_ASSERTION(aVersion, "null passed to handler");
+ if (mDeclarationHandler) {
+ char16_t nullChar = char16_t(0);
+ if (!aEncoding)
+ aEncoding = &nullChar;
+ mDeclarationHandler->HandleXMLDeclaration(nsDependentString(aVersion),
+ nsDependentString(aEncoding),
+ aStandalone > 0);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::ReportError(const char16_t* aErrorText,
+ const char16_t* aSourceText,
+ nsIScriptError *aError,
+ bool *_retval)
+{
+ NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!");
+ // Normally, the expat driver should report the error.
+ *_retval = true;
+
+ if (mErrorHandler) {
+ uint32_t lineNumber;
+ nsresult rv = aError->GetLineNumber(&lineNumber);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ uint32_t columnNumber;
+ rv = aError->GetColumnNumber(&columnNumber);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsISAXLocator> locator = new nsSAXLocator(mPublicId,
+ mSystemId,
+ lineNumber,
+ columnNumber);
+ if (!locator)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ rv = mErrorHandler->FatalError(locator, nsDependentString(aErrorText));
+ if (NS_SUCCEEDED(rv)) {
+ // The error handler has handled the script error. Don't log to console.
+ *_retval = false;
+ }
+ }
+
+ return NS_OK;
+}
+
+// nsISAXXMLReader
+
+NS_IMETHODIMP
+nsSAXXMLReader::GetBaseURI(nsIURI **aBaseURI)
+{
+ NS_IF_ADDREF(*aBaseURI = mBaseURI);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::SetBaseURI(nsIURI *aBaseURI)
+{
+ mBaseURI = aBaseURI;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::GetContentHandler(nsISAXContentHandler **aContentHandler)
+{
+ NS_IF_ADDREF(*aContentHandler = mContentHandler);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::SetContentHandler(nsISAXContentHandler *aContentHandler)
+{
+ mContentHandler = aContentHandler;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::GetDtdHandler(nsISAXDTDHandler **aDtdHandler)
+{
+ NS_IF_ADDREF(*aDtdHandler = mDTDHandler);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::SetDtdHandler(nsISAXDTDHandler *aDtdHandler)
+{
+ mDTDHandler = aDtdHandler;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::GetErrorHandler(nsISAXErrorHandler **aErrorHandler)
+{
+ NS_IF_ADDREF(*aErrorHandler = mErrorHandler);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::SetErrorHandler(nsISAXErrorHandler *aErrorHandler)
+{
+ mErrorHandler = aErrorHandler;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::SetFeature(const nsAString &aName, bool aValue)
+{
+ if (aName.EqualsLiteral("http://xml.org/sax/features/namespace-prefixes")) {
+ mEnableNamespacePrefixes = aValue;
+ return NS_OK;
+ }
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::GetFeature(const nsAString &aName, bool *aResult)
+{
+ if (aName.EqualsLiteral("http://xml.org/sax/features/namespace-prefixes")) {
+ *aResult = mEnableNamespacePrefixes;
+ return NS_OK;
+ }
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::GetDeclarationHandler(nsIMozSAXXMLDeclarationHandler **aDeclarationHandler) {
+ NS_IF_ADDREF(*aDeclarationHandler = mDeclarationHandler);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::SetDeclarationHandler(nsIMozSAXXMLDeclarationHandler *aDeclarationHandler) {
+ mDeclarationHandler = aDeclarationHandler;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::GetLexicalHandler(nsISAXLexicalHandler **aLexicalHandler)
+{
+ NS_IF_ADDREF(*aLexicalHandler = mLexicalHandler);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::SetLexicalHandler(nsISAXLexicalHandler *aLexicalHandler)
+{
+ mLexicalHandler = aLexicalHandler;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::SetProperty(const nsAString &aName, nsISupports* aValue)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::GetProperty(const nsAString &aName, bool *aResult)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::ParseFromString(const nsAString &aStr,
+ const char *aContentType)
+{
+ // Don't call this in the middle of an async parse
+ NS_ENSURE_TRUE(!mIsAsyncParse, NS_ERROR_FAILURE);
+
+ NS_ConvertUTF16toUTF8 data(aStr);
+
+ // The new stream holds a reference to the buffer
+ nsCOMPtr<nsIInputStream> stream;
+ nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream),
+ data.get(), data.Length(),
+ NS_ASSIGNMENT_DEPEND);
+ NS_ENSURE_SUCCESS(rv, rv);
+ return ParseFromStream(stream, "UTF-8", aContentType);
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::ParseFromStream(nsIInputStream *aStream,
+ const char *aCharset,
+ const char *aContentType)
+{
+ // Don't call this in the middle of an async parse
+ NS_ENSURE_TRUE(!mIsAsyncParse, NS_ERROR_FAILURE);
+
+ NS_ENSURE_ARG(aStream);
+ NS_ENSURE_ARG(aContentType);
+
+ // Put the nsCOMPtr out here so we hold a ref to the stream as needed
+ nsresult rv;
+ nsCOMPtr<nsIInputStream> bufferedStream;
+ if (!NS_InputStreamIsBuffered(aStream)) {
+ rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
+ aStream, 4096);
+ NS_ENSURE_SUCCESS(rv, rv);
+ aStream = bufferedStream;
+ }
+
+ rv = EnsureBaseURI();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIPrincipal> nullPrincipal = nsNullPrincipal::Create();
+
+ // The following channel is never openend, so it does not matter what
+ // securityFlags we pass; let's follow the principle of least privilege.
+ nsCOMPtr<nsIChannel> parserChannel;
+ rv = NS_NewInputStreamChannel(getter_AddRefs(parserChannel),
+ mBaseURI,
+ aStream,
+ nullPrincipal,
+ nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
+ nsIContentPolicy::TYPE_OTHER,
+ nsDependentCString(aContentType));
+ if (!parserChannel || NS_FAILED(rv))
+ return NS_ERROR_FAILURE;
+
+ if (aCharset)
+ parserChannel->SetContentCharset(nsDependentCString(aCharset));
+
+ rv = InitParser(nullptr, parserChannel);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = mListener->OnStartRequest(parserChannel, nullptr);
+ if (NS_FAILED(rv))
+ parserChannel->Cancel(rv);
+
+ /* When parsing a new document, we need to clear the XML identifiers.
+ HandleStartDTD will set these values from the DTD declaration tag.
+ We won't have them, of course, if there's a well-formedness error
+ before the DTD tag (such as a space before an XML declaration).
+ */
+ mSystemId.Truncate();
+ mPublicId.Truncate();
+
+ nsresult status;
+ parserChannel->GetStatus(&status);
+
+ uint64_t offset = 0;
+ while (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
+ uint64_t available;
+ rv = aStream->Available(&available);
+ if (rv == NS_BASE_STREAM_CLOSED) {
+ rv = NS_OK;
+ available = 0;
+ }
+ if (NS_FAILED(rv)) {
+ parserChannel->Cancel(rv);
+ break;
+ }
+ if (! available)
+ break; // blocking input stream has none available when done
+
+ if (available > UINT32_MAX)
+ available = UINT32_MAX;
+
+ rv = mListener->OnDataAvailable(parserChannel, nullptr,
+ aStream,
+ offset,
+ (uint32_t)available);
+ if (NS_SUCCEEDED(rv))
+ offset += available;
+ else
+ parserChannel->Cancel(rv);
+ parserChannel->GetStatus(&status);
+ }
+ rv = mListener->OnStopRequest(parserChannel, nullptr, status);
+ mListener = nullptr;
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::ParseAsync(nsIRequestObserver *aObserver)
+{
+ mParserObserver = aObserver;
+ mIsAsyncParse = true;
+ return NS_OK;
+}
+
+// nsIRequestObserver
+
+NS_IMETHODIMP
+nsSAXXMLReader::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
+{
+ NS_ENSURE_TRUE(mIsAsyncParse, NS_ERROR_FAILURE);
+ nsresult rv;
+ rv = EnsureBaseURI();
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
+ rv = InitParser(mParserObserver, channel);
+ NS_ENSURE_SUCCESS(rv, rv);
+ // we don't need or want this anymore
+ mParserObserver = nullptr;
+ return mListener->OnStartRequest(aRequest, aContext);
+}
+
+NS_IMETHODIMP
+nsSAXXMLReader::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
+ nsresult status)
+{
+ NS_ENSURE_TRUE(mIsAsyncParse, NS_ERROR_FAILURE);
+ NS_ENSURE_STATE(mListener);
+ nsresult rv = mListener->OnStopRequest(aRequest, aContext, status);
+ mListener = nullptr;
+ mIsAsyncParse = false;
+ return rv;
+}
+
+// nsIStreamListener
+
+NS_IMETHODIMP
+nsSAXXMLReader::OnDataAvailable(nsIRequest *aRequest, nsISupports *aContext,
+ nsIInputStream *aInputStream, uint64_t offset,
+ uint32_t count)
+{
+ NS_ENSURE_TRUE(mIsAsyncParse, NS_ERROR_FAILURE);
+ NS_ENSURE_STATE(mListener);
+ return mListener->OnDataAvailable(aRequest, aContext, aInputStream, offset,
+ count);
+}
+
+nsresult
+nsSAXXMLReader::InitParser(nsIRequestObserver *aObserver, nsIChannel *aChannel)
+{
+ nsresult rv;
+
+ // setup the parser
+ nsCOMPtr<nsIParser> parser = do_CreateInstance(kParserCID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ parser->SetContentSink(this);
+
+ int32_t charsetSource = kCharsetFromDocTypeDefault;
+ nsAutoCString charset(NS_LITERAL_CSTRING("UTF-8"));
+ TryChannelCharset(aChannel, charsetSource, charset);
+ parser->SetDocumentCharset(charset, charsetSource);
+
+ rv = parser->Parse(mBaseURI, aObserver);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mListener = do_QueryInterface(parser, &rv);
+
+ return rv;
+}
+
+// from nsDocument.cpp
+bool
+nsSAXXMLReader::TryChannelCharset(nsIChannel *aChannel,
+ int32_t& aCharsetSource,
+ nsACString& aCharset)
+{
+ if (aCharsetSource >= kCharsetFromChannel)
+ return true;
+
+ if (aChannel) {
+ nsAutoCString charsetVal;
+ nsresult rv = aChannel->GetContentCharset(charsetVal);
+ if (NS_SUCCEEDED(rv)) {
+ nsAutoCString preferred;
+ if (!EncodingUtils::FindEncodingForLabel(charsetVal, preferred))
+ return false;
+
+ aCharset = preferred;
+ aCharsetSource = kCharsetFromChannel;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+nsresult
+nsSAXXMLReader::EnsureBaseURI()
+{
+ if (mBaseURI)
+ return NS_OK;
+
+ return NS_NewURI(getter_AddRefs(mBaseURI), "about:blank");
+}
+
+nsresult
+nsSAXXMLReader::SplitExpatName(const char16_t *aExpatName,
+ nsString &aURI,
+ nsString &aLocalName,
+ nsString &aQName)
+{
+ /**
+ * Adapted from RDFContentSinkImpl
+ *
+ * Expat can send the following:
+ * localName
+ * namespaceURI<separator>localName
+ * namespaceURI<separator>localName<separator>prefix
+ *
+ * and we use 0xFFFF for the <separator>.
+ *
+ */
+
+ NS_ASSERTION(aExpatName, "null passed to handler");
+ nsDependentString expatStr(aExpatName);
+ int32_t break1, break2 = kNotFound;
+ break1 = expatStr.FindChar(char16_t(0xFFFF));
+
+ if (break1 == kNotFound) {
+ aLocalName = expatStr; // no namespace
+ aURI.Truncate();
+ aQName = expatStr;
+ } else {
+ aURI = StringHead(expatStr, break1);
+ break2 = expatStr.FindChar(char16_t(0xFFFF), break1 + 1);
+ if (break2 == kNotFound) { // namespace, but no prefix
+ aLocalName = Substring(expatStr, break1 + 1);
+ aQName = aLocalName;
+ } else { // namespace with prefix
+ aLocalName = Substring(expatStr, break1 + 1, break2 - break1 - 1);
+ aQName = Substring(expatStr, break2 + 1) +
+ NS_LITERAL_STRING(":") + aLocalName;
+ }
+ }
+
+ return NS_OK;
+}
diff --git a/parser/xml/nsSAXXMLReader.h b/parser/xml/nsSAXXMLReader.h
new file mode 100644
index 000000000..763f787e5
--- /dev/null
+++ b/parser/xml/nsSAXXMLReader.h
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsSAXXMLReader_h__
+#define nsSAXXMLReader_h__
+
+#include "nsCOMPtr.h"
+#include "nsIContentSink.h"
+#include "nsIExtendedExpatSink.h"
+#include "nsIParser.h"
+#include "nsIURI.h"
+#include "nsISAXXMLReader.h"
+#include "nsISAXContentHandler.h"
+#include "nsISAXDTDHandler.h"
+#include "nsISAXErrorHandler.h"
+#include "nsISAXLexicalHandler.h"
+#include "nsIMozSAXXMLDeclarationHandler.h"
+#include "nsCycleCollectionParticipant.h"
+#include "mozilla/Attributes.h"
+
+#define NS_SAXXMLREADER_CONTRACTID "@mozilla.org/saxparser/xmlreader;1"
+#define NS_SAXXMLREADER_CID \
+{ 0xab1da296, 0x6125, 0x40ba, \
+{ 0x96, 0xd0, 0x47, 0xa8, 0x28, 0x2a, 0xe3, 0xdb} }
+
+class nsSAXXMLReader final : public nsISAXXMLReader,
+ public nsIExtendedExpatSink,
+ public nsIContentSink
+{
+public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsSAXXMLReader, nsISAXXMLReader)
+ NS_DECL_NSIEXPATSINK
+ NS_DECL_NSIEXTENDEDEXPATSINK
+ NS_DECL_NSISAXXMLREADER
+ NS_DECL_NSIREQUESTOBSERVER
+ NS_DECL_NSISTREAMLISTENER
+
+ nsSAXXMLReader();
+
+ //nsIContentSink
+ NS_IMETHOD WillParse() override
+ {
+ return NS_OK;
+ }
+
+ NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override;
+ NS_IMETHOD DidBuildModel(bool aTerminated) override;
+ NS_IMETHOD SetParser(nsParserBase* aParser) override;
+
+ NS_IMETHOD WillInterrupt() override
+ {
+ return NS_OK;
+ }
+
+ NS_IMETHOD WillResume() override
+ {
+ return NS_OK;
+ }
+
+ virtual void FlushPendingNotifications(mozFlushType aType) override
+ {
+ }
+
+ NS_IMETHOD SetDocumentCharset(nsACString& aCharset) override
+ {
+ return NS_OK;
+ }
+
+ virtual nsISupports *GetTarget() override
+ {
+ return nullptr;
+ }
+
+private:
+ ~nsSAXXMLReader() {}
+
+ nsCOMPtr<nsISAXContentHandler> mContentHandler;
+ nsCOMPtr<nsISAXDTDHandler> mDTDHandler;
+ nsCOMPtr<nsISAXErrorHandler> mErrorHandler;
+ nsCOMPtr<nsISAXLexicalHandler> mLexicalHandler;
+ nsCOMPtr<nsIMozSAXXMLDeclarationHandler> mDeclarationHandler;
+ nsCOMPtr<nsIURI> mBaseURI;
+ nsCOMPtr<nsIStreamListener> mListener;
+ nsCOMPtr<nsIRequestObserver> mParserObserver;
+ bool mIsAsyncParse;
+ static bool TryChannelCharset(nsIChannel *aChannel,
+ int32_t& aCharsetSource,
+ nsACString& aCharset);
+ nsresult EnsureBaseURI();
+ nsresult InitParser(nsIRequestObserver *aListener, nsIChannel *aChannel);
+ nsresult SplitExpatName(const char16_t *aExpatName,
+ nsString &aURI,
+ nsString &aLocalName,
+ nsString &aQName);
+ nsString mPublicId;
+ nsString mSystemId;
+
+ // Feature flags
+ bool mEnableNamespacePrefixes;
+};
+
+#endif // nsSAXXMLReader_h__
diff --git a/parser/xml/test/moz.build b/parser/xml/test/moz.build
new file mode 100644
index 000000000..20c00e9aa
--- /dev/null
+++ b/parser/xml/test/moz.build
@@ -0,0 +1,8 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# Note: set the test module's name to test_<yourmodule>
+XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
diff --git a/parser/xml/test/unit/CC-BY-LICENSE b/parser/xml/test/unit/CC-BY-LICENSE
new file mode 100644
index 000000000..d0ce194dc
--- /dev/null
+++ b/parser/xml/test/unit/CC-BY-LICENSE
@@ -0,0 +1,59 @@
+Creative Commons Attribution 3.0 Unported License
+
+THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
+
+BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
+
+1. Definitions
+
+ "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.
+ "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License.
+ "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership.
+ "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.
+ "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.
+ "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.
+ "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
+ "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
+ "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.
+
+2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.
+
+3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:
+
+ to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections;
+ to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified.";
+ to Distribute and Publicly Perform the Work including as incorporated in Collections; and,
+ to Distribute and Publicly Perform Adaptations.
+
+ For the avoidance of doubt:
+ Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
+ Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
+ Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.
+
+The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved.
+
+4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
+
+ You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(b), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(b), as requested.
+ If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4 (b) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.
+ Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.
+
+5. Representations, Warranties and Disclaimer
+
+UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
+
+6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. Termination
+
+ This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
+ Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
+
+8. Miscellaneous
+
+ Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
+ Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
+ If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+ No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
+ This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
+ The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.
diff --git a/parser/xml/test/unit/results.js b/parser/xml/test/unit/results.js
new file mode 100644
index 000000000..2a7735363
--- /dev/null
+++ b/parser/xml/test/unit/results.js
@@ -0,0 +1,844 @@
+// vectors by the html5security project (https://code.google.com/p/html5security/ & Creative Commons 3.0 BY), see CC-BY-LICENSE for the full license
+
+var vectors = [
+ {
+ "data": "<form id=\"test\"></form><button form=\"test\" formaction=\"javascript:alert(1)\">X</button>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<meta charset=\"x-imap4-modified-utf7\">&ADz&AGn&AG0&AEf&ACA&AHM&AHI&AGO&AD0&AGn&ACA&AG8Abg&AGUAcgByAG8AcgA9AGEAbABlAHIAdAAoADEAKQ&ACAAPABi",
+ "sanitized": "<html><head></head><body>&amp;ADz&amp;AGn&amp;AG0&amp;AEf&amp;ACA&amp;AHM&amp;AHI&amp;AGO&amp;AD0&amp;AGn&amp;ACA&amp;AG8Abg&amp;AGUAcgByAG8AcgA9AGEAbABlAHIAdAAoADEAKQ&amp;ACAAPABi</body></html>"
+ },
+ {
+ "data": "<meta charset=\"x-imap4-modified-utf7\">&<script&S1&TS&1>alert&A7&(1)&R&UA;&&<&A9&11/script&X&>",
+ "sanitized": "<html><head></head><body>&amp;alert&amp;A7&amp;(1)&amp;R&amp;UA;&amp;&amp;&lt;&amp;A9&amp;11/script&amp;X&amp;&gt;</body></html>"
+ },
+ {
+ "data": "0?<script>Worker(\"#\").onmessage=message=>eval(message.data)</script> :postMessage(importScripts('data:;base64,cG9zdE1lc3NhZ2UoJ2FsZXJ0KDEpJyk'))",
+ "sanitized": "<html><head></head><body>0? :postMessage(importScripts('data:;base64,cG9zdE1lc3NhZ2UoJ2FsZXJ0KDEpJyk'))</body></html>"
+ },
+ {
+ "data": "<script>crypto.generateCRMFRequest('CN=0',0,0,null,'alert(1)',384,null,'rsa-dual-use')</script>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<script>({set/**/$($){_/**/setter=$,_=1}}).$=alert</script>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<input onfocus=write(1) autofocus>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<input onblur=write(1) autofocus><input autofocus>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<a style=\"-o-link:'javascript:alert(1)';-o-link-source:current\">X</a>",
+ "sanitized": "<html><head></head><body><a>X</a></body></html>"
+ },
+ {
+ "data": "<video poster=javascript:alert(1)//></video>",
+ "sanitized": "<html><head></head><body><video poster=\"javascript:alert(1)//\" controls=\"controls\"></video></body></html>"
+ },
+ {
+ "data": "<svg xmlns=\"http://www.w3.org/2000/svg\"><g onload=\"javascript:alert(1)\"></g></svg>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<body onscroll=alert(1)><br><br><br><br><br><br>...<br><br><br><br><input autofocus>",
+ "sanitized": "<html><head></head><body><br><br><br><br><br><br>...<br><br><br><br></body></html>"
+ },
+ {
+ "data": "<x repeat=\"template\" repeat-start=\"999999\">0<y repeat=\"template\" repeat-start=\"999999\">1</y></x>",
+ "sanitized": "<html><head></head><body>01</body></html>"
+ },
+ {
+ "data": "<input pattern=^((a+.)a)+$ value=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<script>({0:#0=alert/#0#/#0#(0)})</script>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "X<x style=`behavior:url(#default#time2)` onbegin=`write(1)` >",
+ "sanitized": "<html><head></head><body>X</body></html>"
+ },
+ {
+ "data": "<?xml-stylesheet href=\"javascript:alert(1)\"?><root/>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<script xmlns=\"http://www.w3.org/1999/xhtml\">&#x61;l&#x65;rt&#40;1)</script>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<meta charset=\"x-mac-farsi\">�script �alert(1)//�/script �",
+ "sanitized": "<html><head></head><body>�script �alert(1)//�/script �</body></html>"
+ },
+ {
+ "data": "<script>ReferenceError.prototype.__defineGetter__('name', function(){alert(1)}),x</script>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<script>Object.__noSuchMethod__ = Function,[{}][0].constructor._('alert(1)')()</script>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<input onblur=focus() autofocus><input>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<form id=test onforminput=alert(1)><input></form><button form=test onformchange=alert(2)>X</button>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "1<set/xmlns=`urn:schemas-microsoft-com:time` style=`beh&#x41vior:url(#default#time2)` attributename=`innerhtml` to=`&lt;img/src=&quot;x&quot;onerror=alert(1)&gt;`>",
+ "sanitized": "<html><head></head><body>1</body></html>"
+ },
+ {
+ "data": "<script src=\"#\">{alert(1)}</script>;1",
+ "sanitized": "<html><head></head><body>;1</body></html>"
+ },
+ {
+ "data": "+ADw-html+AD4APA-body+AD4APA-div+AD4-top secret+ADw-/div+AD4APA-/body+AD4APA-/html+AD4-.toXMLString().match(/.*/m),alert(RegExp.input);",
+ "sanitized": "<html><head></head><body>+ADw-html+AD4APA-body+AD4APA-div+AD4-top secret+ADw-/div+AD4APA-/body+AD4APA-/html+AD4-.toXMLString().match(/.*/m),alert(RegExp.input);</body></html>"
+ },
+ {
+ "data": "<style>p[foo=bar{}*{-o-link:'javascript:alert(1)'}{}*{-o-link-source:current}*{background:red}]{background:green};</style>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "1<animate/xmlns=urn:schemas-microsoft-com:time style=behavior:url(#default#time2) attributename=innerhtml values=&lt;img/src=&quot;.&quot;onerror=alert(1)&gt;>",
+ "sanitized": "<html><head></head><body>1</body></html>"
+ },
+ {
+ "data": "<link rel=stylesheet href=data:,*%7bx:expression(write(1))%7d",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<style>@import \"data:,*%7bx:expression(write(1))%7D\";</style>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<frameset onload=alert(1)>",
+ "sanitized": "<html><head></head></html>"
+ },
+ {
+ "data": "<table background=\"javascript:alert(1)\"></table>",
+ "sanitized": "<html><head></head><body><table></table></body></html>"
+ },
+ {
+ "data": "<a style=\"pointer-events:none;position:absolute;\"><a style=\"position:absolute;\" onclick=\"alert(1);\">XXX</a></a><a href=\"javascript:alert(2)\">XXX</a>",
+ "sanitized": "<html><head></head><body><a></a><a>XXX</a><a>XXX</a></body></html>"
+ },
+ {
+ "data": "1<vmlframe xmlns=urn:schemas-microsoft-com:vml style=behavior:url(#default#vml);position:absolute;width:100%;height:100% src=test.vml#xss></vmlframe>",
+ "sanitized": "<html><head></head><body>1</body></html>"
+ },
+ {
+ "data": "1<a href=#><line xmlns=urn:schemas-microsoft-com:vml style=behavior:url(#default#vml);position:absolute href=javascript:alert(1) strokecolor=white strokeweight=1000px from=0 to=1000 /></a>",
+ "sanitized": "<html><head></head><body>1<a href=\"#\"></a></body></html>"
+ },
+ {
+ "data": "<a style=\"behavior:url(#default#AnchorClick);\" folder=\"javascript:alert(1)\">XXX</a>",
+ "sanitized": "<html><head></head><body><a>XXX</a></body></html>"
+ },
+ {
+ "data": "<!--<img src=\"--><img src=x onerror=alert(1)//\">",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<comment><img src=\"</comment><img src=x onerror=alert(1)//\">",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<!-- up to Opera 11.52, FF 3.6.28 -->\r\n<![><img src=\"]><img src=x onerror=alert(1)//\">\r\n\r\n<!-- IE9+, FF4+, Opera 11.60+, Safari 4.0.4+, GC7+ -->\r\n<svg><![CDATA[><image xlink:href=\"]]><img src=xx:x onerror=alert(2)//\"></svg>",
+ "sanitized": "<html><head></head><body><img>\n\n\n&gt;&lt;image xlink:href=\"<img></body></html>"
+ },
+ {
+ "data": "<style><img src=\"</style><img src=x onerror=alert(1)//\">",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<li style=list-style:url() onerror=alert(1)></li>\n<div style=content:url(data:image/svg+xml,%3Csvg/%3E);visibility:hidden onload=alert(1)></div>",
+ "sanitized": "<html><head></head><body><li></li>\n<div></div></body></html>"
+ },
+ {
+ "data": "<head><base href=\"javascript://\"/></head><body><a href=\"/. /,alert(1)//#\">XXX</a></body>",
+ "sanitized": "<html><head></head><body><a>XXX</a></body></html>"
+ },
+ {
+ "data": "<?xml version=\"1.0\" standalone=\"no\"?>\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n<head>\r\n<style type=\"text/css\">\r\n@font-face {font-family: y; src: url(\"font.svg#x\") format(\"svg\");} body {font: 100px \"y\";}\r\n</style>\r\n</head>\r\n<body>Hello</body>\r\n</html>",
+ "sanitized": "<html><head>\n\n</head>\n<body>Hello\n</body></html>"
+ },
+ {
+ "data": "<style>*[{}@import'test.css?]{color: green;}</style>X",
+ "sanitized": "<html><head></head><body>X</body></html>"
+ },
+ {
+ "data": "<div style=\"font-family:'foo[a];color:red;';\">XXX</div>",
+ "sanitized": "<html><head></head><body><div>XXX</div></body></html>"
+ },
+ {
+ "data": "<div style=\"font-family:foo}color=red;\">XXX</div>",
+ "sanitized": "<html><head></head><body><div>XXX</div></body></html>"
+ },
+ {
+ "data": "<svg xmlns=\"http://www.w3.org/2000/svg\"><script>alert(1)</script></svg>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<SCRIPT FOR=document EVENT=onreadystatechange>alert(1)</SCRIPT>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<OBJECT CLASSID=\"clsid:333C7BC4-460F-11D0-BC04-0080C7055A83\"><PARAM NAME=\"DataURL\" VALUE=\"javascript:alert(1)\"></OBJECT>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<object data=\"data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==\"></object>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<embed src=\"data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==\"></embed>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<x style=\"behavior:url(test.sct)\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<xml id=\"xss\" src=\"test.htc\"></xml>\r\n<label dataformatas=\"html\" datasrc=\"#xss\" datafld=\"payload\"></label>",
+ "sanitized": "<html><head></head><body>\n<label></label></body></html>"
+ },
+ {
+ "data": "<script>[{'a':Object.prototype.__defineSetter__('b',function(){alert(arguments[0])}),'b':['secret']}]</script>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<video><source onerror=\"alert(1)\">",
+ "sanitized": "<html><head></head><body><video controls=\"controls\"><source></video></body></html>"
+ },
+ {
+ "data": "<video onerror=\"alert(1)\"><source></source></video>",
+ "sanitized": "<html><head></head><body><video controls=\"controls\"><source></video></body></html>"
+ },
+ {
+ "data": "<b <script>alert(1)//</script>0</script></b>",
+ "sanitized": "<html><head></head><body><b>alert(1)//0</b></body></html>"
+ },
+ {
+ "data": "<b><script<b></b><alert(1)</script </b></b>",
+ "sanitized": "<html><head></head><body><b></b></body></html>"
+ },
+ {
+ "data": "<div id=\"div1\"><input value=\"``onmouseover=alert(1)\"></div> <div id=\"div2\"></div><script>document.getElementById(\"div2\").innerHTML = document.getElementById(\"div1\").innerHTML;</script>",
+ "sanitized": "<html><head></head><body><div id=\"div1\"></div> <div id=\"div2\"></div></body></html>"
+ },
+ {
+ "data": "<div style=\"[a]color[b]:[c]red\">XXX</div>",
+ "sanitized": "<html><head></head><body><div>XXX</div></body></html>"
+ },
+ {
+ "data": "<div style=\"\\63&#9\\06f&#10\\0006c&#12\\00006F&#13\\R:\\000072 Ed;color\\0\\bla:yellow\\0\\bla;col\\0\\00 \\&#xA0or:blue;\">XXX</div>",
+ "sanitized": "<html><head></head><body><div>XXX</div></body></html>"
+ },
+ {
+ "data": "<!-- IE 6-8 -->\r\n<x '=\"foo\"><x foo='><img src=x onerror=alert(1)//'>\r\n\r\n<!-- IE 6-9 -->\r\n<! '=\"foo\"><x foo='><img src=x onerror=alert(2)//'>\r\n<? '=\"foo\"><x foo='><img src=x onerror=alert(3)//'>",
+ "sanitized": "<html><head></head><body>\n\n\n\n</body></html>"
+ },
+ {
+ "data": "<embed src=\"javascript:alert(1)\"></embed> // O10.10�, OM10.0�, GC6�, FF\r\n<img src=\"javascript:alert(2)\">\r\n<image src=\"javascript:alert(2)\"> // IE6, O10.10�, OM10.0�\r\n<script src=\"javascript:alert(3)\"></script> // IE6, O11.01�, OM10.1�",
+ "sanitized": "<html><head></head><body> // O10.10�, OM10.0�, GC6�, FF\n<img>\n<img> // IE6, O10.10�, OM10.0�\n // IE6, O11.01�, OM10.1�</body></html>"
+ },
+ {
+ "data": "<!DOCTYPE x[<!ENTITY x SYSTEM \"http://html5sec.org/test.xxe\">]><y>&x;</y>",
+ "sanitized": "<!DOCTYPE x[<!entity>\n<html><head></head><body>]&gt;&amp;x;</body></html>"
+ },
+ {
+ "data": "<svg onload=\"javascript:alert(1)\" xmlns=\"http://www.w3.org/2000/svg\"></svg>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<?xml version=\"1.0\"?>\n<?xml-stylesheet type=\"text/xsl\" href=\"data:,%3Cxsl:transform version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' id='xss'%3E%3Cxsl:output method='html'/%3E%3Cxsl:template match='/'%3E%3Cscript%3Ealert(1)%3C/script%3E%3C/xsl:template%3E%3C/xsl:transform%3E\"?>\n<root/>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<!DOCTYPE x [\r\n\t<!ATTLIST img xmlns CDATA \"http://www.w3.org/1999/xhtml\" src CDATA \"xx:x\"\r\n onerror CDATA \"alert(1)\"\r\n onload CDATA \"alert(2)\">\r\n]><img />",
+ "sanitized": "<!DOCTYPE x>\n<html><head></head><body>]&gt;<img></body></html>"
+ },
+ {
+ "data": "<doc xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:html=\"http://www.w3.org/1999/xhtml\">\r\n\t<html:style /><x xlink:href=\"javascript:alert(1)\" xlink:type=\"simple\">XXX</x>\r\n</doc>",
+ "sanitized": "<html><head></head><body>\n\tXXX\n</body></html>"
+ },
+ {
+ "data": "<card xmlns=\"http://www.wapforum.org/2001/wml\"><onevent type=\"ontimer\"><go href=\"javascript:alert(1)\"/></onevent><timer value=\"1\"/></card>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<div style=width:1px;filter:glow onfilterchange=alert(1)>x</div>",
+ "sanitized": "<html><head></head><body><div>x</div></body></html>"
+ },
+ {
+ "data": "<// style=x:expression\\28write(1)\\29>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<form><button formaction=\"javascript:alert(1)\">X</button>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<event-source src=\"event.php\" onload=\"alert(1)\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<a href=\"javascript:alert(1)\"><event-source src=\"data:application/x-dom-event-stream,Event:click%0Adata:XXX%0A%0A\" /></a>",
+ "sanitized": "<html><head></head><body><a></a></body></html>"
+ },
+ {
+ "data": "<script<{alert(1)}/></script </>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<?xml-stylesheet type=\"text/css\"?><!DOCTYPE x SYSTEM \"test.dtd\"><x>&x;</x>",
+ "sanitized": "<!DOCTYPE x SYSTEM \"test.dtd\">\n<html><head></head><body>&amp;x;</body></html>"
+ },
+ {
+ "data": "<?xml-stylesheet type=\"text/css\"?><root style=\"x:expression(write(1))\"/>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<?xml-stylesheet type=\"text/xsl\" href=\"#\"?><img xmlns=\"x-schema:test.xdr\"/>",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<object allowscriptaccess=\"always\" data=\"test.swf\"></object>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<style>*{x:EXPRESSION(write(1))}</style>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<x xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:actuate=\"onLoad\" xlink:href=\"javascript:alert(1)\" xlink:type=\"simple\"/>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<?xml-stylesheet type=\"text/css\" href=\"data:,*%7bx:expression(write(2));%7d\"?>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<x:template xmlns:x=\"http://www.wapforum.org/2001/wml\" x:ontimer=\"$(x:unesc)j$(y:escape)a$(z:noecs)v$(x)a$(y)s$(z)cript$x:alert(1)\"><x:timer value=\"1\"/></x:template>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<x xmlns:ev=\"http://www.w3.org/2001/xml-events\" ev:event=\"load\" ev:handler=\"javascript:alert(1)//#x\"/>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<x xmlns:ev=\"http://www.w3.org/2001/xml-events\" ev:event=\"load\" ev:handler=\"test.evt#x\"/>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<body oninput=alert(1)><input autofocus>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<svg xmlns=\"http://www.w3.org/2000/svg\">\n<a xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"javascript:alert(1)\"><rect width=\"1000\" height=\"1000\" fill=\"white\"/></a>\n</svg>",
+ "sanitized": "<html><head></head><body>\n\n</body></html>"
+ },
+ {
+ "data": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n\n<animation xlink:href=\"javascript:alert(1)\"/>\n<animation xlink:href=\"data:text/xml,%3Csvg xmlns='http://www.w3.org/2000/svg' onload='alert(1)'%3E%3C/svg%3E\"/>\n\n<image xlink:href=\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' onload='alert(1)'%3E%3C/svg%3E\"/>\n\n<foreignObject xlink:href=\"javascript:alert(1)\"/>\n<foreignObject xlink:href=\"data:text/xml,%3Cscript xmlns='http://www.w3.org/1999/xhtml'%3Ealert(1)%3C/script%3E\"/>\n\n</svg>",
+ "sanitized": "<html><head></head><body>\n\n\n\n\n\n\n\n\n\n</body></html>"
+ },
+ {
+ "data": "<svg xmlns=\"http://www.w3.org/2000/svg\">\n<set attributeName=\"onmouseover\" to=\"alert(1)\"/>\n<animate attributeName=\"onunload\" to=\"alert(1)\"/>\n</svg>",
+ "sanitized": "<html><head></head><body>\n\n\n</body></html>"
+ },
+ {
+ "data": "<!-- Up to Opera 10.63 -->\r\n<div style=content:url(test2.svg)></div>\r\n\r\n<!-- Up to Opera 11.64 - see link below -->\r\n\r\n<!-- Up to Opera 12.x -->\r\n<div style=\"background:url(test5.svg)\">PRESS ENTER</div>",
+ "sanitized": "<html><head></head><body><div></div>\n\n\n\n\n<div>PRESS ENTER</div></body></html>"
+ },
+ {
+ "data": "[A]\n<? foo=\"><script>alert(1)</script>\">\n<! foo=\"><script>alert(1)</script>\">\n</ foo=\"><script>alert(1)</script>\">\n[B]\n<? foo=\"><x foo='?><script>alert(1)</script>'>\">\n[C]\n<! foo=\"[[[x]]\"><x foo=\"]foo><script>alert(1)</script>\">\n[D]\n<% foo><x foo=\"%><script>alert(1)</script>\">",
+ "sanitized": "<html><head></head><body>[A]\n\"&gt;\n\"&gt;\n\"&gt;\n[B]\n\"&gt;\n[C]\n\n[D]\n&lt;% foo&gt;</body></html>"
+ },
+ {
+ "data": "<div style=\"background:url(http://foo.f/f oo/;color:red/*/foo.jpg);\">X</div>",
+ "sanitized": "<html><head></head><body><div>X</div></body></html>"
+ },
+ {
+ "data": "<div style=\"list-style:url(http://foo.f)\\20url(javascript:alert(1));\">X</div>",
+ "sanitized": "<html><head></head><body><div>X</div></body></html>"
+ },
+ {
+ "data": "<svg xmlns=\"http://www.w3.org/2000/svg\">\n<handler xmlns:ev=\"http://www.w3.org/2001/xml-events\" ev:event=\"load\">alert(1)</handler>\n</svg>",
+ "sanitized": "<html><head></head><body>\nalert(1)\n</body></html>"
+ },
+ {
+ "data": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n<feImage>\n<set attributeName=\"xlink:href\" to=\"data:image/svg+xml;charset=utf-8;base64,\nPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxzY3JpcHQ%2BYWxlcnQoMSk8L3NjcmlwdD48L3N2Zz4NCg%3D%3D\"/>\n</feImage>\n</svg>",
+ "sanitized": "<html><head></head><body>\n\n\n\n</body></html>"
+ },
+ {
+ "data": "<iframe src=mhtml:http://html5sec.org/test.html!xss.html></iframe>\n<iframe src=mhtml:http://html5sec.org/test.gif!xss.html></iframe>",
+ "sanitized": "<html><head></head><body>\n</body></html>"
+ },
+ {
+ "data": "<!-- IE 5-9 -->\r\n<div id=d><x xmlns=\"><iframe onload=alert(1)\"></div>\n<script>d.innerHTML+='';</script>\r\n\r\n<!-- IE 10 in IE5-9 Standards mode -->\r\n<div id=d><x xmlns='\"><iframe onload=alert(2)//'></div>\n<script>d.innerHTML+='';</script>",
+ "sanitized": "<html><head></head><body><div id=\"d\"></div>\n\n\n\n<div id=\"d\"></div>\n</body></html>"
+ },
+ {
+ "data": "<div id=d><div style=\"font-family:'sans\\27\\2F\\2A\\22\\2A\\2F\\3B color\\3Ared\\3B'\">X</div></div>\n<script>with(document.getElementById(\"d\"))innerHTML=innerHTML</script>",
+ "sanitized": "<html><head></head><body><div id=\"d\"><div>X</div></div>\n</body></html>"
+ },
+ {
+ "data": "XXX<style>\r\n\r\n*{color:gre/**/en !/**/important} /* IE 6-9 Standards mode */\r\n\r\n<!--\r\n--><!--*{color:red} /* all UA */\r\n\r\n*{background:url(xx:x //**/\\red/*)} /* IE 6-7 Standards mode */\r\n\r\n</style>",
+ "sanitized": "<html><head></head><body>XXX</body></html>"
+ },
+ {
+ "data": "<img[a][b]src=x[d]onerror[c]=[e]\"alert(1)\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<a href=\"[a]java[b]script[c]:alert(1)\">XXX</a>",
+ "sanitized": "<html><head></head><body><a>XXX</a></body></html>"
+ },
+ {
+ "data": "<img src=\"x` `<script>alert(1)</script>\"` `>",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<script>history.pushState(0,0,'/i/am/somewhere_else');</script>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<svg xmlns=\"http://www.w3.org/2000/svg\" id=\"foo\">\r\n<x xmlns=\"http://www.w3.org/2001/xml-events\" event=\"load\" observer=\"foo\" handler=\"data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Chandler%20xml%3Aid%3D%22bar%22%20type%3D%22application%2Fecmascript%22%3E alert(1) %3C%2Fhandler%3E%0A%3C%2Fsvg%3E%0A#bar\"/>\r\n</svg>",
+ "sanitized": "<html><head></head><body>\n\n</body></html>"
+ },
+ {
+ "data": "<iframe src=\"data:image/svg-xml,%1F%8B%08%00%00%00%00%00%02%03%B3)N.%CA%2C(Q%A8%C8%CD%C9%2B%B6U%CA())%B0%D2%D7%2F%2F%2F%D7%2B7%D6%CB%2FJ%D77%B4%B4%B4%D4%AF%C8(%C9%CDQ%B2K%CCI-*%D10%D4%B4%D1%87%E8%B2%03\"></iframe>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<img src onerror /\" '\"= alt=alert(1)//\">",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<title onpropertychange=alert(1)></title><title title=></title>",
+ "sanitized": "<html><head><title></title><title title=\"\"></title></head><body></body></html>"
+ },
+ {
+ "data": "<!-- IE 5-8 standards mode -->\r\n<a href=http://foo.bar/#x=`y></a><img alt=\"`><img src=xx:x onerror=alert(1)></a>\">\r\n\r\n<!-- IE 5-9 standards mode -->\r\n<!a foo=x=`y><img alt=\"`><img src=xx:x onerror=alert(2)//\">\r\n<?a foo=x=`y><img alt=\"`><img src=xx:x onerror=alert(3)//\">",
+ "sanitized": "<html><head></head><body><a href=\"http://foo.bar/#x=%60y\"></a><img alt=\"`&gt;&lt;img src=xx:x onerror=alert(1)&gt;&lt;/a&gt;\">\n\n\n<img alt=\"`&gt;&lt;img src=xx:x onerror=alert(2)//\">\n<img alt=\"`&gt;&lt;img src=xx:x onerror=alert(3)//\"></body></html>"
+ },
+ {
+ "data": "<svg xmlns=\"http://www.w3.org/2000/svg\">\n<a id=\"x\"><rect fill=\"white\" width=\"1000\" height=\"1000\"/></a>\n<rect fill=\"white\" style=\"clip-path:url(test3.svg#a);fill:url(#b);filter:url(#c);marker:url(#d);mask:url(#e);stroke:url(#f);\"/>\n</svg>",
+ "sanitized": "<html><head></head><body>\n\n\n</body></html>"
+ },
+ {
+ "data": "<svg xmlns=\"http://www.w3.org/2000/svg\">\r\n<path d=\"M0,0\" style=\"marker-start:url(test4.svg#a)\"/>\r\n</svg>",
+ "sanitized": "<html><head></head><body>\n\n</body></html>"
+ },
+ {
+ "data": "<div style=\"background:url(/f#[a]oo/;color:red/*/foo.jpg);\">X</div>",
+ "sanitized": "<html><head></head><body><div>X</div></body></html>"
+ },
+ {
+ "data": "<div style=\"font-family:foo{bar;background:url(http://foo.f/oo};color:red/*/foo.jpg);\">X</div>",
+ "sanitized": "<html><head></head><body><div>X</div></body></html>"
+ },
+ {
+ "data": "<div id=\"x\">XXX</div>\n<style>\n\n#x{font-family:foo[bar;color:green;}\n\n#y];color:red;{}\n\n</style>",
+ "sanitized": "<html><head></head><body><div id=\"x\">XXX</div>\n</body></html>"
+ },
+ {
+ "data": "<x style=\"background:url('x[a];color:red;/*')\">XXX</x>",
+ "sanitized": "<html><head></head><body>XXX</body></html>"
+ },
+ {
+ "data": "<!--[if]><script>alert(1)</script -->\r\n<!--[if<img src=x onerror=alert(2)//]> -->",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<div id=\"x\">x</div>\n<xml:namespace prefix=\"t\">\n<import namespace=\"t\" implementation=\"#default#time2\">\n<t:set attributeName=\"innerHTML\" targetElement=\"x\" to=\"&lt;img&#11;src=x:x&#11;onerror&#11;=alert(1)&gt;\">",
+ "sanitized": "<html><head></head><body><div id=\"x\">x</div>\n\n\n</body></html>"
+ },
+ {
+ "data": "<a href=\"http://attacker.org\">\n\t<iframe src=\"http://example.org/\"></iframe>\n</a>",
+ "sanitized": "<html><head></head><body><a href=\"http://attacker.org\">\n\t\n</a></body></html>"
+ },
+ {
+ "data": "<div draggable=\"true\" ondragstart=\"event.dataTransfer.setData('text/plain','malicious code');\">\n\t<h1>Drop me</h1>\n</div>\n\n<iframe src=\"http://www.example.org/dropHere.html\"></iframe>",
+ "sanitized": "<html><head></head><body><div draggable=\"true\">\n\t<h1>Drop me</h1>\n</div>\n\n</body></html>"
+ },
+ {
+ "data": "<iframe src=\"view-source:http://www.example.org/\" frameborder=\"0\" style=\"width:400px;height:180px\"></iframe>\n\n<textarea type=\"text\" cols=\"50\" rows=\"10\"></textarea>",
+ "sanitized": "<html><head></head><body>\n\n<textarea type=\"text\" cols=\"50\" rows=\"10\"></textarea></body></html>"
+ },
+ {
+ "data": "<script>\nfunction makePopups(){\n\tfor (i=1;i<6;i++) {\n\t\twindow.open('popup.html','spam'+i,'width=50,height=50');\n\t}\n}\n</script>\n\n<body>\n<a href=\"#\" onclick=\"makePopups()\">Spam</a>",
+ "sanitized": "<html><head>\n\n</head><body>\n<a href=\"#\">Spam</a></body></html>"
+ },
+ {
+ "data": "<html xmlns=\"http://www.w3.org/1999/xhtml\"\nxmlns:svg=\"http://www.w3.org/2000/svg\">\n<body style=\"background:gray\">\n<iframe src=\"http://example.com/\" style=\"width:800px; height:350px; border:none; mask: url(#maskForClickjacking);\"/>\n<svg:svg>\n<svg:mask id=\"maskForClickjacking\" maskUnits=\"objectBoundingBox\" maskContentUnits=\"objectBoundingBox\">\n\t<svg:rect x=\"0.0\" y=\"0.0\" width=\"0.373\" height=\"0.3\" fill=\"white\"/>\n\t<svg:circle cx=\"0.45\" cy=\"0.7\" r=\"0.075\" fill=\"white\"/>\n</svg:mask>\n</svg:svg>\n</body>\n</html>",
+ "sanitized": "<html><head></head><body>\n\n&lt;svg:svg&gt;\n&lt;svg:mask id=\"maskForClickjacking\" maskUnits=\"objectBoundingBox\" maskContentUnits=\"objectBoundingBox\"&gt;\n\t&lt;svg:rect x=\"0.0\" y=\"0.0\" width=\"0.373\" height=\"0.3\" fill=\"white\"/&gt;\n\t&lt;svg:circle cx=\"0.45\" cy=\"0.7\" r=\"0.075\" fill=\"white\"/&gt;\n&lt;/svg:mask&gt;\n&lt;/svg:svg&gt;\n&lt;/body&gt;\n&lt;/html&gt;</body></html>"
+ },
+ {
+ "data": "<iframe sandbox=\"allow-same-origin allow-forms allow-scripts\" src=\"http://example.org/\"></iframe>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<span class=foo>Some text</span>\n<a class=bar href=\"http://www.example.org\">www.example.org</a>\n\n<script src=\"http://code.jquery.com/jquery-1.4.4.js\"></script>\n<script>\n$(\"span.foo\").click(function() {\nalert('foo');\n$(\"a.bar\").click();\n});\n$(\"a.bar\").click(function() {\nalert('bar');\nlocation=\"http://html5sec.org\";\n});\n</script>",
+ "sanitized": "<html><head></head><body><span class=\"foo\">Some text</span>\n<a class=\"bar\" href=\"http://www.example.org\">www.example.org</a>\n\n\n</body></html>"
+ },
+ {
+ "data": "<script src=\"/\\example.com\\foo.js\"></script> // Safari 5.0, Chrome 9, 10\n<script src=\"\\\\example.com\\foo.js\"></script> // Safari 5.0",
+ "sanitized": "<html><head> </head><body>// Safari 5.0, Chrome 9, 10\n // Safari 5.0</body></html>"
+ },
+ {
+ "data": "<?xml version=\"1.0\"?>\r\n<?xml-stylesheet type=\"text/xml\" href=\"#stylesheet\"?>\r\n<!DOCTYPE doc [\r\n<!ATTLIST xsl:stylesheet\r\n id ID #REQUIRED>]>\r\n<svg xmlns=\"http://www.w3.org/2000/svg\">\r\n <xsl:stylesheet id=\"stylesheet\" version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\r\n <xsl:template match=\"/\">\r\n <iframe xmlns=\"http://www.w3.org/1999/xhtml\" src=\"javascript:alert(1)\"></iframe>\r\n </xsl:template>\r\n </xsl:stylesheet>\r\n <circle fill=\"red\" r=\"40\"></circle>\r\n</svg>",
+ "sanitized": "<!DOCTYPE doc>\n<html><head></head><body>]&gt;\n\n \n \n \n \n \n \n</body></html>"
+ },
+ {
+ "data": "<object id=\"x\" classid=\"clsid:CB927D12-4FF7-4a9e-A169-56E4B8A75598\"></object>\r\n<object classid=\"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B\" onqt_error=\"alert(1)\" style=\"behavior:url(#x);\"><param name=postdomevents /></object>",
+ "sanitized": "<html><head></head><body>\n</body></html>"
+ },
+ {
+ "data": "<svg xmlns=\"http://www.w3.org/2000/svg\" id=\"x\">\r\n<listener event=\"load\" handler=\"#y\" xmlns=\"http://www.w3.org/2001/xml-events\" observer=\"x\"/>\r\n<handler id=\"y\">alert(1)</handler>\r\n</svg>",
+ "sanitized": "<html><head></head><body>\n\nalert(1)\n</body></html>"
+ },
+ {
+ "data": "<svg><style>&lt;img/src=x onerror=alert(1)// </b>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<svg>\n<image style='filter:url(\"data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22><script>parent.alert(1)</script></svg>\")'>\n<!--\nSame effect with\n<image filter='...'>\n-->\n</svg>",
+ "sanitized": "<html><head></head><body>\n\n\n</body></html>"
+ },
+ {
+ "data": "<math href=\"javascript:alert(1)\">CLICKME</math>\r\n\r\n<math>\r\n<!-- up to FF 13 -->\r\n<maction actiontype=\"statusline#http://google.com\" xlink:href=\"javascript:alert(2)\">CLICKME</maction>\r\n\r\n<!-- FF 14+ -->\r\n<maction actiontype=\"statusline\" xlink:href=\"javascript:alert(3)\">CLICKME<mtext>http://http://google.com</mtext></maction>\r\n</math>",
+ "sanitized": "<html><head></head><body><math>CLICKME</math>\n\n<math>\n\n<maction actiontype=\"statusline#http://google.com\">CLICKME</maction>\n\n\n<maction actiontype=\"statusline\">CLICKME<mtext>http://http://google.com</mtext></maction>\n</math></body></html>"
+ },
+ {
+ "data": "<b>drag and drop one of the following strings to the drop box:</b>\r\n<br/><hr/>\r\njAvascript:alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie);//\r\n<br/><hr/>\r\nfeed:javascript:alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie);//\r\n<br/><hr/>\r\nfeed:data:text/html,&#x3c;script>alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie)&#x3c;/script>&#x3c;b>\r\n<br/><hr/>\r\nfeed:feed:javAscript:javAscript:feed:alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie);//\r\n<br/><hr/>\r\n<div id=\"dropbox\" style=\"height: 360px;width: 500px;border: 5px solid #000;position: relative;\" ondragover=\"event.preventDefault()\">+ Drop Box +</div>",
+ "sanitized": "<html><head></head><body><b>drag and drop one of the following strings to the drop box:</b>\n<br><hr>\njAvascript:alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie);//\n<br><hr>\nfeed:javascript:alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie);//\n<br><hr>\nfeed:data:text/html,&lt;script&gt;alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie)&lt;/script&gt;&lt;b&gt;\n<br><hr>\nfeed:feed:javAscript:javAscript:feed:alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie);//\n<br><hr>\n<div id=\"dropbox\">+ Drop Box +</div></body></html>"
+ },
+ {
+ "data": "<!doctype html>\r\n<form>\r\n<label>type a,b,c,d - watch the network tab/traffic (JS is off, latest NoScript)</label>\r\n<br>\r\n<input name=\"secret\" type=\"password\">\r\n</form>\r\n<!-- injection --><svg height=\"50px\">\r\n<image xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<set attributeName=\"xlink:href\" begin=\"accessKey(a)\" to=\"//example.com/?a\" />\r\n<set attributeName=\"xlink:href\" begin=\"accessKey(b)\" to=\"//example.com/?b\" />\r\n<set attributeName=\"xlink:href\" begin=\"accessKey(c)\" to=\"//example.com/?c\" />\r\n<set attributeName=\"xlink:href\" begin=\"accessKey(d)\" to=\"//example.com/?d\" />\r\n</image>\r\n</svg>",
+ "sanitized": "<!DOCTYPE html>\n<html><head></head><body>\n<label>type a,b,c,d - watch the network tab/traffic (JS is off, latest NoScript)</label>\n<br>\n\n\n\n\n\n\n\n\n\n</body></html>"
+ },
+ {
+ "data": "<!-- `<img/src=xx:xx onerror=alert(1)//--!>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<xmp>\r\n<%\r\n</xmp>\r\n<img alt='%></xmp><img src=xx:x onerror=alert(1)//'>\r\n\r\n<script>\r\nx='<%'\r\n</script> %>/\r\nalert(2)\r\n</script>\r\n\r\nXXX\r\n<style>\r\n*['<!--']{}\r\n</style>\r\n-->{}\r\n*{color:red}</style>",
+ "sanitized": "<html><head></head><body>\n&lt;%\n\n<img alt=\"%&gt;&lt;/xmp&gt;&lt;img src=xx:x onerror=alert(1)//\">\n\n %&gt;/\nalert(2)\n\n\nXXX\n\n--&gt;{}\n*{color:red}</body></html>"
+ },
+ {
+ "data": "<?xml-stylesheet type=\"text/xsl\" href=\"#\" ?>\r\n<stylesheet xmlns=\"http://www.w3.org/TR/WD-xsl\">\r\n<template match=\"/\">\r\n<eval>new ActiveXObject(&apos;htmlfile&apos;).parentWindow.alert(1)</eval>\r\n<if expr=\"new ActiveXObject('htmlfile').parentWindow.alert(2)\"></if>\r\n</template>\r\n</stylesheet>",
+ "sanitized": "<html><head></head><body>\n\n</body></html>"
+ },
+ {
+ "data": "<form action=\"\" method=\"post\">\r\n<input name=\"username\" value=\"admin\" />\r\n<input name=\"password\" type=\"password\" value=\"secret\" />\r\n<input name=\"injected\" value=\"injected\" dirname=\"password\" />\r\n<input type=\"submit\">\r\n</form>",
+ "sanitized": "<html><head></head><body>\n\n\n\n\n</body></html>"
+ },
+ {
+ "data": "<SCRIPT>alert('XSS');</SCRIPT>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "'';!--\"<XSS>=&{()}",
+ "sanitized": "<html><head></head><body>'';!--\"=&amp;{()}</body></html>"
+ },
+ {
+ "data": "<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<IMG SRC=\"javascript:alert('XSS');\">",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<IMG SRC=javascript:alert('XSS')>",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<IMG SRC=JaVaScRiPt:alert('XSS')>",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<IMG SRC=javascript:alert(&quot;XSS&quot;)>",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<IMG SRC=`javascript:alert(\"RSnake says, 'XSS'\")`>",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "SRC=&#10<IMG 6;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>",
+ "sanitized": "<html><head></head><body>SRC=\n<img></body></html>"
+ },
+ {
+ "data": "<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<IMG SRC=\"javascript:alert('XSS');\">",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<IMG SRC=\"jav&#x09;ascript:alert('XSS');\">",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<IMG SRC=\"jav&#x0A;ascript:alert('XSS');\">",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<IMG SRC=\"jav&#x0D;ascript:alert('XSS');\">",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<IMG SRC=\" &#14; javascript:alert('XSS');\">",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<SCRIPT/XSS SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<SCRIPT SRC=http://ha.ckers.org/xss.js?<B>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<IMG SRC=\"javascript:alert('XSS')\"",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<SCRIPT>a=/XSS/",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "\\\";alert('XSS');//",
+ "sanitized": "<html><head></head><body>\\\";alert('XSS');//</body></html>"
+ },
+ {
+ "data": "<INPUT TYPE=\"IMAGE\" SRC=\"javascript:alert('XSS');\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<BODY BACKGROUND=\"javascript:alert('XSS')\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<BODY ONLOAD=alert('XSS')>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<IMG DYNSRC=\"javascript:alert('XSS')\">",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<IMG LOWSRC=\"javascript:alert('XSS')\">",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<BGSOUND SRC=\"javascript:alert('XSS');\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<BR SIZE=\"&{alert('XSS')}\">",
+ "sanitized": "<html><head></head><body><br></body></html>"
+ },
+ {
+ "data": "<LAYER SRC=\"http://ha.ckers.org/scriptlet.html\"></LAYER>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<LINK REL=\"stylesheet\" HREF=\"javascript:alert('XSS');\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<LINK REL=\"stylesheet\" HREF=\"http://ha.ckers.org/xss.css\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<STYLE>@import'http://ha.ckers.org/xss.css';</STYLE>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<META HTTP-EQUIV=\"Link\" Content=\"<http://ha.ckers.org/xss.css>; REL=stylesheet\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<STYLE>BODY{-moz-binding:url(\"http://ha.ckers.org/xssmoz.xml#xss\")}</STYLE>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<IMG SRC='vbscript:msgbox(\"XSS\")'>",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<IMG SRC=\"mocha:[code]\">",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<IMG SRC=\"livescript:[code]\">",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<META HTTP-EQUIV=\"refresh\" CONTENT=\"0;url=javascript:alert('XSS');\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<META HTTP-EQUIV=\"refresh\" CONTENT=\"0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<META HTTP-EQUIV=\"Link\" Content=\"<javascript:alert('XSS')>; REL=stylesheet\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<META HTTP-EQUIV=\"refresh\" CONTENT=\"0; URL=http://;URL=javascript:alert('XSS');\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<IFRAME SRC=\"javascript:alert('XSS');\"></IFRAME>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<FRAMESET><FRAME SRC=\"javascript:alert('XSS');\"></FRAMESET>",
+ "sanitized": "<html><head></head></html>"
+ },
+ {
+ "data": "<TABLE BACKGROUND=\"javascript:alert('XSS')\">",
+ "sanitized": "<html><head></head><body><table></table></body></html>"
+ },
+ {
+ "data": "<DIV STYLE=\"background-image: url(javascript:alert('XSS'))\">",
+ "sanitized": "<html><head></head><body><div></div></body></html>"
+ },
+ {
+ "data": "<DIV STYLE=\"background-image: url(&#1;javascript:alert('XSS'))\">",
+ "sanitized": "<html><head></head><body><div></div></body></html>"
+ },
+ {
+ "data": "<DIV STYLE=\"width: expression(alert('XSS'));\">",
+ "sanitized": "<html><head></head><body><div></div></body></html>"
+ },
+ {
+ "data": "<STYLE>@im\\port'\\ja\\vasc\\ript:alert(\"XSS\")';</STYLE>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<IMG STYLE=\"xss:expr/*XSS*/ession(alert('XSS'))\">",
+ "sanitized": "<html><head></head><body><img></body></html>"
+ },
+ {
+ "data": "<XSS STYLE=\"xss:expression(alert('XSS'))\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "exp/*<XSS STYLE='no\\xss:noxss(\"*//*\");",
+ "sanitized": "<html><head></head><body>exp/*</body></html>"
+ },
+ {
+ "data": "<STYLE TYPE=\"text/javascript\">alert('XSS');</STYLE>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<STYLE>.XSS{background-image:url(\"javascript:alert('XSS')\");}</STYLE><A CLASS=XSS></A>",
+ "sanitized": "<html><head></head><body><a class=\"XSS\"></a></body></html>"
+ },
+ {
+ "data": "<STYLE type=\"text/css\">BODY{background:url(\"javascript:alert('XSS')\")}</STYLE>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<BASE HREF=\"javascript:alert('XSS');//\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<OBJECT TYPE=\"text/x-scriptlet\" DATA=\"http://ha.ckers.org/scriptlet.html\"></OBJECT>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<OBJECT classid=clsid:ae24fdae-03c6-11d1-8b76-0080c744f389><param name=url value=javascript:alert('XSS')></OBJECT>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "getURL(\"javascript:alert('XSS')\")",
+ "sanitized": "<html><head></head><body>getURL(\"javascript:alert('XSS')\")</body></html>"
+ },
+ {
+ "data": "a=\"get\";",
+ "sanitized": "<html><head></head><body>a=\"get\";</body></html>"
+ },
+ {
+ "data": "<!--<value><![CDATA[<XML ID=I><X><C><![CDATA[<IMG SRC=\"javas<![CDATA[cript:alert('XSS');\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<XML SRC=\"http://ha.ckers.org/xsstest.xml\" ID=I></XML>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<HTML><BODY>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<SCRIPT SRC=\"http://ha.ckers.org/xss.jpg\"></SCRIPT>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<!--#exec cmd=\"/bin/echo '<SCRIPT SRC'\"--><!--#exec cmd=\"/bin/echo '=http://ha.ckers.org/xss.js></SCRIPT>'\"-->",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<? echo('<SCR)';",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<META HTTP-EQUIV=\"Set-Cookie\" Content=\"USERID=&lt;SCRIPT&gt;alert('XSS')&lt;/SCRIPT&gt;\">",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<HEAD><META HTTP-EQUIV=\"CONTENT-TYPE\" CONTENT=\"text/html; charset=UTF-7\"> </HEAD>+ADw-SCRIPT+AD4-alert('XSS');+ADw-/SCRIPT+AD4-",
+ "sanitized": "<html><head> </head><body>+ADw-SCRIPT+AD4-alert('XSS');+ADw-/SCRIPT+AD4-</body></html>"
+ },
+ {
+ "data": "<SCRIPT a=\">\" SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<SCRIPT a=\">\" '' SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<SCRIPT \"a='>'\" SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<SCRIPT a=`>` SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>",
+ "sanitized": "<html><head></head><body></body></html>"
+ },
+ {
+ "data": "<SCRIPT>document.write(\"<SCRI\");</SCRIPT>PT SRC",
+ "sanitized": "<html><head></head><body>PT SRC</body></html>"
+ },
+ {
+ "data": "",
+ "sanitized": "<html><head></head><body></body></html>"
+ }
+]
diff --git a/parser/xml/test/unit/test_namespace_support.js b/parser/xml/test/unit/test_namespace_support.js
new file mode 100644
index 000000000..bcad61e91
--- /dev/null
+++ b/parser/xml/test/unit/test_namespace_support.js
@@ -0,0 +1,52 @@
+function noop() {}
+
+function run_test() {
+ var contentHandler = {
+ attrs: null,
+ reset: function() {
+ this.attrs = [];
+ },
+ startDocument: noop,
+ endDocument: noop,
+
+ startElement: function startElement(aNamespaceURI, aLocalName, aNodeName, aAttrs) {
+ for (var i = 0; i < aAttrs.length; i++)
+ this.attrs.push(aAttrs.getQName(i));
+ },
+
+ endElement: noop,
+ characters: noop,
+ processingInstruction: noop,
+ ignorableWhitespace: noop,
+ startPrefixMapping: noop,
+ endPrefixMapping: noop
+ };
+
+ const nsISAXXMLReader = Components.interfaces.nsISAXXMLReader;
+ const src = "<a:x xmlns:a='foo' y='bar'/>";
+ const NS_PREFIX = "http://xml.org/sax/features/namespace-prefixes";
+
+ var saxReader = Components.classes["@mozilla.org/saxparser/xmlreader;1"]
+ .createInstance(nsISAXXMLReader);
+ do_check_false(saxReader.getFeature(NS_PREFIX));
+ saxReader.contentHandler = contentHandler;
+ contentHandler.reset();
+ saxReader.parseFromString(src, "application/xml");
+ do_check_eq(contentHandler.attrs.length, 1);
+ do_check_eq(contentHandler.attrs[0], "y");
+
+ saxReader.setFeature(NS_PREFIX, true);
+ do_check_true(saxReader.getFeature(NS_PREFIX));
+ contentHandler.reset();
+ saxReader.parseFromString(src, "application/xml");
+ do_check_eq(contentHandler.attrs.length, 2);
+ do_check_eq(contentHandler.attrs[0], "xmlns:a");
+ do_check_eq(contentHandler.attrs[1], "y");
+
+ saxReader.setFeature(NS_PREFIX, false);
+ do_check_false(saxReader.getFeature(NS_PREFIX));
+ contentHandler.reset();
+ saxReader.parseFromString(src, "application/xml");
+ do_check_eq(contentHandler.attrs.length, 1);
+ do_check_eq(contentHandler.attrs[0], "y");
+}
diff --git a/parser/xml/test/unit/test_parser.js b/parser/xml/test/unit/test_parser.js
new file mode 100644
index 000000000..79c32bae4
--- /dev/null
+++ b/parser/xml/test/unit/test_parser.js
@@ -0,0 +1,167 @@
+function updateDocumentSourceMaps(source) {
+ const nsIDOMNode = Components.interfaces.nsIDOMNode;
+
+ const nsISAXXMLReader = Components.interfaces.nsISAXXMLReader;
+ const saxReader = Components.classes["@mozilla.org/saxparser/xmlreader;1"]
+ .createInstance(nsISAXXMLReader);
+ try {
+ saxReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
+ saxReader.setFeature("http://xml.org/sax/features/namespace", true);
+ }
+ catch (e) {
+ // do nothing, we'll accept it as it is.
+ }
+ var parseErrorLog = [];
+
+ /* XXX ajvincent Because throwing an exception doesn't stop parsing, we need
+ * to record errors and handle them after the parsing is finished.
+ */
+ function do_parse_check(aCondition, aMsg) {
+ if (!aCondition)
+ parseErrorLog[parseErrorLog.length] = aMsg;
+ }
+
+ var contentHandler = {
+ startDocument: function startDocument() {
+ },
+
+ endDocument: function endDocument() {
+ },
+
+ handleAttributes: function handleAttributes(aAttributes) {
+ for (var i = 0; i < aAttributes.length; i++) {
+ var attrNamespaceURI = aAttributes.getURI(i);
+ var attrLocalName = aAttributes.getLocalName(i);
+ var attrNodeName = aAttributes.getQName(i);
+ var value = aAttributes.getValue(i);
+ do_parse_check(attrLocalName, "Missing attribute local name");
+ do_parse_check(attrNodeName, "Missing attribute node name");
+ }
+ },
+
+ startElement: function startElement(aNamespaceURI, aLocalName, aNodeName, aAttributes) {
+ do_parse_check(aLocalName, "Missing element local name (startElement)");
+ do_parse_check(aNodeName, "Missing element node name (startElement)");
+ do_parse_check(aAttributes, "Missing element attributes");
+ this.handleAttributes(aAttributes);
+ },
+
+ endElement: function endElement(aNamespaceURI, aLocalName, aNodeName) {
+ do_parse_check(aLocalName, "Missing element local name (endElement)");
+ do_parse_check(aNodeName, "Missing element node name (endElement)");
+ },
+
+ inCDataSection: false,
+
+ characters: function characters(aData) {
+ },
+
+ processingInstruction: function processingInstruction(aTarget, aData) {
+ do_parse_check(aTarget, "Missing processing instruction target");
+ },
+
+ ignorableWhitespace: function ignorableWhitespace(aWhitespace) {
+ },
+
+ startPrefixMapping: function startPrefixMapping(aPrefix, aURI) {
+ },
+
+ endPrefixMapping: function endPrefixMapping(aPrefix) {
+ }
+ };
+
+ var lexicalHandler = {
+ comment: function comment(aContents) {
+ },
+
+ startDTD: function startDTD(aName, aPublicId, aSystemId) {
+ do_parse_check(aName, "Missing DTD name");
+ },
+
+ endDTD: function endDTD() {
+ },
+
+ startCDATA: function startCDATA() {
+ },
+
+ endCDATA: function endCDATA() {
+ },
+
+ startEntity: function startEntity(aName) {
+ do_parse_check(aName, "Missing entity name (startEntity)");
+ },
+
+ endEntity: function endEntity(aName) {
+ do_parse_check(aName, "Missing entity name (endEntity)");
+ }
+ };
+
+ var dtdHandler = {
+ notationDecl: function notationDecl(aName, aPublicId, aSystemId) {
+ do_parse_check(aName, "Missing notation name");
+ },
+
+ unparsedEntityDecl:
+ function unparsedEntityDecl(aName, aPublicId, aSystemId, aNotationName) {
+ do_parse_check(aName, "Missing entity name (unparsedEntityDecl)");
+ }
+ };
+
+ var errorHandler = {
+ error: function error(aLocator, aError) {
+ do_parse_check(!aError, "XML error");
+ },
+
+ fatalError: function fatalError(aLocator, aError) {
+ do_parse_check(!aError, "XML fatal error");
+ },
+
+ ignorableWarning: function ignorableWarning(aLocator, aError) {
+ do_parse_check(!aError, "XML ignorable warning");
+ }
+ };
+
+ saxReader.contentHandler = contentHandler;
+ saxReader.lexicalHandler = lexicalHandler;
+ saxReader.dtdHandler = dtdHandler;
+ saxReader.errorHandler = errorHandler;
+
+ saxReader.parseFromString(source, "application/xml");
+
+ // Just in case it leaks.
+ saxReader.contentHandler = null;
+ saxReader.lexicalHandler = null;
+ saxReader.dtdHandler = null;
+ saxReader.errorHandler = null;
+
+ return parseErrorLog;
+}
+
+function do_check_true_with_dump(aCondition, aParseLog) {
+ if (!aCondition) {
+ dump(aParseLog.join("\n"));
+ }
+ do_check_true(aCondition);
+}
+
+function run_test() {
+ var src;
+ src = "<!DOCTYPE foo>\n<!-- all your foo are belong to bar -->";
+ src += "<foo id='foo'>\n<?foo wooly bully?>\nfoo";
+ src += "<![CDATA[foo fighters]]></foo>\n";
+ var parseErrorLog = updateDocumentSourceMaps(src);
+
+ if (parseErrorLog.length > 0) {
+ dump(parseErrorLog.join("\n"));
+ }
+ do_check_true_with_dump(parseErrorLog.length == 0, parseErrorLog);
+
+ // End tag isn't well-formed.
+ src = "<!DOCTYPE foo>\n<!-- all your foo are belong to bar -->";
+ src += "<foo id='foo'>\n<?foo wooly bully?>\nfoo";
+ src += "<![CDATA[foo fighters]]></foo\n";
+
+ parseErrorLog = updateDocumentSourceMaps(src);
+
+ do_check_true_with_dump(parseErrorLog.length == 1 && parseErrorLog[0] == "XML fatal error", parseErrorLog);
+}
diff --git a/parser/xml/test/unit/test_sanitizer.js b/parser/xml/test/unit/test_sanitizer.js
new file mode 100644
index 000000000..b8aaa1e08
--- /dev/null
+++ b/parser/xml/test/unit/test_sanitizer.js
@@ -0,0 +1,21 @@
+function run_test() {
+ var Ci = Components.interfaces;
+ var Cc = Components.classes;
+
+ // vectors by the html5security project (https://code.google.com/p/html5security/ & Creative Commons 3.0 BY), see CC-BY-LICENSE for the full license
+ load("results.js"); // gives us a `vectors' array
+
+ var ParserUtils = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils);
+ var sanitizeFlags = ParserUtils.SanitizerCidEmbedsOnly|ParserUtils.SanitizerDropForms|ParserUtils.SanitizerDropNonCSSPresentation;
+ // flags according to
+ // http://mxr.mozilla.org/comm-central/source/mailnews/mime/src/mimemoz2.cpp#2218
+ // and default settings
+
+
+ for (var item in vectors) {
+ var evil = vectors[item].data;
+ var sanitized = vectors[item].sanitized;
+ var out = ParserUtils.sanitize(evil, sanitizeFlags);
+ do_check_eq(sanitized, out);
+ }
+}
diff --git a/parser/xml/test/unit/test_xml_declaration.js b/parser/xml/test/unit/test_xml_declaration.js
new file mode 100644
index 000000000..4cad511fb
--- /dev/null
+++ b/parser/xml/test/unit/test_xml_declaration.js
@@ -0,0 +1,82 @@
+function noop() {}
+
+function run_test() {
+ var evts;
+
+ var contentHandler = {
+ attrs: null,
+ startDocument: function() {
+ evts.push("startDocument");
+ },
+ endDocument: noop,
+
+ startElement: function startElement() {
+ evts.push("startElement");
+ },
+
+ endElement: noop,
+ characters: noop,
+ processingInstruction: noop,
+ ignorableWhitespace: noop,
+ startPrefixMapping: noop,
+ endPrefixMapping: noop
+ };
+
+ function XMLDeclHandler(version, encoding, standalone) {
+ evts.splice(evts.length, 0, version, encoding, standalone);
+ }
+
+ const nsISAXXMLReader = Components.interfaces.nsISAXXMLReader;
+ var saxReader = Components.classes["@mozilla.org/saxparser/xmlreader;1"]
+ .createInstance(nsISAXXMLReader);
+ saxReader.contentHandler = contentHandler;
+ saxReader.declarationHandler = XMLDeclHandler;
+
+ evts = [];
+ saxReader.parseFromString("<root/>", "application/xml");
+ do_check_eq(evts.length, 2);
+ do_check_eq(evts[0], "startDocument");
+ do_check_eq(evts[1], "startElement");
+
+ evts = [];
+ saxReader.parseFromString("<?xml version='1.0'?><root/>", "application/xml");
+ do_check_eq(evts.length, 5);
+ do_check_eq(evts[0], "startDocument");
+ do_check_eq(evts[1], "1.0");
+ do_check_eq(evts[2], "");
+ do_check_false(evts[3]);
+ do_check_eq(evts[4], "startElement");
+
+ evts = [];
+ saxReader.parseFromString("<?xml version='1.0' encoding='UTF-8'?><root/>", "application/xml");
+ do_check_eq(evts.length, 5);
+ do_check_eq(evts[0], "startDocument");
+ do_check_eq(evts[1], "1.0");
+ do_check_eq(evts[2], "UTF-8");
+ do_check_false(evts[3]);
+ do_check_eq(evts[4], "startElement");
+
+ evts = [];
+ saxReader.parseFromString("<?xml version='1.0' standalone='yes'?><root/>", "application/xml");
+ do_check_eq(evts.length, 5);
+ do_check_eq(evts[0], "startDocument");
+ do_check_eq(evts[1], "1.0");
+ do_check_eq(evts[2], "");
+ do_check_true(evts[3]);
+ do_check_eq(evts[4], "startElement");
+
+ evts = [];
+ saxReader.parseFromString("<?xml version='1.0' encoding='UTF-8' standalone='yes'?><root/>", "application/xml");
+ do_check_eq(evts.length, 5);
+ do_check_eq(evts[0], "startDocument");
+ do_check_eq(evts[1], "1.0");
+ do_check_eq(evts[2], "UTF-8");
+ do_check_true(evts[3]);
+ do_check_eq(evts[4], "startElement");
+
+ evts = [];
+ // Not well-formed
+ saxReader.parseFromString("<?xml encoding='UTF-8'?><root/>", "application/xml");
+ do_check_eq(evts.length, 1);
+ do_check_eq(evts[0], "startDocument");
+}
diff --git a/parser/xml/test/unit/xpcshell.ini b/parser/xml/test/unit/xpcshell.ini
new file mode 100644
index 000000000..78bb604d2
--- /dev/null
+++ b/parser/xml/test/unit/xpcshell.ini
@@ -0,0 +1,9 @@
+[DEFAULT]
+head =
+tail =
+support-files = results.js
+
+[test_parser.js]
+[test_namespace_support.js]
+[test_xml_declaration.js]
+[test_sanitizer.js]