|
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 "nsScriptLoader.h" |
|
12 #include "nsIHTMLDocument.h" |
|
13 |
|
14 NS_IMPL_CYCLE_COLLECTION_INHERITED(nsHtml5DocumentBuilder, nsContentSink, |
|
15 mOwnedElements) |
|
16 |
|
17 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsHtml5DocumentBuilder) |
|
18 NS_INTERFACE_MAP_END_INHERITING(nsContentSink) |
|
19 |
|
20 NS_IMPL_ADDREF_INHERITED(nsHtml5DocumentBuilder, nsContentSink) |
|
21 NS_IMPL_RELEASE_INHERITED(nsHtml5DocumentBuilder, nsContentSink) |
|
22 |
|
23 nsHtml5DocumentBuilder::nsHtml5DocumentBuilder(bool aRunsToCompletion) |
|
24 { |
|
25 mRunsToCompletion = aRunsToCompletion; |
|
26 } |
|
27 |
|
28 nsresult |
|
29 nsHtml5DocumentBuilder::Init(nsIDocument* aDoc, |
|
30 nsIURI* aURI, |
|
31 nsISupports* aContainer, |
|
32 nsIChannel* aChannel) |
|
33 { |
|
34 return nsContentSink::Init(aDoc, aURI, aContainer, aChannel); |
|
35 } |
|
36 |
|
37 nsHtml5DocumentBuilder::~nsHtml5DocumentBuilder() |
|
38 { |
|
39 } |
|
40 |
|
41 nsresult |
|
42 nsHtml5DocumentBuilder::MarkAsBroken(nsresult aReason) |
|
43 { |
|
44 mBroken = aReason; |
|
45 return aReason; |
|
46 } |
|
47 |
|
48 void |
|
49 nsHtml5DocumentBuilder::SetDocumentCharsetAndSource(nsACString& aCharset, int32_t aCharsetSource) |
|
50 { |
|
51 if (mDocument) { |
|
52 mDocument->SetDocumentCharacterSetSource(aCharsetSource); |
|
53 mDocument->SetDocumentCharacterSet(aCharset); |
|
54 } |
|
55 } |
|
56 |
|
57 void |
|
58 nsHtml5DocumentBuilder::UpdateStyleSheet(nsIContent* aElement) |
|
59 { |
|
60 // Break out of the doc update created by Flush() to zap a runnable |
|
61 // waiting to call UpdateStyleSheet without the right observer |
|
62 EndDocUpdate(); |
|
63 |
|
64 if (MOZ_UNLIKELY(!mParser)) { |
|
65 // EndDocUpdate ran stuff that called nsIParser::Terminate() |
|
66 return; |
|
67 } |
|
68 |
|
69 nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(aElement)); |
|
70 NS_ASSERTION(ssle, "Node didn't QI to style."); |
|
71 |
|
72 ssle->SetEnableUpdates(true); |
|
73 |
|
74 bool willNotify; |
|
75 bool isAlternate; |
|
76 nsresult rv = ssle->UpdateStyleSheet(mRunsToCompletion ? nullptr : this, |
|
77 &willNotify, |
|
78 &isAlternate); |
|
79 if (NS_SUCCEEDED(rv) && willNotify && !isAlternate && !mRunsToCompletion) { |
|
80 ++mPendingSheetCount; |
|
81 mScriptLoader->AddExecuteBlocker(); |
|
82 } |
|
83 |
|
84 if (aElement->IsHTML(nsGkAtoms::link)) { |
|
85 // look for <link rel="next" href="url"> |
|
86 nsAutoString relVal; |
|
87 aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, relVal); |
|
88 if (!relVal.IsEmpty()) { |
|
89 uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(relVal); |
|
90 bool hasPrefetch = linkTypes & nsStyleLinkElement::ePREFETCH; |
|
91 if (hasPrefetch || (linkTypes & nsStyleLinkElement::eNEXT)) { |
|
92 nsAutoString hrefVal; |
|
93 aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal); |
|
94 if (!hrefVal.IsEmpty()) { |
|
95 PrefetchHref(hrefVal, aElement, hasPrefetch); |
|
96 } |
|
97 } |
|
98 if (linkTypes & nsStyleLinkElement::eDNS_PREFETCH) { |
|
99 nsAutoString hrefVal; |
|
100 aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal); |
|
101 if (!hrefVal.IsEmpty()) { |
|
102 PrefetchDNS(hrefVal); |
|
103 } |
|
104 } |
|
105 } |
|
106 } |
|
107 |
|
108 // Re-open update |
|
109 BeginDocUpdate(); |
|
110 } |
|
111 |
|
112 void |
|
113 nsHtml5DocumentBuilder::SetDocumentMode(nsHtml5DocumentMode m) |
|
114 { |
|
115 nsCompatibility mode = eCompatibility_NavQuirks; |
|
116 switch (m) { |
|
117 case STANDARDS_MODE: |
|
118 mode = eCompatibility_FullStandards; |
|
119 break; |
|
120 case ALMOST_STANDARDS_MODE: |
|
121 mode = eCompatibility_AlmostStandards; |
|
122 break; |
|
123 case QUIRKS_MODE: |
|
124 mode = eCompatibility_NavQuirks; |
|
125 break; |
|
126 } |
|
127 nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(mDocument); |
|
128 NS_ASSERTION(htmlDocument, "Document didn't QI into HTML document."); |
|
129 htmlDocument->SetCompatibilityMode(mode); |
|
130 } |
|
131 |
|
132 // nsContentSink overrides |
|
133 |
|
134 void |
|
135 nsHtml5DocumentBuilder::UpdateChildCounts() |
|
136 { |
|
137 // No-op |
|
138 } |
|
139 |
|
140 nsresult |
|
141 nsHtml5DocumentBuilder::FlushTags() |
|
142 { |
|
143 return NS_OK; |
|
144 } |