예제 #1
0
nsresult
txMozillaXMLOutput::endElement()
{
    TX_ENSURE_CURRENTNODE;

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

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

    NS_ASSERTION(mCurrentNode->IsElement(), "borked mCurrentNode");
    NS_ENSURE_TRUE(mCurrentNode->IsElement(), NS_ERROR_UNEXPECTED);

    nsIContent* element = static_cast<nsIContent*>
                                     (static_cast<nsINode*>
                                                 (mCurrentNode));

    // Handle html-elements
    if (!mNoFixup) {
        if (element->IsHTML()) {
            rv = endHTMLElement(element);
            NS_ENSURE_SUCCESS(rv, rv);
        }

        // Handle script elements
        if (element->Tag() == nsGkAtoms::script &&
            (element->IsHTML() ||
            element->GetNameSpaceID() == kNameSpaceID_SVG)) {

            rv = element->DoneAddingChildren(PR_TRUE);

            // If the act of insertion evaluated the script, we're fine.
            // Else, add this script element to the array of loading scripts.
            if (rv == NS_ERROR_HTMLPARSER_BLOCK) {
                nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(element);
                rv = mNotifier->AddScriptElement(sele);
                NS_ENSURE_SUCCESS(rv, rv);
            }
        }
    }

    if (mCreatingNewDocument) {
        // Handle all sorts of stylesheets
        nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
            do_QueryInterface(mCurrentNode);
        if (ssle) {
            ssle->SetEnableUpdates(PR_TRUE);
            PRBool willNotify;
            PRBool isAlternate;
            nsresult rv = ssle->UpdateStyleSheet(mNotifier, &willNotify,
                                                 &isAlternate);
            if (mNotifier && NS_SUCCEEDED(rv) && willNotify && !isAlternate) {
                mNotifier->AddPendingStylesheet();
            }
        }
    }

    // Add the element to the tree if it wasn't added before and take one step
    // up the tree
    PRUint32 last = mCurrentNodeStack.Count() - 1;
    NS_ASSERTION(last != (PRUint32)-1, "empty stack");

    nsCOMPtr<nsINode> parent = mCurrentNodeStack.SafeObjectAt(last);
    mCurrentNodeStack.RemoveObjectAt(last);

    if (mCurrentNode == mNonAddedNode) {
        if (parent == mDocument) {
            NS_ASSERTION(!mRootContentCreated,
                         "Parent to add to shouldn't be a document if we "
                         "have a root content");
            mRootContentCreated = PR_TRUE;
        }

        // Check to make sure that script hasn't inserted the node somewhere
        // else in the tree
        if (!mCurrentNode->GetNodeParent()) {
            parent->AppendChildTo(mNonAddedNode, PR_TRUE);
        }
        mNonAddedNode = nsnull;
    }

    mCurrentNode = parent;

    mTableState =
        static_cast<TableState>(NS_PTR_TO_INT32(mTableStateStack.pop()));

    return NS_OK;
}
예제 #2
0
void txMozillaXMLOutput::endElement(const nsAString& aName, const PRInt32 aNsID)
{
    TX_ENSURE_CURRENTNODE;

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

#ifdef DEBUG
    if (mTableState != ADDED_TBODY) {
        nsAutoString nodeName;
        mCurrentNode->GetNodeName(nodeName);
        NS_ASSERTION(nodeName.Equals(aName,
                                     nsCaseInsensitiveStringComparator()),
                     "Unbalanced startElement and endElement calls!");
    }
    else {
        nsCOMPtr<nsIDOMNode> parent;
        mCurrentNode->GetParentNode(getter_AddRefs(parent));
        nsAutoString nodeName;
        parent->GetNodeName(nodeName);
        NS_ASSERTION(nodeName.Equals(aName,
                                     nsCaseInsensitiveStringComparator()),
                     "Unbalanced startElement and endElement calls!");
    }
#endif

    closePrevious(eCloseElement | eFlushText);

    // Handle html-elements
    if ((mOutputFormat.mMethod == eHTMLOutput && aNsID == kNameSpaceID_None) ||
        aNsID == kNameSpaceID_XHTML) {
        nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mCurrentNode);
        NS_ASSERTION(element, "endElement'ing non-element");
        endHTMLElement(element);
    }

    // Handle svg script elements
    if (aNsID == kNameSpaceID_SVG && txHTMLAtoms::script->Equals(aName)) {
        // Add this script element to the array of loading script elements.
        nsCOMPtr<nsIScriptElement> scriptElement =
            do_QueryInterface(mCurrentNode);
        NS_ASSERTION(scriptElement, "Need script element");
        mNotifier->AddScriptElement(scriptElement);
    }

    if (mCreatingNewDocument) {
        // Handle all sorts of stylesheets
        nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
            do_QueryInterface(mCurrentNode);
        if (ssle) {
            ssle->SetEnableUpdates(PR_TRUE);
            if (ssle->UpdateStyleSheet(nsnull, mNotifier) ==
                NS_ERROR_HTMLPARSER_BLOCK) {
                nsCOMPtr<nsIStyleSheet> stylesheet;
                ssle->GetStyleSheet(*getter_AddRefs(stylesheet));
                if (mNotifier) {
                    mNotifier->AddStyleSheet(stylesheet);
                }
            }
        }
    }

    // Add the element to the tree if it wasn't added before and take one step
    // up the tree
    // we can't use GetParentNode to check if mCurrentNode is the
    // "non-added node" since that does strange things when we've called
    // BindToTree manually
    if (mCurrentNode == mNonAddedNode) {
        nsCOMPtr<nsIDocument> document = do_QueryInterface(mNonAddedParent);
        if (document && !mRootContent) {
            mRootContent = do_QueryInterface(mCurrentNode);
            // XXXbz what to do on failure here?
            document->SetRootContent(mRootContent);
        }
        else {
            nsCOMPtr<nsIDOMNode> resultNode;
            mNonAddedParent->AppendChild(mCurrentNode,
                                         getter_AddRefs(resultNode));
        }
        mCurrentNode = mNonAddedParent;
        mNonAddedParent = nsnull;
        mNonAddedNode = nsnull;
    }
    else {
        nsCOMPtr<nsIDOMNode> parent;
        mCurrentNode->GetParentNode(getter_AddRefs(parent));
        mCurrentNode = parent;
    }

    mTableState =
        NS_STATIC_CAST(TableState, NS_PTR_TO_INT32(mTableStateStack.pop()));
}