Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/script/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
  {
53
  }
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
0
  {
68
0
    MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
69
0
    return mUri;
70
0
  }
71
72
  nsIPrincipal* GetScriptURITriggeringPrincipal()
73
0
  {
74
0
    MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
75
0
    return mSrcTriggeringPrincipal;
76
0
  }
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
0
  {
101
0
    MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
102
0
    return mIsModule;
103
0
  }
104
105
  /**
106
   * Is the script deferred. Currently only supported by HTML scripts.
107
   */
108
  bool GetScriptDeferred()
109
  {
110
    MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
111
    return mDefer;
112
  }
113
114
  /**
115
   * Is the script async. Currently only supported by HTML scripts.
116
   */
117
  bool GetScriptAsync()
118
  {
119
    MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
120
    return mAsync;
121
  }
122
123
  /**
124
   * Is the script an external script?
125
   */
126
  bool GetScriptExternal()
127
0
  {
128
0
    MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
129
0
    return mExternal;
130
0
  }
131
132
  /**
133
   * Returns how the element was created.
134
   */
135
  mozilla::dom::FromParser GetParserCreated()
136
  {
137
    return mParserCreated;
138
  }
139
140
  void SetScriptLineNumber(uint32_t aLineNumber)
141
  {
142
    mLineNumber = aLineNumber;
143
  }
144
145
  uint32_t GetScriptLineNumber()
146
  {
147
    return mLineNumber;
148
  }
149
150
  void SetScriptColumnNumber(uint32_t aColumnNumber)
151
  {
152
    mColumnNumber = aColumnNumber;
153
  }
154
155
  uint32_t GetScriptColumnNumber()
156
  {
157
    return mColumnNumber;
158
  }
159
160
  void SetIsMalformed()
161
  {
162
    mMalformed = true;
163
  }
164
165
  bool IsMalformed()
166
  {
167
    return mMalformed;
168
  }
169
170
  void PreventExecution()
171
  {
172
    mAlreadyStarted = true;
173
  }
174
175
  void LoseParserInsertedness()
176
  {
177
    mUri = nullptr;
178
    mCreatorParser = nullptr;
179
    mParserCreated = mozilla::dom::NOT_FROM_PARSER;
180
    mForceAsync = !GetAsyncState();
181
182
    // Reset state set by FreezeExecutionAttrs().
183
    mFrozen = false;
184
    mIsModule = false;
185
    mExternal = false;
186
    mAsync = false;
187
    mDefer = false;
188
  }
189
190
  void SetCreatorParser(nsIParser* aParser)
191
  {
192
    mCreatorParser = do_GetWeakReference(aParser);
193
  }
194
195
  /**
196
   * Unblocks the creator parser
197
   */
198
  void UnblockParser()
199
0
  {
200
0
    nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
201
0
    if (parser) {
202
0
      parser->UnblockParser();
203
0
    }
204
0
  }
205
206
  /**
207
   * Attempts to resume parsing asynchronously
208
   */
209
  void ContinueParserAsync()
210
0
  {
211
0
    nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
212
0
    if (parser) {
213
0
      parser->ContinueInterruptedParsingAsync();
214
0
    }
215
0
  }
216
217
  /**
218
   * Informs the creator parser that the evaluation of this script is starting
219
   */
220
  void BeginEvaluating()
221
0
  {
222
0
    nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
223
0
    if (parser) {
224
0
      parser->PushDefinedInsertionPoint();
225
0
    }
226
0
  }
227
228
  /**
229
   * Informs the creator parser that the evaluation of this script is ending
230
   */
231
  void EndEvaluating()
232
0
  {
233
0
    nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
234
0
    if (parser) {
235
0
      parser->PopDefinedInsertionPoint();
236
0
    }
237
0
  }
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
  {
244
    nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
245
    return parser.forget();
246
  }
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
  {
257
    mDoneAddingChildren = true;
258
    bool block = MaybeProcessScript();
259
    if (!mAlreadyStarted) {
260
      // Need to lose parser-insertedness here to allow another script to cause
261
      // execution later.
262
      LoseParserInsertedness();
263
    }
264
    return block;
265
  }
266
267
  /**
268
   * Get the CORS mode of the script element
269
   */
270
  virtual mozilla::CORSMode GetCORSMode() const
271
  {
272
    /* Default to no CORS */
273
    return mozilla::CORS_NONE;
274
  }
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___