1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sw=2 et tw=78: */
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 "nsHtml5DocumentBuilder.h"
8 
9 #include "nsIStyleSheetLinkingElement.h"
10 #include "nsStyleLinkElement.h"
11 #include "nsIHTMLDocument.h"
12 #include "nsNameSpaceManager.h"
13 #include "mozilla/dom/ScriptLoader.h"
14 
NS_IMPL_CYCLE_COLLECTION_INHERITED(nsHtml5DocumentBuilder,nsContentSink,mOwnedElements)15 NS_IMPL_CYCLE_COLLECTION_INHERITED(nsHtml5DocumentBuilder, nsContentSink,
16                                    mOwnedElements)
17 
18 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsHtml5DocumentBuilder)
19 NS_INTERFACE_MAP_END_INHERITING(nsContentSink)
20 
21 NS_IMPL_ADDREF_INHERITED(nsHtml5DocumentBuilder, nsContentSink)
22 NS_IMPL_RELEASE_INHERITED(nsHtml5DocumentBuilder, nsContentSink)
23 
24 nsHtml5DocumentBuilder::nsHtml5DocumentBuilder(bool aRunsToCompletion)
25     : mBroken(NS_OK), mFlushState(eHtml5FlushState::eNotFlushing) {
26   mRunsToCompletion = aRunsToCompletion;
27 }
28 
Init(nsIDocument * aDoc,nsIURI * aURI,nsISupports * aContainer,nsIChannel * aChannel)29 nsresult nsHtml5DocumentBuilder::Init(nsIDocument* aDoc, nsIURI* aURI,
30                                       nsISupports* aContainer,
31                                       nsIChannel* aChannel) {
32   return nsContentSink::Init(aDoc, aURI, aContainer, aChannel);
33 }
34 
~nsHtml5DocumentBuilder()35 nsHtml5DocumentBuilder::~nsHtml5DocumentBuilder() {}
36 
MarkAsBroken(nsresult aReason)37 nsresult nsHtml5DocumentBuilder::MarkAsBroken(nsresult aReason) {
38   mBroken = aReason;
39   return aReason;
40 }
41 
SetDocumentCharsetAndSource(NotNull<const Encoding * > aEncoding,int32_t aCharsetSource)42 void nsHtml5DocumentBuilder::SetDocumentCharsetAndSource(
43     NotNull<const Encoding*> aEncoding, int32_t aCharsetSource) {
44   if (mDocument) {
45     mDocument->SetDocumentCharacterSetSource(aCharsetSource);
46     mDocument->SetDocumentCharacterSet(aEncoding);
47   }
48 }
49 
UpdateStyleSheet(nsIContent * aElement)50 void nsHtml5DocumentBuilder::UpdateStyleSheet(nsIContent* aElement) {
51   nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(aElement));
52   if (!ssle) {
53     MOZ_ASSERT(nsNameSpaceManager::GetInstance()->mSVGDisabled,
54                "Node didn't QI to style, but SVG wasn't disabled.");
55     return;
56   }
57 
58   // Break out of the doc update created by Flush() to zap a runnable
59   // waiting to call UpdateStyleSheet without the right observer
60   EndDocUpdate();
61 
62   if (MOZ_UNLIKELY(!mParser)) {
63     // EndDocUpdate ran stuff that called nsIParser::Terminate()
64     return;
65   }
66 
67   ssle->SetEnableUpdates(true);
68 
69   bool willNotify;
70   bool isAlternate;
71   nsresult rv = ssle->UpdateStyleSheet(mRunsToCompletion ? nullptr : this,
72                                        &willNotify, &isAlternate);
73   if (NS_SUCCEEDED(rv) && willNotify && !isAlternate && !mRunsToCompletion) {
74     ++mPendingSheetCount;
75     mScriptLoader->AddParserBlockingScriptExecutionBlocker();
76   }
77 
78   // Re-open update
79   BeginDocUpdate();
80 }
81 
SetDocumentMode(nsHtml5DocumentMode m)82 void nsHtml5DocumentBuilder::SetDocumentMode(nsHtml5DocumentMode m) {
83   nsCompatibility mode = eCompatibility_NavQuirks;
84   switch (m) {
85     case STANDARDS_MODE:
86       mode = eCompatibility_FullStandards;
87       break;
88     case ALMOST_STANDARDS_MODE:
89       mode = eCompatibility_AlmostStandards;
90       break;
91     case QUIRKS_MODE:
92       mode = eCompatibility_NavQuirks;
93       break;
94   }
95   nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(mDocument);
96   NS_ASSERTION(htmlDocument, "Document didn't QI into HTML document.");
97   htmlDocument->SetCompatibilityMode(mode);
98 }
99 
100 // nsContentSink overrides
101 
UpdateChildCounts()102 void nsHtml5DocumentBuilder::UpdateChildCounts() {
103   // No-op
104 }
105 
FlushTags()106 nsresult nsHtml5DocumentBuilder::FlushTags() { return NS_OK; }
107