/work/obj-fuzz/dist/include/nsIScriptElement.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 nsIScriptElement_h___ |
8 | | #define nsIScriptElement_h___ |
9 | | |
10 | | #include "nsISupports.h" |
11 | | #include "nsIURI.h" |
12 | | #include "nsCOMPtr.h" |
13 | | #include "nsIScriptLoaderObserver.h" |
14 | | #include "nsWeakPtr.h" |
15 | | #include "nsIParser.h" |
16 | | #include "nsIContent.h" |
17 | | #include "nsContentCreatorFunctions.h" |
18 | | #include "mozilla/CORSMode.h" |
19 | | |
20 | | // Must be kept in sync with xpcom/rust/xpcom/src/interfaces/nonidl.rs |
21 | | #define NS_ISCRIPTELEMENT_IID \ |
22 | | { 0xe60fca9b, 0x1b96, 0x4e4e, \ |
23 | | { 0xa9, 0xb4, 0xdc, 0x98, 0x4f, 0x88, 0x3f, 0x9c } } |
24 | | |
25 | | /** |
26 | | * Internal interface implemented by script elements |
27 | | */ |
28 | | class nsIScriptElement : public nsIScriptLoaderObserver |
29 | | { |
30 | | public: |
31 | | NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTELEMENT_IID) |
32 | | |
33 | | explicit nsIScriptElement(mozilla::dom::FromParser aFromParser) |
34 | | : mLineNumber(1), |
35 | | mColumnNumber(1), |
36 | | mAlreadyStarted(false), |
37 | | mMalformed(false), |
38 | | mDoneAddingChildren(aFromParser == mozilla::dom::NOT_FROM_PARSER || |
39 | | aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT), |
40 | | mForceAsync(aFromParser == mozilla::dom::NOT_FROM_PARSER || |
41 | | aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT), |
42 | | mFrozen(false), |
43 | | mIsModule(false), |
44 | | mDefer(false), |
45 | | mAsync(false), |
46 | | mExternal(false), |
47 | | mParserCreated(aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT ? |
48 | | mozilla::dom::NOT_FROM_PARSER : aFromParser), |
49 | | // Fragment parser-created scripts (if executable) |
50 | | // behave like script-created scripts. |
51 | | mCreatorParser(nullptr) |
52 | 0 | { |
53 | 0 | } |
54 | | |
55 | | /** |
56 | | * Content type identifying the scripting language. Can be empty, in |
57 | | * which case javascript will be assumed. |
58 | | * Return false if type attribute is not found. |
59 | | */ |
60 | | virtual bool GetScriptType(nsAString& type) = 0; |
61 | | |
62 | | /** |
63 | | * Location of script source text. Can return null, in which case |
64 | | * this is assumed to be an inline script element. |
65 | | */ |
66 | | nsIURI* GetScriptURI() |
67 | | { |
68 | | MOZ_ASSERT(mFrozen, "Not ready for this call yet!"); |
69 | | return mUri; |
70 | | } |
71 | | |
72 | | nsIPrincipal* GetScriptURITriggeringPrincipal() |
73 | | { |
74 | | MOZ_ASSERT(mFrozen, "Not ready for this call yet!"); |
75 | | return mSrcTriggeringPrincipal; |
76 | | } |
77 | | |
78 | | /** |
79 | | * Script source text for inline script elements. |
80 | | */ |
81 | | virtual void GetScriptText(nsAString& text) = 0; |
82 | | |
83 | | virtual void GetScriptCharset(nsAString& charset) = 0; |
84 | | |
85 | | /** |
86 | | * Freezes the return values of the following methods so that subsequent |
87 | | * modifications to the attributes don't change execution behavior: |
88 | | * - GetScriptIsModule() |
89 | | * - GetScriptDeferred() |
90 | | * - GetScriptAsync() |
91 | | * - GetScriptURI() |
92 | | * - GetScriptExternal() |
93 | | */ |
94 | | virtual void FreezeExecutionAttrs(nsIDocument* aOwnerDoc) = 0; |
95 | | |
96 | | /** |
97 | | * Is the script a module script. Currently only supported by HTML scripts. |
98 | | */ |
99 | | bool GetScriptIsModule() |
100 | | { |
101 | | MOZ_ASSERT(mFrozen, "Not ready for this call yet!"); |
102 | | return mIsModule; |
103 | | } |
104 | | |
105 | | /** |
106 | | * Is the script deferred. Currently only supported by HTML scripts. |
107 | | */ |
108 | | bool GetScriptDeferred() |
109 | 0 | { |
110 | 0 | MOZ_ASSERT(mFrozen, "Not ready for this call yet!"); |
111 | 0 | return mDefer; |
112 | 0 | } |
113 | | |
114 | | /** |
115 | | * Is the script async. Currently only supported by HTML scripts. |
116 | | */ |
117 | | bool GetScriptAsync() |
118 | 0 | { |
119 | 0 | MOZ_ASSERT(mFrozen, "Not ready for this call yet!"); |
120 | 0 | return mAsync; |
121 | 0 | } |
122 | | |
123 | | /** |
124 | | * Is the script an external script? |
125 | | */ |
126 | | bool GetScriptExternal() |
127 | | { |
128 | | MOZ_ASSERT(mFrozen, "Not ready for this call yet!"); |
129 | | return mExternal; |
130 | | } |
131 | | |
132 | | /** |
133 | | * Returns how the element was created. |
134 | | */ |
135 | | mozilla::dom::FromParser GetParserCreated() |
136 | 0 | { |
137 | 0 | return mParserCreated; |
138 | 0 | } |
139 | | |
140 | | void SetScriptLineNumber(uint32_t aLineNumber) |
141 | 0 | { |
142 | 0 | mLineNumber = aLineNumber; |
143 | 0 | } |
144 | | |
145 | | uint32_t GetScriptLineNumber() |
146 | 0 | { |
147 | 0 | return mLineNumber; |
148 | 0 | } |
149 | | |
150 | | void SetScriptColumnNumber(uint32_t aColumnNumber) |
151 | 0 | { |
152 | 0 | mColumnNumber = aColumnNumber; |
153 | 0 | } |
154 | | |
155 | | uint32_t GetScriptColumnNumber() |
156 | 0 | { |
157 | 0 | return mColumnNumber; |
158 | 0 | } |
159 | | |
160 | | void SetIsMalformed() |
161 | 0 | { |
162 | 0 | mMalformed = true; |
163 | 0 | } |
164 | | |
165 | | bool IsMalformed() |
166 | 0 | { |
167 | 0 | return mMalformed; |
168 | 0 | } |
169 | | |
170 | | void PreventExecution() |
171 | 0 | { |
172 | 0 | mAlreadyStarted = true; |
173 | 0 | } |
174 | | |
175 | | void LoseParserInsertedness() |
176 | 0 | { |
177 | 0 | mUri = nullptr; |
178 | 0 | mCreatorParser = nullptr; |
179 | 0 | mParserCreated = mozilla::dom::NOT_FROM_PARSER; |
180 | 0 | mForceAsync = !GetAsyncState(); |
181 | 0 |
|
182 | 0 | // Reset state set by FreezeExecutionAttrs(). |
183 | 0 | mFrozen = false; |
184 | 0 | mIsModule = false; |
185 | 0 | mExternal = false; |
186 | 0 | mAsync = false; |
187 | 0 | mDefer = false; |
188 | 0 | } |
189 | | |
190 | | void SetCreatorParser(nsIParser* aParser) |
191 | 0 | { |
192 | 0 | mCreatorParser = do_GetWeakReference(aParser); |
193 | 0 | } |
194 | | |
195 | | /** |
196 | | * Unblocks the creator parser |
197 | | */ |
198 | | void UnblockParser() |
199 | | { |
200 | | nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser); |
201 | | if (parser) { |
202 | | parser->UnblockParser(); |
203 | | } |
204 | | } |
205 | | |
206 | | /** |
207 | | * Attempts to resume parsing asynchronously |
208 | | */ |
209 | | void ContinueParserAsync() |
210 | | { |
211 | | nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser); |
212 | | if (parser) { |
213 | | parser->ContinueInterruptedParsingAsync(); |
214 | | } |
215 | | } |
216 | | |
217 | | /** |
218 | | * Informs the creator parser that the evaluation of this script is starting |
219 | | */ |
220 | | void BeginEvaluating() |
221 | | { |
222 | | nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser); |
223 | | if (parser) { |
224 | | parser->PushDefinedInsertionPoint(); |
225 | | } |
226 | | } |
227 | | |
228 | | /** |
229 | | * Informs the creator parser that the evaluation of this script is ending |
230 | | */ |
231 | | void EndEvaluating() |
232 | | { |
233 | | nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser); |
234 | | if (parser) { |
235 | | parser->PopDefinedInsertionPoint(); |
236 | | } |
237 | | } |
238 | | |
239 | | /** |
240 | | * Retrieves a pointer to the creator parser if this has one or null if not |
241 | | */ |
242 | | already_AddRefed<nsIParser> GetCreatorParser() |
243 | 0 | { |
244 | 0 | nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser); |
245 | 0 | return parser.forget(); |
246 | 0 | } |
247 | | |
248 | | /** |
249 | | * This method is called when the parser finishes creating the script |
250 | | * element's children, if any are present. |
251 | | * |
252 | | * @return whether the parser will be blocked while this script is being |
253 | | * loaded |
254 | | */ |
255 | | bool AttemptToExecute() |
256 | 0 | { |
257 | 0 | mDoneAddingChildren = true; |
258 | 0 | bool block = MaybeProcessScript(); |
259 | 0 | if (!mAlreadyStarted) { |
260 | 0 | // Need to lose parser-insertedness here to allow another script to cause |
261 | 0 | // execution later. |
262 | 0 | LoseParserInsertedness(); |
263 | 0 | } |
264 | 0 | return block; |
265 | 0 | } |
266 | | |
267 | | /** |
268 | | * Get the CORS mode of the script element |
269 | | */ |
270 | | virtual mozilla::CORSMode GetCORSMode() const |
271 | 0 | { |
272 | 0 | /* Default to no CORS */ |
273 | 0 | return mozilla::CORS_NONE; |
274 | 0 | } |
275 | | |
276 | | /** |
277 | | * Fire an error event |
278 | | */ |
279 | | virtual nsresult FireErrorEvent() = 0; |
280 | | |
281 | | protected: |
282 | | /** |
283 | | * Processes the script if it's in the document-tree and links to or |
284 | | * contains a script. Once it has been evaluated there is no way to make it |
285 | | * reevaluate the script, you'll have to create a new element. This also means |
286 | | * that when adding a src attribute to an element that already contains an |
287 | | * inline script, the script referenced by the src attribute will not be |
288 | | * loaded. |
289 | | * |
290 | | * In order to be able to use multiple childNodes, or to use the |
291 | | * fallback mechanism of using both inline script and linked script you have |
292 | | * to add all attributes and childNodes before adding the element to the |
293 | | * document-tree. |
294 | | * |
295 | | * @return whether the parser will be blocked while this script is being |
296 | | * loaded |
297 | | */ |
298 | | virtual bool MaybeProcessScript() = 0; |
299 | | |
300 | | /** |
301 | | * Since we've removed the XPCOM interface to HTML elements, we need a way to |
302 | | * retreive async state from script elements without bringing the type in. |
303 | | */ |
304 | | virtual bool GetAsyncState() = 0; |
305 | | |
306 | | /** |
307 | | * The start line number of the script. |
308 | | */ |
309 | | uint32_t mLineNumber; |
310 | | |
311 | | /** |
312 | | * The start column number of the script. |
313 | | */ |
314 | | uint32_t mColumnNumber; |
315 | | |
316 | | /** |
317 | | * The "already started" flag per HTML5. |
318 | | */ |
319 | | bool mAlreadyStarted; |
320 | | |
321 | | /** |
322 | | * The script didn't have an end tag. |
323 | | */ |
324 | | bool mMalformed; |
325 | | |
326 | | /** |
327 | | * False if parser-inserted but the parser hasn't triggered running yet. |
328 | | */ |
329 | | bool mDoneAddingChildren; |
330 | | |
331 | | /** |
332 | | * If true, the .async property returns true instead of reflecting the |
333 | | * content attribute. |
334 | | */ |
335 | | bool mForceAsync; |
336 | | |
337 | | /** |
338 | | * Whether src, defer and async are frozen. |
339 | | */ |
340 | | bool mFrozen; |
341 | | |
342 | | /** |
343 | | * The effective moduleness. |
344 | | */ |
345 | | bool mIsModule; |
346 | | |
347 | | /** |
348 | | * The effective deferredness. |
349 | | */ |
350 | | bool mDefer; |
351 | | |
352 | | /** |
353 | | * The effective asyncness. |
354 | | */ |
355 | | bool mAsync; |
356 | | |
357 | | /** |
358 | | * The effective externalness. A script can be external with mUri being null |
359 | | * if the src attribute contained an invalid URL string. |
360 | | */ |
361 | | bool mExternal; |
362 | | |
363 | | /** |
364 | | * Whether this element was parser-created. |
365 | | */ |
366 | | mozilla::dom::FromParser mParserCreated; |
367 | | |
368 | | /** |
369 | | * The effective src (or null if no src). |
370 | | */ |
371 | | nsCOMPtr<nsIURI> mUri; |
372 | | |
373 | | /** |
374 | | * The triggering principal for the src URL. |
375 | | */ |
376 | | nsCOMPtr<nsIPrincipal> mSrcTriggeringPrincipal; |
377 | | |
378 | | /** |
379 | | * The creator parser of a non-defer, non-async parser-inserted script. |
380 | | */ |
381 | | nsWeakPtr mCreatorParser; |
382 | | }; |
383 | | |
384 | | NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptElement, NS_ISCRIPTELEMENT_IID) |
385 | | |
386 | | #endif // nsIScriptElement_h___ |