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"
18 #include "nsIScriptLoaderObserver.h"
19 #include "nsIWeakReferenceUtils.h"
20 #include "nsStringFwd.h"
23 // XXX Avoid including this here by moving function bodies to the cpp file
24 #include "nsIPrincipal.h"
31 namespace mozilla::dom
{
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 \
40 0xe60fca9b, 0x1b96, 0x4e4e, { \
41 0xa9, 0xb4, 0xdc, 0x98, 0x4f, 0x88, 0x3f, 0x9c \
46 * Internal interface implemented by script elements
48 class nsIScriptElement
: public nsIScriptLoaderObserver
{
50 NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTELEMENT_IID
)
52 explicit nsIScriptElement(mozilla::dom::FromParser aFromParser
)
55 mAlreadyStarted(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
),
65 mKind(JS::loader::ScriptKind::eClassic
),
66 mParserCreated(aFromParser
== mozilla::dom::FROM_PARSER_FRAGMENT
67 ? mozilla::dom::NOT_FROM_PARSER
69 // Fragment parser-created scripts (if executable)
70 // behave like script-created scripts.
71 mCreatorParser(nullptr) {}
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;
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!");
89 nsIPrincipal
* GetScriptURITriggeringPrincipal() {
90 MOZ_ASSERT(mFrozen
, "Not ready for this call yet!");
91 return mSrcTriggeringPrincipal
;
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()
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!");
138 * Is the script async.
140 bool GetScriptAsync() {
141 MOZ_ASSERT(mFrozen
, "Not ready for this call yet!");
146 * Is the script an external script?
148 bool GetScriptExternal() {
149 MOZ_ASSERT(mFrozen
, "Not ready for this call yet!");
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() {
176 mCreatorParser
= nullptr;
177 mParserCreated
= mozilla::dom::NOT_FROM_PARSER
;
178 mForceAsync
= !GetAsyncState();
180 // Reset state set by FreezeExecutionAttrs().
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
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
228 LoseParserInsertedness();
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;
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
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
272 * @return whether the parser will be blocked while this script is being
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.
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
327 * Whether src, defer and async are frozen.
332 * The effective deferredness.
337 * The effective asyncness.
342 * The effective externalness. A script can be external with mUri being null
343 * if the src attribute contained an invalid URL string.
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___