1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/parser/html/nsHtml5Parser.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,362 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef NS_HTML5_PARSER 1.10 +#define NS_HTML5_PARSER 1.11 + 1.12 +#include "nsAutoPtr.h" 1.13 +#include "nsIParser.h" 1.14 +#include "nsDeque.h" 1.15 +#include "nsIURL.h" 1.16 +#include "nsParserCIID.h" 1.17 +#include "nsITokenizer.h" 1.18 +#include "nsIContentSink.h" 1.19 +#include "nsIRequest.h" 1.20 +#include "nsIChannel.h" 1.21 +#include "nsCOMArray.h" 1.22 +#include "nsContentSink.h" 1.23 +#include "nsCycleCollectionParticipant.h" 1.24 +#include "nsIInputStream.h" 1.25 +#include "nsDetectionConfident.h" 1.26 +#include "nsHtml5OwningUTF16Buffer.h" 1.27 +#include "nsHtml5TreeOpExecutor.h" 1.28 +#include "nsHtml5StreamParser.h" 1.29 +#include "nsHtml5AtomTable.h" 1.30 +#include "nsWeakReference.h" 1.31 +#include "nsHtml5StreamListener.h" 1.32 + 1.33 +class nsHtml5Parser : public nsIParser, 1.34 + public nsSupportsWeakReference 1.35 +{ 1.36 + public: 1.37 + NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW 1.38 + NS_DECL_CYCLE_COLLECTING_ISUPPORTS 1.39 + 1.40 + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsHtml5Parser, nsIParser) 1.41 + 1.42 + nsHtml5Parser(); 1.43 + virtual ~nsHtml5Parser(); 1.44 + 1.45 + /* Start nsIParser */ 1.46 + /** 1.47 + * No-op for backwards compat. 1.48 + */ 1.49 + NS_IMETHOD_(void) SetContentSink(nsIContentSink* aSink); 1.50 + 1.51 + /** 1.52 + * Returns the tree op executor for backwards compat. 1.53 + */ 1.54 + NS_IMETHOD_(nsIContentSink*) GetContentSink(); 1.55 + 1.56 + /** 1.57 + * Always returns "view" for backwards compat. 1.58 + */ 1.59 + NS_IMETHOD_(void) GetCommand(nsCString& aCommand); 1.60 + 1.61 + /** 1.62 + * No-op for backwards compat. 1.63 + */ 1.64 + NS_IMETHOD_(void) SetCommand(const char* aCommand); 1.65 + 1.66 + /** 1.67 + * No-op for backwards compat. 1.68 + */ 1.69 + NS_IMETHOD_(void) SetCommand(eParserCommands aParserCommand); 1.70 + 1.71 + /** 1.72 + * Call this method once you've created a parser, and want to instruct it 1.73 + * about what charset to load 1.74 + * 1.75 + * @param aCharset the charset of a document 1.76 + * @param aCharsetSource the source of the charset 1.77 + */ 1.78 + NS_IMETHOD_(void) SetDocumentCharset(const nsACString& aCharset, int32_t aSource); 1.79 + 1.80 + /** 1.81 + * Don't call. For interface compat only. 1.82 + */ 1.83 + NS_IMETHOD_(void) GetDocumentCharset(nsACString& aCharset, int32_t& aSource) 1.84 + { 1.85 + NS_NOTREACHED("No one should call this."); 1.86 + } 1.87 + 1.88 + /** 1.89 + * Get the channel associated with this parser 1.90 + * @param aChannel out param that will contain the result 1.91 + * @return NS_OK if successful or NS_NOT_AVAILABLE if not 1.92 + */ 1.93 + NS_IMETHOD GetChannel(nsIChannel** aChannel); 1.94 + 1.95 + /** 1.96 + * Return |this| for backwards compat. 1.97 + */ 1.98 + NS_IMETHOD GetDTD(nsIDTD** aDTD); 1.99 + 1.100 + /** 1.101 + * Get the stream parser for this parser 1.102 + */ 1.103 + virtual nsIStreamListener* GetStreamListener(); 1.104 + 1.105 + /** 1.106 + * Don't call. For interface compat only. 1.107 + */ 1.108 + NS_IMETHOD ContinueInterruptedParsing(); 1.109 + 1.110 + /** 1.111 + * Blocks the parser. 1.112 + */ 1.113 + NS_IMETHOD_(void) BlockParser(); 1.114 + 1.115 + /** 1.116 + * Unblocks the parser. 1.117 + */ 1.118 + NS_IMETHOD_(void) UnblockParser(); 1.119 + 1.120 + /** 1.121 + * Asynchronously continues parsing. 1.122 + */ 1.123 + NS_IMETHOD_(void) ContinueInterruptedParsingAsync(); 1.124 + 1.125 + /** 1.126 + * Query whether the parser is enabled (i.e. not blocked) or not. 1.127 + */ 1.128 + NS_IMETHOD_(bool) IsParserEnabled(); 1.129 + 1.130 + /** 1.131 + * Query whether the parser thinks it's done with parsing. 1.132 + */ 1.133 + NS_IMETHOD_(bool) IsComplete(); 1.134 + 1.135 + /** 1.136 + * Set up request observer. 1.137 + * 1.138 + * @param aURL used for View Source title 1.139 + * @param aListener a listener to forward notifications to 1.140 + * @param aKey the root context key (used for document.write) 1.141 + * @param aMode ignored (for interface compat only) 1.142 + */ 1.143 + NS_IMETHOD Parse(nsIURI* aURL, 1.144 + nsIRequestObserver* aListener = nullptr, 1.145 + void* aKey = 0, 1.146 + nsDTDMode aMode = eDTDMode_autodetect); 1.147 + 1.148 + /** 1.149 + * document.write and document.close 1.150 + * 1.151 + * @param aSourceBuffer the argument of document.write (empty for .close()) 1.152 + * @param aKey a key unique to the script element that caused this call 1.153 + * @param aContentType "text/html" for HTML mode, else text/plain mode 1.154 + * @param aLastCall true if .close() false if .write() 1.155 + * @param aMode ignored (for interface compat only) 1.156 + */ 1.157 + NS_IMETHOD Parse(const nsAString& aSourceBuffer, 1.158 + void* aKey, 1.159 + const nsACString& aContentType, 1.160 + bool aLastCall, 1.161 + nsDTDMode aMode = eDTDMode_autodetect); 1.162 + 1.163 + /** 1.164 + * Stops the parser prematurely 1.165 + */ 1.166 + NS_IMETHOD Terminate(); 1.167 + 1.168 + /** 1.169 + * Don't call. For interface backwards compat only. 1.170 + */ 1.171 + NS_IMETHOD ParseFragment(const nsAString& aSourceBuffer, 1.172 + nsTArray<nsString>& aTagStack); 1.173 + 1.174 + /** 1.175 + * Don't call. For interface compat only. 1.176 + */ 1.177 + NS_IMETHOD BuildModel(); 1.178 + 1.179 + /** 1.180 + * Don't call. For interface compat only. 1.181 + */ 1.182 + NS_IMETHODIMP CancelParsingEvents(); 1.183 + 1.184 + /** 1.185 + * Don't call. For interface compat only. 1.186 + */ 1.187 + virtual void Reset(); 1.188 + 1.189 + /** 1.190 + * True in fragment mode and during synchronous document.write 1.191 + */ 1.192 + virtual bool CanInterrupt(); 1.193 + 1.194 + /** 1.195 + * True if the insertion point (per HTML5) is defined. 1.196 + */ 1.197 + virtual bool IsInsertionPointDefined(); 1.198 + 1.199 + /** 1.200 + * Call immediately before starting to evaluate a parser-inserted script. 1.201 + */ 1.202 + virtual void BeginEvaluatingParserInsertedScript(); 1.203 + 1.204 + /** 1.205 + * Call immediately after having evaluated a parser-inserted script. 1.206 + */ 1.207 + virtual void EndEvaluatingParserInsertedScript(); 1.208 + 1.209 + /** 1.210 + * Marks the HTML5 parser as not a script-created parser: Prepares the 1.211 + * parser to be able to read a stream. 1.212 + * 1.213 + * @param aCommand the parser command (Yeah, this is bad API design. Let's 1.214 + * make this better when retiring nsIParser) 1.215 + */ 1.216 + virtual void MarkAsNotScriptCreated(const char* aCommand); 1.217 + 1.218 + /** 1.219 + * True if this is a script-created HTML5 parser. 1.220 + */ 1.221 + virtual bool IsScriptCreated(); 1.222 + 1.223 + /* End nsIParser */ 1.224 + 1.225 + // Not from an external interface 1.226 + // Non-inherited methods 1.227 + 1.228 + public: 1.229 + 1.230 + /** 1.231 + * Initializes the parser to load from a channel. 1.232 + */ 1.233 + virtual nsresult Initialize(nsIDocument* aDoc, 1.234 + nsIURI* aURI, 1.235 + nsISupports* aContainer, 1.236 + nsIChannel* aChannel); 1.237 + 1.238 + inline nsHtml5Tokenizer* GetTokenizer() { 1.239 + return mTokenizer; 1.240 + } 1.241 + 1.242 + void InitializeDocWriteParserState(nsAHtml5TreeBuilderState* aState, int32_t aLine); 1.243 + 1.244 + void DropStreamParser() 1.245 + { 1.246 + if (GetStreamParser()) { 1.247 + GetStreamParser()->DropTimer(); 1.248 + mStreamListener->DropDelegate(); 1.249 + mStreamListener = nullptr; 1.250 + } 1.251 + } 1.252 + 1.253 + void StartTokenizer(bool aScriptingEnabled); 1.254 + 1.255 + void ContinueAfterFailedCharsetSwitch(); 1.256 + 1.257 + nsHtml5StreamParser* GetStreamParser() 1.258 + { 1.259 + if (!mStreamListener) { 1.260 + return nullptr; 1.261 + } 1.262 + return mStreamListener->GetDelegate(); 1.263 + } 1.264 + 1.265 + /** 1.266 + * Parse until pending data is exhausted or a script blocks the parser 1.267 + */ 1.268 + nsresult ParseUntilBlocked(); 1.269 + 1.270 + private: 1.271 + 1.272 + // State variables 1.273 + 1.274 + /** 1.275 + * Whether the last character tokenized was a carriage return (for CRLF) 1.276 + */ 1.277 + bool mLastWasCR; 1.278 + 1.279 + /** 1.280 + * Whether the last character tokenized was a carriage return (for CRLF) 1.281 + * when preparsing document.write. 1.282 + */ 1.283 + bool mDocWriteSpeculativeLastWasCR; 1.284 + 1.285 + /** 1.286 + * The parser is blocking on a script 1.287 + */ 1.288 + bool mBlocked; 1.289 + 1.290 + /** 1.291 + * Whether the document.write() speculator is already active. 1.292 + */ 1.293 + bool mDocWriteSpeculatorActive; 1.294 + 1.295 + /** 1.296 + * The number of parser-inserted script currently being evaluated. 1.297 + */ 1.298 + int32_t mParserInsertedScriptsBeingEvaluated; 1.299 + 1.300 + /** 1.301 + * True if document.close() has been called. 1.302 + */ 1.303 + bool mDocumentClosed; 1.304 + 1.305 + bool mInDocumentWrite; 1.306 + 1.307 + // Portable parser objects 1.308 + /** 1.309 + * The first buffer in the pending UTF-16 buffer queue 1.310 + */ 1.311 + nsRefPtr<nsHtml5OwningUTF16Buffer> mFirstBuffer; 1.312 + 1.313 + /** 1.314 + * The last buffer in the pending UTF-16 buffer queue. Always points 1.315 + * to a sentinel object with nullptr as its parser key. 1.316 + */ 1.317 + nsHtml5OwningUTF16Buffer* mLastBuffer; // weak ref; 1.318 + 1.319 + /** 1.320 + * The tree operation executor 1.321 + */ 1.322 + nsRefPtr<nsHtml5TreeOpExecutor> mExecutor; 1.323 + 1.324 + /** 1.325 + * The HTML5 tree builder 1.326 + */ 1.327 + const nsAutoPtr<nsHtml5TreeBuilder> mTreeBuilder; 1.328 + 1.329 + /** 1.330 + * The HTML5 tokenizer 1.331 + */ 1.332 + const nsAutoPtr<nsHtml5Tokenizer> mTokenizer; 1.333 + 1.334 + /** 1.335 + * Another HTML5 tree builder for preloading document.written content. 1.336 + */ 1.337 + nsAutoPtr<nsHtml5TreeBuilder> mDocWriteSpeculativeTreeBuilder; 1.338 + 1.339 + /** 1.340 + * Another HTML5 tokenizer for preloading document.written content. 1.341 + */ 1.342 + nsAutoPtr<nsHtml5Tokenizer> mDocWriteSpeculativeTokenizer; 1.343 + 1.344 + /** 1.345 + * The stream listener holding the stream parser. 1.346 + */ 1.347 + nsRefPtr<nsHtml5StreamListener> mStreamListener; 1.348 + 1.349 + /** 1.350 + * 1.351 + */ 1.352 + int32_t mRootContextLineNumber; 1.353 + 1.354 + /** 1.355 + * Whether it's OK to transfer parsing back to the stream parser 1.356 + */ 1.357 + bool mReturnToStreamParserPermitted; 1.358 + 1.359 + /** 1.360 + * The scoped atom table 1.361 + */ 1.362 + nsHtml5AtomTable mAtomTable; 1.363 + 1.364 +}; 1.365 +#endif