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.

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

mercurial