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/. */
7 #ifndef mozilla_dom_ScriptLoadContext_h
8 #define mozilla_dom_ScriptLoadContext_h
10 #include "js/AllocPolicy.h"
11 #include "js/RootingAPI.h"
12 #include "js/SourceText.h"
13 #include "js/TypeDecls.h"
14 #include "js/loader/LoadContextBase.h"
15 #include "js/loader/ScriptKind.h"
16 #include "mozilla/Atomics.h"
17 #include "mozilla/Assertions.h"
18 #include "mozilla/CORSMode.h"
19 #include "mozilla/dom/SRIMetadata.h"
20 #include "mozilla/LinkedList.h"
21 #include "mozilla/Maybe.h"
22 #include "mozilla/MaybeOneOf.h"
23 #include "mozilla/PreloaderBase.h"
24 #include "mozilla/StaticPrefs_dom.h"
25 #include "mozilla/Utf8.h" // mozilla::Utf8Unit
26 #include "mozilla/Variant.h"
27 #include "mozilla/Vector.h"
29 #include "nsCycleCollectionParticipant.h"
30 #include "nsIScriptElement.h"
32 class nsICacheInfoChannel
;
38 namespace mozilla::dom
{
43 * DOM specific ScriptLoadContext.
45 * ScriptLoadContexts augment the loading of a ScriptLoadRequest. They
46 * describe how a ScriptLoadRequests loading and evaluation needs to be
47 * augmented, based on the information provided by the loading context. In
48 * the case of the DOM, the ScriptLoadContext is used to identify how a script
49 * should be loaded according to information found in the HTML document into
50 * which it will be loaded. The following fields describe how the
51 * ScriptLoadRequest will be loaded.
54 * stores the mode (Async, Sync, Deferred), and preload, which
55 * allows the ScriptLoader to decide if the script should be pushed
56 * offThread, or if the preloaded request should be used.
58 * Set when the script tag is in the head, and should be treated as
61 * Set for scripts whose bodies are inline in the html. In this case,
62 * the script does not need to be fetched first.
64 * Set if we are in an XSLT request.
65 * * TODO: mIsPreload (will be moved from ScriptFetchOptions)
66 * Set for scripts that are preloaded in a
67 * <link rel="preload" as="script"> element.
69 * In addition to describing how the ScriptLoadRequest will be loaded by the
70 * DOM ScriptLoader, the ScriptLoadContext contains fields that facilitate
71 * those custom behaviors, including support for offthread parsing, pointers
72 * to runnables (for cancellation and cleanup if a script is parsed offthread)
73 * and preload element specific controls.
77 class ScriptLoadContext
: public JS::loader::LoadContextBase
,
78 public PreloaderBase
{
80 virtual ~ScriptLoadContext();
83 explicit ScriptLoadContext();
85 NS_DECL_ISUPPORTS_INHERITED
86 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ScriptLoadContext
,
87 JS::loader::LoadContextBase
)
90 static void PrioritizeAsPreload(nsIChannel
* aChannel
);
91 virtual void PrioritizeAsPreload() override
;
93 bool IsPreload() const;
95 bool CompileStarted() const;
97 JS::OffThreadToken
** OffThreadTokenPtr() {
98 return mOffThreadToken
? &mOffThreadToken
: nullptr;
101 bool IsTracking() const { return mIsTracking
; }
102 void SetIsTracking() {
103 MOZ_ASSERT(!mIsTracking
);
107 void BlockOnload(Document
* aDocument
);
109 void MaybeUnblockOnload();
111 enum class ScriptMode
: uint8_t {
115 eLinkPreload
// this is a load initiated by <link rel="preload"
119 void SetScriptMode(bool aDeferAttr
, bool aAsyncAttr
, bool aLinkPreload
);
121 bool IsLinkPreloadScript() const {
122 return mScriptMode
== ScriptMode::eLinkPreload
;
125 bool IsBlockingScript() const { return mScriptMode
== ScriptMode::eBlocking
; }
127 bool IsDeferredScript() const { return mScriptMode
== ScriptMode::eDeferred
; }
129 bool IsAsyncScript() const { return mScriptMode
== ScriptMode::eAsync
; }
131 nsIScriptElement
* GetScriptElement() const;
133 // Make this request a preload (speculative) request.
134 void SetIsPreloadRequest() {
135 MOZ_ASSERT(!GetScriptElement());
136 MOZ_ASSERT(!IsPreload());
140 // Make a preload request into an actual load request for the given element.
141 void SetIsLoadRequest(nsIScriptElement
* aElement
);
143 FromParser
GetParserCreated() const {
144 nsIScriptElement
* element
= GetScriptElement();
146 return NOT_FROM_PARSER
;
148 return element
->GetParserCreated();
151 // Used to output a string for the Gecko Profiler.
152 void GetProfilerLabel(nsACString
& aOutString
) override
;
154 void MaybeCancelOffThreadScript();
156 ScriptMode mScriptMode
; // Whether this is a blocking, defer or async script.
157 bool mScriptFromHead
; // Synchronous head script block loading of other non
159 bool mIsInline
; // Is the script inline or loaded?
160 bool mInDeferList
; // True if we live in mDeferRequests.
161 bool mInAsyncList
; // True if we live in mLoadingAsyncRequests or
162 // mLoadedAsyncRequests.
163 bool mIsNonAsyncScriptInserted
; // True if we live in
164 // mNonAsyncExternalScriptInsertedRequests
165 bool mIsXSLT
; // True if we live in mXSLTRequests.
166 bool mInCompilingList
; // True if we are in mOffThreadCompilingRequests.
167 bool mIsTracking
; // True if the script comes from a source on our
168 // tracking protection list.
169 bool mWasCompiledOMT
; // True if the script has been compiled off main
172 // Off-thread parsing token. Set at the start of off-thread parsing and
173 // cleared when the result of the parse is used.
174 JS::OffThreadToken
* mOffThreadToken
;
176 // Runnable that is dispatched to the main thread when off-thread compilation
178 RefPtr
<Runnable
> mRunnable
;
182 // Set on scripts and top level modules.
185 // Non-null if there is a document that this request is blocking from loading.
186 RefPtr
<Document
> mLoadBlockedDocument
;
188 // For preload requests, we defer reporting errors to the console until the
190 nsresult mUnreportedPreloadError
;
193 } // namespace mozilla::dom
195 #endif // mozilla_dom_ScriptLoadContext_h