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
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/
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
15 * The Original Code is Mozilla.
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.
23 * Vidur Apparao <vidur@netscape.com> (original author)
25 * Alternatively, the contents of this file may be used under the terms of
26 * either of the GNU General Public License Version 2 or later (the "GPL"),
27 * or 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.
37 * ***** END LICENSE BLOCK ***** */
40 * A class that handles loading and evaluation of <script> elements.
43 #ifndef __nsScriptLoader_h__
44 #define __nsScriptLoader_h__
47 #include "nsIScriptElement.h"
49 #include "nsCOMArray.h"
51 #include "nsAutoPtr.h"
52 #include "nsIDocument.h"
53 #include "nsIStreamLoader.h"
55 class nsScriptLoadRequest
;
57 //////////////////////////////////////////////////////////////
58 // Script loader implementation
59 //////////////////////////////////////////////////////////////
61 class nsScriptLoader
: public nsIStreamLoaderObserver
64 nsScriptLoader(nsIDocument
* aDocument
);
65 virtual ~nsScriptLoader();
68 NS_DECL_NSISTREAMLOADEROBSERVER
71 * The loader maintains a weak reference to the document with
72 * which it is initialized. This call forces the reference to
75 void DropDocumentReference()
81 * Add an observer for all scripts loaded through this loader.
83 * @param aObserver observer for all script processing.
85 nsresult
AddObserver(nsIScriptLoaderObserver
* aObserver
)
87 return mObservers
.AppendObject(aObserver
) ? NS_OK
:
88 NS_ERROR_OUT_OF_MEMORY
;
94 * @param aObserver observer to be removed
96 void RemoveObserver(nsIScriptLoaderObserver
* aObserver
)
98 mObservers
.RemoveObject(aObserver
);
102 * Process a script element. This will include both loading the
103 * source of the element if it is not inline and evaluating
106 * If the script is an inline script that can be executed immediately
107 * (i.e. there are no other scripts pending) then ScriptAvailable
108 * and ScriptEvaluated will be called before the function returns.
110 * If NS_ERROR_HTMLPARSER_BLOCK is returned the script could not be
111 * executed immediately. In this case ScriptAvailable is guaranteed
112 * to be called at a later point (as well as possibly ScriptEvaluated).
114 * @param aElement The element representing the script to be loaded and
117 nsresult
ProcessScriptElement(nsIScriptElement
* aElement
);
120 * Gets the currently executing script. This is useful if you want to
121 * generate a unique key based on the currently executing script.
123 nsIScriptElement
* GetCurrentScript()
125 return mCurrentScript
;
129 * Whether the loader is enabled or not.
130 * When disabled, processing of new script elements is disabled.
131 * Any call to ProcessScriptElement() will fail with a return code of
132 * NS_ERROR_NOT_AVAILABLE. Note that this DOES NOT disable
133 * currently loading or executing scripts.
139 void SetEnabled(PRBool aEnabled
)
141 if (!mEnabled
&& aEnabled
) {
142 ProcessPendingRequestsAsync();
148 * Add/remove blocker. Blockers will stop scripts from executing, but not
151 void AddExecuteBlocker()
155 void RemoveExecuteBlocker()
157 if (!--mBlockerCount
) {
158 ProcessPendingRequestsAsync();
163 * Convert the given buffer to a UTF-16 string.
164 * @param aChannel Channel corresponding to the data. May be null.
165 * @param aData The data to convert
166 * @param aLength Length of the data
167 * @param aHintCharset Hint for the character set (e.g., from a charset
168 * attribute). May be the empty string.
169 * @param aDocument Document which the data is loaded for. Must not be
171 * @param aString [out] Data as converted to unicode
173 static nsresult
ConvertToUTF16(nsIChannel
* aChannel
, const PRUint8
* aData
,
175 const nsString
& aHintCharset
,
176 nsIDocument
* aDocument
, nsString
& aString
);
179 * Processes any pending requests that are ready for processing.
181 void ProcessPendingRequests();
184 * Check whether it's OK to execute a script loaded via aChannel in
187 static PRBool
ShouldExecuteScript(nsIDocument
* aDocument
,
188 nsIChannel
* aChannel
);
191 * Starts deferring deferred scripts and puts them in the mDeferredRequests
194 void BeginDeferringScripts()
196 mDeferEnabled
= PR_TRUE
;
200 * Stops defering scripts and immediately processes the mDeferredRequests
203 * WARNING: This function will syncronously execute content scripts, so be
204 * prepared that the world might change around you.
206 void EndDeferringScripts();
209 * Adds aURI to the preload list and starts loading it.
211 * @param aURI The URI of the external script.
212 * @param aCharset The charset parameter for the script.
213 * @param aType The type parameter for the script.
215 virtual void PreloadURI(nsIURI
*aURI
, const nsAString
&aCharset
,
216 const nsAString
&aType
);
220 * Helper function to check the content policy for a given request.
222 nsresult
CheckContentPolicy(nsScriptLoadRequest
*aRequest
,
223 nsISupports
*aContext
,
224 const nsAString
&aType
);
227 * Start a load for aRequest's URI.
229 nsresult
StartLoad(nsScriptLoadRequest
*aRequest
, const nsAString
&aType
);
232 * Process any pending requests asyncronously (i.e. off an event) if there
233 * are any. Note that this is a no-op if there aren't any currently pending
236 virtual void ProcessPendingRequestsAsync();
239 * If true, the loader is ready to execute scripts, and so are all its
240 * ancestors. If the loader itself is ready but some ancestor is not, this
241 * function will add an execute blocker and ask the ancestor to remove it
242 * once it becomes ready.
244 PRBool
ReadyToExecuteScripts();
247 * Return whether just this loader is ready to execute scripts.
249 PRBool
SelfReadyToExecuteScripts()
251 return mEnabled
&& !mBlockerCount
;
254 PRBool
AddPendingChildLoader(nsScriptLoader
* aChild
) {
255 return mPendingChildLoaders
.AppendElement(aChild
) != nsnull
;
258 nsresult
ProcessRequest(nsScriptLoadRequest
* aRequest
);
259 void FireScriptAvailable(nsresult aResult
,
260 nsScriptLoadRequest
* aRequest
);
261 void FireScriptEvaluated(nsresult aResult
,
262 nsScriptLoadRequest
* aRequest
);
263 nsresult
EvaluateScript(nsScriptLoadRequest
* aRequest
,
264 const nsAFlatString
& aScript
);
266 nsresult
PrepareLoadedRequest(nsScriptLoadRequest
* aRequest
,
267 nsIStreamLoader
* aLoader
,
270 const PRUint8
* aString
);
272 // Returns the first pending (non deferred) request
273 nsScriptLoadRequest
* GetFirstPendingRequest();
275 nsIDocument
* mDocument
; // [WEAK]
276 nsCOMArray
<nsIScriptLoaderObserver
> mObservers
;
277 nsCOMArray
<nsScriptLoadRequest
> mRequests
;
279 // In mRequests, the additional information here is stored by the element.
281 nsRefPtr
<nsScriptLoadRequest
> mRequest
;
285 struct PreloadRequestComparator
{
286 PRBool
Equals(const PreloadInfo
&aPi
, nsScriptLoadRequest
* const &aRequest
)
289 return aRequest
== aPi
.mRequest
;
292 struct PreloadURIComparator
{
293 PRBool
Equals(const PreloadInfo
&aPi
, nsIURI
* const &aURI
) const;
295 nsTArray
<PreloadInfo
> mPreloads
;
297 nsCOMPtr
<nsIScriptElement
> mCurrentScript
;
298 // XXXbz do we want to cycle-collect these or something? Not sure.
299 nsTArray
< nsRefPtr
<nsScriptLoader
> > mPendingChildLoaders
;
300 PRUint32 mBlockerCount
;
301 PRPackedBool mEnabled
;
302 PRPackedBool mDeferEnabled
;
305 #endif //__nsScriptLoader_h__