Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsIScriptElement_h___
7 #define nsIScriptElement_h___
9 #include "nsISupports.h"
10 #include "nsIURI.h"
11 #include "nsCOMPtr.h"
12 #include "nsIScriptLoaderObserver.h"
13 #include "nsWeakPtr.h"
14 #include "nsIParser.h"
15 #include "nsContentCreatorFunctions.h"
16 #include "nsIDOMHTMLScriptElement.h"
17 #include "mozilla/CORSMode.h"
19 #define NS_ISCRIPTELEMENT_IID \
20 { 0x491628bc, 0xce7c, 0x4db4, \
21 { 0x93, 0x3f, 0xce, 0x1b, 0x75, 0xee, 0x75, 0xce } }
23 /**
24 * Internal interface implemented by script elements
25 */
26 class nsIScriptElement : public nsIScriptLoaderObserver {
27 public:
28 NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTELEMENT_IID)
30 nsIScriptElement(mozilla::dom::FromParser aFromParser)
31 : mLineNumber(0),
32 mAlreadyStarted(false),
33 mMalformed(false),
34 mDoneAddingChildren(aFromParser == mozilla::dom::NOT_FROM_PARSER ||
35 aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT),
36 mForceAsync(aFromParser == mozilla::dom::NOT_FROM_PARSER ||
37 aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT),
38 mFrozen(false),
39 mDefer(false),
40 mAsync(false),
41 mExternal(false),
42 mParserCreated(aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT ?
43 mozilla::dom::NOT_FROM_PARSER : aFromParser),
44 // Fragment parser-created scripts (if executable)
45 // behave like script-created scripts.
46 mCreatorParser(nullptr)
47 {
48 }
50 /**
51 * Content type identifying the scripting language. Can be empty, in
52 * which case javascript will be assumed.
53 */
54 virtual void GetScriptType(nsAString& type) = 0;
56 /**
57 * Location of script source text. Can return null, in which case
58 * this is assumed to be an inline script element.
59 */
60 nsIURI* GetScriptURI()
61 {
62 NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
63 return mUri;
64 }
66 /**
67 * Script source text for inline script elements.
68 */
69 virtual void GetScriptText(nsAString& text) = 0;
71 virtual void GetScriptCharset(nsAString& charset) = 0;
73 /**
74 * Freezes the return values of GetScriptDeferred(), GetScriptAsync() and
75 * GetScriptURI() so that subsequent modifications to the attributes don't
76 * change execution behavior.
77 */
78 virtual void FreezeUriAsyncDefer() = 0;
80 /**
81 * Is the script deferred. Currently only supported by HTML scripts.
82 */
83 bool GetScriptDeferred()
84 {
85 NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
86 return mDefer;
87 }
89 /**
90 * Is the script async. Currently only supported by HTML scripts.
91 */
92 bool GetScriptAsync()
93 {
94 NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
95 return mAsync;
96 }
98 /**
99 * Is the script an external script?
100 */
101 bool GetScriptExternal()
102 {
103 NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
104 return mExternal;
105 }
107 /**
108 * Returns how the element was created.
109 */
110 mozilla::dom::FromParser GetParserCreated()
111 {
112 return mParserCreated;
113 }
115 void SetScriptLineNumber(uint32_t aLineNumber)
116 {
117 mLineNumber = aLineNumber;
118 }
119 uint32_t GetScriptLineNumber()
120 {
121 return mLineNumber;
122 }
124 void SetIsMalformed()
125 {
126 mMalformed = true;
127 }
128 bool IsMalformed()
129 {
130 return mMalformed;
131 }
133 void PreventExecution()
134 {
135 mAlreadyStarted = true;
136 }
138 void LoseParserInsertedness()
139 {
140 mFrozen = false;
141 mUri = nullptr;
142 mCreatorParser = nullptr;
143 mParserCreated = mozilla::dom::NOT_FROM_PARSER;
144 bool async = false;
145 nsCOMPtr<nsIDOMHTMLScriptElement> htmlScript = do_QueryInterface(this);
146 if (htmlScript) {
147 htmlScript->GetAsync(&async);
148 }
149 mForceAsync = !async;
150 }
152 void SetCreatorParser(nsIParser* aParser)
153 {
154 mCreatorParser = do_GetWeakReference(aParser);
155 }
157 /**
158 * Unblocks the creator parser
159 */
160 void UnblockParser()
161 {
162 nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
163 if (parser) {
164 parser->UnblockParser();
165 }
166 }
168 /**
169 * Attempts to resume parsing asynchronously
170 */
171 void ContinueParserAsync()
172 {
173 nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
174 if (parser) {
175 parser->ContinueInterruptedParsingAsync();
176 }
177 }
179 /**
180 * Informs the creator parser that the evaluation of this script is starting
181 */
182 void BeginEvaluating()
183 {
184 nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
185 if (parser) {
186 parser->BeginEvaluatingParserInsertedScript();
187 }
188 }
190 /**
191 * Informs the creator parser that the evaluation of this script is ending
192 */
193 void EndEvaluating()
194 {
195 nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
196 if (parser) {
197 parser->EndEvaluatingParserInsertedScript();
198 }
199 }
201 /**
202 * Retrieves a pointer to the creator parser if this has one or null if not
203 */
204 already_AddRefed<nsIParser> GetCreatorParser()
205 {
206 nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
207 return parser.forget();
208 }
210 /**
211 * This method is called when the parser finishes creating the script
212 * element's children, if any are present.
213 *
214 * @return whether the parser will be blocked while this script is being
215 * loaded
216 */
217 bool AttemptToExecute()
218 {
219 mDoneAddingChildren = true;
220 bool block = MaybeProcessScript();
221 if (!mAlreadyStarted) {
222 // Need to lose parser-insertedness here to allow another script to cause
223 // execution later.
224 LoseParserInsertedness();
225 }
226 return block;
227 }
229 /**
230 * Get the CORS mode of the script element
231 */
232 virtual mozilla::CORSMode GetCORSMode() const
233 {
234 /* Default to no CORS */
235 return mozilla::CORS_NONE;
236 }
238 /**
239 * Fire an error event
240 */
241 virtual nsresult FireErrorEvent() = 0;
243 protected:
244 /**
245 * Processes the script if it's in the document-tree and links to or
246 * contains a script. Once it has been evaluated there is no way to make it
247 * reevaluate the script, you'll have to create a new element. This also means
248 * that when adding a src attribute to an element that already contains an
249 * inline script, the script referenced by the src attribute will not be
250 * loaded.
251 *
252 * In order to be able to use multiple childNodes, or to use the
253 * fallback mechanism of using both inline script and linked script you have
254 * to add all attributes and childNodes before adding the element to the
255 * document-tree.
256 *
257 * @return whether the parser will be blocked while this script is being
258 * loaded
259 */
260 virtual bool MaybeProcessScript() = 0;
262 /**
263 * The start line number of the script.
264 */
265 uint32_t mLineNumber;
267 /**
268 * The "already started" flag per HTML5.
269 */
270 bool mAlreadyStarted;
272 /**
273 * The script didn't have an end tag.
274 */
275 bool mMalformed;
277 /**
278 * False if parser-inserted but the parser hasn't triggered running yet.
279 */
280 bool mDoneAddingChildren;
282 /**
283 * If true, the .async property returns true instead of reflecting the
284 * content attribute.
285 */
286 bool mForceAsync;
288 /**
289 * Whether src, defer and async are frozen.
290 */
291 bool mFrozen;
293 /**
294 * The effective deferredness.
295 */
296 bool mDefer;
298 /**
299 * The effective asyncness.
300 */
301 bool mAsync;
303 /**
304 * The effective externalness. A script can be external with mUri being null
305 * if the src attribute contained an invalid URL string.
306 */
307 bool mExternal;
309 /**
310 * Whether this element was parser-created.
311 */
312 mozilla::dom::FromParser mParserCreated;
314 /**
315 * The effective src (or null if no src).
316 */
317 nsCOMPtr<nsIURI> mUri;
319 /**
320 * The creator parser of a non-defer, non-async parser-inserted script.
321 */
322 nsWeakPtr mCreatorParser;
323 };
325 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptElement, NS_ISCRIPTELEMENT_IID)
327 #endif // nsIScriptElement_h___