diff --git a/mozilla/content/base/public/nsIDocument.h b/mozilla/content/base/public/nsIDocument.h index 19f9ca156ec..98f755b46ad 100644 --- a/mozilla/content/base/public/nsIDocument.h +++ b/mozilla/content/base/public/nsIDocument.h @@ -22,6 +22,7 @@ #include "nsISupports.h" #include "nsIUnicharInputStream.h" #include "nsGUIEvent.h" + class nsIArena; class nsIContent; class nsIDocumentContainer; @@ -35,6 +36,7 @@ class nsIStyleSheet; class nsIURL; class nsIViewManager; class nsString; +class nsIScriptContextOwner; class nsIWebWidget; class nsIDOMEvent; class nsIDeviceContext; @@ -119,6 +121,14 @@ public: virtual nsIStyleSheet* GetStyleSheetAt(PRInt32 aIndex) = 0; virtual void AddStyleSheet(nsIStyleSheet* aSheet) = 0; + /** + * Set the object from which a document can get a script context. + * This is the context within which all scripts (during document + * creation and during event handling) will run. + */ + virtual nsIScriptContextOwner *GetScriptContextOwner() = 0; + virtual void SetScriptContextOwner(nsIScriptContextOwner *aScriptContextOwner) = 0; + //---------------------------------------------------------------------- // Document notification API's diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index bff1e9da835..2a9551829a0 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -26,6 +26,7 @@ #include "nsIDocumentObserver.h" #include "nsEventListenerManager.h" #include "nsIScriptGlobalObject.h" +#include "nsIScriptContextOwner.h" #include "nsSelection.h" #include "nsIDOMText.h" @@ -77,6 +78,7 @@ nsDocument::nsDocument() mParentDocument = nsnull; mRootContent = nsnull; mScriptObject = nsnull; + mScriptContextOwner = nsnull; mListenerManager = nsnull; if (NS_OK != NS_NewSelection(&mSelection)) { @@ -113,6 +115,7 @@ nsDocument::~nsDocument() NS_IF_RELEASE(mArena); NS_IF_RELEASE(mSelection); + NS_IF_RELEASE(mScriptContextOwner); } nsresult nsDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr) @@ -336,6 +339,28 @@ void nsDocument::AddStyleSheet(nsIStyleSheet* aSheet) } } +nsIScriptContextOwner *nsDocument::GetScriptContextOwner() +{ + if (nsnull != mScriptContextOwner) { + NS_ADDREF(mScriptContextOwner); + } + + return mScriptContextOwner; +} + +void nsDocument::SetScriptContextOwner(nsIScriptContextOwner *aScriptContextOwner) +{ + if (nsnull != mScriptContextOwner) { + NS_RELEASE(mScriptContextOwner); + } + + mScriptContextOwner = aScriptContextOwner; + + if (nsnull != mScriptContextOwner) { + NS_ADDREF(mScriptContextOwner); + } +} + // Note: We don't hold a reference to the document observer; we assume // that it has a live reference to the document. void nsDocument::AddObserver(nsIDocumentObserver* aObserver) diff --git a/mozilla/content/base/src/nsDocument.h b/mozilla/content/base/src/nsDocument.h index d7509abc13d..bde9408f564 100644 --- a/mozilla/content/base/src/nsDocument.h +++ b/mozilla/content/base/src/nsDocument.h @@ -22,7 +22,7 @@ #include "nsVoidArray.h" #include "nsIDOMDocument.h" #include "nsIScriptObjectOwner.h" -#include "nsIScriptContext.h" +#include "nsIScriptContextOwner.h" #include "nsIDOMEventCapturer.h" class nsISelection; @@ -99,6 +99,14 @@ public: virtual nsIStyleSheet* GetStyleSheetAt(PRInt32 aIndex); virtual void AddStyleSheet(nsIStyleSheet* aSheet); + /** + * Set the object from which a document can get a script context. + * This is the context within which all scripts (during document + * creation and during event handling) will run. + */ + virtual nsIScriptContextOwner *GetScriptContextOwner(); + virtual void SetScriptContextOwner(nsIScriptContextOwner *aScriptContextOwner); + /** * Add a new observer of document change notifications. Whenever * content is changed, appended, inserted or removed the observers are @@ -231,6 +239,7 @@ protected: nsVoidArray mStyleSheets; nsVoidArray mObservers; void* mScriptObject; + nsIScriptContextOwner *mScriptContextOwner; nsIEventListenerManager* mListenerManager; }; diff --git a/mozilla/content/html/document/src/nsHTMLContentSink.cpp b/mozilla/content/html/document/src/nsHTMLContentSink.cpp index 8860e70e246..1eee94c0e93 100644 --- a/mozilla/content/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/content/html/document/src/nsHTMLContentSink.cpp @@ -151,6 +151,7 @@ protected: nsresult ProcessAREATag(const nsIParserNode& aNode); nsresult ProcessBASETag(const nsIParserNode& aNode); nsresult ProcessSTYLETag(const nsIParserNode& aNode); + nsresult ProcessSCRIPTTag(const nsIParserNode& aNode); nsresult ProcessBRTag(nsIHTMLContent** aInstancePtrResult, const nsIParserNode& aNode); @@ -741,6 +742,11 @@ PRInt32 HTMLContentSink::AddLeaf(const nsIParserNode& aNode) return 0; case eHTMLTag_script: + // XXX SCRIPT tag evaluation is currently turned off till we + // get more scripts working. +#if 0 + ProcessSCRIPTTag(aNode); +#endif return 0; case eHTMLTag_area: @@ -1029,6 +1035,102 @@ nsresult HTMLContentSink::ProcessSPACERTag(nsIHTMLContent** aInstancePtrResult, return rv; } +#define SCRIPT_BUF_SIZE 1024 + +nsresult HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode) +{ + nsresult rv = NS_OK; + PRInt32 i, ac = aNode.GetAttributeCount(); + + // Look for SRC attribute + nsString* src = nsnull; + for (i = 0; i < ac; i++) { + const nsString& key = aNode.GetKeyAt(i); + if (key.EqualsIgnoreCase("src")) { + src = new nsString(aNode.GetValueAt(i)); + } + } + + char *script = nsnull; + PRInt32 len = 0; + + // If there is a SRC attribute, (for now) read from the + // stream synchronously and hold the data in a string. + if (nsnull != src) { + // Use the SRC attribute value to open a blocking stream + nsIURL* url = nsnull; + char* spec = src->ToNewCString(); + rv = NS_NewURL(&url, nsnull, spec); + delete spec; + delete src; + if (NS_OK != rv) { + return rv; + } + PRInt32 ec; + nsIInputStream* iin = url->Open(&ec); + if (nsnull == iin) { + NS_RELEASE(url); + return (nsresult) ec;/* XXX fix url->Open */ + } + + // Drain the stream by reading from it a chunk at a time + nsString data; + PRInt32 err, nb; + do { + char buf[SCRIPT_BUF_SIZE]; + + nb = iin->Read(&err, buf, 0, SCRIPT_BUF_SIZE); + if (0 == err) { + data.Append((const char *)buf, nb); + } + } while (err == 0); + + if (NS_INPUTSTREAM_EOF == err) { + script = data.ToNewCString(); + len = data.Length(); + } + else { + rv = NS_ERROR_FAILURE; + } + + NS_RELEASE(iin); + NS_RELEASE(url); + } + else { + // Otherwise, get the text content of the script tag + const nsString& content = aNode.GetSkippedContent(); + script = content.ToNewCString(); + len = content.Length(); + } + + if (nsnull != script) { + nsIScriptContextOwner *owner; + nsIScriptContext *context; + owner = mDocument->GetScriptContextOwner(); + if (nsnull != owner) { + + rv = owner->GetScriptContext(&context); + if (rv != NS_OK) { + NS_RELEASE(owner); + return rv; + } + + jsval val; + PRBool result = context->EvaluateString(script, len, &val); + + if (PR_FALSE == result) { + rv = NS_ERROR_FAILURE; + } + + NS_RELEASE(context); + NS_RELEASE(owner); + } + delete script; + } + + 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? nsresult HTMLContentSink::ProcessSTYLETag(const nsIParserNode& aNode) diff --git a/mozilla/layout/base/public/nsIDocument.h b/mozilla/layout/base/public/nsIDocument.h index 19f9ca156ec..98f755b46ad 100644 --- a/mozilla/layout/base/public/nsIDocument.h +++ b/mozilla/layout/base/public/nsIDocument.h @@ -22,6 +22,7 @@ #include "nsISupports.h" #include "nsIUnicharInputStream.h" #include "nsGUIEvent.h" + class nsIArena; class nsIContent; class nsIDocumentContainer; @@ -35,6 +36,7 @@ class nsIStyleSheet; class nsIURL; class nsIViewManager; class nsString; +class nsIScriptContextOwner; class nsIWebWidget; class nsIDOMEvent; class nsIDeviceContext; @@ -119,6 +121,14 @@ public: virtual nsIStyleSheet* GetStyleSheetAt(PRInt32 aIndex) = 0; virtual void AddStyleSheet(nsIStyleSheet* aSheet) = 0; + /** + * Set the object from which a document can get a script context. + * This is the context within which all scripts (during document + * creation and during event handling) will run. + */ + virtual nsIScriptContextOwner *GetScriptContextOwner() = 0; + virtual void SetScriptContextOwner(nsIScriptContextOwner *aScriptContextOwner) = 0; + //---------------------------------------------------------------------- // Document notification API's diff --git a/mozilla/layout/base/src/nsDocument.cpp b/mozilla/layout/base/src/nsDocument.cpp index bff1e9da835..2a9551829a0 100644 --- a/mozilla/layout/base/src/nsDocument.cpp +++ b/mozilla/layout/base/src/nsDocument.cpp @@ -26,6 +26,7 @@ #include "nsIDocumentObserver.h" #include "nsEventListenerManager.h" #include "nsIScriptGlobalObject.h" +#include "nsIScriptContextOwner.h" #include "nsSelection.h" #include "nsIDOMText.h" @@ -77,6 +78,7 @@ nsDocument::nsDocument() mParentDocument = nsnull; mRootContent = nsnull; mScriptObject = nsnull; + mScriptContextOwner = nsnull; mListenerManager = nsnull; if (NS_OK != NS_NewSelection(&mSelection)) { @@ -113,6 +115,7 @@ nsDocument::~nsDocument() NS_IF_RELEASE(mArena); NS_IF_RELEASE(mSelection); + NS_IF_RELEASE(mScriptContextOwner); } nsresult nsDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr) @@ -336,6 +339,28 @@ void nsDocument::AddStyleSheet(nsIStyleSheet* aSheet) } } +nsIScriptContextOwner *nsDocument::GetScriptContextOwner() +{ + if (nsnull != mScriptContextOwner) { + NS_ADDREF(mScriptContextOwner); + } + + return mScriptContextOwner; +} + +void nsDocument::SetScriptContextOwner(nsIScriptContextOwner *aScriptContextOwner) +{ + if (nsnull != mScriptContextOwner) { + NS_RELEASE(mScriptContextOwner); + } + + mScriptContextOwner = aScriptContextOwner; + + if (nsnull != mScriptContextOwner) { + NS_ADDREF(mScriptContextOwner); + } +} + // Note: We don't hold a reference to the document observer; we assume // that it has a live reference to the document. void nsDocument::AddObserver(nsIDocumentObserver* aObserver) diff --git a/mozilla/layout/base/src/nsDocument.h b/mozilla/layout/base/src/nsDocument.h index d7509abc13d..bde9408f564 100644 --- a/mozilla/layout/base/src/nsDocument.h +++ b/mozilla/layout/base/src/nsDocument.h @@ -22,7 +22,7 @@ #include "nsVoidArray.h" #include "nsIDOMDocument.h" #include "nsIScriptObjectOwner.h" -#include "nsIScriptContext.h" +#include "nsIScriptContextOwner.h" #include "nsIDOMEventCapturer.h" class nsISelection; @@ -99,6 +99,14 @@ public: virtual nsIStyleSheet* GetStyleSheetAt(PRInt32 aIndex); virtual void AddStyleSheet(nsIStyleSheet* aSheet); + /** + * Set the object from which a document can get a script context. + * This is the context within which all scripts (during document + * creation and during event handling) will run. + */ + virtual nsIScriptContextOwner *GetScriptContextOwner(); + virtual void SetScriptContextOwner(nsIScriptContextOwner *aScriptContextOwner); + /** * Add a new observer of document change notifications. Whenever * content is changed, appended, inserted or removed the observers are @@ -231,6 +239,7 @@ protected: nsVoidArray mStyleSheets; nsVoidArray mObservers; void* mScriptObject; + nsIScriptContextOwner *mScriptContextOwner; nsIEventListenerManager* mListenerManager; }; diff --git a/mozilla/layout/build/Makefile b/mozilla/layout/build/Makefile index 7b50ebc1637..10020d54ed1 100644 --- a/mozilla/layout/build/Makefile +++ b/mozilla/layout/build/Makefile @@ -25,7 +25,7 @@ LIBRARY_NAME = raptorhtml MODULE=raptor -REQUIRES=xpcom raptor +REQUIRES=xpcom raptor CPPSRCS=dlldeps.cpp diff --git a/mozilla/layout/build/makefile.win b/mozilla/layout/build/makefile.win index 653788fa3ef..1ebfec6220b 100644 --- a/mozilla/layout/build/makefile.win +++ b/mozilla/layout/build/makefile.win @@ -20,7 +20,7 @@ DEPTH=..\.. DEFINES=-D_IMPL_NS_HTML MODULE=raptor -REQUIRES=xpcom raptor +REQUIRES=xpcom raptor dom CPPSRCS=dlldeps.cpp diff --git a/mozilla/layout/html/document/src/nsHTMLContentSink.cpp b/mozilla/layout/html/document/src/nsHTMLContentSink.cpp index 8860e70e246..1eee94c0e93 100644 --- a/mozilla/layout/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/layout/html/document/src/nsHTMLContentSink.cpp @@ -151,6 +151,7 @@ protected: nsresult ProcessAREATag(const nsIParserNode& aNode); nsresult ProcessBASETag(const nsIParserNode& aNode); nsresult ProcessSTYLETag(const nsIParserNode& aNode); + nsresult ProcessSCRIPTTag(const nsIParserNode& aNode); nsresult ProcessBRTag(nsIHTMLContent** aInstancePtrResult, const nsIParserNode& aNode); @@ -741,6 +742,11 @@ PRInt32 HTMLContentSink::AddLeaf(const nsIParserNode& aNode) return 0; case eHTMLTag_script: + // XXX SCRIPT tag evaluation is currently turned off till we + // get more scripts working. +#if 0 + ProcessSCRIPTTag(aNode); +#endif return 0; case eHTMLTag_area: @@ -1029,6 +1035,102 @@ nsresult HTMLContentSink::ProcessSPACERTag(nsIHTMLContent** aInstancePtrResult, return rv; } +#define SCRIPT_BUF_SIZE 1024 + +nsresult HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode) +{ + nsresult rv = NS_OK; + PRInt32 i, ac = aNode.GetAttributeCount(); + + // Look for SRC attribute + nsString* src = nsnull; + for (i = 0; i < ac; i++) { + const nsString& key = aNode.GetKeyAt(i); + if (key.EqualsIgnoreCase("src")) { + src = new nsString(aNode.GetValueAt(i)); + } + } + + char *script = nsnull; + PRInt32 len = 0; + + // If there is a SRC attribute, (for now) read from the + // stream synchronously and hold the data in a string. + if (nsnull != src) { + // Use the SRC attribute value to open a blocking stream + nsIURL* url = nsnull; + char* spec = src->ToNewCString(); + rv = NS_NewURL(&url, nsnull, spec); + delete spec; + delete src; + if (NS_OK != rv) { + return rv; + } + PRInt32 ec; + nsIInputStream* iin = url->Open(&ec); + if (nsnull == iin) { + NS_RELEASE(url); + return (nsresult) ec;/* XXX fix url->Open */ + } + + // Drain the stream by reading from it a chunk at a time + nsString data; + PRInt32 err, nb; + do { + char buf[SCRIPT_BUF_SIZE]; + + nb = iin->Read(&err, buf, 0, SCRIPT_BUF_SIZE); + if (0 == err) { + data.Append((const char *)buf, nb); + } + } while (err == 0); + + if (NS_INPUTSTREAM_EOF == err) { + script = data.ToNewCString(); + len = data.Length(); + } + else { + rv = NS_ERROR_FAILURE; + } + + NS_RELEASE(iin); + NS_RELEASE(url); + } + else { + // Otherwise, get the text content of the script tag + const nsString& content = aNode.GetSkippedContent(); + script = content.ToNewCString(); + len = content.Length(); + } + + if (nsnull != script) { + nsIScriptContextOwner *owner; + nsIScriptContext *context; + owner = mDocument->GetScriptContextOwner(); + if (nsnull != owner) { + + rv = owner->GetScriptContext(&context); + if (rv != NS_OK) { + NS_RELEASE(owner); + return rv; + } + + jsval val; + PRBool result = context->EvaluateString(script, len, &val); + + if (PR_FALSE == result) { + rv = NS_ERROR_FAILURE; + } + + NS_RELEASE(context); + NS_RELEASE(owner); + } + delete script; + } + + 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? nsresult HTMLContentSink::ProcessSTYLETag(const nsIParserNode& aNode) diff --git a/mozilla/layout/html/style/src/makefile.win b/mozilla/layout/html/style/src/makefile.win index 063feeb4651..9fb916a3141 100644 --- a/mozilla/layout/html/style/src/makefile.win +++ b/mozilla/layout/html/style/src/makefile.win @@ -19,7 +19,7 @@ DEPTH=..\..\..\.. LIBRARY_NAME=raptorhtmlstyle_s MODULE=raptor -REQUIRES=xpcom raptor js +REQUIRES=xpcom raptor dom js DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN @@ -38,7 +38,7 @@ CPP_OBJS=.\$(OBJDIR)\nsCSSKeywords.obj .\$(OBJDIR)\nsCSSLayout.obj \ LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I$(PUBLIC)\netlib \ -I..\..\..\base\src \ - -I..\..\base\src -I$(PUBLIC)\js + -I..\..\base\src -I$(PUBLIC)\js -I$(PUBLIC)\dom LCFLAGS = \ $(LCFLAGS) \