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