Backed out changeset 9d8b4c0b99ed (bug 1945683) for causing btime failures. CLOSED...
[gecko.git] / dom / script / nsIScriptElement.h
blob8601dbd18292ccdd32b3c4c9606cf6e5dc5f2524
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 nsIScriptElement_h___
8 #define nsIScriptElement_h___
10 #include "js/ColumnNumber.h" // JS::ColumnNumberOneOrigin
11 #include "js/loader/ScriptKind.h"
12 #include "mozilla/AlreadyAddRefed.h"
13 #include "mozilla/Assertions.h"
14 #include "mozilla/CORSMode.h"
15 #include "mozilla/dom/FromParser.h"
16 #include "nsCOMPtr.h"
17 #include "nsID.h"
18 #include "nsIScriptLoaderObserver.h"
19 #include "nsIWeakReferenceUtils.h"
20 #include "nsStringFwd.h"
21 #include "nscore.h"
23 // XXX Avoid including this here by moving function bodies to the cpp file
24 #include "nsIPrincipal.h"
26 class nsIContent;
27 class nsIParser;
28 class nsIPrincipal;
29 class nsIURI;
31 namespace mozilla::dom {
32 class Document;
33 enum class FetchPriority : uint8_t;
34 enum class ReferrerPolicy : uint8_t;
35 } // namespace mozilla::dom
37 // Must be kept in sync with xpcom/rust/xpcom/src/interfaces/nonidl.rs
38 #define NS_ISCRIPTELEMENT_IID \
39 { \
40 0xe60fca9b, 0x1b96, 0x4e4e, { \
41 0xa9, 0xb4, 0xdc, 0x98, 0x4f, 0x88, 0x3f, 0x9c \
42 } \
45 /**
46 * Internal interface implemented by script elements
48 class nsIScriptElement : public nsIScriptLoaderObserver {
49 public:
50 NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTELEMENT_IID)
52 explicit nsIScriptElement(mozilla::dom::FromParser aFromParser)
53 : mLineNumber(1),
54 mColumnNumber(1),
55 mAlreadyStarted(false),
56 mMalformed(false),
57 mDoneAddingChildren(aFromParser == mozilla::dom::NOT_FROM_PARSER ||
58 aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT),
59 mForceAsync(aFromParser == mozilla::dom::NOT_FROM_PARSER ||
60 aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT),
61 mFrozen(false),
62 mDefer(false),
63 mAsync(false),
64 mExternal(false),
65 mKind(JS::loader::ScriptKind::eClassic),
66 mParserCreated(aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT
67 ? mozilla::dom::NOT_FROM_PARSER
68 : aFromParser),
69 // Fragment parser-created scripts (if executable)
70 // behave like script-created scripts.
71 mCreatorParser(nullptr) {}
73 /**
74 * Content type identifying the scripting language. Can be empty, in
75 * which case javascript will be assumed.
76 * Return false if type attribute is not found.
78 virtual bool GetScriptType(nsAString& type) = 0;
80 /**
81 * Location of script source text. Can return null, in which case
82 * this is assumed to be an inline script element.
84 nsIURI* GetScriptURI() {
85 MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
86 return mUri;
89 nsIPrincipal* GetScriptURITriggeringPrincipal() {
90 MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
91 return mSrcTriggeringPrincipal;
94 /**
95 * Script source text for inline script elements.
97 virtual void GetScriptText(nsAString& text) const = 0;
99 virtual void GetScriptCharset(nsAString& charset) = 0;
102 * Freezes the return values of the following methods so that subsequent
103 * modifications to the attributes don't change execution behavior:
104 * - GetScriptIsModule()
105 * - GetScriptIsImportMap()
106 * - GetScriptDeferred()
107 * - GetScriptAsync()
108 * - GetScriptURI()
109 * - GetScriptExternal()
111 virtual void FreezeExecutionAttrs(const mozilla::dom::Document*) = 0;
114 * Is the script a module script.
116 bool GetScriptIsModule() {
117 MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
118 return mKind == JS::loader::ScriptKind::eModule;
122 * Is the script an import map.
124 bool GetScriptIsImportMap() {
125 MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
126 return mKind == JS::loader::ScriptKind::eImportMap;
130 * Is the script deferred.
132 bool GetScriptDeferred() {
133 MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
134 return mDefer;
138 * Is the script async.
140 bool GetScriptAsync() {
141 MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
142 return mAsync;
146 * Is the script an external script?
148 bool GetScriptExternal() {
149 MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
150 return mExternal;
154 * Returns how the element was created.
156 mozilla::dom::FromParser GetParserCreated() { return mParserCreated; }
158 void SetScriptLineNumber(uint32_t aLineNumber) { mLineNumber = aLineNumber; }
160 uint32_t GetScriptLineNumber() { return mLineNumber; }
162 void SetScriptColumnNumber(JS::ColumnNumberOneOrigin aColumnNumber) {
163 mColumnNumber = aColumnNumber;
166 JS::ColumnNumberOneOrigin GetScriptColumnNumber() { return mColumnNumber; }
168 void SetIsMalformed() { mMalformed = true; }
170 bool IsMalformed() { return mMalformed; }
172 void PreventExecution() { mAlreadyStarted = true; }
174 void LoseParserInsertedness() {
175 mUri = nullptr;
176 mCreatorParser = nullptr;
177 mParserCreated = mozilla::dom::NOT_FROM_PARSER;
178 mForceAsync = !GetAsyncState();
180 // Reset state set by FreezeExecutionAttrs().
181 mFrozen = false;
182 mExternal = false;
183 mAsync = false;
184 mDefer = false;
185 mKind = JS::loader::ScriptKind::eClassic;
188 void SetCreatorParser(nsIParser* aParser);
191 * Unblocks the creator parser
193 void UnblockParser();
196 * Attempts to resume parsing asynchronously
198 void ContinueParserAsync();
201 * Informs the creator parser that the evaluation of this script is starting
203 void BeginEvaluating();
206 * Informs the creator parser that the evaluation of this script is ending
208 void EndEvaluating();
211 * Retrieves a pointer to the creator parser if this has one or null if not
213 already_AddRefed<nsIParser> GetCreatorParser();
216 * This method is called when the parser finishes creating the script
217 * element's children, if any are present.
219 * @return whether the parser will be blocked while this script is being
220 * loaded
222 bool AttemptToExecute() {
223 mDoneAddingChildren = true;
224 bool block = MaybeProcessScript();
225 if (!mAlreadyStarted) {
226 // Need to lose parser-insertedness here to allow another script to cause
227 // execution later.
228 LoseParserInsertedness();
230 return block;
234 * Get the CORS mode of the script element
236 virtual mozilla::CORSMode GetCORSMode() const {
237 /* Default to no CORS */
238 return mozilla::CORS_NONE;
242 * Get the fetch priority
243 * (https://html.spec.whatwg.org/multipage/scripting.html#attr-script-fetchpriority)
244 * of the script element.
246 virtual mozilla::dom::FetchPriority GetFetchPriority() const = 0;
249 * Get referrer policy of the script element
251 virtual mozilla::dom::ReferrerPolicy GetReferrerPolicy();
254 * Fire an error event
256 virtual nsresult FireErrorEvent() = 0;
258 protected:
260 * Processes the script if it's in the document-tree and links to or
261 * contains a script. Once it has been evaluated there is no way to make it
262 * reevaluate the script, you'll have to create a new element. This also means
263 * that when adding a src attribute to an element that already contains an
264 * inline script, the script referenced by the src attribute will not be
265 * loaded.
267 * In order to be able to use multiple childNodes, or to use the
268 * fallback mechanism of using both inline script and linked script you have
269 * to add all attributes and childNodes before adding the element to the
270 * document-tree.
272 * @return whether the parser will be blocked while this script is being
273 * loaded
275 virtual bool MaybeProcessScript() = 0;
278 * Since we've removed the XPCOM interface to HTML elements, we need a way to
279 * retreive async state from script elements without bringing the type in.
281 virtual bool GetAsyncState() = 0;
284 * Allow implementing elements to avoid unnecessary QueryReferences.
286 virtual nsIContent* GetAsContent() = 0;
289 * Determine whether this is a(n) classic/module/importmap script.
291 void DetermineKindFromType(const mozilla::dom::Document* aOwnerDoc);
293 bool IsClassicNonAsyncDefer();
296 * The start line number of the script.
298 uint32_t mLineNumber;
301 * The start column number of the script.
303 JS::ColumnNumberOneOrigin mColumnNumber;
306 * The "already started" flag per HTML5.
308 bool mAlreadyStarted;
311 * The script didn't have an end tag.
313 bool mMalformed;
316 * False if parser-inserted but the parser hasn't triggered running yet.
318 bool mDoneAddingChildren;
321 * If true, the .async property returns true instead of reflecting the
322 * content attribute.
324 bool mForceAsync;
327 * Whether src, defer and async are frozen.
329 bool mFrozen;
332 * The effective deferredness.
334 bool mDefer;
337 * The effective asyncness.
339 bool mAsync;
342 * The effective externalness. A script can be external with mUri being null
343 * if the src attribute contained an invalid URL string.
345 bool mExternal;
348 * The effective script kind.
350 JS::loader::ScriptKind mKind;
353 * Whether this element was parser-created.
355 mozilla::dom::FromParser mParserCreated;
358 * The effective src (or null if no src).
360 nsCOMPtr<nsIURI> mUri;
363 * The triggering principal for the src URL.
365 nsCOMPtr<nsIPrincipal> mSrcTriggeringPrincipal;
368 * The creator parser of a non-defer, non-async parser-inserted script.
370 nsWeakPtr mCreatorParser;
373 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptElement, NS_ISCRIPTELEMENT_IID)
375 #endif // nsIScriptElement_h___