1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications.
19 : * Portions created by the Initial Developer are Copyright (C) 2001
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Vidur Apparao <vidur@netscape.com> (original author)
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #ifndef nsIScriptElement_h___
40 : #define nsIScriptElement_h___
41 :
42 : #include "nsISupports.h"
43 : #include "nsIURI.h"
44 : #include "nsCOMPtr.h"
45 : #include "nsIScriptLoaderObserver.h"
46 : #include "nsWeakPtr.h"
47 : #include "nsIParser.h"
48 : #include "nsContentCreatorFunctions.h"
49 : #include "nsIDOMHTMLScriptElement.h"
50 : #include "mozilla/CORSMode.h"
51 :
52 : #define NS_ISCRIPTELEMENT_IID \
53 : { 0x24ab3ff2, 0xd75e, 0x4be4, \
54 : { 0x8d, 0x50, 0xd6, 0x75, 0x31, 0x29, 0xab, 0x65 } }
55 :
56 : /**
57 : * Internal interface implemented by script elements
58 : */
59 0 : class nsIScriptElement : public nsIScriptLoaderObserver {
60 : public:
61 : NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTELEMENT_IID)
62 :
63 0 : nsIScriptElement(mozilla::dom::FromParser aFromParser)
64 : : mLineNumber(0),
65 : mAlreadyStarted(false),
66 : mMalformed(false),
67 : mDoneAddingChildren(aFromParser == mozilla::dom::NOT_FROM_PARSER ||
68 : aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT),
69 : mForceAsync(aFromParser == mozilla::dom::NOT_FROM_PARSER ||
70 : aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT),
71 : mFrozen(false),
72 : mDefer(false),
73 : mAsync(false),
74 : mExternal(false),
75 : mParserCreated(aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT ?
76 : mozilla::dom::NOT_FROM_PARSER : aFromParser),
77 : // Fragment parser-created scripts (if executable)
78 : // behave like script-created scripts.
79 0 : mCreatorParser(nsnull)
80 : {
81 0 : }
82 :
83 : /**
84 : * Content type identifying the scripting language. Can be empty, in
85 : * which case javascript will be assumed.
86 : */
87 : virtual void GetScriptType(nsAString& type) = 0;
88 :
89 : /**
90 : * Location of script source text. Can return null, in which case
91 : * this is assumed to be an inline script element.
92 : */
93 0 : nsIURI* GetScriptURI()
94 : {
95 0 : NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
96 0 : return mUri;
97 : }
98 :
99 : /**
100 : * Script source text for inline script elements.
101 : */
102 : virtual void GetScriptText(nsAString& text) = 0;
103 :
104 : virtual void GetScriptCharset(nsAString& charset) = 0;
105 :
106 : /**
107 : * Freezes the return values of GetScriptDeferred(), GetScriptAsync() and
108 : * GetScriptURI() so that subsequent modifications to the attributes don't
109 : * change execution behavior.
110 : */
111 : virtual void FreezeUriAsyncDefer() = 0;
112 :
113 : /**
114 : * Is the script deferred. Currently only supported by HTML scripts.
115 : */
116 0 : bool GetScriptDeferred()
117 : {
118 0 : NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
119 0 : return mDefer;
120 : }
121 :
122 : /**
123 : * Is the script async. Currently only supported by HTML scripts.
124 : */
125 0 : bool GetScriptAsync()
126 : {
127 0 : NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
128 0 : return mAsync;
129 : }
130 :
131 : /**
132 : * Is the script an external script?
133 : */
134 0 : bool GetScriptExternal()
135 : {
136 0 : NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
137 0 : return mExternal;
138 : }
139 :
140 : /**
141 : * Returns how the element was created.
142 : */
143 0 : mozilla::dom::FromParser GetParserCreated()
144 : {
145 0 : return mParserCreated;
146 : }
147 :
148 0 : void SetScriptLineNumber(PRUint32 aLineNumber)
149 : {
150 0 : mLineNumber = aLineNumber;
151 0 : }
152 0 : PRUint32 GetScriptLineNumber()
153 : {
154 0 : return mLineNumber;
155 : }
156 :
157 0 : void SetIsMalformed()
158 : {
159 0 : mMalformed = true;
160 0 : }
161 0 : bool IsMalformed()
162 : {
163 0 : return mMalformed;
164 : }
165 :
166 0 : void PreventExecution()
167 : {
168 0 : mAlreadyStarted = true;
169 0 : }
170 :
171 0 : void LoseParserInsertedness()
172 : {
173 0 : mFrozen = false;
174 0 : mUri = nsnull;
175 0 : mCreatorParser = nsnull;
176 0 : mParserCreated = mozilla::dom::NOT_FROM_PARSER;
177 0 : bool async = false;
178 0 : nsCOMPtr<nsIDOMHTMLScriptElement> htmlScript = do_QueryInterface(this);
179 0 : if (htmlScript) {
180 0 : htmlScript->GetAsync(&async);
181 : }
182 0 : mForceAsync = !async;
183 0 : }
184 :
185 0 : void SetCreatorParser(nsIParser* aParser)
186 : {
187 0 : mCreatorParser = getter_AddRefs(NS_GetWeakReference(aParser));
188 0 : }
189 :
190 : /**
191 : * Unblocks the creator parser
192 : */
193 0 : void UnblockParser()
194 : {
195 0 : nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
196 0 : if (parser) {
197 0 : parser->UnblockParser();
198 : }
199 0 : }
200 :
201 : /**
202 : * Attempts to resume parsing asynchronously
203 : */
204 0 : void ContinueParserAsync()
205 : {
206 0 : nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
207 0 : if (parser) {
208 0 : parser->ContinueInterruptedParsingAsync();
209 : }
210 0 : }
211 :
212 : /**
213 : * Informs the creator parser that the evaluation of this script is starting
214 : */
215 0 : void BeginEvaluating()
216 : {
217 0 : nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
218 0 : if (parser) {
219 0 : parser->BeginEvaluatingParserInsertedScript();
220 : }
221 0 : }
222 :
223 : /**
224 : * Informs the creator parser that the evaluation of this script is ending
225 : */
226 0 : void EndEvaluating()
227 : {
228 0 : nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
229 0 : if (parser) {
230 0 : parser->EndEvaluatingParserInsertedScript();
231 : }
232 0 : }
233 :
234 : /**
235 : * Retrieves a pointer to the creator parser if this has one or null if not
236 : */
237 0 : already_AddRefed<nsIParser> GetCreatorParser()
238 : {
239 0 : nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser);
240 0 : return parser.forget();
241 : }
242 :
243 : /**
244 : * This method is called when the parser finishes creating the script
245 : * element's children, if any are present.
246 : *
247 : * @return whether the parser will be blocked while this script is being
248 : * loaded
249 : */
250 0 : bool AttemptToExecute()
251 : {
252 0 : mDoneAddingChildren = true;
253 0 : bool block = MaybeProcessScript();
254 0 : if (!mAlreadyStarted) {
255 : // Need to lose parser-insertedness here to allow another script to cause
256 : // execution later.
257 0 : LoseParserInsertedness();
258 : }
259 0 : return block;
260 : }
261 :
262 : /**
263 : * Get the CORS mode of the script element
264 : */
265 0 : virtual mozilla::CORSMode GetCORSMode() const
266 : {
267 : /* Default to no CORS */
268 0 : return mozilla::CORS_NONE;
269 : }
270 :
271 : protected:
272 : /**
273 : * Processes the script if it's in the document-tree and links to or
274 : * contains a script. Once it has been evaluated there is no way to make it
275 : * reevaluate the script, you'll have to create a new element. This also means
276 : * that when adding a src attribute to an element that already contains an
277 : * inline script, the script referenced by the src attribute will not be
278 : * loaded.
279 : *
280 : * In order to be able to use multiple childNodes, or to use the
281 : * fallback mechanism of using both inline script and linked script you have
282 : * to add all attributes and childNodes before adding the element to the
283 : * document-tree.
284 : *
285 : * @return whether the parser will be blocked while this script is being
286 : * loaded
287 : */
288 : virtual bool MaybeProcessScript() = 0;
289 :
290 : /**
291 : * The start line number of the script.
292 : */
293 : PRUint32 mLineNumber;
294 :
295 : /**
296 : * The "already started" flag per HTML5.
297 : */
298 : bool mAlreadyStarted;
299 :
300 : /**
301 : * The script didn't have an end tag.
302 : */
303 : bool mMalformed;
304 :
305 : /**
306 : * False if parser-inserted but the parser hasn't triggered running yet.
307 : */
308 : bool mDoneAddingChildren;
309 :
310 : /**
311 : * If true, the .async property returns true instead of reflecting the
312 : * content attribute.
313 : */
314 : bool mForceAsync;
315 :
316 : /**
317 : * Whether src, defer and async are frozen.
318 : */
319 : bool mFrozen;
320 :
321 : /**
322 : * The effective deferredness.
323 : */
324 : bool mDefer;
325 :
326 : /**
327 : * The effective asyncness.
328 : */
329 : bool mAsync;
330 :
331 : /**
332 : * The effective externalness. A script can be external with mUri being null
333 : * if the src attribute contained an invalid URL string.
334 : */
335 : bool mExternal;
336 :
337 : /**
338 : * Whether this element was parser-created.
339 : */
340 : mozilla::dom::FromParser mParserCreated;
341 :
342 : /**
343 : * The effective src (or null if no src).
344 : */
345 : nsCOMPtr<nsIURI> mUri;
346 :
347 : /**
348 : * The creator parser of a non-defer, non-async parser-inserted script.
349 : */
350 : nsWeakPtr mCreatorParser;
351 : };
352 :
353 : NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptElement, NS_ISCRIPTELEMENT_IID)
354 :
355 : #endif // nsIScriptElement_h___
|