Imported Upstream version 1.4+r1.3.1
Markus Koschany
8 years ago
3 | 3 | |
4 | 4 | /* |
5 | 5 | * Copyright (c) 2005, 2006, 2007 Henri Sivonen |
6 | * Copyright (c) 2007-2012 Mozilla Foundation | |
6 | * Copyright (c) 2007-2011 Mozilla Foundation | |
7 | 7 | * Portions of comments Copyright 2004-2007 Apple Computer, Inc., Mozilla |
8 | 8 | * Foundation, and Opera Software ASA. |
9 | 9 | * |
0 | <!-- | |
1 | * Copyright (c) 2007-2012 Mozilla Foundation | |
2 | * | |
3 | * Permission is hereby granted, free of charge, to any person obtaining a | |
4 | * copy of this software and associated documentation files (the "Software"), | |
5 | * to deal in the Software without restriction, including without limitation | |
6 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
7 | * and/or sell copies of the Software, and to permit persons to whom the | |
8 | * Software is furnished to do so, subject to the following conditions: | |
9 | * | |
10 | * The above copyright notice and this permission notice shall be included in | |
11 | * all copies or substantial portions of the Software. | |
12 | * | |
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
16 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
19 | * DEALINGS IN THE SOFTWARE. | |
20 | --> | |
21 | 0 | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
22 | 1 | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
23 | 2 | <modelVersion>4.0.0</modelVersion> |
24 | 3 | <groupId>nu.validator.htmlparser</groupId> |
25 | 4 | <artifactId>htmlparser</artifactId> |
26 | <packaging>bundle</packaging> | |
27 | <version>1.4</version> | |
5 | <packaging>jar</packaging> | |
6 | <version>1.3.1</version> | |
28 | 7 | <name>htmlparser</name> |
29 | 8 | <url>http://about.validator.nu/htmlparser/</url> |
30 | <description>The Validator.nu HTML Parser is an implementation of the HTML5 parsing algorithm in Java for applications. The parser is designed to work as a drop-in replacement for the XML parser in applications that already support XHTML 1.x content with an XML parser and use SAX, DOM or XOM to interface with the parser.</description> | |
31 | <!-- | |
32 | Usage notes for this POM: | |
33 | ||
34 | To build without signing, run: | |
35 | mvn clean source:jar javadoc:jar repository:bundle-create | |
36 | (enter 0 <return> when prompted) | |
37 | ||
38 | To build and sign, run: | |
39 | mvn clean source:jar javadoc:jar package gpg:sign repository:bundle-create | |
40 | (enter 0 <return> when prompted) | |
41 | ||
42 | This POM file is used for creating the bundle for distribution via the | |
43 | Maven Central Repository. It is not used as part of the normal development | |
44 | process of the parser and the maintainer of the parser (Henri Sivonen) | |
45 | isn't experienced in POM tweaking. If you need this POM to do something | |
46 | that it currently does not do or do something better, you need to write | |
47 | the changes you need yourself and contribute a patch via | |
48 | http://bugzilla.validator.nu/ | |
49 | --> | |
9 | <description>The Validator.nu HTML Parser is an implementation of the HTML5 parsing algorithm in Java for applications that do not run scripts. The parser is designed to work as a drop-in replacement for the XML parser in applications that already support XHTML 1.x content with an XML parser and use SAX, DOM or XOM to interface with the parser.</description> | |
50 | 10 | <developers> |
51 | 11 | <developer> |
52 | 12 | <id>hsivonen</id> |
68 | 28 | </license> |
69 | 29 | </licenses> |
70 | 30 | <scm> |
71 | <connection>scm:hg:http://hg.mozilla.org/projects/htmlparser/</connection> | |
72 | <url>http://hg.mozilla.org/projects/htmlparser/</url> | |
31 | <connection>scm:svn:http://svn.versiondude.net/whattf/htmlparser/</connection> | |
73 | 32 | </scm> |
74 | 33 | <build> |
75 | <sourceDirectory>${project.build.directory}/src</sourceDirectory> | |
34 | <sourceDirectory>${basedir}/src</sourceDirectory> | |
76 | 35 | <testSourceDirectory>${basedir}/test-src</testSourceDirectory> |
77 | 36 | <plugins> |
78 | 37 | <plugin> |
84 | 43 | </configuration> |
85 | 44 | </plugin> |
86 | 45 | <plugin> |
87 | <artifactId>maven-antrun-plugin</artifactId> | |
88 | <version>1.7</version> | |
89 | <dependencies> | |
90 | <dependency> | |
91 | <groupId>com.sun</groupId> | |
92 | <artifactId>tools</artifactId> | |
93 | <version>1.5.0</version> | |
94 | <scope>system</scope> | |
95 | <systemPath>${java.home}/../lib/tools.jar</systemPath> | |
96 | </dependency> | |
97 | </dependencies> | |
98 | <executions> | |
99 | <execution> | |
100 | <id>intitialize-sources</id> | |
101 | <phase>initialize</phase> | |
102 | <goals> | |
103 | <goal>run</goal> | |
104 | </goals> | |
105 | <configuration> | |
106 | <target> | |
107 | <delete dir="${project.build.sourceDirectory}"/> | |
108 | <mkdir dir="${project.build.sourceDirectory}"/> | |
109 | <copy todir="${project.build.sourceDirectory}"> | |
110 | <fileset dir="${basedir}/src"/> | |
111 | </copy> | |
112 | </target> | |
113 | </configuration> | |
114 | </execution> | |
115 | <execution> | |
116 | <id>tokenizer-hotspot-workaround</id> | |
117 | <phase>process-sources</phase> | |
118 | <goals> | |
119 | <goal>run</goal> | |
120 | </goals> | |
121 | <configuration> | |
122 | <target> | |
123 | <property name="translator.sources" value="${basedir}/translator-src"/> | |
124 | <property name="translator.classes" value="${project.build.directory}/translator-classes"/> | |
125 | <mkdir dir="${translator.classes}"/> | |
126 | <javac srcdir="${translator.sources}" includes="nu/validator/htmlparser/generator/ApplyHotSpotWorkaround.java" destdir="${translator.classes}" includeantruntime="false"/> | |
127 | <java classname="nu.validator.htmlparser.generator.ApplyHotSpotWorkaround"> | |
128 | <classpath> | |
129 | <pathelement location="${translator.classes}"/> | |
130 | </classpath> | |
131 | <arg value="${project.build.sourceDirectory}/nu/validator/htmlparser/impl/Tokenizer.java"/> | |
132 | <arg value="${project.build.sourceDirectory}/nu/validator/htmlparser/impl/HotSpotWorkaround.txt"/> | |
133 | </java> | |
134 | </target> | |
135 | </configuration> | |
136 | </execution> | |
137 | </executions> | |
138 | </plugin> | |
139 | <plugin> | |
140 | 46 | <groupId>org.apache.maven.plugins</groupId> |
141 | 47 | <artifactId>maven-surefire-plugin</artifactId> |
142 | 48 | <configuration> |
143 | 49 | <skip>true</skip> |
144 | </configuration> | |
145 | </plugin> | |
146 | <plugin> | |
147 | <groupId>org.apache.felix</groupId> | |
148 | <artifactId>maven-bundle-plugin</artifactId> | |
149 | <version>2.3.7</version> | |
150 | <extensions>true</extensions> | |
151 | <configuration> | |
152 | <archive> | |
153 | <addMavenDescriptor>false</addMavenDescriptor> | |
154 | </archive> | |
155 | <instructions> | |
156 | <Bundle-Name>${project.name}</Bundle-Name> | |
157 | <Bundle-SymbolicName>nu.validator.htmlparser</Bundle-SymbolicName> | |
158 | <Bundle-Version>${project.version}</Bundle-Version> | |
159 | <Bundle-RequiredExecutionEnvironment>J2SE-1.5</Bundle-RequiredExecutionEnvironment> | |
160 | <_removeheaders>Built-By,Bnd-LastModified</_removeheaders> | |
161 | </instructions> | |
162 | 50 | </configuration> |
163 | 51 | </plugin> |
164 | 52 | <plugin> |
234 | 122 | <properties> |
235 | 123 | <rpm.java.dir>/usr/share/java</rpm.java.dir> |
236 | 124 | <rpm.javadoc.dir>/usr/share/javadoc</rpm.javadoc.dir> |
237 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
238 | 125 | </properties> |
239 | 126 | </project> |
350 | 350 | */ |
351 | 351 | @Override public void setErrorHandler(ErrorHandler errorHandler) { |
352 | 352 | treeBuilder.setErrorHandler(errorHandler); |
353 | if (driver != null) { | |
354 | driver.setErrorHandler(errorHandler); | |
355 | } | |
353 | driver.setErrorHandler(errorHandler); | |
356 | 354 | } |
357 | 355 | |
358 | 356 | public void setTransitionHander(TransitionHandler handler) { |
784 | 784 | public static final AttributeName MASK = new AttributeName(ALL_NO_NS, SAME_LOCAL("mask"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
785 | 785 | public static final AttributeName LINK = new AttributeName(ALL_NO_NS, SAME_LOCAL("link"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
786 | 786 | public static final AttributeName LANG = new AttributeName(LANG_NS, SAME_LOCAL("lang"), LANG_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
787 | public static final AttributeName LOOP = new AttributeName(ALL_NO_NS, SAME_LOCAL("loop"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); | |
788 | 787 | public static final AttributeName LIST = new AttributeName(ALL_NO_NS, SAME_LOCAL("list"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
789 | 788 | public static final AttributeName TYPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("type"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED); |
790 | 789 | public static final AttributeName WHEN = new AttributeName(ALL_NO_NS, SAME_LOCAL("when"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
929 | 928 | 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); |
930 | 929 | public static final AttributeName MINSIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("minsize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
931 | 930 | public static final AttributeName MAXSIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("maxsize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
931 | public static final AttributeName LOOPEND = new AttributeName(ALL_NO_NS, SAME_LOCAL("loopend"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); | |
932 | 932 | public static final AttributeName LARGEOP = new AttributeName(ALL_NO_NS, SAME_LOCAL("largeop"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
933 | 933 | public static final AttributeName UNICODE = new AttributeName(ALL_NO_NS, SAME_LOCAL("unicode"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
934 | 934 | public static final AttributeName TARGETX = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("targetx", "targetX"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1026 | 1026 | public static final AttributeName MASKUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("maskunits", "maskUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1027 | 1027 | public static final AttributeName MAXLENGTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("maxlength"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1028 | 1028 | public static final AttributeName LINEBREAK = new AttributeName(ALL_NO_NS, SAME_LOCAL("linebreak"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1029 | public static final AttributeName LOOPSTART = new AttributeName(ALL_NO_NS, SAME_LOCAL("loopstart"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); | |
1029 | 1030 | public static final AttributeName TRANSFORM = new AttributeName(ALL_NO_NS, SAME_LOCAL("transform"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1030 | 1031 | public static final AttributeName V_HANGING = new AttributeName(ALL_NO_NS, SAME_LOCAL("v-hanging"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1031 | 1032 | public static final AttributeName VALUETYPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("valuetype"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED); |
1032 | 1033 | public static final AttributeName POINTSATZ = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("pointsatz", "pointsAtZ"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1033 | 1034 | public static final AttributeName POINTSATX = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("pointsatx", "pointsAtX"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1034 | 1035 | public static final AttributeName POINTSATY = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("pointsaty", "pointsAtY"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1036 | public static final AttributeName PLAYCOUNT = new AttributeName(ALL_NO_NS, SAME_LOCAL("playcount"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); | |
1035 | 1037 | public static final AttributeName SYMMETRIC = new AttributeName(ALL_NO_NS, SAME_LOCAL("symmetric"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1036 | 1038 | public static final AttributeName SCROLLING = new AttributeName(ALL_NO_NS, SAME_LOCAL("scrolling"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED); |
1037 | 1039 | public static final AttributeName REPEATDUR = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("repeatdur", "repeatDur"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1091 | 1093 | public static final AttributeName CELLPADDING = new AttributeName(ALL_NO_NS, SAME_LOCAL("cellpadding"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1092 | 1094 | public static final AttributeName CELLSPACING = new AttributeName(ALL_NO_NS, SAME_LOCAL("cellspacing"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1093 | 1095 | public static final AttributeName COLUMNWIDTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("columnwidth"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1094 | public static final AttributeName CROSSORIGIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("crossorigin"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); | |
1095 | 1096 | public static final AttributeName COLUMNALIGN = new AttributeName(ALL_NO_NS, SAME_LOCAL("columnalign"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1096 | 1097 | public static final AttributeName COLUMNLINES = new AttributeName(ALL_NO_NS, SAME_LOCAL("columnlines"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1097 | 1098 | public static final AttributeName CONTEXTMENU = new AttributeName(ALL_NO_NS, SAME_LOCAL("contextmenu"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); |
1365 | 1366 | MASK, |
1366 | 1367 | LINK, |
1367 | 1368 | LANG, |
1368 | LOOP, | |
1369 | 1369 | LIST, |
1370 | 1370 | TYPE, |
1371 | 1371 | WHEN, |
1510 | 1510 | NOSHADE, |
1511 | 1511 | MINSIZE, |
1512 | 1512 | MAXSIZE, |
1513 | LOOPEND, | |
1513 | 1514 | LARGEOP, |
1514 | 1515 | UNICODE, |
1515 | 1516 | TARGETX, |
1607 | 1608 | MASKUNITS, |
1608 | 1609 | MAXLENGTH, |
1609 | 1610 | LINEBREAK, |
1611 | LOOPSTART, | |
1610 | 1612 | TRANSFORM, |
1611 | 1613 | V_HANGING, |
1612 | 1614 | VALUETYPE, |
1613 | 1615 | POINTSATZ, |
1614 | 1616 | POINTSATX, |
1615 | 1617 | POINTSATY, |
1618 | PLAYCOUNT, | |
1616 | 1619 | SYMMETRIC, |
1617 | 1620 | SCROLLING, |
1618 | 1621 | REPEATDUR, |
1672 | 1675 | CELLPADDING, |
1673 | 1676 | CELLSPACING, |
1674 | 1677 | COLUMNWIDTH, |
1675 | CROSSORIGIN, | |
1676 | 1678 | COLUMNALIGN, |
1677 | 1679 | COLUMNLINES, |
1678 | 1680 | CONTEXTMENU, |
1947 | 1949 | 149809441, |
1948 | 1950 | 150018784, |
1949 | 1951 | 150445028, |
1950 | 150813181, | |
1951 | 1952 | 150923321, |
1952 | 1953 | 152528754, |
1953 | 1954 | 152536216, |
2092 | 2093 | 249533729, |
2093 | 2094 | 250235623, |
2094 | 2095 | 250269543, |
2096 | 251083937, | |
2095 | 2097 | 251402351, |
2096 | 2098 | 252339047, |
2097 | 2099 | 253260911, |
2189 | 2191 | 316797986, |
2190 | 2192 | 317486755, |
2191 | 2193 | 317794164, |
2194 | 318721061, | |
2192 | 2195 | 320076137, |
2193 | 2196 | 322657125, |
2194 | 2197 | 322887778, |
2195 | 2198 | 323506876, |
2196 | 2199 | 323572412, |
2197 | 2200 | 323605180, |
2201 | 323938869, | |
2198 | 2202 | 325060058, |
2199 | 2203 | 325320188, |
2200 | 2204 | 325398738, |
2254 | 2258 | 371448425, |
2255 | 2259 | 371448430, |
2256 | 2260 | 371545055, |
2257 | 371593469, | |
2258 | 2261 | 371596922, |
2259 | 2262 | 371758751, |
2260 | 2263 | 371964792, |
369 | 369 | // return "ANNOTATION_XML"; |
370 | 370 | // case TreeBuilder.FOREIGNOBJECT_OR_DESC: |
371 | 371 | // return "FOREIGNOBJECT_OR_DESC"; |
372 | // case TreeBuilder.MENUITEM: | |
373 | // return "MENUITEM"; | |
374 | 372 | // } |
375 | 373 | // return null; |
376 | 374 | // } |
714 | 712 | public static final ElementName LOWLIMIT = new ElementName("lowlimit", "lowlimit", TreeBuilder.OTHER); |
715 | 713 | public static final ElementName METADATA = new ElementName("metadata", "metadata", TreeBuilder.OTHER); |
716 | 714 | public static final ElementName MENCLOSE = new ElementName("menclose", "menclose", TreeBuilder.OTHER); |
717 | public static final ElementName MENUITEM = new ElementName("menuitem", "menuitem", TreeBuilder.MENUITEM | SPECIAL); | |
718 | 715 | public static final ElementName MPHANTOM = new ElementName("mphantom", "mphantom", TreeBuilder.OTHER); |
719 | 716 | public static final ElementName NOFRAMES = new ElementName("noframes", "noframes", TreeBuilder.NOFRAMES | SPECIAL); |
720 | 717 | public static final ElementName NOSCRIPT = new ElementName("noscript", "noscript", TreeBuilder.NOSCRIPT | SPECIAL); |
1107 | 1104 | LOWLIMIT, |
1108 | 1105 | METADATA, |
1109 | 1106 | MENCLOSE, |
1110 | MENUITEM, | |
1111 | 1107 | MPHANTOM, |
1112 | 1108 | NOFRAMES, |
1113 | 1109 | NOSCRIPT, |
1501 | 1497 | 281683369, |
1502 | 1498 | 282120228, |
1503 | 1499 | 282250732, |
1504 | 282498697, | |
1505 | 1500 | 282508942, |
1506 | 1501 | 283743649, |
1507 | 1502 | 283787570, |
476 | 476 | } |
477 | 477 | |
478 | 478 | @Override protected void errSlashNotFollowedByGt() throws SAXException { |
479 | err("A slash was not immediately followed by \u201C>\u201D."); | |
479 | err("A slash was not immediate followed by \u201C>\u201D."); | |
480 | 480 | } |
481 | 481 | |
482 | 482 | @Override protected void errHtml4XmlVoidSyntax() throws SAXException { |
19 | 19 | * DEALINGS IN THE SOFTWARE. |
20 | 20 | */ |
21 | 21 | |
22 | /** | |
23 | * compressed returnValue: | |
24 | * int returnState = returnValue >> 33 | |
25 | * boolean breakOuterState = ((returnValue >> 32) & 0x1) != 0) | |
26 | * int pos = returnValue & 0xFFFFFFFF // same as (int)returnValue | |
27 | */ | |
28 | 22 | @SuppressWarnings("unused") private long workAroundHotSpotHugeMethodLimit( |
29 | 23 | int state, char c, int pos, @NoLength char[] buf, |
30 | 24 | boolean reconsume, int returnState, int endPos) throws SAXException { |
35 | 29 | long returnStateAndPos = workAroundHotSpotHugeMethodLimit( |
36 | 30 | state, c, pos, buf, reconsume, returnState, endPos); |
37 | 31 | pos = (int)returnStateAndPos; // 5.1.3 in the Java spec |
38 | returnState = (int)(returnStateAndPos >> 33); | |
32 | returnState = (int)(returnStateAndPos >> 32); | |
39 | 33 | state = stateSave; |
40 | if ( (pos == endPos) || ( (((int)(returnStateAndPos >> 32)) & 0x1) != 0) ) { | |
34 | if (pos == endPos) { | |
41 | 35 | break stateloop; |
42 | 36 | } |
43 | 37 | continue stateloop; |
44 | 38 | // END HOTSPOT WORKAROUND |
45 | 39 | default: |
46 | assert !reconsume : "Must not reconsume when returning from HotSpot workaround."; | |
47 | stateSave = state; | |
48 | return (((long)returnState) << 33) | pos; | |
40 | break stateloop; | |
49 | 41 | } |
50 | 42 | } |
51 | 43 | assert !reconsume : "Must not reconsume when returning from HotSpot workaround."; |
52 | 44 | stateSave = state; |
53 | return (((long)returnState) << 33) | (1L << 32) | pos ; | |
45 | return (((long)returnState) << 32) | pos; | |
54 | 46 | } |
577 | 577 | state = MetaScanner.ATTRIBUTE_NAME; |
578 | 578 | continue stateloop; |
579 | 579 | default: |
580 | contentIndex = Integer.MAX_VALUE; | |
581 | charsetIndex = Integer.MAX_VALUE; | |
580 | contentIndex = -1; | |
581 | charsetIndex = -1; | |
582 | 582 | state = MetaScanner.ATTRIBUTE_NAME; |
583 | 583 | continue stateloop; |
584 | 584 | } |
215 | 215 | |
216 | 216 | public static final int SCRIPT_DATA_DOUBLE_ESCAPE_END = 72; |
217 | 217 | |
218 | public static final int PROCESSING_INSTRUCTION = 73; | |
219 | ||
220 | public static final int PROCESSING_INSTRUCTION_QUESTION_MARK = 74; | |
221 | ||
222 | 218 | /** |
223 | 219 | * Magic value for UTF-16 operations. |
224 | 220 | */ |
507 | 503 | private int line; |
508 | 504 | |
509 | 505 | private Interner interner; |
510 | ||
511 | // CPPONLY: private boolean viewingXmlSource; | |
512 | 506 | |
513 | 507 | // [NOCPP[ |
514 | 508 | |
536 | 530 | * @param tokenHandler |
537 | 531 | * the handler for receiving tokens |
538 | 532 | */ |
539 | public Tokenizer(TokenHandler tokenHandler | |
540 | // CPPONLY: , boolean viewingXmlSource | |
541 | ) { | |
533 | public Tokenizer(TokenHandler tokenHandler) { | |
542 | 534 | this.tokenHandler = tokenHandler; |
543 | 535 | this.encodingDeclarationHandler = null; |
544 | 536 | // [NOCPP[ |
552 | 544 | this.publicIdentifier = null; |
553 | 545 | this.systemIdentifier = null; |
554 | 546 | this.attributes = null; |
555 | // CPPONLY: this.viewingXmlSource = viewingXmlSource; | |
556 | 547 | } |
557 | 548 | |
558 | 549 | public void setInterner(Interner interner) { |
564 | 555 | this.publicId = newPublicId; |
565 | 556 | |
566 | 557 | } |
567 | ||
568 | // CPPONLY: boolean isViewingXmlSource() { | |
569 | // CPPONLY: return viewingXmlSource; | |
570 | // CPPONLY: } | |
571 | 558 | |
572 | 559 | // [NOCPP[ |
573 | 560 | |
1130 | 1117 | * switched to the PCDATA state. |
1131 | 1118 | */ |
1132 | 1119 | maybeErrAttributesOnEndTag(attrs); |
1133 | // CPPONLY: if (!viewingXmlSource) { | |
1134 | 1120 | tokenHandler.endTag(tagName); |
1135 | // CPPONLY: } | |
1136 | 1121 | Portability.delete(attributes); |
1137 | 1122 | } else { |
1138 | // CPPONLY: if (viewingXmlSource) { | |
1139 | // CPPONLY: Portability.delete(attributes); | |
1140 | // CPPONLY: } else { | |
1141 | 1123 | tokenHandler.startTag(tagName, attrs, selfClosing); |
1142 | // CPPONLY: } | |
1143 | 1124 | } |
1144 | 1125 | tagName.release(); |
1145 | 1126 | tagName = null; |
1203 | 1184 | attributes.addAttribute(attributeName, "", xmlnsPolicy); |
1204 | 1185 | } |
1205 | 1186 | } else { |
1206 | if (AttributeName.BORDER != attributeName) { | |
1207 | err("Attribute value omitted for a non-boolean attribute. (HTML4-only error.)"); | |
1208 | attributes.addAttribute(attributeName, "", xmlnsPolicy); | |
1209 | } | |
1187 | err("Attribute value omitted for a non-boolean attribute. (HTML4-only error.)"); | |
1188 | attributes.addAttribute(attributeName, "", xmlnsPolicy); | |
1210 | 1189 | } |
1211 | 1190 | } else { |
1212 | 1191 | if (AttributeName.SRC == attributeName |
1240 | 1219 | if (attributeName != null) { |
1241 | 1220 | String val = longStrBufToString(); // Ownership transferred to |
1242 | 1221 | // HtmlAttributes |
1243 | // CPPONLY: if (mViewSource) { | |
1244 | // CPPONLY: mViewSource.MaybeLinkifyAttributeValue(attributeName, val); | |
1245 | // CPPONLY: } | |
1246 | 1222 | // [NOCPP[ |
1247 | 1223 | if (!endTag && html4 && html4ModeCompatibleWithXhtml1Schemata |
1248 | 1224 | && attributeName.isCaseFolded()) { |
1339 | 1315 | * meaning. (The rest of the array is garbage and should not be |
1340 | 1316 | * examined.) |
1341 | 1317 | */ |
1342 | // CPPONLY: if (mViewSource) { | |
1343 | // CPPONLY: mViewSource.SetBuffer(buffer); | |
1344 | // CPPONLY: pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd()); | |
1345 | // CPPONLY: mViewSource.DropBuffer((pos == buffer.getEnd()) ? pos : pos + 1); | |
1346 | // CPPONLY: } else { | |
1347 | // CPPONLY: pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd()); | |
1348 | // CPPONLY: } | |
1349 | // [NOCPP[ | |
1350 | 1318 | pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState, |
1351 | 1319 | buffer.getEnd()); |
1352 | // ]NOCPP] | |
1353 | 1320 | if (pos == buffer.getEnd()) { |
1354 | 1321 | // exiting due to end of buffer |
1355 | 1322 | buffer.setStart(pos); |
1554 | 1521 | state = transition(state, Tokenizer.CLOSE_TAG_OPEN, reconsume, pos); |
1555 | 1522 | continue stateloop; |
1556 | 1523 | case '?': |
1557 | // CPPONLY: if (viewingXmlSource) { | |
1558 | // CPPONLY: state = transition(state, | |
1559 | // CPPONLY: Tokenizer.PROCESSING_INSTRUCTION, | |
1560 | // CPPONLY: reconsume, | |
1561 | // CPPONLY: pos); | |
1562 | // CPPONLY: continue stateloop; | |
1563 | // CPPONLY: } | |
1564 | 1524 | /* |
1565 | 1525 | * U+003F QUESTION MARK (?) Parse error. |
1566 | 1526 | */ |
1600 | 1560 | * the data state. |
1601 | 1561 | */ |
1602 | 1562 | cstart = pos; |
1563 | state = transition(state, Tokenizer.DATA, reconsume, pos); | |
1603 | 1564 | reconsume = true; |
1604 | state = transition(state, Tokenizer.DATA, reconsume, pos); | |
1605 | 1565 | continue stateloop; |
1606 | 1566 | } |
1607 | 1567 | } |
1926 | 1886 | * input character. |
1927 | 1887 | */ |
1928 | 1888 | clearLongStrBuf(); |
1929 | reconsume = true; | |
1930 | 1889 | state = transition(state, Tokenizer.ATTRIBUTE_VALUE_UNQUOTED, reconsume, pos); |
1931 | 1890 | noteUnquotedAttributeValue(); |
1891 | reconsume = true; | |
1932 | 1892 | continue stateloop; |
1933 | 1893 | case '\'': |
1934 | 1894 | /* |
2106 | 2066 | * Reconsume the character in the before |
2107 | 2067 | * attribute name state. |
2108 | 2068 | */ |
2069 | state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos); | |
2109 | 2070 | reconsume = true; |
2110 | state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos); | |
2111 | 2071 | continue stateloop; |
2112 | 2072 | } |
2113 | 2073 | } |
2145 | 2105 | * Reconsume the character in the before attribute |
2146 | 2106 | * name state. |
2147 | 2107 | */ |
2108 | state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos); | |
2148 | 2109 | reconsume = true; |
2149 | state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos); | |
2150 | 2110 | continue stateloop; |
2151 | 2111 | } |
2152 | 2112 | // XXX reorder point |
2396 | 2356 | default: |
2397 | 2357 | errBogusComment(); |
2398 | 2358 | clearLongStrBuf(); |
2359 | state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); | |
2399 | 2360 | reconsume = true; |
2400 | state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); | |
2401 | 2361 | continue stateloop; |
2402 | 2362 | } |
2403 | 2363 | } |
2418 | 2378 | // continue stateloop; |
2419 | 2379 | default: |
2420 | 2380 | errBogusComment(); |
2381 | state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); | |
2421 | 2382 | reconsume = true; |
2422 | state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); | |
2423 | 2383 | continue stateloop; |
2424 | 2384 | } |
2425 | 2385 | } |
2759 | 2719 | appendLongStrBuf(c); |
2760 | 2720 | } else { |
2761 | 2721 | errBogusComment(); |
2722 | state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); | |
2762 | 2723 | reconsume = true; |
2763 | state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); | |
2764 | 2724 | continue stateloop; |
2765 | 2725 | } |
2766 | 2726 | index++; |
2767 | 2727 | continue; |
2768 | 2728 | } else { |
2769 | 2729 | cstart = pos; // start coalescing |
2730 | state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos); | |
2770 | 2731 | reconsume = true; |
2771 | state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos); | |
2772 | 2732 | break; // FALL THROUGH continue stateloop; |
2773 | 2733 | } |
2774 | 2734 | } |
2816 | 2776 | tokenHandler.characters(Tokenizer.RSQB_RSQB, 0, |
2817 | 2777 | 1); |
2818 | 2778 | cstart = pos; |
2779 | state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos); | |
2819 | 2780 | reconsume = true; |
2820 | state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos); | |
2821 | 2781 | continue stateloop; |
2822 | 2782 | } |
2823 | 2783 | } |
2835 | 2795 | default: |
2836 | 2796 | tokenHandler.characters(Tokenizer.RSQB_RSQB, 0, 2); |
2837 | 2797 | cstart = pos; |
2798 | state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos); | |
2838 | 2799 | reconsume = true; |
2839 | state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos); | |
2840 | 2800 | continue stateloop; |
2841 | 2801 | |
2842 | 2802 | } |
2937 | 2897 | if ((returnState & DATA_AND_RCDATA_MASK) == 0) { |
2938 | 2898 | cstart = pos; |
2939 | 2899 | } |
2900 | state = transition(state, returnState, reconsume, pos); | |
2940 | 2901 | reconsume = true; |
2941 | state = transition(state, returnState, reconsume, pos); | |
2942 | 2902 | continue stateloop; |
2943 | 2903 | case '#': |
2944 | 2904 | /* |
2951 | 2911 | default: |
2952 | 2912 | if (c == additional) { |
2953 | 2913 | emitOrAppendStrBuf(returnState); |
2914 | state = transition(state, returnState, reconsume, pos); | |
2954 | 2915 | reconsume = true; |
2955 | state = transition(state, returnState, reconsume, pos); | |
2956 | 2916 | continue stateloop; |
2957 | 2917 | } |
2958 | 2918 | if (c >= 'a' && c <= 'z') { |
2970 | 2930 | if ((returnState & DATA_AND_RCDATA_MASK) == 0) { |
2971 | 2931 | cstart = pos; |
2972 | 2932 | } |
2933 | state = transition(state, returnState, reconsume, pos); | |
2973 | 2934 | reconsume = true; |
2974 | state = transition(state, returnState, reconsume, pos); | |
2975 | 2935 | continue stateloop; |
2976 | 2936 | } |
2977 | 2937 | // Didn't fail yet |
3044 | 3004 | if ((returnState & DATA_AND_RCDATA_MASK) == 0) { |
3045 | 3005 | cstart = pos; |
3046 | 3006 | } |
3007 | state = transition(state, returnState, reconsume, pos); | |
3047 | 3008 | reconsume = true; |
3048 | state = transition(state, returnState, reconsume, pos); | |
3049 | 3009 | continue stateloop; |
3050 | 3010 | } |
3051 | 3011 | // Didn't fail yet |
3108 | 3068 | } |
3109 | 3069 | } |
3110 | 3070 | |
3111 | if (c == ';') { | |
3112 | // If we see a semicolon, there cannot be a | |
3113 | // longer match. Break the loop. However, before | |
3114 | // breaking, take the longest match so far as the | |
3115 | // candidate, if we are just about to complete a | |
3116 | // match. | |
3117 | if (entCol + 1 == NamedCharacters.NAMES[lo].length()) { | |
3118 | candidate = lo; | |
3119 | strBufMark = strBufLen; | |
3120 | } | |
3121 | break outer; | |
3122 | } | |
3123 | ||
3124 | 3071 | if (hi < lo) { |
3125 | 3072 | break outer; |
3126 | 3073 | } |
3138 | 3085 | if ((returnState & DATA_AND_RCDATA_MASK) == 0) { |
3139 | 3086 | cstart = pos; |
3140 | 3087 | } |
3088 | state = transition(state, returnState, reconsume, pos); | |
3141 | 3089 | reconsume = true; |
3142 | state = transition(state, returnState, reconsume, pos); | |
3143 | 3090 | continue stateloop; |
3144 | 3091 | } else { |
3145 | 3092 | // c can't be CR, LF or nul if we got here |
3183 | 3130 | */ |
3184 | 3131 | errNoNamedCharacterMatch(); |
3185 | 3132 | appendStrBufToLongStrBuf(); |
3133 | state = transition(state, returnState, reconsume, pos); | |
3186 | 3134 | reconsume = true; |
3187 | state = transition(state, returnState, reconsume, pos); | |
3188 | 3135 | continue stateloop; |
3189 | 3136 | } |
3190 | 3137 | } |
3201 | 3148 | * second column of the named character references |
3202 | 3149 | * table). |
3203 | 3150 | */ |
3204 | // CPPONLY: completedNamedCharacterReference(); | |
3205 | 3151 | @Const @NoLength char[] val = NamedCharacters.VALUES[candidate]; |
3206 | 3152 | if ( |
3207 | 3153 | // [NOCPP[ |
3215 | 3161 | } |
3216 | 3162 | // this is so complicated! |
3217 | 3163 | if (strBufMark < strBufLen) { |
3164 | // if (strBufOffset != -1) { | |
3165 | // if ((returnState & (~1)) != 0) { | |
3166 | // for (int i = strBufMark; i < strBufLen; i++) { | |
3167 | // appendLongStrBuf(buf[strBufOffset + i]); | |
3168 | // } | |
3169 | // } else { | |
3170 | // tokenHandler.characters(buf, strBufOffset | |
3171 | // + strBufMark, strBufLen | |
3172 | // - strBufMark); | |
3173 | // } | |
3174 | // } else { | |
3218 | 3175 | if ((returnState & DATA_AND_RCDATA_MASK) != 0) { |
3219 | 3176 | for (int i = strBufMark; i < strBufLen; i++) { |
3220 | 3177 | appendLongStrBuf(strBuf[i]); |
3223 | 3180 | tokenHandler.characters(strBuf, strBufMark, |
3224 | 3181 | strBufLen - strBufMark); |
3225 | 3182 | } |
3226 | } | |
3227 | // Check if we broke out early with c being the last | |
3228 | // character that matched as opposed to being the | |
3229 | // first one that didn't match. In the case of an | |
3230 | // early break, the next run on text should start | |
3231 | // *after* the current character and the current | |
3232 | // character shouldn't be reconsumed. | |
3233 | boolean earlyBreak = (c == ';' && strBufMark == strBufLen); | |
3183 | // } | |
3184 | } | |
3234 | 3185 | if ((returnState & DATA_AND_RCDATA_MASK) == 0) { |
3235 | cstart = earlyBreak ? pos + 1 : pos; | |
3236 | } | |
3237 | reconsume = !earlyBreak; | |
3186 | cstart = pos; | |
3187 | } | |
3238 | 3188 | state = transition(state, returnState, reconsume, pos); |
3189 | reconsume = true; | |
3239 | 3190 | continue stateloop; |
3240 | 3191 | /* |
3241 | 3192 | * If the markup contains I'm ¬it; I tell you, the |
3288 | 3239 | * When it comes to interpreting the number, |
3289 | 3240 | * interpret it as a decimal number. |
3290 | 3241 | */ |
3242 | state = transition(state, Tokenizer.DECIMAL_NRC_LOOP, reconsume, pos); | |
3291 | 3243 | reconsume = true; |
3292 | state = transition(state, Tokenizer.DECIMAL_NRC_LOOP, reconsume, pos); | |
3293 | 3244 | // FALL THROUGH continue stateloop; |
3294 | 3245 | } |
3295 | 3246 | // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER |
3355 | 3306 | if ((returnState & DATA_AND_RCDATA_MASK) == 0) { |
3356 | 3307 | cstart = pos; |
3357 | 3308 | } |
3309 | state = transition(state, returnState, reconsume, pos); | |
3358 | 3310 | reconsume = true; |
3359 | state = transition(state, returnState, reconsume, pos); | |
3360 | 3311 | continue stateloop; |
3361 | 3312 | } else { |
3362 | 3313 | errCharRefLacksSemicolon(); |
3363 | 3314 | if ((returnState & DATA_AND_RCDATA_MASK) == 0) { |
3364 | 3315 | cstart = pos; |
3365 | 3316 | } |
3317 | state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos); | |
3366 | 3318 | reconsume = true; |
3367 | state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos); | |
3368 | 3319 | // FALL THROUGH continue stateloop; |
3369 | 3320 | break decimalloop; |
3370 | 3321 | } |
3445 | 3396 | if ((returnState & DATA_AND_RCDATA_MASK) == 0) { |
3446 | 3397 | cstart = pos; |
3447 | 3398 | } |
3399 | state = transition(state, returnState, reconsume, pos); | |
3448 | 3400 | reconsume = true; |
3449 | state = transition(state, returnState, reconsume, pos); | |
3450 | 3401 | continue stateloop; |
3451 | 3402 | } else { |
3452 | 3403 | errCharRefLacksSemicolon(); |
3453 | 3404 | if ((returnState & DATA_AND_RCDATA_MASK) == 0) { |
3454 | 3405 | cstart = pos; |
3455 | 3406 | } |
3407 | state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos); | |
3456 | 3408 | reconsume = true; |
3457 | state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos); | |
3458 | 3409 | continue stateloop; |
3459 | 3410 | } |
3460 | 3411 | } |
3683 | 3634 | * the data state. |
3684 | 3635 | */ |
3685 | 3636 | cstart = pos; |
3637 | state = transition(state, returnState, reconsume, pos); | |
3686 | 3638 | reconsume = true; |
3687 | state = transition(state, returnState, reconsume, pos); | |
3688 | 3639 | continue stateloop; |
3689 | 3640 | } |
3690 | 3641 | } |
3715 | 3666 | 0, 2); |
3716 | 3667 | emitStrBuf(); |
3717 | 3668 | cstart = pos; |
3669 | state = transition(state, returnState, reconsume, pos); | |
3718 | 3670 | reconsume = true; |
3719 | state = transition(state, returnState, reconsume, pos); | |
3720 | 3671 | continue stateloop; |
3721 | 3672 | } |
3722 | 3673 | appendStrBuf(c); |
3958 | 3909 | * the data state. |
3959 | 3910 | */ |
3960 | 3911 | cstart = pos; |
3912 | state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos); | |
3961 | 3913 | reconsume = true; |
3962 | state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos); | |
3963 | 3914 | continue stateloop; |
3964 | 3915 | } |
3965 | 3916 | } |
3989 | 3940 | * Anything else Reconsume the current input |
3990 | 3941 | * character in the script data state. |
3991 | 3942 | */ |
3943 | state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos); | |
3992 | 3944 | reconsume = true; |
3993 | state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos); | |
3994 | 3945 | continue stateloop; |
3995 | 3946 | } |
3996 | 3947 | } |
4019 | 3970 | * Anything else Reconsume the current input |
4020 | 3971 | * character in the script data state. |
4021 | 3972 | */ |
3973 | state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos); | |
4022 | 3974 | reconsume = true; |
4023 | state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos); | |
4024 | 3975 | continue stateloop; |
4025 | 3976 | } |
4026 | 3977 | } |
4546 | 4497 | appendLongStrBuf(c); |
4547 | 4498 | } else { |
4548 | 4499 | errBogusComment(); |
4500 | state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); | |
4549 | 4501 | reconsume = true; |
4550 | state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos); | |
4551 | 4502 | continue stateloop; |
4552 | 4503 | } |
4553 | 4504 | index++; |
4554 | 4505 | continue; |
4555 | 4506 | } else { |
4507 | state = transition(state, Tokenizer.DOCTYPE, reconsume, pos); | |
4556 | 4508 | reconsume = true; |
4557 | state = transition(state, Tokenizer.DOCTYPE, reconsume, pos); | |
4558 | 4509 | break markupdeclarationdoctypeloop; |
4559 | 4510 | // continue stateloop; |
4560 | 4511 | } |
4602 | 4553 | * Reconsume the current character in the before |
4603 | 4554 | * DOCTYPE name state. |
4604 | 4555 | */ |
4556 | state = transition(state, Tokenizer.BEFORE_DOCTYPE_NAME, reconsume, pos); | |
4605 | 4557 | reconsume = true; |
4606 | state = transition(state, Tokenizer.BEFORE_DOCTYPE_NAME, reconsume, pos); | |
4607 | 4558 | break doctypeloop; |
4608 | 4559 | // continue stateloop; |
4609 | 4560 | } |
4842 | 4793 | if (folded != Tokenizer.UBLIC[index]) { |
4843 | 4794 | bogusDoctype(); |
4844 | 4795 | // forceQuirks = true; |
4796 | state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos); | |
4845 | 4797 | reconsume = true; |
4846 | state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos); | |
4847 | 4798 | continue stateloop; |
4848 | 4799 | } |
4849 | 4800 | index++; |
4850 | 4801 | continue; |
4851 | 4802 | } else { |
4803 | state = transition(state, Tokenizer.AFTER_DOCTYPE_PUBLIC_KEYWORD, reconsume, pos); | |
4852 | 4804 | reconsume = true; |
4853 | state = transition(state, Tokenizer.AFTER_DOCTYPE_PUBLIC_KEYWORD, reconsume, pos); | |
4854 | 4805 | break doctypeublicloop; |
4855 | 4806 | // continue stateloop; |
4856 | 4807 | } |
5438 | 5389 | } |
5439 | 5390 | if (folded != Tokenizer.YSTEM[index]) { |
5440 | 5391 | bogusDoctype(); |
5392 | state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos); | |
5441 | 5393 | reconsume = true; |
5442 | state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos); | |
5443 | 5394 | continue stateloop; |
5444 | 5395 | } |
5445 | 5396 | index++; |
5446 | 5397 | continue stateloop; |
5447 | 5398 | } else { |
5399 | state = transition(state, Tokenizer.AFTER_DOCTYPE_SYSTEM_KEYWORD, reconsume, pos); | |
5448 | 5400 | reconsume = true; |
5449 | state = transition(state, Tokenizer.AFTER_DOCTYPE_SYSTEM_KEYWORD, reconsume, pos); | |
5450 | 5401 | break doctypeystemloop; |
5451 | 5402 | // continue stateloop; |
5452 | 5403 | } |
5750 | 5701 | */ |
5751 | 5702 | continue; |
5752 | 5703 | } |
5753 | } | |
5754 | // XXX reorder point | |
5755 | case PROCESSING_INSTRUCTION: | |
5756 | processinginstructionloop: for (;;) { | |
5757 | if (++pos == endPos) { | |
5758 | break stateloop; | |
5759 | } | |
5760 | c = checkChar(buf, pos); | |
5761 | switch (c) { | |
5762 | case '?': | |
5763 | state = transition( | |
5764 | state, | |
5765 | Tokenizer.PROCESSING_INSTRUCTION_QUESTION_MARK, | |
5766 | reconsume, pos); | |
5767 | break processinginstructionloop; | |
5768 | // continue stateloop; | |
5769 | default: | |
5770 | continue; | |
5771 | } | |
5772 | } | |
5773 | case PROCESSING_INSTRUCTION_QUESTION_MARK: | |
5774 | if (++pos == endPos) { | |
5775 | break stateloop; | |
5776 | } | |
5777 | c = checkChar(buf, pos); | |
5778 | switch (c) { | |
5779 | case '>': | |
5780 | state = transition(state, Tokenizer.DATA, | |
5781 | reconsume, pos); | |
5782 | continue stateloop; | |
5783 | default: | |
5784 | state = transition(state, | |
5785 | Tokenizer.PROCESSING_INSTRUCTION, | |
5786 | reconsume, pos); | |
5787 | continue stateloop; | |
5788 | 5704 | } |
5789 | 5705 | // END HOTSPOT WORKAROUND |
5790 | 5706 | } |
6767 | 6683 | attributeName = other.attributeName.cloneAttributeName(interner); |
6768 | 6684 | } |
6769 | 6685 | |
6770 | Portability.delete(attributes); | |
6686 | if (attributes != null) { | |
6687 | Portability.delete(attributes); | |
6688 | } | |
6771 | 6689 | if (other.attributes == null) { |
6772 | 6690 | attributes = null; |
6773 | 6691 | } else { |
54 | 54 | import nu.validator.htmlparser.common.XmlViolationPolicy; |
55 | 55 | |
56 | 56 | import org.xml.sax.ErrorHandler; |
57 | import org.xml.sax.Locator; | |
58 | 57 | import org.xml.sax.SAXException; |
59 | 58 | import org.xml.sax.SAXParseException; |
60 | 59 | |
197 | 196 | final static int FONT = 64; |
198 | 197 | |
199 | 198 | final static int KEYGEN = 65; |
200 | ||
201 | final static int MENUITEM = 66; | |
202 | 199 | |
203 | 200 | // start insertion modes |
204 | 201 | |
342 | 339 | // [NOCPP[ |
343 | 340 | |
344 | 341 | private static final @Local String HTML_LOCAL = "html"; |
345 | ||
342 | ||
346 | 343 | // ]NOCPP] |
347 | 344 | |
348 | 345 | private int mode = INITIAL; |
364 | 361 | |
365 | 362 | private DoctypeExpectation doctypeExpectation = DoctypeExpectation.HTML; |
366 | 363 | |
367 | private LocatorImpl firstCommentLocation; | |
368 | ||
369 | 364 | // ]NOCPP] |
370 | 365 | |
371 | 366 | private boolean scriptingEnabled = false; |
480 | 475 | errorHandler.error(spe); |
481 | 476 | } |
482 | 477 | |
478 | /** | |
479 | * Reports a stray start tag. | |
480 | * @param name the name of the stray tag | |
481 | * | |
482 | * @throws SAXException | |
483 | */ | |
484 | private void errStrayStartTag(String name) throws SAXException { | |
485 | err("Stray end tag \u201C" + name + "\u201D."); | |
486 | } | |
487 | ||
488 | /** | |
489 | * Reports a stray end tag. | |
490 | * @param name the name of the stray tag | |
491 | * | |
492 | * @throws SAXException | |
493 | */ | |
494 | private void errStrayEndTag(String name) throws SAXException { | |
495 | err("Stray end tag \u201C" + name + "\u201D."); | |
496 | } | |
497 | ||
498 | /** | |
499 | * Reports a state when elements expected to be closed were not. | |
500 | * | |
501 | * @param eltPos the position of the start tag on the stack of the element | |
502 | * being closed. | |
503 | * @param name the name of the end tag | |
504 | * | |
505 | * @throws SAXException | |
506 | */ | |
507 | private void errUnclosedElements(int eltPos, String name) throws SAXException { | |
508 | errNoCheck("End tag \u201C" + name + "\u201D seen, but there were open elements."); | |
509 | errListUnclosedStartTags(eltPos); | |
510 | } | |
511 | ||
512 | /** | |
513 | * Reports a state when elements expected to be closed ahead of an implied | |
514 | * end tag but were not. | |
515 | * | |
516 | * @param eltPos the position of the start tag on the stack of the element | |
517 | * being closed. | |
518 | * @param name the name of the end tag | |
519 | * | |
520 | * @throws SAXException | |
521 | */ | |
522 | private void errUnclosedElementsImplied(int eltPos, String name) throws SAXException { | |
523 | errNoCheck("End tag \u201C" + name + "\u201D implied, but there were open elements."); | |
524 | errListUnclosedStartTags(eltPos); | |
525 | } | |
526 | ||
527 | /** | |
528 | * Reports a state when elements expected to be closed ahead of an implied | |
529 | * table cell close. | |
530 | * | |
531 | * @param eltPos the position of the start tag on the stack of the element | |
532 | * being closed. | |
533 | * @throws SAXException | |
534 | */ | |
535 | private void errUnclosedElementsCell(int eltPos) throws SAXException { | |
536 | errNoCheck("A table cell was implicitly closed, but there were open elements."); | |
537 | errListUnclosedStartTags(eltPos); | |
538 | } | |
539 | ||
483 | 540 | private void errListUnclosedStartTags(int eltPos) throws SAXException { |
484 | 541 | if (currentPtr != -1) { |
485 | 542 | for (int i = currentPtr; i > eltPos; i--) { |
486 | 543 | reportUnclosedElementNameAndLocation(i); |
487 | 544 | } |
488 | 545 | } |
546 | } | |
547 | ||
548 | /** | |
549 | * Reports arriving at/near end of document with unclosed elements remaining. | |
550 | * | |
551 | * @param message | |
552 | * the message | |
553 | * @throws SAXException | |
554 | */ | |
555 | private void errEndWithUnclosedElements(String message) throws SAXException { | |
556 | if (errorHandler == null) { | |
557 | return; | |
558 | } | |
559 | errNoCheck(message); | |
560 | // just report all remaining unclosed elements | |
561 | errListUnclosedStartTags(0); | |
489 | 562 | } |
490 | 563 | |
491 | 564 | /** |
520 | 593 | return; |
521 | 594 | } |
522 | 595 | SAXParseException spe = new SAXParseException(message, tokenizer); |
523 | errorHandler.warning(spe); | |
524 | } | |
525 | ||
526 | /** | |
527 | * Reports a warning with an explicit locator | |
528 | * | |
529 | * @param message | |
530 | * the message | |
531 | * @throws SAXException | |
532 | */ | |
533 | final void warn(String message, Locator locator) throws SAXException { | |
534 | if (errorHandler == null) { | |
535 | return; | |
536 | } | |
537 | SAXParseException spe = new SAXParseException(message, locator); | |
538 | 596 | errorHandler.warning(spe); |
539 | 597 | } |
540 | 598 | |
555 | 613 | html4 = false; |
556 | 614 | idLocations.clear(); |
557 | 615 | wantingComments = wantsComments(); |
558 | firstCommentLocation = null; | |
559 | 616 | // ]NOCPP] |
560 | 617 | start(fragment); |
561 | 618 | charBufferLen = 0; |
595 | 652 | contextNode = null; |
596 | 653 | } else { |
597 | 654 | mode = INITIAL; |
598 | // If we are viewing XML source, put a foreign element permanently | |
599 | // on the stack so that cdataSectionAllowed() returns true. | |
600 | // CPPONLY: if (tokenizer.isViewingXmlSource()) { | |
601 | // CPPONLY: T elt = createElement("http://www.w3.org/2000/svg", | |
602 | // CPPONLY: "svg", | |
603 | // CPPONLY: tokenizer.emptyAttributes()); | |
604 | // CPPONLY: StackNode<T> node = new StackNode<T>(ElementName.SVG, | |
605 | // CPPONLY: "svg", | |
606 | // CPPONLY: elt); | |
607 | // CPPONLY: currentPtr++; | |
608 | // CPPONLY: stack[currentPtr] = node; | |
609 | // CPPONLY: } | |
610 | 655 | } |
611 | 656 | } |
612 | 657 | |
633 | 678 | // ]NOCPP] |
634 | 679 | if (isQuirky(name, publicIdentifier, |
635 | 680 | systemIdentifier, forceQuirks)) { |
636 | errQuirkyDoctype(); | |
681 | err("Quirky doctype. Expected \u201C<!DOCTYPE html>\u201D."); | |
637 | 682 | documentModeInternal(DocumentMode.QUIRKS_MODE, |
638 | 683 | publicIdentifier, systemIdentifier, |
639 | 684 | false); |
640 | 685 | } else if (isAlmostStandards(publicIdentifier, |
641 | 686 | systemIdentifier)) { |
642 | // [NOCPP[ | |
643 | if (firstCommentLocation != null) { | |
644 | warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); | |
645 | } | |
646 | // ]NOCPP] | |
647 | errAlmostStandardsDoctype(); | |
687 | err("Almost standards mode doctype. Expected \u201C<!DOCTYPE html>\u201D."); | |
648 | 688 | documentModeInternal( |
649 | 689 | DocumentMode.ALMOST_STANDARDS_MODE, |
650 | 690 | publicIdentifier, systemIdentifier, |
651 | 691 | false); |
652 | 692 | } else { |
653 | 693 | // [NOCPP[ |
654 | if (firstCommentLocation != null) { | |
655 | warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); | |
656 | } | |
657 | 694 | if ((Portability.literalEqualsString( |
658 | 695 | "-//W3C//DTD HTML 4.0//EN", |
659 | 696 | publicIdentifier) && (systemIdentifier == null || Portability.literalEqualsString( |
700 | 737 | true); |
701 | 738 | } else if (isAlmostStandards(publicIdentifier, |
702 | 739 | systemIdentifier)) { |
703 | if (firstCommentLocation != null) { | |
704 | warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); | |
705 | } | |
706 | 740 | 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."); |
707 | 741 | documentModeInternal( |
708 | 742 | DocumentMode.ALMOST_STANDARDS_MODE, |
709 | 743 | publicIdentifier, systemIdentifier, |
710 | 744 | true); |
711 | 745 | } else { |
712 | if (firstCommentLocation != null) { | |
713 | warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); | |
714 | } | |
715 | 746 | if ("-//W3C//DTD HTML 4.01//EN".equals(publicIdentifier)) { |
716 | 747 | if (!"http://www.w3.org/TR/html4/strict.dtd".equals(systemIdentifier)) { |
717 | 748 | 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."); |
736 | 767 | true); |
737 | 768 | } else if (isAlmostStandards(publicIdentifier, |
738 | 769 | systemIdentifier)) { |
739 | if (firstCommentLocation != null) { | |
740 | warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); | |
741 | } | |
742 | 770 | if ("-//W3C//DTD HTML 4.01 Transitional//EN".equals(publicIdentifier) |
743 | 771 | && systemIdentifier != null) { |
744 | 772 | if (!"http://www.w3.org/TR/html4/loose.dtd".equals(systemIdentifier)) { |
752 | 780 | publicIdentifier, systemIdentifier, |
753 | 781 | true); |
754 | 782 | } else { |
755 | if (firstCommentLocation != null) { | |
756 | warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); | |
757 | } | |
758 | 783 | 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."); |
759 | 784 | documentModeInternal( |
760 | 785 | DocumentMode.STANDARDS_MODE, |
775 | 800 | html4); |
776 | 801 | } else if (isAlmostStandards(publicIdentifier, |
777 | 802 | systemIdentifier)) { |
778 | if (firstCommentLocation != null) { | |
779 | warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); | |
780 | } | |
781 | 803 | if ("-//W3C//DTD HTML 4.01 Transitional//EN".equals(publicIdentifier)) { |
782 | 804 | if (!"http://www.w3.org/TR/html4/loose.dtd".equals(systemIdentifier)) { |
783 | 805 | 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."); |
790 | 812 | publicIdentifier, systemIdentifier, |
791 | 813 | html4); |
792 | 814 | } else { |
793 | if (firstCommentLocation != null) { | |
794 | warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); | |
795 | } | |
796 | 815 | if ("-//W3C//DTD HTML 4.01//EN".equals(publicIdentifier)) { |
797 | 816 | if (!"http://www.w3.org/TR/html4/strict.dtd".equals(systemIdentifier)) { |
798 | 817 | 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."); |
844 | 863 | /* |
845 | 864 | * A DOCTYPE token Parse error. |
846 | 865 | */ |
847 | errStrayDoctype(); | |
866 | err("Stray doctype."); | |
848 | 867 | /* |
849 | 868 | * Ignore the token. |
850 | 869 | */ |
868 | 887 | throws SAXException { |
869 | 888 | needToDropLF = false; |
870 | 889 | // [NOCPP[ |
871 | if (firstCommentLocation == null) { | |
872 | firstCommentLocation = new LocatorImpl(tokenizer); | |
873 | } | |
874 | 890 | if (!wantingComments) { |
875 | 891 | return; |
876 | 892 | } |
917 | 933 | */ |
918 | 934 | public final void characters(@Const @NoLength char[] buf, int start, int length) |
919 | 935 | throws SAXException { |
920 | // Note: Can't attach error messages to EOF in C++ yet | |
921 | ||
922 | // CPPONLY: if (tokenizer.isViewingXmlSource()) { | |
923 | // CPPONLY: return; | |
924 | // CPPONLY: } | |
925 | 936 | if (needToDropLF) { |
926 | 937 | needToDropLF = false; |
927 | 938 | if (buf[start] == '\n') { |
938 | 949 | case IN_BODY: |
939 | 950 | case IN_CELL: |
940 | 951 | case IN_CAPTION: |
941 | if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) { | |
952 | if (!isInForeign()) { | |
942 | 953 | reconstructTheActiveFormattingElements(); |
943 | 954 | } |
944 | 955 | // fall through |
997 | 1008 | * Reconstruct the active formatting |
998 | 1009 | * elements, if any. |
999 | 1010 | */ |
1000 | if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) { | |
1011 | if (!isInForeign()) { | |
1001 | 1012 | flushCharacters(); |
1002 | 1013 | reconstructTheActiveFormattingElements(); |
1003 | 1014 | } |
1052 | 1063 | err("Non-space characters found without seeing a doctype first. Expected e.g. \u201C<!DOCTYPE html>\u201D."); |
1053 | 1064 | break; |
1054 | 1065 | case HTML: |
1055 | // XXX figure out a way to report this in the Gecko View Source case | |
1056 | 1066 | err("Non-space characters found without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D."); |
1057 | 1067 | break; |
1058 | 1068 | case HTML401_STRICT: |
1149 | 1159 | * Parse error. Act as if an end tag with |
1150 | 1160 | * the tag name "noscript" had been seen |
1151 | 1161 | */ |
1152 | errNonSpaceInNoscriptInHead(); | |
1162 | err("Non-space character inside \u201Cnoscript\u201D inside \u201Chead\u201D."); | |
1153 | 1163 | flushCharacters(); |
1154 | 1164 | pop(); |
1155 | 1165 | mode = IN_HEAD; |
1194 | 1204 | * Reconstruct the active formatting |
1195 | 1205 | * elements, if any. |
1196 | 1206 | */ |
1197 | if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) { | |
1207 | if (!isInForeign()) { | |
1198 | 1208 | flushCharacters(); |
1199 | 1209 | reconstructTheActiveFormattingElements(); |
1200 | 1210 | } |
1222 | 1232 | * current token. |
1223 | 1233 | */ |
1224 | 1234 | if (currentPtr == 0) { |
1225 | errNonSpaceInColgroupInFragment(); | |
1235 | err("Non-space in \u201Ccolgroup\u201D when parsing fragment."); | |
1226 | 1236 | start = i + 1; |
1227 | 1237 | continue; |
1228 | 1238 | } |
1235 | 1245 | case IN_SELECT_IN_TABLE: |
1236 | 1246 | break charactersloop; |
1237 | 1247 | case AFTER_BODY: |
1238 | errNonSpaceAfterBody(); | |
1248 | err("Non-space character after body."); | |
1239 | 1249 | fatal(); |
1240 | 1250 | mode = framesetOk ? FRAMESET_OK : IN_BODY; |
1241 | 1251 | i--; |
1249 | 1259 | /* |
1250 | 1260 | * Parse error. |
1251 | 1261 | */ |
1252 | errNonSpaceInFrameset(); | |
1262 | err("Non-space in \u201Cframeset\u201D."); | |
1253 | 1263 | /* |
1254 | 1264 | * Ignore the token. |
1255 | 1265 | */ |
1264 | 1274 | /* |
1265 | 1275 | * Parse error. |
1266 | 1276 | */ |
1267 | errNonSpaceAfterFrameset(); | |
1277 | err("Non-space after \u201Cframeset\u201D."); | |
1268 | 1278 | /* |
1269 | 1279 | * Ignore the token. |
1270 | 1280 | */ |
1274 | 1284 | /* |
1275 | 1285 | * Parse error. |
1276 | 1286 | */ |
1277 | errNonSpaceInTrailer(); | |
1287 | err("Non-space character in page trailer."); | |
1278 | 1288 | /* |
1279 | 1289 | * Switch back to the main mode and |
1280 | 1290 | * reprocess the token. |
1283 | 1293 | i--; |
1284 | 1294 | continue; |
1285 | 1295 | case AFTER_AFTER_FRAMESET: |
1286 | errNonSpaceInTrailer(); | |
1296 | /* | |
1297 | * Parse error. | |
1298 | */ | |
1299 | err("Non-space character in page trailer."); | |
1287 | 1300 | /* |
1288 | 1301 | * Switch back to the main mode and |
1289 | 1302 | * reprocess the token. |
1309 | 1322 | return; |
1310 | 1323 | } |
1311 | 1324 | if (currentPtr >= 0) { |
1312 | if (isSpecialParentInForeign(stack[currentPtr])) { | |
1325 | StackNode<T> stackNode = stack[currentPtr]; | |
1326 | if (stackNode.ns == "http://www.w3.org/1999/xhtml") { | |
1327 | return; | |
1328 | } | |
1329 | if (stackNode.isHtmlIntegrationPoint()) { | |
1330 | return; | |
1331 | } | |
1332 | if (stackNode.ns == "http://www.w3.org/1998/Math/MathML" | |
1333 | && stackNode.getGroup() == MI_MO_MN_MS_MTEXT) { | |
1313 | 1334 | return; |
1314 | 1335 | } |
1315 | 1336 | accumulateCharacters(REPLACEMENT_CHARACTER, 0, 1); |
1318 | 1339 | |
1319 | 1340 | public final void eof() throws SAXException { |
1320 | 1341 | flushCharacters(); |
1321 | // Note: Can't attach error messages to EOF in C++ yet | |
1322 | 1342 | eofloop: for (;;) { |
1323 | 1343 | if (isInForeign()) { |
1324 | // [NOCPP[ | |
1325 | 1344 | err("End of file in a foreign namespace context."); |
1326 | // ]NOCPP] | |
1327 | 1345 | break eofloop; |
1328 | 1346 | } |
1329 | 1347 | switch (mode) { |
1381 | 1399 | mode = IN_HEAD; |
1382 | 1400 | continue; |
1383 | 1401 | case IN_HEAD: |
1384 | // [NOCPP[ | |
1385 | 1402 | if (errorHandler != null && currentPtr > 1) { |
1386 | errEofWithUnclosedElements(); | |
1387 | } | |
1388 | // ]NOCPP] | |
1403 | errEndWithUnclosedElements("End of file seen and there were open elements."); | |
1404 | } | |
1389 | 1405 | while (currentPtr > 0) { |
1390 | 1406 | popOnEof(); |
1391 | 1407 | } |
1392 | 1408 | mode = AFTER_HEAD; |
1393 | 1409 | continue; |
1394 | 1410 | case IN_HEAD_NOSCRIPT: |
1395 | // [NOCPP[ | |
1396 | errEofWithUnclosedElements(); | |
1397 | // ]NOCPP] | |
1411 | errEndWithUnclosedElements("End of file seen and there were open elements."); | |
1398 | 1412 | while (currentPtr > 1) { |
1399 | 1413 | popOnEof(); |
1400 | 1414 | } |
1430 | 1444 | case HTML: |
1431 | 1445 | break; |
1432 | 1446 | default: |
1433 | errEofWithUnclosedElements(); | |
1447 | errEndWithUnclosedElements("End of file seen and there were open elements."); | |
1434 | 1448 | break openelementloop; |
1435 | 1449 | } |
1436 | 1450 | } |
1437 | 1451 | // ]NOCPP] |
1438 | 1452 | break eofloop; |
1439 | 1453 | case TEXT: |
1440 | // [NOCPP[ | |
1441 | 1454 | if (errorHandler != null) { |
1442 | 1455 | errNoCheck("End of file seen when expecting text or an end tag."); |
1443 | 1456 | errListUnclosedStartTags(0); |
1444 | 1457 | } |
1445 | // ]NOCPP] | |
1446 | 1458 | // XXX mark script as already executed |
1447 | 1459 | if (originalMode == AFTER_HEAD) { |
1448 | 1460 | popOnEof(); |
1456 | 1468 | case IN_SELECT: |
1457 | 1469 | case IN_SELECT_IN_TABLE: |
1458 | 1470 | case IN_FRAMESET: |
1459 | // [NOCPP[ | |
1460 | 1471 | if (errorHandler != null && currentPtr > 0) { |
1461 | errEofWithUnclosedElements(); | |
1462 | } | |
1463 | // ]NOCPP] | |
1472 | errEndWithUnclosedElements("End of file seen and there were open elements."); | |
1473 | } | |
1464 | 1474 | break eofloop; |
1465 | 1475 | case AFTER_BODY: |
1466 | 1476 | case AFTER_FRAMESET: |
1565 | 1575 | case P: |
1566 | 1576 | case PRE_OR_LISTING: |
1567 | 1577 | case TABLE: |
1568 | errHtmlStartTagInForeignContext(name); | |
1578 | err("HTML start tag \u201C" | |
1579 | + name | |
1580 | + "\u201D in a foreign namespace context."); | |
1569 | 1581 | while (!isSpecialParentInForeign(stack[currentPtr])) { |
1570 | 1582 | pop(); |
1571 | 1583 | } |
1574 | 1586 | if (attributes.contains(AttributeName.COLOR) |
1575 | 1587 | || attributes.contains(AttributeName.FACE) |
1576 | 1588 | || attributes.contains(AttributeName.SIZE)) { |
1577 | errHtmlStartTagInForeignContext(name); | |
1589 | err("HTML start tag \u201C" | |
1590 | + name | |
1591 | + "\u201D in a foreign namespace context."); | |
1578 | 1592 | while (!isSpecialParentInForeign(stack[currentPtr])) { |
1579 | 1593 | pop(); |
1580 | 1594 | } |
1622 | 1636 | attributes = null; // CPP |
1623 | 1637 | break starttagloop; |
1624 | 1638 | case TD_OR_TH: |
1625 | errStartTagInTableBody(name); | |
1639 | err("\u201C" + name | |
1640 | + "\u201D start tag in table body."); | |
1626 | 1641 | clearStackBackTo(findLastInTableScopeOrRootTbodyTheadTfoot()); |
1627 | 1642 | appendToCurrentNodeAndPushElement( |
1628 | 1643 | ElementName.TR, |
1665 | 1680 | eltPos = findLastOrRoot(TreeBuilder.TR); |
1666 | 1681 | if (eltPos == 0) { |
1667 | 1682 | assert fragment; |
1668 | errNoTableRowToClose(); | |
1683 | err("No table row to close."); | |
1669 | 1684 | break starttagloop; |
1670 | 1685 | } |
1671 | 1686 | clearStackBackTo(eltPos); |
1719 | 1734 | mode = IN_TABLE_BODY; |
1720 | 1735 | continue starttagloop; |
1721 | 1736 | case TABLE: |
1722 | errTableSeenWhileTableOpen(); | |
1737 | err("Start tag for \u201Ctable\u201D seen but the previous \u201Ctable\u201D is still open."); | |
1723 | 1738 | eltPos = findLastInTableScope(name); |
1724 | 1739 | if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) { |
1725 | 1740 | assert fragment; |
1728 | 1743 | generateImpliedEndTags(); |
1729 | 1744 | // XXX is the next if dead code? |
1730 | 1745 | if (errorHandler != null && !isCurrent("table")) { |
1731 | errNoCheckUnclosedElementsOnStack(); | |
1746 | errNoCheck("Unclosed elements on stack."); | |
1732 | 1747 | } |
1733 | 1748 | while (currentPtr >= eltPos) { |
1734 | 1749 | pop(); |
1773 | 1788 | break starttagloop; |
1774 | 1789 | case FORM: |
1775 | 1790 | if (formPointer != null) { |
1776 | errFormWhenFormOpen(); | |
1791 | err("Saw a \u201Cform\u201D start tag, but there was already an active \u201Cform\u201D element. Nested forms are not allowed. Ignoring the tag."); | |
1777 | 1792 | break starttagloop; |
1778 | 1793 | } else { |
1779 | errStartTagInTable(name); | |
1794 | err("Start tag \u201Cform\u201D seen in \u201Ctable\u201D."); | |
1780 | 1795 | appendVoidFormToCurrent(attributes); |
1781 | 1796 | attributes = null; // CPP |
1782 | 1797 | break starttagloop; |
1783 | 1798 | } |
1784 | 1799 | default: |
1785 | errStartTagInTable(name); | |
1800 | err("Start tag \u201C" + name | |
1801 | + "\u201D seen in \u201Ctable\u201D."); | |
1786 | 1802 | // fall through to IN_BODY |
1787 | 1803 | break intableloop; |
1788 | 1804 | } |
1802 | 1818 | } |
1803 | 1819 | generateImpliedEndTags(); |
1804 | 1820 | if (errorHandler != null && currentPtr != eltPos) { |
1805 | errNoCheckUnclosedElementsOnStack(); | |
1821 | errNoCheck("Unclosed elements on stack."); | |
1806 | 1822 | } |
1807 | 1823 | while (currentPtr >= eltPos) { |
1808 | 1824 | pop(); |
1823 | 1839 | case TD_OR_TH: |
1824 | 1840 | eltPos = findLastInTableScopeTdTh(); |
1825 | 1841 | if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) { |
1826 | errNoCellToClose(); | |
1842 | err("No cell to close."); | |
1827 | 1843 | break starttagloop; |
1828 | 1844 | } else { |
1829 | 1845 | closeTheCell(eltPos); |
1841 | 1857 | errStrayStartTag(name); |
1842 | 1858 | break starttagloop; |
1843 | 1859 | } else { |
1844 | errFramesetStart(); | |
1860 | err("\u201Cframeset\u201D start tag seen."); | |
1845 | 1861 | detachFromParent(stack[1].node); |
1846 | 1862 | while (currentPtr > 0) { |
1847 | 1863 | pop(); |
1912 | 1928 | errStrayStartTag(name); |
1913 | 1929 | break starttagloop; |
1914 | 1930 | } |
1915 | errFooSeenWhenFooOpen(name); | |
1931 | err("\u201Cbody\u201D start tag found but the \u201Cbody\u201D element is already open."); | |
1916 | 1932 | framesetOk = false; |
1917 | 1933 | if (mode == FRAMESET_OK) { |
1918 | 1934 | mode = IN_BODY; |
1934 | 1950 | case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6: |
1935 | 1951 | implicitlyCloseP(); |
1936 | 1952 | if (stack[currentPtr].getGroup() == H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6) { |
1937 | errHeadingWhenHeadingOpen(); | |
1953 | err("Heading cannot be a child of another heading."); | |
1938 | 1954 | pop(); |
1939 | 1955 | } |
1940 | 1956 | appendToCurrentNodeAndPushElementMayFoster( |
1959 | 1975 | break starttagloop; |
1960 | 1976 | case FORM: |
1961 | 1977 | if (formPointer != null) { |
1962 | errFormWhenFormOpen(); | |
1978 | err("Saw a \u201Cform\u201D start tag, but there was already an active \u201Cform\u201D element. Nested forms are not allowed. Ignoring the tag."); | |
1963 | 1979 | break starttagloop; |
1964 | 1980 | } else { |
1965 | 1981 | implicitlyCloseP(); |
2010 | 2026 | case A: |
2011 | 2027 | int activeAPos = findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker("a"); |
2012 | 2028 | if (activeAPos != -1) { |
2013 | errFooSeenWhenFooOpen(name); | |
2029 | err("An \u201Ca\u201D start tag seen with already an active \u201Ca\u201D element."); | |
2014 | 2030 | StackNode<T> activeA = listOfActiveFormattingElements[activeAPos]; |
2015 | 2031 | activeA.retain(); |
2016 | 2032 | adoptionAgencyEndTag("a"); |
2039 | 2055 | case NOBR: |
2040 | 2056 | reconstructTheActiveFormattingElements(); |
2041 | 2057 | if (TreeBuilder.NOT_FOUND_ON_STACK != findLastInScope("nobr")) { |
2042 | errFooSeenWhenFooOpen(name); | |
2058 | err("\u201Cnobr\u201D start tag seen when there was an open \u201Cnobr\u201D element in scope."); | |
2043 | 2059 | adoptionAgencyEndTag("nobr"); |
2044 | 2060 | reconstructTheActiveFormattingElements(); |
2045 | 2061 | } |
2051 | 2067 | case BUTTON: |
2052 | 2068 | eltPos = findLastInScope(name); |
2053 | 2069 | if (eltPos != TreeBuilder.NOT_FOUND_ON_STACK) { |
2054 | errFooSeenWhenFooOpen(name); | |
2070 | err("\u201Cbutton\u201D start tag seen when there was an open \u201Cbutton\u201D element in scope."); | |
2071 | ||
2055 | 2072 | generateImpliedEndTags(); |
2056 | 2073 | if (errorHandler != null |
2057 | 2074 | && !isCurrent(name)) { |
2102 | 2119 | case AREA_OR_WBR: |
2103 | 2120 | reconstructTheActiveFormattingElements(); |
2104 | 2121 | // FALL THROUGH to PARAM_OR_SOURCE_OR_TRACK |
2105 | // CPPONLY: case MENUITEM: | |
2106 | 2122 | case PARAM_OR_SOURCE_OR_TRACK: |
2107 | 2123 | appendVoidElementToCurrentMayFoster( |
2108 | 2124 | elementName, |
2119 | 2135 | attributes = null; // CPP |
2120 | 2136 | break starttagloop; |
2121 | 2137 | case IMAGE: |
2122 | errImage(); | |
2138 | err("Saw a start tag \u201Cimage\u201D."); | |
2123 | 2139 | elementName = ElementName.IMG; |
2124 | 2140 | continue starttagloop; |
2125 | 2141 | case KEYGEN: |
2132 | 2148 | attributes = null; // CPP |
2133 | 2149 | break starttagloop; |
2134 | 2150 | case ISINDEX: |
2135 | errIsindex(); | |
2151 | err("\u201Cisindex\u201D seen."); | |
2136 | 2152 | if (formPointer != null) { |
2137 | 2153 | break starttagloop; |
2138 | 2154 | } |
2281 | 2297 | attributes = null; // CPP |
2282 | 2298 | break starttagloop; |
2283 | 2299 | case RT_OR_RP: |
2300 | /* | |
2301 | * If the stack of open elements has a ruby | |
2302 | * element in scope, then generate implied end | |
2303 | * tags. If the current node is not then a ruby | |
2304 | * element, this is a parse error; pop all the | |
2305 | * nodes from the current node up to the node | |
2306 | * immediately before the bottommost ruby | |
2307 | * element on the stack of open elements. | |
2308 | * | |
2309 | * Insert an HTML element for the token. | |
2310 | */ | |
2284 | 2311 | eltPos = findLastInScope("ruby"); |
2285 | 2312 | if (eltPos != NOT_FOUND_ON_STACK) { |
2286 | 2313 | generateImpliedEndTags(); |
2287 | 2314 | } |
2288 | 2315 | if (eltPos != currentPtr) { |
2289 | if (eltPos != NOT_FOUND_ON_STACK) { | |
2290 | errStartTagSeenWithoutRuby(name); | |
2291 | } else { | |
2292 | errUnclosedChildrenInRuby(); | |
2316 | if (errorHandler != null) { | |
2317 | if (eltPos != NOT_FOUND_ON_STACK) { | |
2318 | ||
2319 | errNoCheck("Start tag \u201C" | |
2320 | + name | |
2321 | + "\u201D seen without a \u201Cruby\u201D element being open."); | |
2322 | } else { | |
2323 | errNoCheck("Unclosed children in \u201Cruby\u201D."); | |
2324 | } | |
2325 | } | |
2326 | while (currentPtr > eltPos) { | |
2327 | pop(); | |
2293 | 2328 | } |
2294 | 2329 | } |
2295 | 2330 | appendToCurrentNodeAndPushElementMayFoster( |
2427 | 2462 | break starttagloop; |
2428 | 2463 | case HEAD: |
2429 | 2464 | /* Parse error. */ |
2430 | errFooSeenWhenFooOpen(name); | |
2465 | err("Start tag for \u201Chead\u201D seen when \u201Chead\u201D was already open."); | |
2431 | 2466 | /* Ignore the token. */ |
2432 | 2467 | break starttagloop; |
2433 | 2468 | default: |
2474 | 2509 | attributes = null; // CPP |
2475 | 2510 | break starttagloop; |
2476 | 2511 | case HEAD: |
2477 | errFooSeenWhenFooOpen(name); | |
2512 | err("Start tag for \u201Chead\u201D seen when \u201Chead\u201D was already open."); | |
2478 | 2513 | break starttagloop; |
2479 | 2514 | case NOSCRIPT: |
2480 | errFooSeenWhenFooOpen(name); | |
2515 | err("Start tag for \u201Cnoscript\u201D seen when \u201Cnoscript\u201D was already open."); | |
2481 | 2516 | break starttagloop; |
2482 | 2517 | default: |
2483 | errBadStartTagInHead(name); | |
2518 | err("Bad start tag in \u201C" + name | |
2519 | + "\u201D in \u201Chead\u201D."); | |
2484 | 2520 | pop(); |
2485 | 2521 | mode = IN_HEAD; |
2486 | 2522 | continue; |
2504 | 2540 | default: |
2505 | 2541 | if (currentPtr == 0) { |
2506 | 2542 | assert fragment; |
2507 | errGarbageInColgroup(); | |
2543 | err("Garbage in \u201Ccolgroup\u201D fragment."); | |
2508 | 2544 | break starttagloop; |
2509 | 2545 | } |
2510 | 2546 | pop(); |
2518 | 2554 | case TR: |
2519 | 2555 | case TD_OR_TH: |
2520 | 2556 | case TABLE: |
2521 | errStartTagWithSelectOpen(name); | |
2557 | err("\u201C" | |
2558 | + name | |
2559 | + "\u201D start tag with \u201Cselect\u201D open."); | |
2522 | 2560 | eltPos = findLastInTableScope("select"); |
2523 | 2561 | if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) { |
2524 | 2562 | assert fragment; |
2563 | 2601 | attributes = null; // CPP |
2564 | 2602 | break starttagloop; |
2565 | 2603 | case SELECT: |
2566 | errStartSelectWhereEndSelectExpected(); | |
2604 | err("\u201Cselect\u201D start tag where end tag expected."); | |
2567 | 2605 | eltPos = findLastInTableScope(name); |
2568 | 2606 | if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) { |
2569 | 2607 | assert fragment; |
2570 | errNoSelectInTableScope(); | |
2608 | err("No \u201Cselect\u201D in table scope."); | |
2571 | 2609 | break starttagloop; |
2572 | 2610 | } else { |
2573 | 2611 | while (currentPtr >= eltPos) { |
2579 | 2617 | case INPUT: |
2580 | 2618 | case TEXTAREA: |
2581 | 2619 | case KEYGEN: |
2582 | errStartTagWithSelectOpen(name); | |
2620 | err("\u201C" | |
2621 | + name | |
2622 | + "\u201D start tag seen in \u201Cselect\2201D."); | |
2583 | 2623 | eltPos = findLastInTableScope("select"); |
2584 | 2624 | if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) { |
2585 | 2625 | assert fragment; |
2673 | 2713 | err("Start tag seen without seeing a doctype first. Expected e.g. \u201C<!DOCTYPE html>\u201D."); |
2674 | 2714 | break; |
2675 | 2715 | case HTML: |
2676 | // ]NOCPP] | |
2677 | errStartTagWithoutDoctype(); | |
2678 | // [NOCPP[ | |
2716 | err("Start tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D."); | |
2679 | 2717 | break; |
2680 | 2718 | case HTML401_STRICT: |
2681 | 2719 | 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."); |
2811 | 2849 | attributes = null; // CPP |
2812 | 2850 | break starttagloop; |
2813 | 2851 | case BASE: |
2814 | errFooBetweenHeadAndBody(name); | |
2852 | err("\u201Cbase\u201D element outside \u201Chead\u201D."); | |
2815 | 2853 | pushHeadPointerOntoStack(); |
2816 | 2854 | appendVoidElementToCurrentMayFoster( |
2817 | 2855 | elementName, |
2821 | 2859 | attributes = null; // CPP |
2822 | 2860 | break starttagloop; |
2823 | 2861 | case LINK_OR_BASEFONT_OR_BGSOUND: |
2824 | errFooBetweenHeadAndBody(name); | |
2862 | err("\u201Clink\u201D element outside \u201Chead\u201D."); | |
2825 | 2863 | pushHeadPointerOntoStack(); |
2826 | 2864 | appendVoidElementToCurrentMayFoster( |
2827 | 2865 | elementName, |
2831 | 2869 | attributes = null; // CPP |
2832 | 2870 | break starttagloop; |
2833 | 2871 | case META: |
2834 | errFooBetweenHeadAndBody(name); | |
2872 | err("\u201Cmeta\u201D element outside \u201Chead\u201D."); | |
2835 | 2873 | checkMetaCharset(attributes); |
2836 | 2874 | pushHeadPointerOntoStack(); |
2837 | 2875 | appendVoidElementToCurrentMayFoster( |
2842 | 2880 | attributes = null; // CPP |
2843 | 2881 | break starttagloop; |
2844 | 2882 | case SCRIPT: |
2845 | errFooBetweenHeadAndBody(name); | |
2883 | err("\u201Cscript\u201D element between \u201Chead\u201D and \u201Cbody\u201D."); | |
2846 | 2884 | pushHeadPointerOntoStack(); |
2847 | 2885 | appendToCurrentNodeAndPushElement( |
2848 | 2886 | elementName, |
2855 | 2893 | break starttagloop; |
2856 | 2894 | case STYLE: |
2857 | 2895 | case NOFRAMES: |
2858 | errFooBetweenHeadAndBody(name); | |
2896 | err("\u201C" | |
2897 | + name | |
2898 | + "\u201D element between \u201Chead\u201D and \u201Cbody\u201D."); | |
2859 | 2899 | pushHeadPointerOntoStack(); |
2860 | 2900 | appendToCurrentNodeAndPushElement( |
2861 | 2901 | elementName, |
2867 | 2907 | attributes = null; // CPP |
2868 | 2908 | break starttagloop; |
2869 | 2909 | case TITLE: |
2870 | errFooBetweenHeadAndBody(name); | |
2910 | err("\u201Ctitle\u201D element outside \u201Chead\u201D."); | |
2871 | 2911 | pushHeadPointerOntoStack(); |
2872 | 2912 | appendToCurrentNodeAndPushElement( |
2873 | 2913 | elementName, |
2930 | 2970 | // fails |
2931 | 2971 | } |
2932 | 2972 | } |
2933 | if (selfClosing) { | |
2934 | errSelfClosing(); | |
2973 | if (errorHandler != null && selfClosing) { | |
2974 | errNoCheck("Self-closing syntax (\u201C/>\u201D) used on a non-void HTML element. Ignoring the slash and treating as a start tag."); | |
2935 | 2975 | } |
2936 | 2976 | if (attributes != HtmlAttributes.EMPTY_ATTRIBUTES) { |
2937 | 2977 | Portability.delete(attributes); |
3147 | 3187 | @Local String name = elementName.name; |
3148 | 3188 | endtagloop: for (;;) { |
3149 | 3189 | if (isInForeign()) { |
3150 | if (stack[currentPtr].name != name) { | |
3151 | errEndTagDidNotMatchCurrentOpenElement(name, stack[currentPtr].popName); | |
3190 | if (errorHandler != null && stack[currentPtr].name != name) { | |
3191 | errNoCheck("End tag \u201C" | |
3192 | + name | |
3193 | + "\u201D did not match the name of the current open element (\u201C" | |
3194 | + stack[currentPtr].popName + "\u201D)."); | |
3152 | 3195 | } |
3153 | 3196 | eltPos = currentPtr; |
3154 | 3197 | for (;;) { |
3170 | 3213 | eltPos = findLastOrRoot(TreeBuilder.TR); |
3171 | 3214 | if (eltPos == 0) { |
3172 | 3215 | assert fragment; |
3173 | errNoTableRowToClose(); | |
3216 | err("No table row to close."); | |
3174 | 3217 | break endtagloop; |
3175 | 3218 | } |
3176 | 3219 | clearStackBackTo(eltPos); |
3181 | 3224 | eltPos = findLastOrRoot(TreeBuilder.TR); |
3182 | 3225 | if (eltPos == 0) { |
3183 | 3226 | assert fragment; |
3184 | errNoTableRowToClose(); | |
3227 | err("No table row to close."); | |
3185 | 3228 | break endtagloop; |
3186 | 3229 | } |
3187 | 3230 | clearStackBackTo(eltPos); |
3196 | 3239 | eltPos = findLastOrRoot(TreeBuilder.TR); |
3197 | 3240 | if (eltPos == 0) { |
3198 | 3241 | assert fragment; |
3199 | errNoTableRowToClose(); | |
3242 | err("No table row to close."); | |
3200 | 3243 | break endtagloop; |
3201 | 3244 | } |
3202 | 3245 | clearStackBackTo(eltPos); |
3295 | 3338 | mode = IN_TABLE; |
3296 | 3339 | break endtagloop; |
3297 | 3340 | case TABLE: |
3298 | errTableClosedWhileCaptionOpen(); | |
3341 | err("\u201Ctable\u201D closed but \u201Ccaption\u201D was still open."); | |
3299 | 3342 | eltPos = findLastInTableScope("caption"); |
3300 | 3343 | if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) { |
3301 | 3344 | break endtagloop; |
3382 | 3425 | case TBODY_OR_THEAD_OR_TFOOT: |
3383 | 3426 | break; |
3384 | 3427 | default: |
3385 | errEndWithUnclosedElements(name); | |
3428 | errEndWithUnclosedElements("End tag for \u201Cbody\u201D seen but there were unclosed elements."); | |
3386 | 3429 | break uncloseloop1; |
3387 | 3430 | } |
3388 | 3431 | } |
3407 | 3450 | case HTML: |
3408 | 3451 | break; |
3409 | 3452 | default: |
3410 | errEndWithUnclosedElements(name); | |
3453 | errEndWithUnclosedElements("End tag for \u201Chtml\u201D seen but there were unclosed elements."); | |
3411 | 3454 | break uncloseloop2; |
3412 | 3455 | } |
3413 | 3456 | } |
3453 | 3496 | case P: |
3454 | 3497 | eltPos = findLastInButtonScope("p"); |
3455 | 3498 | if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) { |
3456 | errNoElementToCloseButEndTagSeen("p"); | |
3499 | err("No \u201Cp\u201D element in scope but a \u201Cp\u201D end tag seen."); | |
3457 | 3500 | // XXX Can the 'in foreign' case happen anymore? |
3458 | 3501 | if (isInForeign()) { |
3459 | errHtmlStartTagInForeignContext(name); | |
3502 | err("HTML start tag \u201C" | |
3503 | + name | |
3504 | + "\u201D in a foreign namespace context."); | |
3460 | 3505 | while (stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") { |
3461 | 3506 | pop(); |
3462 | 3507 | } |
3478 | 3523 | case LI: |
3479 | 3524 | eltPos = findLastInListScope(name); |
3480 | 3525 | if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) { |
3481 | errNoElementToCloseButEndTagSeen(name); | |
3526 | err("No \u201Cli\u201D element in list scope but a \u201Cli\u201D end tag seen."); | |
3482 | 3527 | } else { |
3483 | 3528 | generateImpliedEndTagsExceptFor(name); |
3484 | 3529 | if (errorHandler != null |
3493 | 3538 | case DD_OR_DT: |
3494 | 3539 | eltPos = findLastInScope(name); |
3495 | 3540 | if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) { |
3496 | errNoElementToCloseButEndTagSeen(name); | |
3541 | err("No \u201C" | |
3542 | + name | |
3543 | + "\u201D element in scope but a \u201C" | |
3544 | + name + "\u201D end tag seen."); | |
3497 | 3545 | } else { |
3498 | 3546 | generateImpliedEndTagsExceptFor(name); |
3499 | 3547 | if (errorHandler != null |
3536 | 3584 | } |
3537 | 3585 | break endtagloop; |
3538 | 3586 | case BR: |
3539 | errEndTagBr(); | |
3587 | err("End tag \u201Cbr\u201D."); | |
3540 | 3588 | if (isInForeign()) { |
3541 | errHtmlStartTagInForeignContext(name); | |
3589 | err("HTML start tag \u201C" | |
3590 | + name | |
3591 | + "\u201D in a foreign namespace context."); | |
3542 | 3592 | while (stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") { |
3543 | 3593 | pop(); |
3544 | 3594 | } |
3549 | 3599 | HtmlAttributes.EMPTY_ATTRIBUTES); |
3550 | 3600 | break endtagloop; |
3551 | 3601 | case AREA_OR_WBR: |
3552 | // CPPONLY: case MENUITEM: | |
3553 | 3602 | case PARAM_OR_SOURCE_OR_TRACK: |
3554 | 3603 | case EMBED_OR_IMG: |
3555 | 3604 | case IMAGE: |
3611 | 3660 | case COLGROUP: |
3612 | 3661 | if (currentPtr == 0) { |
3613 | 3662 | assert fragment; |
3614 | errGarbageInColgroup(); | |
3663 | err("Garbage in \u201Ccolgroup\u201D fragment."); | |
3615 | 3664 | break endtagloop; |
3616 | 3665 | } |
3617 | 3666 | pop(); |
3623 | 3672 | default: |
3624 | 3673 | if (currentPtr == 0) { |
3625 | 3674 | assert fragment; |
3626 | errGarbageInColgroup(); | |
3675 | err("Garbage in \u201Ccolgroup\u201D fragment."); | |
3627 | 3676 | break endtagloop; |
3628 | 3677 | } |
3629 | 3678 | pop(); |
3637 | 3686 | case TBODY_OR_THEAD_OR_TFOOT: |
3638 | 3687 | case TR: |
3639 | 3688 | case TD_OR_TH: |
3640 | errEndTagSeenWithSelectOpen(name); | |
3689 | err("\u201C" | |
3690 | + name | |
3691 | + "\u201D end tag with \u201Cselect\u201D open."); | |
3641 | 3692 | if (findLastInTableScope(name) != TreeBuilder.NOT_FOUND_ON_STACK) { |
3642 | 3693 | eltPos = findLastInTableScope("select"); |
3643 | 3694 | if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) { |
3703 | 3754 | break endtagloop; |
3704 | 3755 | } |
3705 | 3756 | default: |
3706 | errEndTagAfterBody(); | |
3757 | err("Saw an end tag after \u201Cbody\u201D had been closed."); | |
3707 | 3758 | mode = framesetOk ? FRAMESET_OK : IN_BODY; |
3708 | 3759 | continue; |
3709 | 3760 | } |
3743 | 3794 | err("End tag seen without seeing a doctype first. Expected e.g. \u201C<!DOCTYPE html>\u201D."); |
3744 | 3795 | break; |
3745 | 3796 | case HTML: |
3746 | // ]NOCPP] | |
3747 | errEndTagSeenWithoutDoctype(); | |
3748 | // [NOCPP[ | |
3797 | err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D."); | |
3749 | 3798 | break; |
3750 | 3799 | case HTML401_STRICT: |
3751 | 3800 | 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."); |
4331 | 4380 | formattingEltStackPos--; |
4332 | 4381 | } |
4333 | 4382 | if (formattingEltStackPos == -1) { |
4334 | errNoElementToCloseButEndTagSeen(name); | |
4383 | err("No element \u201C" + name + "\u201D to close."); | |
4335 | 4384 | removeFromListOfActiveFormattingElements(formattingEltListPos); |
4336 | 4385 | return true; |
4337 | 4386 | } |
4338 | 4387 | if (!inScope) { |
4339 | errNoElementToCloseButEndTagSeen(name); | |
4388 | err("No element \u201C" + name + "\u201D to close."); | |
4340 | 4389 | return true; |
4341 | 4390 | } |
4342 | 4391 | // stackPos now points to the formatting element and it is in scope |
4343 | if (formattingEltStackPos != currentPtr) { | |
4344 | errEndTagViolatesNestingRules(name); | |
4392 | if (errorHandler != null && formattingEltStackPos != currentPtr) { | |
4393 | errNoCheck("End tag \u201C" + name + "\u201D violates nesting rules."); | |
4345 | 4394 | } |
4346 | 4395 | int furthestBlockPos = formattingEltStackPos + 1; |
4347 | 4396 | while (furthestBlockPos <= currentPtr) { |
4716 | 4765 | case ALTER_INFOSET: |
4717 | 4766 | // fall through |
4718 | 4767 | case ALLOW: |
4719 | 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."); | |
4768 | warn("Attribute \u201Cxmlns:xlink\u201D with the value \u201Chttp://www.w3org/1999/xlink\u201D is not serializable as XML 1.0 without changing document semantics."); | |
4720 | 4769 | break; |
4721 | 4770 | case FATAL: |
4722 | 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."); | |
4771 | fatal("Attribute \u201Cxmlns:xlink\u201D with the value \u201Chttp://www.w3org/1999/xlink\u201D is not serializable as XML 1.0 without changing document semantics."); | |
4723 | 4772 | break; |
4724 | 4773 | } |
4725 | 4774 | } |
5275 | 5324 | && stack[currentPtr].ns != "http://www.w3.org/1999/xhtml"; |
5276 | 5325 | } |
5277 | 5326 | |
5278 | private boolean isInForeignButNotHtmlOrMathTextIntegrationPoint() { | |
5279 | if (currentPtr < 0) { | |
5280 | return false; | |
5281 | } | |
5282 | return !isSpecialParentInForeign(stack[currentPtr]); | |
5283 | } | |
5284 | ||
5285 | 5327 | /** |
5286 | 5328 | * The argument MUST be an interned string or <code>null</code>. |
5287 | 5329 | * |
5365 | 5407 | if (charBufferLen > 0) { |
5366 | 5408 | if ((mode == IN_TABLE || mode == IN_TABLE_BODY || mode == IN_ROW) |
5367 | 5409 | && charBufferContainsNonWhitespace()) { |
5368 | errNonSpaceInTable(); | |
5410 | err("Misplaced non-space characters insided a table."); | |
5369 | 5411 | reconstructTheActiveFormattingElements(); |
5370 | 5412 | if (!stack[currentPtr].isFosterParenting()) { |
5371 | 5413 | // reconstructing gave us a new current node |
5672 | 5714 | return currentPtr + 1; |
5673 | 5715 | } |
5674 | 5716 | |
5675 | /** | |
5676 | * Reports a stray start tag. | |
5677 | * @param name the name of the stray tag | |
5678 | * | |
5679 | * @throws SAXException | |
5680 | */ | |
5681 | private void errStrayStartTag(@Local String name) throws SAXException { | |
5682 | err("Stray end tag \u201C" + name + "\u201D."); | |
5683 | } | |
5684 | ||
5685 | /** | |
5686 | * Reports a stray end tag. | |
5687 | * @param name the name of the stray tag | |
5688 | * | |
5689 | * @throws SAXException | |
5690 | */ | |
5691 | private void errStrayEndTag(@Local String name) throws SAXException { | |
5692 | err("Stray end tag \u201C" + name + "\u201D."); | |
5693 | } | |
5694 | ||
5695 | /** | |
5696 | * Reports a state when elements expected to be closed were not. | |
5697 | * | |
5698 | * @param eltPos the position of the start tag on the stack of the element | |
5699 | * being closed. | |
5700 | * @param name the name of the end tag | |
5701 | * | |
5702 | * @throws SAXException | |
5703 | */ | |
5704 | private void errUnclosedElements(int eltPos, @Local String name) throws SAXException { | |
5705 | errNoCheck("End tag \u201C" + name + "\u201D seen, but there were open elements."); | |
5706 | errListUnclosedStartTags(eltPos); | |
5707 | } | |
5708 | ||
5709 | /** | |
5710 | * Reports a state when elements expected to be closed ahead of an implied | |
5711 | * end tag but were not. | |
5712 | * | |
5713 | * @param eltPos the position of the start tag on the stack of the element | |
5714 | * being closed. | |
5715 | * @param name the name of the end tag | |
5716 | * | |
5717 | * @throws SAXException | |
5718 | */ | |
5719 | private void errUnclosedElementsImplied(int eltPos, String name) throws SAXException { | |
5720 | errNoCheck("End tag \u201C" + name + "\u201D implied, but there were open elements."); | |
5721 | errListUnclosedStartTags(eltPos); | |
5722 | } | |
5723 | ||
5724 | /** | |
5725 | * Reports a state when elements expected to be closed ahead of an implied | |
5726 | * table cell close. | |
5727 | * | |
5728 | * @param eltPos the position of the start tag on the stack of the element | |
5729 | * being closed. | |
5730 | * @throws SAXException | |
5731 | */ | |
5732 | private void errUnclosedElementsCell(int eltPos) throws SAXException { | |
5733 | errNoCheck("A table cell was implicitly closed, but there were open elements."); | |
5734 | errListUnclosedStartTags(eltPos); | |
5735 | } | |
5736 | ||
5737 | private void errStrayDoctype() throws SAXException { | |
5738 | err("Stray doctype."); | |
5739 | } | |
5740 | ||
5741 | private void errAlmostStandardsDoctype() throws SAXException { | |
5742 | err("Almost standards mode doctype. Expected \u201C<!DOCTYPE html>\u201D."); | |
5743 | } | |
5744 | ||
5745 | private void errQuirkyDoctype() throws SAXException { | |
5746 | err("Quirky doctype. Expected \u201C<!DOCTYPE html>\u201D."); | |
5747 | } | |
5748 | ||
5749 | private void errNonSpaceInTrailer() throws SAXException { | |
5750 | err("Non-space character in page trailer."); | |
5751 | } | |
5752 | ||
5753 | private void errNonSpaceAfterFrameset() throws SAXException { | |
5754 | err("Non-space after \u201Cframeset\u201D."); | |
5755 | } | |
5756 | ||
5757 | private void errNonSpaceInFrameset() throws SAXException { | |
5758 | err("Non-space in \u201Cframeset\u201D."); | |
5759 | } | |
5760 | ||
5761 | private void errNonSpaceAfterBody() throws SAXException { | |
5762 | err("Non-space character after body."); | |
5763 | } | |
5764 | ||
5765 | private void errNonSpaceInColgroupInFragment() throws SAXException { | |
5766 | err("Non-space in \u201Ccolgroup\u201D when parsing fragment."); | |
5767 | } | |
5768 | ||
5769 | private void errNonSpaceInNoscriptInHead() throws SAXException { | |
5770 | err("Non-space character inside \u201Cnoscript\u201D inside \u201Chead\u201D."); | |
5771 | } | |
5772 | ||
5773 | private void errFooBetweenHeadAndBody(@Local String name) throws SAXException { | |
5774 | if (errorHandler == null) { | |
5775 | return; | |
5776 | } | |
5777 | errNoCheck("\u201C" + name + "\u201D element between \u201Chead\u201D and \u201Cbody\u201D."); | |
5778 | } | |
5779 | ||
5780 | private void errStartTagWithoutDoctype() throws SAXException { | |
5781 | err("Start tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D."); | |
5782 | } | |
5783 | ||
5784 | private void errNoSelectInTableScope() throws SAXException { | |
5785 | err("No \u201Cselect\u201D in table scope."); | |
5786 | } | |
5787 | ||
5788 | private void errStartSelectWhereEndSelectExpected() throws SAXException { | |
5789 | err("\u201Cselect\u201D start tag where end tag expected."); | |
5790 | } | |
5791 | ||
5792 | private void errStartTagWithSelectOpen(@Local String name) | |
5793 | throws SAXException { | |
5794 | if (errorHandler == null) { | |
5795 | return; | |
5796 | } | |
5797 | errNoCheck("\u201C" + name | |
5798 | + "\u201D start tag with \u201Cselect\u201D open."); | |
5799 | } | |
5800 | ||
5801 | private void errBadStartTagInHead(@Local String name) throws SAXException { | |
5802 | if (errorHandler == null) { | |
5803 | return; | |
5804 | } | |
5805 | errNoCheck("Bad start tag in \u201C" + name | |
5806 | + "\u201D in \u201Chead\u201D."); | |
5807 | } | |
5808 | ||
5809 | private void errImage() throws SAXException { | |
5810 | err("Saw a start tag \u201Cimage\u201D."); | |
5811 | } | |
5812 | ||
5813 | private void errIsindex() throws SAXException { | |
5814 | err("\u201Cisindex\u201D seen."); | |
5815 | } | |
5816 | ||
5817 | private void errFooSeenWhenFooOpen(@Local String name) throws SAXException { | |
5818 | if (errorHandler == null) { | |
5819 | return; | |
5820 | } | |
5821 | errNoCheck("An \u201C" + name + "\u201D start tag seen but an element of the same type was already open."); | |
5822 | } | |
5823 | ||
5824 | private void errHeadingWhenHeadingOpen() throws SAXException { | |
5825 | err("Heading cannot be a child of another heading."); | |
5826 | } | |
5827 | ||
5828 | private void errFramesetStart() throws SAXException { | |
5829 | err("\u201Cframeset\u201D start tag seen."); | |
5830 | } | |
5831 | ||
5832 | private void errNoCellToClose() throws SAXException { | |
5833 | err("No cell to close."); | |
5834 | } | |
5835 | ||
5836 | private void errStartTagInTable(@Local String name) throws SAXException { | |
5837 | if (errorHandler == null) { | |
5838 | return; | |
5839 | } | |
5840 | errNoCheck("Start tag \u201C" + name | |
5841 | + "\u201D seen in \u201Ctable\u201D."); | |
5842 | } | |
5843 | ||
5844 | private void errFormWhenFormOpen() throws SAXException { | |
5845 | err("Saw a \u201Cform\u201D start tag, but there was already an active \u201Cform\u201D element. Nested forms are not allowed. Ignoring the tag."); | |
5846 | } | |
5847 | ||
5848 | private void errTableSeenWhileTableOpen() throws SAXException { | |
5849 | err("Start tag for \u201Ctable\u201D seen but the previous \u201Ctable\u201D is still open."); | |
5850 | } | |
5851 | ||
5852 | private void errStartTagInTableBody(@Local String name) throws SAXException { | |
5853 | if (errorHandler == null) { | |
5854 | return; | |
5855 | } | |
5856 | errNoCheck("\u201C" + name + "\u201D start tag in table body."); | |
5857 | } | |
5858 | ||
5859 | private void errEndTagSeenWithoutDoctype() throws SAXException { | |
5860 | err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D."); | |
5861 | } | |
5862 | ||
5863 | private void errEndTagAfterBody() throws SAXException { | |
5864 | err("Saw an end tag after \u201Cbody\u201D had been closed."); | |
5865 | } | |
5866 | ||
5867 | private void errEndTagSeenWithSelectOpen(@Local String name) throws SAXException { | |
5868 | if (errorHandler == null) { | |
5869 | return; | |
5870 | } | |
5871 | errNoCheck("\u201C" + name | |
5872 | + "\u201D end tag with \u201Cselect\u201D open."); | |
5873 | } | |
5874 | ||
5875 | private void errGarbageInColgroup() throws SAXException { | |
5876 | err("Garbage in \u201Ccolgroup\u201D fragment."); | |
5877 | } | |
5878 | ||
5879 | private void errEndTagBr() throws SAXException { | |
5880 | err("End tag \u201Cbr\u201D."); | |
5881 | } | |
5882 | ||
5883 | private void errNoElementToCloseButEndTagSeen(@Local String name) | |
5884 | throws SAXException { | |
5885 | if (errorHandler == null) { | |
5886 | return; | |
5887 | } | |
5888 | errNoCheck("No \u201C" + name + "\u201D element in scope but a \u201C" | |
5889 | + name + "\u201D end tag seen."); | |
5890 | } | |
5891 | ||
5892 | private void errHtmlStartTagInForeignContext(@Local String name) | |
5893 | throws SAXException { | |
5894 | if (errorHandler == null) { | |
5895 | return; | |
5896 | } | |
5897 | errNoCheck("HTML start tag \u201C" + name | |
5898 | + "\u201D in a foreign namespace context."); | |
5899 | } | |
5900 | ||
5901 | private void errTableClosedWhileCaptionOpen() throws SAXException { | |
5902 | err("\u201Ctable\u201D closed but \u201Ccaption\u201D was still open."); | |
5903 | } | |
5904 | ||
5905 | private void errNoTableRowToClose() throws SAXException { | |
5906 | err("No table row to close."); | |
5907 | } | |
5908 | ||
5909 | private void errNonSpaceInTable() throws SAXException { | |
5910 | err("Misplaced non-space characters insided a table."); | |
5911 | } | |
5912 | ||
5913 | private void errUnclosedChildrenInRuby() throws SAXException { | |
5914 | if (errorHandler == null) { | |
5915 | return; | |
5916 | } | |
5917 | errNoCheck("Unclosed children in \u201Cruby\u201D."); | |
5918 | } | |
5919 | ||
5920 | private void errStartTagSeenWithoutRuby(@Local String name) throws SAXException { | |
5921 | if (errorHandler == null) { | |
5922 | return; | |
5923 | } | |
5924 | errNoCheck("Start tag \u201C" | |
5925 | + name | |
5926 | + "\u201D seen without a \u201Cruby\u201D element being open."); | |
5927 | } | |
5928 | ||
5929 | private void errSelfClosing() throws SAXException { | |
5930 | if (errorHandler == null) { | |
5931 | return; | |
5932 | } | |
5933 | errNoCheck("Self-closing syntax (\u201C/>\u201D) used on a non-void HTML element. Ignoring the slash and treating as a start tag."); | |
5934 | } | |
5935 | ||
5936 | private void errNoCheckUnclosedElementsOnStack() throws SAXException { | |
5937 | errNoCheck("Unclosed elements on stack."); | |
5938 | } | |
5939 | ||
5940 | private void errEndTagDidNotMatchCurrentOpenElement(@Local String name, | |
5941 | @Local String currOpenName) throws SAXException { | |
5942 | if (errorHandler == null) { | |
5943 | return; | |
5944 | } | |
5945 | errNoCheck("End tag \u201C" | |
5946 | + name | |
5947 | + "\u201D did not match the name of the current open element (\u201C" | |
5948 | + currOpenName + "\u201D)."); | |
5949 | } | |
5950 | ||
5951 | private void errEndTagViolatesNestingRules(@Local String name) throws SAXException { | |
5952 | if (errorHandler == null) { | |
5953 | return; | |
5954 | } | |
5955 | errNoCheck("End tag \u201C" + name + "\u201D violates nesting rules."); | |
5956 | } | |
5957 | ||
5958 | private void errEofWithUnclosedElements() throws SAXException { | |
5959 | if (errorHandler == null) { | |
5960 | return; | |
5961 | } | |
5962 | errNoCheck("End of file seen and there were open elements."); | |
5963 | // just report all remaining unclosed elements | |
5964 | errListUnclosedStartTags(0); | |
5965 | } | |
5966 | ||
5967 | /** | |
5968 | * Reports arriving at/near end of document with unclosed elements remaining. | |
5969 | * | |
5970 | * @param message | |
5971 | * the message | |
5972 | * @throws SAXException | |
5973 | */ | |
5974 | private void errEndWithUnclosedElements(@Local String name) throws SAXException { | |
5975 | if (errorHandler == null) { | |
5976 | return; | |
5977 | } | |
5978 | errNoCheck("End tag for \u201C" | |
5979 | + name | |
5980 | + "\u201D seen, but there were unclosed elements."); | |
5981 | // just report all remaining unclosed elements | |
5982 | errListUnclosedStartTags(0); | |
5983 | } | |
5984 | 5717 | } |
50 | 50 | */ |
51 | 51 | private int end; |
52 | 52 | |
53 | //[NOCPP[ | |
54 | ||
55 | 53 | /** |
56 | 54 | * Constructor for wrapping an existing UTF-16 code unit array. |
57 | 55 | * |
68 | 66 | this.end = end; |
69 | 67 | } |
70 | 68 | |
71 | // ]NOCPP] | |
72 | ||
73 | 69 | /** |
74 | 70 | * Returns the start index. |
75 | 71 | * |
281 | 281 | } else { |
282 | 282 | // The usual stuff. Want more bytes next time. |
283 | 283 | shouldReadBytes = true; |
284 | // return -1 if zero | |
284 | 285 | int cPos = charBuffer.position(); |
285 | if (cPos == 0) { | |
286 | // No output. Read more bytes right away | |
287 | break; | |
288 | } | |
289 | return cPos; | |
286 | return cPos == 0 ? -1 : cPos; | |
290 | 287 | } |
291 | 288 | } else { |
292 | 289 | // The result is in error. No need to test. |
154 | 154 | "xlink"); |
155 | 155 | WELL_KNOWN_ATTRIBUTE_PREFIXES.put( |
156 | 156 | "http://www.w3.org/2001/XMLSchema-instance", "xsi"); |
157 | WELL_KNOWN_ATTRIBUTE_PREFIXES.put("http://www.w3.org/1999/xlink", | |
157 | WELL_KNOWN_ATTRIBUTE_PREFIXES.put("http://www.w3org/1999/xlink", | |
158 | 158 | "xlink"); |
159 | 159 | } |
160 | 160 |
100 | 100 | "nsINameSpaceManager", "nsIContent", "nsIDocument", |
101 | 101 | "nsTraceRefcnt", "jArray", "nsHtml5DocumentMode", |
102 | 102 | "nsHtml5ArrayCopy", "nsHtml5Parser", "nsHtml5Atoms", |
103 | "nsHtml5TreeOperation", "nsHtml5PendingNotification", | |
104 | "nsHtml5StateSnapshot", "nsHtml5StackNode", | |
105 | "nsHtml5TreeOpExecutor", "nsHtml5StreamParser", | |
106 | "nsAHtml5TreeBuilderState", "nsHtml5Highlighter", | |
107 | "nsHtml5ViewSourceUtils" }; | |
108 | ||
109 | private static final String[] TOKENIZER_INCLUDES = { "prtypes", "nsIAtom", | |
110 | "nsHtml5AtomTable", "nsString", "nsIContent", "nsTraceRefcnt", | |
111 | "jArray", "nsHtml5DocumentMode", "nsHtml5ArrayCopy", | |
112 | "nsHtml5NamedCharacters", "nsHtml5NamedCharactersAccel", | |
113 | "nsHtml5Atoms", "nsAHtml5TreeBuilderState", "nsHtml5Macros", | |
114 | "nsHtml5Highlighter", "nsHtml5TokenizerLoopPolicies" }; | |
103 | "nsHtml5ByteReadable", "nsHtml5TreeOperation", | |
104 | "nsHtml5PendingNotification", "nsHtml5StateSnapshot", | |
105 | "nsHtml5StackNode", "nsHtml5TreeOpExecutor", "nsHtml5StreamParser", | |
106 | "nsAHtml5TreeBuilderState" }; | |
115 | 107 | |
116 | 108 | private static final String[] INCLUDES = { "prtypes", "nsIAtom", |
117 | 109 | "nsHtml5AtomTable", "nsString", "nsINameSpaceManager", |
118 | "nsIContent", "nsTraceRefcnt", "jArray", "nsHtml5ArrayCopy", | |
119 | "nsAHtml5TreeBuilderState", "nsHtml5Atoms", "nsHtml5ByteReadable", | |
120 | "nsIUnicodeDecoder", "nsHtml5Macros" }; | |
110 | "nsIContent", "nsIDocument", "nsTraceRefcnt", "jArray", | |
111 | "nsHtml5DocumentMode", "nsHtml5ArrayCopy", | |
112 | "nsHtml5NamedCharacters", "nsHtml5NamedCharactersAccel", | |
113 | "nsHtml5Atoms", "nsHtml5ByteReadable", "nsIUnicodeDecoder", | |
114 | "nsAHtml5TreeBuilderState", "nsHtml5Macros" }; | |
121 | 115 | |
122 | 116 | private static final String[] OTHER_DECLATIONS = {}; |
123 | 117 | |
126 | 120 | private static final String[] NAMED_CHARACTERS_INCLUDES = { "prtypes", |
127 | 121 | "jArray", "nscore", "nsDebug", "prlog", "nsMemory" }; |
128 | 122 | |
129 | private static final String[] FORWARD_DECLARATIONS = { | |
130 | "nsHtml5StreamParser" }; | |
123 | private static final String[] FORWARD_DECLARATIONS = { "nsHtml5StreamParser", }; | |
131 | 124 | |
132 | 125 | private static final String[] CLASSES_THAT_NEED_SUPPLEMENT = { |
133 | "MetaScanner", "Tokenizer", "TreeBuilder", "UTF16Buffer", }; | |
134 | ||
135 | private static final String[] STATE_LOOP_POLICIES = { | |
136 | "nsHtml5ViewSourcePolicy", "nsHtml5SilentPolicy" }; | |
126 | "MetaScanner", "TreeBuilder", "UTF16Buffer", }; | |
137 | 127 | |
138 | 128 | private final Map<String, String> atomMap = new HashMap<String, String>(); |
139 | 129 | |
169 | 159 | } |
170 | 160 | |
171 | 161 | public String booleanType() { |
172 | return "bool"; | |
162 | return "PRBool"; | |
173 | 163 | } |
174 | 164 | |
175 | 165 | public String byteType() { |
209 | 199 | } |
210 | 200 | |
211 | 201 | public String falseLiteral() { |
212 | return "false"; | |
202 | return "PR_FALSE"; | |
213 | 203 | } |
214 | 204 | |
215 | 205 | public String trueLiteral() { |
216 | return "true"; | |
206 | return "PR_TRUE"; | |
217 | 207 | } |
218 | 208 | |
219 | 209 | public String nullLiteral() { |
308 | 298 | public String[] boilerplateIncludes(String javaClass) { |
309 | 299 | if ("TreeBuilder".equals(javaClass)) { |
310 | 300 | return TREE_BUILDER_INCLUDES; |
311 | } else if ("Tokenizer".equals(javaClass)) { | |
312 | return TOKENIZER_INCLUDES; | |
313 | 301 | } else { |
314 | 302 | return INCLUDES; |
315 | 303 | } |
402 | 390 | public String characterNameTypeDeclaration() { |
403 | 391 | return "nsHtml5CharacterName"; |
404 | 392 | } |
405 | ||
406 | public String transition() { | |
407 | return "P::transition"; | |
408 | } | |
409 | ||
410 | public String tokenizerErrorCondition() { | |
411 | return "P::reportErrors"; | |
412 | } | |
413 | ||
414 | public String firstTransitionArg() { | |
415 | return "mViewSource"; | |
416 | } | |
417 | ||
418 | public String errorHandler() { | |
419 | return "NS_UNLIKELY(mViewSource)"; | |
420 | } | |
421 | ||
422 | public String completedCharacterReference() { | |
423 | return "P::completedNamedCharacterReference(mViewSource)"; | |
424 | } | |
425 | ||
426 | public String[] stateLoopPolicies() { | |
427 | return STATE_LOOP_POLICIES; | |
428 | } | |
429 | 393 | } |
150 | 150 | } |
151 | 151 | } |
152 | 152 | |
153 | public void printWithoutIndent(String arg) { | |
154 | indented = false; | |
155 | buf.append(arg); | |
156 | } | |
157 | ||
158 | 153 | public void print(String arg) { |
159 | 154 | if (!indented) { |
160 | 155 | makeIndent(); |
182 | 177 | } |
183 | 178 | } |
184 | 179 | |
185 | private boolean supportErrorReporting = true; | |
180 | private boolean skipRestOfStatementsInBlock = false; | |
186 | 181 | |
182 | private String currentTokenizerState = null; | |
183 | ||
184 | private boolean inTokenizerLoop() { | |
185 | return "stateLoop".equals(currentMethod) | |
186 | && "Tokenizer".equals(javaClassName); | |
187 | } | |
188 | ||
187 | 189 | protected SourcePrinter printer = new SourcePrinter(); |
188 | 190 | |
189 | 191 | private SourcePrinter staticInitializerPrinter = new SourcePrinter(); |
219 | 221 | private boolean destructor; |
220 | 222 | |
221 | 223 | protected boolean inStatic = false; |
222 | ||
223 | private boolean reportTransitions = false; | |
224 | ||
225 | private int stateLoopCallCount = 0; | |
226 | 224 | |
227 | 225 | /** |
228 | 226 | * @param cppTypes |
254 | 252 | private void printMembers(List<BodyDeclaration> members, |
255 | 253 | LocalSymbolTable arg) { |
256 | 254 | for (BodyDeclaration member : members) { |
257 | if ("Tokenizer".equals(javaClassName) | |
258 | && member instanceof MethodDeclaration | |
259 | && "stateLoop".equals(((MethodDeclaration) member).getName())) { | |
260 | reportTransitions = true; | |
261 | } | |
262 | 255 | member.accept(this, arg); |
263 | reportTransitions = false; | |
264 | 256 | } |
265 | 257 | } |
266 | 258 | |
324 | 316 | printer.print(cppTypes.localForLiteral("html")); |
325 | 317 | } else if ("documentModeHandler".equals(n.getName())) { |
326 | 318 | printer.print("this"); |
327 | } else if ("errorHandler".equals(n.getName())) { | |
328 | printer.print(cppTypes.errorHandler()); | |
329 | 319 | } else { |
330 | 320 | String prefixedName = javaClassName + "." + n.getName(); |
331 | 321 | String constant = symbolTable.cppDefinesByJavaNames.get(prefixedName); |
1343 | 1333 | } |
1344 | 1334 | printTypeArgs(n.getTypeArgs(), arg); |
1345 | 1335 | printer.print(n.getName()); |
1346 | if ("stateLoop".equals(n.getName()) | |
1347 | && "Tokenizer".equals(javaClassName) | |
1348 | && cppTypes.stateLoopPolicies().length > 0) { | |
1349 | printer.print("<"); | |
1350 | printer.print(cppTypes.stateLoopPolicies()[stateLoopCallCount]); | |
1351 | printer.print(">"); | |
1352 | stateLoopCallCount++; | |
1353 | } | |
1354 | 1336 | printer.print("("); |
1355 | 1337 | if (n.getArgs() != null) { |
1356 | 1338 | for (Iterator<Expression> i = n.getArgs().iterator(); i.hasNext();) { |
1553 | 1535 | |
1554 | 1536 | currentMethod = n.getName(); |
1555 | 1537 | |
1556 | destructor = "destructor".equals(currentMethod); | |
1538 | destructor = "destructor".equals(n.getName()); | |
1557 | 1539 | |
1558 | 1540 | // if (n.getJavaDoc() != null) { |
1559 | 1541 | // n.getJavaDoc().accept(this, arg); |
1570 | 1552 | printModifiers(n.getModifiers()); |
1571 | 1553 | } |
1572 | 1554 | |
1573 | if ("stateLoop".equals(currentMethod) | |
1574 | && "Tokenizer".equals(javaClassName) | |
1575 | && cppTypes.stateLoopPolicies().length > 0) { | |
1576 | printer.print("template<class P>"); | |
1577 | if (inHeader()) { | |
1578 | printer.print(" "); | |
1579 | } else { | |
1580 | printer.printLn(); | |
1581 | } | |
1582 | } | |
1583 | ||
1584 | 1555 | printTypeParameters(n.getTypeParameters(), arg); |
1585 | 1556 | if (n.getTypeParameters() != null) { |
1586 | 1557 | printer.print(" "); |
1768 | 1739 | |
1769 | 1740 | public void visit(ExpressionStmt n, LocalSymbolTable arg) { |
1770 | 1741 | Expression e = n.getExpression(); |
1771 | if (isCompletedCharacterReference(e)) { | |
1772 | printer.print(cppTypes.completedCharacterReference()); | |
1773 | printer.print(";"); | |
1742 | if (isDroppedExpression(e)) { | |
1774 | 1743 | return; |
1775 | } | |
1776 | boolean needsCondition = isTokenizerErrorReportingExpression(e); | |
1777 | if (!needsCondition && isDroppedExpression(e)) { | |
1778 | return; | |
1779 | } | |
1780 | if (needsCondition) { | |
1781 | printer.print("if ("); | |
1782 | printer.print(cppTypes.tokenizerErrorCondition()); | |
1783 | printer.printLn(") {"); | |
1784 | printer.indent(); | |
1785 | 1744 | } |
1786 | 1745 | e.accept(this, arg); |
1787 | 1746 | if (!inConstructorBody) { |
1788 | 1747 | printer.print(";"); |
1789 | 1748 | } |
1790 | if (needsCondition) { | |
1791 | printer.printLn(); | |
1792 | printer.unindent(); | |
1793 | printer.print("}"); | |
1794 | } | |
1795 | 1749 | } |
1796 | 1750 | |
1797 | 1751 | private void visitTransition(MethodCallExpr call, LocalSymbolTable arg) { |
1798 | 1752 | List<Expression> args = call.getArgs(); |
1799 | if (reportTransitions) { | |
1800 | printer.print(cppTypes.transition()); | |
1801 | printer.print("("); | |
1802 | printer.print(cppTypes.firstTransitionArg()); | |
1803 | printer.print(", "); | |
1804 | args.get(1).accept(this, arg); | |
1805 | printer.print(", "); | |
1806 | args.get(2).accept(this, arg); | |
1807 | printer.print(", "); | |
1808 | args.get(3).accept(this, arg); | |
1809 | printer.print(")"); | |
1810 | } else { | |
1811 | args.get(1).accept(this, arg); | |
1812 | } | |
1813 | } | |
1814 | ||
1815 | private boolean isTokenizerErrorReportingExpression(Expression e) { | |
1816 | if (!reportTransitions) { | |
1817 | return false; | |
1818 | } | |
1819 | if (e instanceof MethodCallExpr) { | |
1820 | MethodCallExpr methodCallExpr = (MethodCallExpr) e; | |
1821 | String name = methodCallExpr.getName(); | |
1822 | if (supportErrorReporting && !name.startsWith("errHtml4") | |
1823 | && ("stateLoop".equals(currentMethod)) | |
1824 | && (name.startsWith("err") || name.startsWith("maybeErr"))) { | |
1825 | return true; | |
1826 | } | |
1827 | } | |
1828 | return false; | |
1829 | } | |
1830 | ||
1831 | private boolean isCompletedCharacterReference(Expression e) { | |
1832 | if (!reportTransitions) { | |
1833 | return false; | |
1834 | } | |
1835 | if (e instanceof MethodCallExpr) { | |
1836 | MethodCallExpr methodCallExpr = (MethodCallExpr) e; | |
1837 | String name = methodCallExpr.getName(); | |
1838 | if (name.equals("completedNamedCharacterReference")) { | |
1839 | return true; | |
1840 | } | |
1841 | } | |
1842 | return false; | |
1843 | } | |
1844 | ||
1753 | args.get(1).accept(this, arg); | |
1754 | } | |
1755 | ||
1845 | 1756 | private boolean isDroppedExpression(Expression e) { |
1846 | 1757 | if (e instanceof MethodCallExpr) { |
1847 | 1758 | MethodCallExpr methodCallExpr = (MethodCallExpr) e; |
1848 | 1759 | String name = methodCallExpr.getName(); |
1849 | if (name.startsWith("fatal") || name.startsWith("note") | |
1850 | || name.startsWith("errHtml4") || name.startsWith("warn") | |
1851 | || name.startsWith("maybeWarn")) { | |
1852 | return true; | |
1853 | } | |
1854 | if (supportErrorReporting | |
1855 | && ("stateLoop".equals(currentMethod) && !reportTransitions) | |
1856 | && (name.startsWith("err") || name.startsWith("maybeErr"))) { | |
1857 | return true; | |
1858 | } | |
1859 | if (name.equals("completedNamedCharacterReference") | |
1860 | && !reportTransitions) { | |
1760 | if (name.startsWith("fatal") || name.startsWith("err") | |
1761 | || name.startsWith("warn") || name.startsWith("maybeErr") | |
1762 | || name.startsWith("maybeWarn") || name.startsWith("note")) { | |
1861 | 1763 | return true; |
1862 | 1764 | } |
1863 | 1765 | } |
1881 | 1783 | |
1882 | 1784 | public void visit(SwitchEntryStmt n, LocalSymbolTable arg) { |
1883 | 1785 | if (n.getLabel() != null) { |
1884 | boolean isMenuitem = n.getLabel().toString().equals("MENUITEM"); | |
1885 | if (isMenuitem) { | |
1886 | printer.printWithoutIndent("#ifdef ENABLE_VOID_MENUITEM\n"); | |
1887 | } | |
1888 | 1786 | printer.print("case "); |
1889 | 1787 | n.getLabel().accept(this, arg); |
1890 | 1788 | printer.print(":"); |
1891 | if (isMenuitem) { | |
1892 | printer.printWithoutIndent("\n#endif"); | |
1893 | } | |
1894 | 1789 | } else { |
1895 | 1790 | printer.print("default:"); |
1896 | 1791 | } |
2129 | 2024 | } |
2130 | 2025 | |
2131 | 2026 | private boolean isErrorOnlyBlock(Statement elseStmt) { |
2132 | if (supportErrorReporting) { | |
2133 | return false; | |
2134 | } | |
2135 | 2027 | if (elseStmt instanceof BlockStmt) { |
2136 | 2028 | BlockStmt block = (BlockStmt) elseStmt; |
2137 | 2029 | List<Statement> statements = block.getStmts(); |
2157 | 2049 | } |
2158 | 2050 | |
2159 | 2051 | private boolean isErrorHandlerIf(Expression condition) { |
2160 | if (supportErrorReporting) { | |
2161 | return false; | |
2162 | } | |
2163 | 2052 | return condition.toString().indexOf("errorHandler") != -1; |
2164 | 2053 | } |
2165 | 2054 |