LCOV - code coverage report
Current view: top level - dom/xml - nsXMLContentSink.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 361 719 50.2 %
Date: 2017-07-14 16:53:18 Functions: 41 59 69.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "nsCOMPtr.h"
       8             : #include "nsXMLContentSink.h"
       9             : #include "nsIParser.h"
      10             : #include "nsIDocument.h"
      11             : #include "nsIDOMDocument.h"
      12             : #include "nsIDOMDocumentType.h"
      13             : #include "nsIContent.h"
      14             : #include "nsIURI.h"
      15             : #include "nsNetUtil.h"
      16             : #include "nsIDocShell.h"
      17             : #include "nsIStyleSheetLinkingElement.h"
      18             : #include "nsIDOMComment.h"
      19             : #include "nsIDOMCDATASection.h"
      20             : #include "DocumentType.h"
      21             : #include "nsHTMLParts.h"
      22             : #include "nsCRT.h"
      23             : #include "mozilla/StyleSheetInlines.h"
      24             : #include "mozilla/css/Loader.h"
      25             : #include "nsGkAtoms.h"
      26             : #include "nsContentUtils.h"
      27             : #include "nsIScriptContext.h"
      28             : #include "nsNameSpaceManager.h"
      29             : #include "nsIServiceManager.h"
      30             : #include "nsIScriptSecurityManager.h"
      31             : #include "nsIContentViewer.h"
      32             : #include "prtime.h"
      33             : #include "mozilla/Logging.h"
      34             : #include "nsRect.h"
      35             : #include "nsIWebNavigation.h"
      36             : #include "nsIScriptElement.h"
      37             : #include "nsStyleLinkElement.h"
      38             : #include "nsReadableUtils.h"
      39             : #include "nsUnicharUtils.h"
      40             : #include "nsICookieService.h"
      41             : #include "nsIPrompt.h"
      42             : #include "nsIChannel.h"
      43             : #include "nsIPrincipal.h"
      44             : #include "nsXMLPrettyPrinter.h"
      45             : #include "nsNodeInfoManager.h"
      46             : #include "nsContentCreatorFunctions.h"
      47             : #include "nsIContentPolicy.h"
      48             : #include "nsContentPolicyUtils.h"
      49             : #include "nsError.h"
      50             : #include "nsIDOMProcessingInstruction.h"
      51             : #include "nsNodeUtils.h"
      52             : #include "nsIScriptGlobalObject.h"
      53             : #include "nsIHTMLDocument.h"
      54             : #include "mozAutoDocUpdate.h"
      55             : #include "nsMimeTypes.h"
      56             : #include "nsHtml5SVGLoadDispatcher.h"
      57             : #include "nsTextNode.h"
      58             : #include "mozilla/dom/CDATASection.h"
      59             : #include "mozilla/dom/Comment.h"
      60             : #include "mozilla/dom/Element.h"
      61             : #include "mozilla/dom/HTMLTemplateElement.h"
      62             : #include "mozilla/dom/ProcessingInstruction.h"
      63             : #include "mozilla/dom/ScriptLoader.h"
      64             : 
      65             : using namespace mozilla;
      66             : using namespace mozilla::dom;
      67             : 
      68             : // XXX Open Issues:
      69             : // 1) what's not allowed - We need to figure out which HTML tags
      70             : //    (prefixed with a HTML namespace qualifier) are explicitly not
      71             : //    allowed (if any).
      72             : // 2) factoring code with nsHTMLContentSink - There's some amount of
      73             : //    common code between this and the HTML content sink. This will
      74             : //    increase as we support more and more HTML elements. How can code
      75             : //    from the code be factored?
      76             : 
      77             : nsresult
      78          21 : NS_NewXMLContentSink(nsIXMLContentSink** aResult,
      79             :                      nsIDocument* aDoc,
      80             :                      nsIURI* aURI,
      81             :                      nsISupports* aContainer,
      82             :                      nsIChannel* aChannel)
      83             : {
      84          21 :   NS_PRECONDITION(nullptr != aResult, "null ptr");
      85          21 :   if (nullptr == aResult) {
      86           0 :     return NS_ERROR_NULL_POINTER;
      87             :   }
      88          42 :   RefPtr<nsXMLContentSink> it = new nsXMLContentSink();
      89             : 
      90          21 :   nsresult rv = it->Init(aDoc, aURI, aContainer, aChannel);
      91          21 :   NS_ENSURE_SUCCESS(rv, rv);
      92             : 
      93          21 :   it.forget(aResult);
      94          21 :   return NS_OK;
      95             : }
      96             : 
      97          22 : nsXMLContentSink::nsXMLContentSink()
      98             :   : mTextLength(0)
      99             :   , mNotifyLevel(0)
     100             :   , mPrettyPrintXML(true)
     101             :   , mPrettyPrintHasSpecialRoot(0)
     102             :   , mPrettyPrintHasFactoredElements(0)
     103             :   , mPrettyPrinting(0)
     104          22 :   , mPreventScriptExecution(0)
     105             : {
     106          22 :   PodArrayZero(mText);
     107          22 : }
     108             : 
     109           0 : nsXMLContentSink::~nsXMLContentSink()
     110             : {
     111           0 : }
     112             : 
     113             : nsresult
     114          22 : nsXMLContentSink::Init(nsIDocument* aDoc,
     115             :                        nsIURI* aURI,
     116             :                        nsISupports* aContainer,
     117             :                        nsIChannel* aChannel)
     118             : {
     119          22 :   nsresult rv = nsContentSink::Init(aDoc, aURI, aContainer, aChannel);
     120          22 :   NS_ENSURE_SUCCESS(rv, rv);
     121             : 
     122          22 :   aDoc->AddObserver(this);
     123          22 :   mIsDocumentObserver = true;
     124             : 
     125          22 :   if (!mDocShell) {
     126          22 :     mPrettyPrintXML = false;
     127             :   }
     128             : 
     129          22 :   mState = eXMLContentSinkState_InProlog;
     130          22 :   mDocElement = nullptr;
     131             : 
     132          22 :   return NS_OK;
     133             : }
     134             : 
     135         317 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXMLContentSink)
     136         295 :   NS_INTERFACE_MAP_ENTRY(nsIContentSink)
     137         116 :   NS_INTERFACE_MAP_ENTRY(nsIXMLContentSink)
     138          93 :   NS_INTERFACE_MAP_ENTRY(nsIExpatSink)
     139          71 :   NS_INTERFACE_MAP_ENTRY(nsITransformObserver)
     140          71 : NS_INTERFACE_MAP_END_INHERITING(nsContentSink)
     141             : 
     142         803 : NS_IMPL_ADDREF_INHERITED(nsXMLContentSink, nsContentSink)
     143         802 : NS_IMPL_RELEASE_INHERITED(nsXMLContentSink, nsContentSink)
     144             : 
     145             : NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLContentSink)
     146             : 
     147           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLContentSink,
     148             :                                                   nsContentSink)
     149           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCurrentHead)
     150           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocElement)
     151           0 :   for (uint32_t i = 0, count = tmp->mContentStack.Length(); i < count; i++) {
     152           0 :     const StackNode& node = tmp->mContentStack.ElementAt(i);
     153           0 :     cb.NoteXPCOMChild(node.mContent);
     154             :   }
     155           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     156             : 
     157             : // nsIContentSink
     158             : NS_IMETHODIMP
     159          44 : nsXMLContentSink::WillParse(void)
     160             : {
     161          44 :   return WillParseImpl();
     162             : }
     163             : 
     164             : NS_IMETHODIMP
     165          22 : nsXMLContentSink::WillBuildModel(nsDTDMode aDTDMode)
     166             : {
     167          22 :   WillBuildModelImpl();
     168             : 
     169             :   // Notify document that the load is beginning
     170          22 :   mDocument->BeginLoad();
     171             : 
     172             :   // Check for correct load-command for maybe prettyprinting
     173          22 :   if (mPrettyPrintXML) {
     174           0 :     nsAutoCString command;
     175           0 :     GetParser()->GetCommand(command);
     176           0 :     if (!command.EqualsLiteral("view")) {
     177           0 :       mPrettyPrintXML = false;
     178             :     }
     179             :   }
     180             : 
     181          22 :   return NS_OK;
     182             : }
     183             : 
     184             : bool
     185          43 : nsXMLContentSink::CanStillPrettyPrint()
     186             : {
     187          43 :   return mPrettyPrintXML &&
     188          86 :          (!mPrettyPrintHasFactoredElements || mPrettyPrintHasSpecialRoot);
     189             : }
     190             : 
     191             : nsresult
     192          22 : nsXMLContentSink::MaybePrettyPrint()
     193             : {
     194          22 :   if (!CanStillPrettyPrint()) {
     195          22 :     mPrettyPrintXML = false;
     196             : 
     197          22 :     return NS_OK;
     198             :   }
     199             : 
     200             :   // stop observing in order to avoid crashing when replacing content
     201           0 :   mDocument->RemoveObserver(this);
     202           0 :   mIsDocumentObserver = false;
     203             : 
     204             :   // Reenable the CSSLoader so that the prettyprinting stylesheets can load
     205           0 :   if (mCSSLoader) {
     206           0 :     mCSSLoader->SetEnabled(true);
     207             :   }
     208             : 
     209           0 :   RefPtr<nsXMLPrettyPrinter> printer;
     210           0 :   nsresult rv = NS_NewXMLPrettyPrinter(getter_AddRefs(printer));
     211           0 :   NS_ENSURE_SUCCESS(rv, rv);
     212             : 
     213             :   bool isPrettyPrinting;
     214           0 :   rv = printer->PrettyPrint(mDocument, &isPrettyPrinting);
     215           0 :   NS_ENSURE_SUCCESS(rv, rv);
     216             : 
     217           0 :   mPrettyPrinting = isPrettyPrinting;
     218           0 :   return NS_OK;
     219             : }
     220             : 
     221             : static void
     222           0 : CheckXSLTParamPI(nsIDOMProcessingInstruction* aPi,
     223             :                  nsIDocumentTransformer* aProcessor,
     224             :                  nsIDocument* aDocument)
     225             : {
     226           0 :   nsAutoString target, data;
     227           0 :   aPi->GetTarget(target);
     228             : 
     229             :   // Check for namespace declarations
     230           0 :   if (target.EqualsLiteral("xslt-param-namespace")) {
     231           0 :     aPi->GetData(data);
     232           0 :     nsAutoString prefix, namespaceAttr;
     233             :     nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::prefix,
     234           0 :                                             prefix);
     235           0 :     if (!prefix.IsEmpty() &&
     236           0 :         nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::_namespace,
     237             :                                                 namespaceAttr)) {
     238           0 :       aProcessor->AddXSLTParamNamespace(prefix, namespaceAttr);
     239             :     }
     240             :   }
     241             : 
     242             :   // Check for actual parameters
     243           0 :   else if (target.EqualsLiteral("xslt-param")) {
     244           0 :     aPi->GetData(data);
     245           0 :     nsAutoString name, namespaceAttr, select, value;
     246             :     nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::name,
     247           0 :                                             name);
     248             :     nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::_namespace,
     249           0 :                                             namespaceAttr);
     250           0 :     if (!nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::select, select)) {
     251           0 :       select.SetIsVoid(true);
     252             :     }
     253           0 :     if (!nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::value, value)) {
     254           0 :       value.SetIsVoid(true);
     255             :     }
     256           0 :     if (!name.IsEmpty()) {
     257           0 :       nsCOMPtr<nsIDOMNode> doc = do_QueryInterface(aDocument);
     258           0 :       aProcessor->AddXSLTParam(name, namespaceAttr, select, value, doc);
     259             :     }
     260             :   }
     261           0 : }
     262             : 
     263             : NS_IMETHODIMP
     264          22 : nsXMLContentSink::DidBuildModel(bool aTerminated)
     265             : {
     266          22 :   if (!mParser) {
     267             :     // If mParser is null, this parse has already been terminated and must
     268             :     // not been terminated again. However, nsDocument may still think that
     269             :     // the parse has not been terminated and call back into here in the case
     270             :     // where the XML parser has finished but the XSLT transform associated
     271             :     // with the document has not.
     272           0 :     return NS_OK;
     273             :   }
     274             : 
     275          22 :   DidBuildModelImpl(aTerminated);
     276             : 
     277          22 :   if (mXSLTProcessor) {
     278             :     // stop observing in order to avoid crashing when replacing content
     279           0 :     mDocument->RemoveObserver(this);
     280           0 :     mIsDocumentObserver = false;
     281             : 
     282             :     // Check for xslt-param and xslt-param-namespace PIs
     283           0 :     for (nsIContent* child = mDocument->GetFirstChild();
     284           0 :          child;
     285           0 :          child = child->GetNextSibling()) {
     286           0 :       if (child->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) {
     287           0 :         nsCOMPtr<nsIDOMProcessingInstruction> pi = do_QueryInterface(child);
     288           0 :         CheckXSLTParamPI(pi, mXSLTProcessor, mDocument);
     289             :       }
     290           0 :       else if (child->IsElement()) {
     291             :         // Only honor PIs in the prolog
     292           0 :         break;
     293             :       }
     294             :     }
     295             : 
     296           0 :     nsCOMPtr<nsIDOMDocument> currentDOMDoc(do_QueryInterface(mDocument));
     297           0 :     mXSLTProcessor->SetSourceContentModel(currentDOMDoc);
     298             :     // Since the processor now holds a reference to us we drop our reference
     299             :     // to it to avoid owning cycles
     300           0 :     mXSLTProcessor = nullptr;
     301             :   }
     302             :   else {
     303             :     // Kick off layout for non-XSLT transformed documents.
     304             : 
     305             :     // Check if we want to prettyprint
     306          22 :     MaybePrettyPrint();
     307             : 
     308          22 :     bool startLayout = true;
     309             : 
     310          22 :     if (mPrettyPrinting) {
     311           0 :       NS_ASSERTION(!mPendingSheetCount, "Shouldn't have pending sheets here!");
     312             : 
     313             :       // We're pretty-printing now.  See whether we should wait up on
     314             :       // stylesheet loads
     315           0 :       if (mDocument->CSSLoader()->HasPendingLoads() &&
     316           0 :           NS_SUCCEEDED(mDocument->CSSLoader()->AddObserver(this))) {
     317             :         // wait for those sheets to load
     318           0 :         startLayout = false;
     319             :       }
     320             :     }
     321             : 
     322          22 :     if (startLayout) {
     323          22 :       StartLayout(false);
     324             : 
     325          22 :       ScrollToRef();
     326             :     }
     327             : 
     328          22 :     mDocument->RemoveObserver(this);
     329          22 :     mIsDocumentObserver = false;
     330             : 
     331          22 :     mDocument->EndLoad();
     332             :   }
     333             : 
     334          22 :   DropParserAndPerfHint();
     335             : 
     336          22 :   return NS_OK;
     337             : }
     338             : 
     339             : NS_IMETHODIMP
     340           0 : nsXMLContentSink::OnDocumentCreated(nsIDocument* aResultDocument)
     341             : {
     342           0 :   NS_ENSURE_ARG(aResultDocument);
     343             : 
     344           0 :   nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(aResultDocument);
     345           0 :   if (htmlDoc) {
     346           0 :     htmlDoc->SetDocWriteDisabled(true);
     347             :   }
     348             : 
     349           0 :   nsCOMPtr<nsIContentViewer> contentViewer;
     350           0 :   mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
     351           0 :   if (contentViewer) {
     352           0 :     return contentViewer->SetDocumentInternal(aResultDocument, true);
     353             :   }
     354           0 :   return NS_OK;
     355             : }
     356             : 
     357             : NS_IMETHODIMP
     358           0 : nsXMLContentSink::OnTransformDone(nsresult aResult,
     359             :                                   nsIDocument* aResultDocument)
     360             : {
     361           0 :   NS_ASSERTION(NS_FAILED(aResult) || aResultDocument,
     362             :                "Don't notify about transform success without a document.");
     363             : 
     364           0 :   nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aResultDocument);
     365             : 
     366           0 :   nsCOMPtr<nsIContentViewer> contentViewer;
     367           0 :   mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
     368             : 
     369           0 :   if (NS_FAILED(aResult) && contentViewer) {
     370             :     // Transform failed.
     371           0 :     if (domDoc) {
     372           0 :       aResultDocument->SetMayStartLayout(false);
     373             :       // We have an error document.
     374           0 :       contentViewer->SetDOMDocument(domDoc);
     375             :     }
     376             :     else {
     377             :       // We don't have an error document, display the
     378             :       // untransformed source document.
     379           0 :       nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(mDocument);
     380           0 :       contentViewer->SetDOMDocument(document);
     381             :     }
     382             :   }
     383             : 
     384           0 :   nsCOMPtr<nsIDocument> originalDocument = mDocument;
     385           0 :   if (NS_SUCCEEDED(aResult) || aResultDocument) {
     386             :     // Transform succeeded or it failed and we have an error
     387             :     // document to display.
     388           0 :     mDocument = aResultDocument;
     389           0 :     nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
     390           0 :     if (htmlDoc) {
     391           0 :       htmlDoc->SetDocWriteDisabled(false);
     392             :     }
     393             :   }
     394             : 
     395             :   // Notify document observers that all the content has been stuck
     396             :   // into the document.
     397             :   // XXX do we need to notify for things like PIs?  Or just the
     398             :   // documentElement?
     399           0 :   nsIContent *rootElement = mDocument->GetRootElement();
     400           0 :   if (rootElement) {
     401           0 :     NS_ASSERTION(mDocument->IndexOf(rootElement) != -1,
     402             :                  "rootElement not in doc?");
     403           0 :     mDocument->BeginUpdate(UPDATE_CONTENT_MODEL);
     404           0 :     nsNodeUtils::ContentInserted(mDocument, rootElement,
     405           0 :                                  mDocument->IndexOf(rootElement));
     406           0 :     mDocument->EndUpdate(UPDATE_CONTENT_MODEL);
     407             :   }
     408             : 
     409             :   // Start the layout process
     410           0 :   StartLayout(false);
     411             : 
     412           0 :   ScrollToRef();
     413             : 
     414           0 :   originalDocument->EndLoad();
     415             : 
     416           0 :   return NS_OK;
     417             : }
     418             : 
     419             : NS_IMETHODIMP
     420           0 : nsXMLContentSink::StyleSheetLoaded(StyleSheet* aSheet,
     421             :                                    bool aWasAlternate,
     422             :                                    nsresult aStatus)
     423             : {
     424           0 :   if (!mPrettyPrinting) {
     425           0 :     return nsContentSink::StyleSheetLoaded(aSheet, aWasAlternate, aStatus);
     426             :   }
     427             : 
     428           0 :   if (!mDocument->CSSLoader()->HasPendingLoads()) {
     429           0 :     mDocument->CSSLoader()->RemoveObserver(this);
     430           0 :     StartLayout(false);
     431           0 :     ScrollToRef();
     432             :   }
     433             : 
     434           0 :   return NS_OK;
     435             : }
     436             : 
     437             : NS_IMETHODIMP
     438          22 : nsXMLContentSink::WillInterrupt(void)
     439             : {
     440          22 :   return WillInterruptImpl();
     441             : }
     442             : 
     443             : NS_IMETHODIMP
     444          44 : nsXMLContentSink::WillResume(void)
     445             : {
     446          44 :   return WillResumeImpl();
     447             : }
     448             : 
     449             : NS_IMETHODIMP
     450          22 : nsXMLContentSink::SetParser(nsParserBase* aParser)
     451             : {
     452          22 :   NS_PRECONDITION(aParser, "Should have a parser here!");
     453          22 :   mParser = aParser;
     454          22 :   return NS_OK;
     455             : }
     456             : 
     457             : nsresult
     458         135 : nsXMLContentSink::CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
     459             :                                 mozilla::dom::NodeInfo* aNodeInfo, uint32_t aLineNumber,
     460             :                                 nsIContent** aResult, bool* aAppendContent,
     461             :                                 FromParser aFromParser)
     462             : {
     463         135 :   NS_ASSERTION(aNodeInfo, "can't create element without nodeinfo");
     464             : 
     465         135 :   *aResult = nullptr;
     466         135 :   *aAppendContent = true;
     467         135 :   nsresult rv = NS_OK;
     468             : 
     469         270 :   RefPtr<mozilla::dom::NodeInfo> ni = aNodeInfo;
     470         270 :   RefPtr<Element> content;
     471         135 :   rv = NS_NewElement(getter_AddRefs(content), ni.forget(), aFromParser);
     472         135 :   NS_ENSURE_SUCCESS(rv, rv);
     473             : 
     474         270 :   if (aNodeInfo->Equals(nsGkAtoms::script, kNameSpaceID_XHTML)
     475         135 :       || aNodeInfo->Equals(nsGkAtoms::script, kNameSpaceID_SVG)
     476             :     ) {
     477           0 :     nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(content);
     478           0 :     if (sele) {
     479           0 :       sele->SetScriptLineNumber(aLineNumber);
     480           0 :       sele->SetCreatorParser(GetParser());
     481             :     } else {
     482           0 :       MOZ_ASSERT(nsNameSpaceManager::GetInstance()->mSVGDisabled, "Node didn't QI to script, but SVG wasn't disabled.");
     483             :     }
     484             :   }
     485             : 
     486             :   // XHTML needs some special attention
     487         135 :   if (aNodeInfo->NamespaceEquals(kNameSpaceID_XHTML)) {
     488           2 :     mPrettyPrintHasFactoredElements = true;
     489             :   }
     490             :   else {
     491             :     // If we care, find out if we just used a special factory.
     492         262 :     if (!mPrettyPrintHasFactoredElements && !mPrettyPrintHasSpecialRoot &&
     493         129 :         mPrettyPrintXML) {
     494           0 :       mPrettyPrintHasFactoredElements =
     495             :         nsContentUtils::NameSpaceManager()->
     496           0 :           HasElementCreator(aNodeInfo->NamespaceID());
     497             :     }
     498             : 
     499         133 :     if (!aNodeInfo->NamespaceEquals(kNameSpaceID_SVG)) {
     500           5 :       content.forget(aResult);
     501             : 
     502           5 :       return NS_OK;
     503             :     }
     504             :   }
     505             : 
     506         390 :   if (aNodeInfo->Equals(nsGkAtoms::link, kNameSpaceID_XHTML) ||
     507         260 :       aNodeInfo->Equals(nsGkAtoms::style, kNameSpaceID_XHTML) ||
     508         130 :       aNodeInfo->Equals(nsGkAtoms::style, kNameSpaceID_SVG)) {
     509          10 :     nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(content));
     510           5 :     if (ssle) {
     511           5 :       ssle->InitStyleLinkElement(false);
     512           5 :       if (aFromParser) {
     513           5 :         ssle->SetEnableUpdates(false);
     514             :       }
     515           5 :       if (!aNodeInfo->Equals(nsGkAtoms::link, kNameSpaceID_XHTML)) {
     516           5 :         ssle->SetLineNumber(aFromParser ? aLineNumber : 0);
     517             :       }
     518             :     }
     519             :   }
     520             : 
     521         130 :   content.forget(aResult);
     522             : 
     523         130 :   return NS_OK;
     524             : }
     525             : 
     526             : 
     527             : nsresult
     528         141 : nsXMLContentSink::CloseElement(nsIContent* aContent)
     529             : {
     530         141 :   NS_ASSERTION(aContent, "missing element to close");
     531             : 
     532         141 :   mozilla::dom::NodeInfo *nodeInfo = aContent->NodeInfo();
     533             : 
     534             :   // Some HTML nodes need DoneAddingChildren() called to initialize
     535             :   // properly (eg form state restoration).
     536         284 :   if ((nodeInfo->NamespaceID() == kNameSpaceID_XHTML &&
     537           4 :        (nodeInfo->NameAtom() == nsGkAtoms::select ||
     538           4 :         nodeInfo->NameAtom() == nsGkAtoms::textarea ||
     539           4 :         nodeInfo->NameAtom() == nsGkAtoms::video ||
     540           4 :         nodeInfo->NameAtom() == nsGkAtoms::audio ||
     541           4 :         nodeInfo->NameAtom() == nsGkAtoms::object ||
     542           2 :         nodeInfo->NameAtom() == nsGkAtoms::applet))
     543         282 :       || nodeInfo->NameAtom() == nsGkAtoms::title
     544             :       ) {
     545           0 :     aContent->DoneAddingChildren(HaveNotifiedForCurrentContent());
     546             :   }
     547             : 
     548         141 :   if (IsMonolithicContainer(nodeInfo)) {
     549           0 :     mInMonolithicContainer--;
     550             :   }
     551             : 
     552         280 :   if (!nodeInfo->NamespaceEquals(kNameSpaceID_XHTML) &&
     553         139 :       !nodeInfo->NamespaceEquals(kNameSpaceID_SVG)) {
     554          11 :     return NS_OK;
     555             :   }
     556             : 
     557         260 :   if (nodeInfo->Equals(nsGkAtoms::script, kNameSpaceID_XHTML)
     558         130 :       || nodeInfo->Equals(nsGkAtoms::script, kNameSpaceID_SVG)
     559             :     ) {
     560           0 :     nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(aContent);
     561           0 :     if (!sele) {
     562           0 :       MOZ_ASSERT(nsNameSpaceManager::GetInstance()->mSVGDisabled, "Node didn't QI to script, but SVG wasn't disabled.");
     563           0 :       return NS_OK;
     564             :     }
     565             : 
     566           0 :     if (mPreventScriptExecution) {
     567           0 :       sele->PreventExecution();
     568           0 :       return NS_OK;
     569             :     }
     570             : 
     571             :     // Always check the clock in nsContentSink right after a script
     572           0 :     StopDeflecting();
     573             : 
     574             :     // Now tell the script that it's ready to go. This may execute the script
     575             :     // or return true, or neither if the script doesn't need executing.
     576           0 :     bool block = sele->AttemptToExecute();
     577             : 
     578             :     // If the parser got blocked, make sure to return the appropriate rv.
     579             :     // I'm not sure if this is actually needed or not.
     580           0 :     if (mParser && !mParser->IsParserEnabled()) {
     581           0 :       block = true;
     582             :     }
     583             : 
     584           0 :     return block ? NS_ERROR_HTMLPARSER_BLOCK : NS_OK;
     585             :   }
     586             : 
     587         130 :   nsresult rv = NS_OK;
     588         130 :   if (nodeInfo->Equals(nsGkAtoms::meta, kNameSpaceID_XHTML) &&
     589             :            // Need to check here to make sure this meta tag does not set
     590             :            // mPrettyPrintXML to false when we have a special root!
     591           0 :            (!mPrettyPrintXML || !mPrettyPrintHasSpecialRoot)) {
     592           0 :     rv = ProcessMETATag(aContent);
     593             :   }
     594         390 :   else if (nodeInfo->Equals(nsGkAtoms::link, kNameSpaceID_XHTML) ||
     595         260 :            nodeInfo->Equals(nsGkAtoms::style, kNameSpaceID_XHTML) ||
     596         130 :            nodeInfo->Equals(nsGkAtoms::style, kNameSpaceID_SVG)) {
     597          10 :     nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(aContent));
     598           5 :     if (ssle) {
     599           5 :       ssle->SetEnableUpdates(true);
     600             :       bool willNotify;
     601             :       bool isAlternate;
     602          10 :       rv = ssle->UpdateStyleSheet(mRunsToCompletion ? nullptr : this,
     603             :                                   &willNotify,
     604          10 :                                   &isAlternate);
     605           5 :       if (NS_SUCCEEDED(rv) && willNotify && !isAlternate && !mRunsToCompletion) {
     606           0 :         ++mPendingSheetCount;
     607           0 :         mScriptLoader->AddParserBlockingScriptExecutionBlocker();
     608             :       }
     609             :     }
     610             :   }
     611             : 
     612         130 :   return rv;
     613             : }
     614             : 
     615             : nsresult
     616         185 : nsXMLContentSink::AddContentAsLeaf(nsIContent *aContent)
     617             : {
     618         185 :   nsresult result = NS_OK;
     619             : 
     620         349 :   if ((eXMLContentSinkState_InProlog == mState) ||
     621         164 :       (eXMLContentSinkState_InEpilog == mState)) {
     622          21 :     NS_ASSERTION(mDocument, "Fragments have no prolog or epilog");
     623          21 :     mDocument->AppendChildTo(aContent, false);
     624             :   }
     625             :   else {
     626         328 :     nsCOMPtr<nsIContent> parent = GetCurrentContent();
     627             : 
     628         164 :     if (parent) {
     629         164 :       result = parent->AppendChildTo(aContent, false);
     630             :     }
     631             :   }
     632         185 :   return result;
     633             : }
     634             : 
     635             : // Create an XML parser and an XSL content sink and start parsing
     636             : // the XSL stylesheet located at the given URI.
     637             : nsresult
     638           0 : nsXMLContentSink::LoadXSLStyleSheet(nsIURI* aUrl)
     639             : {
     640             :   nsCOMPtr<nsIDocumentTransformer> processor =
     641           0 :     do_CreateInstance("@mozilla.org/document-transformer;1?type=xslt");
     642           0 :   if (!processor) {
     643             :     // No XSLT processor available, continue normal document loading
     644           0 :     return NS_OK;
     645             :   }
     646             : 
     647           0 :   processor->SetTransformObserver(this);
     648             : 
     649           0 :   if (NS_SUCCEEDED(processor->LoadStyleSheet(aUrl, mDocument))) {
     650           0 :     mXSLTProcessor.swap(processor);
     651             :   }
     652             : 
     653             :   // Intentionally ignore errors here, we should continue loading the
     654             :   // XML document whether we're able to load the XSLT stylesheet or
     655             :   // not.
     656             : 
     657           0 :   return NS_OK;
     658             : }
     659             : 
     660             : nsresult
     661           0 : nsXMLContentSink::ProcessStyleLink(nsIContent* aElement,
     662             :                                    const nsAString& aHref,
     663             :                                    bool aAlternate,
     664             :                                    const nsAString& aTitle,
     665             :                                    const nsAString& aType,
     666             :                                    const nsAString& aMedia)
     667             : {
     668           0 :   nsresult rv = NS_OK;
     669           0 :   mPrettyPrintXML = false;
     670             : 
     671           0 :   nsAutoCString cmd;
     672           0 :   if (mParser)
     673           0 :     GetParser()->GetCommand(cmd);
     674           0 :   if (cmd.EqualsASCII(kLoadAsData))
     675           0 :     return NS_OK; // Do not load stylesheets when loading as data
     676             : 
     677           0 :   NS_ConvertUTF16toUTF8 type(aType);
     678           0 :   if (type.EqualsIgnoreCase(TEXT_XSL) ||
     679           0 :       type.EqualsIgnoreCase(APPLICATION_XSLT_XML) ||
     680           0 :       type.EqualsIgnoreCase(TEXT_XML) ||
     681           0 :       type.EqualsIgnoreCase(APPLICATION_XML)) {
     682           0 :     if (aAlternate) {
     683             :       // don't load alternate XSLT
     684           0 :       return NS_OK;
     685             :     }
     686             :     // LoadXSLStyleSheet needs a mDocShell.
     687           0 :     if (!mDocShell)
     688           0 :       return NS_OK;
     689             : 
     690           0 :     nsCOMPtr<nsIURI> url;
     691           0 :     rv = NS_NewURI(getter_AddRefs(url), aHref, nullptr,
     692           0 :                    mDocument->GetDocBaseURI());
     693           0 :     NS_ENSURE_SUCCESS(rv, rv);
     694             : 
     695             :     // Do security check
     696           0 :     nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
     697             :     rv = secMan->
     698           0 :       CheckLoadURIWithPrincipal(mDocument->NodePrincipal(), url,
     699           0 :                                 nsIScriptSecurityManager::ALLOW_CHROME);
     700           0 :     NS_ENSURE_SUCCESS(rv, NS_OK);
     701             : 
     702             :     // Do content policy check
     703           0 :     int16_t decision = nsIContentPolicy::ACCEPT;
     704           0 :     rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_XSLT,
     705             :                                    url,
     706           0 :                                    mDocument->NodePrincipal(),
     707             :                                    aElement,
     708             :                                    type,
     709             :                                    nullptr,
     710             :                                    &decision,
     711             :                                    nsContentUtils::GetContentPolicy(),
     712           0 :                                    nsContentUtils::GetSecurityManager());
     713             : 
     714           0 :     NS_ENSURE_SUCCESS(rv, rv);
     715             : 
     716           0 :     if (NS_CP_REJECTED(decision)) {
     717           0 :       return NS_OK;
     718             :     }
     719             : 
     720           0 :     return LoadXSLStyleSheet(url);
     721             :   }
     722             : 
     723             :   // Let nsContentSink deal with css.
     724           0 :   rv = nsContentSink::ProcessStyleLink(aElement, aHref, aAlternate,
     725           0 :                                        aTitle, aType, aMedia);
     726             : 
     727             :   // nsContentSink::ProcessStyleLink handles the bookkeeping here wrt
     728             :   // pending sheets.
     729             : 
     730           0 :   return rv;
     731             : }
     732             : 
     733             : void
     734          22 : nsXMLContentSink::SetDocumentCharset(NotNull<const Encoding*> aEncoding)
     735             : {
     736          22 :   if (mDocument) {
     737          22 :     mDocument->SetDocumentCharacterSet(aEncoding);
     738             :   }
     739          22 : }
     740             : 
     741             : nsISupports *
     742          22 : nsXMLContentSink::GetTarget()
     743             : {
     744          22 :   return mDocument;
     745             : }
     746             : 
     747             : bool
     748          44 : nsXMLContentSink::IsScriptExecuting()
     749             : {
     750          44 :   return IsScriptExecutingImpl();
     751             : }
     752             : 
     753             : nsresult
     754         401 : nsXMLContentSink::FlushText(bool aReleaseTextNode)
     755             : {
     756         401 :   nsresult rv = NS_OK;
     757             : 
     758         401 :   if (mTextLength != 0) {
     759         162 :     if (mLastTextNode) {
     760           0 :       bool notify = HaveNotifiedForCurrentContent();
     761             :       // We could probably always increase mInNotification here since
     762             :       // if AppendText doesn't notify it shouldn't trigger evil code.
     763             :       // But just in case it does, we don't want to mask any notifications.
     764           0 :       if (notify) {
     765           0 :         ++mInNotification;
     766             :       }
     767           0 :       rv = mLastTextNode->AppendText(mText, mTextLength, notify);
     768           0 :       if (notify) {
     769           0 :         --mInNotification;
     770             :       }
     771             : 
     772           0 :       mTextLength = 0;
     773             :     } else {
     774         486 :       RefPtr<nsTextNode> textContent = new nsTextNode(mNodeInfoManager);
     775             : 
     776         162 :       mLastTextNode = textContent;
     777             : 
     778             :       // Set the text in the text node
     779         162 :       textContent->SetText(mText, mTextLength, false);
     780         162 :       mTextLength = 0;
     781             : 
     782             :       // Add text to its parent
     783         162 :       rv = AddContentAsLeaf(textContent);
     784             :     }
     785             :   }
     786             : 
     787         401 :   if (aReleaseTextNode) {
     788         321 :     mLastTextNode = nullptr;
     789             :   }
     790             : 
     791         401 :   return rv;
     792             : }
     793             : 
     794             : nsIContent*
     795         324 : nsXMLContentSink::GetCurrentContent()
     796             : {
     797         324 :   if (mContentStack.Length() == 0) {
     798          22 :     return nullptr;
     799             :   }
     800         302 :   return GetCurrentStackNode()->mContent;
     801             : }
     802             : 
     803             : StackNode*
     804         443 : nsXMLContentSink::GetCurrentStackNode()
     805             : {
     806         443 :   int32_t count = mContentStack.Length();
     807         443 :   return count != 0 ? &mContentStack[count-1] : nullptr;
     808             : }
     809             : 
     810             : 
     811             : nsresult
     812         141 : nsXMLContentSink::PushContent(nsIContent *aContent)
     813             : {
     814         141 :   NS_PRECONDITION(aContent, "Null content being pushed!");
     815         141 :   StackNode *sn = mContentStack.AppendElement();
     816         141 :   NS_ENSURE_TRUE(sn, NS_ERROR_OUT_OF_MEMORY);
     817             : 
     818         141 :   nsIContent* contentToPush = aContent;
     819             : 
     820             :   // When an XML parser would append a node to a template element, it
     821             :   // must instead append it to the template element's template contents.
     822         141 :   if (contentToPush->IsHTMLElement(nsGkAtoms::_template)) {
     823             :     HTMLTemplateElement* templateElement =
     824           0 :       static_cast<HTMLTemplateElement*>(contentToPush);
     825           0 :     contentToPush = templateElement->Content();
     826             :   }
     827             : 
     828         141 :   sn->mContent = contentToPush;
     829         141 :   sn->mNumFlushed = 0;
     830         141 :   return NS_OK;
     831             : }
     832             : 
     833             : void
     834         141 : nsXMLContentSink::PopContent()
     835             : {
     836         141 :   int32_t count = mContentStack.Length();
     837             : 
     838         141 :   if (count == 0) {
     839           0 :     NS_WARNING("Popping empty stack");
     840           0 :     return;
     841             :   }
     842             : 
     843         141 :   mContentStack.RemoveElementAt(count - 1);
     844             : }
     845             : 
     846             : bool
     847           0 : nsXMLContentSink::HaveNotifiedForCurrentContent() const
     848             : {
     849           0 :   uint32_t stackLength = mContentStack.Length();
     850           0 :   if (stackLength) {
     851           0 :     const StackNode& stackNode = mContentStack[stackLength - 1];
     852           0 :     nsIContent* parent = stackNode.mContent;
     853           0 :     return stackNode.mNumFlushed == parent->GetChildCount();
     854             :   }
     855           0 :   return true;
     856             : }
     857             : 
     858             : void
     859         130 : nsXMLContentSink::MaybeStartLayout(bool aIgnorePendingSheets)
     860             : {
     861             :   // XXXbz if aIgnorePendingSheets is true, what should we do when
     862             :   // mXSLTProcessor or CanStillPrettyPrint()?
     863         130 :   if (mLayoutStarted || mXSLTProcessor || CanStillPrettyPrint()) {
     864         109 :     return;
     865             :   }
     866          21 :   StartLayout(aIgnorePendingSheets);
     867             : }
     868             : 
     869             : ////////////////////////////////////////////////////////////////////////
     870             : 
     871             : bool
     872         141 : nsXMLContentSink::SetDocElement(int32_t aNameSpaceID,
     873             :                                 nsIAtom* aTagName,
     874             :                                 nsIContent *aContent)
     875             : {
     876         141 :   if (mDocElement)
     877         119 :     return false;
     878             : 
     879             :   // check for root elements that needs special handling for
     880             :   // prettyprinting
     881          23 :   if ((aNameSpaceID == kNameSpaceID_XBL &&
     882          22 :        aTagName == nsGkAtoms::bindings) ||
     883           0 :       (aNameSpaceID == kNameSpaceID_XSLT &&
     884           0 :        (aTagName == nsGkAtoms::stylesheet ||
     885           0 :         aTagName == nsGkAtoms::transform))) {
     886           1 :     mPrettyPrintHasSpecialRoot = true;
     887           1 :     if (mPrettyPrintXML) {
     888             :       // In this case, disable script execution, stylesheet
     889             :       // loading, and auto XLinks since we plan to prettyprint.
     890           0 :       mDocument->ScriptLoader()->SetEnabled(false);
     891           0 :       if (mCSSLoader) {
     892           0 :         mCSSLoader->SetEnabled(false);
     893             :       }
     894             :     }
     895             :   }
     896             : 
     897          22 :   mDocElement = aContent;
     898          22 :   nsresult rv = mDocument->AppendChildTo(mDocElement, NotifyForDocElement());
     899          22 :   if (NS_FAILED(rv)) {
     900             :     // If we return false here, the caller will bail out because it won't
     901             :     // find a parent content node to append to, which is fine.
     902           0 :     return false;
     903             :   }
     904             : 
     905          22 :   if (aTagName == nsGkAtoms::html &&
     906             :       aNameSpaceID == kNameSpaceID_XHTML) {
     907           0 :     ProcessOfflineManifest(aContent);
     908             :   }
     909             : 
     910          22 :   return true;
     911             : }
     912             : 
     913             : NS_IMETHODIMP
     914         146 : nsXMLContentSink::HandleStartElement(const char16_t *aName,
     915             :                                      const char16_t **aAtts,
     916             :                                      uint32_t aAttsCount,
     917             :                                      uint32_t aLineNumber)
     918             : {
     919             :   return HandleStartElement(aName, aAtts, aAttsCount, aLineNumber,
     920         146 :                             true);
     921             : }
     922             : 
     923             : nsresult
     924         146 : nsXMLContentSink::HandleStartElement(const char16_t *aName,
     925             :                                      const char16_t **aAtts,
     926             :                                      uint32_t aAttsCount,
     927             :                                      uint32_t aLineNumber,
     928             :                                      bool aInterruptable)
     929             : {
     930         146 :   NS_PRECONDITION(aAttsCount % 2 == 0, "incorrect aAttsCount");
     931             :   // Adjust aAttsCount so it's the actual number of attributes
     932         146 :   aAttsCount /= 2;
     933             : 
     934         146 :   nsresult result = NS_OK;
     935         146 :   bool appendContent = true;
     936         292 :   nsCOMPtr<nsIContent> content;
     937             : 
     938             :   // XXX Hopefully the parser will flag this before we get
     939             :   // here. If we're in the epilog, there should be no
     940             :   // new elements
     941         146 :   MOZ_ASSERT(eXMLContentSinkState_InEpilog != mState);
     942             : 
     943         146 :   FlushText();
     944         146 :   DidAddContent();
     945             : 
     946         146 :   mState = eXMLContentSinkState_InDocumentElement;
     947             : 
     948             :   int32_t nameSpaceID;
     949         292 :   nsCOMPtr<nsIAtom> prefix, localName;
     950         292 :   nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
     951         438 :                                  getter_AddRefs(localName), &nameSpaceID);
     952             : 
     953         146 :   if (!OnOpenContainer(aAtts, aAttsCount, nameSpaceID, localName, aLineNumber)) {
     954           5 :     return NS_OK;
     955             :   }
     956             : 
     957         282 :   RefPtr<mozilla::dom::NodeInfo> nodeInfo;
     958         282 :   nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID,
     959         141 :                                            nsIDOMNode::ELEMENT_NODE);
     960             : 
     961         141 :   result = CreateElement(aAtts, aAttsCount, nodeInfo, aLineNumber,
     962         282 :                          getter_AddRefs(content), &appendContent,
     963         282 :                          FROM_PARSER_NETWORK);
     964         141 :   NS_ENSURE_SUCCESS(result, result);
     965             : 
     966             :   // Have to do this before we push the new content on the stack... and have to
     967             :   // do that before we set attributes, call BindToTree, etc.  Ideally we'd push
     968             :   // on the stack inside CreateElement (which is effectively what the HTML sink
     969             :   // does), but that's hard with all the subclass overrides going on.
     970         282 :   nsCOMPtr<nsIContent> parent = GetCurrentContent();
     971             : 
     972         141 :   result = PushContent(content);
     973         141 :   NS_ENSURE_SUCCESS(result, result);
     974             : 
     975             :   // Set the attributes on the new content element
     976         141 :   result = AddAttributes(aAtts, content);
     977             : 
     978         141 :   if (NS_OK == result) {
     979             :     // Store the element
     980         141 :     if (!SetDocElement(nameSpaceID, localName, content) && appendContent) {
     981         119 :       NS_ENSURE_TRUE(parent, NS_ERROR_UNEXPECTED);
     982             : 
     983         119 :       parent->AppendChildTo(content, false);
     984             :     }
     985             :   }
     986             : 
     987             :   // Some HTML nodes need DoneCreatingElement() called to initialize
     988             :   // properly (eg form state restoration).
     989         141 :   if (nodeInfo->NamespaceID() == kNameSpaceID_XHTML) {
     990           6 :     if (nodeInfo->NameAtom() == nsGkAtoms::input ||
     991           4 :         nodeInfo->NameAtom() == nsGkAtoms::button ||
     992           4 :         nodeInfo->NameAtom() == nsGkAtoms::menuitem ||
     993           6 :         nodeInfo->NameAtom() == nsGkAtoms::audio ||
     994           2 :         nodeInfo->NameAtom() == nsGkAtoms::video) {
     995           0 :       content->DoneCreatingElement();
     996           2 :     } else if (nodeInfo->NameAtom() == nsGkAtoms::head && !mCurrentHead) {
     997           0 :       mCurrentHead = content;
     998             :     }
     999             :   }
    1000             : 
    1001         141 :   if (IsMonolithicContainer(nodeInfo)) {
    1002           0 :     mInMonolithicContainer++;
    1003             :   }
    1004             : 
    1005         141 :   if (content != mDocElement && !mCurrentHead) {
    1006             :     // This isn't the root and we're not inside an XHTML <head>.
    1007             :     // Might need to start layout
    1008         119 :     MaybeStartLayout(false);
    1009             :   }
    1010             : 
    1011         141 :   if (content == mDocElement) {
    1012          22 :     NotifyDocElementCreated(mDocument);
    1013             : 
    1014          22 :     if (aInterruptable && NS_SUCCEEDED(result) && mParser && !mParser->IsParserEnabled()) {
    1015           0 :       return NS_ERROR_HTMLPARSER_BLOCK;
    1016             :     }
    1017             :   }
    1018             : 
    1019         141 :   return aInterruptable && NS_SUCCEEDED(result) ? DidProcessATokenImpl() :
    1020         141 :                                                   result;
    1021             : }
    1022             : 
    1023             : NS_IMETHODIMP
    1024         141 : nsXMLContentSink::HandleEndElement(const char16_t *aName)
    1025             : {
    1026         141 :   return HandleEndElement(aName, true);
    1027             : }
    1028             : 
    1029             : nsresult
    1030         141 : nsXMLContentSink::HandleEndElement(const char16_t *aName,
    1031             :                                    bool aInterruptable)
    1032             : {
    1033         141 :   nsresult result = NS_OK;
    1034             : 
    1035             :   // XXX Hopefully the parser will flag this before we get
    1036             :   // here. If we're in the prolog or epilog, there should be
    1037             :   // no close tags for elements.
    1038         141 :   MOZ_ASSERT(eXMLContentSinkState_InDocumentElement == mState);
    1039             : 
    1040         141 :   FlushText();
    1041             : 
    1042         141 :   StackNode* sn = GetCurrentStackNode();
    1043         141 :   if (!sn) {
    1044           0 :     return NS_ERROR_UNEXPECTED;
    1045             :   }
    1046             : 
    1047         282 :   nsCOMPtr<nsIContent> content;
    1048         141 :   sn->mContent.swap(content);
    1049         141 :   uint32_t numFlushed = sn->mNumFlushed;
    1050             : 
    1051         141 :   PopContent();
    1052         141 :   NS_ASSERTION(content, "failed to pop content");
    1053             : #ifdef DEBUG
    1054             :   // Check that we're closing the right thing
    1055         282 :   nsCOMPtr<nsIAtom> debugNameSpacePrefix, debugTagAtom;
    1056             :   int32_t debugNameSpaceID;
    1057         282 :   nsContentUtils::SplitExpatName(aName, getter_AddRefs(debugNameSpacePrefix),
    1058         282 :                                  getter_AddRefs(debugTagAtom),
    1059         141 :                                  &debugNameSpaceID);
    1060             :   // Check if we are closing a template element because template
    1061             :   // elements do not get pushed on the stack, the template
    1062             :   // element content is pushed instead.
    1063         141 :   bool isTemplateElement = debugTagAtom == nsGkAtoms::_template &&
    1064         141 :                            debugNameSpaceID == kNameSpaceID_XHTML;
    1065         141 :   NS_ASSERTION(content->NodeInfo()->Equals(debugTagAtom, debugNameSpaceID) ||
    1066             :                (debugNameSpaceID == kNameSpaceID_MathML &&
    1067             :                 content->NodeInfo()->NamespaceID() == kNameSpaceID_disabled_MathML &&
    1068             :                 content->NodeInfo()->Equals(debugTagAtom)) ||
    1069             :                (debugNameSpaceID == kNameSpaceID_SVG &&
    1070             :                 content->NodeInfo()->NamespaceID() == kNameSpaceID_disabled_SVG &&
    1071             :                 content->NodeInfo()->Equals(debugTagAtom)) ||
    1072             :                isTemplateElement, "Wrong element being closed");
    1073             : #endif
    1074             : 
    1075         141 :   result = CloseElement(content);
    1076             : 
    1077         141 :   if (mCurrentHead == content) {
    1078           0 :     mCurrentHead = nullptr;
    1079             :   }
    1080             : 
    1081         141 :   if (mDocElement == content) {
    1082             :     // XXXbz for roots that don't want to be appended on open, we
    1083             :     // probably need to deal here.... (and stop appending them on open).
    1084          22 :     mState = eXMLContentSinkState_InEpilog;
    1085             : 
    1086             :     // We might have had no occasion to start layout yet.  Do so now.
    1087          22 :     MaybeStartLayout(false);
    1088             :   }
    1089             : 
    1090         141 :   int32_t stackLen = mContentStack.Length();
    1091         141 :   if (mNotifyLevel >= stackLen) {
    1092          42 :     if (numFlushed < content->GetChildCount()) {
    1093          27 :       NotifyAppend(content, numFlushed);
    1094             :     }
    1095          42 :     mNotifyLevel = stackLen - 1;
    1096             :   }
    1097         141 :   DidAddContent();
    1098             : 
    1099         141 :   if (content->IsSVGElement(nsGkAtoms::svg)) {
    1100          21 :     FlushTags();
    1101          63 :     nsCOMPtr<nsIRunnable> event = new nsHtml5SVGLoadDispatcher(content);
    1102          21 :     if (NS_FAILED(content->OwnerDoc()->Dispatch("nsHtml5SVGLoadDispatcher",
    1103             :                                                 TaskCategory::Other,
    1104             :                                                 event.forget()))) {
    1105           0 :       NS_WARNING("failed to dispatch svg load dispatcher");
    1106             :     }
    1107             :   }
    1108             : 
    1109         141 :   return aInterruptable && NS_SUCCEEDED(result) ? DidProcessATokenImpl() :
    1110         141 :                                                   result;
    1111             : }
    1112             : 
    1113             : NS_IMETHODIMP
    1114          23 : nsXMLContentSink::HandleComment(const char16_t *aName)
    1115             : {
    1116          23 :   FlushText();
    1117             : 
    1118          69 :   RefPtr<Comment> comment = new Comment(mNodeInfoManager);
    1119          23 :   comment->SetText(nsDependentString(aName), false);
    1120          23 :   nsresult rv = AddContentAsLeaf(comment);
    1121          23 :   DidAddContent();
    1122             : 
    1123          46 :   return NS_SUCCEEDED(rv) ? DidProcessATokenImpl() : rv;
    1124             : }
    1125             : 
    1126             : NS_IMETHODIMP
    1127           0 : nsXMLContentSink::HandleCDataSection(const char16_t *aData,
    1128             :                                      uint32_t aLength)
    1129             : {
    1130             :   // XSLT doesn't differentiate between text and cdata and wants adjacent
    1131             :   // textnodes merged, so add as text.
    1132           0 :   if (mXSLTProcessor) {
    1133           0 :     return AddText(aData, aLength);
    1134             :   }
    1135             : 
    1136           0 :   FlushText();
    1137             : 
    1138           0 :   RefPtr<CDATASection> cdata = new CDATASection(mNodeInfoManager);
    1139           0 :   cdata->SetText(aData, aLength, false);
    1140           0 :   nsresult rv = AddContentAsLeaf(cdata);
    1141           0 :   DidAddContent();
    1142             : 
    1143           0 :   return NS_SUCCEEDED(rv) ? DidProcessATokenImpl() : rv;
    1144             : }
    1145             : 
    1146             : NS_IMETHODIMP
    1147           0 : nsXMLContentSink::HandleDoctypeDecl(const nsAString & aSubset,
    1148             :                                     const nsAString & aName,
    1149             :                                     const nsAString & aSystemId,
    1150             :                                     const nsAString & aPublicId,
    1151             :                                     nsISupports* aCatalogData)
    1152             : {
    1153           0 :   FlushText();
    1154             : 
    1155           0 :   nsresult rv = NS_OK;
    1156             : 
    1157           0 :   NS_ASSERTION(mDocument, "Shouldn't get here from a document fragment");
    1158             : 
    1159           0 :   nsCOMPtr<nsIAtom> name = NS_Atomize(aName);
    1160           0 :   NS_ENSURE_TRUE(name, NS_ERROR_OUT_OF_MEMORY);
    1161             : 
    1162             :   // Create a new doctype node
    1163           0 :   nsCOMPtr<nsIDOMDocumentType> docType;
    1164           0 :   rv = NS_NewDOMDocumentType(getter_AddRefs(docType), mNodeInfoManager,
    1165           0 :                              name, aPublicId, aSystemId, aSubset);
    1166           0 :   if (NS_FAILED(rv) || !docType) {
    1167           0 :     return rv;
    1168             :   }
    1169             : 
    1170           0 :   MOZ_ASSERT(!aCatalogData, "Need to add back support for catalog style "
    1171             :                             "sheets");
    1172             : 
    1173           0 :   nsCOMPtr<nsIContent> content = do_QueryInterface(docType);
    1174           0 :   NS_ASSERTION(content, "doctype isn't content?");
    1175             : 
    1176           0 :   rv = mDocument->AppendChildTo(content, false);
    1177           0 :   DidAddContent();
    1178           0 :   return NS_SUCCEEDED(rv) ? DidProcessATokenImpl() : rv;
    1179             : }
    1180             : 
    1181             : NS_IMETHODIMP
    1182         533 : nsXMLContentSink::HandleCharacterData(const char16_t *aData,
    1183             :                                       uint32_t aLength)
    1184             : {
    1185         533 :   return HandleCharacterData(aData, aLength, true);
    1186             : }
    1187             : 
    1188             : nsresult
    1189         533 : nsXMLContentSink::HandleCharacterData(const char16_t *aData, uint32_t aLength,
    1190             :                                       bool aInterruptable)
    1191             : {
    1192         533 :   nsresult rv = NS_OK;
    1193        1038 :   if (aData && mState != eXMLContentSinkState_InProlog &&
    1194         505 :       mState != eXMLContentSinkState_InEpilog) {
    1195         483 :     rv = AddText(aData, aLength);
    1196             :   }
    1197         533 :   return aInterruptable && NS_SUCCEEDED(rv) ? DidProcessATokenImpl() : rv;
    1198             : }
    1199             : 
    1200             : NS_IMETHODIMP
    1201           0 : nsXMLContentSink::HandleProcessingInstruction(const char16_t *aTarget,
    1202             :                                               const char16_t *aData)
    1203             : {
    1204           0 :   FlushText();
    1205             : 
    1206           0 :   const nsDependentString target(aTarget);
    1207           0 :   const nsDependentString data(aData);
    1208             : 
    1209             :   nsCOMPtr<nsIContent> node =
    1210           0 :     NS_NewXMLProcessingInstruction(mNodeInfoManager, target, data);
    1211             : 
    1212           0 :   nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(node));
    1213           0 :   if (ssle) {
    1214           0 :     ssle->InitStyleLinkElement(false);
    1215           0 :     ssle->SetEnableUpdates(false);
    1216           0 :     mPrettyPrintXML = false;
    1217             :   }
    1218             : 
    1219           0 :   nsresult rv = AddContentAsLeaf(node);
    1220           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1221           0 :   DidAddContent();
    1222             : 
    1223           0 :   if (ssle) {
    1224             :     // This is an xml-stylesheet processing instruction... but it might not be
    1225             :     // a CSS one if the type is set to something else.
    1226           0 :     ssle->SetEnableUpdates(true);
    1227             :     bool willNotify;
    1228             :     bool isAlternate;
    1229           0 :     rv = ssle->UpdateStyleSheet(mRunsToCompletion ? nullptr : this,
    1230             :                                 &willNotify,
    1231           0 :                                 &isAlternate);
    1232           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1233             : 
    1234           0 :     if (willNotify) {
    1235             :       // Successfully started a stylesheet load
    1236           0 :       if (!isAlternate && !mRunsToCompletion) {
    1237           0 :         ++mPendingSheetCount;
    1238           0 :         mScriptLoader->AddParserBlockingScriptExecutionBlocker();
    1239             :       }
    1240             : 
    1241           0 :       return NS_OK;
    1242             :     }
    1243             :   }
    1244             : 
    1245             :   // If it's not a CSS stylesheet PI...
    1246           0 :   nsAutoString type;
    1247           0 :   nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::type, type);
    1248             : 
    1249           0 :   if (mState != eXMLContentSinkState_InProlog ||
    1250           0 :       !target.EqualsLiteral("xml-stylesheet") ||
    1251           0 :       type.IsEmpty()                          ||
    1252           0 :       type.LowerCaseEqualsLiteral("text/css")) {
    1253           0 :     return DidProcessATokenImpl();
    1254             :   }
    1255             : 
    1256           0 :   nsAutoString href, title, media;
    1257           0 :   bool isAlternate = false;
    1258             : 
    1259             :   // If there was no href, we can't do anything with this PI
    1260           0 :   if (!ParsePIData(data, href, title, media, isAlternate)) {
    1261           0 :       return DidProcessATokenImpl();
    1262             :   }
    1263             : 
    1264           0 :   rv = ProcessStyleLink(node, href, isAlternate, title, type, media);
    1265           0 :   return NS_SUCCEEDED(rv) ? DidProcessATokenImpl() : rv;
    1266             : }
    1267             : 
    1268             : /* static */
    1269             : bool
    1270           0 : nsXMLContentSink::ParsePIData(const nsString &aData, nsString &aHref,
    1271             :                               nsString &aTitle, nsString &aMedia,
    1272             :                               bool &aIsAlternate)
    1273             : {
    1274             :   // If there was no href, we can't do anything with this PI
    1275           0 :   if (!nsContentUtils::GetPseudoAttributeValue(aData, nsGkAtoms::href, aHref)) {
    1276           0 :     return false;
    1277             :   }
    1278             : 
    1279           0 :   nsContentUtils::GetPseudoAttributeValue(aData, nsGkAtoms::title, aTitle);
    1280             : 
    1281           0 :   nsContentUtils::GetPseudoAttributeValue(aData, nsGkAtoms::media, aMedia);
    1282             : 
    1283           0 :   nsAutoString alternate;
    1284             :   nsContentUtils::GetPseudoAttributeValue(aData,
    1285             :                                           nsGkAtoms::alternate,
    1286           0 :                                           alternate);
    1287             : 
    1288           0 :   aIsAlternate = alternate.EqualsLiteral("yes");
    1289             : 
    1290           0 :   return true;
    1291             : }
    1292             : 
    1293             : NS_IMETHODIMP
    1294           4 : nsXMLContentSink::HandleXMLDeclaration(const char16_t *aVersion,
    1295             :                                        const char16_t *aEncoding,
    1296             :                                        int32_t aStandalone)
    1297             : {
    1298           4 :   mDocument->SetXMLDeclaration(aVersion, aEncoding, aStandalone);
    1299             : 
    1300           4 :   return DidProcessATokenImpl();
    1301             : }
    1302             : 
    1303             : NS_IMETHODIMP
    1304           0 : nsXMLContentSink::ReportError(const char16_t* aErrorText,
    1305             :                               const char16_t* aSourceText,
    1306             :                               nsIScriptError *aError,
    1307             :                               bool *_retval)
    1308             : {
    1309           0 :   NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!");
    1310           0 :   nsresult rv = NS_OK;
    1311             : 
    1312             :   // The expat driver should report the error.  We're just cleaning up the mess.
    1313           0 :   *_retval = true;
    1314             : 
    1315           0 :   mPrettyPrintXML = false;
    1316             : 
    1317           0 :   mState = eXMLContentSinkState_InProlog;
    1318             : 
    1319             :   // XXX need to stop scripts here -- hsivonen
    1320             : 
    1321             :   // stop observing in order to avoid crashing when removing content
    1322           0 :   mDocument->RemoveObserver(this);
    1323           0 :   mIsDocumentObserver = false;
    1324             : 
    1325             :   // Clear the current content
    1326           0 :   nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mDocument));
    1327           0 :   if (node) {
    1328             :     for (;;) {
    1329           0 :       nsCOMPtr<nsIDOMNode> child, dummy;
    1330           0 :       node->GetLastChild(getter_AddRefs(child));
    1331           0 :       if (!child)
    1332           0 :         break;
    1333           0 :       node->RemoveChild(child, getter_AddRefs(dummy));
    1334           0 :     }
    1335             :   }
    1336           0 :   mDocElement = nullptr;
    1337             : 
    1338             :   // Clear any buffered-up text we have.  It's enough to set the length to 0.
    1339             :   // The buffer itself is allocated when we're created and deleted in our
    1340             :   // destructor, so don't mess with it.
    1341           0 :   mTextLength = 0;
    1342             : 
    1343           0 :   if (mXSLTProcessor) {
    1344             :     // Get rid of the XSLT processor.
    1345           0 :     mXSLTProcessor->CancelLoads();
    1346           0 :     mXSLTProcessor = nullptr;
    1347             :   }
    1348             : 
    1349             :   // release the nodes on stack
    1350           0 :   mContentStack.Clear();
    1351           0 :   mNotifyLevel = 0;
    1352             : 
    1353             :   // return leaving the document empty if we're asked to not add a <parsererror> root node
    1354           0 :   if (mDocument->SuppressParserErrorElement()) {
    1355           0 :     return NS_OK;
    1356             :   }
    1357             : 
    1358             :   // prepare to set <parsererror> as the document root
    1359             :   rv = HandleProcessingInstruction(u"xml-stylesheet",
    1360           0 :                                    u"href=\"chrome://global/locale/intl.css\" type=\"text/css\"");
    1361           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1362             : 
    1363           0 :   const char16_t* noAtts[] = { 0, 0 };
    1364             : 
    1365           0 :   NS_NAMED_LITERAL_STRING(errorNs,
    1366             :                           "http://www.mozilla.org/newlayout/xml/parsererror.xml");
    1367             : 
    1368           0 :   nsAutoString parsererror(errorNs);
    1369           0 :   parsererror.Append((char16_t)0xFFFF);
    1370           0 :   parsererror.AppendLiteral("parsererror");
    1371             : 
    1372           0 :   rv = HandleStartElement(parsererror.get(), noAtts, 0, (uint32_t)-1,
    1373           0 :                           false);
    1374           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1375             : 
    1376           0 :   rv = HandleCharacterData(aErrorText, NS_strlen(aErrorText), false);
    1377           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1378             : 
    1379           0 :   nsAutoString sourcetext(errorNs);
    1380           0 :   sourcetext.Append((char16_t)0xFFFF);
    1381           0 :   sourcetext.AppendLiteral("sourcetext");
    1382             : 
    1383           0 :   rv = HandleStartElement(sourcetext.get(), noAtts, 0, (uint32_t)-1,
    1384           0 :                           false);
    1385           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1386             : 
    1387           0 :   rv = HandleCharacterData(aSourceText, NS_strlen(aSourceText), false);
    1388           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1389             : 
    1390           0 :   rv = HandleEndElement(sourcetext.get(), false);
    1391           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1392             : 
    1393           0 :   rv = HandleEndElement(parsererror.get(), false);
    1394           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1395             : 
    1396           0 :   FlushTags();
    1397             : 
    1398           0 :   return NS_OK;
    1399             : }
    1400             : 
    1401             : nsresult
    1402         135 : nsXMLContentSink::AddAttributes(const char16_t** aAtts,
    1403             :                                 nsIContent* aContent)
    1404             : {
    1405             :   // Add tag attributes to the content attributes
    1406         270 :   nsCOMPtr<nsIAtom> prefix, localName;
    1407         793 :   while (*aAtts) {
    1408             :     int32_t nameSpaceID;
    1409         658 :     nsContentUtils::SplitExpatName(aAtts[0], getter_AddRefs(prefix),
    1410         987 :                                    getter_AddRefs(localName), &nameSpaceID);
    1411             : 
    1412             :     // Add attribute to content
    1413         329 :     aContent->SetAttr(nameSpaceID, localName, prefix,
    1414         658 :                       nsDependentString(aAtts[1]), false);
    1415         329 :     aAtts += 2;
    1416             :   }
    1417             : 
    1418         270 :   return NS_OK;
    1419             : }
    1420             : 
    1421             : #define NS_ACCUMULATION_BUFFER_SIZE 4096
    1422             : 
    1423             : nsresult
    1424         483 : nsXMLContentSink::AddText(const char16_t* aText,
    1425             :                           int32_t aLength)
    1426             : {
    1427             :   // Copy data from string into our buffer; flush buffer when it fills up.
    1428         483 :   int32_t offset = 0;
    1429        1449 :   while (0 != aLength) {
    1430         483 :     int32_t amount = NS_ACCUMULATION_BUFFER_SIZE - mTextLength;
    1431         483 :     if (0 == amount) {
    1432           0 :       nsresult rv = FlushText(false);
    1433           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
    1434           0 :         return rv;
    1435             :       }
    1436           0 :       MOZ_ASSERT(mTextLength == 0);
    1437           0 :       amount = NS_ACCUMULATION_BUFFER_SIZE;
    1438             :     }
    1439             : 
    1440         483 :     if (amount > aLength) {
    1441         483 :       amount = aLength;
    1442             :     }
    1443         483 :     memcpy(&mText[mTextLength], &aText[offset], sizeof(char16_t) * amount);
    1444         483 :     mTextLength += amount;
    1445         483 :     offset += amount;
    1446         483 :     aLength -= amount;
    1447             :   }
    1448             : 
    1449         483 :   return NS_OK;
    1450             : }
    1451             : 
    1452             : void
    1453          57 : nsXMLContentSink::FlushPendingNotifications(FlushType aType)
    1454             : {
    1455             :   // Only flush tags if we're not doing the notification ourselves
    1456             :   // (since we aren't reentrant)
    1457          57 :   if (!mInNotification) {
    1458          57 :     if (mIsDocumentObserver) {
    1459             :       // Only flush if we're still a document observer (so that our child
    1460             :       // counts should be correct).
    1461           0 :       if (aType >= FlushType::ContentAndNotify) {
    1462           0 :         FlushTags();
    1463             :       }
    1464             :       else {
    1465           0 :         FlushText(false);
    1466             :       }
    1467             :     }
    1468          57 :     if (aType >= FlushType::EnsurePresShellInitAndFrames) {
    1469             :       // Make sure that layout has started so that the reflow flush
    1470             :       // will actually happen.
    1471           0 :       MaybeStartLayout(true);
    1472             :     }
    1473             :   }
    1474          57 : }
    1475             : 
    1476             : /**
    1477             :  * NOTE!! Forked from SinkContext. Please keep in sync.
    1478             :  *
    1479             :  * Flush all elements that have been seen so far such that
    1480             :  * they are visible in the tree. Specifically, make sure
    1481             :  * that they are all added to their respective parents.
    1482             :  * Also, do notification at the top for all content that
    1483             :  * has been newly added so that the frame tree is complete.
    1484             :  */
    1485             : nsresult
    1486          80 : nsXMLContentSink::FlushTags()
    1487             : {
    1488          80 :   mDeferredFlushTags = false;
    1489          80 :   bool oldBeganUpdate = mBeganUpdate;
    1490          80 :   uint32_t oldUpdates = mUpdatesInNotification;
    1491             : 
    1492          80 :   mUpdatesInNotification = 0;
    1493          80 :   ++mInNotification;
    1494             :   {
    1495             :     // Scope so we call EndUpdate before we decrease mInNotification
    1496         160 :     mozAutoDocUpdate updateBatch(mDocument, UPDATE_CONTENT_MODEL, true);
    1497          80 :     mBeganUpdate = true;
    1498             : 
    1499             :     // Don't release last text node in case we need to add to it again
    1500          80 :     FlushText(false);
    1501             : 
    1502             :     // Start from the base of the stack (growing downward) and do
    1503             :     // a notification from the node that is closest to the root of
    1504             :     // tree for any content that has been added.
    1505             : 
    1506             :     int32_t stackPos;
    1507          80 :     int32_t stackLen = mContentStack.Length();
    1508          80 :     bool flushed = false;
    1509             :     uint32_t childCount;
    1510             :     nsIContent* content;
    1511             : 
    1512         165 :     for (stackPos = 0; stackPos < stackLen; ++stackPos) {
    1513          85 :       content = mContentStack[stackPos].mContent;
    1514          85 :       childCount = content->GetChildCount();
    1515             : 
    1516          85 :       if (!flushed && (mContentStack[stackPos].mNumFlushed < childCount)) {
    1517          27 :         NotifyAppend(content, mContentStack[stackPos].mNumFlushed);
    1518          27 :         flushed = true;
    1519             :       }
    1520             : 
    1521          85 :       mContentStack[stackPos].mNumFlushed = childCount;
    1522             :     }
    1523          80 :     mNotifyLevel = stackLen - 1;
    1524             :   }
    1525          80 :   --mInNotification;
    1526             : 
    1527          80 :   if (mUpdatesInNotification > 1) {
    1528           0 :     UpdateChildCounts();
    1529             :   }
    1530             : 
    1531          80 :   mUpdatesInNotification = oldUpdates;
    1532          80 :   mBeganUpdate = oldBeganUpdate;
    1533             : 
    1534          80 :   return NS_OK;
    1535             : }
    1536             : 
    1537             : /**
    1538             :  * NOTE!! Forked from SinkContext. Please keep in sync.
    1539             :  */
    1540             : void
    1541          35 : nsXMLContentSink::UpdateChildCounts()
    1542             : {
    1543             :   // Start from the top of the stack (growing upwards) and see if any
    1544             :   // new content has been appended. If so, we recognize that reflows
    1545             :   // have been generated for it and we should make sure that no
    1546             :   // further reflows occur.  Note that we have to include stackPos == 0
    1547             :   // to properly notify on kids of <html>.
    1548          35 :   int32_t stackLen = mContentStack.Length();
    1549          35 :   int32_t stackPos = stackLen - 1;
    1550         117 :   while (stackPos >= 0) {
    1551          41 :     StackNode & node = mContentStack[stackPos];
    1552          41 :     node.mNumFlushed = node.mContent->GetChildCount();
    1553             : 
    1554          41 :     stackPos--;
    1555             :   }
    1556          35 :   mNotifyLevel = stackLen - 1;
    1557          35 : }
    1558             : 
    1559             : bool
    1560         282 : nsXMLContentSink::IsMonolithicContainer(mozilla::dom::NodeInfo* aNodeInfo)
    1561             : {
    1562         286 :   return ((aNodeInfo->NamespaceID() == kNameSpaceID_XHTML &&
    1563           8 :           (aNodeInfo->NameAtom() == nsGkAtoms::tr ||
    1564           8 :            aNodeInfo->NameAtom() == nsGkAtoms::select ||
    1565           8 :            aNodeInfo->NameAtom() == nsGkAtoms::object ||
    1566         568 :            aNodeInfo->NameAtom() == nsGkAtoms::applet)) ||
    1567         282 :           (aNodeInfo->NamespaceID() == kNameSpaceID_MathML &&
    1568           0 :           (aNodeInfo->NameAtom() == nsGkAtoms::math))
    1569         282 :           );
    1570             : }
    1571             : 
    1572             : void
    1573           0 : nsXMLContentSink::ContinueInterruptedParsingIfEnabled()
    1574             : {
    1575           0 :   if (mParser && mParser->IsParserEnabled()) {
    1576           0 :     GetParser()->ContinueInterruptedParsing();
    1577             :   }
    1578           0 : }
    1579             : 
    1580             : void
    1581           0 : nsXMLContentSink::ContinueInterruptedParsingAsync()
    1582             : {
    1583             :   nsCOMPtr<nsIRunnable> ev =
    1584           0 :     NewRunnableMethod("nsXMLContentSink::ContinueInterruptedParsingIfEnabled",
    1585             :                       this,
    1586           0 :                       &nsXMLContentSink::ContinueInterruptedParsingIfEnabled);
    1587             : 
    1588           0 :   NS_DispatchToCurrentThread(ev);
    1589           0 : }
    1590             : 
    1591             : nsIParser*
    1592           0 : nsXMLContentSink::GetParser()
    1593             : {
    1594           0 :   return static_cast<nsIParser*>(mParser.get());
    1595             : }

Generated by: LCOV version 1.13