diff --git a/mozilla/content/base/public/MANIFEST_IDL b/mozilla/content/base/public/MANIFEST_IDL index 158c001a268..ffed46f129b 100644 --- a/mozilla/content/base/public/MANIFEST_IDL +++ b/mozilla/content/base/public/MANIFEST_IDL @@ -8,3 +8,5 @@ nsISelection.idl nsISelectionController.idl nsISelectionListener.idl nsISelectionPrivate.idl +nsIScriptLoader.idl +nsIScriptLoaderObserver.idl diff --git a/mozilla/content/base/public/Makefile.in b/mozilla/content/base/public/Makefile.in index e916c045f1c..cd121d7eb13 100644 --- a/mozilla/content/base/public/Makefile.in +++ b/mozilla/content/base/public/Makefile.in @@ -64,6 +64,8 @@ XPIDLSRCS = \ nsISelectionListener.idl \ nsISelection.idl \ nsISelectionPrivate.idl \ + nsIScriptLoader.idl \ + nsIScriptLoaderObserver.idl \ $(NULL) EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS)) diff --git a/mozilla/content/base/public/makefile.win b/mozilla/content/base/public/makefile.win index 06105b5df55..2d76798520d 100644 --- a/mozilla/content/base/public/makefile.win +++ b/mozilla/content/base/public/makefile.win @@ -58,6 +58,8 @@ XPIDLSRCS= \ .\nsISelectionListener.idl \ .\nsISelection.idl \ .\nsISelectionPrivate.idl \ + .\nsIScriptLoader.idl \ + .\nsIScriptLoaderObserver.idl \ $(NULL) diff --git a/mozilla/content/base/public/nsIDocument.h b/mozilla/content/base/public/nsIDocument.h index 23a57043a87..93631deafb9 100644 --- a/mozilla/content/base/public/nsIDocument.h +++ b/mozilla/content/base/public/nsIDocument.h @@ -61,6 +61,7 @@ class nsIDOMDocumentType; class nsIBindingManager; class nsIObserver; class nsISupportsArray; +class nsIScriptLoader; class nsString; // IID for the nsIDocument interface @@ -254,6 +255,11 @@ public: */ NS_IMETHOD GetNameSpaceManager(nsINameSpaceManager*& aManager) = 0; + /** + * Get the script loader for this document + */ + NS_IMETHOD GetScriptLoader(nsIScriptLoader** aScriptLoader) = 0; + //---------------------------------------------------------------------- // Document notification API's diff --git a/mozilla/content/base/src/Makefile.in b/mozilla/content/base/src/Makefile.in index ade10483dcb..6075720c2fb 100644 --- a/mozilla/content/base/src/Makefile.in +++ b/mozilla/content/base/src/Makefile.in @@ -60,6 +60,7 @@ CPPSRCS = \ nsHTMLContentSerializer.cpp \ nsParserUtils.cpp \ nsPlainTextSerializer.cpp \ + nsScriptLoader.cpp \ $(NULL) # we don't want the shared lib, but we want to force the creation of a static lib. diff --git a/mozilla/content/base/src/makefile.win b/mozilla/content/base/src/makefile.win index b01e5c7e7a8..f54f6791fb9 100644 --- a/mozilla/content/base/src/makefile.win +++ b/mozilla/content/base/src/makefile.win @@ -57,7 +57,8 @@ CPPSRCS = \ nsHTMLContentSerializer.cpp \ nsParserUtils.cpp \ nsPlainTextSerializer.cpp \ - nsContentUtils.cpp \ + nsContentUtils.cpp \ + nsScriptLoader.cpp \ $(NULL) MODULE=raptor @@ -91,7 +92,8 @@ CPP_OBJS= \ .\$(OBJDIR)\nsHTMLContentSerializer.obj \ .\$(OBJDIR)\nsParserUtils.obj \ .\$(OBJDIR)\nsPlainTextSerializer.obj \ - .\$(OBJDIR)\nsContentUtils.obj \ + .\$(OBJDIR)\nsContentUtils.obj \ + .\$(OBJDIR)\nsScriptLoader.obj \ $(NULL) LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor \ diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index a8f15400ed0..5da0c1aa05a 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -310,7 +310,6 @@ nsDOMImplementation::~nsDOMImplementation() { } - // XPConnect interface list for nsDOMImplementation NS_CLASSINFO_MAP_BEGIN(DOMImplementation) NS_CLASSINFO_MAP_ENTRY(nsIDOMDOMImplementation) @@ -519,6 +518,10 @@ nsDocument::~nsDocument() NS_IF_RELEASE(mNameSpaceManager); + if (mScriptLoader) { + mScriptLoader->DropDocumentReference(); + } + mDOMStyleSheets = nsnull; // Release the stylesheets list. if (nsnull != mHeaderData) { @@ -1384,6 +1387,25 @@ nsDocument::GetNameSpaceManager(nsINameSpaceManager*& aManager) return NS_OK; } +NS_IMETHODIMP +nsDocument::GetScriptLoader(nsIScriptLoader** aScriptLoader) +{ + NS_ENSURE_ARG_POINTER(aScriptLoader); + + if (!mScriptLoader) { + nsScriptLoader* loader = new nsScriptLoader(); + if (!loader) { + return NS_ERROR_OUT_OF_MEMORY; + } + mScriptLoader = loader; + mScriptLoader->Init(this); + } + + *aScriptLoader = mScriptLoader; + NS_IF_ADDREF(*aScriptLoader); + + return NS_OK; +} // Note: We don't hold a reference to the document observer; we assume // that it has a live reference to the document. diff --git a/mozilla/content/base/src/nsDocument.h b/mozilla/content/base/src/nsDocument.h index 90709c5394d..de9981e9754 100644 --- a/mozilla/content/base/src/nsDocument.h +++ b/mozilla/content/base/src/nsDocument.h @@ -50,6 +50,7 @@ #include "nsILineBreakerFactory.h" #include "nsIScriptObjectPrincipal.h" #include "nsIURI.h" +#include "nsScriptLoader.h" class nsIEventListenerManager; class nsDOMStyleSheetList; @@ -385,6 +386,11 @@ public: */ NS_IMETHOD GetNameSpaceManager(nsINameSpaceManager*& aManager); + /** + * Get the script loader for this document + */ + NS_IMETHOD GetScriptLoader(nsIScriptLoader** aScriptLoader); + /** * Add a new observer of document change notifications. Whenever * content is changed, appended, inserted or removed the observers are @@ -540,6 +546,7 @@ protected: PRBool mInDestructor; nsCOMPtr mDOMStyleSheets; nsINameSpaceManager* mNameSpaceManager; + nsCOMPtr mScriptLoader; nsDocHeaderData* mHeaderData; nsCOMPtr mLineBreaker; nsCOMPtr mWordBreaker; diff --git a/mozilla/content/base/src/nsScriptLoader.cpp b/mozilla/content/base/src/nsScriptLoader.cpp index 6a54aeec0d5..20d39158e5b 100644 --- a/mozilla/content/base/src/nsScriptLoader.cpp +++ b/mozilla/content/base/src/nsScriptLoader.cpp @@ -57,7 +57,7 @@ public: nsScriptLoadRequest(nsIDOMHTMLScriptElement* aElement, nsIScriptLoaderObserver* aObserver, const char* aVersionString); - ~nsScriptLoadRequest(); + virtual ~nsScriptLoadRequest(); NS_DECL_ISUPPORTS @@ -81,8 +81,8 @@ nsScriptLoadRequest::nsScriptLoadRequest(nsIDOMHTMLScriptElement* aElement, nsIScriptLoaderObserver* aObserver, const char* aVersionString) : mElement(aElement), mObserver(aObserver), - mJSVersion(aVersionString), mLoading(PR_TRUE), mWasPending(PR_FALSE), - mIsInline(PR_TRUE), mLineNo(1) + mLoading(PR_TRUE), mWasPending(PR_FALSE), + mIsInline(PR_TRUE), mJSVersion(aVersionString), mLineNo(1) { NS_INIT_ISUPPORTS(); } diff --git a/mozilla/content/html/content/public/MANIFEST b/mozilla/content/html/content/public/MANIFEST index 1cba6fe2610..0f440c76d57 100644 --- a/mozilla/content/html/content/public/MANIFEST +++ b/mozilla/content/html/content/public/MANIFEST @@ -5,4 +5,4 @@ nsIForm.h nsIFormControl.h nsILink.h nsISelectElement.h - +nsIScriptElement.h diff --git a/mozilla/content/html/content/public/Makefile.in b/mozilla/content/html/content/public/Makefile.in index d23349c2830..52247c742d5 100644 --- a/mozilla/content/html/content/public/Makefile.in +++ b/mozilla/content/html/content/public/Makefile.in @@ -33,6 +33,7 @@ EXPORTS = \ nsIForm.h \ nsILink.h \ nsISelectElement.h \ + nsIScriptElement.h \ $(NULL) EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS)) diff --git a/mozilla/content/html/content/public/makefile.win b/mozilla/content/html/content/public/makefile.win index 53997e463cc..f65680caa0c 100644 --- a/mozilla/content/html/content/public/makefile.win +++ b/mozilla/content/html/content/public/makefile.win @@ -21,7 +21,8 @@ DEPTH=..\..\..\.. -EXPORTS=nsIFormControl.h nsIForm.h nsILink.h nsISelectElement.h +EXPORTS=nsIFormControl.h nsIForm.h nsILink.h \ + nsISelectElement.h nsIScriptElement.h MODULE=raptor diff --git a/mozilla/content/html/content/src/nsHTMLAtomList.h b/mozilla/content/html/content/src/nsHTMLAtomList.h index 0130c4207e2..ab3fa2efb19 100644 --- a/mozilla/content/html/content/src/nsHTMLAtomList.h +++ b/mozilla/content/html/content/src/nsHTMLAtomList.h @@ -201,6 +201,7 @@ HTML_ATOM(method, "method") HTML_ATOM(multicol, "multicol") HTML_ATOM(multiple, "multiple") HTML_ATOM(name, "name") +HTML_ATOM(noembed, "noembed") HTML_ATOM(noframes, "noframes") HTML_ATOM(nohref, "nohref") HTML_ATOM(noresize, "noresize") diff --git a/mozilla/content/html/content/src/nsHTMLScriptElement.cpp b/mozilla/content/html/content/src/nsHTMLScriptElement.cpp index 6f2ddea3740..4e441a04d17 100644 --- a/mozilla/content/html/content/src/nsHTMLScriptElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLScriptElement.cpp @@ -30,10 +30,15 @@ #include "nsStyleConsts.h" #include "nsIPresContext.h" #include "nsITextContent.h" - +#include "nsIDocument.h" +#include "nsIScriptLoader.h" +#include "nsIScriptLoaderObserver.h" +#include "nsIScriptElement.h" class nsHTMLScriptElement : public nsGenericHTMLContainerElement, - public nsIDOMHTMLScriptElement + public nsIDOMHTMLScriptElement, + public nsIScriptLoaderObserver, + public nsIScriptElement { public: nsHTMLScriptElement(); @@ -54,7 +59,20 @@ public: // nsIDOMHTMLScriptElement NS_DECL_NSIDOMHTMLSCRIPTELEMENT + // nsIScriptLoaderObserver + NS_DECL_NSISCRIPTLOADEROBSERVER + + // nsIScriptElement + NS_IMETHOD SetLineNumber(PRUint32 aLineNumber); + NS_IMETHOD GetLineNumber(PRUint32* aLineNumber); + + NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep, + PRBool aCompileEventHandlers); + NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const; + +protected: + PRUint32 mLineNumber; }; nsresult @@ -86,6 +104,7 @@ NS_NewHTMLScriptElement(nsIHTMLContent** aInstancePtrResult, nsHTMLScriptElement::nsHTMLScriptElement() { + mLineNumber = 0; } nsHTMLScriptElement::~nsHTMLScriptElement() @@ -96,21 +115,38 @@ nsHTMLScriptElement::~nsHTMLScriptElement() NS_IMPL_ADDREF_INHERITED(nsHTMLScriptElement, nsGenericElement) NS_IMPL_RELEASE_INHERITED(nsHTMLScriptElement, nsGenericElement) - // XPConnect interface list for nsHTMLScriptElement NS_CLASSINFO_MAP_BEGIN(HTMLScriptElement) NS_CLASSINFO_MAP_ENTRY(nsIDOMHTMLScriptElement) NS_CLASSINFO_MAP_ENTRY_FUNCTION(GetGenericHTMLElementIIDs) NS_CLASSINFO_MAP_END - // QueryInterface implementation for nsHTMLScriptElement NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLScriptElement, nsGenericHTMLContainerElement) NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLScriptElement) + NS_INTERFACE_MAP_ENTRY(nsIScriptLoaderObserver) + NS_INTERFACE_MAP_ENTRY(nsIScriptElement) NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLScriptElement) NS_HTML_CONTENT_INTERFACE_MAP_END +NS_IMETHODIMP +nsHTMLScriptElement::SetDocument(nsIDocument* aDocument, PRBool aDeep, + PRBool aCompileEventHandlers) +{ + nsresult rv = nsGenericHTMLContainerElement::SetDocument(aDocument, aDeep, + aCompileEventHandlers); + + if (NS_SUCCEEDED(rv) && mDocument && mParent) { + nsCOMPtr loader; + mDocument->GetScriptLoader(getter_AddRefs(loader)); + if (loader) { + loader->ProcessScriptElement(this, this); + } + } + + return rv; +} nsresult nsHTMLScriptElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) @@ -249,3 +285,44 @@ nsHTMLScriptElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const return NS_OK; } + +/* void scriptAvailable (in nsresult aResult, in nsIDOMHTMLScriptElement aElement, in nsIURI aURI, in PRInt32 aLineNo, in PRUint32 aScriptLength, [size_is (aScriptLength)] in wstring aScript); */ +NS_IMETHODIMP +nsHTMLScriptElement::ScriptAvailable(nsresult aResult, + nsIDOMHTMLScriptElement *aElement, + PRBool aIsInline, + PRBool aWasPending, + nsIURI *aURI, + PRInt32 aLineNo, + const nsAString& aScript) +{ + return NS_OK; +} + +/* void scriptEvaluated (in nsresult aResult, in nsIDOMHTMLScriptElement aElement); */ +NS_IMETHODIMP +nsHTMLScriptElement::ScriptEvaluated(nsresult aResult, + nsIDOMHTMLScriptElement *aElement, + PRBool aIsInline, + PRBool aWasPending) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLScriptElement::SetLineNumber(PRUint32 aLineNumber) +{ + mLineNumber = aLineNumber; + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLScriptElement::GetLineNumber(PRUint32* aLineNumber) +{ + NS_ENSURE_ARG_POINTER(aLineNumber); + + *aLineNumber = mLineNumber; + + return NS_OK; +} diff --git a/mozilla/content/html/document/src/nsHTMLContentSink.cpp b/mozilla/content/html/document/src/nsHTMLContentSink.cpp index bfff16437cb..1339133b444 100644 --- a/mozilla/content/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/content/html/document/src/nsHTMLContentSink.cpp @@ -30,11 +30,12 @@ #include "nsICSSStyleSheet.h" #include "nsICSSLoader.h" #include "nsICSSLoaderObserver.h" +#include "nsIScriptLoader.h" +#include "nsIScriptLoaderObserver.h" #include "nsIHTMLContent.h" #include "nsIHTMLContentContainer.h" #include "nsIUnicharInputStream.h" #include "nsIURL.h" -#include "nsIStreamLoader.h" #include "nsNetUtil.h" #include "nsIPresShell.h" #include "nsIPresContext.h" @@ -45,6 +46,7 @@ #include "nsHTMLTokens.h" #include "nsHTMLEntities.h" #include "nsCRT.h" +#include "nsSupportsArray.h" #include "jsapi.h" // for JSVERSION_* and JS_VersionToString #include "prtime.h" #include "prlog.h" @@ -58,6 +60,8 @@ #include "nsIDOMHTMLDocument.h" #include "nsIDOMDOMImplementation.h" #include "nsIDOMDocumentType.h" +#include "nsIDOMHTMLScriptElement.h" +#include "nsIScriptElement.h" #include "nsIDOMHTMLFormElement.h" #include "nsIDOMHTMLTextAreaElement.h" @@ -169,7 +173,7 @@ static PRLogModuleInfo* gSinkLogModuleInfo; class SinkContext; class HTMLContentSink : public nsIHTMLContentSink, - public nsIStreamLoaderObserver, + public nsIScriptLoaderObserver, public nsITimerCallback, public nsICSSLoaderObserver, public nsIDocumentObserver, @@ -188,7 +192,7 @@ public: // nsISupports NS_DECL_ISUPPORTS - NS_DECL_NSISTREAMLOADEROBSERVER + NS_DECL_NSISCRIPTLOADEROBSERVER // nsIContentSink NS_IMETHOD WillBuildModel(void); @@ -317,7 +321,6 @@ public: nsCOMPtr mNodeInfoManager; nsIURI* mDocumentURI; nsIURI* mDocumentBaseURL; - nsCOMPtr mScriptURI; nsIWebShell* mWebShell; nsIParser* mParser; @@ -335,7 +338,6 @@ public: nsIHTMLContent* mHead; nsString* mTitle; nsString mUnicodeXferBuf; - nsString mScriptCharset; PRBool mLayoutStarted; PRInt32 mInScript; @@ -347,6 +349,9 @@ public: SinkContext* mCurrentContext; SinkContext* mHeadContext; PRInt32 mNumOpenIFRAMES; + nsSupportsArray mScriptElements; + PRBool mParserBlocked; + PRBool mNeedToBlockParser; nsCString mRef; @@ -393,13 +398,7 @@ public: // Script processing related routines nsresult ResumeParsing(); PRBool PreEvaluateScript(); - void PostEvaluateScript(PRBool aBodyPresent); - nsresult EvaluateScript(const nsAReadableString& aScript, - nsIURI *aScriptURI, - PRInt32 aLineNo, - const char* aVersion, - PRBool aInScriptTag); - const char* mScriptLanguageVersion; + void PostEvaluateScript(); void UpdateAllContexts(); void NotifyAppend(nsIContent* aContent, @@ -2145,6 +2144,8 @@ HTMLContentSink::HTMLContentSink() { mInMonolithicContainer = 0; mInsideNoXXXTag = 0; mFlags=0; + mNeedToBlockParser = PR_FALSE; + mParserBlocked = PR_FALSE; } HTMLContentSink::~HTMLContentSink() @@ -2207,7 +2208,7 @@ HTMLContentSink::~HTMLContentSink() NS_IMPL_ISUPPORTS7(HTMLContentSink, nsIHTMLContentSink, nsIContentSink, - nsIStreamLoaderObserver, + nsIScriptLoaderObserver, nsITimerCallback, nsICSSLoaderObserver, nsIDocumentObserver, @@ -2247,6 +2248,11 @@ HTMLContentSink::Init(nsIDocument* aDoc, mWebShell = aContainer; NS_ADDREF(aContainer); + nsCOMPtr loader; + rv = mDocument->GetScriptLoader(getter_AddRefs(loader)); + NS_ENSURE_SUCCESS(rv, rv); + loader->AddObserver(this); + PRBool enabled = PR_TRUE; nsCOMPtr prefs(do_GetService(NS_PREF_CONTRACTID)); NS_ASSERTION(prefs, "oops no prefs!"); @@ -2431,6 +2437,12 @@ HTMLContentSink::DidBuildModel(PRInt32 aQualityLevel) ScrollToRef(); + nsCOMPtr loader; + mDocument->GetScriptLoader(getter_AddRefs(loader)); + if (loader) { + loader->RemoveObserver(this); + } + mDocument->EndLoad(); // Ref. Bug 49115 @@ -4477,7 +4489,7 @@ HTMLContentSink::PreEvaluateScript() } void -HTMLContentSink::PostEvaluateScript(PRBool aBodyPresent) +HTMLContentSink::PostEvaluateScript() { mInScript--; mCurrentContext->SetPreAppend(PR_FALSE); @@ -4489,268 +4501,79 @@ HTMLContentSink::IsInScript() return (mInScript > 0); } -nsresult -HTMLContentSink::EvaluateScript(const nsAReadableString& aScript, - nsIURI *aScriptURI, - PRInt32 aLineNo, - const char* aVersion, - PRBool aInScriptTag) -{ - nsresult rv = NS_OK; - - if (aScript.Length() > 0) { - nsCOMPtr globalObject; - mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject)); - NS_ENSURE_TRUE(globalObject, NS_ERROR_FAILURE); - - nsCOMPtr context; - NS_ENSURE_SUCCESS(globalObject->GetContext(getter_AddRefs(context)), - NS_ERROR_FAILURE); - - nsCOMPtr principal; - mDocument->GetPrincipal(getter_AddRefs(principal)); - NS_ASSERTION(principal, "principal required for document"); - - nsAutoString ret; - char* url = nsnull; - - if (aScriptURI) { - (void)aScriptURI->GetSpec(&url); - } - - // If we are currently processing a script tag, set - // a flag in nsIScriptContext indicating for the same. - if (aInScriptTag) - context->SetProcessingScriptTag(PR_TRUE); - - PRBool isUndefined; - context->EvaluateString(aScript, nsnull, principal, url, - aLineNo, aVersion, ret, &isUndefined); - - // we are done processing the script. Unset the - // flag in nsIScriptContext - if (aInScriptTag) - context->SetProcessingScriptTag(PR_FALSE); - - if (url) { - nsCRT::free(url); - } - } - - return rv; -} - NS_IMETHODIMP -HTMLContentSink::OnStreamComplete(nsIStreamLoader* aLoader, - nsISupports* aContext, - nsresult aStatus, - PRUint32 stringLen, - const char* string) +HTMLContentSink::ScriptAvailable(nsresult aResult, + nsIDOMHTMLScriptElement *aElement, + PRBool aIsInline, + PRBool aWasPending, + nsIURI *aURI, + PRInt32 aLineNo, + const nsAString& aScript) { - nsresult rv = NS_OK; + // Check if this is the element we were waiting for + PRUint32 count; + mScriptElements.Count(&count); + nsCOMPtr sup(dont_AddRef(mScriptElements.ElementAt(count-1))); + nsCOMPtr scriptElement(do_QueryInterface(sup)); + if (aElement != scriptElement.get()) { + return NS_OK; + } - if(mParser) { + if (mParserBlocked) { // make sure to unblock the parser before evaluating the script, // we must unblock the parser even if loading the script failed or // if the script was empty, if we don't, the parser will never be // unblocked. mParser->UnblockParser(); + mParserBlocked = PR_FALSE; } - if (stringLen) { - nsAutoString characterSet; - nsCOMPtr unicodeDecoder; - nsXPIDLCString contenttypeheader; - nsCOMPtr httpChannel; + // Mark the current script as loaded + mNeedToBlockParser = PR_FALSE; - nsCOMPtr channel; - nsCOMPtr request; - rv = aLoader->GetRequest(getter_AddRefs(request)); - NS_ASSERTION(request, "StreamLoader's request went away prematurely"); - if (NS_FAILED(rv)) return rv; - - channel = do_QueryInterface(request); - - if (channel) { - httpChannel = do_QueryInterface(channel); - if (httpChannel) { - rv = httpChannel->GetResponseHeader("content-type", - getter_Copies(contenttypeheader)); - } - } - - if (NS_SUCCEEDED(rv)) { - nsAutoString contentType; - contentType.AssignWithConversion(contenttypeheader.get()); - - PRInt32 start = contentType.RFind("charset=", PR_TRUE ) ; - - if(kNotFound != start) { - start += 8; // 8 = "charset=".length - PRInt32 end = contentType.FindCharInSet(";\n\r ", start ); - if(kNotFound == end ) end = contentType.Length(); - - contentType.Mid(characterSet, start, end - start); - NS_WITH_SERVICE(nsICharsetAlias, calias, kCharsetAliasCID, &rv); - - if(NS_SUCCEEDED(rv) && calias) { - nsAutoString preferred; - rv = calias->GetPreferred(characterSet, preferred); - - if(NS_SUCCEEDED(rv)) { - characterSet = preferred; - } - } - } - } - - if (NS_FAILED(rv) || characterSet.IsEmpty()) { - //charset from script charset tag - characterSet.Assign(mScriptCharset); - } - - if (NS_FAILED(rv) || characterSet.IsEmpty()) { - // charset from document default - rv = mDocument->GetDocumentCharacterSet(characterSet); - } - - NS_ASSERTION(NS_SUCCEEDED(rv), "Could not get document charset!"); - - nsCOMPtr charsetConv = - do_GetService(kCharsetConverterManagerCID, &rv); - - if (NS_SUCCEEDED(rv) && charsetConv) { - rv = charsetConv->GetUnicodeDecoder(&characterSet, - getter_AddRefs(unicodeDecoder)); - } - - // converts from the charset to unicode - if (NS_SUCCEEDED(rv)) { - PRInt32 unicodeLength = 0; - - rv = unicodeDecoder->GetMaxLength(string, stringLen, &unicodeLength); - if (NS_SUCCEEDED(rv)) { - mUnicodeXferBuf.SetCapacity(unicodeLength); - - // XXX: Whaaaaa! const violation!!! - PRUnichar *ustr = (PRUnichar *) mUnicodeXferBuf.GetUnicode(); - - rv = unicodeDecoder->Convert(string, (PRInt32 *) &stringLen, ustr, - &unicodeLength); - - if (NS_SUCCEEDED(rv)) { - mUnicodeXferBuf.SetLength(unicodeLength); - } else { - mUnicodeXferBuf.SetLength(0); - } - } - } - - NS_ASSERTION(NS_SUCCEEDED(rv), - "Could not convert external JavaScript to Unicode!"); - - if ((NS_OK == aStatus) && (NS_SUCCEEDED(rv))) { - PRBool bodyPresent = PreEvaluateScript(); - - //-- Merge the principal of the script file with that of the document - nsCOMPtr owner; - channel->GetOwner(getter_AddRefs(owner)); - nsCOMPtr prin; - - if (owner) { - prin = do_QueryInterface(owner, &rv); - if (NS_FAILED(rv)) return rv; - } - - rv = mDocument->AddPrincipal(prin); - - if (NS_FAILED(rv)) - return rv; - - rv = EvaluateScript(mUnicodeXferBuf, mScriptURI, 1, - mScriptLanguageVersion, PR_TRUE); - if (NS_FAILED(rv)) - return rv; - - PostEvaluateScript(bodyPresent); - - } + if (NS_SUCCEEDED(aResult)) { + PreEvaluateScript(); + } + else { + mScriptElements.RemoveElementAt(count-1); } - if(mParser && mParser->IsParserEnabled()){ - rv = mParser->ContinueParsing(); + return NS_OK; +} + +NS_IMETHODIMP +HTMLContentSink::ScriptEvaluated(nsresult aResult, + nsIDOMHTMLScriptElement *aElement, + PRBool aIsInline, + PRBool aWasPending) +{ + // Check if this is the element we were waiting for + PRUint32 count; + mScriptElements.Count(&count); + nsCOMPtr sup(dont_AddRef(mScriptElements.ElementAt(count-1))); + nsCOMPtr scriptElement(do_QueryInterface(sup)); + if (aElement != scriptElement.get()) { + return NS_OK; } - //invalidate Xfer buffer content - mUnicodeXferBuf.SetLength(0); + // Pop the script element stack + mScriptElements.RemoveElementAt(count-1); - return rv; + if (NS_SUCCEEDED(aResult)) { + PostEvaluateScript(); + } + + if(mParser && mParser->IsParserEnabled() && aWasPending){ + mParser->ContinueParsing(); + } + + return NS_OK; } nsresult HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode) { nsresult rv = NS_OK; - PRBool isJavaScript = PR_TRUE; - const char* jsVersionString = nsnull; - PRInt32 i, ac = aNode.GetAttributeCount(); - - // Look for SRC attribute and look for a LANGUAGE attribute - nsAutoString src; - for (i = 0; i < ac; i++) { - nsAutoString key(aNode.GetKeyAt(i)); - if (key.EqualsIgnoreCase("src")) { - GetAttributeValueAt(aNode, i, src); - } - else if (key.EqualsIgnoreCase("type")) { - nsAutoString type; - - GetAttributeValueAt(aNode, i, type); - - nsAutoString mimeType; - nsAutoString params; - SplitMimeType(type, mimeType, params); - - isJavaScript = mimeType.EqualsIgnoreCase("application/x-javascript") || - mimeType.EqualsIgnoreCase("text/javascript"); - if (isJavaScript) { - JSVersion jsVersion = JSVERSION_DEFAULT; - if (params.Find("version=", PR_TRUE) == 0) { - if (params.Length() != 11 || params[8] != '1' || params[9] != '.') - jsVersion = JSVERSION_UNKNOWN; - else switch (params[10]) { - case '0': jsVersion = JSVERSION_1_0; break; - case '1': jsVersion = JSVERSION_1_1; break; - case '2': jsVersion = JSVERSION_1_2; break; - case '3': jsVersion = JSVERSION_1_3; break; - case '4': jsVersion = JSVERSION_1_4; break; - case '5': jsVersion = JSVERSION_1_5; break; - default: jsVersion = JSVERSION_UNKNOWN; - } - } - jsVersionString = JS_VersionToString(jsVersion); - } - } - else if (key.EqualsIgnoreCase("language")) { - nsAutoString lang; - - GetAttributeValueAt(aNode, i, lang); - isJavaScript = nsParserUtils::IsJavaScriptLanguage(lang, &jsVersionString); - } - else if (key.EqualsIgnoreCase("charset")) { - //charset from script charset tag - nsAutoString charset; - - GetAttributeValueAt(aNode, i, charset); - NS_WITH_SERVICE(nsICharsetAlias, calias, kCharsetAliasCID, &rv); - if(NS_SUCCEEDED(rv) && (nsnull != calias) ) - { - rv = calias->GetPreferred(charset, mScriptCharset); - } else { - mScriptCharset = charset; - } - } - } // Create content object NS_ASSERTION(mCurrentContext->mStackPos > 0, "leaf w/o container"); @@ -4758,160 +4581,88 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode) return NS_ERROR_FAILURE; } nsIHTMLContent* parent = mCurrentContext->mStack[mCurrentContext->mStackPos-1].mContent; - nsIHTMLContent* element = nsnull; + nsCOMPtr element; nsCOMPtr nodeInfo; mNodeInfoManager->GetNodeInfo(nsHTMLAtoms::script, nsnull, kNameSpaceID_None, *getter_AddRefs(nodeInfo)); - rv = NS_CreateHTMLElement(&element, nodeInfo, PR_FALSE); - if (NS_SUCCEEDED(rv)) { - PRInt32 id; - mDocument->GetAndIncrementContentID(&id); - element->SetContentID(id); - - // Add in the attributes and add the style content object to the - // head container. - element->SetDocument(mDocument, PR_FALSE, PR_TRUE); - rv = AddAttributes(aNode, element); - if (NS_FAILED(rv)) { - NS_RELEASE(element); - return rv; - } - if (mCurrentContext->mStack[mCurrentContext->mStackPos-1].mInsertionPoint != -1) { - parent->InsertChildAt(element, - mCurrentContext->mStack[mCurrentContext->mStackPos-1].mInsertionPoint++, - PR_FALSE, PR_FALSE); - } - else { - parent->AppendChildTo(element, PR_FALSE, PR_FALSE); - } - } - else { + rv = NS_CreateHTMLElement(getter_AddRefs(element), nodeInfo, PR_FALSE); + if (NS_FAILED(rv)) { return rv; } - + + PRInt32 id; + mDocument->GetAndIncrementContentID(&id); + element->SetContentID(id); + + // Add in the attributes and add the style content object to the + // head container. + element->SetDocument(mDocument, PR_FALSE, PR_TRUE); + rv = AddAttributes(aNode, element); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr sele(do_QueryInterface(element)); + if (sele) { + sele->SetLineNumber((PRUint32)aNode.GetSourceLineNumber()); + } + // Create a text node holding the content // First, get the text content of the script tag nsAutoString script; script.Assign(aNode.GetSkippedContent()); if (script.Length() > 0) { - nsIContent* text; - rv = NS_NewTextNode(&text); + nsCOMPtr text; + rv = NS_NewTextNode(getter_AddRefs(text)); if (NS_OK == rv) { - nsIDOMText* tc; - rv = text->QueryInterface(NS_GET_IID(nsIDOMText), (void**)&tc); + nsCOMPtr tc; + rv = text->QueryInterface(NS_GET_IID(nsIDOMText), + (void**)getter_AddRefs(tc)); if (NS_OK == rv) { tc->SetData(script); - NS_RELEASE(tc); } element->AppendChildTo(text, PR_FALSE, PR_FALSE); text->SetDocument(mDocument, PR_FALSE, PR_TRUE); - NS_RELEASE(text); } } - NS_RELEASE(element); // Don't include script loading and evaluation in the stopwatch // that is measuring content creation time MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::ProcessSCRIPTTag()\n")); MOZ_TIMER_STOP(mWatch); - // Don't process scripts that aren't JavaScript and don't process - // scripts that are inside iframes, noframe, or noscript tags, - // or if the script context has script evaluation disabled: - PRBool scriptsEnabled = PR_TRUE; - nsCOMPtr globalObject; - mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject)); - if (globalObject) - { - nsCOMPtr context; - if (NS_SUCCEEDED(globalObject->GetContext(getter_AddRefs(context))) - && context) - context->GetScriptsEnabled(&scriptsEnabled); + // Assume that we're going to block the parser with a script load. + // If it's an inline script, we'll be told otherwise in the call + // to our ScriptAvailable method. + mNeedToBlockParser = PR_TRUE; + + nsCOMPtr scriptElement(do_QueryInterface(element)); + mScriptElements.AppendElement(scriptElement); + + // Insert the child into the content tree. This will evaluate the + // script as well. + if (mCurrentContext->mStack[mCurrentContext->mStackPos-1].mInsertionPoint != -1) { + parent->InsertChildAt(element, + mCurrentContext->mStack[mCurrentContext->mStackPos-1].mInsertionPoint++, + PR_FALSE, PR_FALSE); + } + else { + parent->AppendChildTo(element, PR_FALSE, PR_FALSE); } - if (scriptsEnabled && isJavaScript && !mNumOpenIFRAMES && !mInsideNoXXXTag) { - mScriptLanguageVersion = jsVersionString; - - // If there is a SRC attribute... - if (src.Length() > 0) { - // Use the SRC attribute value to load the URL - { - rv = NS_NewURI(getter_AddRefs(mScriptURI), src, mDocumentBaseURL); - } - if (NS_OK != rv) { - return rv; - } - - // Check that this page is allowed to load this URI. - NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager, - NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); - if (NS_FAILED(rv)) - return rv; - rv = securityManager->CheckLoadURI(mDocumentBaseURL, mScriptURI, nsIScriptSecurityManager::ALLOW_CHROME); - if (NS_FAILED(rv)) - return rv; - - // After the security manager, the content-policy stuff gets a veto - // For pinkerton: a symphony for string conversion, in 3 parts. - nsXPIDLCString urlCString; - mScriptURI->GetSpec(getter_Copies(urlCString)); - nsAutoString url; - url.AssignWithConversion((const char *)urlCString); - nsCOMPtr DOMElement = do_QueryInterface(element, &rv); - - PRBool shouldLoad = PR_TRUE; - if (NS_SUCCEEDED(rv) && - (rv = NS_CheckContentLoadPolicy(nsIContentPolicy::CONTENT_SCRIPT, - url, DOMElement, &shouldLoad), - NS_SUCCEEDED(rv)) && - !shouldLoad) { - - // content-policy veto causes silent failure - return NS_OK; - } - - nsCOMPtr loadGroup; - nsCOMPtr loader; - - mDocument->GetDocumentLoadGroup(getter_AddRefs(loadGroup)); - - // supply a prompter if you have one. this allows modal dialogs put up - // from within this new stream loader to have proper parenting. but it's - // not fatal if there isn't a prompter. - nsCOMPtr promptcall(do_QueryInterface(mWebShell)); - rv = NS_NewStreamLoader(getter_AddRefs(loader), mScriptURI, this, - nsnull, loadGroup, promptcall, - nsIChannel::LOAD_NORMAL); - if (NS_OK == rv) { - rv = NS_ERROR_HTMLPARSER_BLOCK; - } - } - else { - PRBool bodyPresent = PreEvaluateScript(); - - PRUint32 lineNo = (PRUint32)aNode.GetSourceLineNumber(); - nsIURI *docURI = mDocument->GetDocumentURL(); - - EvaluateScript(script, docURI, lineNo, jsVersionString, PR_TRUE); - NS_IF_RELEASE(docURI); - - PostEvaluateScript(bodyPresent); - - // If the parse was disabled as a result of this evaluate script - // (for example, if the script document.wrote a SCRIPT SRC= tag, - // we remind the parser to block. - if ((nsnull != mParser) && (PR_FALSE == mParser->IsParserEnabled())) { - rv = NS_ERROR_HTMLPARSER_BLOCK; - } - } + // If the act of insertion evaluated the script, we're fine. + // Else, block the parser till the script has loaded. + if (mNeedToBlockParser) { + mParserBlocked = PR_TRUE; + return NS_ERROR_HTMLPARSER_BLOCK; + } + else { + return NS_OK; } - - return rv; } - // 3 ways to load a style sheet: inline, style src=, link tag // XXX What does nav do if we have SRC= and some style data inline? diff --git a/mozilla/content/shared/public/nsHTMLAtomList.h b/mozilla/content/shared/public/nsHTMLAtomList.h index 0130c4207e2..ab3fa2efb19 100644 --- a/mozilla/content/shared/public/nsHTMLAtomList.h +++ b/mozilla/content/shared/public/nsHTMLAtomList.h @@ -201,6 +201,7 @@ HTML_ATOM(method, "method") HTML_ATOM(multicol, "multicol") HTML_ATOM(multiple, "multiple") HTML_ATOM(name, "name") +HTML_ATOM(noembed, "noembed") HTML_ATOM(noframes, "noframes") HTML_ATOM(nohref, "nohref") HTML_ATOM(noresize, "noresize") diff --git a/mozilla/content/xml/document/src/nsXMLContentSink.cpp b/mozilla/content/xml/document/src/nsXMLContentSink.cpp index 1f121485605..7931459d41e 100644 --- a/mozilla/content/xml/document/src/nsXMLContentSink.cpp +++ b/mozilla/content/xml/document/src/nsXMLContentSink.cpp @@ -74,6 +74,7 @@ #include "nsIDocumentViewer.h" #include "nsIScrollable.h" #include "nsIWebNavigation.h" +#include "nsIScriptElement.h" // XXX misnamed header file, but oh well #include "nsHTMLTokens.h" @@ -150,6 +151,8 @@ nsXMLContentSink::nsXMLContentSink() mStyleSheetCount = 0; mCSSLoader = nsnull; mXSLTransformMediator = nsnull; + mNeedToBlockParser = PR_FALSE; + mParserBlocked = PR_FALSE; } nsXMLContentSink::~nsXMLContentSink() @@ -201,6 +204,11 @@ nsXMLContentSink::Init(nsIDocument* aDoc, mWebShell = aContainer; NS_IF_ADDREF(aContainer); + nsCOMPtr loader; + nsresult rv = mDocument->GetScriptLoader(getter_AddRefs(loader)); + NS_ENSURE_SUCCESS(rv, rv); + loader->AddObserver(this); + mState = eXMLContentSinkState_InProlog; mDocElement = nsnull; mRootElement = nsnull; @@ -226,7 +234,7 @@ NS_INTERFACE_MAP_BEGIN(nsXMLContentSink) NS_INTERFACE_MAP_ENTRY(nsIContentSink) NS_INTERFACE_MAP_ENTRY(nsIObserver) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) - NS_INTERFACE_MAP_ENTRY(nsIStreamLoaderObserver) + NS_INTERFACE_MAP_ENTRY(nsIScriptLoaderObserver) NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXMLContentSink) NS_INTERFACE_MAP_END @@ -280,6 +288,12 @@ nsXMLContentSink::DidBuildModel(PRInt32 aQualityLevel) rv = SetupTransformMediator(); } + nsCOMPtr loader; + mDocument->GetScriptLoader(getter_AddRefs(loader)); + if (loader) { + loader->RemoveObserver(this); + } + if (!mXSLTransformMediator || NS_FAILED(rv)) { StartLayout(); ScrollToRef(); @@ -566,6 +580,7 @@ nsXMLContentSink::OpenContainer(const nsIParserNode& aNode) nsCOMPtr nameSpacePrefix; PRBool isHTML = PR_FALSE; PRBool pushContent = PR_TRUE; + PRBool appendContent = PR_TRUE; nsCOMPtr content; // XXX Hopefully the parser will flag this before we get @@ -599,6 +614,9 @@ nsXMLContentSink::OpenContainer(const nsIParserNode& aNode) if (isHTML) { if (tagAtom.get() == nsHTMLAtoms::script) { result = ProcessStartSCRIPTTag(aNode); + // Don't append the content to the tree until we're all + // done collecting its contents + appendContent = PR_FALSE; } else if (tagAtom.get() == nsHTMLAtoms::title) { if (mTitleText.IsEmpty()) mInTitle = PR_TRUE; // The first title wins @@ -667,7 +685,7 @@ nsXMLContentSink::OpenContainer(const nsIParserNode& aNode) if (!mXSLTransformMediator) mDocument->SetRootContent(mDocElement); } - else { + else if (appendContent) { nsCOMPtr parent = getter_AddRefs(GetCurrentContent()); parent->AppendChildTo(content, PR_FALSE, PR_FALSE); @@ -695,6 +713,7 @@ nsXMLContentSink::CloseContainer(const nsIParserNode& aNode) nsCOMPtr nameSpacePrefix; PRBool isHTML = PR_FALSE; PRBool popContent = PR_TRUE; + PRBool appendContent = PR_FALSE; // XXX Hopefully the parser will flag this before we get // here. If we're in the prolog or epilog, there should be @@ -714,6 +733,7 @@ nsXMLContentSink::CloseContainer(const nsIParserNode& aNode) if (tagAtom.get() == nsHTMLAtoms::script) { result = ProcessEndSCRIPTTag(aNode); + appendContent = PR_TRUE; } else if (tagAtom.get() == nsHTMLAtoms::title) { if (mInTitle) { // The first title wins nsCOMPtr xmlDoc(do_QueryInterface(mDocument)); @@ -759,6 +779,11 @@ nsXMLContentSink::CloseContainer(const nsIParserNode& aNode) if (mDocElement == content.get()) { mState = eXMLContentSinkState_InEpilog; } + else if (appendContent) { + nsCOMPtr parent = getter_AddRefs(GetCurrentContent()); + + parent->AppendChildTo(content, PR_FALSE, PR_FALSE); + } } else { // XXX Again, the parser should catch unmatched tags and @@ -775,7 +800,13 @@ nsXMLContentSink::CloseContainer(const nsIParserNode& aNode) } NS_IF_RELEASE(nameSpace); - return result; + if (mNeedToBlockParser) { + mParserBlocked = PR_TRUE; + return NS_ERROR_HTMLPARSER_BLOCK; + } + else { + return result; + } } NS_IMETHODIMP @@ -881,9 +912,7 @@ nsXMLContentSink::AddCDATASection(const nsIParserNode& aNode) nsresult result = NS_OK; const nsAReadableString& text = aNode.GetText(); - if (mInScript) { - mScriptText.Append(text); - } else if (mInTitle) { + if (mInTitle) { mTitleText.Append(text); } else if (mTextAreaElement) { mTextareaText.Append(text); @@ -1515,9 +1544,7 @@ nsXMLContentSink::AddText(const nsAReadableString& aString) return NS_OK; } - if (mInScript) { - mScriptText.Append(aString); - } else if (mInTitle) { + if (mInTitle) { mTitleText.Append(aString); } else if (mTextAreaElement) { mTextareaText.Append(aString); @@ -1750,203 +1777,102 @@ nsXMLContentSink::StartLayout() } } -NS_IMETHODIMP -nsXMLContentSink::ResumeParsing() +nsresult +nsXMLContentSink::ProcessEndSCRIPTTag(const nsIParserNode& aNode) { - if (mParser) { + nsresult result = NS_OK; + + nsCOMPtr element(dont_AddRef(GetCurrentContent())); + nsCOMPtr scriptElement(do_QueryInterface(element)); + NS_ASSERTION(scriptElement, "null script element in XML content sink"); + mScriptElements.AppendElement(scriptElement); + + nsCOMPtr sele(do_QueryInterface(element)); + if (sele) { + sele->SetLineNumber(mScriptLineNo); + } + + mInScript = PR_FALSE; + mConstrainSize = PR_TRUE; + // Assume that we're going to block the parser with a script load. + // If it's an inline script, we'll be told otherwise in the call + // to our ScriptAvailable method. + mNeedToBlockParser = PR_TRUE; + + return result; +} + +NS_IMETHODIMP +nsXMLContentSink::ScriptAvailable(nsresult aResult, + nsIDOMHTMLScriptElement *aElement, + PRBool aIsInline, + PRBool aWasPending, + nsIURI *aURI, + PRInt32 aLineNo, + const nsAString& aScript) +{ + // Check if this is the element we were waiting for + PRUint32 count; + mScriptElements.Count(&count); + nsCOMPtr sup(dont_AddRef(mScriptElements.ElementAt(count-1))); + nsCOMPtr scriptElement(do_QueryInterface(sup)); + if (aElement != scriptElement.get()) { + return NS_OK; + } + + if (mParserBlocked) { + // make sure to unblock the parser before evaluating the script, + // we must unblock the parser even if loading the script failed or + // if the script was empty, if we don't, the parser will never be + // unblocked. + mParser->UnblockParser(); + mParserBlocked = PR_FALSE; + } + + // Mark the current script as loaded + mNeedToBlockParser = PR_FALSE; + + if (NS_FAILED(aResult)) { + mScriptElements.RemoveElementAt(count-1); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsXMLContentSink::ScriptEvaluated(nsresult aResult, + nsIDOMHTMLScriptElement *aElement, + PRBool aIsInline, + PRBool aWasPending) +{ + // Check if this is the element we were waiting for + PRUint32 count; + mScriptElements.Count(&count); + nsCOMPtr sup(dont_AddRef(mScriptElements.ElementAt(count-1))); + nsCOMPtr scriptElement(do_QueryInterface(sup)); + if (aElement != scriptElement.get()) { + return NS_OK; + } + + // Pop the script element stack + mScriptElements.RemoveElementAt(count-1); + + if(mParser && mParser->IsParserEnabled() && aWasPending){ mParser->ContinueParsing(); } return NS_OK; } -NS_IMETHODIMP -nsXMLContentSink::EvaluateScript(nsString& aScript, nsIURI *aScriptURI, PRUint32 aLineNo, const char* aVersion) -{ - nsresult rv = NS_OK; - - if (0 < aScript.Length()) { - nsCOMPtr scriptGlobal; - mDocument->GetScriptGlobalObject(getter_AddRefs(scriptGlobal)); - if (scriptGlobal) { - nsCOMPtr context; - NS_ENSURE_SUCCESS(scriptGlobal->GetContext(getter_AddRefs(context)), - NS_ERROR_FAILURE); - - char* url = nsnull; - if (aScriptURI) { - rv = aScriptURI->GetSpec(&url); - } - - nsCOMPtr principal; - if (NS_SUCCEEDED(rv)) { - rv = mDocument->GetPrincipal(getter_AddRefs(principal)); - NS_ASSERTION(principal, "principal required for document"); - } - - if (NS_SUCCEEDED(rv)) { - nsAutoString val; - PRBool isUndefined; - - (void) context->EvaluateString(aScript, nsnull, principal, url, aLineNo, aVersion, - val, &isUndefined); - } - if (url) { - nsCRT::free(url); - } - } - } - - return rv; -} - -nsresult -nsXMLContentSink::ProcessEndSCRIPTTag(const nsIParserNode& aNode) -{ - nsresult result = NS_OK; - if (mInScript) { - nsCOMPtr docURI( dont_AddRef( mDocument->GetDocumentURL() ) ); - result = EvaluateScript(mScriptText, docURI, mScriptLineNo, mScriptLanguageVersion); - mScriptText.Truncate(); - mInScript = PR_FALSE; - } - - return result; -} - -NS_IMETHODIMP -nsXMLContentSink::OnStreamComplete(nsIStreamLoader* aLoader, - nsISupports* context, - nsresult aStatus, - PRUint32 stringLen, - const char* string) -{ - nsresult rv = NS_OK; - nsString aData; aData.AssignWithConversion(string, stringLen); - - if (NS_OK == aStatus) { - { // scope in block so nsCOMPtr released at one point - nsCOMPtr channel; - nsCOMPtr request; - aLoader->GetRequest(getter_AddRefs(request)); - if (request) - channel = do_QueryInterface(request); - - nsCOMPtr url; - if (channel) { - channel->GetURI(getter_AddRefs(url)); - } - - if(mParser) { - mParser->UnblockParser(); // make sure to unblock the parser before evaluating the script - } - - rv = EvaluateScript(aData, url, 1, mScriptLanguageVersion); - } - if (NS_FAILED(rv)) return rv; - } - - if(mParser && mParser->IsParserEnabled()){ - rv=mParser->ContinueParsing(); - } - - if (NS_FAILED(rv)) return rv; - - return rv; -} - nsresult nsXMLContentSink::ProcessStartSCRIPTTag(const nsIParserNode& aNode) { - nsresult rv = NS_OK; - PRBool isJavaScript = PR_TRUE; - const char* jsVersionString = nsnull; - PRInt32 i, ac = aNode.GetAttributeCount(); + // Wait until we get the script content + mInScript = PR_TRUE; + mConstrainSize = PR_FALSE; + mScriptLineNo = (PRUint32)aNode.GetSourceLineNumber(); - // Look for SRC attribute and look for a LANGUAGE attribute - nsAutoString src; - for (i = 0; i < ac; i++) { - nsAutoString key(aNode.GetKeyAt(i)); - if (key.EqualsIgnoreCase("src")) { - src = aNode.GetValueAt(i); - } - else if (key.EqualsIgnoreCase("type")) { - const nsString& type = aNode.GetValueAt(i); - - nsAutoString mimeType; - nsAutoString params; - SplitMimeType(type, mimeType, params); - - isJavaScript = mimeType.EqualsIgnoreCase("text/javascript"); - if (isJavaScript) { - JSVersion jsVersion = JSVERSION_DEFAULT; - if (params.Find("version=", PR_TRUE) == 0) { - if (params.Length() != 11 || params[8] != '1' || params[9] != '.') - jsVersion = JSVERSION_UNKNOWN; - else switch (params[10]) { - case '0': jsVersion = JSVERSION_1_0; break; - case '1': jsVersion = JSVERSION_1_1; break; - case '2': jsVersion = JSVERSION_1_2; break; - case '3': jsVersion = JSVERSION_1_3; break; - case '4': jsVersion = JSVERSION_1_4; break; - case '5': jsVersion = JSVERSION_1_5; break; - default: jsVersion = JSVERSION_UNKNOWN; - } - } - jsVersionString = JS_VersionToString(jsVersion); - } - } - else if (key.EqualsIgnoreCase("language")) { - const nsString& lang = aNode.GetValueAt(i); - isJavaScript = nsParserUtils::IsJavaScriptLanguage(lang, &jsVersionString); - } - } - - // Don't process scripts that aren't JavaScript - if (isJavaScript) { - mScriptLanguageVersion = jsVersionString; - - // If there is a SRC attribute... - if (src.Length() > 0) { - // Use the SRC attribute value to load the URL - nsIURI* url = nsnull; - nsAutoString absURL; - // XXX we need to get passed in the nsILoadGroup here! -// nsILoadGroup* group = mDocument->GetDocumentLoadGroup(); - rv = NS_NewURI(&url, src, mDocumentBaseURL); - if (NS_OK != rv) { - return rv; - } - - // Check that this page is allowed to load this URI. - NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager, - NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); - if (NS_FAILED(rv)) - return rv; - rv = securityManager->CheckLoadURI(mDocumentBaseURL, url, nsIScriptSecurityManager::ALLOW_CHROME); - if (NS_FAILED(rv)) - return rv; - - nsCOMPtr loader; - nsCOMPtr loadGroup; - - mDocument->GetDocumentLoadGroup(getter_AddRefs(loadGroup)); - rv = NS_NewStreamLoader(getter_AddRefs(loader), url, this, nsnull, - loadGroup); - NS_RELEASE(url); - if (NS_OK == rv) { - rv = NS_ERROR_HTMLPARSER_BLOCK; - } - } - else { - // Wait until we get the script content - mInScript = PR_TRUE; - mConstrainSize = PR_FALSE; - mScriptLineNo = (PRUint32)aNode.GetSourceLineNumber(); - } - } - - return rv; + return NS_OK; } nsresult diff --git a/mozilla/content/xml/document/src/nsXMLContentSink.h b/mozilla/content/xml/document/src/nsXMLContentSink.h index 8c930731f7b..c0b3f611c47 100644 --- a/mozilla/content/xml/document/src/nsXMLContentSink.h +++ b/mozilla/content/xml/document/src/nsXMLContentSink.h @@ -37,6 +37,10 @@ class nsICSSStyleSheet; #include "nsICSSLoaderObserver.h" #include "nsIHTMLContent.h" +#include "nsIDOMHTMLScriptElement.h" +#include "nsIScriptLoader.h" +#include "nsIScriptLoaderObserver.h" +#include "nsSupportsArray.h" class nsIDocument; class nsIScriptObjectOwner; @@ -63,7 +67,7 @@ typedef enum { class nsXMLContentSink : public nsIXMLContentSink, public nsIObserver, public nsSupportsWeakReference, - public nsIStreamLoaderObserver, + public nsIScriptLoaderObserver, public nsICSSLoaderObserver { public: @@ -76,7 +80,7 @@ public: // nsISupports NS_DECL_ISUPPORTS - NS_DECL_NSISTREAMLOADEROBSERVER + NS_DECL_NSISCRIPTLOADEROBSERVER // nsIContentSink NS_IMETHOD WillBuildModel(void); @@ -109,10 +113,6 @@ public: const PRUnichar *aTopic, const PRUnichar *someData); - NS_IMETHOD ResumeParsing(); - NS_IMETHOD EvaluateScript(nsString& aScript, nsIURI *aScriptURI, PRUint32 aLineNo, const char* aVersion); - const char* mScriptLanguageVersion; - protected: void StartLayout(); @@ -189,10 +189,13 @@ protected: PRPackedBool mInScript; PRPackedBool mInTitle; - nsString mScriptText; nsString mStyleText; PRUint32 mScriptLineNo; + PRBool mNeedToBlockParser; + PRBool mParserBlocked; + nsSupportsArray mScriptElements; + nsString mPreferredStyle; PRInt32 mStyleSheetCount; nsICSSLoader* mCSSLoader; diff --git a/mozilla/content/xul/document/src/nsXULDocument.cpp b/mozilla/content/xul/document/src/nsXULDocument.cpp index 832239fb3a3..d5a39394c18 100644 --- a/mozilla/content/xul/document/src/nsXULDocument.cpp +++ b/mozilla/content/xul/document/src/nsXULDocument.cpp @@ -471,6 +471,9 @@ nsXULDocument::~nsXULDocument() mCSSLoader->DropDocumentReference(); } + if (mScriptLoader) { + mScriptLoader->DropDocumentReference(); + } delete mTemplateBuilderTable; delete mBoxObjectTable; @@ -1370,6 +1373,26 @@ nsXULDocument::GetCSSLoader(nsICSSLoader*& aLoader) return result; } +NS_IMETHODIMP +nsXULDocument::GetScriptLoader(nsIScriptLoader** aLoader) +{ + NS_ENSURE_ARG_POINTER(aLoader); + nsresult result = NS_OK; + if (!mScriptLoader) { + nsScriptLoader* loader = new nsScriptLoader(); + if (!loader) { + return NS_ERROR_OUT_OF_MEMORY; + } + mScriptLoader = loader; + mScriptLoader->Init(this); + } + + *aLoader = mScriptLoader; + NS_IF_ADDREF(*aLoader); + + return result; +} + NS_IMETHODIMP nsXULDocument::GetScriptGlobalObject(nsIScriptGlobalObject** aScriptGlobalObject) { diff --git a/mozilla/content/xul/document/src/nsXULDocument.h b/mozilla/content/xul/document/src/nsXULDocument.h index 692cd70db20..57ded37a887 100644 --- a/mozilla/content/xul/document/src/nsXULDocument.h +++ b/mozilla/content/xul/document/src/nsXULDocument.h @@ -70,6 +70,7 @@ #include "nsINodeInfo.h" #include "nsIDOMDocumentEvent.h" #include "nsIFocusController.h" +#include "nsScriptLoader.h" class nsIAtom; class nsIElementFactory; @@ -230,6 +231,8 @@ public: NS_IMETHOD GetNameSpaceManager(nsINameSpaceManager*& aManager); + NS_IMETHOD GetScriptLoader(nsIScriptLoader** aScriptLoader); + virtual void AddObserver(nsIDocumentObserver* aObserver); virtual PRBool RemoveObserver(nsIDocumentObserver* aObserver); @@ -502,6 +505,7 @@ protected: nsCOMPtr mAttrStyleSheet; // [OWNER] nsCOMPtr mInlineStyleSheet; // [OWNER] nsCOMPtr mCSSLoader; // [OWNER] + nsCOMPtr mScriptLoader; // [OWNER] nsElementMap mElementMap; nsCOMPtr mLocalStore; nsCOMPtr mLineBreaker; // [OWNER]