nsresult
txMozillaXMLOutput::startElementInternal(nsIAtom* aPrefix,
                                         nsIAtom* aLocalName,
                                         PRInt32 aNsID)
{
    TX_ENSURE_CURRENTNODE;

    if (mBadChildLevel) {
        ++mBadChildLevel;
        PR_LOG(txLog::xslt, PR_LOG_DEBUG,
               ("startElement, mBadChildLevel = %d\n", mBadChildLevel));
        return NS_OK;
    }

    nsresult rv = closePrevious(PR_TRUE);
    NS_ENSURE_SUCCESS(rv, rv);

    // Push and init state
    if (mTreeDepth == MAX_REFLOW_DEPTH) {
        // eCloseElement couldn't add the parent so we fail as well or we've
        // reached the limit of the depth of the tree that we allow.
        ++mBadChildLevel;
        PR_LOG(txLog::xslt, PR_LOG_DEBUG,
               ("startElement, mBadChildLevel = %d\n", mBadChildLevel));
        return NS_OK;
    }

    ++mTreeDepth;

    rv = mTableStateStack.push(NS_INT32_TO_PTR(mTableState));
    NS_ENSURE_SUCCESS(rv, rv);

    if (!mCurrentNodeStack.AppendObject(mCurrentNode)) {
        return NS_ERROR_OUT_OF_MEMORY;
    }

    mTableState = NORMAL;
    mOpenedElementIsHTML = PR_FALSE;

    // Create the element
    nsCOMPtr<nsINodeInfo> ni;
    ni = mNodeInfoManager->GetNodeInfo(aLocalName, aPrefix, aNsID);
    NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);

    NS_NewElement(getter_AddRefs(mOpenedElement), aNsID, ni.forget(), PR_FALSE);

    // Set up the element and adjust state
    if (!mNoFixup) {
        if (aNsID == kNameSpaceID_XHTML) {
            mOpenedElementIsHTML = (mOutputFormat.mMethod == eHTMLOutput);
            rv = startHTMLElement(mOpenedElement, mOpenedElementIsHTML);
            NS_ENSURE_SUCCESS(rv, rv);

        }
    }

    if (mCreatingNewDocument) {
        // Handle all sorts of stylesheets
        nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
            do_QueryInterface(mOpenedElement);
        if (ssle) {
            ssle->InitStyleLinkElement(PR_FALSE);
            ssle->SetEnableUpdates(PR_FALSE);
        }
    }

    return NS_OK;
}
void txMozillaXMLOutput::startElement(const nsAString& aName,
                                      const PRInt32 aNsID)
{
    TX_ENSURE_CURRENTNODE;

    if (mBadChildLevel) {
        ++mBadChildLevel;
        PR_LOG(txLog::xslt, PR_LOG_DEBUG,
               ("startElement, mBadChildLevel = %d\n", mBadChildLevel));
        return;
    }

    closePrevious(eCloseElement | eFlushText);

    if (mBadChildLevel || mTreeDepth == MAX_REFLOW_DEPTH) {
        // eCloseElement couldn't add the parent so we fail as well or we've
        // reached the limit of the depth of the tree that we allow.
        ++mBadChildLevel;
        PR_LOG(txLog::xslt, PR_LOG_DEBUG,
               ("startElement, mBadChildLevel = %d\n", mBadChildLevel));
        return;
    }

    ++mTreeDepth;

    nsresult rv = mTableStateStack.push(NS_INT32_TO_PTR(mTableState));
    if (NS_FAILED(rv)) {
        return;
    }
    mTableState = NORMAL;

    nsCOMPtr<nsIDOMElement> element;
    mDontAddCurrent = PR_FALSE;

    if ((mOutputFormat.mMethod == eHTMLOutput) && (aNsID == kNameSpaceID_None)) {
        if (mDocumentIsHTML) {
            rv = mDocument->CreateElement(aName,
                                          getter_AddRefs(element));
        }
        else {
            nsAutoString lcname;
            ToLowerCase(aName, lcname);
            rv = mDocument->CreateElementNS(NS_LITERAL_STRING(kXHTMLNameSpaceURI),
                                            lcname,
                                            getter_AddRefs(element));
        }
        if (NS_FAILED(rv)) {
            return;
        }

        startHTMLElement(element, PR_FALSE);
    }
    else {
        nsAutoString nsURI;
        gTxNameSpaceManager->GetNameSpaceURI(aNsID, nsURI);
        rv = mDocument->CreateElementNS(nsURI, aName,
                                        getter_AddRefs(element));
        NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create element");
        if (NS_FAILED(rv)) {
            return;
        }

        if (aNsID == kNameSpaceID_XHTML) {
            startHTMLElement(element, PR_TRUE);
        } else if (aNsID == kNameSpaceID_SVG &&
                   txHTMLAtoms::script->Equals(aName)) {
            mDontAddCurrent = PR_TRUE;
        }
    }

    if (mCreatingNewDocument) {
        // Handle all sorts of stylesheets
        nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
            do_QueryInterface(element);
        if (ssle) {
            ssle->InitStyleLinkElement(nsnull, PR_FALSE);
            ssle->SetEnableUpdates(PR_FALSE);
        }
    }
    mParentNode = mCurrentNode;
    mCurrentNode = do_QueryInterface(element);
}