Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/parser/html/javasrc/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 272 kB image not shown  

Quelle  TreeBuilder.java   Sprache: JAVA

 
/*
 * Copyright (c) 2007 Henri Sivonen
 * Copyright (c) 2007-2017 Mozilla Foundation
 * Portions of comments Copyright 2004-2008 Apple Computer, Inc., Mozilla
 * Foundation, and Opera Software ASA.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */


/*
 * The comments following this one that use the same comment syntax as this
 * comment are quotes from the WHATWG HTML 5 spec as of 27 June 2007
 * amended as of June 28 2007.
 * That document came with this statement:
 * "© Copyright 2004-2007 Apple Computer, Inc., Mozilla Foundation, and
 * Opera Software ASA. You are granted a license to use, reproduce and
 * create derivative works of this document."
 */


package nu.validator.htmlparser.impl;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.xml.sax.ErrorHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import nu.validator.htmlparser.annotation.Auto;
import nu.validator.htmlparser.annotation.Const;
import nu.validator.htmlparser.annotation.IdType;
import nu.validator.htmlparser.annotation.Inline;
import nu.validator.htmlparser.annotation.Literal;
import nu.validator.htmlparser.annotation.Local;
import nu.validator.htmlparser.annotation.NoLength;
import nu.validator.htmlparser.annotation.NsUri;
import nu.validator.htmlparser.common.DocumentMode;
import nu.validator.htmlparser.common.DocumentModeHandler;
import nu.validator.htmlparser.common.Interner;
import nu.validator.htmlparser.common.TokenHandler;
import nu.validator.htmlparser.common.XmlViolationPolicy;

public abstract class TreeBuilder<T> implements TokenHandler,
        TreeBuilderState<T> {

    /**
     * Array version of U+FFFD.
     */

    private static final @NoLength char[] REPLACEMENT_CHARACTER = { '\uFFFD' };

    // Start dispatch groups

    final static int OTHER = 0;

    final static int A = 1;

    final static int BASE = 2;

    final static int BODY = 3;

    final static int BR = 4;

    final static int BUTTON = 5;

    final static int CAPTION = 6;

    final static int COL = 7;

    final static int COLGROUP = 8;

    final static int FORM = 9;

    final static int FRAME = 10;

    final static int FRAMESET = 11;

    final static int IMAGE = 12;

    final static int INPUT = 13;

    final static int RT_OR_RP = 14;

    final static int LI = 15;

    final static int LINK_OR_BASEFONT_OR_BGSOUND = 16;

    final static int MATH = 17;

    final static int META = 18;

    final static int SVG = 19;

    final static int HEAD = 20;

    final static int HR = 22;

    final static int HTML = 23;

    final static int NOBR = 24;

    final static int NOFRAMES = 25;

    final static int NOSCRIPT = 26;

    final static int OPTGROUP = 27;

    final static int OPTION = 28;

    final static int P = 29;

    final static int PLAINTEXT = 30;

    final static int SCRIPT = 31;

    final static int SELECT = 32;

    final static int STYLE = 33;

    final static int TABLE = 34;

    final static int TEXTAREA = 35;

    final static int TITLE = 36;

    final static int TR = 37;

    final static int XMP = 38;

    final static int TBODY_OR_THEAD_OR_TFOOT = 39;

    final static int TD_OR_TH = 40;

    final static int DD_OR_DT = 41;

    final static int H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 = 42;

    final static int MARQUEE_OR_APPLET = 43;

    final static int PRE_OR_LISTING = 44;

    final static int B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U = 45;

    final static int UL_OR_OL_OR_DL = 46;

    final static int IFRAME = 47;

    final static int EMBED = 48;

    final static int AREA_OR_WBR = 49;

    final static int DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU = 50;

    final static int ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY = 51;

    final static int RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR = 52;

    final static int RB_OR_RTC = 53;

    final static int PARAM_OR_SOURCE_OR_TRACK = 55;

    final static int MGLYPH_OR_MALIGNMARK = 56;

    final static int MI_MO_MN_MS_MTEXT = 57;

    final static int ANNOTATION_XML = 58;

    final static int FOREIGNOBJECT_OR_DESC = 59;

    final static int NOEMBED = 60;

    final static int FIELDSET = 61;

    final static int OUTPUT = 62;

    final static int OBJECT = 63;

    final static int FONT = 64;

    final static int KEYGEN = 65;

    final static int TEMPLATE = 66;

    final static int IMG = 67;

    // start insertion modes

    private static final int IN_ROW = 0;

    private static final int IN_TABLE_BODY = 1;

    private static final int IN_TABLE = 2;

    private static final int IN_CAPTION = 3;

    private static final int IN_CELL = 4;

    private static final int FRAMESET_OK = 5;

    private static final int IN_BODY = 6;

    private static final int IN_HEAD = 7;

    private static final int IN_HEAD_NOSCRIPT = 8;

    // no fall-through

    private static final int IN_COLUMN_GROUP = 9;

    // no fall-through

    private static final int IN_SELECT_IN_TABLE = 10;

    private static final int IN_SELECT = 11;

    // no fall-through

    private static final int AFTER_BODY = 12;

    // no fall-through

    private static final int IN_FRAMESET = 13;

    private static final int AFTER_FRAMESET = 14;

    // no fall-through

    private static final int INITIAL = 15;

    // could add fall-through

    private static final int BEFORE_HTML = 16;

    // could add fall-through

    private static final int BEFORE_HEAD = 17;

    // no fall-through

    private static final int AFTER_HEAD = 18;

    // no fall-through

    private static final int AFTER_AFTER_BODY = 19;

    // no fall-through

    private static final int AFTER_AFTER_FRAMESET = 20;

    // no fall-through

    private static final int TEXT = 21;

    private static final int IN_TEMPLATE = 22;

    // start charset states

    private static final int CHARSET_INITIAL = 0;

    private static final int CHARSET_C = 1;

    private static final int CHARSET_H = 2;

    private static final int CHARSET_A = 3;

    private static final int CHARSET_R = 4;

    private static final int CHARSET_S = 5;

    private static final int CHARSET_E = 6;

    private static final int CHARSET_T = 7;

    private static final int CHARSET_EQUALS = 8;

    private static final int CHARSET_SINGLE_QUOTED = 9;

    private static final int CHARSET_DOUBLE_QUOTED = 10;

    private static final int CHARSET_UNQUOTED = 11;

    // end pseudo enums

    @Literal private final static String[] QUIRKY_PUBLIC_IDS = {
            "+//silmaril//dtd html pro v0r11 19970101//",
            "-//advasoft ltd//dtd html 3.0 aswedit + extensions//",
            "-//as//dtd html 3.0 aswedit + extensions//",
            "-//ietf//dtd html 2.0 level 1//",
            "-//ietf//dtd html 2.0 level 2//",
            "-//ietf//dtd html 2.0 strict level 1//",
            "-//ietf//dtd html 2.0 strict level 2//",
            "-//ietf//dtd html 2.0 strict//",
            "-//ietf//dtd html 2.0//",
            "-//ietf//dtd html 2.1e//",
            "-//ietf//dtd html 3.0//",
            "-//ietf//dtd html 3.2 final//",
            "-//ietf//dtd html 3.2//",
            "-//ietf//dtd html 3//",
            "-//ietf//dtd html level 0//",
            "-//ietf//dtd html level 1//",
            "-//ietf//dtd html level 2//",
            "-//ietf//dtd html level 3//",
            "-//ietf//dtd html strict level 0//",
            "-//ietf//dtd html strict level 1//",
            "-//ietf//dtd html strict level 2//",
            "-//ietf//dtd html strict level 3//",
            "-//ietf//dtd html strict//",
            "-//ietf//dtd html//",
            "-//metrius//dtd metrius presentational//",
            "-//microsoft//dtd internet explorer 2.0 html strict//",
            "-//microsoft//dtd internet explorer 2.0 html//",
            "-//microsoft//dtd internet explorer 2.0 tables//",
            "-//microsoft//dtd internet explorer 3.0 html strict//",
            "-//microsoft//dtd internet explorer 3.0 html//",
            "-//microsoft//dtd internet explorer 3.0 tables//",
            "-//netscape comm. corp.//dtd html//",
            "-//netscape comm. corp.//dtd strict html//",
            "-//o'reilly and associates//dtd html 2.0//",
            "-//o'reilly and associates//dtd html extended 1.0//",
            "-//o'reilly and associates//dtd html extended relaxed 1.0//",
            "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//",
            "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//",
            "-//spyglass//dtd html 2.0 extended//",
            "-//sq//dtd html 2.0 hotmetal + extensions//",
            "-//sun microsystems corp.//dtd hotjava html//",
            "-//sun microsystems corp.//dtd hotjava strict html//",
            "-//w3c//dtd html 3 1995-03-24//", "-//w3c//dtd html 3.2 draft//",
            "-//w3c//dtd html 3.2 final//", "-//w3c//dtd html 3.2//",
            "-//w3c//dtd html 3.2s draft//", "-//w3c//dtd html 4.0 frameset//",
            "-//w3c//dtd html 4.0 transitional//",
            "-//w3c//dtd html experimental 19960712//",
            "-//w3c//dtd html experimental 970421//", "-//w3c//dtd w3 html//",
            "-//w3o//dtd w3 html 3.0//", "-//webtechs//dtd mozilla html 2.0//",
            "-//webtechs//dtd mozilla html//" };

    private static final int NOT_FOUND_ON_STACK = Integer.MAX_VALUE;

    // [NOCPP[

    private static final @Local String HTML_LOCAL = "html";

    // ]NOCPP]

    private int mode = INITIAL;

    private int originalMode = INITIAL;

    /**
     * Used only when moving back to IN_BODY.
     */

    private boolean framesetOk = true;

    protected Tokenizer tokenizer;

    // [NOCPP[

    protected ErrorHandler errorHandler;

    private DocumentModeHandler documentModeHandler;

    // ]NOCPP]

    private boolean scriptingEnabled = false;

    private boolean needToDropLF;

    // [NOCPP[

    private boolean wantingComments;

    // ]NOCPP]

    private boolean fragment;

    private @Local String contextName;

    private @NsUri String contextNamespace;

    private T contextNode;

    /**
     * Stack of template insertion modes
     */

    private @Auto int[] templateModeStack;

    /**
     * Current template mode stack pointer.
     */

    private int templateModePtr = -1;

    private @Auto StackNode<T>[] stackNodes;

    /**
     * Index of the earliest possible unused or empty element in stackNodes.
     */

    private int stackNodesIdx = -1;

    private int numStackNodes = 0;

    private @Auto StackNode<T>[] stack;

    private int currentPtr = -1;

    private @Auto StackNode<T>[] listOfActiveFormattingElements;

    private int listPtr = -1;

    private T formPointer;

    private T headPointer;

    protected @Auto char[] charBuffer;

    protected int charBufferLen = 0;

    private boolean quirks = false;

    private boolean forceNoQuirks = false;

    private boolean allowDeclarativeShadowRoots = false;

    private boolean keepBuffer = false;

    // [NOCPP[

    private boolean reportingDoctype = true;

    private XmlViolationPolicy namePolicy = XmlViolationPolicy.ALTER_INFOSET;

    private final Map<String, LocatorImpl> idLocations = new HashMap<String, LocatorImpl>();

    // ]NOCPP]

    protected TreeBuilder() {
        fragment = false;
    }

    /**
     * Reports an condition that would make the infoset incompatible with XML
     * 1.0 as fatal.
     *
     * @throws SAXException
     * @throws SAXParseException
     */

    protected void fatal() throws SAXException {
    }

    // CPPONLY: @Inline private @Creator Object htmlCreator(@HtmlCreator Object htmlCreator) {
    // CPPONLY:     @Creator Object creator;
    // CPPONLY:     creator.html = htmlCreator;
    // CPPONLY:     return creator;
    // CPPONLY: }
    // CPPONLY:
    // CPPONLY: @Inline private @Creator Object svgCreator(@SvgCreator Object svgCreator) {
    // CPPONLY:     @Creator Object creator;
    // CPPONLY:     creator.svg = svgCreator;
    // CPPONLY:     return creator;
    // CPPONLY: }

    // [NOCPP[

    protected final void fatal(Exception e) throws SAXException {
        SAXParseException spe = new SAXParseException(e.getMessage(),
                tokenizer, e);
        if (errorHandler != null) {
            errorHandler.fatalError(spe);
        }
        throw spe;
    }

    final void fatal(String s) throws SAXException {
        SAXParseException spe = new SAXParseException(s, tokenizer);
        if (errorHandler != null) {
            errorHandler.fatalError(spe);
        }
        throw spe;
    }

    /**
     * Reports a Parse Error.
     *
     * @param message
     *            the message
     * @throws SAXException
     */

    final void err(String message) throws SAXException {
        if (errorHandler == null) {
            return;
        }
        errNoCheck(message);
    }

    /**
     * Reports a Parse Error without checking if an error handler is present.
     *
     * @param message
     *            the message
     * @throws SAXException
     */

    final void errNoCheck(String message) throws SAXException {
        SAXParseException spe = new SAXParseException(message, tokenizer);
        errorHandler.error(spe);
    }

    private void errListUnclosedStartTags(int eltPos) throws SAXException {
        if (currentPtr != -1) {
            for (int i = currentPtr; i > eltPos; i--) {
                reportUnclosedElementNameAndLocation(i);
            }
        }
    }

    /**
     * Reports the name and location of an unclosed element.
     *
     * @throws SAXException
     */

    private final void reportUnclosedElementNameAndLocation(int pos) throws SAXException {
        StackNode<T> node = stack[pos];
        if (node.isOptionalEndTag()) {
            return;
        }
        TaintableLocatorImpl locator = node.getLocator();
        if (locator.isTainted()) {
            return;
        }
        locator.markTainted();
        SAXParseException spe = new SAXParseException(
                "Unclosed element \u201C" + node.popName + "\u201D.", locator);
        errorHandler.error(spe);
    }

    /**
     * Reports a warning
     *
     * @param message
     *            the message
     * @throws SAXException
     */

    final void warn(String message) throws SAXException {
        if (errorHandler == null) {
            return;
        }
        SAXParseException spe = new SAXParseException(message, tokenizer);
        errorHandler.warning(spe);
    }

    /**
     * Reports a warning with an explicit locator
     *
     * @param message
     *            the message
     * @throws SAXException
     */

    final void warn(String message, Locator locator) throws SAXException {
        if (errorHandler == null) {
            return;
        }
        SAXParseException spe = new SAXParseException(message, locator);
        errorHandler.warning(spe);
    }

    // ]NOCPP]

    public void setKeepBuffer(boolean keepBuffer) {
        this.keepBuffer = keepBuffer;
    }

    public boolean dropBufferIfLongerThan(int length) {
        if (charBuffer.length > length) {
            charBuffer = null;
            return true;
        }
        return false;
    }

    @SuppressWarnings("unchecked"public final void startTokenization(Tokenizer self) throws SAXException {
        tokenizer = self;
        stackNodes = new StackNode[64];
        stack = new StackNode[64];
        templateModeStack = new int[64];
        listOfActiveFormattingElements = new StackNode[64];
        needToDropLF = false;
        originalMode = INITIAL;
        templateModePtr = -1;
        stackNodesIdx = 0;
        numStackNodes = 0;
        currentPtr = -1;
        listPtr = -1;
        formPointer = null;
        headPointer = null;
        // [NOCPP[
        idLocations.clear();
        wantingComments = wantsComments();
        // ]NOCPP]
        start(fragment);
        charBufferLen = 0;
        if (!keepBuffer) {
            charBuffer = null;
        }
        framesetOk = true;
        if (fragment) {
            T elt;
            if (contextNode != null) {
                elt = contextNode;
            } else {
                elt = createHtmlElementSetAsRoot(tokenizer.emptyAttributes());
            }
            // When the context node is not in the HTML namespace, contrary
            // to the spec, the first node on the stack is not set to "html"
            // in the HTML namespace. Instead, it is set to a node that has
            // the characteristics of the appropriate "adjusted current node".
            // This way, there is no need to perform "adjusted current node"
            // checks during tree construction. Instead, it's sufficient to
            // just look at the current node. However, this also means that it
            // is not safe to treat "html" in the HTML namespace as a sentinel
            // that ends stack popping. Instead, stack popping loops that are
            // meant not to pop the first element on the stack need to check
            // for currentPos becoming zero.
            if (contextNamespace == "http://www.w3.org/2000/svg") {
                ElementName elementName = ElementName.SVG;
                if ("title" == contextName || "desc" == contextName
                        || "foreignObject" == contextName) {
                    // These elements are all alike and we don't care about
                    // the exact name.
                    elementName = ElementName.FOREIGNOBJECT;
                }
                // This is the SVG variant of the StackNode constructor.
                StackNode<T> node = createStackNode(elementName,
                        elementName.getCamelCaseName(), elt
                        // [NOCPP[
                        , errorHandler == null ? null
                                : new TaintableLocatorImpl(tokenizer)
                // ]NOCPP]
                );
                currentPtr++;
                stack[currentPtr] = node;
                tokenizer.setState(Tokenizer.DATA);
                // The frameset-ok flag is set even though <frameset> never
                // ends up being allowed as HTML frameset in the fragment case.
                mode = FRAMESET_OK;
            } else if (contextNamespace == "http://www.w3.org/1998/Math/MathML") {
                ElementName elementName = ElementName.MATH;
                if ("mi" == contextName || "mo" == contextName
                        || "mn" == contextName || "ms" == contextName
                        || "mtext" == contextName) {
                    // These elements are all alike and we don't care about
                    // the exact name.
                    elementName = ElementName.MTEXT;
                } else if ("annotation-xml" == contextName) {
                    elementName = ElementName.ANNOTATION_XML;
                    // Blink does not check the encoding attribute of the
                    // annotation-xml element innerHTML is being set on.
                    // Let's do the same at least until
                    // https://www.w3.org/Bugs/Public/show_bug.cgi?id=26783
                    // is resolved.
                }
                // This is the MathML variant of the StackNode constructor.
                StackNode<T> node = createStackNode(elementName, elt,
                        elementName.getName(), false
                        // [NOCPP[
                        , errorHandler == null ? null
                                : new TaintableLocatorImpl(tokenizer)
                // ]NOCPP]
                );
                currentPtr++;
                stack[currentPtr] = node;
                tokenizer.setState(Tokenizer.DATA);
                // The frameset-ok flag is set even though <frameset> never
                // ends up being allowed as HTML frameset in the fragment case.
                mode = FRAMESET_OK;
            } else { // html
                StackNode<T> node = createStackNode(ElementName.HTML, elt
                // [NOCPP[
                        , errorHandler == null ? null
                                : new TaintableLocatorImpl(tokenizer)
                // ]NOCPP]
                );
                currentPtr++;
                stack[currentPtr] = node;
                if ("template" == contextName) {
                    pushTemplateMode(IN_TEMPLATE);
                }
                resetTheInsertionMode();
                formPointer = getFormPointerForContext(contextNode);
                if ("title" == contextName || "textarea" == contextName) {
                    tokenizer.setState(Tokenizer.RCDATA);
                } else if ("style" == contextName || "xmp" == contextName
                        || "iframe" == contextName || "noembed" == contextName
                        || "noframes" == contextName
                        || (scriptingEnabled && "noscript" == contextName)) {
                    tokenizer.setState(Tokenizer.RAWTEXT);
                } else if ("plaintext" == contextName) {
                    tokenizer.setState(Tokenizer.PLAINTEXT);
                } else if ("script" == contextName) {
                    tokenizer.setState(Tokenizer.SCRIPT_DATA);
                } else {
                    tokenizer.setState(Tokenizer.DATA);
                }
            }
        } else {
            mode = INITIAL;
            // If we are viewing XML source, put a foreign element permanently
            // on the stack so that cdataSectionAllowed() returns true.
            // CPPONLY: if (tokenizer.isViewingXmlSource()) {
            // CPPONLY: T elt = createElement("http://www.w3.org/2000/svg",
            // CPPONLY: "svg",
            // CPPONLY: tokenizer.emptyAttributes(), null,
            // CPPONLY: svgCreator(NS_NewSVGSVGElement));
            // CPPONLY: StackNode<T> node = createStackNode(ElementName.SVG,
            // CPPONLY: "svg",
            // CPPONLY: elt);
            // CPPONLY: currentPtr++;
            // CPPONLY: stack[currentPtr] = node;
            // CPPONLY: }
        }
    }

    public final void doctype(@Local String name, String publicIdentifier,
            String systemIdentifier, boolean forceQuirks) throws SAXException {
        needToDropLF = false;
        if (!isInForeign() && mode == INITIAL) {
            // [NOCPP[
            if (reportingDoctype) {
                // ]NOCPP]
                String emptyString = Portability.newEmptyString();
                appendDoctypeToDocument(name == null ? "" : name,
                        publicIdentifier == null ? emptyString
                                : publicIdentifier,
                        systemIdentifier == null ? emptyString
                                : systemIdentifier);
                Portability.releaseString(emptyString);
                // [NOCPP[
            }
            // ]NOCPP]
            if (isQuirky(name, publicIdentifier, systemIdentifier,
                    forceQuirks)) {
                errQuirkyDoctype();
                documentModeInternal(DocumentMode.QUIRKS_MODE,
                        publicIdentifier, systemIdentifier);
            } else if (isAlmostStandards(publicIdentifier,
                    systemIdentifier)) {
                errAlmostStandardsDoctype();
                documentModeInternal(
                        DocumentMode.ALMOST_STANDARDS_MODE,
                        publicIdentifier, systemIdentifier);
            } else {
                // [NOCPP[
                if ((Portability.literalEqualsString(
                        "-//W3C//DTD HTML 4.0//EN", publicIdentifier) && (systemIdentifier == null || Portability.literalEqualsString(
                        "http://www.w3.org/TR/REC-html40/strict.dtd",
                        systemIdentifier)))
                        || (Portability.literalEqualsString(
                                "-//W3C//DTD HTML 4.01//EN",
                                publicIdentifier) && (systemIdentifier == null || Portability.literalEqualsString(
                                "http://www.w3.org/TR/html4/strict.dtd",
                                systemIdentifier)))
                        || (Portability.literalEqualsString(
                                "-//W3C//DTD XHTML 1.0 Strict//EN",
                                publicIdentifier) && Portability.literalEqualsString(
                                "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd",
                                systemIdentifier))
                        || (Portability.literalEqualsString(
                                "-//W3C//DTD XHTML 1.1//EN",
                                publicIdentifier) && Portability.literalEqualsString(
                                "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd",
                                systemIdentifier))

                ) {
                    err("Obsolete doctype. Expected \u201C\u201D.");
                } else if (!((systemIdentifier == null || Portability.literalEqualsString(
                        "about:legacy-compat", systemIdentifier)) && publicIdentifier == null)) {
                    err("Legacy doctype. Expected \u201C\u201D.");
                }
                // ]NOCPP]
                documentModeInternal(DocumentMode.STANDARDS_MODE,
                        publicIdentifier, systemIdentifier);
            }

            /*
             *
             * Then, switch to the root element mode of the tree construction
             * stage.
             */

            mode = BEFORE_HTML;
            return;
        }
        /*
         * A DOCTYPE token Parse error.
         */

        errStrayDoctype();
        /*
         * Ignore the token.
         */

        return;
    }

    public final void comment(@NoLength char[] buf, int start, int length)
            throws SAXException {
        needToDropLF = false;
        // [NOCPP[
        if (!wantingComments) {
            return;
        }
        // ]NOCPP]
        if (!isInForeign()) {
            switch (mode) {
                case INITIAL:
                case BEFORE_HTML:
                case AFTER_AFTER_BODY:
                case AFTER_AFTER_FRAMESET:
                    /*
                     * A comment token Append a Comment node to the Document
                     * object with the data attribute set to the data given in
                     * the comment token.
                     */

                    appendCommentToDocument(buf, start, length);
                    return;
                case AFTER_BODY:
                    /*
                     * A comment token Append a Comment node to the first
                     * element in the stack of open elements (the html element),
                     * with the data attribute set to the data given in the
                     * comment token.
                     */

                    flushCharacters();
                    appendComment(stack[0].node, buf, start, length);
                    return;
                default:
                    break;
            }
        }
        /*
         * A comment token Append a Comment node to the current node with the
         * data attribute set to the data given in the comment token.
         */

        flushCharacters();
        appendComment(stack[currentPtr].node, buf, start, length);
        return;
    }

    /**
     * @see nu.validator.htmlparser.common.TokenHandler#characters(char[], int,
     *      int)
     */

    public final void characters(@Const @NoLength char[] buf, int start, int length)
            throws SAXException {
        // Note: Can't attach error messages to EOF in C++ yet

        // CPPONLY: if (tokenizer.isViewingXmlSource()) {
        // CPPONLY: return;
        // CPPONLY: }
        if (needToDropLF) {
            needToDropLF = false;
            if (buf[start] == '\n') {
                start++;
                length--;
                if (length == 0) {
                    return;
                }
            }
        }

        // optimize the most common case
        switch (mode) {
            case IN_BODY:
            case IN_CELL:
            case IN_CAPTION:
                if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
                    reconstructTheActiveFormattingElements();
                }
                // CPPONLY: MOZ_FALLTHROUGH;
            case TEXT:
                accumulateCharacters(buf, start, length);
                return;
            case IN_TABLE:
            case IN_TABLE_BODY:
            case IN_ROW:
                accumulateCharactersForced(buf, start, length);
                return;
            default:
                int end = start + length;
                charactersloop: for (int i = start; i < end; i++) {
                    switch (buf[i]) {
                        case ' ':
                        case '\t':
                        case '\n':
                        case '\r':
                        case '\u000C':
                            /*
                             * A character token that is one of one of U+0009
                             * CHARACTER TABULATION, U+000A LINE FEED (LF),
                             * U+000C FORM FEED (FF), or U+0020 SPACE
                             */

                            switch (mode) {
                                case INITIAL:
                                case BEFORE_HTML:
                                case BEFORE_HEAD:
                                    /*
                                     * Ignore the token.
                                     */

                                    start = i + 1;
                                    continue;
                                case IN_HEAD:
                                case IN_HEAD_NOSCRIPT:
                                case AFTER_HEAD:
                                case IN_COLUMN_GROUP:
                                case IN_FRAMESET:
                                case AFTER_FRAMESET:
                                    /*
                                     * Append the character to the current node.
                                     */

                                    continue;
                                case FRAMESET_OK:
                                case IN_TEMPLATE:
                                case IN_BODY:
                                case IN_CELL:
                                case IN_CAPTION:
                                    if (start < i) {
                                        accumulateCharacters(buf, start, i
                                                - start);
                                        start = i;
                                    }

                                    /*
                                     * Reconstruct the active formatting
                                     * elements, if any.
                                     */

                                    if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
                                        flushCharacters();
                                        reconstructTheActiveFormattingElements();
                                    }
                                    /*
                                     * Append the token's character to the
                                     * current node.
                                     */

                                    break charactersloop;
                                case IN_SELECT:
                                case IN_SELECT_IN_TABLE:
                                    break charactersloop;
                                case IN_TABLE:
                                case IN_TABLE_BODY:
                                case IN_ROW:
                                    accumulateCharactersForced(buf, i, 1);
                                    start = i + 1;
                                    continue;
                                case AFTER_BODY:
                                case AFTER_AFTER_BODY:
                                case AFTER_AFTER_FRAMESET:
                                    if (start < i) {
                                        accumulateCharacters(buf, start, i
                                                - start);
                                        start = i;
                                    }
                                    /*
                                     * Reconstruct the active formatting
                                     * elements, if any.
                                     */

                                    flushCharacters();
                                    reconstructTheActiveFormattingElements();
                                    /*
                                     * Append the token's character to the
                                     * current node.
                                     */

                                    continue;
                            }
                            // CPPONLY: MOZ_FALLTHROUGH_ASSERT();
                        default:
                            /*
                             * A character token that is not one of one of
                             * U+0009 CHARACTER TABULATION, U+000A LINE FEED
                             * (LF), U+000C FORM FEED (FF), or U+0020 SPACE
                             */

                            switch (mode) {
                                case INITIAL:
                                    /*
                                     * Parse error.
                                     */

                                    // [NOCPP[
                                    // XXX figure out a way to report this in the Gecko View Source case
                                    err("Non-space characters found without seeing a doctype first. Expected \u201C\u201D.");
                                    // ]NOCPP]
                                    /*
                                     *
                                     * Set the document to quirks mode.
                                     */

                                    documentModeInternal(
                                            DocumentMode.QUIRKS_MODE, null,
                                            null);
                                    /*
                                     * Then, switch to the root element mode of
                                     * the tree construction stage
                                     */

                                    mode = BEFORE_HTML;
                                    /*
                                     * and reprocess the current token.
                                     */

                                    i--;
                                    continue;
                                case BEFORE_HTML:
                                    /*
                                     * Create an HTMLElement node with the tag
                                     * name html, in the HTML namespace. Append
                                     * it to the Document object.
                                     */

                                    // No need to flush characters here,
                                    // because there's nothing to flush.
                                    appendHtmlElementToDocumentAndPush();
                                    /* Switch to the main mode */
                                    mode = BEFORE_HEAD;
                                    /*
                                     * reprocess the current token.
                                     */

                                    i--;
                                    continue;
                                case BEFORE_HEAD:
                                    if (start < i) {
                                        accumulateCharacters(buf, start, i
                                                - start);
                                        start = i;
                                    }
                                    /*
                                     * /Act as if a start tag token with the tag
                                     * name "head" and no attributes had been
                                     * seen,
                                     */

                                    flushCharacters();
                                    appendToCurrentNodeAndPushHeadElement(HtmlAttributes.EMPTY_ATTRIBUTES);
                                    mode = IN_HEAD;
                                    /*
                                     * then reprocess the current token.
                                     *
                                     * This will result in an empty head element
                                     * being generated, with the current token
                                     * being reprocessed in the "after head"
                                     * insertion mode.
                                     */

                                    i--;
                                    continue;
                                case IN_HEAD:
                                    if (start < i) {
                                        accumulateCharacters(buf, start, i
                                                - start);
                                        start = i;
                                    }
                                    /*
                                     * Act as if an end tag token with the tag
                                     * name "head" had been seen,
                                     */

                                    flushCharacters();
                                    pop();
                                    mode = AFTER_HEAD;
                                    /*
                                     * and reprocess the current token.
                                     */

                                    i--;
                                    continue;
                                case IN_HEAD_NOSCRIPT:
                                    if (start < i) {
                                        accumulateCharacters(buf, start, i
                                                - start);
                                        start = i;
                                    }
                                    /*
                                     * Parse error. Act as if an end tag with
                                     * the tag name "noscript" had been seen
                                     */

                                    errNonSpaceInNoscriptInHead();
                                    flushCharacters();
                                    pop();
                                    mode = IN_HEAD;
                                    /*
                                     * and reprocess the current token.
                                     */

                                    i--;
                                    continue;
                                case AFTER_HEAD:
                                    if (start < i) {
                                        accumulateCharacters(buf, start, i
                                                - start);
                                        start = i;
                                    }
                                    /*
                                     * Act as if a start tag token with the tag
                                     * name "body" and no attributes had been
                                     * seen,
                                     */

                                    flushCharacters();
                                    appendToCurrentNodeAndPushBodyElement();
                                    mode = FRAMESET_OK;
                                    /*
                                     * and then reprocess the current token.
                                     */

                                    i--;
                                    continue;
                                case FRAMESET_OK:
                                    framesetOk = false;
                                    mode = IN_BODY;
                                    i--;
                                    continue;
                                case IN_TEMPLATE:
                                case IN_BODY:
                                case IN_CELL:
                                case IN_CAPTION:
                                    if (start < i) {
                                        accumulateCharacters(buf, start, i
                                                - start);
                                        start = i;
                                    }
                                    /*
                                     * Reconstruct the active formatting
                                     * elements, if any.
                                     */

                                    if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
                                        flushCharacters();
                                        reconstructTheActiveFormattingElements();
                                    }
                                    /*
                                     * Append the token's character to the
                                     * current node.
                                     */

                                    break charactersloop;
                                case IN_TABLE:
                                case IN_TABLE_BODY:
                                case IN_ROW:
                                    accumulateCharactersForced(buf, i, 1);
                                    start = i + 1;
                                    continue;
                                case IN_COLUMN_GROUP:
                                    if (start < i) {
                                        accumulateCharacters(buf, start, i
                                                - start);
                                        start = i;
                                    }
                                    /*
                                     * Act as if an end tag with the tag name
                                     * "colgroup" had been seen, and then, if
                                     * that token wasn't ignored, reprocess the
                                     * current token.
                                     */

                                    if (currentPtr == 0 || stack[currentPtr].getGroup() ==
                                            TreeBuilder.TEMPLATE) {
                                        errNonSpaceInColgroupInFragment();
                                        start = i + 1;
                                        continue;
                                    }
                                    flushCharacters();
                                    pop();
                                    mode = IN_TABLE;
                                    i--;
                                    continue;
                                case IN_SELECT:
                                case IN_SELECT_IN_TABLE:
                                    break charactersloop;
                                case AFTER_BODY:
                                    errNonSpaceAfterBody();
                                    fatal();
                                    mode = framesetOk ? FRAMESET_OK : IN_BODY;
                                    i--;
                                    continue;
                                case IN_FRAMESET:
                                    if (start < i) {
                                        accumulateCharacters(buf, start, i
                                                - start);
                                        // start index is adjusted below.
                                    }
                                    /*
                                     * Parse error.
                                     */

                                    errNonSpaceInFrameset();
                                    /*
                                     * Ignore the token.
                                     */

                                    start = i + 1;
                                    continue;
                                case AFTER_FRAMESET:
                                    if (start < i) {
                                        accumulateCharacters(buf, start, i
                                                - start);
                                        // start index is adjusted below.
                                    }
                                    /*
                                     * Parse error.
                                     */

                                    errNonSpaceAfterFrameset();
                                    /*
                                     * Ignore the token.
                                     */

                                    start = i + 1;
                                    continue;
                                case AFTER_AFTER_BODY:
                                    /*
                                     * Parse error.
                                     */

                                    errNonSpaceInTrailer();
                                    /*
                                     * Switch back to the main mode and
                                     * reprocess the token.
                                     */

                                    mode = framesetOk ? FRAMESET_OK : IN_BODY;
                                    i--;
                                    continue;
                                case AFTER_AFTER_FRAMESET:
                                    if (start < i) {
                                        accumulateCharacters(buf, start, i
                                                - start);
                                        // start index is adjusted below.
                                    }
                                    /*
                                     * Parse error.
                                     */

                                    errNonSpaceInTrailer();
                                    /*
                                     * Ignore the token.
                                     */

                                    start = i + 1;
                                    continue;
                            }
                    }
                }
                if (start < end) {
                    accumulateCharacters(buf, start, end - start);
                }
        }
    }

    /**
     * @see nu.validator.htmlparser.common.TokenHandler#zeroOriginatingReplacementCharacter()
     */

    public void zeroOriginatingReplacementCharacter() throws SAXException {
        if (mode == TEXT) {
            accumulateCharacters(REPLACEMENT_CHARACTER, 0, 1);
            return;
        }
        if (currentPtr >= 0) {
            if (isSpecialParentInForeign(stack[currentPtr])) {
                return;
            }
            accumulateCharacters(REPLACEMENT_CHARACTER, 0, 1);
        }
    }

    /**
     * @see nu.validator.htmlparser.common.TokenHandler#zeroOrReplacementCharacter()
     */

    public void zeroOrReplacementCharacter() throws SAXException {
        zeroOriginatingReplacementCharacter();
    }

    public final void eof() throws SAXException {
        flushCharacters();
        // Note: Can't attach error messages to EOF in C++ yet
        eofloop: for (;;) {
            switch (mode) {
                case INITIAL:
                    /*
                     * Parse error.
                     */

                    // [NOCPP[
                    err("End of file seen without seeing a doctype first. Expected \u201C\u201D.");
                    // ]NOCPP]
                    /*
                     *
                     * Set the document to quirks mode.
                     */

                    documentModeInternal(DocumentMode.QUIRKS_MODE, nullnull);
                    /*
                     * Then, switch to the root element mode of the tree
                     * construction stage
                     */

                    mode = BEFORE_HTML;
                    /*
                     * and reprocess the current token.
                     */

                    continue;
                case BEFORE_HTML:
                    /*
                     * Create an HTMLElement node with the tag name html, in the
                     * HTML namespace. Append it to the Document object.
                     */

                    appendHtmlElementToDocumentAndPush();
                    // XXX application cache manifest
                    /* Switch to the main mode */
                    mode = BEFORE_HEAD;
                    /*
                     * reprocess the current token.
                     */

                    continue;
                case BEFORE_HEAD:
                    appendToCurrentNodeAndPushHeadElement(HtmlAttributes.EMPTY_ATTRIBUTES);
                    mode = IN_HEAD;
                    continue;
                case IN_HEAD:
                    // [NOCPP[
                    if (errorHandler != null && currentPtr > 1) {
                        errEofWithUnclosedElements();
                    }
                    // ]NOCPP]
                    while (currentPtr > 0) {
                        popOnEof();
                    }
                    mode = AFTER_HEAD;
                    continue;
                case IN_HEAD_NOSCRIPT:
                    // [NOCPP[
                    errEofWithUnclosedElements();
                    // ]NOCPP]
                    while (currentPtr > 1) {
                        popOnEof();
                    }
                    mode = IN_HEAD;
                    continue;
                case AFTER_HEAD:
                    appendToCurrentNodeAndPushBodyElement();
                    mode = IN_BODY;
                    continue;
                case IN_TABLE_BODY:
                case IN_ROW:
                case IN_TABLE:
                case IN_SELECT_IN_TABLE:
                case IN_SELECT:
                case IN_COLUMN_GROUP:
                case FRAMESET_OK:
                case IN_CAPTION:
                case IN_CELL:
                case IN_BODY:
                    // [NOCPP[
                    // i > 0 to stop in time in the foreign fragment case.
                    openelementloop: for (int i = currentPtr; i > 0; i--) {
                        int group = stack[i].getGroup();
                        switch (group) {
                            case DD_OR_DT:
                            case LI:
                            case P:
                            case TBODY_OR_THEAD_OR_TFOOT:
                            case TD_OR_TH:
                            case BODY:
                            case HTML:
                                break;
                            default:
                                errEofWithUnclosedElements();
                                break openelementloop;
                        }
                    }
                    // ]NOCPP]

                    if (isTemplateModeStackEmpty()) {
                        break eofloop;
                    }

                    // fall through to IN_TEMPLATE
                    // CPPONLY: MOZ_FALLTHROUGH;
                case IN_TEMPLATE:
                    int eltPos = findLast("template");
                    if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                        assert fragment;
                        break eofloop;
                    }
                    if (errorHandler != null) {
                        errListUnclosedStartTags(0);
                    }
                    while (currentPtr >= eltPos) {
                        pop();
                    }
                    clearTheListOfActiveFormattingElementsUpToTheLastMarker();
                    popTemplateMode();
                    resetTheInsertionMode();

                    // Reprocess token.
                    continue;
                case TEXT:
                    // [NOCPP[
                    if (errorHandler != null) {
                        errNoCheck("End of file seen when expecting text or an end tag.");
                        errListUnclosedStartTags(0);
                    }
                    // ]NOCPP]
                    // XXX mark script as already executed
                    if (originalMode == AFTER_HEAD) {
                        popOnEof();
                    }
                    popOnEof();
                    mode = originalMode;
                    continue;
                case IN_FRAMESET:
                    // [NOCPP[
                    if (errorHandler != null && currentPtr > 0) {
                        errEofWithUnclosedElements();
                    }
                    // ]NOCPP]
                    break eofloop;
                case AFTER_BODY:
                case AFTER_FRAMESET:
                case AFTER_AFTER_BODY:
                case AFTER_AFTER_FRAMESET:
                default:
                    // [NOCPP[
                    if (currentPtr == 0) { // This silliness is here to poison
                        // buggy compiler optimizations in
                        // GWT
                        System.currentTimeMillis();
                    }
                    // ]NOCPP]
                    break eofloop;
            }
        }
        while (currentPtr > 0) {
            popOnEof();
        }
        if (!fragment) {
            popOnEof();
        }
        /* Stop parsing. */
    }

    /**
     * @see nu.validator.htmlparser.common.TokenHandler#endTokenization()
     */

    public final void endTokenization() throws SAXException {
        formPointer = null;
        headPointer = null;
        contextName = null;
        contextNode = null;
        templateModeStack = null;
        if (stack != null) {
            while (currentPtr > -1) {
                stack[currentPtr].release(this);
                currentPtr--;
            }
            stack = null;
        }
        if (listOfActiveFormattingElements != null) {
            while (listPtr > -1) {
                if (listOfActiveFormattingElements[listPtr] != null) {
                    listOfActiveFormattingElements[listPtr].release(this);
                }
                listPtr--;
            }
            listOfActiveFormattingElements = null;
        }
        if (stackNodes != null) {
            for (int i = 0; i < numStackNodes; i++) {
                assert stackNodes[i].isUnused();
                Portability.delete(stackNodes[i]);
            }
            numStackNodes = 0;
            stackNodesIdx = 0;
            stackNodes = null;
        }
        // [NOCPP[
        idLocations.clear();
        // ]NOCPP]

        if (!keepBuffer) {
            charBuffer = null;
        }
        end();
    }

    public final void startTag(ElementName elementName,
            HtmlAttributes attributes, boolean selfClosing) throws SAXException {
        flushCharacters();

        // [NOCPP[
        boolean wasSelfClosing = selfClosing;
        boolean voidElement = false;
        if (errorHandler != null) {
            // ID uniqueness
            @IdType String id = attributes.getId();
            if (id != null && !isTemplateContents()) {
                LocatorImpl oldLoc = idLocations.get(id);
                if (oldLoc != null) {
                    err("Duplicate ID \u201C" + id + "\u201D.");
                    errorHandler.warning(new SAXParseException(
                            "The first occurrence of ID \u201C" + id
                            + "\u201D was here.", oldLoc));
                } else {
                    idLocations.put(id, new LocatorImpl(tokenizer));
                }
            }
        }
        // ]NOCPP]

        int eltPos;
        needToDropLF = false;
        starttagloop: for (;;) {
            int group = elementName.getGroup();
            @Local String name = elementName.getName();
            if (isInForeign()) {
                StackNode<T> currentNode = stack[currentPtr];
                @NsUri String currNs = currentNode.ns;
                if (!(currentNode.isHtmlIntegrationPoint() || (currNs == "http://www.w3.org/1998/Math/MathML" && ((currentNode.getGroup() == MI_MO_MN_MS_MTEXT && group != MGLYPH_OR_MALIGNMARK) || (currentNode.getGroup() == ANNOTATION_XML && group == SVG))))) {
                    switch (group) {
                        case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
                        case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
                        case BODY:
                        case BR:
                        case RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR:
                        case DD_OR_DT:
                        case UL_OR_OL_OR_DL:
                        case EMBED:
                        case IMG:
                        case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
                        case HEAD:
                        case HR:
                        case LI:
                        case META:
                        case NOBR:
                        case P:
                        case PRE_OR_LISTING:
                        case TABLE:
                        case FONT:
                            // re-check FONT to deal with the special case
                            if (!(group == FONT && !(attributes.contains(AttributeName.COLOR)
                                    || attributes.contains(AttributeName.FACE) || attributes.contains(AttributeName.SIZE)))) {
                                errHtmlStartTagInForeignContext(name);
                                if (!fragment) {
                                    while (!isSpecialParentInForeign(stack[currentPtr])) {
                                        popForeign(-1, -1);
                                    }
                                    continue starttagloop;
                                } // else fall thru
                            }
                            // CPPONLY: MOZ_FALLTHROUGH;
                        default:
                            if ("http://www.w3.org/2000/svg" == currNs) {
                                attributes.adjustForSvg();
                                if (selfClosing) {
                                    appendVoidElementToCurrentMayFosterSVG(
                                            elementName, attributes);
                                    selfClosing = false;
                                } else {
                                    appendToCurrentNodeAndPushElementMayFosterSVG(
                                            elementName, attributes);
                                }
                                attributes = null// CPP
                                break starttagloop;
                            } else {
                                attributes.adjustForMath();
                                if (selfClosing) {
                                    appendVoidElementToCurrentMayFosterMathML(
                                            elementName, attributes);
                                    selfClosing = false;
                                } else {
                                    appendToCurrentNodeAndPushElementMayFosterMathML(
                                            elementName, attributes);
                                }
                                attributes = null// CPP
                                break starttagloop;
                            }
                    } // switch
                } // foreignObject / annotation-xml
            }
            switch (mode) {
                case IN_TEMPLATE:
                    switch (group) {
                        case COL:
                            popTemplateMode();
                            pushTemplateMode(IN_COLUMN_GROUP);
                            mode = IN_COLUMN_GROUP;
                            // Reprocess token.
                            continue;
                        case CAPTION:
                        case COLGROUP:
                        case TBODY_OR_THEAD_OR_TFOOT:
                            popTemplateMode();
                            pushTemplateMode(IN_TABLE);
                            mode = IN_TABLE;
                            // Reprocess token.
                            continue;
                        case TR:
                            popTemplateMode();
                            pushTemplateMode(IN_TABLE_BODY);
                            mode = IN_TABLE_BODY;
                            // Reprocess token.
                            continue;
                        case TD_OR_TH:
                            popTemplateMode();
                            pushTemplateMode(IN_ROW);
                            mode = IN_ROW;
                            // Reprocess token.
                            continue;
                        case META:
                            checkMetaCharset(attributes);
                            appendVoidElementToCurrentMayFoster(
                                    elementName,
                                    attributes);
                            selfClosing = false;
                            // [NOCPP[
                            voidElement = true;
                            // ]NOCPP]
                            attributes = null// CPP
                            break starttagloop;
                        case TITLE:
                            startTagTitleInHead(elementName, attributes);
                            attributes = null// CPP
                            break starttagloop;
                        case BASE:
                        case LINK_OR_BASEFONT_OR_BGSOUND:
                            appendVoidElementToCurrentMayFoster(
                                    elementName,
                                    attributes);
                            selfClosing = false;
                            // [NOCPP[
                            voidElement = true;
                            // ]NOCPP]
                            attributes = null// CPP
                            break starttagloop;
                        case SCRIPT:
                            startTagScriptInHead(elementName, attributes);
                            attributes = null// CPP
                            break starttagloop;
                        case NOFRAMES:
                        case STYLE:
                            startTagGenericRawText(elementName, attributes);
                            attributes = null// CPP
                            break starttagloop;
                        case TEMPLATE:
                            startTagTemplateInHead(elementName, attributes);
                            attributes = null// CPP
                            break starttagloop;
                        default:
                            popTemplateMode();
                            pushTemplateMode(IN_BODY);
                            mode = IN_BODY;
                            // Reprocess token.
                            continue;
                    }
                case IN_ROW:
                    switch (group) {
                        case TD_OR_TH:
                            clearStackBackTo(findLastOrRoot(TreeBuilder.TR));
                            appendToCurrentNodeAndPushElement(
                                    elementName,
                                    attributes);
                            mode = IN_CELL;
                            insertMarker();
                            attributes = null// CPP
                            break starttagloop;
                        case CAPTION:
--> --------------------

--> maximum size reached

--> --------------------

90%


¤ Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.0.39Bemerkung:  (vorverarbeitet)  ¤

*Bot Zugriff






Entwurf

Ziele

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Ergonomie der
Schnittstellen

Diese beiden folgenden Angebotsgruppen bietet das Unternehmen

Angebot

Hier finden Sie eine Liste der Produkte des Unternehmens