18403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// Copyright (c) 2011, Mike Samuel 28403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// All rights reserved. 38403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// 48403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// Redistribution and use in source and binary forms, with or without 58403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// modification, are permitted provided that the following conditions 68403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// are met: 78403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// 88403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// Redistributions of source code must retain the above copyright 98403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// notice, this list of conditions and the following disclaimer. 108403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// Redistributions in binary form must reproduce the above copyright 118403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// notice, this list of conditions and the following disclaimer in the 128403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// documentation and/or other materials provided with the distribution. 138403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// Neither the name of the OWASP nor the names of its contributors may 148403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// be used to endorse or promote products derived from this software 158403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// without specific prior written permission. 168403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 178403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 188403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 198403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 208403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 218403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 228403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 238403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 248403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 258403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 268403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 278403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel// POSSIBILITY OF SUCH DAMAGE. 288403881c365ab36b721ccc4500af1b3a5bd25870mikesamuel 295c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.compackage org.owasp.html; 305c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com 315c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.comimport java.util.List; 325c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com 331ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuelimport javax.annotation.Nullable; 3427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuelimport javax.annotation.concurrent.Immutable; 3527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 365c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.comimport com.google.common.collect.ImmutableMap; 375c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.comimport com.google.common.collect.Lists; 385c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com 394e867904c8295537803c1c8a076e130df5674b58mikesamuel/** 404e867904c8295537803c1c8a076e130df5674b58mikesamuel * Wraps an HTML stream event receiver to fill in missing close tags. 414e867904c8295537803c1c8a076e130df5674b58mikesamuel * If the balancer is given the HTML {@code <p>1<p>2}, the wrapped receiver will 424e867904c8295537803c1c8a076e130df5674b58mikesamuel * see events equivalent to {@code <p>1</p><p>2</p>}. 434e867904c8295537803c1c8a076e130df5674b58mikesamuel * 444e867904c8295537803c1c8a076e130df5674b58mikesamuel * @author Mike Samuel <mikesamuel@gmail.com> 454e867904c8295537803c1c8a076e130df5674b58mikesamuel */ 465c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com@TCB 474e867904c8295537803c1c8a076e130df5674b58mikesamuelpublic class TagBalancingHtmlStreamEventReceiver 484e867904c8295537803c1c8a076e130df5674b58mikesamuel implements HtmlStreamEventReceiver { 495c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com private final HtmlStreamEventReceiver underlying; 503f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel private int nestingLimit = Integer.MAX_VALUE; 5127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel private final List<ElementContainmentInfo> openElements 5227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel = Lists.newArrayList(); 535c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com 544e867904c8295537803c1c8a076e130df5674b58mikesamuel public TagBalancingHtmlStreamEventReceiver( 554e867904c8295537803c1c8a076e130df5674b58mikesamuel HtmlStreamEventReceiver underlying) { 565c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com this.underlying = underlying; 575c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com } 585c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com 593f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel public void setNestingLimit(int limit) { 603f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel if (openElements.size() > limit) { 613f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel throw new IllegalStateException(); 623f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel } 633f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel this.nestingLimit = limit; 643f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel } 653f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel 665c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com public void openDocument() { 675c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com underlying.openDocument(); 685c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com } 695c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com 705c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com public void closeDocument() { 713f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel for (int i = Math.min(nestingLimit, openElements.size()); --i >= 0;) { 723f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel underlying.closeTag(openElements.get(i).elementName); 735c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com } 7427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel openElements.clear(); 755c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com underlying.closeDocument(); 765c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com } 775c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com 785c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com public void openTag(String elementName, List<String> attrs) { 795c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com String canonElementName = HtmlLexer.canonicalName(elementName); 8027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementContainmentInfo elInfo = ELEMENT_CONTAINMENT_RELATIONSHIPS.get( 8127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel canonElementName); 8227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel // Treat unrecognized tags as void, but emit closing tags in closeTag(). 8327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel if (elInfo == null) { 843f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel if (openElements.size() < nestingLimit) { 853f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel underlying.openTag(elementName, attrs); 863f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel } 8727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel return; 8827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 8927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 9063dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel prepareForContent(elInfo); 9163dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel 9263dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel if (openElements.size() < nestingLimit) { 9363dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel underlying.openTag(elInfo.elementName, attrs); 9463dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel } 9563dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel if (!elInfo.isVoid) { 9663dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel openElements.add(elInfo); 9763dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel } 9863dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel } 9963dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel 10063dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel private void prepareForContent(ElementContainmentInfo elInfo) { 1011ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel int nOpen = openElements.size(); 1021ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel if (nOpen != 0) { 1031ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel ElementContainmentInfo top = openElements.get(nOpen - 1); 1041ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel if ((top.contents & elInfo.types) == 0) { 1051ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel ElementContainmentInfo blockContainerChild = top.blockContainerChild; 1061ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel // Open implied elements, such as list-items and table cells & rows. 1071ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel if (blockContainerChild != null 1081ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel && (blockContainerChild.contents & elInfo.types) != 0) { 1091ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel underlying.openTag( 1101ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel blockContainerChild.elementName, Lists.<String>newArrayList()); 1111ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel openElements.add(blockContainerChild); 1121ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel top = blockContainerChild; 1131ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel ++nOpen; 1141ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel } 1153f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel } 1161ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel 1171ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel // Close all the elements that cannot contain the element to open. 1181ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel List<ElementContainmentInfo> toResumeInReverse = null; 1191ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel while (true) { 1201ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel if ((top.contents & elInfo.types) != 0) { break; } 1211ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel if (openElements.size() < nestingLimit) { 1221ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel underlying.closeTag(top.elementName); 1231ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel } 1241ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel openElements.remove(--nOpen); 1251ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel if (top.resumable) { 1261ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel if (toResumeInReverse == null) { 1271ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel toResumeInReverse = Lists.newArrayList(); 1281ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel } 1291ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel toResumeInReverse.add(top); 1305c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com } 1311ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel if (nOpen == 0) { break; } 1321ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel top = openElements.get(nOpen - 1); 13327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 13427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 1351ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel if (toResumeInReverse != null) { 1361ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel resume(toResumeInReverse); 1371ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel } 1383f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel } 1395c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com } 1405c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com 1415c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com public void closeTag(String elementName) { 1425c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com String canonElementName = HtmlLexer.canonicalName(elementName); 14327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementContainmentInfo elInfo = ELEMENT_CONTAINMENT_RELATIONSHIPS.get( 14427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel canonElementName); 14527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel if (elInfo == null) { // Allow unrecognized end tags through. 1463f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel if (openElements.size() < nestingLimit) { 1473f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel underlying.closeTag(elementName); 1483f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel } 14927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel return; 15027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 15127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel int index = openElements.lastIndexOf(elInfo); 152783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel // Let any of </h1>, </h2>, ... close other header tags. 153783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel if (isHeaderElementName(canonElementName)) { 154783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel for (int i = openElements.size(), limit = index + 1; -- i >= limit;) { 155783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel ElementContainmentInfo openEl = openElements.get(i); 156783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel if (isHeaderElementName(openEl.elementName)) { 157783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel elInfo = openEl; 158783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel index = i; 159783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel canonElementName = openEl.elementName; 160783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel break; 16163dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel } 16263dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel } 163783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel } 164783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel if (index < 0) { 165783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel return; // Don't close unopened tags. 166783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel } 167783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel 168783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel // Ensure that index is in the scope of closeable elements. 169783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel // This approximates the "has an element in *** scope" predicates defined at 170783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html 171783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel // #has-an-element-in-the-specific-scope 172783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel int blockingScopes = elInfo.blockedByScopes; 173783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel for (int i = openElements.size(); --i > index;) { 174783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel if ((openElements.get(i).inScopes & blockingScopes) != 0) { 175783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel return; 17663dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel } 17763dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel } 178783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel 1795c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com int last = openElements.size(); 18027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel // Close all the elements that cannot contain the element to open. 18127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel List<ElementContainmentInfo> toResumeInReverse = null; 1825c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com while (--last > index) { 18327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementContainmentInfo unclosed = openElements.remove(last); 1843f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel if (last + 1 < nestingLimit) { 1853f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel underlying.closeTag(unclosed.elementName); 1863f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel } 18727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel if (unclosed.resumable) { 18827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel if (toResumeInReverse == null) { 18927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel toResumeInReverse = Lists.newArrayList(); 19027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 19127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel toResumeInReverse.add(unclosed); 19227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 1935c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com } 1943f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel if (openElements.size() < nestingLimit) { 19563dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel underlying.closeTag(elInfo.elementName); 1963f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel } 1975c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com openElements.remove(index); 19827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel if (toResumeInReverse != null) { 1993f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel resume(toResumeInReverse); 2003f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel } 2013f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel } 2023f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel 2033f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel private void resume(List<ElementContainmentInfo> toResumeInReverse) { 2043f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel for (ElementContainmentInfo toResume : toResumeInReverse) { 2053f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel // TODO: If resuming of things other than plain formatting tags like <b> 2063f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel // and <i>, then we need to store the attributes for resumable tags so 2073f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel // that we can resume with the appropriate attributes. 2083f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel if (openElements.size() < nestingLimit) { 20927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel underlying.openTag(toResume.elementName, Lists.<String>newArrayList()); 21027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 2113f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel openElements.add(toResume); 21227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 2135c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com } 2145c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com 215550c8d3230c152db7156b266d089512b72ac0024mikesamuel private static final long HTML_SPACE_CHAR_BITMASK = 216550c8d3230c152db7156b266d089512b72ac0024mikesamuel (1L << ' ') 217550c8d3230c152db7156b266d089512b72ac0024mikesamuel | (1L << '\t') 218550c8d3230c152db7156b266d089512b72ac0024mikesamuel | (1L << '\n') 219550c8d3230c152db7156b266d089512b72ac0024mikesamuel | (1L << '\u000c') 220550c8d3230c152db7156b266d089512b72ac0024mikesamuel | (1L << '\r'); 22163dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel 222550c8d3230c152db7156b266d089512b72ac0024mikesamuel public static boolean isInterElementWhitespace(String text) { 22363dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel int n = text.length(); 22463dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel for (int i = 0; i < n; ++i) { 22563dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel int ch = text.charAt(i); 226550c8d3230c152db7156b266d089512b72ac0024mikesamuel if (ch > 0x20 || (HTML_SPACE_CHAR_BITMASK & (1L << ch)) == 0) { 227550c8d3230c152db7156b266d089512b72ac0024mikesamuel return false; 22863dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel } 22963dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel } 230550c8d3230c152db7156b266d089512b72ac0024mikesamuel return true; 231550c8d3230c152db7156b266d089512b72ac0024mikesamuel } 232550c8d3230c152db7156b266d089512b72ac0024mikesamuel 233550c8d3230c152db7156b266d089512b72ac0024mikesamuel public void text(String text) { 234550c8d3230c152db7156b266d089512b72ac0024mikesamuel if (!isInterElementWhitespace(text)) { 235550c8d3230c152db7156b266d089512b72ac0024mikesamuel prepareForContent(ElementContainmentRelationships.CHARACTER_DATA_ONLY); 236550c8d3230c152db7156b266d089512b72ac0024mikesamuel } 23763dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel 2383f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel if (openElements.size() < nestingLimit) { 2393f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel underlying.text(text); 2403f54e49f2181c52ca40d99fbe738b2484ba91528mikesamuel } 2415c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com } 2425c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com 24363dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel private static boolean isHeaderElementName(String canonElementName) { 24463dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel return canonElementName.length() == 2 && canonElementName.charAt(0) == 'h' 24563dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel && canonElementName.charAt(1) <= '9'; 24663dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel } 24763dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel 2485c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com 24927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel @Immutable 2501ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel private static final class ElementContainmentInfo { 25127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel final String elementName; 25227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel /** 25327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel * True if the adoption agency algorithm allows an element to be resumed 25427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel * after a mis-nested end tag closes it. 25527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel * E.g. in {@code <b>Foo<i>Bar</b>Baz</i>} the {@code <i>} element is 25627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel * resumed after the {@code <b>} element is closed. 25727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel */ 25827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel final boolean resumable; 25927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel /** A set of bits of element groups into which the element falls. */ 26027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel final int types; 26127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel /** The type of elements that an element can contain. */ 26227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel final int contents; 26327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel /** True if the element has no content -- not even text content. */ 26427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel final boolean isVoid; 2651ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel /** A legal child of this node that can contain block content. */ 2661ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel final @Nullable ElementContainmentInfo blockContainerChild; 267783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel /** A bit set of close tag scopes that block this element's close tags. */ 268783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel final int blockedByScopes; 269783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel /** A bit set of scopes groups into which this element falls. */ 270783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel final int inScopes; 27127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 27227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementContainmentInfo( 2731ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel String elementName, boolean resumable, int types, int contents, 274783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel @Nullable ElementContainmentInfo blockContainerChild, 275783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel int inScopes) { 27627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel this.elementName = elementName; 27727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel this.resumable = resumable; 27827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel this.types = types; 27927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel this.contents = contents; 28027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel this.isVoid = contents == 0 28127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel && HtmlTextEscapingMode.isVoidElement(elementName); 2821ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel this.blockContainerChild = blockContainerChild; 283783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel this.blockedByScopes = 284783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel ElementContainmentRelationships.CloseTagScope.ALL & ~inScopes; 285783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel this.inScopes = inScopes; 28627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 28727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 28827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel @Override public String toString() { 28927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel return "<" + elementName + ">"; 29027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 29127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 29227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 29379b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel static final ImmutableMap<String, ElementContainmentInfo> 29479b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel ELEMENT_CONTAINMENT_RELATIONSHIPS 29527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel = new ElementContainmentRelationships().toMap(); 29627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 29727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel private static class ElementContainmentRelationships { 29827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel private enum ElementGroup { 29927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel BLOCK, 30027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel INLINE, 30127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel INLINE_MINUS_A, 30227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel MIXED, 30327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel TABLE_CONTENT, 30427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel HEAD_CONTENT, 30527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel TOP_CONTENT, 30627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel AREA_ELEMENT, 30727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel FORM_ELEMENT, 30827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel LEGEND_ELEMENT, 30927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel LI_ELEMENT, 31027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel DL_PART, 31127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel P_ELEMENT, 31227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel OPTIONS_ELEMENT, 31327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel OPTION_ELEMENT, 31427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel PARAM_ELEMENT, 31527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel TABLE_ELEMENT, 31627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel TR_ELEMENT, 31727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel TD_ELEMENT, 31827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel COL_ELEMENT, 31963dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel CHARACTER_DATA, 32027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ; 32127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 32227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 323783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel /** 324783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel * An identifier for one of the "has a *** element in scope" predicates 325783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel * used by HTML5 to decide when a close tag implicitly closes tags above 326783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel * the target element on the open element stack. 327783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel */ 328783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel private enum CloseTagScope { 329783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel COMMON, 330783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel BUTTON, 331783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel LIST_ITEM, 332783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel TABLE, 333783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel ; 334783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel 335783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel static final int ALL = (1 << values().length) - 1; 336783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel } 337783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel 33827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel private static int elementGroupBits(ElementGroup a) { 33927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel return 1 << a.ordinal(); 34027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 34127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 34227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel private static int elementGroupBits( 34327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup a, ElementGroup b) { 34427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel return (1 << a.ordinal()) | (1 << b.ordinal()); 34527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 34627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 34727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel private static int elementGroupBits( 34827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup a, ElementGroup b, ElementGroup c) { 34927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel return (1 << a.ordinal()) | (1 << b.ordinal()) | (1 << c.ordinal()); 35027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 35127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 35227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel private static int elementGroupBits( 35327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup... bits) { 35427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel int bitField = 0; 35527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel for (ElementGroup bit : bits) { 35627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel bitField |= (1 << bit.ordinal()); 35727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 35827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel return bitField; 35927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 36027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 361783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel private static int scopeBits(CloseTagScope a) { 362783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel return 1 << a.ordinal(); 363783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel } 364783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel 365783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel private static int scopeBits( 366783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel CloseTagScope a, CloseTagScope b, CloseTagScope c) { 367783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel return (1 << a.ordinal()) | (1 << b.ordinal()) | (1 << c.ordinal()); 368783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel } 369783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel 37027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel private ImmutableMap.Builder<String, ElementContainmentInfo> definitions 37127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel = ImmutableMap.builder(); 37227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 3731ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel private ElementContainmentInfo defineElement( 37427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel String elementName, boolean resumable, int types, int contentTypes) { 3751ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel return defineElement(elementName, resumable, types, contentTypes, null); 3761ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel } 3771ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel 3781ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel private ElementContainmentInfo defineElement( 3791ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel String elementName, boolean resumable, int types, int contentTypes, 380783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel int inScopes) { 381783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel return defineElement( 382783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel elementName, resumable, types, contentTypes, null, inScopes); 383783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel } 384783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel 385783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel private ElementContainmentInfo defineElement( 386783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel String elementName, boolean resumable, int types, int contentTypes, 3871ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel @Nullable ElementContainmentInfo blockContainer) { 388783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel return defineElement( 389783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel elementName, resumable, types, contentTypes, blockContainer, 0); 390783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel } 391783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel 392783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel private ElementContainmentInfo defineElement( 393783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel String elementName, boolean resumable, int types, int contentTypes, 394783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel @Nullable ElementContainmentInfo blockContainer, int inScopes) { 3951ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel ElementContainmentInfo info = new ElementContainmentInfo( 396783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel elementName, resumable, types, contentTypes, blockContainer, 397783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel inScopes); 3981ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel definitions.put(elementName, info); 3991ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel return info; 40027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 40127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 40227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel private ImmutableMap<String, ElementContainmentInfo> toMap() { 40327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel return definitions.build(); 40427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 40527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 40627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel { 40727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 40827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "a", false, elementGroupBits( 40927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 41027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 41127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE_MINUS_A 41227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 41327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 41427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "abbr", true, elementGroupBits( 41527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 41627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 41727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 41827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 41927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 42027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "acronym", true, elementGroupBits( 42127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 42227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 42327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 42427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 42527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 42627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "address", false, elementGroupBits( 42727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 42827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 42927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.P_ELEMENT 43027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 43127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 43227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "applet", false, elementGroupBits( 43327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 43427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 43527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE, 43627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.PARAM_ELEMENT 437783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel ), scopeBits( 438783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel CloseTagScope.COMMON, CloseTagScope.BUTTON, 439783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel CloseTagScope.LIST_ITEM 44027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 44127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 44227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "area", false, elementGroupBits(ElementGroup.AREA_ELEMENT), 0); 44327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 44427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "audio", false, elementGroupBits( 44527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 44627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), 0); 44727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 44827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "b", true, elementGroupBits( 44927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 45027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 45127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 45227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 45327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 45427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "base", false, elementGroupBits(ElementGroup.HEAD_CONTENT), 0); 45527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 45627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "basefont", false, elementGroupBits( 45727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 45827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), 0); 45927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 46027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "bdi", true, elementGroupBits( 46127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 46227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 46327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 46427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 46527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 46627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "bdo", true, elementGroupBits( 46727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 46827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 46927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 47027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 47127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 47227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "big", true, elementGroupBits( 47327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 47427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 47527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 47627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 47727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 47827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "blink", true, elementGroupBits( 47927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 48027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 48127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 48227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 48327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 48427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "blockquote", false, elementGroupBits( 48527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 48627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 48727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE 48827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 48927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 49027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "body", false, elementGroupBits( 49127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TOP_CONTENT 49227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 49327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE 49427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 49527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 49627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "br", false, elementGroupBits( 49727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 49827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), 0); 49927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 50027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "button", false, elementGroupBits( 50127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 50227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 50327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE 504783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel ), scopeBits(CloseTagScope.BUTTON)); 50527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 50627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "canvas", false, elementGroupBits( 50727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 50827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 50927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 51027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 51127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 51227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "caption", false, elementGroupBits( 51327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TABLE_CONTENT 51427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 51527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 516783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel ), scopeBits( 517783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel CloseTagScope.COMMON, CloseTagScope.BUTTON, 518783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel CloseTagScope.LIST_ITEM 51927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 52027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 52127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "center", false, elementGroupBits( 52227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 52327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 52427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE 52527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 52627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 52727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "cite", true, elementGroupBits( 52827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 52927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 53027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 53127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 53227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 53327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "code", true, elementGroupBits( 53427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 53527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 53627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 53727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 53827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 53927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "col", false, elementGroupBits( 54027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TABLE_CONTENT, ElementGroup.COL_ELEMENT 54127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), 0); 54227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 54327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "colgroup", false, elementGroupBits( 54427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TABLE_CONTENT 54527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 54627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.COL_ELEMENT 54727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 5481ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel ElementContainmentInfo DD = defineElement( 54927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "dd", false, elementGroupBits( 55027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.DL_PART 55127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 55227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE 55327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 55427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 55527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "del", true, elementGroupBits( 55627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE, 55727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.MIXED 55827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 55927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE 56027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 56127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 56227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "dfn", true, elementGroupBits( 56327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 56427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 56527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 56627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 56727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 56827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "dir", false, elementGroupBits( 56927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 57027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 57127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.LI_ELEMENT 57227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 57327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 57427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "div", false, elementGroupBits( 57527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 57627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 57727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE 57827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 57927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 58027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "dl", false, elementGroupBits( 58127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 58227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 58327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.DL_PART 5841ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel ), 5851ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel DD); 58627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 58727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "dt", false, elementGroupBits( 58827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.DL_PART 58927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 59027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 59127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 59227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 59327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "em", true, elementGroupBits( 59427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 59527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 59627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 59727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 59827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 59927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "fieldset", false, elementGroupBits( 60027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 60127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 60227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE, 60327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.LEGEND_ELEMENT 60427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 60527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 60627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "font", false, elementGroupBits( 60727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 60827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 60927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 61027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 61127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 61227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "form", false, elementGroupBits( 61327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.FORM_ELEMENT 61427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 61527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE, 61627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE_MINUS_A, ElementGroup.TR_ELEMENT, 61727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TD_ELEMENT 61827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 61927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 62027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "h1", false, elementGroupBits( 62127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 62227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 62327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 62427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 62527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 62627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "h2", false, elementGroupBits( 62727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 62827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 62927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 63027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 63127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 63227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "h3", false, elementGroupBits( 63327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 63427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 63527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 63627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 63727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 63827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "h4", false, elementGroupBits( 63927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 64027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 64127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 64227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 64327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 64427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "h5", false, elementGroupBits( 64527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 64627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 64727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 64827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 64927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 65027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "h6", false, elementGroupBits( 65127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 65227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 65327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 65427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 65527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 65627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "head", false, elementGroupBits( 65727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TOP_CONTENT 65827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 65927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.HEAD_CONTENT 66027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 66127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 66227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "hr", false, elementGroupBits(ElementGroup.BLOCK), 0); 66327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 664783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel "html", false, 0, elementGroupBits(ElementGroup.TOP_CONTENT), 665783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel CloseTagScope.ALL); 66627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 66727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "i", true, elementGroupBits( 66827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 66927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 67027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 67127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 67227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 67327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "iframe", false, elementGroupBits( 67427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 67527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 67627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE 67727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 67827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 67927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "img", false, elementGroupBits( 68027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 68127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), 0); 68227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 68327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "input", false, elementGroupBits( 68427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 68527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), 0); 68627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 68727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "ins", true, elementGroupBits( 68827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE 68927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 69027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE 69127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 69227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 69327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "isindex", false, elementGroupBits(ElementGroup.INLINE), 0); 69427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 69527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "kbd", true, elementGroupBits( 69627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 69727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 69827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 69927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 70027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 70127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "label", false, elementGroupBits( 70227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 70327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 70427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 70527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 70627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 70727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "legend", false, elementGroupBits( 70827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.LEGEND_ELEMENT 70927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 71027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 71127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 7121ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel ElementContainmentInfo LI = defineElement( 71327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "li", false, elementGroupBits( 71427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.LI_ELEMENT 71527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 71627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE 71727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 71827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 71927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "link", false, elementGroupBits( 72027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.HEAD_CONTENT 72127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), 0); 72227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 72327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "listing", false, elementGroupBits( 72427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 72527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 72627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 72727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 72827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 72927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "map", false, elementGroupBits( 73027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 73127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 73227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.AREA_ELEMENT 73327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 73427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 73527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "meta", false, elementGroupBits(ElementGroup.HEAD_CONTENT), 0); 73627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 73727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "nobr", false, elementGroupBits( 73827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 73927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 74027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 74127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 74227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 74327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "noframes", false, elementGroupBits( 74427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.TOP_CONTENT 74527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 74627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE, 74727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TOP_CONTENT 74827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 74927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 75027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "noscript", false, elementGroupBits( 75127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 75227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 75327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE 75427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 75527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 75627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "object", false, elementGroupBits( 75727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A, 75827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.HEAD_CONTENT 75927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 76027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE, 76127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.PARAM_ELEMENT 762783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel ), scopeBits( 763783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel CloseTagScope.COMMON, CloseTagScope.BUTTON, 764783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel CloseTagScope.LIST_ITEM 76527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 76627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 76727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "ol", false, elementGroupBits( 76827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 76927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 77027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.LI_ELEMENT 7711ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel ), 772783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel LI, 773783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel scopeBits(CloseTagScope.LIST_ITEM)); 77427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 77527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "optgroup", false, elementGroupBits( 77627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.OPTIONS_ELEMENT 77727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 77827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.OPTIONS_ELEMENT 77927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 78027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 78127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "option", false, elementGroupBits( 78227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.OPTIONS_ELEMENT, ElementGroup.OPTION_ELEMENT 7834c1e3417997042b0b485cbf71344a0210dfaba04mikesamuel ), elementGroupBits( 7844c1e3417997042b0b485cbf71344a0210dfaba04mikesamuel ElementGroup.CHARACTER_DATA 7854c1e3417997042b0b485cbf71344a0210dfaba04mikesamuel )); 78627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 78727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "p", false, elementGroupBits( 78827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.P_ELEMENT 78927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 79027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.TABLE_ELEMENT 79127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 79227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 79327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "param", false, elementGroupBits(ElementGroup.PARAM_ELEMENT), 0); 79427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 79527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "pre", false, elementGroupBits( 79627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 79727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 79827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 79927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 80027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 80127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "q", true, elementGroupBits( 80227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 80327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 80427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 80527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 80627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 80727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "s", true, elementGroupBits( 80827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 80927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 81027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 81127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 81227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 81327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "samp", true, elementGroupBits( 81427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 81527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 81627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 81727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 81827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 81927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "script", false, elementGroupBits( 82027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE, 82127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE_MINUS_A, ElementGroup.MIXED, 82227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TABLE_CONTENT, ElementGroup.HEAD_CONTENT, 82327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TOP_CONTENT, ElementGroup.AREA_ELEMENT, 82427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.FORM_ELEMENT, ElementGroup.LEGEND_ELEMENT, 82527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.LI_ELEMENT, ElementGroup.DL_PART, 82627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.P_ELEMENT, ElementGroup.OPTIONS_ELEMENT, 82727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.OPTION_ELEMENT, ElementGroup.PARAM_ELEMENT, 82827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TABLE_ELEMENT, ElementGroup.TR_ELEMENT, 82927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TD_ELEMENT, ElementGroup.COL_ELEMENT 83063dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel ), elementGroupBits( 83163dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel ElementGroup.CHARACTER_DATA)); 83227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 83327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "select", false, elementGroupBits( 83427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 83527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 83627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.OPTIONS_ELEMENT 83727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 83827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 83927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "small", true, elementGroupBits( 84027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 84127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 84227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 84327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 84427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 84527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "span", false, elementGroupBits( 84627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 84727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 84827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 84927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 85027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 85127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "strike", true, elementGroupBits( 85227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 85327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 85427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 85527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 85627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 85727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "strong", true, elementGroupBits( 85827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 85927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 86027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 86127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 86227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 86327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "style", false, elementGroupBits( 86427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.HEAD_CONTENT 86563dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel ), elementGroupBits( 86663dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel ElementGroup.CHARACTER_DATA 86763dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel )); 86827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 86927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "sub", true, elementGroupBits( 87027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 87127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 87227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 87327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 87427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 87527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "sup", true, elementGroupBits( 87627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 87727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 87827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 87927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 88027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 88127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "table", false, elementGroupBits( 88227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.TABLE_ELEMENT 88327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 88427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TABLE_CONTENT, ElementGroup.FORM_ELEMENT 885783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel ), CloseTagScope.ALL); 88627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 88727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "tbody", false, elementGroupBits( 88827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TABLE_CONTENT 88927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 89027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TR_ELEMENT 89127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 8921ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel ElementContainmentInfo TD = defineElement( 89327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "td", false, elementGroupBits( 89427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TD_ELEMENT 89527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 89627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE 897783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel ), scopeBits( 898783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel CloseTagScope.COMMON, CloseTagScope.BUTTON, 899783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel CloseTagScope.LIST_ITEM 90027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 90127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 90227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "textarea", false, 90327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel // No, a textarea cannot be inside a link. 90463dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel elementGroupBits(ElementGroup.INLINE), 90563dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel elementGroupBits(ElementGroup.CHARACTER_DATA)); 90627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 90727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "tfoot", false, elementGroupBits( 90827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TABLE_CONTENT 90927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 91027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.FORM_ELEMENT, ElementGroup.TR_ELEMENT, 91127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TD_ELEMENT 91227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 91327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 91427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "th", false, elementGroupBits( 91527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TD_ELEMENT 91627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 91727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK, ElementGroup.INLINE 918783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel ), scopeBits( 919783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel CloseTagScope.COMMON, CloseTagScope.BUTTON, 920783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel CloseTagScope.LIST_ITEM 92127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 92227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 92327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "thead", false, elementGroupBits( 92427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TABLE_CONTENT 92527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 92627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.FORM_ELEMENT, ElementGroup.TR_ELEMENT, 92727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TD_ELEMENT 92827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 92927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 93063dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel "title", false, elementGroupBits(ElementGroup.HEAD_CONTENT), 93163dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel elementGroupBits(ElementGroup.CHARACTER_DATA)); 93227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 93327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "tr", false, elementGroupBits( 93427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.TABLE_CONTENT, ElementGroup.TR_ELEMENT 93527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 93627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.FORM_ELEMENT, ElementGroup.TD_ELEMENT 9371ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel ), 9381ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel TD); 93927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 94027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "tt", true, elementGroupBits( 94127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 94227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 94327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 94427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 94527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 94627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "u", true, elementGroupBits( 94727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 94827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 94927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 95027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 95127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 95227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "ul", false, elementGroupBits( 95327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 95427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 95527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.LI_ELEMENT 9561ecbdce5dd203e7aca2b93650ca3afce17dbc095mikesamuel ), 957783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel LI, 958783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel scopeBits(CloseTagScope.LIST_ITEM)); 95927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 96027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "var", false, elementGroupBits( 96127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 96227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 96327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 96427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 96527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 96627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "video", false, elementGroupBits( 96727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 96827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), 0); 96927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 97027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "wbr", false, elementGroupBits( 97127b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 97227b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), 0); 97327b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel defineElement( 97427b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel "xmp", false, elementGroupBits( 97527b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.BLOCK 97627b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ), elementGroupBits( 97727b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel ElementGroup.INLINE 97827b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel )); 97927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel 98027b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 98163dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel 982a1b4378ade2caa7a029abba418a37ed7b94e7a7fmikesamuel private static final ElementContainmentInfo CHARACTER_DATA_ONLY 98363dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel = new ElementContainmentInfo( 98463dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel "#text", false, 98563dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel elementGroupBits( 98663dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A, 98763dba946a9a0b3af438ca08b6824e653e5ca58c5mikesamuel ElementGroup.BLOCK, ElementGroup.CHARACTER_DATA), 988783908cf042927b900d42383d30ec1fb8ee83d1fmikesamuel 0, null, 0); 98927b4be957534ebb90e21ac8d31bf722e4c9273bfmikesamuel } 99079b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel 99179b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel static boolean allowsPlainTextualContent(String canonElementName) { 99279b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel ElementContainmentInfo info = 99379b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel ELEMENT_CONTAINMENT_RELATIONSHIPS.get(canonElementName); 994ce5bde40e2e126de05105f09f1f965a5c70aaa94mikesamuel if (info == null 995ce5bde40e2e126de05105f09f1f965a5c70aaa94mikesamuel || ((info.contents 996a1b4378ade2caa7a029abba418a37ed7b94e7a7fmikesamuel & ElementContainmentRelationships.CHARACTER_DATA_ONLY.types) 997ce5bde40e2e126de05105f09f1f965a5c70aaa94mikesamuel != 0)) { 99879b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel switch (HtmlTextEscapingMode.getModeForTag(canonElementName)) { 99979b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel case PCDATA: return true; 100079b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel case RCDATA: return true; 100179b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel case PLAIN_TEXT: return true; 100279b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel case VOID: return false; 100379b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel case CDATA: 100479b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel case CDATA_SOMETIMES: 100579b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel return "xmp".equals(canonElementName) 100679b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel || "listing".equals(canonElementName); 100779b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel } 100879b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel } 100979b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel return false; 101079b4c29af1261d95c663bdf0003b70cb0eb8000emikesamuel } 10115c702c12be71d8070da9287cc4a044617dd726a7manico.james@gmail.com} 1012