/work/obj-fuzz/dist/include/mozilla/dom/ScriptLoader.h
Line | Count | Source (jump to first uncovered line) |
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 | | |
7 | | #ifndef mozilla_dom_ScriptLoader_h |
8 | | #define mozilla_dom_ScriptLoader_h |
9 | | |
10 | | #include "nsCOMPtr.h" |
11 | | #include "nsRefPtrHashtable.h" |
12 | | #include "mozilla/Encoding.h" |
13 | | #include "nsIScriptElement.h" |
14 | | #include "nsCOMArray.h" |
15 | | #include "nsCycleCollectionParticipant.h" |
16 | | #include "nsTArray.h" |
17 | | #include "nsAutoPtr.h" |
18 | | #include "nsICacheInfoChannel.h" |
19 | | #include "nsIDocument.h" |
20 | | #include "nsIIncrementalStreamLoader.h" |
21 | | #include "nsURIHashKey.h" |
22 | | #include "mozilla/CORSMode.h" |
23 | | #include "mozilla/dom/ScriptLoadRequest.h" |
24 | | #include "mozilla/dom/SRIMetadata.h" |
25 | | #include "mozilla/dom/SRICheck.h" |
26 | | #include "mozilla/Maybe.h" |
27 | | #include "mozilla/MozPromise.h" |
28 | | #include "mozilla/net/ReferrerPolicy.h" |
29 | | #include "mozilla/StaticPrefs.h" |
30 | | #include "mozilla/Vector.h" |
31 | | |
32 | | class nsIURI; |
33 | | |
34 | | namespace JS { |
35 | | class SourceBufferHolder; |
36 | | } // namespace JS |
37 | | |
38 | | namespace mozilla { |
39 | | namespace dom { |
40 | | |
41 | | class AutoJSAPI; |
42 | | class ModuleLoadRequest; |
43 | | class ModuleScript; |
44 | | class ScriptLoadHandler; |
45 | | class ScriptRequestProcessor; |
46 | | |
47 | | ////////////////////////////////////////////////////////////// |
48 | | // Script loader implementation |
49 | | ////////////////////////////////////////////////////////////// |
50 | | |
51 | | class ScriptLoader final : public nsISupports |
52 | | { |
53 | | class MOZ_STACK_CLASS AutoCurrentScriptUpdater |
54 | | { |
55 | | public: |
56 | | AutoCurrentScriptUpdater(ScriptLoader* aScriptLoader, |
57 | | nsIScriptElement* aCurrentScript) |
58 | | : mOldScript(aScriptLoader->mCurrentScript) |
59 | | , mScriptLoader(aScriptLoader) |
60 | | { |
61 | | nsCOMPtr<nsINode> node = do_QueryInterface(aCurrentScript); |
62 | | mScriptLoader->mCurrentScript = |
63 | | node && !node->IsInShadowTree() ? aCurrentScript : nullptr; |
64 | | } |
65 | | |
66 | | ~AutoCurrentScriptUpdater() |
67 | | { |
68 | | mScriptLoader->mCurrentScript.swap(mOldScript); |
69 | | } |
70 | | |
71 | | private: |
72 | | nsCOMPtr<nsIScriptElement> mOldScript; |
73 | | ScriptLoader* mScriptLoader; |
74 | | }; |
75 | | |
76 | | friend class ModuleLoadRequest; |
77 | | friend class ScriptRequestProcessor; |
78 | | friend class ScriptLoadHandler; |
79 | | friend class AutoCurrentScriptUpdater; |
80 | | |
81 | | public: |
82 | | explicit ScriptLoader(nsIDocument* aDocument); |
83 | | |
84 | | NS_DECL_CYCLE_COLLECTING_ISUPPORTS |
85 | | NS_DECL_CYCLE_COLLECTION_CLASS(ScriptLoader) |
86 | | |
87 | | /** |
88 | | * The loader maintains a weak reference to the document with |
89 | | * which it is initialized. This call forces the reference to |
90 | | * be dropped. |
91 | | */ |
92 | | void DropDocumentReference() |
93 | 0 | { |
94 | 0 | mDocument = nullptr; |
95 | 0 | } |
96 | | |
97 | | /** |
98 | | * Add an observer for all scripts loaded through this loader. |
99 | | * |
100 | | * @param aObserver observer for all script processing. |
101 | | */ |
102 | | nsresult AddObserver(nsIScriptLoaderObserver* aObserver) |
103 | 0 | { |
104 | 0 | return mObservers.AppendObject(aObserver) ? NS_OK : |
105 | 0 | NS_ERROR_OUT_OF_MEMORY; |
106 | 0 | } |
107 | | |
108 | | /** |
109 | | * Remove an observer. |
110 | | * |
111 | | * @param aObserver observer to be removed |
112 | | */ |
113 | | void RemoveObserver(nsIScriptLoaderObserver* aObserver) |
114 | 0 | { |
115 | 0 | mObservers.RemoveObject(aObserver); |
116 | 0 | } |
117 | | |
118 | | /** |
119 | | * Process a script element. This will include both loading the |
120 | | * source of the element if it is not inline and evaluating |
121 | | * the script itself. |
122 | | * |
123 | | * If the script is an inline script that can be executed immediately |
124 | | * (i.e. there are no other scripts pending) then ScriptAvailable |
125 | | * and ScriptEvaluated will be called before the function returns. |
126 | | * |
127 | | * If true is returned the script could not be executed immediately. |
128 | | * In this case ScriptAvailable is guaranteed to be called at a later |
129 | | * point (as well as possibly ScriptEvaluated). |
130 | | * |
131 | | * @param aElement The element representing the script to be loaded and |
132 | | * evaluated. |
133 | | */ |
134 | | bool ProcessScriptElement(nsIScriptElement* aElement); |
135 | | |
136 | | /** |
137 | | * Gets the currently executing script. This is useful if you want to |
138 | | * generate a unique key based on the currently executing script. |
139 | | */ |
140 | | nsIScriptElement* GetCurrentScript() |
141 | 0 | { |
142 | 0 | return mCurrentScript; |
143 | 0 | } |
144 | | |
145 | | nsIScriptElement* GetCurrentParserInsertedScript() |
146 | 0 | { |
147 | 0 | return mCurrentParserInsertedScript; |
148 | 0 | } |
149 | | |
150 | | /** |
151 | | * Whether the loader is enabled or not. |
152 | | * When disabled, processing of new script elements is disabled. |
153 | | * Any call to ProcessScriptElement() will return false. Note that |
154 | | * this DOES NOT disable currently loading or executing scripts. |
155 | | */ |
156 | | bool GetEnabled() |
157 | 0 | { |
158 | 0 | return mEnabled; |
159 | 0 | } |
160 | | |
161 | | void SetEnabled(bool aEnabled) |
162 | 0 | { |
163 | 0 | if (!mEnabled && aEnabled) { |
164 | 0 | ProcessPendingRequestsAsync(); |
165 | 0 | } |
166 | 0 | mEnabled = aEnabled; |
167 | 0 | } |
168 | | |
169 | | /** |
170 | | * Add/remove a blocker for parser-blocking scripts (and XSLT |
171 | | * scripts). Blockers will stop such scripts from executing, but not from |
172 | | * loading. |
173 | | */ |
174 | | void AddParserBlockingScriptExecutionBlocker() |
175 | 0 | { |
176 | 0 | ++mParserBlockingBlockerCount; |
177 | 0 | } |
178 | | |
179 | | void RemoveParserBlockingScriptExecutionBlocker() |
180 | 0 | { |
181 | 0 | if (!--mParserBlockingBlockerCount && ReadyToExecuteScripts()) { |
182 | 0 | ProcessPendingRequestsAsync(); |
183 | 0 | } |
184 | 0 | } |
185 | | |
186 | | /** |
187 | | * Add/remove a blocker for execution of all scripts. Blockers will stop |
188 | | * scripts from executing, but not from loading. |
189 | | */ |
190 | | void AddExecuteBlocker() |
191 | 0 | { |
192 | 0 | ++mBlockerCount; |
193 | 0 | } |
194 | | |
195 | | void RemoveExecuteBlocker() |
196 | 0 | { |
197 | 0 | MOZ_ASSERT(mBlockerCount); |
198 | 0 | if (!--mBlockerCount) { |
199 | 0 | ProcessPendingRequestsAsync(); |
200 | 0 | } |
201 | 0 | } |
202 | | |
203 | | /** |
204 | | * Convert the given buffer to a UTF-16 string. |
205 | | * @param aChannel Channel corresponding to the data. May be null. |
206 | | * @param aData The data to convert |
207 | | * @param aLength Length of the data |
208 | | * @param aHintCharset Hint for the character set (e.g., from a charset |
209 | | * attribute). May be the empty string. |
210 | | * @param aDocument Document which the data is loaded for. Must not be |
211 | | * null. |
212 | | * @param aBufOut [out] char16_t array allocated by ConvertToUTF16 and |
213 | | * containing data converted to unicode. Caller must |
214 | | * js_free() this data when no longer needed. |
215 | | * @param aLengthOut [out] Length of array returned in aBufOut in number |
216 | | * of char16_t code units. |
217 | | */ |
218 | | static nsresult ConvertToUTF16(nsIChannel* aChannel, const uint8_t* aData, |
219 | | uint32_t aLength, |
220 | | const nsAString& aHintCharset, |
221 | | nsIDocument* aDocument, |
222 | | char16_t*& aBufOut, size_t& aLengthOut); |
223 | | |
224 | | static inline nsresult |
225 | | ConvertToUTF16(nsIChannel* aChannel, const uint8_t* aData, |
226 | | uint32_t aLength, const nsAString& aHintCharset, |
227 | | nsIDocument* aDocument, |
228 | | JS::UniqueTwoByteChars& aBufOut, size_t& aLengthOut) |
229 | 0 | { |
230 | 0 | char16_t* bufOut; |
231 | 0 | nsresult rv = ConvertToUTF16(aChannel, aData, aLength, aHintCharset, |
232 | 0 | aDocument, bufOut, aLengthOut); |
233 | 0 | if (NS_SUCCEEDED(rv)) { |
234 | 0 | aBufOut.reset(bufOut); |
235 | 0 | } |
236 | 0 | return rv; |
237 | 0 | }; |
238 | | |
239 | | /** |
240 | | * Handle the completion of a stream. This is called by the |
241 | | * ScriptLoadHandler object which observes the IncrementalStreamLoader |
242 | | * loading the script. The streamed content is expected to be stored on the |
243 | | * aRequest argument. |
244 | | */ |
245 | | nsresult OnStreamComplete(nsIIncrementalStreamLoader* aLoader, |
246 | | ScriptLoadRequest* aRequest, |
247 | | nsresult aChannelStatus, |
248 | | nsresult aSRIStatus, |
249 | | SRICheckDataVerifier* aSRIDataVerifier); |
250 | | |
251 | | /** |
252 | | * Returns wether any request is queued, and not executed yet. |
253 | | */ |
254 | | bool HasPendingRequests(); |
255 | | |
256 | | /** |
257 | | * Processes any pending requests that are ready for processing. |
258 | | */ |
259 | | void ProcessPendingRequests(); |
260 | | |
261 | | /** |
262 | | * Starts deferring deferred scripts and puts them in the mDeferredRequests |
263 | | * queue instead. |
264 | | */ |
265 | | void BeginDeferringScripts() |
266 | 0 | { |
267 | 0 | mDeferEnabled = true; |
268 | 0 | if (mDocument) { |
269 | 0 | mDocument->BlockOnload(); |
270 | 0 | } |
271 | 0 | } |
272 | | |
273 | | /** |
274 | | * Notifies the script loader that parsing is done. If aTerminated is true, |
275 | | * this will drop any pending scripts that haven't run yet. Otherwise, it |
276 | | * will stops deferring scripts and immediately processes the |
277 | | * mDeferredRequests queue. |
278 | | * |
279 | | * WARNING: This function will synchronously execute content scripts, so be |
280 | | * prepared that the world might change around you. |
281 | | */ |
282 | | void ParsingComplete(bool aTerminated); |
283 | | |
284 | | /** |
285 | | * Returns the number of pending scripts, deferred or not. |
286 | | */ |
287 | | uint32_t HasPendingOrCurrentScripts() |
288 | 0 | { |
289 | 0 | return mCurrentScript || mParserBlockingRequest; |
290 | 0 | } |
291 | | |
292 | | /** |
293 | | * Adds aURI to the preload list and starts loading it. |
294 | | * |
295 | | * @param aURI The URI of the external script. |
296 | | * @param aCharset The charset parameter for the script. |
297 | | * @param aType The type parameter for the script. |
298 | | * @param aCrossOrigin The crossorigin attribute for the script. |
299 | | * Void if not present. |
300 | | * @param aIntegrity The expect hash url, if avail, of the request |
301 | | * @param aScriptFromHead Whether or not the script was a child of head |
302 | | */ |
303 | | virtual void PreloadURI(nsIURI* aURI, |
304 | | const nsAString& aCharset, |
305 | | const nsAString& aType, |
306 | | const nsAString& aCrossOrigin, |
307 | | const nsAString& aIntegrity, |
308 | | bool aScriptFromHead, |
309 | | bool aAsync, |
310 | | bool aDefer, |
311 | | bool aNoModule, |
312 | | const mozilla::net::ReferrerPolicy aReferrerPolicy); |
313 | | |
314 | | /** |
315 | | * Process a request that was deferred so that the script could be compiled |
316 | | * off thread. |
317 | | */ |
318 | | nsresult ProcessOffThreadRequest(ScriptLoadRequest* aRequest); |
319 | | |
320 | | bool AddPendingChildLoader(ScriptLoader* aChild) |
321 | | { |
322 | | return mPendingChildLoaders.AppendElement(aChild) != nullptr; |
323 | | } |
324 | | |
325 | | mozilla::dom::DocGroup* GetDocGroup() const |
326 | | { |
327 | | return mDocument->GetDocGroup(); |
328 | | } |
329 | | |
330 | | /** |
331 | | * Register the fact that we saw the load event, and that we need to save the |
332 | | * bytecode at the next loop cycle unless new scripts are waiting in the |
333 | | * pipeline. |
334 | | */ |
335 | | void LoadEventFired(); |
336 | | |
337 | | /** |
338 | | * Destroy and prevent the ScriptLoader or the ScriptLoadRequests from owning |
339 | | * any references to the JSScript or to the Request which might be used for |
340 | | * caching the encoded bytecode. |
341 | | */ |
342 | | void Destroy() |
343 | 0 | { |
344 | 0 | GiveUpBytecodeEncoding(); |
345 | 0 | } |
346 | | |
347 | | private: |
348 | | virtual ~ScriptLoader(); |
349 | | |
350 | | ScriptLoadRequest* CreateLoadRequest(ScriptKind aKind, |
351 | | nsIURI* aURI, |
352 | | nsIScriptElement* aElement, |
353 | | nsIPrincipal* aTriggeringPrincipal, |
354 | | mozilla::CORSMode aCORSMode, |
355 | | const SRIMetadata& aIntegrity, |
356 | | mozilla::net::ReferrerPolicy aReferrerPolicy); |
357 | | |
358 | | /** |
359 | | * Unblocks the creator parser of the parser-blocking scripts. |
360 | | */ |
361 | | void UnblockParser(ScriptLoadRequest* aParserBlockingRequest); |
362 | | |
363 | | /** |
364 | | * Asynchronously resumes the creator parser of the parser-blocking scripts. |
365 | | */ |
366 | | void ContinueParserAsync(ScriptLoadRequest* aParserBlockingRequest); |
367 | | |
368 | | |
369 | | bool ProcessExternalScript(nsIScriptElement* aElement, |
370 | | ScriptKind aScriptKind, |
371 | | nsAutoString aTypeAttr, |
372 | | nsIContent* aScriptContent); |
373 | | |
374 | | bool ProcessInlineScript(nsIScriptElement* aElement, |
375 | | ScriptKind aScriptKind); |
376 | | |
377 | | ScriptLoadRequest* LookupPreloadRequest(nsIScriptElement* aElement, |
378 | | ScriptKind aScriptKind); |
379 | | |
380 | | void GetSRIMetadata(const nsAString& aIntegrityAttr, |
381 | | SRIMetadata *aMetadataOut); |
382 | | |
383 | | /** |
384 | | * Helper function to check the content policy for a given request. |
385 | | */ |
386 | | static nsresult CheckContentPolicy(nsIDocument* aDocument, |
387 | | nsISupports* aContext, |
388 | | nsIURI* aURI, |
389 | | const nsAString& aType, |
390 | | bool aIsPreLoad); |
391 | | |
392 | | /** |
393 | | * Start a load for aRequest's URI. |
394 | | */ |
395 | | nsresult StartLoad(ScriptLoadRequest* aRequest); |
396 | | |
397 | | /** |
398 | | * Abort the current stream, and re-start with a new load request from scratch |
399 | | * without requesting any alternate data. Returns NS_BINDING_RETARGETED on |
400 | | * success, as this error code is used to abort the input stream. |
401 | | */ |
402 | | nsresult RestartLoad(ScriptLoadRequest* aRequest); |
403 | | |
404 | | void HandleLoadError(ScriptLoadRequest *aRequest, nsresult aResult); |
405 | | |
406 | | static bool BinASTEncodingEnabled() |
407 | | { |
408 | | #ifdef JS_BUILD_BINAST |
409 | | return StaticPrefs::dom_script_loader_binast_encoding_enabled(); |
410 | | #else |
411 | | return false; |
412 | | #endif |
413 | | } |
414 | | |
415 | | /** |
416 | | * Process any pending requests asynchronously (i.e. off an event) if there |
417 | | * are any. Note that this is a no-op if there aren't any currently pending |
418 | | * requests. |
419 | | * |
420 | | * This function is virtual to allow cross-library calls to SetEnabled() |
421 | | */ |
422 | | virtual void ProcessPendingRequestsAsync(); |
423 | | |
424 | | /** |
425 | | * If true, the loader is ready to execute parser-blocking scripts, and so are |
426 | | * all its ancestors. If the loader itself is ready but some ancestor is not, |
427 | | * this function will add an execute blocker and ask the ancestor to remove it |
428 | | * once it becomes ready. |
429 | | */ |
430 | | bool ReadyToExecuteParserBlockingScripts(); |
431 | | |
432 | | /** |
433 | | * Return whether just this loader is ready to execute parser-blocking |
434 | | * scripts. |
435 | | */ |
436 | | bool SelfReadyToExecuteParserBlockingScripts() |
437 | | { |
438 | | return ReadyToExecuteScripts() && !mParserBlockingBlockerCount; |
439 | | } |
440 | | |
441 | | /** |
442 | | * Return whether this loader is ready to execute scripts in general. |
443 | | */ |
444 | | bool ReadyToExecuteScripts() |
445 | 0 | { |
446 | 0 | return mEnabled && !mBlockerCount; |
447 | 0 | } |
448 | | |
449 | | nsresult VerifySRI(ScriptLoadRequest *aRequest, |
450 | | nsIIncrementalStreamLoader* aLoader, |
451 | | nsresult aSRIStatus, |
452 | | SRICheckDataVerifier* aSRIDataVerifier) const; |
453 | | |
454 | | nsresult SaveSRIHash(ScriptLoadRequest *aRequest, |
455 | | SRICheckDataVerifier* aSRIDataVerifier) const; |
456 | | |
457 | | void ReportErrorToConsole(ScriptLoadRequest *aRequest, nsresult aResult) const; |
458 | | |
459 | | nsresult AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest, |
460 | | bool* aCouldCompileOut); |
461 | | nsresult ProcessRequest(ScriptLoadRequest* aRequest); |
462 | | nsresult CompileOffThreadOrProcessRequest(ScriptLoadRequest* aRequest); |
463 | | void FireScriptAvailable(nsresult aResult, |
464 | | ScriptLoadRequest* aRequest); |
465 | | void FireScriptEvaluated(nsresult aResult, |
466 | | ScriptLoadRequest* aRequest); |
467 | | nsresult EvaluateScript(ScriptLoadRequest* aRequest); |
468 | | |
469 | | /** |
470 | | * Queue the current script load request to be saved, when the page |
471 | | * initialization ends. The page initialization end is defined as being the |
472 | | * time when the load event got received, and when no more scripts are waiting |
473 | | * to be executed. |
474 | | */ |
475 | | void RegisterForBytecodeEncoding(ScriptLoadRequest* aRequest); |
476 | | |
477 | | /** |
478 | | * Check if all conditions are met, i-e that the onLoad event fired and that |
479 | | * no more script have to be processed. If all conditions are met, queue an |
480 | | * event to encode all the bytecode and save them on the cache. |
481 | | */ |
482 | | void MaybeTriggerBytecodeEncoding(); |
483 | | |
484 | | /** |
485 | | * Iterate over all script load request and save the bytecode of executed |
486 | | * functions on the cache provided by the channel. |
487 | | */ |
488 | | void EncodeBytecode(); |
489 | | void EncodeRequestBytecode(JSContext* aCx, ScriptLoadRequest* aRequest); |
490 | | |
491 | | void GiveUpBytecodeEncoding(); |
492 | | |
493 | | already_AddRefed<nsIScriptGlobalObject> GetScriptGlobalObject(); |
494 | | nsresult FillCompileOptionsForRequest(const mozilla::dom::AutoJSAPI& jsapi, |
495 | | ScriptLoadRequest* aRequest, |
496 | | JS::Handle<JSObject*> aScopeChain, |
497 | | JS::CompileOptions* aOptions); |
498 | | |
499 | | uint32_t NumberOfProcessors(); |
500 | | nsresult PrepareLoadedRequest(ScriptLoadRequest* aRequest, |
501 | | nsIIncrementalStreamLoader* aLoader, |
502 | | nsresult aStatus); |
503 | | |
504 | | void AddDeferRequest(ScriptLoadRequest* aRequest); |
505 | | void AddAsyncRequest(ScriptLoadRequest* aRequest); |
506 | | bool MaybeRemovedDeferRequests(); |
507 | | |
508 | | void MaybeMoveToLoadedList(ScriptLoadRequest* aRequest); |
509 | | |
510 | | mozilla::Maybe<JS::SourceBufferHolder> GetScriptSource(JSContext* aCx, |
511 | | ScriptLoadRequest* aRequest); |
512 | | |
513 | | void SetModuleFetchStarted(ModuleLoadRequest *aRequest); |
514 | | void SetModuleFetchFinishedAndResumeWaitingRequests(ModuleLoadRequest* aRequest, |
515 | | nsresult aResult); |
516 | | |
517 | | bool IsFetchingModule(ModuleLoadRequest* aRequest) const; |
518 | | |
519 | | bool ModuleMapContainsURL(nsIURI* aURL) const; |
520 | | RefPtr<mozilla::GenericPromise> WaitForModuleFetch(nsIURI* aURL); |
521 | | ModuleScript* GetFetchedModule(nsIURI* aURL) const; |
522 | | |
523 | | friend JSScript* |
524 | | HostResolveImportedModule(JSContext* aCx, JS::Handle<JSScript*> aScript, |
525 | | JS::Handle<JSString*> aSpecifier); |
526 | | |
527 | | // Returns wether we should save the bytecode of this script after the |
528 | | // execution of the script. |
529 | | static bool |
530 | | ShouldCacheBytecode(ScriptLoadRequest* aRequest); |
531 | | |
532 | | nsresult CreateModuleScript(ModuleLoadRequest* aRequest); |
533 | | nsresult ProcessFetchedModuleSource(ModuleLoadRequest* aRequest); |
534 | | void CheckModuleDependenciesLoaded(ModuleLoadRequest* aRequest); |
535 | | void ProcessLoadedModuleTree(ModuleLoadRequest* aRequest); |
536 | | bool InstantiateModuleTree(ModuleLoadRequest* aRequest); |
537 | | JS::Value FindFirstParseError(ModuleLoadRequest* aRequest); |
538 | | void StartFetchingModuleDependencies(ModuleLoadRequest* aRequest); |
539 | | |
540 | | RefPtr<mozilla::GenericPromise> |
541 | | StartFetchingModuleAndDependencies(ModuleLoadRequest* aParent, nsIURI* aURI); |
542 | | |
543 | | nsresult AssociateSourceElementsForModuleTree(JSContext* aCx, |
544 | | ModuleLoadRequest* aRequest); |
545 | | |
546 | | nsIDocument* mDocument; // [WEAK] |
547 | | nsCOMArray<nsIScriptLoaderObserver> mObservers; |
548 | | ScriptLoadRequestList mNonAsyncExternalScriptInsertedRequests; |
549 | | // mLoadingAsyncRequests holds async requests while they're loading; when they |
550 | | // have been loaded they are moved to mLoadedAsyncRequests. |
551 | | ScriptLoadRequestList mLoadingAsyncRequests; |
552 | | ScriptLoadRequestList mLoadedAsyncRequests; |
553 | | ScriptLoadRequestList mDeferRequests; |
554 | | ScriptLoadRequestList mXSLTRequests; |
555 | | RefPtr<ScriptLoadRequest> mParserBlockingRequest; |
556 | | |
557 | | // List of script load request that are holding a buffer which has to be saved |
558 | | // on the cache. |
559 | | ScriptLoadRequestList mBytecodeEncodingQueue; |
560 | | |
561 | | // In mRequests, the additional information here is stored by the element. |
562 | | struct PreloadInfo |
563 | | { |
564 | | RefPtr<ScriptLoadRequest> mRequest; |
565 | | nsString mCharset; |
566 | | }; |
567 | | |
568 | | friend void ImplCycleCollectionUnlink(ScriptLoader::PreloadInfo& aField); |
569 | | friend void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, |
570 | | ScriptLoader::PreloadInfo& aField, |
571 | | const char* aName, uint32_t aFlags); |
572 | | |
573 | | struct PreloadRequestComparator |
574 | | { |
575 | | bool Equals(const PreloadInfo& aPi, ScriptLoadRequest* const& aRequest) const |
576 | | { |
577 | | return aRequest == aPi.mRequest; |
578 | | } |
579 | | }; |
580 | | |
581 | | struct PreloadURIComparator |
582 | | { |
583 | | bool Equals(const PreloadInfo& aPi, nsIURI* const &aURI) const; |
584 | | }; |
585 | | |
586 | | nsTArray<PreloadInfo> mPreloads; |
587 | | |
588 | | nsCOMPtr<nsIScriptElement> mCurrentScript; |
589 | | nsCOMPtr<nsIScriptElement> mCurrentParserInsertedScript; |
590 | | nsTArray< RefPtr<ScriptLoader> > mPendingChildLoaders; |
591 | | uint32_t mParserBlockingBlockerCount; |
592 | | uint32_t mBlockerCount; |
593 | | uint32_t mNumberOfProcessors; |
594 | | bool mEnabled; |
595 | | bool mDeferEnabled; |
596 | | bool mDocumentParsingDone; |
597 | | bool mBlockingDOMContentLoaded; |
598 | | bool mLoadEventFired; |
599 | | bool mGiveUpEncoding; |
600 | | |
601 | | // Module map |
602 | | nsRefPtrHashtable<nsURIHashKey, mozilla::GenericPromise::Private> mFetchingModules; |
603 | | nsRefPtrHashtable<nsURIHashKey, ModuleScript> mFetchedModules; |
604 | | |
605 | | nsCOMPtr<nsIConsoleReportCollector> mReporter; |
606 | | |
607 | | // Logging |
608 | | static LazyLogModule gCspPRLog; |
609 | | static LazyLogModule gScriptLoaderLog; |
610 | | }; |
611 | | |
612 | | class nsAutoScriptLoaderDisabler |
613 | | { |
614 | | public: |
615 | | explicit nsAutoScriptLoaderDisabler(nsIDocument* aDoc) |
616 | 0 | { |
617 | 0 | mLoader = aDoc->ScriptLoader(); |
618 | 0 | mWasEnabled = mLoader->GetEnabled(); |
619 | 0 | if (mWasEnabled) { |
620 | 0 | mLoader->SetEnabled(false); |
621 | 0 | } |
622 | 0 | } |
623 | | |
624 | | ~nsAutoScriptLoaderDisabler() |
625 | 0 | { |
626 | 0 | if (mWasEnabled) { |
627 | 0 | mLoader->SetEnabled(true); |
628 | 0 | } |
629 | 0 | } |
630 | | |
631 | | bool mWasEnabled; |
632 | | RefPtr<ScriptLoader> mLoader; |
633 | | }; |
634 | | |
635 | | } // namespace dom |
636 | | } // namespace mozilla |
637 | | |
638 | | #endif // mozilla_dom_ScriptLoader_h |