1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/html/document/src/nsHTMLContentSink.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1163 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set sw=2 ts=2 et tw=78: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +/** 1.11 + * This file is near-OBSOLETE. It is used for about:blank only and for the 1.12 + * HTML element factory. 1.13 + * Don't bother adding new stuff in this file. 1.14 + */ 1.15 + 1.16 +#include "mozilla/ArrayUtils.h" 1.17 + 1.18 +#include "nsContentSink.h" 1.19 +#include "nsCOMPtr.h" 1.20 +#include "nsReadableUtils.h" 1.21 +#include "nsUnicharUtils.h" 1.22 +#include "nsIHTMLContentSink.h" 1.23 +#include "nsIInterfaceRequestor.h" 1.24 +#include "nsIInterfaceRequestorUtils.h" 1.25 +#include "nsScriptLoader.h" 1.26 +#include "nsIURI.h" 1.27 +#include "nsNetUtil.h" 1.28 +#include "nsIContentViewer.h" 1.29 +#include "nsIMarkupDocumentViewer.h" 1.30 +#include "nsINodeInfo.h" 1.31 +#include "nsToken.h" 1.32 +#include "nsIAppShell.h" 1.33 +#include "nsCRT.h" 1.34 +#include "prtime.h" 1.35 +#include "prlog.h" 1.36 +#include "nsNodeUtils.h" 1.37 +#include "nsIContent.h" 1.38 +#include "mozilla/dom/Element.h" 1.39 +#include "mozilla/Preferences.h" 1.40 + 1.41 +#include "nsGenericHTMLElement.h" 1.42 + 1.43 +#include "nsIDOMDocument.h" 1.44 +#include "nsIDOMDocumentType.h" 1.45 +#include "nsIScriptElement.h" 1.46 + 1.47 +#include "nsIComponentManager.h" 1.48 +#include "nsIServiceManager.h" 1.49 + 1.50 +#include "nsGkAtoms.h" 1.51 +#include "nsContentUtils.h" 1.52 +#include "nsIChannel.h" 1.53 +#include "nsIHttpChannel.h" 1.54 +#include "nsIDocShell.h" 1.55 +#include "nsIDocument.h" 1.56 +#include "nsStubDocumentObserver.h" 1.57 +#include "nsIHTMLDocument.h" 1.58 +#include "nsIDOMHTMLMapElement.h" 1.59 +#include "nsICookieService.h" 1.60 +#include "nsTArray.h" 1.61 +#include "nsIScriptSecurityManager.h" 1.62 +#include "nsIPrincipal.h" 1.63 +#include "nsTextFragment.h" 1.64 +#include "nsIScriptGlobalObject.h" 1.65 +#include "nsNameSpaceManager.h" 1.66 + 1.67 +#include "nsIParserService.h" 1.68 + 1.69 +#include "nsIStyleSheetLinkingElement.h" 1.70 +#include "nsITimer.h" 1.71 +#include "nsError.h" 1.72 +#include "nsContentPolicyUtils.h" 1.73 +#include "nsIScriptContext.h" 1.74 +#include "nsStyleLinkElement.h" 1.75 + 1.76 +#include "nsWeakReference.h" // nsHTMLElementFactory supports weak references 1.77 +#include "nsIPrompt.h" 1.78 +#include "nsLayoutCID.h" 1.79 +#include "nsIDocShellTreeItem.h" 1.80 + 1.81 +#include "nsEscape.h" 1.82 +#include "nsNodeInfoManager.h" 1.83 +#include "nsContentCreatorFunctions.h" 1.84 +#include "mozAutoDocUpdate.h" 1.85 +#include "nsTextNode.h" 1.86 + 1.87 +using namespace mozilla; 1.88 +using namespace mozilla::dom; 1.89 + 1.90 +//---------------------------------------------------------------------- 1.91 + 1.92 +typedef nsGenericHTMLElement* 1.93 + (*contentCreatorCallback)(already_AddRefed<nsINodeInfo>&&, 1.94 + FromParser aFromParser); 1.95 + 1.96 +nsGenericHTMLElement* 1.97 +NS_NewHTMLNOTUSEDElement(already_AddRefed<nsINodeInfo>&& aNodeInfo, 1.98 + FromParser aFromParser) 1.99 +{ 1.100 + NS_NOTREACHED("The element ctor should never be called"); 1.101 + return nullptr; 1.102 +} 1.103 + 1.104 +#define HTML_TAG(_tag, _classname) NS_NewHTML##_classname##Element, 1.105 +#define HTML_HTMLELEMENT_TAG(_tag) NS_NewHTMLElement, 1.106 +#define HTML_OTHER(_tag) NS_NewHTMLNOTUSEDElement, 1.107 +static const contentCreatorCallback sContentCreatorCallbacks[] = { 1.108 + NS_NewHTMLUnknownElement, 1.109 +#include "nsHTMLTagList.h" 1.110 +#undef HTML_TAG 1.111 +#undef HTML_HTMLELEMENT_TAG 1.112 +#undef HTML_OTHER 1.113 + NS_NewHTMLUnknownElement 1.114 +}; 1.115 + 1.116 +class SinkContext; 1.117 +class HTMLContentSink; 1.118 + 1.119 +/** 1.120 + * This class is near-OBSOLETE. It is used for about:blank only. 1.121 + * Don't bother adding new stuff in this file. 1.122 + */ 1.123 +class HTMLContentSink : public nsContentSink, 1.124 + public nsIHTMLContentSink 1.125 +{ 1.126 +public: 1.127 + friend class SinkContext; 1.128 + 1.129 + HTMLContentSink(); 1.130 + virtual ~HTMLContentSink(); 1.131 + 1.132 + NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW 1.133 + 1.134 + nsresult Init(nsIDocument* aDoc, nsIURI* aURI, nsISupports* aContainer, 1.135 + nsIChannel* aChannel); 1.136 + 1.137 + // nsISupports 1.138 + NS_DECL_ISUPPORTS_INHERITED 1.139 + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLContentSink, nsContentSink) 1.140 + 1.141 + // nsIContentSink 1.142 + NS_IMETHOD WillParse(void); 1.143 + NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode); 1.144 + NS_IMETHOD DidBuildModel(bool aTerminated); 1.145 + NS_IMETHOD WillInterrupt(void); 1.146 + NS_IMETHOD WillResume(void); 1.147 + NS_IMETHOD SetParser(nsParserBase* aParser); 1.148 + virtual void FlushPendingNotifications(mozFlushType aType); 1.149 + NS_IMETHOD SetDocumentCharset(nsACString& aCharset); 1.150 + virtual nsISupports *GetTarget(); 1.151 + virtual bool IsScriptExecuting(); 1.152 + 1.153 + // nsIHTMLContentSink 1.154 + NS_IMETHOD OpenContainer(ElementType aNodeType); 1.155 + NS_IMETHOD CloseContainer(ElementType aTag); 1.156 + 1.157 +protected: 1.158 + nsCOMPtr<nsIHTMLDocument> mHTMLDocument; 1.159 + 1.160 + // The maximum length of a text run 1.161 + int32_t mMaxTextRun; 1.162 + 1.163 + nsRefPtr<nsGenericHTMLElement> mRoot; 1.164 + nsRefPtr<nsGenericHTMLElement> mBody; 1.165 + nsRefPtr<nsGenericHTMLElement> mHead; 1.166 + 1.167 + nsAutoTArray<SinkContext*, 8> mContextStack; 1.168 + SinkContext* mCurrentContext; 1.169 + SinkContext* mHeadContext; 1.170 + 1.171 + // Boolean indicating whether we've seen a <head> tag that might have had 1.172 + // attributes once already. 1.173 + bool mHaveSeenHead; 1.174 + 1.175 + // Boolean indicating whether we've notified insertion of our root content 1.176 + // yet. We want to make sure to only do this once. 1.177 + bool mNotifiedRootInsertion; 1.178 + 1.179 + uint8_t mScriptEnabled : 1; 1.180 + uint8_t mFramesEnabled : 1; 1.181 + uint8_t unused : 6; // bits available if someone needs one 1.182 + 1.183 + nsINodeInfo* mNodeInfoCache[NS_HTML_TAG_MAX + 1]; 1.184 + 1.185 + nsresult FlushTags(); 1.186 + 1.187 + // Routines for tags that require special handling 1.188 + nsresult CloseHTML(); 1.189 + nsresult OpenBody(); 1.190 + nsresult CloseBody(); 1.191 + 1.192 + void CloseHeadContext(); 1.193 + 1.194 + // nsContentSink overrides 1.195 + void UpdateChildCounts(); 1.196 + 1.197 + void NotifyInsert(nsIContent* aContent, 1.198 + nsIContent* aChildContent, 1.199 + int32_t aIndexInContainer); 1.200 + void NotifyRootInsertion(); 1.201 +}; 1.202 + 1.203 +class SinkContext 1.204 +{ 1.205 +public: 1.206 + SinkContext(HTMLContentSink* aSink); 1.207 + ~SinkContext(); 1.208 + 1.209 + nsresult Begin(nsHTMLTag aNodeType, nsGenericHTMLElement* aRoot, 1.210 + uint32_t aNumFlushed, int32_t aInsertionPoint); 1.211 + nsresult OpenBody(); 1.212 + nsresult CloseBody(); 1.213 + nsresult End(); 1.214 + 1.215 + nsresult GrowStack(); 1.216 + nsresult FlushTags(); 1.217 + 1.218 + bool IsCurrentContainer(nsHTMLTag mType); 1.219 + 1.220 + void DidAddContent(nsIContent* aContent); 1.221 + void UpdateChildCounts(); 1.222 + 1.223 +private: 1.224 + // Function to check whether we've notified for the current content. 1.225 + // What this actually does is check whether we've notified for all 1.226 + // of the parent's kids. 1.227 + bool HaveNotifiedForCurrentContent() const; 1.228 + 1.229 +public: 1.230 + HTMLContentSink* mSink; 1.231 + int32_t mNotifyLevel; 1.232 + 1.233 + struct Node { 1.234 + nsHTMLTag mType; 1.235 + nsGenericHTMLElement* mContent; 1.236 + uint32_t mNumFlushed; 1.237 + int32_t mInsertionPoint; 1.238 + 1.239 + nsIContent *Add(nsIContent *child); 1.240 + }; 1.241 + 1.242 + Node* mStack; 1.243 + int32_t mStackSize; 1.244 + int32_t mStackPos; 1.245 +}; 1.246 + 1.247 +nsresult 1.248 +NS_NewHTMLElement(Element** aResult, already_AddRefed<nsINodeInfo>&& aNodeInfo, 1.249 + FromParser aFromParser) 1.250 +{ 1.251 + *aResult = nullptr; 1.252 + 1.253 + nsCOMPtr<nsINodeInfo> nodeInfo = aNodeInfo; 1.254 + 1.255 + nsIParserService* parserService = nsContentUtils::GetParserService(); 1.256 + if (!parserService) 1.257 + return NS_ERROR_OUT_OF_MEMORY; 1.258 + 1.259 + nsIAtom *name = nodeInfo->NameAtom(); 1.260 + 1.261 + NS_ASSERTION(nodeInfo->NamespaceEquals(kNameSpaceID_XHTML), 1.262 + "Trying to HTML elements that don't have the XHTML namespace"); 1.263 + 1.264 + // Per the Custom Element specification, unknown tags that are valid custom 1.265 + // element names should be HTMLElement instead of HTMLUnknownElement. 1.266 + int32_t tag = parserService->HTMLCaseSensitiveAtomTagToId(name); 1.267 + if (tag == eHTMLTag_userdefined && 1.268 + nsContentUtils::IsCustomElementName(name)) { 1.269 + nsIDocument* doc = nodeInfo->GetDocument(); 1.270 + 1.271 + NS_IF_ADDREF(*aResult = NS_NewHTMLElement(nodeInfo.forget(), aFromParser)); 1.272 + if (!*aResult) { 1.273 + return NS_ERROR_OUT_OF_MEMORY; 1.274 + } 1.275 + 1.276 + // Element may be unresolved at this point. 1.277 + doc->RegisterUnresolvedElement(*aResult); 1.278 + 1.279 + // Try to enqueue a created callback. The custom element data will be set 1.280 + // and created callback will be enqueued if the custom element type 1.281 + // has already been registered. 1.282 + doc->EnqueueLifecycleCallback(nsIDocument::eCreated, *aResult); 1.283 + 1.284 + return NS_OK; 1.285 + } 1.286 + 1.287 + *aResult = CreateHTMLElement(tag, 1.288 + nodeInfo.forget(), aFromParser).take(); 1.289 + return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.290 +} 1.291 + 1.292 +already_AddRefed<nsGenericHTMLElement> 1.293 +CreateHTMLElement(uint32_t aNodeType, 1.294 + already_AddRefed<nsINodeInfo>&& aNodeInfo, 1.295 + FromParser aFromParser) 1.296 +{ 1.297 + NS_ASSERTION(aNodeType <= NS_HTML_TAG_MAX || 1.298 + aNodeType == eHTMLTag_userdefined, 1.299 + "aNodeType is out of bounds"); 1.300 + 1.301 + contentCreatorCallback cb = sContentCreatorCallbacks[aNodeType]; 1.302 + 1.303 + NS_ASSERTION(cb != NS_NewHTMLNOTUSEDElement, 1.304 + "Don't know how to construct tag element!"); 1.305 + 1.306 + nsRefPtr<nsGenericHTMLElement> result = cb(Move(aNodeInfo), aFromParser); 1.307 + 1.308 + return result.forget(); 1.309 +} 1.310 + 1.311 +//---------------------------------------------------------------------- 1.312 + 1.313 +SinkContext::SinkContext(HTMLContentSink* aSink) 1.314 + : mSink(aSink), 1.315 + mNotifyLevel(0), 1.316 + mStack(nullptr), 1.317 + mStackSize(0), 1.318 + mStackPos(0) 1.319 +{ 1.320 + MOZ_COUNT_CTOR(SinkContext); 1.321 +} 1.322 + 1.323 +SinkContext::~SinkContext() 1.324 +{ 1.325 + MOZ_COUNT_DTOR(SinkContext); 1.326 + 1.327 + if (mStack) { 1.328 + for (int32_t i = 0; i < mStackPos; i++) { 1.329 + NS_RELEASE(mStack[i].mContent); 1.330 + } 1.331 + delete [] mStack; 1.332 + } 1.333 +} 1.334 + 1.335 +nsresult 1.336 +SinkContext::Begin(nsHTMLTag aNodeType, 1.337 + nsGenericHTMLElement* aRoot, 1.338 + uint32_t aNumFlushed, 1.339 + int32_t aInsertionPoint) 1.340 +{ 1.341 + if (mStackSize < 1) { 1.342 + nsresult rv = GrowStack(); 1.343 + if (NS_FAILED(rv)) { 1.344 + return rv; 1.345 + } 1.346 + } 1.347 + 1.348 + mStack[0].mType = aNodeType; 1.349 + mStack[0].mContent = aRoot; 1.350 + mStack[0].mNumFlushed = aNumFlushed; 1.351 + mStack[0].mInsertionPoint = aInsertionPoint; 1.352 + NS_ADDREF(aRoot); 1.353 + mStackPos = 1; 1.354 + 1.355 + return NS_OK; 1.356 +} 1.357 + 1.358 +bool 1.359 +SinkContext::IsCurrentContainer(nsHTMLTag aTag) 1.360 +{ 1.361 + if (aTag == mStack[mStackPos - 1].mType) { 1.362 + return true; 1.363 + } 1.364 + 1.365 + return false; 1.366 +} 1.367 + 1.368 +void 1.369 +SinkContext::DidAddContent(nsIContent* aContent) 1.370 +{ 1.371 + if ((mStackPos == 2) && (mSink->mBody == mStack[1].mContent)) { 1.372 + // We just finished adding something to the body 1.373 + mNotifyLevel = 0; 1.374 + } 1.375 + 1.376 + // If we just added content to a node for which 1.377 + // an insertion happen, we need to do an immediate 1.378 + // notification for that insertion. 1.379 + if (0 < mStackPos && 1.380 + mStack[mStackPos - 1].mInsertionPoint != -1 && 1.381 + mStack[mStackPos - 1].mNumFlushed < 1.382 + mStack[mStackPos - 1].mContent->GetChildCount()) { 1.383 + nsIContent* parent = mStack[mStackPos - 1].mContent; 1.384 + int32_t childIndex = mStack[mStackPos - 1].mInsertionPoint - 1; 1.385 + NS_ASSERTION(parent->GetChildAt(childIndex) == aContent, 1.386 + "Flushing the wrong child."); 1.387 + mSink->NotifyInsert(parent, aContent, childIndex); 1.388 + mStack[mStackPos - 1].mNumFlushed = parent->GetChildCount(); 1.389 + } else if (mSink->IsTimeToNotify()) { 1.390 + FlushTags(); 1.391 + } 1.392 +} 1.393 + 1.394 +nsresult 1.395 +SinkContext::OpenBody() 1.396 +{ 1.397 + if (mStackPos <= 0) { 1.398 + NS_ERROR("container w/o parent"); 1.399 + 1.400 + return NS_ERROR_FAILURE; 1.401 + } 1.402 + 1.403 + nsresult rv; 1.404 + if (mStackPos + 1 > mStackSize) { 1.405 + rv = GrowStack(); 1.406 + if (NS_FAILED(rv)) { 1.407 + return rv; 1.408 + } 1.409 + } 1.410 + 1.411 + nsCOMPtr<nsINodeInfo> nodeInfo = 1.412 + mSink->mNodeInfoManager->GetNodeInfo(nsGkAtoms::body, nullptr, 1.413 + kNameSpaceID_XHTML, 1.414 + nsIDOMNode::ELEMENT_NODE); 1.415 + NS_ENSURE_TRUE(nodeInfo, NS_ERROR_UNEXPECTED); 1.416 + 1.417 + // Make the content object 1.418 + nsRefPtr<nsGenericHTMLElement> body = 1.419 + NS_NewHTMLBodyElement(nodeInfo.forget(), FROM_PARSER_NETWORK); 1.420 + if (!body) { 1.421 + return NS_ERROR_OUT_OF_MEMORY; 1.422 + } 1.423 + 1.424 + mStack[mStackPos].mType = eHTMLTag_body; 1.425 + body.forget(&mStack[mStackPos].mContent); 1.426 + mStack[mStackPos].mNumFlushed = 0; 1.427 + mStack[mStackPos].mInsertionPoint = -1; 1.428 + ++mStackPos; 1.429 + mStack[mStackPos - 2].Add(mStack[mStackPos - 1].mContent); 1.430 + 1.431 + return NS_OK; 1.432 +} 1.433 + 1.434 +bool 1.435 +SinkContext::HaveNotifiedForCurrentContent() const 1.436 +{ 1.437 + if (0 < mStackPos) { 1.438 + nsIContent* parent = mStack[mStackPos - 1].mContent; 1.439 + return mStack[mStackPos-1].mNumFlushed == parent->GetChildCount(); 1.440 + } 1.441 + 1.442 + return true; 1.443 +} 1.444 + 1.445 +nsIContent * 1.446 +SinkContext::Node::Add(nsIContent *child) 1.447 +{ 1.448 + NS_ASSERTION(mContent, "No parent to insert/append into!"); 1.449 + if (mInsertionPoint != -1) { 1.450 + NS_ASSERTION(mNumFlushed == mContent->GetChildCount(), 1.451 + "Inserting multiple children without flushing."); 1.452 + mContent->InsertChildAt(child, mInsertionPoint++, false); 1.453 + } else { 1.454 + mContent->AppendChildTo(child, false); 1.455 + } 1.456 + return child; 1.457 +} 1.458 + 1.459 +nsresult 1.460 +SinkContext::CloseBody() 1.461 +{ 1.462 + NS_ASSERTION(mStackPos > 0, 1.463 + "stack out of bounds. wrong context probably!"); 1.464 + 1.465 + if (mStackPos <= 0) { 1.466 + return NS_OK; // Fix crash - Ref. bug 45975 or 45007 1.467 + } 1.468 + 1.469 + --mStackPos; 1.470 + NS_ASSERTION(mStack[mStackPos].mType == eHTMLTag_body, 1.471 + "Tag mismatch. Closing tag on wrong context or something?"); 1.472 + 1.473 + nsGenericHTMLElement* content = mStack[mStackPos].mContent; 1.474 + 1.475 + content->Compact(); 1.476 + 1.477 + // If we're in a state where we do append notifications as 1.478 + // we go up the tree, and we're at the level where the next 1.479 + // notification needs to be done, do the notification. 1.480 + if (mNotifyLevel >= mStackPos) { 1.481 + // Check to see if new content has been added after our last 1.482 + // notification 1.483 + 1.484 + if (mStack[mStackPos].mNumFlushed < content->GetChildCount()) { 1.485 + mSink->NotifyAppend(content, mStack[mStackPos].mNumFlushed); 1.486 + mStack[mStackPos].mNumFlushed = content->GetChildCount(); 1.487 + } 1.488 + 1.489 + // Indicate that notification has now happened at this level 1.490 + mNotifyLevel = mStackPos - 1; 1.491 + } 1.492 + 1.493 + DidAddContent(content); 1.494 + NS_IF_RELEASE(content); 1.495 + 1.496 + return NS_OK; 1.497 +} 1.498 + 1.499 +nsresult 1.500 +SinkContext::End() 1.501 +{ 1.502 + for (int32_t i = 0; i < mStackPos; i++) { 1.503 + NS_RELEASE(mStack[i].mContent); 1.504 + } 1.505 + 1.506 + mStackPos = 0; 1.507 + 1.508 + return NS_OK; 1.509 +} 1.510 + 1.511 +nsresult 1.512 +SinkContext::GrowStack() 1.513 +{ 1.514 + int32_t newSize = mStackSize * 2; 1.515 + if (newSize == 0) { 1.516 + newSize = 32; 1.517 + } 1.518 + 1.519 + Node* stack = new Node[newSize]; 1.520 + 1.521 + if (mStackPos != 0) { 1.522 + memcpy(stack, mStack, sizeof(Node) * mStackPos); 1.523 + delete [] mStack; 1.524 + } 1.525 + 1.526 + mStack = stack; 1.527 + mStackSize = newSize; 1.528 + 1.529 + return NS_OK; 1.530 +} 1.531 + 1.532 +/** 1.533 + * NOTE!! Forked into nsXMLContentSink. Please keep in sync. 1.534 + * 1.535 + * Flush all elements that have been seen so far such that 1.536 + * they are visible in the tree. Specifically, make sure 1.537 + * that they are all added to their respective parents. 1.538 + * Also, do notification at the top for all content that 1.539 + * has been newly added so that the frame tree is complete. 1.540 + */ 1.541 +nsresult 1.542 +SinkContext::FlushTags() 1.543 +{ 1.544 + mSink->mDeferredFlushTags = false; 1.545 + bool oldBeganUpdate = mSink->mBeganUpdate; 1.546 + uint32_t oldUpdates = mSink->mUpdatesInNotification; 1.547 + 1.548 + ++(mSink->mInNotification); 1.549 + mSink->mUpdatesInNotification = 0; 1.550 + { 1.551 + // Scope so we call EndUpdate before we decrease mInNotification 1.552 + mozAutoDocUpdate updateBatch(mSink->mDocument, UPDATE_CONTENT_MODEL, 1.553 + true); 1.554 + mSink->mBeganUpdate = true; 1.555 + 1.556 + // Start from the base of the stack (growing downward) and do 1.557 + // a notification from the node that is closest to the root of 1.558 + // tree for any content that has been added. 1.559 + 1.560 + // Note that we can start at stackPos == 0 here, because it's the caller's 1.561 + // responsibility to handle flushing interactions between contexts (see 1.562 + // HTMLContentSink::BeginContext). 1.563 + int32_t stackPos = 0; 1.564 + bool flushed = false; 1.565 + uint32_t childCount; 1.566 + nsGenericHTMLElement* content; 1.567 + 1.568 + while (stackPos < mStackPos) { 1.569 + content = mStack[stackPos].mContent; 1.570 + childCount = content->GetChildCount(); 1.571 + 1.572 + if (!flushed && (mStack[stackPos].mNumFlushed < childCount)) { 1.573 + if (mStack[stackPos].mInsertionPoint != -1) { 1.574 + // We might have popped the child off our stack already 1.575 + // but not notified on it yet, which is why we have to get it 1.576 + // directly from its parent node. 1.577 + 1.578 + int32_t childIndex = mStack[stackPos].mInsertionPoint - 1; 1.579 + nsIContent* child = content->GetChildAt(childIndex); 1.580 + // Child not on stack anymore; can't assert it's correct 1.581 + NS_ASSERTION(!(mStackPos > (stackPos + 1)) || 1.582 + (child == mStack[stackPos + 1].mContent), 1.583 + "Flushing the wrong child."); 1.584 + mSink->NotifyInsert(content, child, childIndex); 1.585 + } else { 1.586 + mSink->NotifyAppend(content, mStack[stackPos].mNumFlushed); 1.587 + } 1.588 + 1.589 + flushed = true; 1.590 + } 1.591 + 1.592 + mStack[stackPos].mNumFlushed = childCount; 1.593 + stackPos++; 1.594 + } 1.595 + mNotifyLevel = mStackPos - 1; 1.596 + } 1.597 + --(mSink->mInNotification); 1.598 + 1.599 + if (mSink->mUpdatesInNotification > 1) { 1.600 + UpdateChildCounts(); 1.601 + } 1.602 + 1.603 + mSink->mUpdatesInNotification = oldUpdates; 1.604 + mSink->mBeganUpdate = oldBeganUpdate; 1.605 + 1.606 + return NS_OK; 1.607 +} 1.608 + 1.609 +/** 1.610 + * NOTE!! Forked into nsXMLContentSink. Please keep in sync. 1.611 + */ 1.612 +void 1.613 +SinkContext::UpdateChildCounts() 1.614 +{ 1.615 + // Start from the top of the stack (growing upwards) and see if any 1.616 + // new content has been appended. If so, we recognize that reflows 1.617 + // have been generated for it and we should make sure that no 1.618 + // further reflows occur. Note that we have to include stackPos == 0 1.619 + // to properly notify on kids of <html>. 1.620 + int32_t stackPos = mStackPos - 1; 1.621 + while (stackPos >= 0) { 1.622 + Node & node = mStack[stackPos]; 1.623 + node.mNumFlushed = node.mContent->GetChildCount(); 1.624 + 1.625 + stackPos--; 1.626 + } 1.627 + 1.628 + mNotifyLevel = mStackPos - 1; 1.629 +} 1.630 + 1.631 +nsresult 1.632 +NS_NewHTMLContentSink(nsIHTMLContentSink** aResult, 1.633 + nsIDocument* aDoc, 1.634 + nsIURI* aURI, 1.635 + nsISupports* aContainer, 1.636 + nsIChannel* aChannel) 1.637 +{ 1.638 + NS_ENSURE_ARG_POINTER(aResult); 1.639 + 1.640 + nsRefPtr<HTMLContentSink> it = new HTMLContentSink(); 1.641 + 1.642 + nsresult rv = it->Init(aDoc, aURI, aContainer, aChannel); 1.643 + 1.644 + NS_ENSURE_SUCCESS(rv, rv); 1.645 + 1.646 + *aResult = it; 1.647 + NS_ADDREF(*aResult); 1.648 + 1.649 + return NS_OK; 1.650 +} 1.651 + 1.652 +HTMLContentSink::HTMLContentSink() 1.653 +{ 1.654 + // Note: operator new zeros our memory 1.655 +} 1.656 + 1.657 +HTMLContentSink::~HTMLContentSink() 1.658 +{ 1.659 + if (mNotificationTimer) { 1.660 + mNotificationTimer->Cancel(); 1.661 + } 1.662 + 1.663 + int32_t numContexts = mContextStack.Length(); 1.664 + 1.665 + if (mCurrentContext == mHeadContext && numContexts > 0) { 1.666 + // Pop off the second html context if it's not done earlier 1.667 + mContextStack.RemoveElementAt(--numContexts); 1.668 + } 1.669 + 1.670 + int32_t i; 1.671 + for (i = 0; i < numContexts; i++) { 1.672 + SinkContext* sc = mContextStack.ElementAt(i); 1.673 + if (sc) { 1.674 + sc->End(); 1.675 + if (sc == mCurrentContext) { 1.676 + mCurrentContext = nullptr; 1.677 + } 1.678 + 1.679 + delete sc; 1.680 + } 1.681 + } 1.682 + 1.683 + if (mCurrentContext == mHeadContext) { 1.684 + mCurrentContext = nullptr; 1.685 + } 1.686 + 1.687 + delete mCurrentContext; 1.688 + 1.689 + delete mHeadContext; 1.690 + 1.691 + for (i = 0; uint32_t(i) < ArrayLength(mNodeInfoCache); ++i) { 1.692 + NS_IF_RELEASE(mNodeInfoCache[i]); 1.693 + } 1.694 +} 1.695 + 1.696 +NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLContentSink) 1.697 + 1.698 +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLContentSink, nsContentSink) 1.699 + NS_IMPL_CYCLE_COLLECTION_UNLINK(mHTMLDocument) 1.700 + NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoot) 1.701 + NS_IMPL_CYCLE_COLLECTION_UNLINK(mBody) 1.702 + NS_IMPL_CYCLE_COLLECTION_UNLINK(mHead) 1.703 + for (uint32_t i = 0; i < ArrayLength(tmp->mNodeInfoCache); ++i) { 1.704 + NS_IF_RELEASE(tmp->mNodeInfoCache[i]); 1.705 + } 1.706 +NS_IMPL_CYCLE_COLLECTION_UNLINK_END 1.707 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLContentSink, 1.708 + nsContentSink) 1.709 + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHTMLDocument) 1.710 + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot) 1.711 + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBody) 1.712 + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHead) 1.713 + for (uint32_t i = 0; i < ArrayLength(tmp->mNodeInfoCache); ++i) { 1.714 + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mNodeInfoCache[i]"); 1.715 + cb.NoteXPCOMChild(tmp->mNodeInfoCache[i]); 1.716 + } 1.717 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 1.718 + 1.719 +NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLContentSink) 1.720 + NS_INTERFACE_TABLE_BEGIN 1.721 + NS_INTERFACE_TABLE_ENTRY(HTMLContentSink, nsIContentSink) 1.722 + NS_INTERFACE_TABLE_ENTRY(HTMLContentSink, nsIHTMLContentSink) 1.723 + NS_INTERFACE_TABLE_END 1.724 +NS_INTERFACE_TABLE_TAIL_INHERITING(nsContentSink) 1.725 + 1.726 +NS_IMPL_ADDREF_INHERITED(HTMLContentSink, nsContentSink) 1.727 +NS_IMPL_RELEASE_INHERITED(HTMLContentSink, nsContentSink) 1.728 + 1.729 +static bool 1.730 +IsScriptEnabled(nsIDocument *aDoc, nsIDocShell *aContainer) 1.731 +{ 1.732 + NS_ENSURE_TRUE(aDoc && aContainer, true); 1.733 + 1.734 + nsCOMPtr<nsIScriptGlobalObject> globalObject = 1.735 + do_QueryInterface(aDoc->GetInnerWindow()); 1.736 + 1.737 + // Getting context is tricky if the document hasn't had its 1.738 + // GlobalObject set yet 1.739 + if (!globalObject) { 1.740 + globalObject = aContainer->GetScriptGlobalObject(); 1.741 + } 1.742 + 1.743 + NS_ENSURE_TRUE(globalObject && globalObject->GetGlobalJSObject(), true); 1.744 + return nsContentUtils::GetSecurityManager()-> 1.745 + ScriptAllowed(globalObject->GetGlobalJSObject()); 1.746 +} 1.747 + 1.748 +nsresult 1.749 +HTMLContentSink::Init(nsIDocument* aDoc, 1.750 + nsIURI* aURI, 1.751 + nsISupports* aContainer, 1.752 + nsIChannel* aChannel) 1.753 +{ 1.754 + NS_ENSURE_TRUE(aContainer, NS_ERROR_NULL_POINTER); 1.755 + 1.756 + nsresult rv = nsContentSink::Init(aDoc, aURI, aContainer, aChannel); 1.757 + if (NS_FAILED(rv)) { 1.758 + return rv; 1.759 + } 1.760 + 1.761 + aDoc->AddObserver(this); 1.762 + mIsDocumentObserver = true; 1.763 + mHTMLDocument = do_QueryInterface(aDoc); 1.764 + 1.765 + NS_ASSERTION(mDocShell, "oops no docshell!"); 1.766 + 1.767 + // Find out if subframes are enabled 1.768 + if (mDocShell) { 1.769 + bool subFramesEnabled = true; 1.770 + mDocShell->GetAllowSubframes(&subFramesEnabled); 1.771 + if (subFramesEnabled) { 1.772 + mFramesEnabled = true; 1.773 + } 1.774 + } 1.775 + 1.776 + // Find out if scripts are enabled, if not, show <noscript> content 1.777 + if (IsScriptEnabled(aDoc, mDocShell)) { 1.778 + mScriptEnabled = true; 1.779 + } 1.780 + 1.781 + 1.782 + // Changed from 8192 to greatly improve page loading performance on 1.783 + // large pages. See bugzilla bug 77540. 1.784 + mMaxTextRun = Preferences::GetInt("content.maxtextrun", 8191); 1.785 + 1.786 + nsCOMPtr<nsINodeInfo> nodeInfo; 1.787 + nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::html, nullptr, 1.788 + kNameSpaceID_XHTML, 1.789 + nsIDOMNode::ELEMENT_NODE); 1.790 + 1.791 + // Make root part 1.792 + mRoot = NS_NewHTMLHtmlElement(nodeInfo.forget()); 1.793 + if (!mRoot) { 1.794 + return NS_ERROR_OUT_OF_MEMORY; 1.795 + } 1.796 + 1.797 + NS_ASSERTION(mDocument->GetChildCount() == 0, 1.798 + "Document should have no kids here!"); 1.799 + rv = mDocument->AppendChildTo(mRoot, false); 1.800 + NS_ENSURE_SUCCESS(rv, rv); 1.801 + 1.802 + // Make head part 1.803 + nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::head, 1.804 + nullptr, kNameSpaceID_XHTML, 1.805 + nsIDOMNode::ELEMENT_NODE); 1.806 + 1.807 + mHead = NS_NewHTMLHeadElement(nodeInfo.forget()); 1.808 + if (NS_FAILED(rv)) { 1.809 + return NS_ERROR_OUT_OF_MEMORY; 1.810 + } 1.811 + 1.812 + mRoot->AppendChildTo(mHead, false); 1.813 + 1.814 + mCurrentContext = new SinkContext(this); 1.815 + mCurrentContext->Begin(eHTMLTag_html, mRoot, 0, -1); 1.816 + mContextStack.AppendElement(mCurrentContext); 1.817 + 1.818 + return NS_OK; 1.819 +} 1.820 + 1.821 +NS_IMETHODIMP 1.822 +HTMLContentSink::WillParse(void) 1.823 +{ 1.824 + return WillParseImpl(); 1.825 +} 1.826 + 1.827 +NS_IMETHODIMP 1.828 +HTMLContentSink::WillBuildModel(nsDTDMode aDTDMode) 1.829 +{ 1.830 + WillBuildModelImpl(); 1.831 + 1.832 + if (mHTMLDocument) { 1.833 + nsCompatibility mode = eCompatibility_NavQuirks; 1.834 + switch (aDTDMode) { 1.835 + case eDTDMode_full_standards: 1.836 + mode = eCompatibility_FullStandards; 1.837 + break; 1.838 + case eDTDMode_almost_standards: 1.839 + mode = eCompatibility_AlmostStandards; 1.840 + break; 1.841 + default: 1.842 + break; 1.843 + } 1.844 + mHTMLDocument->SetCompatibilityMode(mode); 1.845 + } 1.846 + 1.847 + // Notify document that the load is beginning 1.848 + mDocument->BeginLoad(); 1.849 + 1.850 + return NS_OK; 1.851 +} 1.852 + 1.853 +NS_IMETHODIMP 1.854 +HTMLContentSink::DidBuildModel(bool aTerminated) 1.855 +{ 1.856 + DidBuildModelImpl(aTerminated); 1.857 + 1.858 + // Reflow the last batch of content 1.859 + if (mBody) { 1.860 + mCurrentContext->FlushTags(); 1.861 + } else if (!mLayoutStarted) { 1.862 + // We never saw the body, and layout never got started. Force 1.863 + // layout *now*, to get an initial reflow. 1.864 + // NOTE: only force the layout if we are NOT destroying the 1.865 + // docshell. If we are destroying it, then starting layout will 1.866 + // likely cause us to crash, or at best waste a lot of time as we 1.867 + // are just going to tear it down anyway. 1.868 + bool bDestroying = true; 1.869 + if (mDocShell) { 1.870 + mDocShell->IsBeingDestroyed(&bDestroying); 1.871 + } 1.872 + 1.873 + if (!bDestroying) { 1.874 + StartLayout(false); 1.875 + } 1.876 + } 1.877 + 1.878 + ScrollToRef(); 1.879 + 1.880 + // Make sure we no longer respond to document mutations. We've flushed all 1.881 + // our notifications out, so there's no need to do anything else here. 1.882 + 1.883 + // XXXbz I wonder whether we could End() our contexts here too, or something, 1.884 + // just to make sure we no longer notify... Or is the mIsDocumentObserver 1.885 + // thing sufficient? 1.886 + mDocument->RemoveObserver(this); 1.887 + mIsDocumentObserver = false; 1.888 + 1.889 + mDocument->EndLoad(); 1.890 + 1.891 + DropParserAndPerfHint(); 1.892 + 1.893 + return NS_OK; 1.894 +} 1.895 + 1.896 +NS_IMETHODIMP 1.897 +HTMLContentSink::SetParser(nsParserBase* aParser) 1.898 +{ 1.899 + NS_PRECONDITION(aParser, "Should have a parser here!"); 1.900 + mParser = aParser; 1.901 + return NS_OK; 1.902 +} 1.903 + 1.904 +nsresult 1.905 +HTMLContentSink::CloseHTML() 1.906 +{ 1.907 + if (mHeadContext) { 1.908 + if (mCurrentContext == mHeadContext) { 1.909 + uint32_t numContexts = mContextStack.Length(); 1.910 + 1.911 + // Pop off the second html context if it's not done earlier 1.912 + mCurrentContext = mContextStack.ElementAt(--numContexts); 1.913 + mContextStack.RemoveElementAt(numContexts); 1.914 + } 1.915 + 1.916 + mHeadContext->End(); 1.917 + 1.918 + delete mHeadContext; 1.919 + mHeadContext = nullptr; 1.920 + } 1.921 + 1.922 + return NS_OK; 1.923 +} 1.924 + 1.925 +nsresult 1.926 +HTMLContentSink::OpenBody() 1.927 +{ 1.928 + CloseHeadContext(); // do this just in case if the HEAD was left open! 1.929 + 1.930 + // if we already have a body we're done 1.931 + if (mBody) { 1.932 + return NS_OK; 1.933 + } 1.934 + 1.935 + nsresult rv = mCurrentContext->OpenBody(); 1.936 + 1.937 + if (NS_FAILED(rv)) { 1.938 + return rv; 1.939 + } 1.940 + 1.941 + mBody = mCurrentContext->mStack[mCurrentContext->mStackPos - 1].mContent; 1.942 + 1.943 + if (mCurrentContext->mStackPos > 1) { 1.944 + int32_t parentIndex = mCurrentContext->mStackPos - 2; 1.945 + nsGenericHTMLElement *parent = mCurrentContext->mStack[parentIndex].mContent; 1.946 + int32_t numFlushed = mCurrentContext->mStack[parentIndex].mNumFlushed; 1.947 + int32_t childCount = parent->GetChildCount(); 1.948 + NS_ASSERTION(numFlushed < childCount, "Already notified on the body?"); 1.949 + 1.950 + int32_t insertionPoint = 1.951 + mCurrentContext->mStack[parentIndex].mInsertionPoint; 1.952 + 1.953 + // XXX: I have yet to see a case where numFlushed is non-zero and 1.954 + // insertionPoint is not -1, but this code will try to handle 1.955 + // those cases too. 1.956 + 1.957 + uint32_t oldUpdates = mUpdatesInNotification; 1.958 + mUpdatesInNotification = 0; 1.959 + if (insertionPoint != -1) { 1.960 + NotifyInsert(parent, mBody, insertionPoint - 1); 1.961 + } else { 1.962 + NotifyAppend(parent, numFlushed); 1.963 + } 1.964 + mCurrentContext->mStack[parentIndex].mNumFlushed = childCount; 1.965 + if (mUpdatesInNotification > 1) { 1.966 + UpdateChildCounts(); 1.967 + } 1.968 + mUpdatesInNotification = oldUpdates; 1.969 + } 1.970 + 1.971 + StartLayout(false); 1.972 + 1.973 + return NS_OK; 1.974 +} 1.975 + 1.976 +nsresult 1.977 +HTMLContentSink::CloseBody() 1.978 +{ 1.979 + // Flush out anything that's left 1.980 + mCurrentContext->FlushTags(); 1.981 + mCurrentContext->CloseBody(); 1.982 + 1.983 + return NS_OK; 1.984 +} 1.985 + 1.986 +NS_IMETHODIMP 1.987 +HTMLContentSink::OpenContainer(ElementType aElementType) 1.988 +{ 1.989 + nsresult rv = NS_OK; 1.990 + 1.991 + switch (aElementType) { 1.992 + case eBody: 1.993 + rv = OpenBody(); 1.994 + break; 1.995 + case eHTML: 1.996 + if (mRoot) { 1.997 + // If we've already hit this code once, then we're done 1.998 + if (!mNotifiedRootInsertion) { 1.999 + NotifyRootInsertion(); 1.1000 + } 1.1001 + ProcessOfflineManifest(mRoot); 1.1002 + } 1.1003 + break; 1.1004 + } 1.1005 + 1.1006 + return rv; 1.1007 +} 1.1008 + 1.1009 +NS_IMETHODIMP 1.1010 +HTMLContentSink::CloseContainer(const ElementType aTag) 1.1011 +{ 1.1012 + nsresult rv = NS_OK; 1.1013 + 1.1014 + switch (aTag) { 1.1015 + case eBody: 1.1016 + rv = CloseBody(); 1.1017 + break; 1.1018 + case eHTML: 1.1019 + rv = CloseHTML(); 1.1020 + break; 1.1021 + } 1.1022 + 1.1023 + return rv; 1.1024 +} 1.1025 + 1.1026 +NS_IMETHODIMP 1.1027 +HTMLContentSink::WillInterrupt() 1.1028 +{ 1.1029 + return WillInterruptImpl(); 1.1030 +} 1.1031 + 1.1032 +NS_IMETHODIMP 1.1033 +HTMLContentSink::WillResume() 1.1034 +{ 1.1035 + return WillResumeImpl(); 1.1036 +} 1.1037 + 1.1038 +void 1.1039 +HTMLContentSink::CloseHeadContext() 1.1040 +{ 1.1041 + if (mCurrentContext) { 1.1042 + if (!mCurrentContext->IsCurrentContainer(eHTMLTag_head)) 1.1043 + return; 1.1044 + 1.1045 + mCurrentContext->FlushTags(); 1.1046 + } 1.1047 + 1.1048 + if (!mContextStack.IsEmpty()) 1.1049 + { 1.1050 + uint32_t n = mContextStack.Length() - 1; 1.1051 + mCurrentContext = mContextStack.ElementAt(n); 1.1052 + mContextStack.RemoveElementAt(n); 1.1053 + } 1.1054 +} 1.1055 + 1.1056 +void 1.1057 +HTMLContentSink::NotifyInsert(nsIContent* aContent, 1.1058 + nsIContent* aChildContent, 1.1059 + int32_t aIndexInContainer) 1.1060 +{ 1.1061 + if (aContent && aContent->GetCurrentDoc() != mDocument) { 1.1062 + // aContent is not actually in our document anymore.... Just bail out of 1.1063 + // here; notifying on our document for this insert would be wrong. 1.1064 + return; 1.1065 + } 1.1066 + 1.1067 + mInNotification++; 1.1068 + 1.1069 + { 1.1070 + // Scope so we call EndUpdate before we decrease mInNotification 1.1071 + MOZ_AUTO_DOC_UPDATE(mDocument, UPDATE_CONTENT_MODEL, !mBeganUpdate); 1.1072 + nsNodeUtils::ContentInserted(NODE_FROM(aContent, mDocument), 1.1073 + aChildContent, aIndexInContainer); 1.1074 + mLastNotificationTime = PR_Now(); 1.1075 + } 1.1076 + 1.1077 + mInNotification--; 1.1078 +} 1.1079 + 1.1080 +void 1.1081 +HTMLContentSink::NotifyRootInsertion() 1.1082 +{ 1.1083 + NS_PRECONDITION(!mNotifiedRootInsertion, "Double-notifying on root?"); 1.1084 + NS_ASSERTION(!mLayoutStarted, 1.1085 + "How did we start layout without notifying on root?"); 1.1086 + // Now make sure to notify that we have now inserted our root. If 1.1087 + // there has been no initial reflow yet it'll be a no-op, but if 1.1088 + // there has been one we need this to get its frames constructed. 1.1089 + // Note that if mNotifiedRootInsertion is true we don't notify here, 1.1090 + // since that just means there are multiple <html> tags in the 1.1091 + // document; in those cases we just want to put all the attrs on one 1.1092 + // tag. 1.1093 + mNotifiedRootInsertion = true; 1.1094 + int32_t index = mDocument->IndexOf(mRoot); 1.1095 + NS_ASSERTION(index != -1, "mRoot not child of document?"); 1.1096 + NotifyInsert(nullptr, mRoot, index); 1.1097 + 1.1098 + // Now update the notification information in all our 1.1099 + // contexts, since we just inserted the root and notified on 1.1100 + // our whole tree 1.1101 + UpdateChildCounts(); 1.1102 +} 1.1103 + 1.1104 +void 1.1105 +HTMLContentSink::UpdateChildCounts() 1.1106 +{ 1.1107 + uint32_t numContexts = mContextStack.Length(); 1.1108 + for (uint32_t i = 0; i < numContexts; i++) { 1.1109 + SinkContext* sc = mContextStack.ElementAt(i); 1.1110 + 1.1111 + sc->UpdateChildCounts(); 1.1112 + } 1.1113 + 1.1114 + mCurrentContext->UpdateChildCounts(); 1.1115 +} 1.1116 + 1.1117 +void 1.1118 +HTMLContentSink::FlushPendingNotifications(mozFlushType aType) 1.1119 +{ 1.1120 + // Only flush tags if we're not doing the notification ourselves 1.1121 + // (since we aren't reentrant) 1.1122 + if (!mInNotification) { 1.1123 + // Only flush if we're still a document observer (so that our child counts 1.1124 + // should be correct). 1.1125 + if (mIsDocumentObserver) { 1.1126 + if (aType >= Flush_ContentAndNotify) { 1.1127 + FlushTags(); 1.1128 + } 1.1129 + } 1.1130 + if (aType >= Flush_InterruptibleLayout) { 1.1131 + // Make sure that layout has started so that the reflow flush 1.1132 + // will actually happen. 1.1133 + StartLayout(true); 1.1134 + } 1.1135 + } 1.1136 +} 1.1137 + 1.1138 +nsresult 1.1139 +HTMLContentSink::FlushTags() 1.1140 +{ 1.1141 + if (!mNotifiedRootInsertion) { 1.1142 + NotifyRootInsertion(); 1.1143 + return NS_OK; 1.1144 + } 1.1145 + 1.1146 + return mCurrentContext ? mCurrentContext->FlushTags() : NS_OK; 1.1147 +} 1.1148 + 1.1149 +NS_IMETHODIMP 1.1150 +HTMLContentSink::SetDocumentCharset(nsACString& aCharset) 1.1151 +{ 1.1152 + MOZ_ASSUME_UNREACHABLE("<meta charset> case doesn't occur with about:blank"); 1.1153 + return NS_ERROR_NOT_IMPLEMENTED; 1.1154 +} 1.1155 + 1.1156 +nsISupports * 1.1157 +HTMLContentSink::GetTarget() 1.1158 +{ 1.1159 + return mDocument; 1.1160 +} 1.1161 + 1.1162 +bool 1.1163 +HTMLContentSink::IsScriptExecuting() 1.1164 +{ 1.1165 + return IsScriptExecutingImpl(); 1.1166 +}