content/xml/document/src/nsXMLFragmentContentSink.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     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 #include "nsCOMPtr.h"
     6 #include "nsXMLContentSink.h"
     7 #include "nsIFragmentContentSink.h"
     8 #include "nsIXMLContentSink.h"
     9 #include "nsContentSink.h"
    10 #include "nsIExpatSink.h"
    11 #include "nsIDTD.h"
    12 #include "nsIDocument.h"
    13 #include "nsIDOMDocumentFragment.h"
    14 #include "nsIContent.h"
    15 #include "nsGkAtoms.h"
    16 #include "nsINodeInfo.h"
    17 #include "nsContentCreatorFunctions.h"
    18 #include "nsError.h"
    19 #include "nsIConsoleService.h"
    20 #include "nsIScriptError.h"
    21 #include "nsNetUtil.h"
    22 #include "nsTHashtable.h"
    23 #include "nsHashKeys.h"
    24 #include "nsTArray.h"
    25 #include "nsCycleCollectionParticipant.h"
    26 #include "nsIDocShell.h"
    27 #include "nsScriptLoader.h"
    28 #include "mozilla/css/Loader.h"
    29 #include "mozilla/dom/DocumentFragment.h"
    30 #include "mozilla/dom/ProcessingInstruction.h"
    32 using namespace mozilla::dom;
    34 class nsXMLFragmentContentSink : public nsXMLContentSink,
    35                                  public nsIFragmentContentSink
    36 {
    37 public:
    38   nsXMLFragmentContentSink();
    39   virtual ~nsXMLFragmentContentSink();
    41   NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
    43   // nsISupports
    44   NS_DECL_ISUPPORTS_INHERITED
    45   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsXMLFragmentContentSink,
    46                                                      nsXMLContentSink)
    48   // nsIExpatSink
    49   NS_IMETHOD HandleDoctypeDecl(const nsAString & aSubset, 
    50                                const nsAString & aName, 
    51                                const nsAString & aSystemId, 
    52                                const nsAString & aPublicId,
    53                                nsISupports* aCatalogData);
    54   NS_IMETHOD HandleProcessingInstruction(const char16_t *aTarget, 
    55                                          const char16_t *aData);
    56   NS_IMETHOD HandleXMLDeclaration(const char16_t *aVersion,
    57                                   const char16_t *aEncoding,
    58                                   int32_t aStandalone);
    59   NS_IMETHOD ReportError(const char16_t* aErrorText, 
    60                          const char16_t* aSourceText,
    61                          nsIScriptError *aError,
    62                          bool *_retval);
    64   // nsIContentSink
    65   NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode);
    66   NS_IMETHOD DidBuildModel(bool aTerminated);
    67   NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
    68   virtual nsISupports *GetTarget();
    69   NS_IMETHOD DidProcessATokenImpl();
    71   // nsIXMLContentSink
    73   // nsIFragmentContentSink
    74   NS_IMETHOD FinishFragmentParsing(nsIDOMDocumentFragment** aFragment);
    75   NS_IMETHOD SetTargetDocument(nsIDocument* aDocument);
    76   NS_IMETHOD WillBuildContent();
    77   NS_IMETHOD DidBuildContent();
    78   NS_IMETHOD IgnoreFirstContainer();
    79   NS_IMETHOD SetPreventScriptExecution(bool aPreventScriptExecution);
    81 protected:
    82   virtual bool SetDocElement(int32_t aNameSpaceID, 
    83                                nsIAtom *aTagName,
    84                                nsIContent *aContent);
    85   virtual nsresult CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
    86                                  nsINodeInfo* aNodeInfo, uint32_t aLineNumber,
    87                                  nsIContent** aResult, bool* aAppendContent,
    88                                  mozilla::dom::FromParser aFromParser);
    89   virtual nsresult CloseElement(nsIContent* aContent);
    91   virtual void MaybeStartLayout(bool aIgnorePendingSheets);
    93   // nsContentSink overrides
    94   virtual nsresult ProcessStyleLink(nsIContent* aElement,
    95                                     const nsSubstring& aHref,
    96                                     bool aAlternate,
    97                                     const nsSubstring& aTitle,
    98                                     const nsSubstring& aType,
    99                                     const nsSubstring& aMedia);
   100   nsresult LoadXSLStyleSheet(nsIURI* aUrl);
   101   void StartLayout();
   103   nsCOMPtr<nsIDocument> mTargetDocument;
   104   // the fragment
   105   nsCOMPtr<nsIContent>  mRoot;
   106   bool                  mParseError;
   107 };
   109 static nsresult
   110 NewXMLFragmentContentSinkHelper(nsIFragmentContentSink** aResult)
   111 {
   112   nsXMLFragmentContentSink* it = new nsXMLFragmentContentSink();
   114   NS_ADDREF(*aResult = it);
   116   return NS_OK;
   117 }
   119 nsresult
   120 NS_NewXMLFragmentContentSink(nsIFragmentContentSink** aResult)
   121 {
   122   return NewXMLFragmentContentSinkHelper(aResult);
   123 }
   125 nsXMLFragmentContentSink::nsXMLFragmentContentSink()
   126  : mParseError(false)
   127 {
   128   mRunsToCompletion = true;
   129 }
   131 nsXMLFragmentContentSink::~nsXMLFragmentContentSink()
   132 {
   133 }
   135 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXMLFragmentContentSink)
   136   NS_INTERFACE_MAP_ENTRY(nsIFragmentContentSink)
   137 NS_INTERFACE_MAP_END_INHERITING(nsXMLContentSink)
   139 NS_IMPL_ADDREF_INHERITED(nsXMLFragmentContentSink, nsXMLContentSink)
   140 NS_IMPL_RELEASE_INHERITED(nsXMLFragmentContentSink, nsXMLContentSink)
   142 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLFragmentContentSink)
   144 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLFragmentContentSink,
   145                                                   nsXMLContentSink)
   146   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTargetDocument)
   147   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot)
   148 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
   150 NS_IMETHODIMP 
   151 nsXMLFragmentContentSink::WillBuildModel(nsDTDMode aDTDMode)
   152 {
   153   if (mRoot) {
   154     return NS_OK;
   155   }
   157   mState = eXMLContentSinkState_InDocumentElement;
   159   NS_ASSERTION(mTargetDocument, "Need a document!");
   161   mRoot = new DocumentFragment(mNodeInfoManager);
   163   return NS_OK;
   164 }
   166 NS_IMETHODIMP 
   167 nsXMLFragmentContentSink::DidBuildModel(bool aTerminated)
   168 {
   169   nsRefPtr<nsParserBase> kungFuDeathGrip(mParser);
   171   // Drop our reference to the parser to get rid of a circular
   172   // reference.
   173   mParser = nullptr;
   175   return NS_OK;
   176 }
   178 NS_IMETHODIMP 
   179 nsXMLFragmentContentSink::SetDocumentCharset(nsACString& aCharset)
   180 {
   181   NS_NOTREACHED("fragments shouldn't set charset");
   182   return NS_OK;
   183 }
   185 nsISupports *
   186 nsXMLFragmentContentSink::GetTarget()
   187 {
   188   return mTargetDocument;
   189 }
   191 ////////////////////////////////////////////////////////////////////////
   193 bool
   194 nsXMLFragmentContentSink::SetDocElement(int32_t aNameSpaceID,
   195                                         nsIAtom* aTagName,
   196                                         nsIContent *aContent)
   197 {
   198   // this is a fragment, not a document
   199   return false;
   200 }
   202 nsresult
   203 nsXMLFragmentContentSink::CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
   204                                         nsINodeInfo* aNodeInfo, uint32_t aLineNumber,
   205                                         nsIContent** aResult, bool* aAppendContent,
   206                                         FromParser /*aFromParser*/)
   207 {
   208   // Claim to not be coming from parser, since we don't do any of the
   209   // fancy CloseElement stuff.
   210   nsresult rv = nsXMLContentSink::CreateElement(aAtts, aAttsCount,
   211                                                 aNodeInfo, aLineNumber,
   212                                                 aResult, aAppendContent,
   213                                                 NOT_FROM_PARSER);
   215   // When we aren't grabbing all of the content we, never open a doc
   216   // element, we run into trouble on the first element, so we don't append,
   217   // and simply push this onto the content stack.
   218   if (mContentStack.Length() == 0) {
   219     *aAppendContent = false;
   220   }
   222   return rv;
   223 }
   225 nsresult
   226 nsXMLFragmentContentSink::CloseElement(nsIContent* aContent)
   227 {
   228   // don't do fancy stuff in nsXMLContentSink
   229   if (mPreventScriptExecution && aContent->Tag() == nsGkAtoms::script &&
   230       (aContent->IsHTML() || aContent->IsSVG())) {
   231     nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(aContent);
   232     NS_ASSERTION(sele, "script did QI correctly!");
   233     sele->PreventExecution();
   234   }
   235   return NS_OK;
   236 }
   238 void
   239 nsXMLFragmentContentSink::MaybeStartLayout(bool aIgnorePendingSheets)
   240 {
   241   return;
   242 }
   244 ////////////////////////////////////////////////////////////////////////
   246 NS_IMETHODIMP
   247 nsXMLFragmentContentSink::HandleDoctypeDecl(const nsAString & aSubset, 
   248                                             const nsAString & aName, 
   249                                             const nsAString & aSystemId, 
   250                                             const nsAString & aPublicId,
   251                                             nsISupports* aCatalogData)
   252 {
   253   NS_NOTREACHED("fragments shouldn't have doctype declarations");
   255   return NS_OK;
   256 }
   258 NS_IMETHODIMP
   259 nsXMLFragmentContentSink::HandleProcessingInstruction(const char16_t *aTarget, 
   260                                                       const char16_t *aData)
   261 {
   262   FlushText();
   264   const nsDependentString target(aTarget);
   265   const nsDependentString data(aData);
   267   nsRefPtr<ProcessingInstruction> node =
   268     NS_NewXMLProcessingInstruction(mNodeInfoManager, target, data);
   270   // no special processing here.  that should happen when the fragment moves into the document
   271   return AddContentAsLeaf(node);
   272 }
   274 NS_IMETHODIMP
   275 nsXMLFragmentContentSink::HandleXMLDeclaration(const char16_t *aVersion,
   276                                                const char16_t *aEncoding,
   277                                                int32_t aStandalone)
   278 {
   279   NS_NOTREACHED("fragments shouldn't have XML declarations");
   280   return NS_OK;
   281 }
   283 NS_IMETHODIMP
   284 nsXMLFragmentContentSink::ReportError(const char16_t* aErrorText, 
   285                                       const char16_t* aSourceText,
   286                                       nsIScriptError *aError,
   287                                       bool *_retval)
   288 {
   289   NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!");
   291   // The expat driver should report the error.
   292   *_retval = true;
   294   mParseError = true;
   296 #ifdef DEBUG
   297   // Report the error to stderr.
   298   fprintf(stderr,
   299           "\n%s\n%s\n\n",
   300           NS_LossyConvertUTF16toASCII(aErrorText).get(),
   301           NS_LossyConvertUTF16toASCII(aSourceText).get());
   302 #endif
   304   // The following code is similar to the cleanup in nsXMLContentSink::ReportError()
   305   mState = eXMLContentSinkState_InProlog;
   307   // Clear the current content
   308   nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mRoot));
   309   if (node) {
   310     for (;;) {
   311       nsCOMPtr<nsIDOMNode> child, dummy;
   312       node->GetLastChild(getter_AddRefs(child));
   313       if (!child)
   314         break;
   315       node->RemoveChild(child, getter_AddRefs(dummy));
   316     }
   317   }
   319   // Clear any buffered-up text we have.  It's enough to set the length to 0.
   320   // The buffer itself is allocated when we're created and deleted in our
   321   // destructor, so don't mess with it.
   322   mTextLength = 0;
   324   return NS_OK; 
   325 }
   327 nsresult
   328 nsXMLFragmentContentSink::ProcessStyleLink(nsIContent* aElement,
   329                                            const nsSubstring& aHref,
   330                                            bool aAlternate,
   331                                            const nsSubstring& aTitle,
   332                                            const nsSubstring& aType,
   333                                            const nsSubstring& aMedia)
   334 {
   335   // don't process until moved to document
   336   return NS_OK;
   337 }
   339 nsresult
   340 nsXMLFragmentContentSink::LoadXSLStyleSheet(nsIURI* aUrl)
   341 {
   342   NS_NOTREACHED("fragments shouldn't have XSL style sheets");
   343   return NS_ERROR_UNEXPECTED;
   344 }
   346 void
   347 nsXMLFragmentContentSink::StartLayout()
   348 {
   349   NS_NOTREACHED("fragments shouldn't layout");
   350 }
   352 ////////////////////////////////////////////////////////////////////////
   354 NS_IMETHODIMP 
   355 nsXMLFragmentContentSink::FinishFragmentParsing(nsIDOMDocumentFragment** aFragment)
   356 {
   357   *aFragment = nullptr;
   358   mTargetDocument = nullptr;
   359   mNodeInfoManager = nullptr;
   360   mScriptLoader = nullptr;
   361   mCSSLoader = nullptr;
   362   mContentStack.Clear();
   363   mDocumentURI = nullptr;
   364   mDocShell = nullptr;
   365   mDocElement = nullptr;
   366   mCurrentHead = nullptr;
   367   if (mParseError) {
   368     //XXX PARSE_ERR from DOM3 Load and Save would be more appropriate
   369     mRoot = nullptr;
   370     mParseError = false;
   371     return NS_ERROR_DOM_SYNTAX_ERR;
   372   } else if (mRoot) {
   373     nsresult rv = CallQueryInterface(mRoot, aFragment);
   374     mRoot = nullptr;
   375     return rv;
   376   } else {
   377     return NS_OK;
   378   }
   379 }
   381 NS_IMETHODIMP
   382 nsXMLFragmentContentSink::SetTargetDocument(nsIDocument* aTargetDocument)
   383 {
   384   NS_ENSURE_ARG_POINTER(aTargetDocument);
   386   mTargetDocument = aTargetDocument;
   387   mNodeInfoManager = aTargetDocument->NodeInfoManager();
   389   return NS_OK;
   390 }
   392 NS_IMETHODIMP
   393 nsXMLFragmentContentSink::WillBuildContent()
   394 {
   395   PushContent(mRoot);
   397   return NS_OK;
   398 }
   400 NS_IMETHODIMP
   401 nsXMLFragmentContentSink::DidBuildContent()
   402 {
   403   // Note: we need to FlushText() here because if we don't, we might not get
   404   // an end element to do it for us, so make sure.
   405   if (!mParseError) {
   406     FlushText();
   407   }
   408   PopContent();
   410   return NS_OK;
   411 }
   413 NS_IMETHODIMP
   414 nsXMLFragmentContentSink::DidProcessATokenImpl()
   415 {
   416   return NS_OK;
   417 }
   419 NS_IMETHODIMP
   420 nsXMLFragmentContentSink::IgnoreFirstContainer()
   421 {
   422   NS_NOTREACHED("XML isn't as broken as HTML");
   423   return NS_ERROR_FAILURE;
   424 }
   426 NS_IMETHODIMP
   427 nsXMLFragmentContentSink::SetPreventScriptExecution(bool aPrevent)
   428 {
   429   mPreventScriptExecution = aPrevent;
   430   return NS_OK;
   431 }

mercurial