public final void startTag()

in parser/html/javasrc/TreeBuilder.java [1477:2934]


    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:
                        case COL:
                        case COLGROUP:
                        case TBODY_OR_THEAD_OR_TFOOT:
                        case TR:
                            eltPos = findLastOrRoot(TreeBuilder.TR);
                            if (eltPos == 0) {
                                assert fragment || isTemplateContents();
                                errNoTableRowToClose();
                                break starttagloop;
                            }
                            clearStackBackTo(eltPos);
                            pop();
                            mode = IN_TABLE_BODY;
                            continue;
                        default:
                            // fall through to IN_TABLE
                    }
                    // CPPONLY: MOZ_FALLTHROUGH;
                case IN_TABLE_BODY:
                    switch (group) {
                        case TR:
                            clearStackBackTo(findLastInTableScopeOrRootTemplateTbodyTheadTfoot());
                            appendToCurrentNodeAndPushElement(
                                    elementName,
                                    attributes);
                            mode = IN_ROW;
                            attributes = null; // CPP
                            break starttagloop;
                        case TD_OR_TH:
                            errStartTagInTableBody(name);
                            clearStackBackTo(findLastInTableScopeOrRootTemplateTbodyTheadTfoot());
                            appendToCurrentNodeAndPushElement(
                                    ElementName.TR,
                                    HtmlAttributes.EMPTY_ATTRIBUTES);
                            mode = IN_ROW;
                            continue;
                        case CAPTION:
                        case COL:
                        case COLGROUP:
                        case TBODY_OR_THEAD_OR_TFOOT:
                            eltPos = findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
                            if (eltPos == 0 || stack[eltPos].getGroup() == TEMPLATE) {
                                assert fragment || isTemplateContents();
                                errStrayStartTag(name);
                                break starttagloop;
                            } else {
                                clearStackBackTo(eltPos);
                                pop();
                                mode = IN_TABLE;
                                continue;
                            }
                        default:
                            // fall through to IN_TABLE
                    }
                    // CPPONLY: MOZ_FALLTHROUGH;
                case IN_TABLE:
                    intableloop: for (;;) {
                        switch (group) {
                            case CAPTION:
                                clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
                                insertMarker();
                                appendToCurrentNodeAndPushElement(
                                        elementName,
                                        attributes);
                                mode = IN_CAPTION;
                                attributes = null; // CPP
                                break starttagloop;
                            case COLGROUP:
                                clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
                                appendToCurrentNodeAndPushElement(
                                        elementName,
                                        attributes);
                                mode = IN_COLUMN_GROUP;
                                attributes = null; // CPP
                                break starttagloop;
                            case COL:
                                clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
                                appendToCurrentNodeAndPushElement(
                                        ElementName.COLGROUP,
                                        HtmlAttributes.EMPTY_ATTRIBUTES);
                                mode = IN_COLUMN_GROUP;
                                continue starttagloop;
                            case TBODY_OR_THEAD_OR_TFOOT:
                                clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
                                appendToCurrentNodeAndPushElement(
                                        elementName,
                                        attributes);
                                mode = IN_TABLE_BODY;
                                attributes = null; // CPP
                                break starttagloop;
                            case TR:
                            case TD_OR_TH:
                                clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
                                appendToCurrentNodeAndPushElement(
                                        ElementName.TBODY,
                                        HtmlAttributes.EMPTY_ATTRIBUTES);
                                mode = IN_TABLE_BODY;
                                continue starttagloop;
                            case TEMPLATE:
                                // fall through to IN_HEAD
                                break intableloop;
                            case TABLE:
                                errTableSeenWhileTableOpen();
                                eltPos = findLastInTableScope(name);
                                if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                    assert fragment || isTemplateContents();
                                    break starttagloop;
                                }
                                generateImpliedEndTags();
                                if (errorHandler != null && !isCurrent("table")) {
                                    errNoCheckUnclosedElementsOnStack();
                                }
                                while (currentPtr >= eltPos) {
                                    pop();
                                }
                                resetTheInsertionMode();
                                continue starttagloop;
                            case SCRIPT:
                                // XXX need to manage much more stuff
                                // here if
                                // supporting
                                // document.write()
                                appendToCurrentNodeAndPushElement(
                                        elementName,
                                        attributes);
                                originalMode = mode;
                                mode = TEXT;
                                tokenizer.setStateAndEndTagExpectation(
                                        Tokenizer.SCRIPT_DATA, elementName);
                                attributes = null; // CPP
                                break starttagloop;
                            case STYLE:
                                appendToCurrentNodeAndPushElement(
                                        elementName,
                                        attributes);
                                originalMode = mode;
                                mode = TEXT;
                                tokenizer.setStateAndEndTagExpectation(
                                        Tokenizer.RAWTEXT, elementName);
                                attributes = null; // CPP
                                break starttagloop;
                            case INPUT:
                                errStartTagInTable(name);
                                if (!Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
                                        "hidden",
                                        attributes.getValue(AttributeName.TYPE))) {
                                    break intableloop;
                                }
                                appendVoidInputToCurrent(
                                        attributes,
                                        formPointer);
                                selfClosing = false;
                                // [NOCPP[
                                voidElement = true;
                                // ]NOCPP]
                                attributes = null; // CPP
                                break starttagloop;
                            case FORM:
                                if (formPointer != null || isTemplateContents()) {
                                    errFormWhenFormOpen();
                                    break starttagloop;
                                } else {
                                    errStartTagInTable(name);
                                    appendVoidFormToCurrent(attributes);
                                    attributes = null; // CPP
                                    break starttagloop;
                                }
                            default:
                                errStartTagInTable(name);
                                // fall through to IN_BODY
                                break intableloop;
                        }
                    }
                    // CPPONLY: MOZ_FALLTHROUGH;
                case IN_CAPTION:
                    switch (group) {
                        case CAPTION:
                        case COL:
                        case COLGROUP:
                        case TBODY_OR_THEAD_OR_TFOOT:
                        case TR:
                        case TD_OR_TH:
                            eltPos = findLastInTableScope("caption");
                            if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                assert fragment || isTemplateContents();
                                errStrayStartTag(name);
                                break starttagloop;
                            }
                            generateImpliedEndTags();
                            if (errorHandler != null && currentPtr != eltPos) {
                                errNoCheckUnclosedElementsOnStack();
                            }
                            while (currentPtr >= eltPos) {
                                pop();
                            }
                            clearTheListOfActiveFormattingElementsUpToTheLastMarker();
                            mode = IN_TABLE;
                            continue;
                        default:
                            // fall through to IN_BODY
                    }
                    // CPPONLY: MOZ_FALLTHROUGH;
                case IN_CELL:
                    switch (group) {
                        case CAPTION:
                        case COL:
                        case COLGROUP:
                        case TBODY_OR_THEAD_OR_TFOOT:
                        case TR:
                        case TD_OR_TH:
                            eltPos = findLastInTableScopeTdTh();
                            if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                errNoCellToClose();
                                break starttagloop;
                            } else {
                                closeTheCell(eltPos);
                                continue;
                            }
                        default:
                            // fall through to IN_BODY
                    }
                    // CPPONLY: MOZ_FALLTHROUGH;
                case FRAMESET_OK:
                    switch (group) {
                        case FRAMESET:
                            if (mode == FRAMESET_OK) {
                                if (currentPtr == 0 || stack[1].getGroup() != BODY) {
                                    assert fragment || isTemplateContents();
                                    errStrayStartTag(name);
                                    break starttagloop;
                                } else {
                                    errFramesetStart();
                                    detachFromParent(stack[1].node);
                                    while (currentPtr > 0) {
                                        pop();
                                    }
                                    appendToCurrentNodeAndPushElement(
                                            elementName,
                                            attributes);
                                    mode = IN_FRAMESET;
                                    attributes = null; // CPP
                                    break starttagloop;
                                }
                            } else {
                                errStrayStartTag(name);
                                break starttagloop;
                            }
                            // NOT falling through!
                        case PRE_OR_LISTING:
                        case LI:
                        case DD_OR_DT:
                        case BUTTON:
                        case MARQUEE_OR_APPLET:
                        case OBJECT:
                        case TABLE:
                        case AREA_OR_WBR:
                        case KEYGEN:
                        case BR:
                        case EMBED:
                        case IMG:
                        case INPUT:
                        case HR:
                        case TEXTAREA:
                        case XMP:
                        case IFRAME:
                        case SELECT:
                            if (mode == FRAMESET_OK
                                    && !(group == INPUT && Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
                                            "hidden",
                                            attributes.getValue(AttributeName.TYPE)))) {
                                framesetOk = false;
                                mode = IN_BODY;
                            }
                            // CPPONLY: MOZ_FALLTHROUGH;
                        default:
                            // fall through to IN_BODY
                    }
                    // CPPONLY: MOZ_FALLTHROUGH;
                case IN_BODY:
                    inbodyloop: for (;;) {
                        switch (group) {
                            case HTML:
                                errStrayStartTag(name);
                                if (!fragment && !isTemplateContents()) {
                                    addAttributesToHtml(attributes);
                                    attributes = null; // CPP
                                }
                                break starttagloop;
                            case BASE:
                            case LINK_OR_BASEFONT_OR_BGSOUND:
                            case META:
                            case STYLE:
                            case SCRIPT:
                            case TITLE:
                            case TEMPLATE:
                                // Fall through to IN_HEAD
                                break inbodyloop;
                            case BODY:
                                if (currentPtr == 0 || stack[1].getGroup() != BODY || isTemplateContents()) {
                                    assert fragment || isTemplateContents();
                                    errStrayStartTag(name);
                                    break starttagloop;
                                }
                                errFooSeenWhenFooOpen(name);
                                framesetOk = false;
                                if (mode == FRAMESET_OK) {
                                    mode = IN_BODY;
                                }
                                if (addAttributesToBody(attributes)) {
                                    attributes = null; // CPP
                                }
                                break starttagloop;
                            case P:
                            case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
                            case UL_OR_OL_OR_DL:
                            case ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY:
                                implicitlyCloseP();
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes);
                                attributes = null; // CPP
                                break starttagloop;
                            case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
                                implicitlyCloseP();
                                if (stack[currentPtr].getGroup() == H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6) {
                                    errHeadingWhenHeadingOpen();
                                    pop();
                                }
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes);
                                attributes = null; // CPP
                                break starttagloop;
                            case FIELDSET:
                                implicitlyCloseP();
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes, formPointer);
                                attributes = null; // CPP
                                break starttagloop;
                            case PRE_OR_LISTING:
                                implicitlyCloseP();
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes);
                                needToDropLF = true;
                                attributes = null; // CPP
                                break starttagloop;
                            case FORM:
                                if (formPointer != null && !isTemplateContents()) {
                                    errFormWhenFormOpen();
                                    break starttagloop;
                                } else {
                                    implicitlyCloseP();
                                    appendToCurrentNodeAndPushFormElementMayFoster(attributes);
                                    attributes = null; // CPP
                                    break starttagloop;
                                }
                            case LI:
                            case DD_OR_DT:
                                eltPos = currentPtr;
                                for (;;) {
                                    StackNode<T> node = stack[eltPos]; // weak
                                    // ref
                                    if (node.getGroup() == group) { // LI or
                                        // DD_OR_DT
                                        generateImpliedEndTagsExceptFor(node.name);
                                        if (errorHandler != null
                                                && eltPos != currentPtr) {
                                            errUnclosedElementsImplied(eltPos, name);
                                        }
                                        while (currentPtr >= eltPos) {
                                            pop();
                                        }
                                        break;
                                    } else if (eltPos == 0 || (node.isSpecial()
                                            && (node.ns != "http://www.w3.org/1999/xhtml"
                                                    || (node.name != "p"
                                                            && node.name != "address"
                                                            && node.name != "div")))) {
                                        break;
                                    }
                                    eltPos--;
                                }
                                implicitlyCloseP();
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes);
                                attributes = null; // CPP
                                break starttagloop;
                            case PLAINTEXT:
                                implicitlyCloseP();
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes);
                                tokenizer.setStateAndEndTagExpectation(
                                        Tokenizer.PLAINTEXT, elementName);
                                attributes = null; // CPP
                                break starttagloop;
                            case A:
                                int activeAPos = findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker("a");
                                if (activeAPos != -1) {
                                    errFooSeenWhenFooOpen(name);
                                    StackNode<T> activeA = listOfActiveFormattingElements[activeAPos];
                                    activeA.retain();
                                    adoptionAgencyEndTag("a");
                                    removeFromStack(activeA);
                                    activeAPos = findInListOfActiveFormattingElements(activeA);
                                    if (activeAPos != -1) {
                                        removeFromListOfActiveFormattingElements(activeAPos);
                                    }
                                    activeA.release(this);
                                }
                                reconstructTheActiveFormattingElements();
                                appendToCurrentNodeAndPushFormattingElementMayFoster(
                                        elementName,
                                        attributes);
                                attributes = null; // CPP
                                break starttagloop;
                            case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
                            case FONT:
                                reconstructTheActiveFormattingElements();
                                maybeForgetEarlierDuplicateFormattingElement(elementName.getName(), attributes);
                                appendToCurrentNodeAndPushFormattingElementMayFoster(
                                        elementName,
                                        attributes);
                                attributes = null; // CPP
                                break starttagloop;
                            case NOBR:
                                reconstructTheActiveFormattingElements();
                                if (TreeBuilder.NOT_FOUND_ON_STACK != findLastInScope("nobr")) {
                                    errFooSeenWhenFooOpen(name);
                                    adoptionAgencyEndTag("nobr");
                                    reconstructTheActiveFormattingElements();
                                }
                                appendToCurrentNodeAndPushFormattingElementMayFoster(
                                        elementName,
                                        attributes);
                                attributes = null; // CPP
                                break starttagloop;
                            case BUTTON:
                                eltPos = findLastInScope(name);
                                if (eltPos != TreeBuilder.NOT_FOUND_ON_STACK) {
                                    errFooSeenWhenFooOpen(name);
                                    generateImpliedEndTags();
                                    if (errorHandler != null
                                            && !isCurrent(name)) {
                                        errUnclosedElementsImplied(eltPos, name);
                                    }
                                    while (currentPtr >= eltPos) {
                                        pop();
                                    }
                                    continue starttagloop;
                                } else {
                                    reconstructTheActiveFormattingElements();
                                    appendToCurrentNodeAndPushElementMayFoster(
                                            elementName,
                                            attributes, formPointer);
                                    attributes = null; // CPP
                                    break starttagloop;
                                }
                            case OBJECT:
                                reconstructTheActiveFormattingElements();
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes, formPointer);
                                insertMarker();
                                attributes = null; // CPP
                                break starttagloop;
                            case MARQUEE_OR_APPLET:
                                reconstructTheActiveFormattingElements();
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes);
                                insertMarker();
                                attributes = null; // CPP
                                break starttagloop;
                            case TABLE:
                                // The only quirk. Blame Hixie and
                                // Acid2.
                                if (!quirks) {
                                    implicitlyCloseP();
                                }
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes);
                                mode = IN_TABLE;
                                attributes = null; // CPP
                                break starttagloop;
                            case BR:
                            case EMBED:
                            case AREA_OR_WBR:
                            case KEYGEN:
                                reconstructTheActiveFormattingElements();
                                // FALL THROUGH to PARAM_OR_SOURCE_OR_TRACK
                                // CPPONLY: MOZ_FALLTHROUGH;
                            case PARAM_OR_SOURCE_OR_TRACK:
                                appendVoidElementToCurrentMayFoster(
                                        elementName,
                                        attributes);
                                selfClosing = false;
                                // [NOCPP[
                                voidElement = true;
                                // ]NOCPP]
                                attributes = null; // CPP
                                break starttagloop;
                            case HR:
                                implicitlyCloseP();
                                appendVoidElementToCurrentMayFoster(
                                        elementName,
                                        attributes);
                                selfClosing = false;
                                // [NOCPP[
                                voidElement = true;
                                // ]NOCPP]
                                attributes = null; // CPP
                                break starttagloop;
                            case IMAGE:
                                errImage();
                                elementName = ElementName.IMG;
                                continue starttagloop;
                            case IMG:
                            case INPUT:
                                reconstructTheActiveFormattingElements();
                                appendVoidElementToCurrentMayFoster(
                                        elementName, attributes,
                                        formPointer);
                                selfClosing = false;
                                // [NOCPP[
                                voidElement = true;
                                // ]NOCPP]
                                attributes = null; // CPP
                                break starttagloop;
                            case TEXTAREA:
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes, formPointer);
                                tokenizer.setStateAndEndTagExpectation(
                                        Tokenizer.RCDATA, elementName);
                                originalMode = mode;
                                mode = TEXT;
                                needToDropLF = true;
                                attributes = null; // CPP
                                break starttagloop;
                            case XMP:
                                implicitlyCloseP();
                                reconstructTheActiveFormattingElements();
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes);
                                originalMode = mode;
                                mode = TEXT;
                                tokenizer.setStateAndEndTagExpectation(
                                        Tokenizer.RAWTEXT, elementName);
                                attributes = null; // CPP
                                break starttagloop;
                            case NOSCRIPT:
                                if (!scriptingEnabled) {
                                    reconstructTheActiveFormattingElements();
                                    appendToCurrentNodeAndPushElementMayFoster(
                                            elementName,
                                            attributes);
                                    attributes = null; // CPP
                                    break starttagloop;
                                }
                                // CPPONLY: MOZ_FALLTHROUGH;
                            case NOFRAMES:
                            case IFRAME:
                            case NOEMBED:
                                startTagGenericRawText(elementName, attributes);
                                attributes = null; // CPP
                                break starttagloop;
                            case SELECT:
                                reconstructTheActiveFormattingElements();
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes, formPointer);
                                switch (mode) {
                                    case IN_TABLE:
                                    case IN_CAPTION:
                                    case IN_COLUMN_GROUP:
                                    case IN_TABLE_BODY:
                                    case IN_ROW:
                                    case IN_CELL:
                                        mode = IN_SELECT_IN_TABLE;
                                        break;
                                    default:
                                        mode = IN_SELECT;
                                        break;
                                }
                                attributes = null; // CPP
                                break starttagloop;
                            case OPTGROUP:
                            case OPTION:
                                if (isCurrent("option")) {
                                    pop();
                                }
                                reconstructTheActiveFormattingElements();
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes);
                                attributes = null; // CPP
                                break starttagloop;
                            case RB_OR_RTC:
                                eltPos = findLastInScope("ruby");
                                if (eltPos != NOT_FOUND_ON_STACK) {
                                    generateImpliedEndTags();
                                }
                                if (eltPos != currentPtr) {
                                    if (eltPos == NOT_FOUND_ON_STACK) {
                                        errStartTagSeenWithoutRuby(name);
                                    } else {
                                        errUnclosedChildrenInRuby();
                                    }
                                }
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes);
                                attributes = null; // CPP
                                break starttagloop;
                            case RT_OR_RP:
                                eltPos = findLastInScope("ruby");
                                if (eltPos != NOT_FOUND_ON_STACK) {
                                    generateImpliedEndTagsExceptFor("rtc");
                                }
                                if (eltPos != currentPtr) {
                                    if (!isCurrent("rtc")) {
                                        if (eltPos == NOT_FOUND_ON_STACK) {
                                            errStartTagSeenWithoutRuby(name);
                                        } else {
                                            errUnclosedChildrenInRuby();
                                        }
                                    }
                                }
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes);
                                attributes = null; // CPP
                                break starttagloop;
                            case MATH:
                                reconstructTheActiveFormattingElements();
                                attributes.adjustForMath();
                                if (selfClosing) {
                                    appendVoidElementToCurrentMayFosterMathML(
                                            elementName, attributes);
                                    selfClosing = false;
                                } else {
                                    appendToCurrentNodeAndPushElementMayFosterMathML(
                                            elementName, attributes);
                                }
                                attributes = null; // CPP
                                break starttagloop;
                            case SVG:
                                reconstructTheActiveFormattingElements();
                                attributes.adjustForSvg();
                                if (selfClosing) {
                                    appendVoidElementToCurrentMayFosterSVG(
                                            elementName,
                                            attributes);
                                    selfClosing = false;
                                } else {
                                    appendToCurrentNodeAndPushElementMayFosterSVG(
                                            elementName, attributes);
                                }
                                attributes = null; // CPP
                                break starttagloop;
                            case CAPTION:
                            case COL:
                            case COLGROUP:
                            case TBODY_OR_THEAD_OR_TFOOT:
                            case TR:
                            case TD_OR_TH:
                            case FRAME:
                            case FRAMESET:
                            case HEAD:
                                errStrayStartTag(name);
                                break starttagloop;
                            case OUTPUT:
                                reconstructTheActiveFormattingElements();
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes, formPointer);
                                attributes = null; // CPP
                                break starttagloop;
                            default:
                                reconstructTheActiveFormattingElements();
                                appendToCurrentNodeAndPushElementMayFoster(
                                        elementName,
                                        attributes);
                                attributes = null; // CPP
                                break starttagloop;
                        }
                    }
                    // CPPONLY: MOZ_FALLTHROUGH;
                case IN_HEAD:
                    inheadloop: for (;;) {
                        switch (group) {
                            case HTML:
                                errStrayStartTag(name);
                                if (!fragment && !isTemplateContents()) {
                                    addAttributesToHtml(attributes);
                                    attributes = null; // CPP
                                }
                                break starttagloop;
                            case BASE:
                            case LINK_OR_BASEFONT_OR_BGSOUND:
                                appendVoidElementToCurrentMayFoster(
                                        elementName,
                                        attributes);
                                selfClosing = false;
                                // [NOCPP[
                                voidElement = true;
                                // ]NOCPP]
                                attributes = null; // CPP
                                break starttagloop;
                            case META:
                                // Fall through to IN_HEAD_NOSCRIPT
                                break inheadloop;
                            case TITLE:
                                startTagTitleInHead(elementName, attributes);
                                attributes = null; // CPP
                                break starttagloop;
                            case NOSCRIPT:
                                if (scriptingEnabled) {
                                    appendToCurrentNodeAndPushElement(
                                            elementName,
                                            attributes);
                                    originalMode = mode;
                                    mode = TEXT;
                                    tokenizer.setStateAndEndTagExpectation(
                                            Tokenizer.RAWTEXT, elementName);
                                } else {
                                    appendToCurrentNodeAndPushElementMayFoster(
                                            elementName,
                                            attributes);
                                    mode = IN_HEAD_NOSCRIPT;
                                }
                                attributes = null; // CPP
                                break starttagloop;
                            case SCRIPT:
                                startTagScriptInHead(elementName, attributes);
                                attributes = null; // CPP
                                break starttagloop;
                            case STYLE:
                            case NOFRAMES:
                                startTagGenericRawText(elementName, attributes);
                                attributes = null; // CPP
                                break starttagloop;
                            case HEAD:
                                /* Parse error. */
                                errFooSeenWhenFooOpen(name);
                                /* Ignore the token. */
                                break starttagloop;
                            case TEMPLATE:
                                startTagTemplateInHead(elementName, attributes);
                                attributes = null; // CPP
                                break starttagloop;
                            default:
                                pop();
                                mode = AFTER_HEAD;
                                continue starttagloop;
                        }
                    }
                    // CPPONLY: MOZ_FALLTHROUGH;
                case IN_HEAD_NOSCRIPT:
                    switch (group) {
                        case HTML:
                            // XXX did Hixie really mean to omit "base"
                            // here?
                            errStrayStartTag(name);
                            if (!fragment && !isTemplateContents()) {
                                addAttributesToHtml(attributes);
                                attributes = null; // CPP
                            }
                            break starttagloop;
                        case LINK_OR_BASEFONT_OR_BGSOUND:
                            appendVoidElementToCurrentMayFoster(
                                    elementName,
                                    attributes);
                            selfClosing = false;
                            // [NOCPP[
                            voidElement = true;
                            // ]NOCPP]
                            attributes = null; // CPP
                            break starttagloop;
                        case META:
                            checkMetaCharset(attributes);
                            appendVoidElementToCurrentMayFoster(
                                    elementName,
                                    attributes);
                            selfClosing = false;
                            // [NOCPP[
                            voidElement = true;
                            // ]NOCPP]
                            attributes = null; // CPP
                            break starttagloop;
                        case STYLE:
                        case NOFRAMES:
                            appendToCurrentNodeAndPushElement(
                                    elementName,
                                    attributes);
                            originalMode = mode;
                            mode = TEXT;
                            tokenizer.setStateAndEndTagExpectation(
                                    Tokenizer.RAWTEXT, elementName);
                            attributes = null; // CPP
                            break starttagloop;
                        case HEAD:
                            errFooSeenWhenFooOpen(name);
                            break starttagloop;
                        case NOSCRIPT:
                            errFooSeenWhenFooOpen(name);
                            break starttagloop;
                        default:
                            errBadStartTagInNoscriptInHead(name);
                            pop();
                            mode = IN_HEAD;
                            continue;
                    }
                case IN_COLUMN_GROUP:
                    switch (group) {
                        case HTML:
                            errStrayStartTag(name);
                            if (!fragment && !isTemplateContents()) {
                                addAttributesToHtml(attributes);
                                attributes = null; // CPP
                            }
                            break starttagloop;
                        case COL:
                            appendVoidElementToCurrentMayFoster(
                                    elementName,
                                    attributes);
                            selfClosing = false;
                            // [NOCPP[
                            voidElement = true;
                            // ]NOCPP]
                            attributes = null; // CPP
                            break starttagloop;
                        case TEMPLATE:
                            startTagTemplateInHead(elementName, attributes);
                            attributes = null; // CPP
                            break starttagloop;
                        default:
                            if (currentPtr == 0 || stack[currentPtr].getGroup() == TEMPLATE) {
                                assert fragment || isTemplateContents();
                                errGarbageInColgroup();
                                break starttagloop;
                            }
                            pop();
                            mode = IN_TABLE;
                            continue;
                    }
                case IN_SELECT_IN_TABLE:
                    switch (group) {
                        case CAPTION:
                        case TBODY_OR_THEAD_OR_TFOOT:
                        case TR:
                        case TD_OR_TH:
                        case TABLE:
                            errStartTagWithSelectOpen(name);
                            eltPos = findLastInTableScope("select");
                            if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                assert fragment;
                                break starttagloop; // http://www.w3.org/Bugs/Public/show_bug.cgi?id=8375
                            }
                            while (currentPtr >= eltPos) {
                                pop();
                            }
                            resetTheInsertionMode();
                            continue;
                        default:
                            // fall through to IN_SELECT
                    }
                    // CPPONLY: MOZ_FALLTHROUGH;
                case IN_SELECT:
                    switch (group) {
                        case HTML:
                            errStrayStartTag(name);
                            if (!fragment) {
                                addAttributesToHtml(attributes);
                                attributes = null; // CPP
                            }
                            break starttagloop;
                        case OPTION:
                            if (isCurrent("option")) {
                                pop();
                            }
                            appendToCurrentNodeAndPushElement(
                                    elementName,
                                    attributes);
                            attributes = null; // CPP
                            break starttagloop;
                        case OPTGROUP:
                            if (isCurrent("option")) {
                                pop();
                            }
                            if (isCurrent("optgroup")) {
                                pop();
                            }
                            appendToCurrentNodeAndPushElement(
                                    elementName,
                                    attributes);
                            attributes = null; // CPP
                            break starttagloop;
                        case SELECT:
                            errStartSelectWhereEndSelectExpected();
                            eltPos = findLastInTableScope(name);
                            if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                assert fragment;
                                errNoSelectInTableScope();
                                break starttagloop;
                            } else {
                                while (currentPtr >= eltPos) {
                                    pop();
                                }
                                resetTheInsertionMode();
                                break starttagloop;
                            }
                        case INPUT:
                        case TEXTAREA:
                            errStartTagWithSelectOpen(name);
                            eltPos = findLastInTableScope("select");
                            if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                assert fragment;
                                break starttagloop;
                            }
                            while (currentPtr >= eltPos) {
                                pop();
                            }
                            resetTheInsertionMode();
                            continue;
                        case SCRIPT:
                            startTagScriptInHead(elementName, attributes);
                            attributes = null; // CPP
                            break starttagloop;
                        case TEMPLATE:
                            startTagTemplateInHead(elementName, attributes);
                            attributes = null; // CPP
                            break starttagloop;
                        case HR:
                            if (isCurrent("option")) {
                                pop();
                            }
                            if (isCurrent("optgroup")) {
                                pop();
                            }
                            appendVoidElementToCurrent(elementName, attributes);
                            selfClosing = false;
                            // [NOCPP[
                            voidElement = true;
                            // ]NOCPP]
                            attributes = null; // CPP
                            break starttagloop;
                        default:
                            errStrayStartTag(name);
                            break starttagloop;
                    }
                case AFTER_BODY:
                    switch (group) {
                        case HTML:
                            errStrayStartTag(name);
                            if (!fragment && !isTemplateContents()) {
                                addAttributesToHtml(attributes);
                                attributes = null; // CPP
                            }
                            break starttagloop;
                        default:
                            errStrayStartTag(name);
                            mode = framesetOk ? FRAMESET_OK : IN_BODY;
                            continue;
                    }
                case IN_FRAMESET:
                    switch (group) {
                        case FRAMESET:
                            appendToCurrentNodeAndPushElement(
                                    elementName,
                                    attributes);
                            attributes = null; // CPP
                            break starttagloop;
                        case FRAME:
                            appendVoidElementToCurrentMayFoster(
                                    elementName,
                                    attributes);
                            selfClosing = false;
                            // [NOCPP[
                            voidElement = true;
                            // ]NOCPP]
                            attributes = null; // CPP
                            break starttagloop;
                        default:
                            // fall through to AFTER_FRAMESET
                    }
                    // CPPONLY: MOZ_FALLTHROUGH;
                case AFTER_FRAMESET:
                    switch (group) {
                        case HTML:
                            errStrayStartTag(name);
                            if (!fragment && !isTemplateContents()) {
                                addAttributesToHtml(attributes);
                                attributes = null; // CPP
                            }
                            break starttagloop;
                        case NOFRAMES:
                            appendToCurrentNodeAndPushElement(
                                    elementName,
                                    attributes);
                            originalMode = mode;
                            mode = TEXT;
                            tokenizer.setStateAndEndTagExpectation(
                                    Tokenizer.RAWTEXT, elementName);
                            attributes = null; // CPP
                            break starttagloop;
                        default:
                            errStrayStartTag(name);
                            break starttagloop;
                    }
                case INITIAL:
                    /*
                     * Parse error.
                     */
                    errStartTagWithoutDoctype();
                    /*
                     *
                     * 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.
                     */
                    continue;
                case BEFORE_HTML:
                    switch (group) {
                        case HTML:
                            // optimize error check and streaming SAX by
                            // hoisting
                            // "html" handling here.
                            if (attributes == HtmlAttributes.EMPTY_ATTRIBUTES) {
                                // This has the right magic side effect
                                // that
                                // it
                                // makes attributes in SAX Tree mutable.
                                appendHtmlElementToDocumentAndPush();
                            } else {
                                appendHtmlElementToDocumentAndPush(attributes);
                            }
                            // XXX application cache should fire here
                            mode = BEFORE_HEAD;
                            attributes = null; // CPP
                            break starttagloop;
                        default:
                            /*
                             * Create an HTMLElement node with the tag name
                             * html, in the HTML namespace. Append it to the
                             * Document object.
                             */
                            appendHtmlElementToDocumentAndPush();
                            /* Switch to the main mode */
                            mode = BEFORE_HEAD;
                            /*
                             * reprocess the current token.
                             */
                            continue;
                    }
                case BEFORE_HEAD:
                    switch (group) {
                        case HTML:
                            errStrayStartTag(name);
                            if (!fragment && !isTemplateContents()) {
                                addAttributesToHtml(attributes);
                                attributes = null; // CPP
                            }
                            break starttagloop;
                        case HEAD:
                            /*
                             * A start tag whose tag name is "head"
                             *
                             * Create an element for the token.
                             *
                             * Set the head element pointer to this new element
                             * node.
                             *
                             * Append the new element to the current node and
                             * push it onto the stack of open elements.
                             */
                            appendToCurrentNodeAndPushHeadElement(attributes);
                            /*
                             * Change the insertion mode to "in head".
                             */
                            mode = IN_HEAD;
                            attributes = null; // CPP
                            break starttagloop;
                        default:
                            /*
                             * Any other start tag token
                             *
                             * Act as if a start tag token with the tag name
                             * "head" and no attributes had been seen,
                             */
                            appendToCurrentNodeAndPushHeadElement(HtmlAttributes.EMPTY_ATTRIBUTES);
                            mode = IN_HEAD;
                            /*
                             * then reprocess the current token.
                             *
                             * This will result in an empty head element being
                             * generated, with the current token being
                             * reprocessed in the "after head" insertion mode.
                             */
                            continue;
                    }
                case AFTER_HEAD:
                    switch (group) {
                        case HTML:
                            errStrayStartTag(name);
                            if (!fragment && !isTemplateContents()) {
                                addAttributesToHtml(attributes);
                                attributes = null; // CPP
                            }
                            break starttagloop;
                        case BODY:
                            if (attributes.getLength() == 0) {
                                // This has the right magic side effect
                                // that
                                // it
                                // makes attributes in SAX Tree mutable.
                                appendToCurrentNodeAndPushBodyElement();
                            } else {
                                appendToCurrentNodeAndPushBodyElement(attributes);
                            }
                            framesetOk = false;
                            mode = IN_BODY;
                            attributes = null; // CPP
                            break starttagloop;
                        case FRAMESET:
                            appendToCurrentNodeAndPushElement(
                                    elementName,
                                    attributes);
                            mode = IN_FRAMESET;
                            attributes = null; // CPP
                            break starttagloop;
                        case TEMPLATE:
                            errFooBetweenHeadAndBody(name);
                            pushHeadPointerOntoStack();
                            StackNode<T> headOnStack = stack[currentPtr];
                            startTagTemplateInHead(elementName, attributes);
                            removeFromStack(headOnStack);
                            attributes = null; // CPP
                            break starttagloop;
                        case BASE:
                        case LINK_OR_BASEFONT_OR_BGSOUND:
                            errFooBetweenHeadAndBody(name);
                            pushHeadPointerOntoStack();
                            appendVoidElementToCurrentMayFoster(
                                    elementName,
                                    attributes);
                            selfClosing = false;
                            // [NOCPP[
                            voidElement = true;
                            // ]NOCPP]
                            pop(); // head
                            attributes = null; // CPP
                            break starttagloop;
                        case META:
                            errFooBetweenHeadAndBody(name);
                            checkMetaCharset(attributes);
                            pushHeadPointerOntoStack();
                            appendVoidElementToCurrentMayFoster(
                                    elementName,
                                    attributes);
                            selfClosing = false;
                            // [NOCPP[
                            voidElement = true;
                            // ]NOCPP]
                            pop(); // head
                            attributes = null; // CPP
                            break starttagloop;
                        case SCRIPT:
                            errFooBetweenHeadAndBody(name);
                            pushHeadPointerOntoStack();
                            appendToCurrentNodeAndPushElement(
                                    elementName,
                                    attributes);
                            originalMode = mode;
                            mode = TEXT;
                            tokenizer.setStateAndEndTagExpectation(
                                    Tokenizer.SCRIPT_DATA, elementName);
                            attributes = null; // CPP
                            break starttagloop;
                        case STYLE:
                        case NOFRAMES:
                            errFooBetweenHeadAndBody(name);
                            pushHeadPointerOntoStack();
                            appendToCurrentNodeAndPushElement(
                                    elementName,
                                    attributes);
                            originalMode = mode;
                            mode = TEXT;
                            tokenizer.setStateAndEndTagExpectation(
                                    Tokenizer.RAWTEXT, elementName);
                            attributes = null; // CPP
                            break starttagloop;
                        case TITLE:
                            errFooBetweenHeadAndBody(name);
                            pushHeadPointerOntoStack();
                            appendToCurrentNodeAndPushElement(
                                    elementName,
                                    attributes);
                            originalMode = mode;
                            mode = TEXT;
                            tokenizer.setStateAndEndTagExpectation(
                                    Tokenizer.RCDATA, elementName);
                            attributes = null; // CPP
                            break starttagloop;
                        case HEAD:
                            errStrayStartTag(name);
                            break starttagloop;
                        default:
                            appendToCurrentNodeAndPushBodyElement();
                            mode = FRAMESET_OK;
                            continue;
                    }
                case AFTER_AFTER_BODY:
                    switch (group) {
                        case HTML:
                            errStrayStartTag(name);
                            if (!fragment && !isTemplateContents()) {
                                addAttributesToHtml(attributes);
                                attributes = null; // CPP
                            }
                            break starttagloop;
                        default:
                            errStrayStartTag(name);
                            fatal();
                            mode = framesetOk ? FRAMESET_OK : IN_BODY;
                            continue;
                    }
                case AFTER_AFTER_FRAMESET:
                    switch (group) {
                        case HTML:
                            errStrayStartTag(name);
                            if (!fragment && !isTemplateContents()) {
                                addAttributesToHtml(attributes);
                                attributes = null; // CPP
                            }
                            break starttagloop;
                        case NOFRAMES:
                            startTagGenericRawText(elementName, attributes);
                            attributes = null; // CPP
                            break starttagloop;
                        default:
                            errStrayStartTag(name);
                            break starttagloop;
                    }
                case TEXT:
                    assert false;
                    break starttagloop; // Avoid infinite loop if the assertion
                                        // fails
            }
        }
        if (selfClosing) {
            errSelfClosing();
        // [NOCPP[
        } else if (wasSelfClosing && voidElement
                && tokenizer.getErrorProfile() != null
                && tokenizer.getErrorProfile().get("html-strict") != null) {
            warn("Trailing slash on void elements has no effect and interacts"
                    + " badly with unquoted attribute values.");
        // ]NOCPP]
        }
        // CPPONLY: if (mBuilder == null && attributes != HtmlAttributes.EMPTY_ATTRIBUTES) {
        // CPPONLY:    Portability.delete(attributes);
        // CPPONLY: }
    }