LCOV - code coverage report
Current view: top level - dom/xslt/xslt - txMozillaXMLOutput.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 498 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 39 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "txMozillaXMLOutput.h"
       7             : 
       8             : #include "nsIDocument.h"
       9             : #include "nsIDocShell.h"
      10             : #include "nsIDOMDocument.h"
      11             : #include "nsIDOMDocumentType.h"
      12             : #include "nsIScriptElement.h"
      13             : #include "nsCharsetSource.h"
      14             : #include "nsIRefreshURI.h"
      15             : #include "nsPIDOMWindow.h"
      16             : #include "nsIContent.h"
      17             : #include "nsContentCID.h"
      18             : #include "nsUnicharUtils.h"
      19             : #include "nsGkAtoms.h"
      20             : #include "txLog.h"
      21             : #include "nsIConsoleService.h"
      22             : #include "nsIDOMDocumentFragment.h"
      23             : #include "nsNameSpaceManager.h"
      24             : #include "txStringUtils.h"
      25             : #include "txURIUtils.h"
      26             : #include "nsIHTMLDocument.h"
      27             : #include "nsIStyleSheetLinkingElement.h"
      28             : #include "nsIDocumentTransformer.h"
      29             : #include "mozilla/StyleSheetInlines.h"
      30             : #include "mozilla/css/Loader.h"
      31             : #include "mozilla/dom/Element.h"
      32             : #include "mozilla/dom/ScriptLoader.h"
      33             : #include "mozilla/Encoding.h"
      34             : #include "nsContentUtils.h"
      35             : #include "txXMLUtils.h"
      36             : #include "nsContentSink.h"
      37             : #include "nsINode.h"
      38             : #include "nsContentCreatorFunctions.h"
      39             : #include "nsError.h"
      40             : #include "nsIFrame.h"
      41             : #include <algorithm>
      42             : #include "nsTextNode.h"
      43             : #include "mozilla/dom/Comment.h"
      44             : #include "mozilla/dom/ProcessingInstruction.h"
      45             : 
      46             : using namespace mozilla;
      47             : using namespace mozilla::dom;
      48             : 
      49             : #define TX_ENSURE_CURRENTNODE                           \
      50             :     NS_ASSERTION(mCurrentNode, "mCurrentNode is nullptr"); \
      51             :     if (!mCurrentNode)                                  \
      52             :         return NS_ERROR_UNEXPECTED
      53             : 
      54           0 : txMozillaXMLOutput::txMozillaXMLOutput(txOutputFormat* aFormat,
      55           0 :                                        nsITransformObserver* aObserver)
      56             :     : mTreeDepth(0),
      57             :       mBadChildLevel(0),
      58             :       mTableState(NORMAL),
      59             :       mCreatingNewDocument(true),
      60             :       mOpenedElementIsHTML(false),
      61             :       mRootContentCreated(false),
      62           0 :       mNoFixup(false)
      63             : {
      64           0 :     MOZ_COUNT_CTOR(txMozillaXMLOutput);
      65           0 :     if (aObserver) {
      66           0 :         mNotifier = new txTransformNotifier();
      67           0 :         if (mNotifier) {
      68           0 :             mNotifier->Init(aObserver);
      69             :         }
      70             :     }
      71             : 
      72           0 :     mOutputFormat.merge(*aFormat);
      73           0 :     mOutputFormat.setFromDefaults();
      74           0 : }
      75             : 
      76           0 : txMozillaXMLOutput::txMozillaXMLOutput(txOutputFormat* aFormat,
      77             :                                        nsIDOMDocumentFragment* aFragment,
      78           0 :                                        bool aNoFixup)
      79             :     : mTreeDepth(0),
      80             :       mBadChildLevel(0),
      81             :       mTableState(NORMAL),
      82             :       mCreatingNewDocument(false),
      83             :       mOpenedElementIsHTML(false),
      84             :       mRootContentCreated(false),
      85           0 :       mNoFixup(aNoFixup)
      86             : {
      87           0 :     MOZ_COUNT_CTOR(txMozillaXMLOutput);
      88           0 :     mOutputFormat.merge(*aFormat);
      89           0 :     mOutputFormat.setFromDefaults();
      90             : 
      91           0 :     mCurrentNode = do_QueryInterface(aFragment);
      92           0 :     mDocument = mCurrentNode->OwnerDoc();
      93           0 :     mNodeInfoManager = mDocument->NodeInfoManager();
      94           0 : }
      95             : 
      96           0 : txMozillaXMLOutput::~txMozillaXMLOutput()
      97             : {
      98           0 :     MOZ_COUNT_DTOR(txMozillaXMLOutput);
      99           0 : }
     100             : 
     101             : nsresult
     102           0 : txMozillaXMLOutput::attribute(nsIAtom* aPrefix,
     103             :                               nsIAtom* aLocalName,
     104             :                               nsIAtom* aLowercaseLocalName,
     105             :                               const int32_t aNsID,
     106             :                               const nsString& aValue)
     107             : {
     108           0 :     nsCOMPtr<nsIAtom> owner;
     109           0 :     if (mOpenedElementIsHTML && aNsID == kNameSpaceID_None) {
     110           0 :         if (aLowercaseLocalName) {
     111           0 :             aLocalName = aLowercaseLocalName;
     112             :         }
     113             :         else {
     114           0 :             owner = TX_ToLowerCaseAtom(aLocalName);
     115           0 :             NS_ENSURE_TRUE(owner, NS_ERROR_OUT_OF_MEMORY);
     116             : 
     117           0 :             aLocalName = owner;
     118             :         }
     119             :     }
     120             : 
     121           0 :     return attributeInternal(aPrefix, aLocalName, aNsID, aValue);
     122             : }
     123             : 
     124             : nsresult
     125           0 : txMozillaXMLOutput::attribute(nsIAtom* aPrefix,
     126             :                               const nsAString& aLocalName,
     127             :                               const int32_t aNsID,
     128             :                               const nsString& aValue)
     129             : {
     130           0 :     nsCOMPtr<nsIAtom> lname;
     131             : 
     132           0 :     if (mOpenedElementIsHTML && aNsID == kNameSpaceID_None) {
     133           0 :         nsAutoString lnameStr;
     134           0 :         nsContentUtils::ASCIIToLower(aLocalName, lnameStr);
     135           0 :         lname = NS_Atomize(lnameStr);
     136             :     }
     137             :     else {
     138           0 :         lname = NS_Atomize(aLocalName);
     139             :     }
     140             : 
     141           0 :     NS_ENSURE_TRUE(lname, NS_ERROR_OUT_OF_MEMORY);
     142             : 
     143             :     // Check that it's a valid name
     144           0 :     if (!nsContentUtils::IsValidNodeName(lname, aPrefix, aNsID)) {
     145             :         // Try without prefix
     146           0 :         aPrefix = nullptr;
     147           0 :         if (!nsContentUtils::IsValidNodeName(lname, aPrefix, aNsID)) {
     148             :             // Don't return error here since the callers don't deal
     149           0 :             return NS_OK;
     150             :         }
     151             :     }
     152             : 
     153           0 :     return attributeInternal(aPrefix, lname, aNsID, aValue);
     154             : }
     155             : 
     156             : nsresult
     157           0 : txMozillaXMLOutput::attributeInternal(nsIAtom* aPrefix,
     158             :                                       nsIAtom* aLocalName,
     159             :                                       int32_t aNsID,
     160             :                                       const nsString& aValue)
     161             : {
     162           0 :     if (!mOpenedElement) {
     163             :         // XXX Signal this? (can't add attributes after element closed)
     164           0 :         return NS_OK;
     165             :     }
     166             : 
     167           0 :     NS_ASSERTION(!mBadChildLevel, "mBadChildLevel set when element is opened");
     168             : 
     169           0 :     return mOpenedElement->SetAttr(aNsID, aLocalName, aPrefix, aValue,
     170           0 :                                    false);
     171             : }
     172             : 
     173             : nsresult
     174           0 : txMozillaXMLOutput::characters(const nsAString& aData, bool aDOE)
     175             : {
     176           0 :     nsresult rv = closePrevious(false);
     177           0 :     NS_ENSURE_SUCCESS(rv, rv);
     178             : 
     179           0 :     if (!mBadChildLevel) {
     180           0 :         mText.Append(aData);
     181             :     }
     182             : 
     183           0 :     return NS_OK;
     184             : }
     185             : 
     186             : nsresult
     187           0 : txMozillaXMLOutput::comment(const nsString& aData)
     188             : {
     189           0 :     nsresult rv = closePrevious(true);
     190           0 :     NS_ENSURE_SUCCESS(rv, rv);
     191             : 
     192           0 :     if (mBadChildLevel) {
     193           0 :         return NS_OK;
     194             :     }
     195             : 
     196           0 :     TX_ENSURE_CURRENTNODE;
     197             : 
     198           0 :     RefPtr<Comment> comment = new Comment(mNodeInfoManager);
     199             : 
     200           0 :     rv = comment->SetText(aData, false);
     201           0 :     NS_ENSURE_SUCCESS(rv, rv);
     202             : 
     203           0 :     return mCurrentNode->AppendChildTo(comment, true);
     204             : }
     205             : 
     206             : nsresult
     207           0 : txMozillaXMLOutput::endDocument(nsresult aResult)
     208             : {
     209           0 :     TX_ENSURE_CURRENTNODE;
     210             : 
     211           0 :     if (NS_FAILED(aResult)) {
     212           0 :         if (mNotifier) {
     213           0 :             mNotifier->OnTransformEnd(aResult);
     214             :         }
     215             : 
     216           0 :         return NS_OK;
     217             :     }
     218             : 
     219           0 :     nsresult rv = closePrevious(true);
     220           0 :     if (NS_FAILED(rv)) {
     221           0 :         if (mNotifier) {
     222           0 :             mNotifier->OnTransformEnd(rv);
     223             :         }
     224             : 
     225           0 :         return rv;
     226             :     }
     227             : 
     228           0 :     if (mCreatingNewDocument) {
     229             :         // This should really be handled by nsIDocument::EndLoad
     230           0 :         MOZ_ASSERT(mDocument->GetReadyStateEnum() ==
     231             :                    nsIDocument::READYSTATE_LOADING, "Bad readyState");
     232           0 :         mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE);
     233           0 :         ScriptLoader* loader = mDocument->ScriptLoader();
     234           0 :         if (loader) {
     235           0 :             loader->ParsingComplete(false);
     236             :         }
     237             :     }
     238             : 
     239           0 :     if (!mRefreshString.IsEmpty()) {
     240           0 :         nsPIDOMWindowOuter* win = mDocument->GetWindow();
     241           0 :         if (win) {
     242             :             nsCOMPtr<nsIRefreshURI> refURI =
     243           0 :                 do_QueryInterface(win->GetDocShell());
     244           0 :             if (refURI) {
     245           0 :                 refURI->SetupRefreshURIFromHeader(mDocument->GetDocBaseURI(),
     246           0 :                                                   mDocument->NodePrincipal(),
     247           0 :                                                   mRefreshString);
     248             :             }
     249             :         }
     250             :     }
     251             : 
     252           0 :     if (mNotifier) {
     253           0 :         mNotifier->OnTransformEnd();
     254             :     }
     255             : 
     256           0 :     return NS_OK;
     257             : }
     258             : 
     259             : nsresult
     260           0 : txMozillaXMLOutput::endElement()
     261             : {
     262           0 :     TX_ENSURE_CURRENTNODE;
     263             : 
     264           0 :     if (mBadChildLevel) {
     265           0 :         --mBadChildLevel;
     266           0 :         MOZ_LOG(txLog::xslt, LogLevel::Debug,
     267             :                ("endElement, mBadChildLevel = %d\n", mBadChildLevel));
     268           0 :         return NS_OK;
     269             :     }
     270             : 
     271           0 :     --mTreeDepth;
     272             : 
     273           0 :     nsresult rv = closePrevious(true);
     274           0 :     NS_ENSURE_SUCCESS(rv, rv);
     275             : 
     276           0 :     NS_ASSERTION(mCurrentNode->IsElement(), "borked mCurrentNode");
     277           0 :     NS_ENSURE_TRUE(mCurrentNode->IsElement(), NS_ERROR_UNEXPECTED);
     278             : 
     279           0 :     Element* element = mCurrentNode->AsElement();
     280             : 
     281             :     // Handle html-elements
     282           0 :     if (!mNoFixup) {
     283           0 :         if (element->IsHTMLElement()) {
     284           0 :             rv = endHTMLElement(element);
     285           0 :             NS_ENSURE_SUCCESS(rv, rv);
     286             :         }
     287             : 
     288             :         // Handle elements that are different when parser-created
     289           0 :         if (element->IsAnyOfHTMLElements(nsGkAtoms::title,
     290             :                                          nsGkAtoms::object,
     291             :                                          nsGkAtoms::applet,
     292             :                                          nsGkAtoms::select,
     293           0 :                                          nsGkAtoms::textarea) ||
     294           0 :             element->IsSVGElement(nsGkAtoms::title)) {
     295           0 :             element->DoneAddingChildren(true);
     296           0 :         } else if (element->IsSVGElement(nsGkAtoms::script) ||
     297           0 :                    element->IsHTMLElement(nsGkAtoms::script)) {
     298           0 :             nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(element);
     299           0 :             if (sele) {
     300           0 :               bool block = sele->AttemptToExecute();
     301             :               // If the act of insertion evaluated the script, we're fine.
     302             :               // Else, add this script element to the array of loading scripts.
     303           0 :               if (block) {
     304           0 :                   rv = mNotifier->AddScriptElement(sele);
     305           0 :                   NS_ENSURE_SUCCESS(rv, rv);
     306             :               }
     307             :             } else {
     308           0 :               MOZ_ASSERT(nsNameSpaceManager::GetInstance()->mSVGDisabled, "Script elements need to implement nsIScriptElement and SVG wasn't disabled.");
     309             :             }
     310           0 :         } else if (element->IsAnyOfHTMLElements(nsGkAtoms::input,
     311             :                                                 nsGkAtoms::button,
     312             :                                                 nsGkAtoms::menuitem,
     313             :                                                 nsGkAtoms::audio,
     314             :                                                 nsGkAtoms::video)) {
     315           0 :           element->DoneCreatingElement();
     316             :         }
     317             :     }
     318             : 
     319           0 :     if (mCreatingNewDocument) {
     320             :         // Handle all sorts of stylesheets
     321             :         nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
     322           0 :             do_QueryInterface(mCurrentNode);
     323           0 :         if (ssle) {
     324           0 :             ssle->SetEnableUpdates(true);
     325             :             bool willNotify;
     326             :             bool isAlternate;
     327           0 :             nsresult rv = ssle->UpdateStyleSheet(mNotifier, &willNotify,
     328           0 :                                                  &isAlternate);
     329           0 :             if (mNotifier && NS_SUCCEEDED(rv) && willNotify && !isAlternate) {
     330           0 :                 mNotifier->AddPendingStylesheet();
     331             :             }
     332             :         }
     333             :     }
     334             : 
     335             :     // Add the element to the tree if it wasn't added before and take one step
     336             :     // up the tree
     337           0 :     uint32_t last = mCurrentNodeStack.Count() - 1;
     338           0 :     NS_ASSERTION(last != (uint32_t)-1, "empty stack");
     339             : 
     340           0 :     nsCOMPtr<nsINode> parent = mCurrentNodeStack.SafeObjectAt(last);
     341           0 :     mCurrentNodeStack.RemoveObjectAt(last);
     342             : 
     343           0 :     if (mCurrentNode == mNonAddedNode) {
     344           0 :         if (parent == mDocument) {
     345           0 :             NS_ASSERTION(!mRootContentCreated,
     346             :                          "Parent to add to shouldn't be a document if we "
     347             :                          "have a root content");
     348           0 :             mRootContentCreated = true;
     349             :         }
     350             : 
     351             :         // Check to make sure that script hasn't inserted the node somewhere
     352             :         // else in the tree
     353           0 :         if (!mCurrentNode->GetParentNode()) {
     354           0 :             parent->AppendChildTo(mNonAddedNode, true);
     355             :         }
     356           0 :         mNonAddedNode = nullptr;
     357             :     }
     358             : 
     359           0 :     mCurrentNode = parent;
     360             : 
     361           0 :     mTableState =
     362           0 :         static_cast<TableState>(NS_PTR_TO_INT32(mTableStateStack.pop()));
     363             : 
     364           0 :     return NS_OK;
     365             : }
     366             : 
     367           0 : void txMozillaXMLOutput::getOutputDocument(nsIDOMDocument** aDocument)
     368             : {
     369           0 :     CallQueryInterface(mDocument, aDocument);
     370           0 : }
     371             : 
     372             : nsresult
     373           0 : txMozillaXMLOutput::processingInstruction(const nsString& aTarget, const nsString& aData)
     374             : {
     375           0 :     nsresult rv = closePrevious(true);
     376           0 :     NS_ENSURE_SUCCESS(rv, rv);
     377             : 
     378           0 :     if (mOutputFormat.mMethod == eHTMLOutput)
     379           0 :         return NS_OK;
     380             : 
     381           0 :     TX_ENSURE_CURRENTNODE;
     382             : 
     383           0 :     rv = nsContentUtils::CheckQName(aTarget, false);
     384           0 :     NS_ENSURE_SUCCESS(rv, rv);
     385             : 
     386             :     nsCOMPtr<nsIContent> pi =
     387           0 :       NS_NewXMLProcessingInstruction(mNodeInfoManager, aTarget, aData);
     388             : 
     389           0 :     nsCOMPtr<nsIStyleSheetLinkingElement> ssle;
     390           0 :     if (mCreatingNewDocument) {
     391           0 :         ssle = do_QueryInterface(pi);
     392           0 :         if (ssle) {
     393           0 :             ssle->InitStyleLinkElement(false);
     394           0 :             ssle->SetEnableUpdates(false);
     395             :         }
     396             :     }
     397             : 
     398           0 :     rv = mCurrentNode->AppendChildTo(pi, true);
     399           0 :     NS_ENSURE_SUCCESS(rv, rv);
     400             : 
     401           0 :     if (ssle) {
     402           0 :         ssle->SetEnableUpdates(true);
     403             :         bool willNotify;
     404             :         bool isAlternate;
     405           0 :         rv = ssle->UpdateStyleSheet(mNotifier, &willNotify, &isAlternate);
     406           0 :         if (mNotifier && NS_SUCCEEDED(rv) && willNotify && !isAlternate) {
     407           0 :             mNotifier->AddPendingStylesheet();
     408             :         }
     409             :     }
     410             : 
     411           0 :     return NS_OK;
     412             : }
     413             : 
     414             : nsresult
     415           0 : txMozillaXMLOutput::startDocument()
     416             : {
     417           0 :     if (mNotifier) {
     418           0 :         mNotifier->OnTransformStart();
     419             :     }
     420             : 
     421           0 :     if (mCreatingNewDocument) {
     422           0 :         ScriptLoader* loader = mDocument->ScriptLoader();
     423           0 :         if (loader) {
     424           0 :             loader->BeginDeferringScripts();
     425             :         }
     426             :     }
     427             : 
     428           0 :     return NS_OK;
     429             : }
     430             : 
     431             : nsresult
     432           0 : txMozillaXMLOutput::startElement(nsIAtom* aPrefix, nsIAtom* aLocalName,
     433             :                                  nsIAtom* aLowercaseLocalName,
     434             :                                  const int32_t aNsID)
     435             : {
     436           0 :     NS_PRECONDITION(aNsID != kNameSpaceID_None || !aPrefix,
     437             :                     "Can't have prefix without namespace");
     438             : 
     439           0 :     if (mOutputFormat.mMethod == eHTMLOutput && aNsID == kNameSpaceID_None) {
     440           0 :         nsCOMPtr<nsIAtom> owner;
     441           0 :         if (!aLowercaseLocalName) {
     442           0 :             owner = TX_ToLowerCaseAtom(aLocalName);
     443           0 :             NS_ENSURE_TRUE(owner, NS_ERROR_OUT_OF_MEMORY);
     444             : 
     445           0 :             aLowercaseLocalName = owner;
     446             :         }
     447             :         return startElementInternal(nullptr,
     448             :                                     aLowercaseLocalName,
     449           0 :                                     kNameSpaceID_XHTML);
     450             :     }
     451             : 
     452           0 :     return startElementInternal(aPrefix, aLocalName, aNsID);
     453             : }
     454             : 
     455             : nsresult
     456           0 : txMozillaXMLOutput::startElement(nsIAtom* aPrefix,
     457             :                                  const nsAString& aLocalName,
     458             :                                  const int32_t aNsID)
     459             : {
     460           0 :     int32_t nsId = aNsID;
     461           0 :     nsCOMPtr<nsIAtom> lname;
     462             : 
     463           0 :     if (mOutputFormat.mMethod == eHTMLOutput && aNsID == kNameSpaceID_None) {
     464           0 :         nsId = kNameSpaceID_XHTML;
     465             : 
     466           0 :         nsAutoString lnameStr;
     467           0 :         nsContentUtils::ASCIIToLower(aLocalName, lnameStr);
     468           0 :         lname = NS_Atomize(lnameStr);
     469             :     }
     470             :     else {
     471           0 :         lname = NS_Atomize(aLocalName);
     472             :     }
     473             : 
     474             :     // No biggie if we lose the prefix due to OOM
     475           0 :     NS_ENSURE_TRUE(lname, NS_ERROR_OUT_OF_MEMORY);
     476             : 
     477             :     // Check that it's a valid name
     478           0 :     if (!nsContentUtils::IsValidNodeName(lname, aPrefix, nsId)) {
     479             :         // Try without prefix
     480           0 :         aPrefix = nullptr;
     481           0 :         if (!nsContentUtils::IsValidNodeName(lname, aPrefix, nsId)) {
     482           0 :             return NS_ERROR_XSLT_BAD_NODE_NAME;
     483             :         }
     484             :     }
     485             : 
     486           0 :     return startElementInternal(aPrefix, lname, nsId);
     487             : }
     488             : 
     489             : nsresult
     490           0 : txMozillaXMLOutput::startElementInternal(nsIAtom* aPrefix,
     491             :                                          nsIAtom* aLocalName,
     492             :                                          int32_t aNsID)
     493             : {
     494           0 :     TX_ENSURE_CURRENTNODE;
     495             : 
     496           0 :     if (mBadChildLevel) {
     497           0 :         ++mBadChildLevel;
     498           0 :         MOZ_LOG(txLog::xslt, LogLevel::Debug,
     499             :                ("startElement, mBadChildLevel = %d\n", mBadChildLevel));
     500           0 :         return NS_OK;
     501             :     }
     502             : 
     503           0 :     nsresult rv = closePrevious(true);
     504           0 :     NS_ENSURE_SUCCESS(rv, rv);
     505             : 
     506             :     // Push and init state
     507           0 :     if (mTreeDepth == MAX_REFLOW_DEPTH) {
     508             :         // eCloseElement couldn't add the parent so we fail as well or we've
     509             :         // reached the limit of the depth of the tree that we allow.
     510           0 :         ++mBadChildLevel;
     511           0 :         MOZ_LOG(txLog::xslt, LogLevel::Debug,
     512             :                ("startElement, mBadChildLevel = %d\n", mBadChildLevel));
     513           0 :         return NS_OK;
     514             :     }
     515             : 
     516           0 :     ++mTreeDepth;
     517             : 
     518           0 :     rv = mTableStateStack.push(NS_INT32_TO_PTR(mTableState));
     519           0 :     NS_ENSURE_SUCCESS(rv, rv);
     520             : 
     521           0 :     if (!mCurrentNodeStack.AppendObject(mCurrentNode)) {
     522           0 :         return NS_ERROR_OUT_OF_MEMORY;
     523             :     }
     524             : 
     525           0 :     mTableState = NORMAL;
     526           0 :     mOpenedElementIsHTML = false;
     527             : 
     528             :     // Create the element
     529             :     RefPtr<NodeInfo> ni =
     530           0 :         mNodeInfoManager->GetNodeInfo(aLocalName, aPrefix, aNsID,
     531           0 :                                       nsIDOMNode::ELEMENT_NODE);
     532             : 
     533           0 :     NS_NewElement(getter_AddRefs(mOpenedElement), ni.forget(),
     534           0 :                   mCreatingNewDocument ?
     535           0 :                   FROM_PARSER_XSLT : FROM_PARSER_FRAGMENT);
     536             : 
     537             :     // Set up the element and adjust state
     538           0 :     if (!mNoFixup) {
     539           0 :         if (aNsID == kNameSpaceID_XHTML) {
     540           0 :             mOpenedElementIsHTML = (mOutputFormat.mMethod == eHTMLOutput);
     541           0 :             rv = startHTMLElement(mOpenedElement, mOpenedElementIsHTML);
     542           0 :             NS_ENSURE_SUCCESS(rv, rv);
     543             : 
     544             :         }
     545             :     }
     546             : 
     547           0 :     if (mCreatingNewDocument) {
     548             :         // Handle all sorts of stylesheets
     549             :         nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
     550           0 :             do_QueryInterface(mOpenedElement);
     551           0 :         if (ssle) {
     552           0 :             ssle->InitStyleLinkElement(false);
     553           0 :             ssle->SetEnableUpdates(false);
     554             :         }
     555             :     }
     556             : 
     557           0 :     return NS_OK;
     558             : }
     559             : 
     560             : nsresult
     561           0 : txMozillaXMLOutput::closePrevious(bool aFlushText)
     562             : {
     563           0 :     TX_ENSURE_CURRENTNODE;
     564             : 
     565             :     nsresult rv;
     566           0 :     if (mOpenedElement) {
     567           0 :         bool currentIsDoc = mCurrentNode == mDocument;
     568           0 :         if (currentIsDoc && mRootContentCreated) {
     569             :             // We already have a document element, but the XSLT spec allows this.
     570             :             // As a workaround, create a wrapper object and use that as the
     571             :             // document element.
     572             : 
     573           0 :             rv = createTxWrapper();
     574           0 :             NS_ENSURE_SUCCESS(rv, rv);
     575             :         }
     576             : 
     577           0 :         rv = mCurrentNode->AppendChildTo(mOpenedElement, true);
     578           0 :         NS_ENSURE_SUCCESS(rv, rv);
     579             : 
     580           0 :         if (currentIsDoc) {
     581           0 :             mRootContentCreated = true;
     582           0 :             nsContentSink::NotifyDocElementCreated(mDocument);
     583             :         }
     584             : 
     585           0 :         mCurrentNode = mOpenedElement;
     586           0 :         mOpenedElement = nullptr;
     587             :     }
     588           0 :     else if (aFlushText && !mText.IsEmpty()) {
     589             :         // Text can't appear in the root of a document
     590           0 :         if (mDocument == mCurrentNode) {
     591           0 :             if (XMLUtils::isWhitespace(mText)) {
     592           0 :                 mText.Truncate();
     593             : 
     594           0 :                 return NS_OK;
     595             :             }
     596             : 
     597           0 :             rv = createTxWrapper();
     598           0 :             NS_ENSURE_SUCCESS(rv, rv);
     599             :         }
     600           0 :         RefPtr<nsTextNode> text = new nsTextNode(mNodeInfoManager);
     601             : 
     602           0 :         rv = text->SetText(mText, false);
     603           0 :         NS_ENSURE_SUCCESS(rv, rv);
     604             : 
     605           0 :         rv = mCurrentNode->AppendChildTo(text, true);
     606           0 :         NS_ENSURE_SUCCESS(rv, rv);
     607             : 
     608           0 :         mText.Truncate();
     609             :     }
     610             : 
     611           0 :     return NS_OK;
     612             : }
     613             : 
     614             : nsresult
     615           0 : txMozillaXMLOutput::createTxWrapper()
     616             : {
     617           0 :     NS_ASSERTION(mDocument == mCurrentNode,
     618             :                  "creating wrapper when document isn't parent");
     619             : 
     620             :     int32_t namespaceID;
     621             :     nsresult rv = nsContentUtils::NameSpaceManager()->
     622           0 :         RegisterNameSpace(NS_LITERAL_STRING(kTXNameSpaceURI), namespaceID);
     623           0 :     NS_ENSURE_SUCCESS(rv, rv);
     624             : 
     625             :     nsCOMPtr<Element> wrapper =
     626           0 :       mDocument->CreateElem(nsDependentAtomString(nsGkAtoms::result),
     627           0 :                             nsGkAtoms::transformiix, namespaceID);
     628             : 
     629           0 :     uint32_t i, j, childCount = mDocument->GetChildCount();
     630             : #ifdef DEBUG
     631             :     // Keep track of the location of the current documentElement, if there is
     632             :     // one, so we can verify later
     633           0 :     uint32_t rootLocation = 0;
     634             : #endif
     635           0 :     for (i = 0, j = 0; i < childCount; ++i) {
     636           0 :         nsCOMPtr<nsIContent> childContent = mDocument->GetChildAt(j);
     637             : 
     638             : #ifdef DEBUG
     639           0 :         if (childContent->IsElement()) {
     640           0 :             rootLocation = j;
     641             :         }
     642             : #endif
     643             : 
     644           0 :         if (childContent->NodeInfo()->NameAtom() == nsGkAtoms::documentTypeNodeName) {
     645             : #ifdef DEBUG
     646             :             // The new documentElement should go after the document type.
     647             :             // This is needed for cases when there is no existing
     648             :             // documentElement in the document.
     649           0 :             rootLocation = std::max(rootLocation, j + 1);
     650             : #endif
     651           0 :             ++j;
     652             :         }
     653             :         else {
     654           0 :             mDocument->RemoveChildAt(j, true);
     655             : 
     656           0 :             rv = wrapper->AppendChildTo(childContent, true);
     657           0 :             NS_ENSURE_SUCCESS(rv, rv);
     658           0 :             break;
     659             :         }
     660             :     }
     661             : 
     662           0 :     if (!mCurrentNodeStack.AppendObject(wrapper)) {
     663           0 :         return NS_ERROR_OUT_OF_MEMORY;
     664             :     }
     665           0 :     mCurrentNode = wrapper;
     666           0 :     mRootContentCreated = true;
     667           0 :     NS_ASSERTION(rootLocation == mDocument->GetChildCount(),
     668             :                  "Incorrect root location");
     669           0 :     return mDocument->AppendChildTo(wrapper, true);
     670             : }
     671             : 
     672             : nsresult
     673           0 : txMozillaXMLOutput::startHTMLElement(nsIContent* aElement, bool aIsHTML)
     674             : {
     675           0 :     nsresult rv = NS_OK;
     676             : 
     677           0 :     if ((!aElement->IsHTMLElement(nsGkAtoms::tr) || !aIsHTML) &&
     678           0 :         NS_PTR_TO_INT32(mTableStateStack.peek()) == ADDED_TBODY) {
     679           0 :         uint32_t last = mCurrentNodeStack.Count() - 1;
     680           0 :         NS_ASSERTION(last != (uint32_t)-1, "empty stack");
     681             : 
     682           0 :         mCurrentNode = mCurrentNodeStack.SafeObjectAt(last);
     683           0 :         mCurrentNodeStack.RemoveObjectAt(last);
     684           0 :         mTableStateStack.pop();
     685             :     }
     686             : 
     687           0 :     if (aElement->IsHTMLElement(nsGkAtoms::table) && aIsHTML) {
     688           0 :         mTableState = TABLE;
     689             :     }
     690           0 :     else if (aElement->IsHTMLElement(nsGkAtoms::tr) && aIsHTML &&
     691           0 :              NS_PTR_TO_INT32(mTableStateStack.peek()) == TABLE) {
     692           0 :         nsCOMPtr<nsIContent> tbody;
     693           0 :         rv = createHTMLElement(nsGkAtoms::tbody, getter_AddRefs(tbody));
     694           0 :         NS_ENSURE_SUCCESS(rv, rv);
     695             : 
     696           0 :         rv = mCurrentNode->AppendChildTo(tbody, true);
     697           0 :         NS_ENSURE_SUCCESS(rv, rv);
     698             : 
     699           0 :         rv = mTableStateStack.push(NS_INT32_TO_PTR(ADDED_TBODY));
     700           0 :         NS_ENSURE_SUCCESS(rv, rv);
     701             : 
     702           0 :         if (!mCurrentNodeStack.AppendObject(tbody)) {
     703           0 :             return NS_ERROR_OUT_OF_MEMORY;
     704             :         }
     705             : 
     706           0 :         mCurrentNode = tbody;
     707             :     }
     708           0 :     else if (aElement->IsHTMLElement(nsGkAtoms::head) &&
     709           0 :              mOutputFormat.mMethod == eHTMLOutput) {
     710             :         // Insert META tag, according to spec, 16.2, like
     711             :         // <META http-equiv="Content-Type" content="text/html; charset=EUC-JP">
     712           0 :         nsCOMPtr<nsIContent> meta;
     713           0 :         rv = createHTMLElement(nsGkAtoms::meta, getter_AddRefs(meta));
     714           0 :         NS_ENSURE_SUCCESS(rv, rv);
     715             : 
     716           0 :         rv = meta->SetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv,
     717           0 :                            NS_LITERAL_STRING("Content-Type"), false);
     718           0 :         NS_ENSURE_SUCCESS(rv, rv);
     719             : 
     720           0 :         nsAutoString metacontent;
     721           0 :         metacontent.Append(mOutputFormat.mMediaType);
     722           0 :         metacontent.AppendLiteral("; charset=");
     723           0 :         metacontent.Append(mOutputFormat.mEncoding);
     724           0 :         rv = meta->SetAttr(kNameSpaceID_None, nsGkAtoms::content,
     725           0 :                            metacontent, false);
     726           0 :         NS_ENSURE_SUCCESS(rv, rv);
     727             : 
     728             :         // No need to notify since aElement hasn't been inserted yet
     729           0 :         NS_ASSERTION(!aElement->IsInUncomposedDoc(), "should not be in doc");
     730           0 :         rv = aElement->AppendChildTo(meta, false);
     731           0 :         NS_ENSURE_SUCCESS(rv, rv);
     732             :     }
     733             : 
     734           0 :     return NS_OK;
     735             : }
     736             : 
     737             : nsresult
     738           0 : txMozillaXMLOutput::endHTMLElement(nsIContent* aElement)
     739             : {
     740           0 :     if (mTableState == ADDED_TBODY) {
     741           0 :         NS_ASSERTION(aElement->IsHTMLElement(nsGkAtoms::tbody),
     742             :                      "Element flagged as added tbody isn't a tbody");
     743           0 :         uint32_t last = mCurrentNodeStack.Count() - 1;
     744           0 :         NS_ASSERTION(last != (uint32_t)-1, "empty stack");
     745             : 
     746           0 :         mCurrentNode = mCurrentNodeStack.SafeObjectAt(last);
     747           0 :         mCurrentNodeStack.RemoveObjectAt(last);
     748           0 :         mTableState = static_cast<TableState>
     749           0 :                                  (NS_PTR_TO_INT32(mTableStateStack.pop()));
     750             : 
     751           0 :         return NS_OK;
     752             :     }
     753           0 :     else if (mCreatingNewDocument && aElement->IsHTMLElement(nsGkAtoms::meta)) {
     754             :         // handle HTTP-EQUIV data
     755           0 :         nsAutoString httpEquiv;
     756           0 :         aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, httpEquiv);
     757           0 :         if (!httpEquiv.IsEmpty()) {
     758           0 :             nsAutoString value;
     759           0 :             aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::content, value);
     760           0 :             if (!value.IsEmpty()) {
     761           0 :                 nsContentUtils::ASCIIToLower(httpEquiv);
     762           0 :                 nsCOMPtr<nsIAtom> header = NS_Atomize(httpEquiv);
     763           0 :                 processHTTPEquiv(header, value);
     764             :             }
     765             :         }
     766             :     }
     767             : 
     768           0 :     return NS_OK;
     769             : }
     770             : 
     771           0 : void txMozillaXMLOutput::processHTTPEquiv(nsIAtom* aHeader, const nsString& aValue)
     772             : {
     773             :     // For now we only handle "refresh". There's a longer list in
     774             :     // HTMLContentSink::ProcessHeaderData
     775           0 :     if (aHeader == nsGkAtoms::refresh)
     776           0 :         LossyCopyUTF16toASCII(aValue, mRefreshString);
     777           0 : }
     778             : 
     779             : nsresult
     780           0 : txMozillaXMLOutput::createResultDocument(const nsAString& aName, int32_t aNsID,
     781             :                                          nsIDOMDocument* aSourceDocument,
     782             :                                          bool aLoadedAsData)
     783             : {
     784             :     nsresult rv;
     785             : 
     786             :     // Create the document
     787           0 :     if (mOutputFormat.mMethod == eHTMLOutput) {
     788           0 :         rv = NS_NewHTMLDocument(getter_AddRefs(mDocument),
     789           0 :                                 aLoadedAsData);
     790           0 :         NS_ENSURE_SUCCESS(rv, rv);
     791             :     }
     792             :     else {
     793             :         // We should check the root name/namespace here and create the
     794             :         // appropriate document
     795           0 :         rv = NS_NewXMLDocument(getter_AddRefs(mDocument),
     796           0 :                                aLoadedAsData);
     797           0 :         NS_ENSURE_SUCCESS(rv, rv);
     798             :     }
     799             :     // This should really be handled by nsIDocument::BeginLoad
     800           0 :     MOZ_ASSERT(mDocument->GetReadyStateEnum() ==
     801             :                nsIDocument::READYSTATE_UNINITIALIZED, "Bad readyState");
     802           0 :     mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_LOADING);
     803           0 :     mDocument->SetMayStartLayout(false);
     804           0 :     nsCOMPtr<nsIDocument> source = do_QueryInterface(aSourceDocument);
     805           0 :     NS_ENSURE_STATE(source);
     806           0 :     bool hasHadScriptObject = false;
     807             :     nsIScriptGlobalObject* sgo =
     808           0 :       source->GetScriptHandlingObject(hasHadScriptObject);
     809           0 :     NS_ENSURE_STATE(sgo || !hasHadScriptObject);
     810             : 
     811           0 :     mCurrentNode = mDocument;
     812           0 :     mNodeInfoManager = mDocument->NodeInfoManager();
     813             : 
     814             :     // Reset and set up the document
     815           0 :     URIUtils::ResetWithSource(mDocument, aSourceDocument);
     816             : 
     817             :     // Make sure we set the script handling object after resetting with the
     818             :     // source, so that we have the right principal.
     819           0 :     mDocument->SetScriptHandlingObject(sgo);
     820             : 
     821             :     // Set the charset
     822           0 :     if (!mOutputFormat.mEncoding.IsEmpty()) {
     823           0 :         const Encoding* encoding = Encoding::ForLabel(mOutputFormat.mEncoding);
     824           0 :         if (encoding) {
     825           0 :             mDocument->SetDocumentCharacterSetSource(kCharsetFromOtherComponent);
     826           0 :             mDocument->SetDocumentCharacterSet(WrapNotNull(encoding));
     827             :         }
     828             :     }
     829             : 
     830             :     // Set the mime-type
     831           0 :     if (!mOutputFormat.mMediaType.IsEmpty()) {
     832           0 :         mDocument->SetContentType(mOutputFormat.mMediaType);
     833             :     }
     834           0 :     else if (mOutputFormat.mMethod == eHTMLOutput) {
     835           0 :         mDocument->SetContentType(NS_LITERAL_STRING("text/html"));
     836             :     }
     837             :     else {
     838           0 :         mDocument->SetContentType(NS_LITERAL_STRING("application/xml"));
     839             :     }
     840             : 
     841           0 :     if (mOutputFormat.mMethod == eXMLOutput &&
     842           0 :         mOutputFormat.mOmitXMLDeclaration != eTrue) {
     843             :         int32_t standalone;
     844           0 :         if (mOutputFormat.mStandalone == eNotSet) {
     845           0 :           standalone = -1;
     846             :         }
     847           0 :         else if (mOutputFormat.mStandalone == eFalse) {
     848           0 :           standalone = 0;
     849             :         }
     850             :         else {
     851           0 :           standalone = 1;
     852             :         }
     853             : 
     854             :         // Could use mOutputFormat.mVersion.get() when we support
     855             :         // versions > 1.0.
     856             :         static const char16_t kOneDotZero[] = { '1', '.', '0', '\0' };
     857           0 :         mDocument->SetXMLDeclaration(kOneDotZero, mOutputFormat.mEncoding.get(),
     858           0 :                                      standalone);
     859             :     }
     860             : 
     861             :     // Set up script loader of the result document.
     862           0 :     ScriptLoader *loader = mDocument->ScriptLoader();
     863           0 :     if (mNotifier) {
     864           0 :         loader->AddObserver(mNotifier);
     865             :     }
     866             :     else {
     867             :         // Don't load scripts, we can't notify the caller when they're loaded.
     868           0 :         loader->SetEnabled(false);
     869             :     }
     870             : 
     871           0 :     if (mNotifier) {
     872           0 :         rv = mNotifier->SetOutputDocument(mDocument);
     873           0 :         NS_ENSURE_SUCCESS(rv, rv);
     874             :     }
     875             : 
     876             :     // Do this after calling OnDocumentCreated to ensure that the
     877             :     // PresShell/PresContext has been hooked up and get notified.
     878           0 :     nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
     879           0 :     if (htmlDoc) {
     880           0 :         htmlDoc->SetCompatibilityMode(eCompatibility_FullStandards);
     881             :     }
     882             : 
     883             :     // Add a doc-type if requested
     884           0 :     if (!mOutputFormat.mSystemId.IsEmpty()) {
     885           0 :         nsAutoString qName;
     886           0 :         if (mOutputFormat.mMethod == eHTMLOutput) {
     887           0 :             qName.AssignLiteral("html");
     888             :         }
     889             :         else {
     890           0 :             qName.Assign(aName);
     891             :         }
     892             : 
     893           0 :         nsCOMPtr<nsIDOMDocumentType> documentType;
     894             : 
     895           0 :         nsresult rv = nsContentUtils::CheckQName(qName);
     896           0 :         if (NS_SUCCEEDED(rv)) {
     897           0 :             nsCOMPtr<nsIAtom> doctypeName = NS_Atomize(qName);
     898           0 :             if (!doctypeName) {
     899           0 :                 return NS_ERROR_OUT_OF_MEMORY;
     900             :             }
     901             : 
     902             :             // Indicate that there is no internal subset (not just an empty one)
     903           0 :             rv = NS_NewDOMDocumentType(getter_AddRefs(documentType),
     904             :                                        mNodeInfoManager,
     905             :                                        doctypeName,
     906             :                                        mOutputFormat.mPublicId,
     907             :                                        mOutputFormat.mSystemId,
     908           0 :                                        NullString());
     909           0 :             NS_ENSURE_SUCCESS(rv, rv);
     910             : 
     911           0 :             nsCOMPtr<nsIContent> docType = do_QueryInterface(documentType);
     912           0 :             rv = mDocument->AppendChildTo(docType, true);
     913           0 :             NS_ENSURE_SUCCESS(rv, rv);
     914             :         }
     915             :     }
     916             : 
     917           0 :     return NS_OK;
     918             : }
     919             : 
     920             : nsresult
     921           0 : txMozillaXMLOutput::createHTMLElement(nsIAtom* aName,
     922             :                                       nsIContent** aResult)
     923             : {
     924           0 :     NS_ASSERTION(mOutputFormat.mMethod == eHTMLOutput,
     925             :                  "need to adjust createHTMLElement");
     926             : 
     927           0 :     *aResult = nullptr;
     928             : 
     929           0 :     RefPtr<NodeInfo> ni;
     930           0 :     ni = mNodeInfoManager->GetNodeInfo(aName, nullptr,
     931             :                                        kNameSpaceID_XHTML,
     932           0 :                                        nsIDOMNode::ELEMENT_NODE);
     933             : 
     934           0 :     nsCOMPtr<Element> el;
     935             :     nsresult rv =
     936           0 :         NS_NewHTMLElement(getter_AddRefs(el), ni.forget(),
     937           0 :                           mCreatingNewDocument ?
     938           0 :                             FROM_PARSER_XSLT : FROM_PARSER_FRAGMENT);
     939           0 :     el.forget(aResult);
     940           0 :     return rv;
     941             : }
     942             : 
     943           0 : txTransformNotifier::txTransformNotifier()
     944             :     : mPendingStylesheetCount(0),
     945           0 :       mInTransform(false)
     946             : {
     947           0 : }
     948             : 
     949           0 : txTransformNotifier::~txTransformNotifier()
     950             : {
     951           0 : }
     952             : 
     953           0 : NS_IMPL_ISUPPORTS(txTransformNotifier,
     954             :                   nsIScriptLoaderObserver,
     955             :                   nsICSSLoaderObserver)
     956             : 
     957             : NS_IMETHODIMP
     958           0 : txTransformNotifier::ScriptAvailable(nsresult aResult,
     959             :                                      nsIScriptElement *aElement,
     960             :                                      bool aIsInline,
     961             :                                      nsIURI *aURI,
     962             :                                      int32_t aLineNo)
     963             : {
     964           0 :     if (NS_FAILED(aResult) &&
     965           0 :         mScriptElements.RemoveObject(aElement)) {
     966           0 :         SignalTransformEnd();
     967             :     }
     968             : 
     969           0 :     return NS_OK;
     970             : }
     971             : 
     972             : NS_IMETHODIMP
     973           0 : txTransformNotifier::ScriptEvaluated(nsresult aResult,
     974             :                                      nsIScriptElement *aElement,
     975             :                                      bool aIsInline)
     976             : {
     977           0 :     if (mScriptElements.RemoveObject(aElement)) {
     978           0 :         SignalTransformEnd();
     979             :     }
     980             : 
     981           0 :     return NS_OK;
     982             : }
     983             : 
     984             : NS_IMETHODIMP
     985           0 : txTransformNotifier::StyleSheetLoaded(StyleSheet* aSheet,
     986             :                                       bool aWasAlternate,
     987             :                                       nsresult aStatus)
     988             : {
     989           0 :     if (mPendingStylesheetCount == 0) {
     990             :         // We weren't waiting on this stylesheet anyway.  This can happen if
     991             :         // SignalTransformEnd got called with an error aResult.  See
     992             :         // http://bugzilla.mozilla.org/show_bug.cgi?id=215465.
     993           0 :         return NS_OK;
     994             :     }
     995             : 
     996             :     // We're never waiting for alternate stylesheets
     997           0 :     if (!aWasAlternate) {
     998           0 :         --mPendingStylesheetCount;
     999           0 :         SignalTransformEnd();
    1000             :     }
    1001             : 
    1002           0 :     return NS_OK;
    1003             : }
    1004             : 
    1005             : void
    1006           0 : txTransformNotifier::Init(nsITransformObserver* aObserver)
    1007             : {
    1008           0 :     mObserver = aObserver;
    1009           0 : }
    1010             : 
    1011             : nsresult
    1012           0 : txTransformNotifier::AddScriptElement(nsIScriptElement* aElement)
    1013             : {
    1014           0 :     return mScriptElements.AppendObject(aElement) ? NS_OK :
    1015           0 :                                                     NS_ERROR_OUT_OF_MEMORY;
    1016             : }
    1017             : 
    1018             : void
    1019           0 : txTransformNotifier::AddPendingStylesheet()
    1020             : {
    1021           0 :     ++mPendingStylesheetCount;
    1022           0 : }
    1023             : 
    1024             : void
    1025           0 : txTransformNotifier::OnTransformEnd(nsresult aResult)
    1026             : {
    1027           0 :     mInTransform = false;
    1028           0 :     SignalTransformEnd(aResult);
    1029           0 : }
    1030             : 
    1031             : void
    1032           0 : txTransformNotifier::OnTransformStart()
    1033             : {
    1034           0 :     mInTransform = true;
    1035           0 : }
    1036             : 
    1037             : nsresult
    1038           0 : txTransformNotifier::SetOutputDocument(nsIDocument* aDocument)
    1039             : {
    1040           0 :     mDocument = aDocument;
    1041             : 
    1042             :     // Notify the contentsink that the document is created
    1043           0 :     return mObserver->OnDocumentCreated(mDocument);
    1044             : }
    1045             : 
    1046             : void
    1047           0 : txTransformNotifier::SignalTransformEnd(nsresult aResult)
    1048             : {
    1049           0 :     if (mInTransform ||
    1050           0 :         (NS_SUCCEEDED(aResult) &&
    1051           0 :          (mScriptElements.Count() > 0 || mPendingStylesheetCount > 0))) {
    1052           0 :         return;
    1053             :     }
    1054             : 
    1055             :     // mPendingStylesheetCount is nonzero at this point only if aResult is an
    1056             :     // error.  Set it to 0 so we won't reenter this code when we stop the
    1057             :     // CSSLoader.
    1058           0 :     mPendingStylesheetCount = 0;
    1059           0 :     mScriptElements.Clear();
    1060             : 
    1061             :     // Make sure that we don't get deleted while this function is executed and
    1062             :     // we remove ourselfs from the scriptloader
    1063           0 :     nsCOMPtr<nsIScriptLoaderObserver> kungFuDeathGrip(this);
    1064             : 
    1065           0 :     if (mDocument) {
    1066           0 :         mDocument->ScriptLoader()->RemoveObserver(this);
    1067             :         // XXX Maybe we want to cancel script loads if NS_FAILED(rv)?
    1068             : 
    1069           0 :         if (NS_FAILED(aResult)) {
    1070           0 :             mDocument->CSSLoader()->Stop();
    1071             :         }
    1072             :     }
    1073             : 
    1074           0 :     if (NS_SUCCEEDED(aResult)) {
    1075           0 :         mObserver->OnTransformDone(aResult, mDocument);
    1076             :     }
    1077             : }

Generated by: LCOV version 1.13