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 https://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_parser_PrototypeDocumentParser_h
8 #define mozilla_parser_PrototypeDocumentParser_h
9 
10 #include "nsCycleCollectionParticipant.h"
11 #include "nsIContentSink.h"
12 #include "nsIParser.h"
13 #include "nsXULPrototypeDocument.h"
14 
15 class nsIExpatSink;
16 
17 namespace mozilla {
18 namespace dom {
19 class PrototypeDocumentContentSink;
20 }  // namespace dom
21 }  // namespace mozilla
22 
23 namespace mozilla {
24 namespace parser {
25 
26 // The PrototypeDocumentParser is more of a stub than a real parser. It is
27 // responsible for loading an nsXULPrototypeDocument either from the startup
28 // cache or creating a new prototype from the original source if a cached
29 // version does not exist. Once the parser finishes loading the prototype it
30 // will notify the content sink.
31 class PrototypeDocumentParser final : public nsIParser,
32                                       public nsIStreamListener {
33  public:
34   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
35 
36   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(PrototypeDocumentParser, nsIParser)
37 
38   explicit PrototypeDocumentParser(nsIURI* aDocumentURI,
39                                    dom::Document* aDocument);
40 
41   NS_DECL_NSIREQUESTOBSERVER
42   NS_DECL_NSISTREAMLISTENER
43 
44   // Start nsIParser
45   // Ideally, this would just implement nsBaseParser since most of these are
46   // stubs, but Document.h expects an nsIParser.
47   NS_IMETHOD_(void) SetContentSink(nsIContentSink* aSink) override;
48 
49   NS_IMETHOD_(nsIContentSink*) GetContentSink() override;
50 
GetCommand(nsCString & aCommand)51   NS_IMETHOD_(void) GetCommand(nsCString& aCommand) override {}
52 
SetCommand(const char * aCommand)53   NS_IMETHOD_(void) SetCommand(const char* aCommand) override {}
54 
SetCommand(eParserCommands aParserCommand)55   NS_IMETHOD_(void) SetCommand(eParserCommands aParserCommand) override {}
56 
SetDocumentCharset(NotNull<const Encoding * > aEncoding,int32_t aSource,bool aChannelHadCharset)57   virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding,
58                                   int32_t aSource,
59                                   bool aChannelHadCharset) override {}
60 
GetChannel(nsIChannel ** aChannel)61   NS_IMETHOD GetChannel(nsIChannel** aChannel) override {
62     return NS_ERROR_NOT_IMPLEMENTED;
63   }
64 
GetDTD(nsIDTD ** aDTD)65   NS_IMETHOD GetDTD(nsIDTD** aDTD) override { return NS_ERROR_NOT_IMPLEMENTED; }
66 
67   virtual nsIStreamListener* GetStreamListener() override;
68 
ContinueInterruptedParsing()69   NS_IMETHOD ContinueInterruptedParsing() override {
70     return NS_ERROR_NOT_IMPLEMENTED;
71   }
72 
BlockParser()73   NS_IMETHOD_(void) BlockParser() override {}
74 
UnblockParser()75   NS_IMETHOD_(void) UnblockParser() override {}
76 
ContinueInterruptedParsingAsync()77   NS_IMETHOD_(void) ContinueInterruptedParsingAsync() override {}
78 
IsParserEnabled()79   NS_IMETHOD_(bool) IsParserEnabled() override { return true; }
80 
81   NS_IMETHOD_(bool) IsComplete() override;
82 
83   NS_IMETHOD Parse(nsIURI* aURL, nsIRequestObserver* aListener = nullptr,
84                    void* aKey = 0,
85                    nsDTDMode aMode = eDTDMode_autodetect) override;
86 
Terminate()87   NS_IMETHOD Terminate() override { return NS_ERROR_NOT_IMPLEMENTED; }
88 
ParseFragment(const nsAString & aSourceBuffer,nsTArray<nsString> & aTagStack)89   NS_IMETHOD ParseFragment(const nsAString& aSourceBuffer,
90                            nsTArray<nsString>& aTagStack) override {
91     return NS_ERROR_NOT_IMPLEMENTED;
92   }
93 
BuildModel()94   NS_IMETHOD BuildModel() override { return NS_ERROR_NOT_IMPLEMENTED; }
95 
CancelParsingEvents()96   NS_IMETHOD CancelParsingEvents() override { return NS_ERROR_NOT_IMPLEMENTED; }
97 
Reset()98   virtual void Reset() override {}
99 
IsInsertionPointDefined()100   virtual bool IsInsertionPointDefined() override { return false; }
101 
IncrementScriptNestingLevel()102   void IncrementScriptNestingLevel() final {}
103 
DecrementScriptNestingLevel()104   void DecrementScriptNestingLevel() final {}
105 
HasNonzeroScriptNestingLevel()106   bool HasNonzeroScriptNestingLevel() const final { return false; }
107 
MarkAsNotScriptCreated(const char * aCommand)108   virtual void MarkAsNotScriptCreated(const char* aCommand) override {}
109 
IsScriptCreated()110   virtual bool IsScriptCreated() override { return false; }
111 
112   // End nsIParser
113 
114  private:
115   virtual ~PrototypeDocumentParser();
116 
117  protected:
118   nsresult PrepareToLoadPrototype(nsIURI* aURI,
119                                   nsIPrincipal* aDocumentPrincipal,
120                                   nsIParser** aResult);
121 
122   // This is invoked whenever the prototype for this document is loaded
123   // and should be walked, regardless of whether the XUL cache is
124   // disabled, whether the protototype was loaded, whether the
125   // prototype was loaded from the cache or created by parsing the
126   // actual XUL source, etc.
127   nsresult OnPrototypeLoadDone();
128 
129   nsCOMPtr<nsIURI> mDocumentURI;
130   RefPtr<dom::PrototypeDocumentContentSink> mOriginalSink;
131   RefPtr<dom::Document> mDocument;
132 
133   // The XML parser that data is forwarded to when the prototype does not exist
134   // and must be parsed from disk.
135   nsCOMPtr<nsIStreamListener> mStreamListener;
136 
137   // The current prototype that we are walking to construct the
138   // content model.
139   RefPtr<nsXULPrototypeDocument> mCurrentPrototype;
140 
141   // True if there was a prototype in the cache and it finished loading
142   // already.
143   bool mPrototypeAlreadyLoaded;
144 
145   // True after the parser has notified the content sink that it is done.
146   bool mIsComplete;
147 };
148 
149 }  // namespace parser
150 }  // namespace mozilla
151 
152 #endif  // mozilla_parser_PrototypeDocumentParser_h
153