1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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 #ifndef nsHTMLDocument_h___
7 #define nsHTMLDocument_h___
8
9 #include "mozilla/Attributes.h"
10 #include "nsContentList.h"
11 #include "mozilla/dom/Document.h"
12 #include "nsIHTMLCollection.h"
13 #include "nsIScriptElement.h"
14 #include "nsTArray.h"
15
16 #include "PLDHashTable.h"
17 #include "nsThreadUtils.h"
18 #include "mozilla/dom/HTMLSharedElement.h"
19 #include "mozilla/dom/BindingDeclarations.h"
20
21 class nsCommandManager;
22 class nsIURI;
23 class nsIDocShell;
24 class nsICachingChannel;
25 class nsILoadGroup;
26
27 namespace mozilla {
28 namespace dom {
29 template <typename T>
30 struct Nullable;
31 class WindowProxyHolder;
32 } // namespace dom
33 } // namespace mozilla
34
35 class nsHTMLDocument : public mozilla::dom::Document {
36 protected:
37 typedef mozilla::dom::ReferrerPolicy ReferrerPolicy;
38 typedef mozilla::dom::Document Document;
39 typedef mozilla::Encoding Encoding;
40 template <typename T>
41 using NotNull = mozilla::NotNull<T>;
42
43 public:
44 using Document::SetDocumentURI;
45
46 nsHTMLDocument();
47 virtual nsresult Init() override;
48
49 // Document
50 virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) override;
51 virtual void ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
52 nsIPrincipal* aPrincipal,
53 nsIPrincipal* aPartitionedPrincipal) override;
54
55 virtual nsresult StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
56 nsILoadGroup* aLoadGroup,
57 nsISupports* aContainer,
58 nsIStreamListener** aDocListener,
59 bool aReset = true,
60 nsIContentSink* aSink = nullptr) override;
61
62 protected:
63 virtual bool UseWidthDeviceWidthFallbackViewport() const override;
64
65 public:
66 mozilla::dom::Element* GetUnfocusedKeyEventTarget() override;
67
GetExistingForms()68 nsContentList* GetExistingForms() const { return mForms; }
69
IsPlainText()70 bool IsPlainText() const { return mIsPlainText; }
71
IsViewSource()72 bool IsViewSource() const { return mViewSource; }
73
74 // Returns whether an object was found for aName.
75 bool ResolveName(JSContext* aCx, const nsAString& aName,
76 JS::MutableHandle<JS::Value> aRetval,
77 mozilla::ErrorResult& aError);
78
79 /**
80 * Called when form->BindToTree() is called so that document knows
81 * immediately when a form is added
82 */
83 void AddedForm();
84 /**
85 * Called when form->SetDocument() is called so that document knows
86 * immediately when a form is removed
87 */
88 void RemovedForm();
89 /**
90 * Called to get a better count of forms than document.forms can provide
91 * without calling FlushPendingNotifications (bug 138892).
92 */
93 // XXXbz is this still needed now that we can flush just content,
94 // not the rest?
95 int32_t GetNumFormsSynchronous();
SetIsXHTML(bool aXHTML)96 void SetIsXHTML(bool aXHTML) { mType = (aXHTML ? eXHTML : eHTML); }
97
98 virtual nsresult Clone(mozilla::dom::NodeInfo*,
99 nsINode** aResult) const override;
100
101 using mozilla::dom::DocumentOrShadowRoot::GetElementById;
102
103 virtual void DocAddSizeOfExcludingThis(
104 nsWindowSizes& aWindowSizes) const override;
105 // DocAddSizeOfIncludingThis is inherited from Document.
106
107 virtual bool WillIgnoreCharsetOverride() override;
108
109 // WebIDL API
110 virtual JSObject* WrapNode(JSContext* aCx,
111 JS::Handle<JSObject*> aGivenProto) override;
112 bool IsRegistrableDomainSuffixOfOrEqualTo(const nsAString& aHostSuffixString,
113 const nsACString& aOrigHost);
NamedGetter(JSContext * cx,const nsAString & aName,bool & aFound,JS::MutableHandle<JSObject * > aRetval,mozilla::ErrorResult & rv)114 void NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
115 JS::MutableHandle<JSObject*> aRetval,
116 mozilla::ErrorResult& rv) {
117 JS::Rooted<JS::Value> v(cx);
118 if ((aFound = ResolveName(cx, aName, &v, rv))) {
119 SetUseCounter(mozilla::eUseCounter_custom_HTMLDocumentNamedGetterHit);
120 aRetval.set(v.toObjectOrNull());
121 }
122 }
123 void GetSupportedNames(nsTArray<nsString>& aNames);
124 // We're picking up GetLocation from Document
GetLocation()125 already_AddRefed<mozilla::dom::Location> GetLocation() const {
126 return Document::GetLocation();
127 }
128
129 static bool MatchFormControls(mozilla::dom::Element* aElement,
130 int32_t aNamespaceID, nsAtom* aAtom,
131 void* aData);
132
133 void GetFormsAndFormControls(nsContentList** aFormList,
134 nsContentList** aFormControlList);
135
136 protected:
137 ~nsHTMLDocument();
138
139 nsresult GetBodySize(int32_t* aWidth, int32_t* aHeight);
140
141 nsIContent* MatchId(nsIContent* aContent, const nsAString& aId);
142
143 static void DocumentWriteTerminationFunc(nsISupports* aRef);
144
145 // A helper class to keep nsContentList objects alive for a short period of
146 // time. Note, when the final Release is called on an nsContentList object, it
147 // removes itself from MutationObserver list.
148 class ContentListHolder : public mozilla::Runnable {
149 public:
ContentListHolder(nsHTMLDocument * aDocument,nsContentList * aFormList,nsContentList * aFormControlList)150 ContentListHolder(nsHTMLDocument* aDocument, nsContentList* aFormList,
151 nsContentList* aFormControlList)
152 : mozilla::Runnable("ContentListHolder"),
153 mDocument(aDocument),
154 mFormList(aFormList),
155 mFormControlList(aFormControlList) {}
156
~ContentListHolder()157 ~ContentListHolder() {
158 MOZ_ASSERT(!mDocument->mContentListHolder ||
159 mDocument->mContentListHolder == this);
160 mDocument->mContentListHolder = nullptr;
161 }
162
163 RefPtr<nsHTMLDocument> mDocument;
164 RefPtr<nsContentList> mFormList;
165 RefPtr<nsContentList> mFormControlList;
166 };
167
168 friend class ContentListHolder;
169 ContentListHolder* mContentListHolder;
170
171 /** # of forms in the document, synchronously set */
172 int32_t mNumForms;
173
174 static void TryReloadCharset(nsIContentViewer* aCv, int32_t& aCharsetSource,
175 NotNull<const Encoding*>& aEncoding);
176 void TryUserForcedCharset(nsIContentViewer* aCv, nsIDocShell* aDocShell,
177 int32_t& aCharsetSource,
178 NotNull<const Encoding*>& aEncoding);
179 void TryParentCharset(nsIDocShell* aDocShell, int32_t& charsetSource,
180 NotNull<const Encoding*>& aEncoding);
181
182 // Load flags of the document's channel
183 uint32_t mLoadFlags;
184
185 bool mWarnedWidthHeight;
186
187 /**
188 * Set to true once we know that we are loading plain text content.
189 */
190 bool mIsPlainText;
191
192 /**
193 * Set to true once we know that we are viewing source.
194 */
195 bool mViewSource;
196 };
197
198 namespace mozilla {
199 namespace dom {
200
AsHTMLDocument()201 inline nsHTMLDocument* Document::AsHTMLDocument() {
202 MOZ_ASSERT(IsHTMLOrXHTML());
203 return static_cast<nsHTMLDocument*>(this);
204 }
205
AsHTMLDocument()206 inline const nsHTMLDocument* Document::AsHTMLDocument() const {
207 MOZ_ASSERT(IsHTMLOrXHTML());
208 return static_cast<const nsHTMLDocument*>(this);
209 }
210
211 } // namespace dom
212 } // namespace mozilla
213
214 #endif /* nsHTMLDocument_h___ */
215