/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the TransforMiiX XSLT processor. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 2001 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Peter Van der Beken * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "txMozillaTextOutput.h" #include "nsContentCID.h" #include "nsIDocument.h" #include "nsIDOMDocument.h" #include "nsIDOMElement.h" #include "nsIDOMHTMLElement.h" #include "nsIDOMText.h" #include "nsIDocumentTransformer.h" #include "TxString.h" #include "nsNetUtil.h" #include "nsIDOMNSDocument.h" static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID); txMozillaTextOutput::txMozillaTextOutput(nsIDOMDocument* aSourceDocument, nsIDOMDocument* aResultDocument, nsITransformObserver* aObserver) { mObserver = do_GetWeakReference(aObserver); createResultDocument(aSourceDocument, aResultDocument); } txMozillaTextOutput::txMozillaTextOutput(nsIDOMDocumentFragment* aDest) { nsCOMPtr doc; aDest->GetOwnerDocument(getter_AddRefs(doc)); NS_ASSERTION(doc, "unable to get ownerdocument"); nsCOMPtr textNode; nsresult rv = doc->CreateTextNode(NS_LITERAL_STRING(""), getter_AddRefs(textNode)); if (NS_FAILED(rv)) { return; } nsCOMPtr dummy; rv = aDest->AppendChild(textNode, getter_AddRefs(dummy)); if (NS_FAILED(rv)) { return; } mTextNode = textNode; return; } txMozillaTextOutput::~txMozillaTextOutput() { } NS_IMPL_ISUPPORTS1(txMozillaTextOutput, txIOutputXMLEventHandler); void txMozillaTextOutput::attribute(const String& aName, const PRInt32 aNsID, const String& aValue) { } void txMozillaTextOutput::characters(const String& aData) { if (mTextNode) mTextNode->AppendData(aData); } void txMozillaTextOutput::comment(const String& aData) { } void txMozillaTextOutput::endDocument() { nsCOMPtr observer = do_QueryReferent(mObserver); if (observer) { observer->OnTransformDone(NS_OK, mDocument); } } void txMozillaTextOutput::endElement(const String& aName, const PRInt32 aNsID) { } void txMozillaTextOutput::processingInstruction(const String& aTarget, const String& aData) { } void txMozillaTextOutput::startDocument() { } void txMozillaTextOutput::createResultDocument(nsIDOMDocument* aSourceDocument, nsIDOMDocument* aResultDocument) { nsresult rv = NS_OK; /* * Create an XHTML document to hold the text. * * * * *
 * The text comes here * 
* * * * Except if we are transforming into a non-displayed document we create * the following DOM * * * The text comes here * */ nsCOMPtr doc; if (!aResultDocument) { // Create the document doc = do_CreateInstance(kXMLDocumentCID, &rv); NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't create document"); mDocument = do_QueryInterface(doc); } else { mDocument = aResultDocument; doc = do_QueryInterface(aResultDocument); NS_ASSERTION(doc, "Couldn't QI to nsIDocument"); } if (!doc) { return; } NS_ASSERTION(mDocument, "Need document"); nsCOMPtr nsDoc = do_QueryInterface(mDocument); if (nsDoc) { nsDoc->SetTitle(NS_LITERAL_STRING("")); } // Reset and set up document nsCOMPtr loadGroup; nsCOMPtr channel; nsCOMPtr sourceDoc = do_QueryInterface(aSourceDocument); sourceDoc->GetDocumentLoadGroup(getter_AddRefs(loadGroup)); nsCOMPtr serv = do_GetService(NS_IOSERVICE_CONTRACTID); if (serv) { // Create a temporary channel to get nsIDocument->Reset to // do the right thing. We want the output document to get // much of the input document's characteristics. nsCOMPtr docURL; sourceDoc->GetDocumentURL(getter_AddRefs(docURL)); serv->NewChannelFromURI(docURL, getter_AddRefs(channel)); } doc->Reset(channel, loadGroup); nsCOMPtr baseURL; sourceDoc->GetBaseURL(*getter_AddRefs(baseURL)); doc->SetBaseURL(baseURL); // XXX We might want to call SetDefaultStylesheets here // Notify the contentsink that the document is created nsCOMPtr observer = do_QueryReferent(mObserver); if (observer) { observer->OnDocumentCreated(mDocument); } // Create the content // When transforming into a non-displayed document (i.e. when there is no // observer) we only create a transformiix:result root element. // Don't do this when called through nsIXSLTProcessorObsolete (i.e. when // aResultDocument is set) for compability reasons nsCOMPtr textContainer; if (!aResultDocument && !observer) { nsCOMPtr docElement; mDocument->CreateElementNS(NS_LITERAL_STRING(kTXNameSpaceURI), NS_LITERAL_STRING(kTXWrapper), getter_AddRefs(docElement)); NS_ASSERTION(docElement, "Failed to create wrapper element"); if (!docElement) { return; } rv = mDocument->AppendChild(docElement, getter_AddRefs(textContainer)); NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the wrapper element"); if (NS_FAILED(rv)) { return; } } else { nsCOMPtr element, docElement; nsCOMPtr parent, pre; NS_NAMED_LITERAL_STRING(XHTML_NSURI, "http://www.w3.org/1999/xhtml"); mDocument->CreateElementNS(XHTML_NSURI, NS_LITERAL_STRING("html"), getter_AddRefs(docElement)); nsCOMPtr rootContent = do_QueryInterface(docElement); NS_ASSERTION(rootContent, "Need root element"); if (!rootContent) { return; } rv = rootContent->SetDocument(doc, PR_FALSE, PR_TRUE); NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to set the document"); if (NS_FAILED(rv)) { return; } rv = doc->SetRootContent(rootContent); NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to set the root content"); if (NS_FAILED(rv)) { return; } mDocument->CreateElementNS(XHTML_NSURI, NS_LITERAL_STRING("head"), getter_AddRefs(element)); NS_ASSERTION(element, "Failed to create head element"); if (!element) { return; } rv = docElement->AppendChild(element, getter_AddRefs(parent)); NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the head element"); if (NS_FAILED(rv)) { return; } mDocument->CreateElementNS(XHTML_NSURI, NS_LITERAL_STRING("body"), getter_AddRefs(element)); NS_ASSERTION(element, "Failed to create body element"); if (!element) { return; } rv = docElement->AppendChild(element, getter_AddRefs(parent)); NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the body element"); if (NS_FAILED(rv)) { return; } mDocument->CreateElementNS(XHTML_NSURI, NS_LITERAL_STRING("pre"), getter_AddRefs(element)); NS_ASSERTION(element, "Failed to create pre element"); if (!element) { return; } rv = parent->AppendChild(element, getter_AddRefs(pre)); NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the pre element"); if (NS_FAILED(rv)) { return; } nsCOMPtr htmlElement = do_QueryInterface(pre); htmlElement->SetId(NS_LITERAL_STRING("transformiixResult")); NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the id"); textContainer = pre; } nsCOMPtr textNode; mDocument->CreateTextNode(NS_LITERAL_STRING(""), getter_AddRefs(textNode)); NS_ASSERTION(textNode, "Failed to create the text node"); if (!textNode) { return; } nsCOMPtr dummy; rv = textContainer->AppendChild(textNode, getter_AddRefs(dummy)); NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the text node"); if (NS_FAILED(rv)) { return; } mTextNode = textNode; } void txMozillaTextOutput::startElement(const String& aName, const PRInt32 aNsID) { } void txMozillaTextOutput::getOutputDocument(nsIDOMDocument** aDocument) { *aDocument = mDocument; NS_IF_ADDREF(*aDocument); }